Blas 函数 return 2 使用相对路径和绝对路径编译时的不同结果
Blas function return 2 different result when compiled with relative path and absolute path
当我使用来自 BLAS 的 zgerc
子例程编译 Fortran 代码时,我遇到了一个非常奇怪的问题。基本上,这个子程序计算向量 x 与向量 y 的共轭的外积。有关该功能的更多信息 here。我的简单代码如下:
program main
implicit none
integer :: i
complex(8), dimension(10) :: a = [(i, i=0,9)]
complex(8), dimension(10) :: b = [(i, i=0,9)]
complex(8), dimension(10, 10) :: c
c = 0
CALL zgerc(10, 10, 1.D0, a, 1, b, 1, c, 10)
WRITE(*, *) c
end program main
我这里有 2 个复向量,a
和 b
,都是从 0 到 9,它们的虚部是 0。
现在是奇怪的部分。如果我用绝对路径编译该代码: gfortran -c /home/myUser/Fortran/tests/main.f90 -o main.o
我得到正确的结果,但是如果我用 gfortran -c main.f90 -o main.o
编译(当然我在正确的目录中,我也试过 ./main.f90
) 实部的结果是正确的,但对于虚部,我得到的数字是 1E+225
(如果我使用 ./main.f90
,我得到的数字是 1E+163
)。
我不明白为什么我的代码路径会改变虚部的结果...很高兴能得到你的帮助。
我使用 Ubuntu 20.04.2 和默认的 gfortran (9.3.0)
P.S,我的最终目标是将其用作 Python 和 f2py 中更复杂子程序的一部分。
编辑:我的完整命令:
#gfortran -c /home/myUser/Fortran/tests/main.f90 -o main.o
gfortran -c main.f90 -o main.o
gfortran -o test main.o /home/myUser/PycharmProjects/GSIE_2D/fortran_scripts/libblas.a /home/myUser/PycharmProjects/GSIE_2D/fortran_scripts/liblapack.a
rm ./main.o
./test
第 1 行和第 2 行是 2 种情况,所以我每次 运行 只有一种。
您提供 1d0
,这是一个 double precision
文字,而 zgerc
假定一个 double complex
值。
call zgerc(10, 10, cmplx(1, kind=8), a, 1, b, 1, c, 10)
通过包含显式接口(通过某种 blas 模块),您会在提供错误数据类型的参数时遇到编译时错误。
Intel 的 mkl 在其 blas95
模块和通用例程(gerc
而不是 {c,z}gerc
中提供了此类显式接口。
还有 this 开源模块为标准 blas 例程提供显式接口。
还可以使用 iso_fortran_env
中定义的可移植类型。
program main
use blas95, only: gerc
use iso_fortran_env, only: real64
implicit none
integer, parameter :: n = 10
integer :: i
complex(real64) :: a(n) = [(i, i=0,n-1)], b(n) = [(i, i=0,n-1)], c(n,n)
c = 0
! call zgerc(10, 10, cmplx(1, kind=8), a, 1, b, 1, c, 10) ! standard blas
call gerc(c, a, b, alpha=cmplx(1, kind=real64)) ! generic blas95
print *, c
end program
当我使用来自 BLAS 的 zgerc
子例程编译 Fortran 代码时,我遇到了一个非常奇怪的问题。基本上,这个子程序计算向量 x 与向量 y 的共轭的外积。有关该功能的更多信息 here。我的简单代码如下:
program main
implicit none
integer :: i
complex(8), dimension(10) :: a = [(i, i=0,9)]
complex(8), dimension(10) :: b = [(i, i=0,9)]
complex(8), dimension(10, 10) :: c
c = 0
CALL zgerc(10, 10, 1.D0, a, 1, b, 1, c, 10)
WRITE(*, *) c
end program main
我这里有 2 个复向量,a
和 b
,都是从 0 到 9,它们的虚部是 0。
现在是奇怪的部分。如果我用绝对路径编译该代码: gfortran -c /home/myUser/Fortran/tests/main.f90 -o main.o
我得到正确的结果,但是如果我用 gfortran -c main.f90 -o main.o
编译(当然我在正确的目录中,我也试过 ./main.f90
) 实部的结果是正确的,但对于虚部,我得到的数字是 1E+225
(如果我使用 ./main.f90
,我得到的数字是 1E+163
)。
我不明白为什么我的代码路径会改变虚部的结果...很高兴能得到你的帮助。
我使用 Ubuntu 20.04.2 和默认的 gfortran (9.3.0)
P.S,我的最终目标是将其用作 Python 和 f2py 中更复杂子程序的一部分。
编辑:我的完整命令:
#gfortran -c /home/myUser/Fortran/tests/main.f90 -o main.o
gfortran -c main.f90 -o main.o
gfortran -o test main.o /home/myUser/PycharmProjects/GSIE_2D/fortran_scripts/libblas.a /home/myUser/PycharmProjects/GSIE_2D/fortran_scripts/liblapack.a
rm ./main.o
./test
第 1 行和第 2 行是 2 种情况,所以我每次 运行 只有一种。
您提供 1d0
,这是一个 double precision
文字,而 zgerc
假定一个 double complex
值。
call zgerc(10, 10, cmplx(1, kind=8), a, 1, b, 1, c, 10)
通过包含显式接口(通过某种 blas 模块),您会在提供错误数据类型的参数时遇到编译时错误。
Intel 的 mkl 在其 blas95
模块和通用例程(gerc
而不是 {c,z}gerc
中提供了此类显式接口。
还有 this 开源模块为标准 blas 例程提供显式接口。
还可以使用 iso_fortran_env
中定义的可移植类型。
program main
use blas95, only: gerc
use iso_fortran_env, only: real64
implicit none
integer, parameter :: n = 10
integer :: i
complex(real64) :: a(n) = [(i, i=0,n-1)], b(n) = [(i, i=0,n-1)], c(n,n)
c = 0
! call zgerc(10, 10, cmplx(1, kind=8), a, 1, b, 1, c, 10) ! standard blas
call gerc(c, a, b, alpha=cmplx(1, kind=real64)) ! generic blas95
print *, c
end program