2011-05-08 83 views
5

在試圖在簡單程序中混合精度 - 使用實數和雙精度並使用BLAS的ddot例程時,我想出雙精度單元的錯誤輸出。下面的代碼:帶簡單MKL BLAS例程的Fortran雙精度程序

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例程失敗。

編輯: 我添加了隱式無語句和ddot和sdot函數的兩個類型語句。沒有爲函數調用指定的類型,ddot被隱式輸入爲單精度實數。

回答

6

我沒有使用MKL,但可能您需要一個「使用」語句,以便編譯器知道函數的接口?或者以其他方式聲明功能。它們沒有被聲明,所以編譯器可能假設ddot的返回是單精度的,並且誤解了這些位。

打開警告選項會導致編譯器告訴您有關問題。使用gfortran,請嘗試: -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck = all -std = f2008 -pedantic -fbacktrace

+0

對於一個真正廣泛的警告列表+1 – 2011-05-08 06:30:47

+0

這是隱含的無警告,引導我進入解決方案。謝謝。 – Shamster 2011-05-08 07:15:41

2

傳遞不正確的類變量是接口不匹配的情況(這是非法的,所以原則上編譯器可能會做任何事情,包括啓動WW III),所以也許這會搞亂堆棧,因此下面的調用也會返回不正確的結果。嘗試將這些不正確的電話(標有「不應該工作」的行)註釋掉,看看是否有幫助。

此外,啓用各種可以找到的調試選項,例如, M.S.B的答覆爲gfortran顯示。