【问题标题】:non-square C-order matrices in cuBLAS ( numba )cuBLAS ( numba ) 中的非正方形 C 阶矩阵
【发布时间】:2017-12-31 15:20:06
【问题描述】:

我正在尝试使用 Anaconda 的 Numba 包中的 cuBLAS 函数,但遇到了问题。我需要输入矩阵按 C 顺序排列。输出可以是 Fortran 顺序。

我可以运行包中提供的示例脚本here。该脚本有两个函数,gemm_v1gemm_v2。在gemm_v1 中,用户必须按照 Fortran 顺序创建输入矩阵。在gemm_v2 中,它们可以传递给 GEMM 的 cuda 实现并在设备上转置。我可以让这些示例与方阵一起使用。但是,我不知道如何让gemm_v2 处理非方形输入矩阵。有没有办法处理非正方形的 C 阶输入矩阵?

注意:
理想情况下,在调用 GEMM 后,输入和输出矩阵都将保留在设备上以用于其他计算(这是迭代方法的一部分)。

【问题讨论】:

  • 在对 blas 的调用中,您指定 gemm(transa, transb, m, n, k, alpha, A:r, B:r, beta, C:w);其中 transa 和 transb 是要应用于矩阵的操作。在 gemm_v1 示例中,这是恒等运算,在 gemm_v2 示例中,这是转置。然后,您指定 m、n 和 k。这些是 A (m) 的#rows、A 的#columns/B (n) 的#rows 和 B (k) 的列。如果将其保留在示例的语法中,则将其指定为平方矩阵,因此这是更改它的地方。确保矩阵的形状与声明相匹配。

标签: python anaconda numba cublas


【解决方案1】:

这个例子的问题是,它只适用于方阵。如果矩阵不是正方形,则由于尺寸不匹配,您无法计算 A^t*B^t(假设尺寸适合 A*B)。

我手头没有可用的 cuBLAS 装置,所以这有点像在黑暗中拍摄,但如果 cuBLAS 的工作方式与通常的 BLAS 不同,我会感到非常惊讶。 BLAS 期望矩阵采用列优先顺序(又名 Fortran 顺序),但也可用于行优先顺序(又称 C 顺序)的矩阵。

在我看来,这可能是完全错误的,gemm_v2 不是处理两个 C 阶矩阵相乘的常用/最佳方法,例如,因为如果一个将两个 C 阶矩阵相乘,那么一个 C -阶矩阵作为答案。

gemm 的帮助下计算两个 C 阶矩阵的乘积的技巧如下:

即使你可能知道,我还是想先详细说明行优先顺序(c-memory-layout)和列优先顺序(fortran-memory-layout),以便充实我的答案。

所以如果我们有一个2x3(即2行3列)矩阵A,并将它存储在一些连续的内存中,我们得到:

row-major-order(A) = A11, A12, A13, A21, A22, A23
col-major-order(A) = A11, A21, A12, A22, A13, A33

这意味着,如果我们得到一个连续的内存,它以行优先顺序表示一个矩阵,并将其解释为列优先顺序的矩阵,我们将得到一个完全不同的矩阵!

但是,如果我们看一下转置矩阵A^t,我们可以很容易地看到:

row-major-order(A) = col-major-order(A^t)
col-major-order(A) = row-major-order(A^t)

这意味着,如果我们想得到矩阵C 作为结果,那么blas 例程应该以列优先顺序写入转置矩阵C(毕竟我们不能改变)进入这个记忆。但是,C^t=(AB)^t=B^t*A^tB^tA^t 是以列优先顺序重新解释的原始矩阵。

现在,让A 成为n x k-matrix 和B 一个k x m-matrix,gemm 例程的调用应该如下:

gemm('N', 'N', m, n, k, 1.0, B, m, A, k, 0.0, C, m)

请注意:

  1. 我们不必转置矩阵 AB,因为它是通过将 C-order 重新解释为 Fortran-order 来处理的。
  2. 我们必须交换矩阵AB 的位置,以便得到C^t 的Fortran 顺序结果。
  3. 生成的矩阵 C 为 C 阶(通过将其从 Fortran 阶重新解释为 C 阶,我们摆脱了 ^t)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2014-01-01
    相关资源
    最近更新 更多