"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
)
我无法理解角色或LDA
和LDB
。文件说
LDA 是整数
在输入时,LDA 指定声明的 A 的第一个维度 在调用(子(程序中。当 TRANSA = 'N' 或 'n' 时,则 LDA 必须至少为 max( 1, m (,否则 LDA 必须为 最小最大值( 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,*)
的矩阵的元素A(i,j)
(读取为LDA
行和未指定数量的列(,您需要从矩阵的开头查找(j-1)*LDA + (i-1)
元素(Fortran 数组默认为 1 索引(,因此您需要知道LDA
的值。您不需要知道实际的列数,因此不需要知道虚拟参数中的*
。
在 C/C++ 中也是如此。如果你有一个声明为a[something][LDA]
的 2D 数组,那么元素a[i][j]
位于数组开始后i*LDA + j
位置,你只需要知道LDA
-something
的值不会影响a[i][j]
地址的计算。
虽然GEMM在M x K
矩阵A
上运行,但实际数据可以嵌入到一个更大的LDA x L
矩阵中,其中LDA >= M
和L >= K
,因此LDA
被明确指定。这同样适用于LDB
和LDC
.
BLAS是多年前开发的,当时计算机编程与今天完全不同。特别是内存管理,不像现在这样灵活。分配一个大矩阵,然后使用和重用其中的一部分来存储较小的矩阵是常态。此外,GEMM 还广泛用于例如在各种子矩阵上工作的迭代算法,将数据保留在原始矩阵中并仅指定子矩阵位置和维度的速度更快,因此您需要提供这两个维度。
从Fortran 90开始,该语言具有数组切片和自动数组描述符,允许人们发现切片的维度和更大矩阵的维度,因此如果GEMM是用Fortran 90或更高版本编写的,那么它的参数就不会那么冗长。但即使是这种情况,C 也没有数组描述符,因此您仍然必须提供所有这些参数才能使 GEMM 可以从 C 调用。在C++中,可以将描述符隐藏在矩阵类中,许多数学库实际上都是这样做的(例如,Scythe(。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 为什么stream::忽略未按预期工作