方法可以拥有全局数组:使用指针和malloc,或者只是将其定义为数组:
#omp declare target
int gArray[10];
int* gVals /*somewhere later:*/ = malloc(10*sizeof(int));
#omp end declare target
我虽然,这些在处理上等效,但只是发现了一个巨大的差异:当我将它们映射到目标时,实际上只会映射 gVal。如果我想要设备上的gArray值,则必须使用"目标更新"。这是当前英特尔编译器中的错误,还是规范中涵盖了此错误?找不到任何具体的东西。
顺便说一句:使用本地数组(没有声明目标)可以按预期工作。
测试代码:
for(i=0;i<ct;i++){
gArray[i]=1;gVals[i]=1;
}
#pragma omp target map(gArray[0:2],gVals[0:2])
{
printf("gArrayTarget(1111): %d%d%d%dn",gArray[0],gArray[1],gVals[0],gVals[1]);
gArray[1]=2;gVals[1]=2;
}
printf("gArrayHost(1212): %d%d%d%dn",gArray[0],gArray[1],gVals[0],gVals[1]);
>declare target
将包含的变量放在初始设备上下文中(2.9.4 -- declare target
指令):
如果列表项是变量,则原始变量将映射到相应的 所有设备的初始设备数据环境中的变量。初始化原始变量后,设备数据环境中的对应变量将初始化为相同值。
gArray
变量未初始化,因此设备副本也不会初始化。但它成为初始设备数据环境的一部分。因此,map
条款对gArray
没有影响,因为(2.14.5 -- map
条款):
如果原始列表项的相应列表项位于封闭设备数据环境中初始设备数据环境相对于,则新设备数据环境将使用封闭设备数据环境中的相应列表项。无论指定的映射类型如何,都不会在新设备数据环境中分配额外的存储,也不会执行初始化或分配。
target
指令创建的新数据环境进行封闭。
至于gVals
,以下适用(2.14.5 -- map
条款):
如果出现在数组节中的变量的类型是指针、对数组的引用或对指针的引用,则该变量将隐式处理为好像它出现在映射类型为
alloc
的map
子句中。在新设备数据环境中,为相应的变量分配相应数组部分的存储位置的地址。
因此,这不是英特尔编译器中的错误,而正是标准描述的行为。