2011-05-08 5 views
5

Al tratar de mezclar precisión en un programa simple -utilizando tanto real como doble- y usar la rutina ddot de BLAS, estoy obteniendo resultados incorrectos para la pieza de doble precisión . Aquí está el código:Programa de precisión doble Fortran con una simple rutina MKL BLAS

program test 

!! adding this statement narrowed the issue down to ddot being considered real(4) 
implicit none 

integer, parameter :: dp = kind(1.0d0) 

!! The following 2 lines were added for the calls to the BLAS routines. 
!! This fixed the issue. 
real(dp), external :: ddot 
real, external :: sdot 

real, dimension(3) :: a,b 
real(dp), dimension(3) :: d,e 

integer :: i 

do i = 1,3 
    a(i) = 1.0*i 
    b(i) = 3.5*i 
    d(i) = 1.0d0*i 
    e(i) = 3.5d0*i 
end do 

write (*,200) "sdot real(4) = ", sdot(3,a,1,b,1) ! should work and return 49.0 
write (*,200) "ddot real(4) = ", ddot(3,a,1,b,1) ! should not work 

write (*,200) "sdot real(8) = ", sdot(3,d,1,e,1) ! should not work 
write (*,200) "ddot real(8) = ", ddot(3,d,1,e,1) ! should work and return 49.0 

200 format(a,f5.2) 

end program test 

He intentado compilar con tanto gfortran y ifort usando las librerías MKL BLAS como sigue:

ifort -lmkl_intel_lp64 -lmkl_sequential -lmkl_core 

gfortran -lmkl_intel_lp64 -lmkl_sequential -lmkl_core main.f90 

la salida es:

sdot real(4) = 49.00 
ddot real(4) = 0.00 
sdot real(8) = 4.10 
ddot real(8) = 0.00 

¿Cómo puedo obtener la rutina ddot para procesar correctamente los valores de doble precisión?

Además, la adición del distintivo -autodouble (ifort) o -fdefault-real-8 (gfortran) hace que ambas rutinas ddot funcionen, pero las rutinas sdot fallan.

Edit: Agregué la instrucción none implícita, y las dos declaraciones de tipo para las funciones ddot y sdot. Sin el tipo especificado para las llamadas a funciones, el ddot se tipeaba implícitamente como una sola precisión real.

Respuesta

6

No he usado MKL, pero tal vez necesita una declaración de "uso" para que el compilador conozca la interfaz de las funciones? O para declarar las funciones de otra manera No están declarados, por lo que el compilador probablemente asuma que el retorno de ddot es una precisión única y una interpretación errónea de los bits.

Si activa la opción de advertencia, el compilador le informará sobre el problema. Con gfortran, pruebe: -fimplicit-none -Wall -Wline-Truncation -Wcharacter-Truncation -Wsused -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck = all -std = f2008 -pedantic -fbacktrace

+0

+1 para obtener una lista exhaustiva de advertencias –

+0

Fue la advertencia implícita y ninguna que me indicó la solución. Gracias. – Shamster

2

Pasar variables de tipo incorrectas es un caso de incompatibilidad de interfaz (que es ilegal, por lo que el compilador puede hacer cualquier cosa, incluso arrancar WW III), así que quizás esté estropeando la pila y las llamadas siguientes también devuelvan resultados incorrectos. Intente comentar esas llamadas incorrectas (sus líneas marcadas con "no deberían funcionar") y vea si eso ayuda.

Además, habilite todo tipo de opciones de depuración que pueda encontrar, como p. la respuesta de M.S.B. muestra para gfortran.

Cuestiones relacionadas