arrays - forrtl: advertencia(402): fuerte:(1)
fortran intel-fortran (1)
Creo que está recibiendo esta advertencia porque las subrutinas se pasan secciones de matriz no contiguas y el compilador ha decidido que la subrutina debería obtener una matriz temporal contigua que contenga los valores necesarios. Espero que el código de subrutina esté escrito en términos de una matriz y asuma implícitamente, como siempre lo hacemos cuando se programa en Fortran, que es contigua.
Si leo tu código correctamente, el compilador entiende esta afirmación
stripe(j,1:s(j),1)
significar (por así decirlo)
stripe(j,1,1)
stripe(j,2,1)
stripe(j,3,1)
...
Dado que, como espero que sepa, las matrices de Fortran se almacenan con el primer valor de índice cambiando más rápidamente, su sección de matriz avanza a través de la memoria.
Puede suprimir la advertencia con la opción del compilador noarg_temp_created
. Tenga en cuenta que esto solo suprime la advertencia (lo que podría ahorrar una pizca del tiempo de ejecución del programa, supongo), no afecta lo que hace el compilador, las matrices temporales aún se crearán.
Podría escribir código para crear matrices temporales que contengan la sección que se transferirá a la subrutina. No veo mucha ventaja en hacer esto; Esperaría que el compilador emitiera código que supere a cualquier código que escriba para una operación tan directa.
O podría remodelar / permutar su matriz original una vez, antes de comenzar a llamar a la subrutina, y darle la forma y la disposición correctas para cortar en bloques contiguos. Y luego no se permutar / deshacer al final de todas las llamadas.
La única manera concluyente de responder a su pregunta sobre el rendimiento relativo de su código actual y de cualquier formulación alternativa es codificarlos y sacar su cronómetro.
recibo la siguiente advertencia en tiempo de ejecución:
...
forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #2
forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #3
forrtl: warning (402): fort: (1): In call to GERADHEIT_LINIAL, an array temporary was created for argument #2
forrtl: warning (402): fort: (1): In call to GERADHEIT_LINIAL, an array temporary was created for argument #3
...
para cada llamada de la subrutina / declaración de escritura.
La llamada de la subrutina:
integer :: l,kreise
character(*)::setname
real(8),diemnsion(:,:,:),allocatable::stripe
integer,dimension(:)s(j)
...code and allocation of arrays...
do j=n(1)
call geradheit_linial (s(j),stripe(j,1:s(j),1),
& stripe(j,1:s(j),2),setname)
end do
...
subroutine geradheit_linial (ndaten,x,r,setname)
implicit none
integer,intent(in) :: ndaten
real(8),dimension(ndaten),intent(in) :: x,r
character(*),intent(in) :: setname
y la declaración de escritura:
write(91,*)''Gerade: '',gerade(maxloc(reslt(1:i)),minsumloc,1),
& gerade(maxloc(reslt(1:i)),minsumloc,2)
La stripe
matriz se asigna con el valor máximo esperado para cada dimensión, por lo que la mayoría de las veces solo se pasa un subconjunto a través de la llamada.
Por lo que yo entiendo, no es realmente un problema en términos de precisión, pero puede ralentizar el programa, por lo tanto, se realiza una gran cantidad de escritura en la memoria RAM. Entonces, ¿cuánto ralentiza mi cálculo (la stripe
puede tener una dimensión de aproximadamente una stripe(100,300,3)
y podría stripe(100,300,3)
más adelante)? ¿Y cómo puedo evitar tales arreglos extra ?.