这是关于openacc的问题。 我读了API(v1和v2),并且我不清楚具有相同数组的不同子部分的嵌套数据环境的行为。
代码示例:
#pragma acc data pcopyin(a[0:20])
{
#pragma acc data pcopyin(a[100:20])
{
#pragma acc parallel loop
for(i=0; i<20; i++)
a[i] = i;
a[i+100] = i;
}
}
我的理解是这应该起作用(或者使用两个acc数据部分):
我尝试使用CAPS编译器(v3.3.0,这是我现在唯一可用的测试机器),第二个pragma acc数据返回错误(我的第二个子阵列没有正确的形状) )。 那么我的测试(我猜)会发生在加速器上找到指针“a”,但与之相关的形状([0:20])在我的第二个pragma中是不同的([100:20] )。
这是API中规划的正常行为,还是我的示例应该有效?
此外,如果这应该有效,那么同一个数组的子部分之间是否存在某种连贯性(不知何故,它们将被定位在主机上,我将能够放置[i] + = a我的内核中有[100 + i])?
答案 0 :(得分:1)
目前的测试将查看设备上是否有“a”。因此,当遇到第二数据区域时,“a”已经在设备上但仅部分地。相反,更好的方法是添加指向“a”的指针并在设备上引用此指针。类似的东西:
#include <stdio.h>
int main () {
int a[200];
int *b;
int i;
for(i=0; i<200; i++) a[i] = 0;
b=a+100;
#pragma acc data pcopy(a[0:20])
{
#pragma acc data pcopy(b[0:20])
{
#pragma acc parallel loop
for(i=0; i<20; i++) {
a[i] = i;
b[i] = i;
}
}
}
for(i=0; i<22; i++) printf("%d = %d \n", i, a[i]);
for(i=100; i<122; i++) printf("%d = %d \n", i, a[i]);
return 0;
}
如果您刚刚复制了“a [100:20]”,那么在此范围之外访问将被视为程序员错误。
希望这有帮助, 垫