Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Problem with I/O reentrancy

ZlamalJakub
New Contributor III
397 Views

I observe some dangerous situation in my program using threads. It stops reading from file randomly. I have found, that problem may be connected with INQUIRE statement.

I have prepared sample code and project to demonstrate behavior.

When I run the code it randomly ends with I/O error 40  - Recursive I/O operation

 Thread           20  still alive in cycle            1
 Thread           20  read error at line         5452  error           40

If I comment lines 27,28 creating thread with INQUIRE statement (so only thread reading file is running) everything works OK.

Source code is compiled with multithreaded libraries using Intel(R) Visual Fortran Compiler XE 15.0.0.108 [IA-32]

What I am doing wrong?

0 Kudos
8 Replies
TimP
Honored Contributor III
397 Views

Files aren't shared by default. Consider accessing in single critical or master.

0 Kudos
ZlamalJakub
New Contributor III
397 Views

I do not fully understand your response. You meant that I need to use one critical section for I/O operations that guarantee that only one I/O operation will be performed at a time?

I supposed that if I use multithreaded fortran libraries I can use file I/O statements in every thread without problems. But I observe that if I test file status by INQUIRE in one thread and read from different file in another thread then I receive Recursive I/O operation error. So I expect that there is problem somewhere in READ and INQUIRE statements if they are executed with wrong timing.

 

0 Kudos
TimP
Honored Contributor III
397 Views

I don't know if inquire requires the thread be writable.

0 Kudos
Steven_L_Intel1
Employee
397 Views

I can reproduce this - you shouldn't need any additional synchronization here. (I think you really should add RECURSIVE on both routines, but in this test case it doesn't matter.) Escalated as issue  DPD200363710.

0 Kudos
andrew_4619
Honored Contributor II
397 Views

In my experience INQUIRE in ifort attempts file operations as part of the test for example if you INQUIRE the existence of a file ifort makes and attempt to open it and looks at the system state/error generated. I infer this as if you make systems calls  to look at the last error you find INQUIRE generates system errors (if the file is already open for example) and leaves the error state set (which is slightly irritating). My guess is that this a probably the cause of the problem.  

0 Kudos
ZlamalJakub
New Contributor III
397 Views

Thanks for confirmation of error Steve.

Is it possible to find out if some unit number is free to use without using INQUIRE?

Is there some way to ensure that INQUIRE is called alone without merging all I/O operations into one thread?

To app4619: In win32 is only way to find out existence of file to open it, so I suppose INQUIRE do it. I have substituted INQUIRE by this method and it seems it does not cause I/O errors I reported.

I use following code to test if file is opened for write

    hfile = CreateFile(FileName,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,0)
    if (hfile /= INVALID_HANDLE_VALUE) then
        iret=CloseHandle(hfile)
        isFileOpenedForWrite=.FALSE.
    else
        isFileOpenedForWrite=(GetLastError() == ERROR_SHARING_VIOLATION)
    endif

 

0 Kudos
Steven_L_Intel1
Employee
397 Views

Use the NEWUNIT= keyword in OPEN - that's what it's for.

0 Kudos
Steven_L_Intel1
Employee
397 Views

The problem reported here has been fixed for a release later this year. The original test case has a problem in that the main thread exits before the worker threads do, and that will always create issues, but I modified the code to wait for the worker threads to complete and there was still a problem with the INQUIRE.

0 Kudos
Reply