cublas matrix matrix multiplication 在应用于具有多个 GPU 的一个非常长的维度的矩阵时给出内部错误

cublas matrix matrix multiplication gives INTERNAL ERROR when applying to matrix with one very long dimension with multiple GPUs

我试图做的是简单地将 cublasDgemm(矩阵-矩阵乘法)应用于具有 "double"(8 字节)类型元素的几个矩阵,所有这些元素都具有非常大的一维。在我的例子中,矩阵的大小是 12755046 x 46。简单地说,A[46,12755046]*B_i[12755046,46] = C_i[46,46],其中 i = 1 ,2,3,....

该机器包括 128GB 内存和两个 GTX2080Ti(11GB GPU 内存),所以我最初的策略是将 B_i 分配给每个 GPU。但是,当我在两个 GPU 上执行我的代码时,总是出现内部错误。

所以我通过尝试三件事解决了这个问题: 1. 只使用一个 GPU。没有错误。 2. 缩小矩阵大小但继续使用两个 GPU。没有错误。 3. 使用隐式使用两个 GPU 的 cublasXt。没有错误。

虽然解决了,但我还是很想知道为什么我原来的方案对大维矩阵不起作用?我猜这可能是由于 cublas 的一些内部限制或者我错过了一些配置?

我在这里附上我的简化代码来说明我的原始计划:

double *A, *B[2], *C[2];
cudaMallocManaged(&A, 46*12755046*sizeof(double));
cudaMallocManaged(&B[0], 46*12755046*sizeof(double));
cudaMallocManaged(&B[1], 46*12755046*sizeof(double));
cudaMallocManaged(&C[0], 46*12755046*sizeof(double));
cudaMallocManaged(&C[1], 46*12755046*sizeof(double));
givevalueto(A);
givevalueto(B[0]);
givevalueto(B[1]);
double alpha = 1.0;
double beta = 0.0;
cublasHandle_t  handle[nGPUs];
int iGPU;
for(iGPU=0;iGPU<nGPUs;iGPU++)
{
   cublasCreate (& handle[iGPU]);
}
for(iGPU=0;iGPU<nGPUs;i++)
{
   cudaSetDevice(iGPU);
   cublasDgemm(handle[iGPU],CUBLAS_OP_N,CUBLAS_OP_N,46,46,12755046,&alpha,A,46,B[iGPU],12755046,&beta,C[iGPU],46);
}
for(iGPU=0;iGPU<nGPUs;i++)
{
   cudaSetDevice(iGPU);
   cudaDeviceSynchronize();
}
for(iGPU=0;iGPU<nGPUs;iGPU++)
{
   cudaFree(B[iGPU]);
}

cublas 句柄适用于创建句柄时处于活动状态的设备。

来自 the documentation cublasCreate:

The CUBLAS library context is tied to the current CUDA device.

另请参阅 cublas 上下文的 the description

The device associated with a particular cuBLAS context is assumed to remain unchanged between the corresponding cublasCreate() and cublasDestroy() calls. In order for the cuBLAS library to use a different device in the same host thread, the application must set the new device to be used by calling cudaSetDevice() and then create another cuBLAS context, which will be associated with the new device, by calling cublasCreate().

您可以通过以下方式修复您的代码:

for(iGPU=0;iGPU<nGPUs;iGPU++)
{
   cudaSetDevice(iGPU);              // add this line
   cublasCreate (& handle[iGPU]);
}