如何在CUDA/cublas中转置矩阵?

Hai*_*ang 5 c cuda gpu cublas

假设我有一个尺寸A*B在GPU上的矩阵,其中B(列数)是假定C样式的前导维度.在CUDA(或Cublas)中是否有任何方法将此矩阵转换为FORTRAN样式,其中A(行数)成为主要维度?

如果它可以在host->device传输期间进行转置同时保持原始数据不变,那就更好了.

Fen*_*ang 9

如标题中所要求的那样,为了转置设备行主矩阵A [m] [n],可以这样做:

    float* clone = ...;//copy content of A to clone
    float const alpha(1.0);
    float const beta(0.0);
    cublasHandle_t handle;
    cublasCreate(&handle);
    cublasSgeam( handle, CUBLAS_OP_T, CUBLAS_OP_N, m, n, &alpha, clone, n, &beta, clone, m, A, m );
    cublasDestroy(handle);
Run Code Online (Sandbox Code Playgroud)

并且,乘以两个行主矩阵A [m] [k] B [k] [n],C = A*B

    cublasSgemm( handle, CUBLAS_OP_N, CUBLAS_OP_N, n, m, k, &alpha, B, n, A, k, &beta, C, n );
Run Code Online (Sandbox Code Playgroud)

其中C也是行主矩阵.

  • 没有克隆可以做到这一点吗? (2认同)

dre*_*ash 4

CUDA SDK 包含一个矩阵转置,您可以在此处查看有关如何实现矩阵转置的代码示例,范围从简单实现到优化版本。

\n\n

例如:

\n\n

Na\xc3\xafve 转置

\n\n
__global__ void transposeNaive(float *odata, float* idata,\nint width, int height, int nreps)\n{\n    int xIndex = blockIdx.x*TILE_DIM + threadIdx.x;\n    int yIndex = blockIdx.y*TILE_DIM + threadIdx.y;\n    int index_in = xIndex + width * yIndex;\n    int index_out = yIndex + height * xIndex;\n\n    for (int r=0; r < nreps; r++)\n    {\n        for (int i=0; i<TILE_DIM; i+=BLOCK_ROWS)\n        {\n          odata[index_out+i] = idata[index_in+i*width];\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

就像 talonmies 指出的那样,您可以在 cublas 矩阵运算中指定是否要对矩阵进行转置操作,例如:对于 cublasDgemm() 其中 C = a * op(A) * op(B) + b * C,假设您想要将 A 操作为转置 (A^T),您可以指定参数是否为(\'N\' 正常或 \'T\' 转置)

\n