首页 > 解决方案 > cublas 矩阵矩阵乘法在应用于具有多个 GPU 的一个非常长的维度的矩阵时会产生内部错误

问题描述

我试图做的是简单地将 cublasDgemm(矩阵-矩阵乘法)应用于具有“双”(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 上执行我的代码时,我总是会收到 INTERNAL ERROR。

所以我通过尝试三件事解决了这个问题: 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]);
}

标签: ccudamatrix-multiplicationcublas

解决方案


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

文档cublasCreate

CUBLAS 库上下文与当前的 CUDA 设备相关联。

另见cublas 上下文的描述:

假定与特定 cuBLAS 上下文关联的设备在相应的 cublasCreate() 和 cublasDestroy() 调用之间保持不变。为了使 cuBLAS 库在同一主机线程中使用不同的设备,应用程序必须通过调用 cudaSetDevice() 设置要使用的新设备,然后通过调用创建另一个与新设备关联的 cuBLAS 上下文cublasCreate()。

您可以使用以下方法修复您的代码:

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

推荐阅读