我想使用 BLAS 包。为此,gemm() 函数的前两个参数的含义对我来说并不明显。
参数'N'
和'T'
代表什么?
BLAS.gemm!('N', 'T', lr, alpha, A, B, beta, C)
BLAS.gemm
和 BLAS.gemm!
之间有什么区别?
最佳答案
gemm!(tA, tB, alpha, A, B, beta, C)
Update C as alpha * A * B + beta*C or the other three variants according to tA (transpose A) and tB. Returns the updated C.
注意:这里,alpha
和beta
必须是float
类型标量。 A
、B
和 C
都是矩阵。由您来确保矩阵尺寸匹配。
因此,tA
和 tB
参数表示您要将转置操作应用于 A
还是 B
相乘之前。请注意,这将花费您一些计算时间和分配 - 转置不是免费的。 (因此,如果您要多次应用乘法,每次都使用相同的转置规范,那么最好从一开始就将矩阵存储为转置版本)。选择 N
表示不转置,选择 T
表示转置。您必须选择其中之一。
gemm!()
和 gemv!()
之间的区别在于,对于 gemm!()
您已经需要分配矩阵C
。 !
是“就地修改”信号。请考虑以下它们不同用途的说明:
A = rand(5,5)
B = rand(5,5)
C = Array(Float64, 5, 5)
BLAS.gemm!('N', 'T', 1.0, A, B, 0.0, C)
D = BLAS.gemm('N', 'T', 1.0, A, B)
julia> C == D
true
本质上,这些都执行计算 C = A * B'。 (从技术上讲,gemm!()
执行 C = (0.0)*C + (1.0)*A * B'。)
因此,就地修改的语法 gemm!()
在某些方面有点不寻常(除非您已经使用过像 C 这样的语言,在这种情况下它看起来非常直观) 。您没有像在 Julia 这样的高级面向对象语言中调用函数来赋值时经常使用的显式 =
符号。
如上图所示,在这种情况下,gemm!()
和 gemm()
的结果是相同的,尽管实现该结果的语法和过程相同有点不同。然而,实际上,两者之间的性能差异可能很大,具体取决于您的用例。特别是,如果您要多次执行乘法运算,每次都替换/更新 C
的值,那么 gemm!()
可能是一个不错的选择更快,因为您不需要每次都重新分配新内存,这确实会产生时间成本,无论是在初始内存分配中还是在稍后的垃圾回收中。
关于Julia : BLAS. gemm!() 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38481674/