Question

There are 2 ways to have a global array: Use a pointer and malloc, or just define it as an array:

#omp declare target
int gArray[10];
int* gVals /*somewhere later:*/ = malloc(10*sizeof(int));
#omp end declare target

I though, these where equivalent in handling but just discovered a huge difference: When I map them to a target, only the gVals will be actually mapped. If I want the values of gArray on my device I have to use "target update". Is this a bug in the current Intel compiler or is this covered in the spec? Could not find anything specific to this.

BTW: Using a local array (no declare target) works as intended.

Test code:

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%d\n",gArray[0],gArray[1],gVals[0],gVals[1]);
  gArray[1]=2;gVals[1]=2;
}
printf("gArrayHost(1212): %d%d%d%d\n",gArray[0],gArray[1],gVals[0],gVals[1]);
Was it helpful?

Solution

declare target puts the enclosed variables in the initial device context (2.9.4 -- declare target Directive):

If a list item is a variable then the original variable is mapped to a corresponding variable in the initial device data environment for all devices. If the original variable is initialized, the corresponding variable in the device data environment is initialized with the same value.

Your gArray variable is not initialised, therefore the device copy is not initialised either. But it becomes part of the initial device data environment. The map clause then has no effect on gArray because (2.14.5 -- map Clause):

If a corresponding list item of the original list item is in the enclosing device data environment, the new device data environment uses the corresponding list item from the enclosing device data environment. No additional storage is allocated in the new device data environment and neither initialization nor assignment is performed, regardless of the map-type that is specified.

The initial device data environment is enclosing in respect to the new data environment created by the target directive.

As to gVals, the following apply (2.14.5 -- map Clause):

If the type of the variable appearing in an array section is pointer, reference to array, or reference to pointer then the variable is implicitly treated as if it had appeared in a map clause with a map-type of alloc. The corresponding variable is assigned the address of the storage location of the corresponding array section in the new device data environment.

Therefore it is not a bug in the Intel compiler but exactly the standard-described behaviour.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top