โปรแกรมความเที่ยงตรงสองเท่าของ Fortran พร้อมรูทีน 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 ล้มเหลว

แก้ไข: ฉันเพิ่มคำสั่ง implicit none และคำสั่งประเภทสองสำหรับฟังก์ชัน ddot และ sdot หากไม่มีประเภทที่ระบุสำหรับการเรียกใช้ฟังก์ชัน ddot จะถูกพิมพ์โดยปริยายว่าเป็น single precision real


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

การส่งผ่านตัวแปรประเภทที่ไม่ถูกต้องถือเป็นกรณีของอินเทอร์เฟซที่ไม่ตรงกัน (ซึ่งผิดกฎหมาย ดังนั้นโดยหลักการแล้วคอมไพลเลอร์อาจทำอะไรก็ได้รวมถึงการเริ่ม WW III) ดังนั้นบางทีนี่อาจทำให้สแต็กยุ่งเหยิง และด้วยเหตุนี้การเรียกที่ตามมาจึงส่งกลับผลลัพธ์ที่ไม่ถูกต้อง ลองแสดงความคิดเห็นการโทรที่ไม่ถูกต้องเหล่านั้น (บรรทัดของคุณที่มีเครื่องหมาย "ไม่ควรทำงาน") และดูว่าจะช่วยได้หรือไม่

นอกจากนี้ ให้เปิดใช้งานตัวเลือกการแก้ไขข้อบกพร่องทุกประเภทที่คุณสามารถหาได้ เช่น คำตอบโดย M.S.B. รายการสำหรับ gfortran

person janneb    schedule 08.05.2011