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

时间:2012-12-08 21:15:11

标签: c cuda gpu cublas

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

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

3 个答案:

答案 0 :(得分:8)

如标题中所要求的那样,为了转置设备行主矩阵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);

并且,乘以两个行主矩阵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 );

其中C也是行主矩阵。

答案 1 :(得分:4)

CUDA SDK包含matrix transpose,您可以看到有关如何实现一个代码的here示例,范围从简单的实现到优化版本。

例如:

天真转置

__global__ void transposeNaive(float *odata, float* idata,
int width, int height, int nreps)
{
    int xIndex = blockIdx.x*TILE_DIM + threadIdx.x;
    int yIndex = blockIdx.y*TILE_DIM + threadIdx.y;
    int index_in = xIndex + width * yIndex;
    int index_out = yIndex + height * xIndex;

    for (int r=0; r < nreps; r++)
    {
        for (int i=0; i<TILE_DIM; i+=BLOCK_ROWS)
        {
          odata[index_out+i] = idata[index_in+i*width];
        }
    }
}

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

答案 2 :(得分:4)

与CUDA 5工具包捆绑在一起的CUBLAS版本包含一个类似BLAS的方法(cublasgeam),可用于转置矩阵。它记录在案here