Program presisi ganda Fortran dengan rutinitas MKL BLAS sederhana

Saat mencoba memadukan presisi dalam program sederhana - menggunakan real dan double - dan menggunakan rutinitas ddot dari BLAS, saya mendapatkan keluaran yang salah untuk bagian presisi ganda. Berikut kodenya:

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

Saya sudah mencoba mengkompilasi dengan gfortran dan ifort menggunakan perpustakaan MKL BLAS sebagai berikut:

ifort -lmkl_intel_lp64 -lmkl_sequential -lmkl_core

gfortran -lmkl_intel_lp64 -lmkl_sequential -lmkl_core main.f90

Outputnya adalah:

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

Bagaimana saya bisa membuat rutinitas ddot memproses nilai presisi ganda dengan benar?

Selain itu, menambahkan flag -autodouble (ifort) atau -fdefault-real-8 (gfortran) membuat kedua rutinitas ddot berfungsi, namun rutinitas sdot gagal.

Edit: Saya menambahkan pernyataan implisit none, dan dua pernyataan tipe untuk fungsi ddot dan sdot. Tanpa tipe yang ditentukan untuk panggilan fungsi, ddot diketik secara implisit sebagai presisi tunggal yang nyata.


person Shamster    schedule 08.05.2011    source sumber


Jawaban (2)


Saya belum pernah menggunakan MKL, tapi mungkin Anda memerlukan pernyataan "gunakan" agar kompiler mengetahui antarmuka fungsi? Atau untuk mendeklarasikan fungsinya. Mereka tidak dideklarasikan sehingga kompiler mungkin berasumsi bahwa pengembalian ddot adalah presisi tunggal dan salah menafsirkan bit.

Mengaktifkan opsi peringatan menyebabkan kompiler memberi tahu Anda tentang masalahnya. Dengan gfortran, coba: -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
Itu adalah peringatan implisit-tidak ada yang memberi petunjuk kepada saya tentang solusinya. Terima kasih. - person Shamster; 08.05.2011

Melewati variabel jenis yang salah adalah kasus ketidakcocokan antarmuka (yang ilegal, jadi pada prinsipnya kompiler dapat melakukan apa saja termasuk memulai WW III), jadi mungkin ini mengacaukan tumpukan dan karenanya panggilan berikut juga memberikan hasil yang salah. Cobalah untuk mengomentari panggilan yang salah tersebut (baris Anda yang ditandai dengan "seharusnya tidak berfungsi") dan lihat apakah itu membantu.

Selain itu, aktifkan semua jenis opsi debug yang dapat Anda temukan, misalnya. jawabannya oleh M.S.B. pertunjukan untuk gfortran.

person janneb    schedule 08.05.2011