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

Q: Change in /assume:buffered_io in IVF 11?

newfortranuser
Beginner
930 Views
I am migrating another Fortran library from IVF 10 to IVF 11. Parts of this library originated in the days of Powerstation, if that matters. This library does heavy file output. So naturally it uses /assume:buffered_io.

Everything worked fine in IVF 10.1.030. Repeat: Everything worked fine in IVF 10.1.030.

But in IVF 11.1.060 some (not all) of the the sequential output files get created but never get any data. Even whrn the app terminates normally, no data. Sure enough, setting /assume:nobuffered_io does the trick. The data are back. Given the huge amount of IO, unbuffered is simply not an option. The performance hit will be completely unacceptable to the customer.

So the question is, how has the treatment of buffered io changed between IVF 10 and 11? I understand that buffering leaves a lot up to the implementation. But I thought everythng should be flushed on CLOSE or a normal exit. But then I found this interesting note in the online help for "OPEN:BUFFERED Specifier":

If BUFFERED='YES' is specified, the request may or may not be honored, depending on the output device and other file or connection characteristics.

Interesting... please tell me more.

If it matters, we're also using /fpscomp:general and /fpscomp:nolibs. I'm not done experimenting yet, but these do not seem to be involved.

An example may help:

[bash]    open( unit=42, name='file.txt', access='sequential', action = 'write', status='replace', iostat=ios )
    if ( ios/=0 ) then
      call complain()
      return
    endif

    write(42,'(A)') 'Hello, World."
    close(42)                      [/bash]
This example runs just fine as part of a larger app. I can step through and see the file created on disk, but the friendly message is never written for /assume"buffered_io...even after the app shuts down. If I swich to /assume:nobuffered_io, of course it works. Obviously I don't need buffered_io for this example, but I do need buffered_io when writing multi-gigabyte datafiles in tens-of-megabyte chunks.

I emphasize again that buffered io definitely works in IVF 10.1.030 and appears to not work in IVF 11.1.060.

Please tell me I'm just suffering from a bad case of the Mondays.

Thanks.
0 Kudos
7 Replies
newfortranuser
Beginner
930 Views
Ok, I don't know why my code snippet looks different than I typed it (grumpy about html) so here it is again:

open(unit=42, name='file.txt', access='sequential', action='write', status='replace', iostat=ios)
if (ios/=0) then
call complain()
return
endif
write(42,'(A)') "Hello, World."
close(42)

I hope that shows up better.
0 Kudos
newfortranuser
Beginner
930 Views
It looks like some kind of interaction between buffering and other non-default compiler settings.

I have created a test project which has nothing but the above snippet in main() and it works fine, both buffered and unbuffered. I will test some more and share my results when I know more.

Meanwhile, if anyone knows of a change between IVF 10 and IVF 11 which *might* be involved, I will be inertested. I have a lot of compiler options to compare... :(

Thanks.
0 Kudos
newfortranuser
Beginner
930 Views
Ok. I think I know part of what is going on. This may be completely useless, but on the chance that someday some poor soul like me will be anxiously Googling, here are some notes:

The behavior seems to be very sensitive to how much data has been written to small (10KB) test files and the system load. That made me suspect that the buffers just were not getting flushed. I still think the buffers are supposed to get flushed when the app exits normally. Rather than rely on this, I did an explicit CLOSE. Success! The buffer got flushed to disk.

Next I sprinkled COMMITQQ on the big data files I really care about. Success! It turns out we have probably just been very lucky, unwitting benefactors of unspecified behavior which just happened to break our way for many years until IVF 11.1 came along and shook us out of our complacency.

I actually would be pretty happy, except for one thing: when the app exits normally buffers should get flushed even if we forget to close the file (Ok, shame on us!). But that's not happening in some cases. Although attepts to reproduce this in a simple console app failed, it is a repeatable problem in our production code -- a multithreaded static Fortran lib which uses the multithreaded DLL runtimes and is itself used by a C++ app. And as I mentioned some /fpscomp is turned on and there are other legacy details brought over from CVF. That leaves a lot of room for something to go wrong, but I sure wish the buffers would just flush on exit. Death, taxes and flushed buffers! No matter, we'll flush them with strategic use of COMMITQQ.

0 Kudos
Steven_L_Intel1
Employee
930 Views
I'll run this by our library developers and see what they say.
0 Kudos
Steven_L_Intel1
Employee
930 Views
The key here is that you are doing the I/O in a Fortran routine called from a C++ application. When the main program is Fortran, a Fortran "exit handler" is established that does the run-down of open units, but when the main program is not Fortran, this doesn't happen. What you should therefore do is call for_rtl_finish_ from your C++ application before it exits. It would probably best if you called for_rtl_init_ at the start, though this is not strictly required. You can find information on both of these in the Intel compiler on-disk help.

If you don't want to do this, I suggest using FLUSH rather than COMMITQQ, which will give you much better performance.
0 Kudos
newfortranuser
Beginner
930 Views

Steve,

Thank you! As I say, I guess we've been lucky for a long time. Yikes!

I didn't remember whether FLUSH was an MPI-only thing... thanks.

Your explanation makes a lot of sense. I started wondering how the Fortran lib would ever find out that the C++ caller was shutting down. As you point out, the answer is "it doesn't, unless we tell it."

Humble Thanks!

0 Kudos
Steven_L_Intel1
Employee
930 Views
FLUSH was an extension but is now part of Fortran 2003.
0 Kudos
Reply