abhinavgaba wrote:

> I have one big question - why do we need this? If pointer is mapped 
> explicitly, it becomes an attached pointer, which cannot be modified in 
> target region. How we capture/process it, byref or byval, does not matter, we 
> can do whatever is better. So, why do we need to process it byref?

That's a good question. There are multiple reasons.

First, just mapping a pointer does not make it attached. For a pointer to 
become attached, a map has to be on the pointee, like `map(p[0:1])`, and then 
the attachment should only happen when either the pointer is new, or the 
pointee is new on that construct on which the pointee is being mapped. And 
whether an attachment will be successful or not cannot be determined at 
compile-time (unless the user uses OpenMP 6.1's `attach(always)`).

So, a user must be able to access and modify a pointer in a target region, and 
bring it back, just like any variable, as long as it is not attached.

```c
int *p;
#pragma omp target map(tofrom:p) // p is not an attached
  p = (int*) 111;

printf("%d\n", (int) p); // CHECK: 111
```

Even for cases where both the pointer, pointee are mapped, the expectation is 
for the pointer to still be captured by-ref. If the attachment is not supposed 
to happen (based on the conditions mentioned above), then any modifications to 
the pointer have to be brought back if the map-type is from.

```c
int *p = ...;
#pragma omp target map(tofrom:p[0:1]) // p is not attached, since p is not 
present on the device
#pragma omp target map(tofrom:p) // p is not attached, since pointee is not 
mapped on this construct
  p = (int*) 111;

printf("%d\n", (int) p); // CHECK: 111 
```

And irrespective of whether the attachment succeeds or not, a user can assert 
that the address of the pointer in the target region has to match its mapped 
address. e.g.:

```c
int *p;
#pragma omp target enter data map(p)
int64_t mapped_p = (int64_t) omp_get_mapped_ptr(&p);

#pragma omp target map(present,alloc: p) map(p[0:10])
{
 assert(mapped_p == (int64_t) &p && "address of p in device should match the 
mapped address before the region.");
}
```

Additionally, before this change, when we are using PTR_AND_OBJ when both 
pointer/pointee are mapped (which is not correct as it does not follow the 
conditional pointer-attachment), we are capturing the pointer by value. With 
the ATTACH mapping support in 
https://github.com/abhinavgaba/llvm-project/pull/1, we aren't using PTR_AND_OBJ 
anymore when the base-pointer is a non-struct-member pointer variable. We 
instead map the pointer and pointee with independent maps and then attach them 
conditionally. With that, the kernel signature needs to match for `map(p)` and 
`map(p, p[0:1])`, because for both of them, the PARAM should correspond to the 
same `map(p)`.

https://github.com/llvm/llvm-project/pull/145454
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to