我正在尝试在Anaconda的Numba软件包中使用cuBLAS功能并遇到问题。我需要输入矩阵为C顺序。输出可以是Fortran顺序。
我可以运行随程序包here提供的示例脚本。该脚本有两个函数gemm_v1
和gemm_v2
。在gemm_v1
中,用户必须以Fortran顺序创建输入矩阵。在gemm_v2
中,它们可以传递给GEMM的cuda实现并转换到设备上。我可以使用这些示例来处理方形矩阵。但是,我无法弄清楚如何让gemm_v2
使用非方形输入矩阵。有没有办法处理非方形的C阶输入矩阵?
注意:
理想情况下,在调用GEMM以用于其他计算之后,输入和输出矩阵都将保留在设备上(这是迭代方法的一部分)。
答案 0 :(得分:3)
这个例子的问题是,它只适用于方形矩阵。如果矩阵不是方形,则由于尺寸不匹配(假设尺寸适合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-routine应该按列主要顺序写入转置矩阵C
(之后)这一切我们无法改变)进入这个记忆。但是,C^t=(AB)^t=B^t*A^t
和B^t
和A^t
是按主列顺序重新解释的原始矩阵。
现在,让A
成为n x k
- 矩阵和B
k x m
- 矩阵,gemm例程的调用应如下:< / p>
gemm('N', 'N', m, n, k, 1.0, B, m, A, k, 0.0, C, m)
请注意:
A
和B
,因为它是通过将C-order重新解释为Fortran-order来处理的。A
和B
的位置,以便以Fortran顺序获取C^t
。C
是C顺序的(通过将它从Fortran-order重新解释为C-order,我们摆脱了^t
)。