C++ LAPACK zgemm op(A)尺寸
在netlib的链接中,它将M指定为: 输入时,M指定矩阵的行数 矩阵C.M的op(A)和必须至少为零。 退出时保持不变 所以如果我想用一个3x10矩阵作为a,但我想用它的共轭来表示zgemm(TRANSA='C'),我应该输入什么作为M?3还是10 另外,当我使用其他LAPACK例程时,我将2D矩阵输入为1D,如[3*3],而不是[3][3],调用例程时,我仅将A用于矩阵,我可以对非平方矩阵执行相同的操作吗?[3*10]而不是[3][10]C++ LAPACK zgemm op(A)尺寸,c++,matrix,lapack,lapacke,C++,Matrix,Lapack,Lapacke,在netlib的链接中,它将M指定为: 输入时,M指定矩阵的行数 矩阵C.M的op(A)和必须至少为零。 退出时保持不变 所以如果我想用一个3x10矩阵作为a,但我想用它的共轭来表示zgemm(TRANSA='C'),我应该输入什么作为M?3还是10 另外,当我使用其他LAPACK例程时,我将2D矩阵输入为1D,如[3*3],而不是[3][3],调用例程时,我仅将A用于矩阵,我可以对非平方矩阵执行相同的操作吗?[3*10]而不是[3][10] C++中的代码。 < P> A/命名约定/澄清
C++中的代码。
< P> <强> A/命名约定/澄清<强> < /P> 在给出答案之前,为了更清晰,重要的是要记住以下事实:- 在美国,M表示行大小,N表示列大小
- 在其他一些地方,如欧洲,N表示行大小,M表示列大小
- 您将在netlib.org中找到的所有Blas/Lapack文档都使用美国惯例
- 我(作为一个欧洲人)必须承认,美国公约更符合逻辑,就像索引(I,j)和(m,n)遵循相同的字母顺序一样
- 行大小的I_大小和列大小的J_大小
void cblas_zgemm(CBLAS_LAYOUT layout,
CBLAS_TRANSPOSE opA,
CBLAS_TRANSPOSE opB,
const int M, <-------------- I_Size of op(A)
const int N, <-------------- J_Size of op(B)
const int K, <-------------- J_Size of op(A)
const void* alpha,
const void* A,
const int lda,
const void* B,
const int ldb,
const void* beta,
void* C,
const int ldc);
B.2/内存布局
对于Blas/Lapack兼容性和更一般的数字处理
永远不要使用[I_size][J_size],而是始终使用[I_size*J_size]
(原因是:在一种情况下,您有一个指针数组,在另一种情况下,您有一个连续的内存块,它更便于矢量化、缓存友好性等。)
更准确地说
- 列主修(Fortran风格):A[ld*J_size]
- 行大调(C风格):A[I_size*ld]
-
< > >即使你在C++中编码<强>我建议使用FORTRAN约定(列主要)。假装也支持行主模式,但在引擎盖下,它只是在调用请求的子例程之前将矩阵复制到列主布局中。因此,这个额外的功能只是一个幻觉(关于性能)。更准确地说,这是最重要的。只要
Layout=RowMajor
,您就可以检查Lapacke代码,以查看此函数几乎在任何地方都可以使用(例如,请参见代码)
如果你的矩阵总是小到3x10,blas/lapack不是一个好的选择(对于性能)。考虑使用类似或的库。精彩的解释。非常感谢。我的矩阵相当大,我只是用3和10作为例子。@Alireza我刚刚添加了一些关于内存布局/Lapacke的“更新”(见B.2的结尾)这是一个很好的解释。值得注意的是,通过观察M和N始终是C的行数和列数,K始终是被乘以的维度,可以大大简化您的思维。我发现这比试图根据A和B的维度来推理M和N要简单得多,因为它不受转置的影响。@StephenCanon我同意,你是绝对正确的。我明天一有时间就去清理我的帖子(我现在有点赶时间)。感谢您的积极和建设性反馈。
const Size_t opA_I_size = (opA == CblasNoTrans) ? A.I_size() : A.J_size();
const Size_t opA_J_size = (opA == CblasNoTrans) ? A.J_size() : A.I_size();
const Size_t opB_I_size = (opB == CblasNoTrans) ? B.I_size() : B.J_size();
const Size_t opB_J_size = (opB == CblasNoTrans) ? B.J_size() : B.I_size();
cblas_zgemm(CblasColMajor,
opA,
opB,
opA_I_size,
opB_J_size,
opA_J_size,
alpha,
A.data(),
A.ld(),
B.data(),
B.ld(),
beta,
C.data(),
C.ld());