11

I am running a loop in a Fortran program compiled with gfortran that outputs numerical values to an output file for each iteration of the loop. The problem is that the output is not saved to the file but every so many steps. How do I get it to flush each step?

Example code:

open(unit=1,file='output')

do i = 1, 1000
 write(1,*) i
end do

close(unit=1)
francescalus
  • 30,576
  • 16
  • 61
  • 96
phoganuci
  • 4,984
  • 9
  • 39
  • 50

4 Answers4

14

You need to make the output unbuffered. Try setting the GFORTRAN_UNBUFFERED_ALL environment variable to 'y', 'Y' or 1.

ire_and_curses
  • 68,372
  • 23
  • 116
  • 141
  • Would I do this from bash as follows: GFORTRAN_UNBUFFERED_ALL='y' export $GFORTRAN_UNBUFFERED_ALL ? Just curious? – phoganuci Oct 07 '09 at 19:54
  • Yes, although you don't need the '$' in the export line. This will work until you exit the current shell. If you want this behaviour permanently you may want to add those lines to your `.bashrc` file. – ire_and_curses Oct 07 '09 at 20:06
  • I have tried the following prescription and I have typed: GFORTRAN_UNBUFFERED_ALL='y' export GFORTRAN_UNBUFFERED_ALL echo $GFORTRAN_UNBUFFERED_ALL Echo printed the proper value. I have tried this with 'y','Y', and 1. None of the solved the problem. Thank you for the suggestion, though. – phoganuci Oct 07 '09 at 20:26
  • For me this worked fine, thnx for the suggestion! @Patrick: Did you find out why this didn't work for you? – steabert Nov 22 '10 at 14:02
6

The other way, if gfortran implements it, is to call the non-standard subroutine flush. Not all compilers do implement this.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • 5
    `FLUSH` as a subroutine (as in `call FLUSH()`) is nonstandard, but the `FLUSH` statement is valid Fortran 2003: `FLUSH (10)` – F'x Oct 08 '09 at 18:01
  • From the GNU website, it says: The FLUSH intrinsic and the Fortran 2003 FLUSH statement have identical effect: they flush the runtime library's I/O buffer so that the data becomes visible to other processes. This does not guarantee that the data is committed to disk. – Kevin Panko Nov 10 '13 at 21:48
1

When I need to flush, I just close the file and reopen. This is clumsy and slow, but I don't know of a better way in fortran 90 that'll work with all compilers.

0

The suggestion from "user152979" was excellent and helpful - 10 years later! I'm using an MS-DOS Fortran 5.1 built prgm to transfer programs and data to a custom-made Z80 SBC (single-board computer). The thing is a little prototype, and has only serial ports. To make it work with an experimental Pentium MMX board, (which runs MS-DOS), I needed a little read-write program. Fortran fit the bill, and the .EXE fits on a diskette (no internet access on the MMX board). But the downloaded data to the Z80 was getting scrambled, if I wrote to the COM1 port.

Turns out Fortran was buffering the data. I was only getting part of about every 10th record at the Z80. Closing the COM1 file (the output device) and reopening after writing each record of text, caused the buffer to be flushed, and the little Fortran downloader (and the Z80 SBC) now work perfectly.

So, even if your version of Fortran does not support a "FLUSH" operator, closing and immediately re-opening the file worked fine to flush the buffer contents to the device.

A Side Note about using DOS to write to COM1 port: I had to strap serial port RS-232c pins CTS to pins DTR, DCD and DSR so that MS-DOS could "see" and write to the serial port. In later versions of MS-DOS (ie. "Windows"), you can use the MODE command to set COM port RTS and CTS values to OFF, but with original DOS, you need to use a soldering iron. AND you need to flush any buffered data, after each record write. User152979 says this close & re-open is "clumsy and slow", but in my case, this trick worked perfectly.

gemesyscanada
  • 322
  • 2
  • 3