我想用BLAS包裹。要做到这一点,对于我来说,gemm()函数的两个第一个参数的意义并不明显。参数'N'和'T'代表什么?
BLAS.gemm!('N', 'T', lr, alpha, A, B, beta, C)BLAS.gemm和BLAS.gemm!有什么区别?
发布于 2016-07-20 13:34:56
根据文档
gemm!(tA,tB,alpha,A,B,β,C) 根据tA (转座子A)和tB,将C更新为alpha *A*B+ beta*C或其他三个变体。返回更新的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!()可能会更快一些,因为您不需要每次都重新分配新内存,这在初始内存分配和随后的垃圾收集中都是有时间开销的。
https://stackoverflow.com/questions/38481674
复制相似问题