我正在使用大写字母openacc编译器。我想知道我自己可以管理记忆的东西吗?
例如,使用CUDA的常规openacc代码是:
#pragma acc kernels copyin(a,b) copy(c)
for (i = 0; i < SIZE; ++i)
for (j = 0; j < SIZE; ++j)
for (k = 0; k < SIZE; ++k)
c[i][j] += a[i][k] * b[k][j];
我想以这种方式改变
//allocation
cudaMalloc((void**)&a, num_bytes);
cudaMalloc((void**)&b, num_bytes);
cudaMalloc((void**)&c, num_bytes);
//transfer-in
cudaMemcpy(hostA, a, num_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(hostB, b, num_bytes, cudaMemcpyHostToDevice);
//computation
//i think it will be generated as codelet by CAPS openACC compiler.
#pragma acc kernels
for (i = 0; i < SIZE; ++i)
for (j = 0; j < SIZE; ++j)
for (k = 0; k < SIZE; ++k)
c[i][j] += a[i][k] * b[k][j];
cudaMemcpy(c, hostC, num_bytes, cudaMemcpyDeviceToHost);
cudaFree(&a);cudaFree(&b);cudaFree(&c);
答案 0 :(得分:3)
是的,你可以自己分配内存。在您的示例中,应该可以使用device_ptr
编译指示来实现此目的,例如:
cudaMalloc((void**)&a, num_bytes);
cudaMalloc((void**)&b, num_bytes);
cudaMalloc((void**)&c, num_bytes);
cudaMemcpy(hostA, a, num_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(hostB, b, num_bytes, cudaMemcpyHostToDevice);
#pragma acc data deviceptr(a, b, c)
#pragma acc kernels
for (i = 0; i < SIZE; ++i)
for (j = 0; j < SIZE; ++j)
for (k = 0; k < SIZE; ++k)
c[i][j] += a[i][k] * b[k][j];
cudaMemcpy(c, hostC, num_bytes, cudaMemcpyDeviceToHost);
cudaFree(a);cudaFree(b);cudaFree(c);
[免责声明:用浏览器编写,绝不编译或测试,使用风险自负]
这应该声明a
,b
和c
是编译器的预先存在的分配。如果您愿意,您还应该能够使用OpenACC acc_malloc
例程来代替cudaMalloc
分配内存。
感谢@ user2054656指出我在此答案的第一个版本中错误地使用了device_resident
。
答案 1 :(得分:2)
我同意talonmies的帖子,除了你应该使用deviceptr
pragma的data
条款。我这样说是因为device_resident
确实请求OpenACC实现来分配内存,而device_ptr则没有。
您不需要分配内存,因为它已由用户cudaMalloc()