2015-03-04 14 views
6

Ricevo l'avviso di runtime fortran "Un array temporaneo è stato creato" durante l'esecuzione del mio codice (compilato con gfortran) e vorrei sapere se esiste un modo migliore per risolvere questo avviso.Avviso di runtime Fortran: array temporaneo

mio codice originale è qualcosa di simile:

allocate(flx_est(lsign,3)) 
allocate(flx_err(lsign,3)) 
do i=1,lsign 
call combflx_calc(flx_est(i,:),flx_err(i,:)) 
enddo 

all'interno della subroutine definisco le variabili in questo modo:

subroutine combflx_calc(flx_est,flx_err) 
use,intrinsic    :: ISO_Fortran_env, only: real64 
implicit none 
real(real64),intent(inout) :: flx_est(3),flx_err(3) 

flux_est e flx_err vettori possono cambiare all'interno della subroutine a seconda delle diverse condizioni e Devo aggiornare i loro valori di conseguenza.

Fortran non sembra gradire questa struttura. Posso risolverlo definendo variabili temporanee:

tmp_flx_est=flx_est(i,:) 
tmp_flx_err=flx_err(i,:) 
call combflx_calc(tmp_flx_est,tmp_flx_err) 
flx_est(i,:)=tmp_flx_est 
flx_err(i,:)=tmp_flx_err 

Ma mi sembra un modo abbastanza sciocco per risolverlo.

Come puoi vedere, non sono un esperto di Fortran, quindi qualsiasi aiuto è più che benvenuto.

+2

In che modo la "correzione" fissa qualcosa? Il temporaneo è ancora lì, lo stai facendo manualmente. –

+0

Non fissato, il mascheramento è migliore. Non ho visto il potenziale danno del mio approccio iniziale, quindi volevo solo eliminare l'avviso – cardogar

+0

Non sono d'accordo sul fatto che il mascheramento è meglio che riparare. Se si desidera mascherare si potrebbe semplicemente non compilare con il controllo runtime abilitato. – casey

risposta

9

Un modo è quello di superare una forma presupposta matrice

real(real64),intent(inout) :: flx_est(:),flx_err(:) 

l'altra è per scambiare le dimensioni della matrice, in modo che è possibile passare una sezione contigua della matrice 2D.

call combflx_calc(flx_est(:,i),flx_err(:,i)) 

Il problema è che la dimensione esplicita argomenti fittizi della vostra procedura (var(n)) richiedono array contigui. Gli array di forme presunte possono avere qualche passo.

+0

Infatti, quando uso gli argomenti di forma assunta ottengo "Errore: Interfaccia esplicita richiesta per" combflx_calc "in (1): argomento della forma assunta". Tuttavia, lo scambio di dimensioni implica un lavoro piuttosto enorme e noioso. Grazie per le tue idee! – cardogar

+0

Significa ciò che dice. Devi avere un'interfaccia esplicita. Tutte le procedure dovrebbero essere inserite in un modulo. –

+0

ho fatto: 'interfaccia subroutine combflx_calc (flx_est, flx_err) uso, intrinseca :: ISO_Fortran_env, solo: real64 reale (real64), intenti (inout) :: flx_est (:), flx_err (:) fine subroutine combflx_calc end interface' Sembra funzionare senza avvertimenti, pensi che sia corretto? – cardogar

6

L'array temporaneo è in fase di creazione perché si passa una matrice a gradini alla subroutine. Gli array di Fortran sono colonne maggiori, quindi l'indice più a sinistra varia più velocemente in un array, o, meglio detto, l'indice più a sinistra è contiguo in memoria e ogni variabile a destra si trova su quelli a sinistra.

Quando si chiama

call combflx_calc(flx_est(i,:),flx_err(i,:)) 

Queste fette sono le matrici del vostro 3-vettore strided dalla lunghezza di lsign. La subroutine si aspetta che le variabili di una singola dimensione contigue nella memoria, che non è la variabile che si passa in esso. Pertanto, è necessario eseguire un temporaneo per il subroutine su cui operare e quindi copiato nuovamente nella sezione dell'array.

La tua "correzione" non cambia questo, semplicemente non ti avvisa più di un temporaneo perché stai utilizzando una variabile creata in modo esplicito piuttosto che il runtime che lo sta facendo per te.

La risposta di Vladimir offre opzioni per evitare il temporaneo, quindi non le duplicherò qui.

Problemi correlati