【问题标题】:BLAS subroutines dgemm, dgemv and ddot doesn't work with scalars?BLAS 子程序 dgemm、dgemv 和 ddot 不适用于标量?
【发布时间】:2009-06-17 11:29:45
【问题描述】:

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

【问题讨论】:

    标签: matrix fortran gfortran scalar


    【解决方案1】:

    BLAS 例程应该正确处理大小为 1 的对象。我认为它不能依赖于编译器,但它可能依赖于你所依赖的 BLAS 的实现(尽管我认为它是实现的错误)。可以在Netlib 上找到的 BLAS 的参考(阅读:非目标优化)实现可以很好地处理这种情况。

    我已经对大小为 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 替换为您的优化版本,以检查它是否有任何更改(您可以编译并链接到我在前面的答案中链接到的 ddot.f 文件)

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      • 2018-04-06
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2012-01-02
      相关资源
      最近更新 更多