Ich habe ein Problem mit einem Fortran-Code, der für die Kompilierung mit Intel Fortran-Compiler geschrieben wurde.Standard Äquivalent für Intel Fortran Form = 'binär'
Das spezifische Problem, das ich habe, ist mit der OPEN
Aussage. Ich habe versucht, den Quellcode neu zu schreiben, damit ich ihn mit einem kostenlosen Compiler, nämlich GNU Fortran, kompilieren kann, und es ist mir gelungen, aber ich habe einige Probleme damit.
Es gibt eine temporäre Dateiausgabe mit OPEN(access = 'direct', form = 'binary', status = 'replace'...)
, aber form = 'binary'
ist kein Standard und wird nicht vom GNU Fortran Compiler unterstützt.
Nach der Suche nach Lösungen im Internet fand ich, dass form = 'unformatted'
sollte gleichwertig sein und GNU Fortran kann damit umgehen. Ja, es stimmt, ich konnte kompilieren und der Code läuft einwandfrei. Der Code ist jedoch eine wissenschaftliche Berechnung, die in diesen auf diese Weise geöffneten Dateien eine große Menge an Daten generiert. Mein Problem ist, dass form = 'unformatted'
Dateien 4 mal größer als mit form = 'binary'
ergibt.
Mit diesem habe ich nicht genug Festplattenspeicher für erfolgreiche Läufe in einigen Fällen mit unformatiertem Format, während mit binären ich hätte. Gibt es eine Entsprechung für Intel Fortran's "binary", die mit GNU Fortran verwendet werden kann und ähnliche Dateigrößen ergibt?
Wie es wurde gefragt, addiere ich einen kurzen, vereinfachte Beispielcode:
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
Das Lesen des ersten Datensatz ist in program xx
notwendig, da die Datei data.txt
von erzeugte subroutine init
aus einem vorherigen Laufe stammt meinen (Aufruf von subroutine init
möglicherweise nicht bei jedem Lauf), und einige Parameter müssen gelesen werden, um Daten in data.txt
zu interpretieren.
Mehrere Dateien werden so generiert und der erste Datensatz wird nicht immer benötigt. Ich nehme an, access = stream
könnte funktionieren, wenn der erste Datensatz gelesen wird, auch wenn es nicht notwendig ist.
Aber wenn ich ersetzen access = direct
mit access = stream
und entfernen recl
und jedes Vorkommen von rec =
in WRITE()
oder READ()
ich Laufzeitfehler der Inkonsistenz während Datei-I/O erhalten.
Speichern Sie den gleichen Datentyp in beiden Aufrufen? Können Sie Ihren Code dort anzeigen, wo die tatsächlichen Schreibvorgänge ausgeführt werden? – Chiel
Es gibt keinen Unterschied in den zwei Codes mit Ausnahme des 'binären' gegenüber 'unformatierten' Austauschs. Ich bekomme das gleiche Problem, auch wenn ich beide Versionen mit Intel Fortran Compiler kompiliere. – Balazs
Die größere Datei ergibt sich wahrscheinlich aus der Tatsache, dass Sie viele Schreibvorgänge durchführen und bei jedem Schreiben des GNU-Compilers eine Ganzzahl am Anfang und Ende hinzufügt, die die Größe der geschriebenen Daten beschreibt. Wenn Sie der Anweisung 'open' einen 'access =' stream 'zur Verfügung stellen, haben Sie wahrscheinlich Ihr Problem gelöst. – Chiel