假设我在GPU上有一个维度为A*B
的矩阵,其中B
(列数)是假设C样式的前导维度。在CUDA(或Cublas)中是否有任何方法将此矩阵转换为FORTRAN样式,其中A
(行数)成为主要维度?
如果可以在host->device
传输期间进行转置,同时保持原始数据不变,那就更好了。
答案 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。