朱莉娅:BLAS.gemm!() 参数
Julia : BLAS.gemm!() parameters
我想使用 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
应用转置运算。请注意,这将花费您一些计算时间和分配 - 转置不是免费的。 (因此,如果你打算多次应用乘法,每次都使用相同的转置规范,你最好从一开始就将矩阵存储为转置版本)。 Select N
不转置,T
转置。你必须select其中之一。
gemm!()
和gemv!()
的区别在于,对于gemm!()
,您已经需要分配矩阵C
。 !
是一个 "modify in place" 信号。考虑以下对它们不同用途的说明:
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()
在这种情况下的结果是相同的,尽管实现该结果的语法和过程略有不同。然而,实际上,两者之间的性能差异可能很大,具体取决于您的用例。特别是,如果您要多次执行该乘法运算,每次 replacing/updating C
的值,那么 gemm!()
可能会快一点,因为您不需要每次都重新分配新内存,这确实有时间成本,无论是在初始内存分配中还是在以后的垃圾收集中。
我想使用 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
应用转置运算。请注意,这将花费您一些计算时间和分配 - 转置不是免费的。 (因此,如果你打算多次应用乘法,每次都使用相同的转置规范,你最好从一开始就将矩阵存储为转置版本)。 Select N
不转置,T
转置。你必须select其中之一。
gemm!()
和gemv!()
的区别在于,对于gemm!()
,您已经需要分配矩阵C
。 !
是一个 "modify in place" 信号。考虑以下对它们不同用途的说明:
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()
在这种情况下的结果是相同的,尽管实现该结果的语法和过程略有不同。然而,实际上,两者之间的性能差异可能很大,具体取决于您的用例。特别是,如果您要多次执行该乘法运算,每次 replacing/updating C
的值,那么 gemm!()
可能会快一点,因为您不需要每次都重新分配新内存,这确实有时间成本,无论是在初始内存分配中还是在以后的垃圾收集中。