BLAS子程序dgemm,dgemv和ddot不兼容标量?

时间:2009-06-17 11:29:46

标签: matrix fortran gfortran scalar

我有一个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。

1 个答案:

答案 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定义是否正确
  • 将参考BLAS替换为优化的BLAS,以检查它是否发生了任何变化(您可以在我在答案前面链接的ddot.f文件中编译和链接)
相关问题