Я пытался просто применить cublasDgemm (умножение матрицы на матрицу) на несколько матриц с элементом типа «double» (8 байтов), каждый из которых имеет одно измерение, которое очень велико. В моем случае размеры матриц 12755046 на 46. Проще говоря, A [46,12755046] * B_i [12755046,46] = C_i [46,46], где i = 1,2,3, ... .
Машина имеет 128 ГБ памяти и два GTX2080Ti (11 ГБ памяти GPU), поэтому моей первоначальной стратегией было распределение B_i для каждого GPU. Однако я всегда получаю ВНУТРЕННЮЮ ОШИБКУ, когда выполняю свой код на двух графических процессорах.
Поэтому я решил эту проблему, попробовав три вещи: 1. использовать только один графический процессор. Нет ошибки. 2. уменьшите размер матрицы, но продолжайте использовать два графических процессора. Нет ошибки. 3. использовать 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]);
}