使用 lapack/blas 将矩阵的子集乘以另一个矩阵

use*_*361 3 matlab matrix blas lapack matrix-multiplication

我想使用 dgemm 或任何其他 lapack/blas 函数将矩阵 A 的子集乘以另一个矩阵。我认为由于子矩阵的元素可能不连续,所以我不能直接使用 dgemm 而不将子矩阵复制到另一个空间。所以,当这个子矩阵本身很大时,它可能效率很低,我认为用 C 编写这个特定问题的乘法代码可能会更好。 由于复制然后使用 lapack/blas 本身,可能根本没有效率。我在 matlab 中使用 lapack/blas 作为 mex 文件。

我的问题是

1- lapack/blas 是否有任何功能可以在乘法中处理子矩阵?2-如果不是,直接编写乘法代码更好还是将子矩阵复制到另一个矩阵并使用dgemm更好?

zti*_*tik 5

实际上dgemm是为子矩阵乘法而设计的。您只需要正确使用每个矩阵的起始指针和参数LDA, LDB, LDC

CBLAS的变体是:

void cblas_dgemm (const CBLAS_LAYOUT layout, const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc);
Run Code Online (Sandbox Code Playgroud)

假设你有矩阵:

  • A(15x10)
  • B(10x20)
  • C(15x20)

调用dgemmColumn Major矩阵存储:

cblas_dgemm (CblasColMajor, CblasNoTrans, CblasNoTrans, 15, 20, 10, 1., A, 15, B, 10, 1., C, 15);
Run Code Online (Sandbox Code Playgroud)

假设您需要调用dgemm传递子矩阵:

  • As(3x2)在出发点(2,1)A
  • Bs(2x5)在出发点(3,5)B
  • Cs(3x5)在出发点(4,2)C

NMK将改变为3,5,2,但LDXs将保持与上面相同。然后你必须传递正确的指针,dgemm以便它们指向每个子矩阵的开始。由于您有C编号,因此您必须从每个坐标中减去一个。

  • As 起点是 A + (1+0*15)
  • Bs 起点是 B + (2+4*10)
  • Cs 起点是 C + (3+1*15)

    cblas_dgemm (CblasColMajor, CblasNoTrans, CblasNoTrans, 3, 5, 2, 1., A+1, 15, B+42, 10, 1., C+18, 15);
    
    Run Code Online (Sandbox Code Playgroud)

的想法N LDA是说我有一个矩阵,A(LDA,*)但我将使用上子矩阵As(N,*)。在示例情况下,您不想使用上子矩阵,而是使用其他内部A. 在这种情况下,您将创建一个指向A+1矩阵的新指针。现在As是 的上子矩阵A+1

类似地调用 Fortran 的原始dgemm函数 from Cwill 是

    char NoTrans = `N`;
    int N = 3;
    int M = 5;
    int K = 2;
    int LDA = 15;
    int LDB = 10;
    int LDC = 15;
    double alpha = 1.0;
    double beta = 1.0;
    dgemm (&NoTrans, &NoTrans, N, M, K, alpha, A+1, LDA, B+42, LDB, beta, C+18, LDC);
Run Code Online (Sandbox Code Playgroud)