Программа двойной точности на Фортране с простой процедурой MKL BLAS

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

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


person Shamster    schedule 08.05.2011    source источник


Ответы (2)


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

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

person M. S. B.    schedule 08.05.2011
comment
Это было предупреждение о неявном отсутствии, которое подсказало мне решение. Спасибо. - person Shamster; 08.05.2011

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

Кроме того, включите все виды параметров отладки, которые вы можете найти, например, ответ М.С.Б. шоу для гфортрана.

person janneb    schedule 08.05.2011