2012-01-26 8 views
9

sto cercando di scrivere una serie di file, dove ho aperto il file in questo modo:Fortran I/O: Specificando grande record di dimensioni

open(unit=20, FILE="output.txt", form='unformatted', access='direct', recl=sizeof(u)) 

Qui, u è un array e sizeof(u) è 2.730.025,92 mila, che è ~ 2,5 GB. Quando eseguo il programma, viene visualizzato un errore Fortran runtime error: RECL parameter is non-positive in OPEN statement, che a mio avviso significa che la dimensione del record è troppo grande.

C'è un modo per gestire questo? Un'opzione sarebbe quella di scrivere la matrice in più di una chiamata di scrittura in modo tale che la dimensione del record in ciascuna scrittura sia inferiore a 2,5 GB. Ma mi chiedo se posso scrivere l'intero array in una singola chiamata.

Edit: u è stato dichiarato come double precision u(5,0:408,0:408,0:407) Il programma è stato compilato come gfortran -O3 -fopenmp -mcmodel=medium test.f C'è un codice OpenMP in questo programma, ma il file/O è sequenziale io.

gfortran v 4.5.0, OS: openSUSE 11.3 a 64 bit AMD Opteron

Grazie per il vostro aiuto.

risposta

16

Dovresti essere in grado di scrivere array di grandi dimensioni finché la memoria lo consente. Sembra che stai ricevendo un overflow intero con la funzione sizeof. sizeof non è lo standard Fortran e non lo consiglio di utilizzarlo (le implementazioni possono variare tra i compilatori). Invece, è una pratica migliore utilizzare l'istruzione inquire per ottenere la lunghezza del record. Sono stato in grado di riprodurre il tuo problema con ifort e questa soluzione funziona per me. È possibile evitare integer overflow dichiarando una variabile tipo più elevato:

integer(kind=8) :: reclen 

inquire(iolength=reclen)u 

open(unit=20,file='output.txt',form='unformatted',& 
    access='direct',recl=reclen) 

EDIT: Dopo alcune indagini, questo sembra essere un problema gfortran. Impostare un tipo superiore per intero reclen risolve il problema per ifort e pgf90, ma non per gfortran - Ho appena provato questo con la versione 4.6.2. Anche se reclen ha il valore positivo corretto, sembra che recl sia un intero con segno a 32 bit internamente con gfortran (Grazie a @ M.S.B. Per averlo indicato). L'errore di runtring di Fortran lo suggerisce e non che il valore sia maggiore del massimo. Dubito che sia un problema del sistema operativo. Se possibile, provare a utilizzare ifort (gratuito per uso non commerciale): Intel Non-Commercial Software Download.

+5

solo per aggiungere questo: 'sizeof' restituisce il numero di byte e' recl' non è necessariamente in byte, quindi 'inquire' è il modo corretto per farlo. – steabert

+0

@steabert Grazie per l'aggiunta, questo è corretto. Un esempio per questo è il codice da OP, che si interrompe con ifort ad esempio - ifort assume recl è la lunghezza della matrice come in numero di elementi, e non il numero di byte. – milancurcic

+0

Ho ancora lo stesso errore. Sembra proprio perché il valore massimo richiesto da 'recl' è 2147483648 (2 GB). – jitihsk

Problemi correlati