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

Multiplying a subset of matrix to another matrix using lapack/blas

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

我的问题是

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

其实dgemm是为子矩阵乘法设计的。您只需要正确使用每个矩阵的起始指针和参数 LDALDBLDC.

BLAS 的 C 变体是:

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);

假设你有矩阵:

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

Column Major 矩阵存储调用 dgemm :

cblas_dgemm (CblasColMajor, CblasNoTrans, CblasNoTrans, 15, 20, 10, 1., A, 15, B, 10, 1., C, 15);

假设您需要调用 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);
    

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

的上子矩阵

类似地,从 C 调用 Fortran 的原始 dgemm 函数将是

    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);