`sgemm` 的维度参数是如何工作的?

How does the dimention argument of `sgemm` work?

我正在尝试理解 sgemm 的文档,因为我正在将代码从使用此库转换到其他库。

函数原型为

sgemm   (   character   TRANSA,
        character   TRANSB,
        integer     M,
        integer     N,
        integer     K,
        real    ALPHA,
        real, dimension(lda,*)      A,
        integer     LDA,
        real, dimension(ldb,*)      B,
        integer     LDB,
        real    BETA,
        real, dimension(ldc,*)      C,
        integer     LDC 
    )   

我无法理解 LDALDB 的角色。文档说

LDA is INTEGER

On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ).

指定A的第一个维度是什么意思?这像是在行和列专业之间切换吗?或者这是切片张量?

LD代表主尺寸。 BLAS 最初是 Fortran 77 子程序库,在 Fortran 中矩阵按列存储:A(i,j) 在内存中紧跟 A(i+1,j),与 C/C++ 相反,其中 a[i][j] 后跟 a[i][j+1]。为了访问维度为 A(LDA,*)(读取为 LDA 行和未指定数量的列)的矩阵的元素 A(i,j),您需要从中查找 (j-1)*LDA + (i-1) 元素矩阵的开头(Fortran 数组默认为 1 索引),因此您需要知道 LDA 的值。您不需要知道实际的列数,因此不需要知道虚拟参数中的 *

在C/C++中也是一样。如果你有一个声明为 a[something][LDA] 的二维数组,那么元素 a[i][j] 位于数组开始后的 i*LDA + j 个位置,你只需要知道 LDA - 值something的地址不影响a[i][j].

的地址计算

尽管 GEMM 在 M x K 矩阵 A 上运行,但实际数据可能嵌入到更大的矩阵 LDA x L 中,其中 LDA >= ML >= K,因此明确指定了 LDA。这同样适用于 LDBLDC.

BLAS 是多年前开发的,当时计算机编程与今天大不相同。特别是内存管理,不像现在这样灵活。分配一个大矩阵,然后使用和重用它的一部分来存储较小的矩阵是一种常态。此外,GEMM 广泛用于,例如,在各种子矩阵上工作的迭代算法,将数据保留在原始矩阵中并仅指定子矩阵的位置和维度会更快,因此您需要提供两个维度。

从 Fortran 90 开始,该语言具有数组切片和自动数组描述符,允许发现切片的维度和更大矩阵的维度,因此如果 GEMM 是用 Fortran 90 或更高版本编写的,它不会' 就其论点而言如此冗长。但即使是这种情况,C 也没有数组描述符,因此您仍然必须提供所有这些参数才能使 GEMM 可从 C 调用。在 C++ 中,可以将描述符隐藏在矩阵中 class,许多数学库实际上也是这样做的(例如,Scythe)。