Программа двойной точности Fortran с простой программой MKL BLAS - PullRequest
5 голосов
/ 08 мая 2011

Пытаясь смешать точность в простой программе - с использованием как реальной, так и двойной - и использовать подпрограмму ddot из 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

Я попытался скомпилировать как gfortran, так и ifort с использованием библиотек MKL BLAS следующим образом:

ifort -lmkl_intel_lp64 -lmkl_sequential -lmkl_core

gfortran -lmkl_intel_lp64 -lmkl_sequential -lmkl_core main.f90

Вывод:

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

Как мне получить процедуру ddot для правильной обработки значений двойной точности?

Кроме того, добавление флага -autodouble (ifort) или -fdefault-real-8 (gfortran) делает обе подпрограммы ddot работающими, но подпрограммы sdot не работают.

Edit: Я добавил неявный оператор none и операторы двух типов для функций ddot и sdot. Без типа, указанного для вызовов функции, ddot неявно вводился как вещественное с одинарной точностью.

Ответы [ 2 ]

6 голосов
/ 08 мая 2011

Я не использовал MKL, но, возможно, вам нужен оператор "use", чтобы компилятор знал интерфейс для функций? Или иначе объявить функции. Они не объявлены, поэтому компилятор, вероятно, предполагает, что возвращение ddot имеет одинарную точность, и неправильно интерпретирует биты.

Включение опции предупреждения заставляет компилятор сообщать вам о проблеме. С gfortran попробуйте: -fimplicit-none -Wall -Wline-усечение -Wcharacter-усечение -Wsurprising -Waliasing -Wimplicit-interface -Wunused-параметр -fwhole-файл -fcheck = все -std = f2008 -pedantic -fbacktrace

2 голосов
/ 08 мая 2011

Передача неверных переменных типа - это случай несоответствия интерфейса (что недопустимо, поэтому в принципе компилятор может сделать что угодно, включая начало WW III), поэтому, возможно, это портит стек и, следовательно, последующие вызовы также возвращают неверные результаты.Попробуйте закомментировать эти неправильные вызовы (ваши строки, помеченные как «не должны работать») и посмотрите, поможет ли это.

Также включите все виды параметров отладки, которые вы можете найти, как, например, ответ MSB дляgfortran.

...