1

我正在使用 caps 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);
4

2 回答 2

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是对编译器的预先存在的分配。如果您愿意,您还应该能够使用 OpenACCacc_malloc例程来代替 分配内存。cudaMalloc

感谢@user2054656 指出我device_resident在此答案的第一个版本中的错误使用。

于 2013-05-03T08:03:03.313 回答
2

我同意 talonmies 的帖子,除了你应该使用pragma的deviceptr条款。data我这样说是因为device_resident确实要求 OpenACC 实现分配内存,而 device_ptr 没有。您不需要分配内存,因为它已经由用户分配cudaMalloc()

于 2013-05-03T09:02:21.133 回答