fortranfortran2008

forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$


I have a Fortran routine that opens a lot of text files write data from a time loop. This routine uses open with the newunit option, this unit is stored in an object in order to write things in files later. This works fine most of the time but when the program needs to open a large number N of files at the same time I get the following error:

**forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$**

reffering to the first open function in createFiles subroutine. This error occurs whether the file already exists or not. I don't know if this might help but at this stage the new unit that should be generated would be -32768.

I include a minimal code sample with a "timeSeries" class including a routine that creates two files:

The example is composed of the two following files. It breaks for i=32639.

main.f90 :

program writeFiles

use TS

logical :: stat
integer :: i, istep, N, NtimeSteps
character(len=16) :: fileName1, fileName2
character(len=300) :: path
type(timeSeries), dimension(:), allocatable :: myTS

call getcwd( path )

path = trim(path) // '\Output_files'
inquire(directory = trim(path), exist = stat )
if (.not. stat) call system("mkdir " // '"' // trim(path) // '"' )

N = 50000
NtimeSteps = 100
allocate(myTS(N))

do i = 1, N
    write(fileName1,'(a6,i6.6,a4)') 'file1_', i, '.txt'
    write(fileName2,'(a6,i6.6,a4)') 'file2_', i, '.txt'
    call myTS(i)%createFiles(trim(path),fileName1,fileName2)
end do

do istep = 1, NtimeSteps
    #
    #compute stuff
    #
    do i = 1, N 
         write(myTS(i)%fileUnit,*) 'stuff'
    end do
end do

do i = 1, N
    close(myTS(i)%fileUnit)
end do

end program writeFiles

module.f90 :

module TS

    type timeSeries
    integer :: fileUnit

    contains

    procedure :: createFiles       => timeSeries_createFiles

    end type timeSeries

    contains

    subroutine timeSeries_createFiles(this,dir,fileName1,fileName2)
        class(timeSeries) :: this
        character(*) :: dir, fileName1, fileName2 

        open(newunit = this%fileUnit , file = dir // '\' // fileName1, status = 'replace') !error occurs here after multiple function calls
        write(this%fileUnit,*) 'Write stuff'
        close(this%fileUnit)
        open(newunit = this%fileUnit , file = dir // '\' // fileName2, status = 'replace') 
    end subroutine timeSeries_createFiles

end module

Any idea about the reason for this error? Is there a limitation for the number of files opened at the same time? Could it be related to a memory issue?

I'm using Intel(R) Visual Fortran Compiler 17.0.4.210


Solution

  • Windows has this interesting habit of not releasing all the resources for a closed file for a short time after you do a close. I have seen this sort of problem on and off for decades. My usual recommendation is to put a call to SLEEPQQ with a duration of half a second after a CLOSE when you intend to do another OPEN soon after on the same file. But you're not doing that here.

    There's more here that is puzzling. The error message referring to unit -1 and CONOUT$ should not occur when opening an explicit file and using NEWUNIT. In Intel's implementation, NEWUNIT numbers start at -129 and go more negative from there. Unit -1 is used for PRINT or WRITE(*), and CONOUT$ is the console. STATUS='REPLACE' would not be valid for a unit connected to the console. That the newunit number would be -32768 is telling and suggests an internal limit for NEWUNIT in the Intel libraries.

    I did a test of my own and see that if you use NEWUNIT and close the unit, the unit numbers go as low as -16384 before cycling back to -129. That's ok if indeed you're closing the units, but you're never closing the second file you open, so you're at least hitting a maximum number of NEWUNIT files open. I would recommend figuring out a different way of approaching the problem that didn't require leaving thousands of files open.