我正在尝试使用 OpenACC 将现有的 C 代码卸载到 GPU。在原始 CPU 代码中,很多时候需要根据某个参数的值来选择一个数据数组。下面给出了一个示例 CPU 代码:
#include <stdio.h>
#include <stdlib.h>
void selectArray (int **F, int a);
#define NN 1000
int *C, *D, *E;
int main(void)
{
int *F, a = 10; // a is the parameter used to select the array
C = (int *)malloc(NN * sizeof(int));
D = (int *)malloc(NN * sizeof(int));
E = (int *)malloc(NN * sizeof(int));
for (int i = 0; i < NN; i++)
{
C[i] = 10;
D[i] = 20;
}
selectArray(&F, a);
for (int i = 0; i < NN; i++)
{
E[i] = 2 * F[i];
}
for (int i = 0; i < 200; i++)
printf("%d %d \n", i, E[i]);
return 0;
}
void selectArray(int **F, int a)
{
if (a <= 15)
{
(*F) = C;
}
else
{
(*F) = D;
}
}
对于 OpenACC 版本的代码,数组 C 和 D 已经存在于 GPU 上,需要对基于参数a选择的数组进行进一步的计算。
#include <stdio.h>
#include <stdlib.h>
void selectArray(int **F, int a);
#define NN 1000
int *C, *D, *E;
int main(void)
{
int *F, a = 10; // a is the parameter used to select the array
C = (int *)malloc(NN * sizeof(int));
D = (int *)malloc(NN * sizeof(int));
E = (int *)malloc(NN * sizeof(int));
#pragma acc enter data create(C[:NN], D[:NN])
#pragma acc parallel loop present(C[:NN], D[:NN])
for (int i = 0; i < NN; i++)
{
C[i] = 10;
D[i] = 20;
}
selectArray(&F, a);
#pragma acc enter data copyin(F[:1]) create(E[:NN])
// Here, I cannot figure out how to point F to a selected array (C or D) on the device
#pragma acc parallel loop
for (int i = 0; i < NN; i++)
{
E[i] = 2 * F[i]; //further calculations on selected array on GPU
}
}
#pragma acc exit data delete (C[:NN], D[:NN], F)copyout(E[:200])
for (int i = 0; i < 200; i++)
printf("%d %d \n", i, E[i]);
return 0;
}
void selectArray(int **F, int a)
{
if (a <= 15)
{
(*F) = C;
}
else
{
(*F) = D;
}
}
在实际代码中,数组 C 和 D 是在不同的函数中计算的,而不是在主函数中计算的。我曾尝试在互联网上搜索以解决此问题,但找不到任何相关示例。我在 Windows 10 上使用 PGI 19.10 编译器。需要这方面的帮助。提前致谢