BLAS 子程序 dgemm、dgemv 和 ddot 不適用於標量? (BLAS subroutines dgemm, dgemv and ddot doesn't work with scalars?)


問題描述

BLAS 子程序 dgemm、dgemv 和 ddot 不適用於標量? (BLAS subroutines dgemm, dgemv and ddot doesn't work with scalars?)

I have a Fortran subroutine which uses BLAS' subroutines dgemm, dgemv and ddot, which calculate matrix * matrix, matrix * vector and vector * vector. I have m * m matrices and m * 1 vectors. In some cases m=1. It seems that those subroutines doesn't work well in those cases. They doesn't give errors, but there seems to be some numerical unstability in results. So I have to write something like:

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)

So my actual question is, am I right that those BLAS' subroutines doesn't work properly when m=1 or is there just something wrong in my code? Can the compiler affect this? I'm using gfortran.


參考解法

方法 1:

BLAS routines are supposed to behave correctly with objects of size 1. I don't think it can depend on compiler, but it could possible depend on the implementation of BLAS you're relying on (though I'd consider it a bug of the implementation). The reference (read: not target-optimised) implementation of BLAS, which can be found on Netlib, handles that case fine.

I've done some testing on both arrays of size 1, and size-1 slices of larger array (as in your own code), and they both work fine:

 $ 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     

</blockquote>

Things I'd consider to debug this problem further:

  • Check that your ddot definition is correct
  • Substitute the reference BLAS to your optimised one, to check if it changes anything (you can just compile and link in the ddot.f file I linked to earlier in my answer)

(by JouniF'x)

參考文件

  1. BLAS subroutines dgemm, dgemv and ddot doesn't work with scalars? (CC BY-SA 3.0/4.0)

#matrix #scalar #fortran #gfortran






相關問題

BLAS 子程序 dgemm、dgemv 和 ddot 不適用於標量? (BLAS subroutines dgemm, dgemv and ddot doesn't work with scalars?)

為什麼我們需要維護自己的矩陣來轉換遊戲對象? (Why we need to maintain our own matrices to transform Game objects?)

R 高斯消除和 qr 分解 (R Gaussian Elimination and qr factorization)

生成尺寸為 8x8 的正定矩陣 (Generating Positive definite matrix of dimensions 8x8)

替代在此 Ruby 代碼中使用基於時間間隔分配標籤的巨型 if/else (Alternative to using a giant if/else in this Ruby code that assigns labels based on the time interval)

如何創建一個行矩陣,其元素是我的 while 循環的迭代 (How to create a row matrix whose elements are the iterations of my while loop)

在Matlab中找到矩陣中相同元素的開始索引和結束索引 (Find the Start Index and End Index of the same Element in a Matrix in Matlab)

用 Matlab 寫一個方程(矩陣大小) (writing an equation with Matlab (Matrix size))

使用 numpy 或 pandas 從元組列表中為二元組創建頻率矩陣 (Create a frequency matrix for bigrams from a list of tuples, using numpy or pandas)

如何在循環和 if 語句中使用遞歸公式 (How to use recursive formula in loop and if statement)

如何從 p 值矩陣中獲得緊湊的字母顯示? (How to get a compact letter display from a matrix of p-values?)

刺激基質上的液體流動 (Stimulating Liquid Flow on Matrix)







留言討論