Reputation: 23
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
Reputation: 60058
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