Balazs
Balazs

Reputation: 23

Standard equivalent for Intel Fortran form = 'binary'

I have a problem with a Fortran code that is written for compiling with Intel Fortran compiler.

The specific problem I have is with the OPEN statement. I tried to rewrite the source code so I can compile it with a free compiler, namely GNU Fortran, and I succeeded, but I have some issues with it.

There is some temporary file output with OPEN(access = 'direct', form = 'binary', status = 'replace'...), but form = 'binary' is not standard and not supported by GNU Fortran compiler.

After looking for solutions on the web I found that form = 'unformatted' should be equivalent and GNU Fortran can deal with it. Yes, it is true, I was able to compile and the code runs correctly. However, the code is a scientific calculation generating a huge amount of data in these files opened this way. My problem is that form = 'unformatted' results in files 4 times bigger than with form = 'binary'.

With this I do not have enough hard disk space for successful runs in some cases with unformatted format, while with binary I could have. Is there an equivalent for Intel Fortran's 'binary' that can be used with GNU Fortran and results in similar file sizes?

As it was asked for, I am adding a short, simplified sample code:

subroutine init
use module params  ! contains param1, param2, param3, ... which are inetger or real
common /params2/ maxi, maxj, maxk, limit, recnum ! integers defined elsewhere
real*8, allocatable :: x(:)
... other variables
open (unit = 5, file = 'data.txt', access = 'direct',
 *    form = 'binary', recl = 16*maxk+8, status = 'replace')
write(5, rec = 1) param1, param2, param3, maxi, maxj, maxk, limit, recnum ...
recnum = 2
do i = 1, maxi
  do j = 2, maxj
     ... do some stuff with x
     write(55, rec=recnum) x(0), (xt(k), xt(limit-k), k = 1, maxk)
  recnum = recnum + 1
  done
done
close(5)
end subroutine init

program xx
common /params2/ maxi, maxj, maxk, limit, recnum
...
call subroutine init
...
open (unit = 5, file = 'data.txt', access = 'direct',
 *   form = 'binary', recl = 16*maxk+8, status = 'old')
... do some stuff
read(5, rec=1) param1, param2, param3, maxi, maxj, maxk, limit, recnum, ...
... do some stuff
recnum = 1
do i = 1, maxi
  do j = 2, maxj
  recnum = recnum + 1
     ... do some stuff
     read(5, rec=recnum) x(0), (xt(k), xt(limit-k), k = 1, maxk)
     ... do some stuff
  done
done
close(5)
end program

The reading of first record is necessary in program xx because the file data.txt generated by subroutine init my originate from a previous run (call of subroutine init might not happen at every run), and some parameters are needed to be read to interpret data in data.txt.

Multiple files are generated like this and the first record is not always needed. I assume access = stream might work if the first record is read even if it is not necessary.

But when I replace access = direct with access = stream and remove recl and every occurrence of rec = in WRITE() or READ() I get runtime error of inconsistency during file I/O.

Upvotes: 2

Views: 1703

Answers (1)

I wasn't able to find an exact duplicate, but has been treated here before.

  form='binary'

is completely non-standard. The standard way is to use

  access='stream', `form='unformatted'

that will enable the standard stream access from Fortran 2003 which is modelled after C and can be used in all reasonably recent compilers.

Basically, the form='binary' wasn't very compatible with the rest of the language. The right way is to really change the access, that's why you are probably confused.

The sequential and direct access are all record-based and can result in record markers being written in addition to your data. The non-standard form='binary' changes that, but the proper way is to use the stream access which can be both formatted and unformatted. Especially the unformatted is very handy and let's you save exactly the bytes you have in memory without any additional markers.

Upvotes: 5

Related Questions