我有一个Fortran子程序,它使用BLAS'子程序dgemm,dgemv和ddot,它们计算矩阵*矩阵,矩阵*向量和向量*向量。我有m * m矩阵和m * 1个向量。在某些情况下,m = 1。看来这些子程序在这些情况下效果不佳。它们不会出错,但结果中似乎存在一些数值不稳定性。所以我必须写一些类似的东西:
if(m>1) then
vtuni(i,t) = yt(i,t) - ct(i,t) - ddot(m, zt(i,1:m,(t-1)*tvar(3)+1), 1, arec, 1)
else
vtuni(i,t) = yt(i,t) - ct(i,t) - zt(i,1,(t-1)*tvar(3)+1)*arec(1)
所以我的实际问题是,我是对的,当m = 1时,那些BLAS'子程序不能正常工作,或者我的代码中有什么问题吗?编译器可以影响这个吗?我正在使用gfortran。
答案 0 :(得分:1)
BLAS例程应该对大小为1的对象行为正常。我认为它不依赖于编译器,但它可能取决于你所依赖的BLAS的实现(尽管我认为它是一个实施的错误)。 BLAS的参考(读取:非目标优化)实现(可以在Netlib上找到)处理这种情况。
我已经对大小为1的数组和大小为1的大数组(就像你自己的代码一样)进行了一些测试,它们都运行良好:
$ cat a.f90 implicit none double precision :: u(1), v(1) double precision, external :: ddot u(:) = 2 v(:) = 3 print *, ddot(1, u, 1, v, 1) end $ gfortran a.f90 -lblas && ./a.out 6.0000000000000000 $ cat b.f90 implicit none double precision, allocatable :: u(:,:,:), v(:) double precision, external :: ddot integer :: i, j allocate(u(3,1,3),v(1)) u(:,:,:) = 2 v(:) = 3 i = 2 j = 2 print *, ddot(1, u(i,1:1,j), 1, v, 1) end $ gfortran b.f90 -lblas && ./a.out 6.0000000000000000
我会考虑进一步调试此问题:
ddot
定义是否正确ddot.f
文件中编译和链接)