使用 CUDA,我想为不同的数组分配内存,每个 GPU 一个来自与 main() 不同的函数,但我一定错过了一些关于指针算术的东西。我是这么想的,
void InitThisMemory(int***, int N, int Nout, size_t* pitch, int height, int width); // This function's purpose is to initialize A and the pitch
int main(void){
int** A;
int N = 10;
int NOut = 2;
int height = 2, width = 2;
size_t pitch;
InitThisMemory(&A, N, NOut, &pitch, height, width);
return 0;
}
InitThisMemory(int ***A, int N, int Nout, size_t* pitch, int height, int width){
int i;
*A = (int**)malloc(Nout * sizeof(int*));
for(i = 0;i < Nout;i++){
cudaSetDevice(i);
cudaMallocPitch((void**)&(*A[i]), &(*pitch), width, height);
}
}
免责声明:不是我的实际代码,但这应该重现错误。如果我错过了某处变量的分配,请告诉我。
为什么我认为问题出在算术上?仅仅是因为如果Nout = 1
,这工作得很好(这意味着我只使用一台设备)。
有什么想法吗?
我认为
您的错误是编写(void**)&(*A[i])
而不是(void **) (&(*A)[i])
,但我建议您按如下方式重构:
- 使用局部 int ** 变量来保存
malloc()
返回值; - 在呼叫
cudaMallocPitch()
时使用该本地; - 仅当所有
cudaMallocPitch()
调用都成功时,才传回malloc()
返回值。
如果执行这些操作,则在其中一个cudaMallocPitch()
调用失败的情况下编写正确的清理代码会更简单,并且除非一切成功,否则无需传播回传。