OMP 目标中全局数组(malloc 与静态)的不同处理方式


有两种

方法可以拥有全局数组:使用指针和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条款):

如果出现在数组节中的变量的类型是指针、对数组的引用或对指针的引用,则该变量将隐式处理为好像它出现在映射类型allocmap 子句中。在新设备数据环境中,为相应的变量分配相应数组部分的存储位置的地址。

因此,这不是英特尔编译器中的错误,而正是标准描述的行为。

最新更新