7 Commits

Author SHA1 Message Date
Abhinav Gaba
1d1c83ad73
Reland "[OpenMP][Offload] Handle present/to/from when a different entry did alloc/delete." (#184260)
Some tests that were checking for prints inside/outside `target` regions
needed to be updated to work on systems where the ordering wasn't
deterministic.

Reverts llvm/llvm-project#184240
    
Original description from #165494:

-----

OpenMP allows cases like the following:

```c
  int *p1, *p2, x;
  p1 = p2 = &x;
  ...
  #pragma omp target_exit_data map(delete: p1[:]) from(p2[0])
```

Which means, when the runtime encounters the `from` entry, the ref-count
may
not be zero, but it will go down to zero at the end of the current
construct,
which should cause the "from" transfer to happen.

Similarly, a user may have:

```c
  struct S {
    int *p;
  };

  #pragma omp declare_mapper (id1: S s) map(s.p) map(present, alloc: s.p[0:10])
  #pragma omp declare_mapper (id2: S s) map(s.p, s.p[0:10])

  S s1;

 // present-check should fail here
 #pragma omp target_enter_data map(alloc: s.p[0:10]) map(mapper(id1), to: s)
 // "to" should be honored here
 #pragma omp target_enter_data map(alloc: s.p[0:10]) map(mapper(id2), to: s)
```

Where the allocation happens before the "to" entry is encountered by the
runtime. Or, an allocation happens before a "present" entry is
encountered.

To handle cases like this, we need to use the state information of
previously
seen new allocations, deletions, "from" entries, when honoring
`to`/`from`/`present` map entries.

-----
2026-03-02 15:32:30 -08:00
Abhinav Gaba
42a0fbc2c7
Revert "[OpenMP][Offload] Handle present/to/from when a different entry did alloc/delete." (#184240)
Reverts llvm/llvm-project#165494

Some buildbots are not happy about CHECKs enforcing strict ordering of
prints inside/after target regions.
2026-03-02 21:52:20 +00:00
Abhinav Gaba
1a7060a7b0
[OpenMP][Offload] Handle present/to/from when a different entry did alloc/delete. (#165494)
OpenMP allows cases like the following:

```c
  int *p1, *p2, x;
  p1 = p2 = &x;
  ...
  #pragma omp target_exit_data map(delete: p1[:]) from(p2[0])
```

Which means, when the runtime encounters the `from` entry, the ref-count
may not be zero, but it will go down to zero at the end of the current
construct, which should cause the "from" transfer to happen.

Similarly, a user may have:

```c
  struct S {
    int *p;
  };

  #pragma omp declare_mapper (id1: S s) map(s.p) map(present, alloc: s.p[0:10])
  #pragma omp declare_mapper (id2: S s) map(s.p, s.p[0:10])

  S s1;

 // present-check should fail here
 #pragma omp target_enter_data map(alloc: s.p[0:10]) map(mapper(id1), to: s)
 // "to" should be honored here
 #pragma omp target_enter_data map(alloc: s.p[0:10]) map(mapper(id2), to: s)
```

Where the allocation happens before the "to" entry is encountered by the
runtime. Or, an allocation happens before a "present" entry is
encountered.

To handle cases like this, we need to use the state information of
previously seen new allocations, deletions, "from" entries, when
honoring `to`/`from`/`present` map entries.
2026-03-02 13:13:51 -08:00
Abhinav Gaba
c62cd2877c
[OpenMP][Offload] Add LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS to treat attach(auto) as attach(always). (#172382)
This is needed as a way to support older code that was expecting
unconditional attachment to happen for cases like:

```c
  int *p;
  int x;

  #pragma omp targret enter data map(p) // (A)
  #pragma omp target enter data map(x)  // (B)
  p = &x;

  // By default, this does NOT attach p and x
  #pragma omp target enter data map(p[0:0]) // (C)
```

When the environment variable is set, such maps, where both the pointer
and the pointee already have corresponding copies on the device, but are
not attached to one another, will be attached as-if OpenMP 6.1 TR14's
`attach(always)` map-type-modifier was specified on `(C)`.
2025-12-16 15:55:27 -08:00
Abhinav Gaba
5af3fa81cc
[Offload][OpenMP] Support shadow-pointer tracking for Fortran descriptors. (#158370)
This change adds support for saving full contents of attached Fortran
descriptors, and not just their pointee address, in the shadow-pointer
table.

With this, we now support:
* comparing full contents of descriptors to check whether a previous
shadow-pointer entry is stale;
* restoring the full contents of descriptors

And with that, we can now use ATTACH map-types (added in #149036) for
mapping Fortran pointer/allocatable arrays, and array-sections on them.
e.g.:

```f90
  integer, allocatable :: x(:)
  !$omp target enter data map(to: x(:))
```

as:

```
  void* addr_of_pointee = allocated(x) ? &x(1) : nullptr;
  int64_t sizeof_pointee = allocated(x) ? sizeof(x(:)) : 0

  addr_of_pointee,    addr_of_pointee, sizeof_pointee,     TO
  addr_of_descriptor, addr_of_pointee, size_of_descriptor, ATTACH
```
2025-09-15 10:37:38 -07:00
Abhinav Gaba
12769aa728
[Offload] Introduce ATTACH map-type support for pointer attachment. (#149036)
This patch introduces libomptarget support for the ATTACH map-type,
which can be used to implement OpenMP conditional compliant pointer
attachment, based on whether the pointer/pointee is newly mapped on a
given construct.

For example, for the following:

```c
  int *p;
  #pragma omp target enter data map(p[1:10])
```

The following maps can be emitted by clang:
```
  (A)
  &p[0], &p[1], 10 * sizeof(p[1]), TO | FROM
  &p, &p[1], sizeof(p), ATTACH
```

Without this map-type, these two possible maps could be emitted by
clang:
```
  (B)
  &p[0], &p[1], 10 * sizeof(p[1]), TO | FROM

  (C)
  &p, &p[1], 10 * sizeof(p[1]), TO | FROM | PTR_AND_OBJ
````

(B) does not perform any pointer attachment, while (C) also maps the
pointer p, which are both incorrect.

In terms of implementation, maps with the ATTACH map-type are handled
after all other maps have been processed, as it requires knowledge of
which new allocations happened as part of the construct. As per OpenMP
5.0, an attachment should happen only when either the pointer or the
pointee was newly mapped while handling the construct.

Maps with ATTACH map-type-bit do not increase/decrease the ref-count.

With OpenMP 6.1, `attach(always/never)` can be used to force/prevent
attachment. For `attach(always)`, the compiler will insert the ALWAYS
map-type, which would let libomptarget bypass the check about one of the
pointer/pointee being new. With `attach(never)`, the ATTACH map will not
be emitted at all.

The size argument of the ATTACH map-type can specify values greater than
`sizeof(void*)` which can be used to support pointer attachment on
Fortran descriptors. Note that this also requires shadow-pointer
tracking to also support them. That has not been implemented in this
patch.

This was worked upon in coordination with Ravi Narayanaswamy, who has
since retired. Happy retirement, Ravi!

---------

Co-authored-by: Alex Duran <alejandro.duran@intel.com>
2025-08-17 15:17:04 -07:00
Johannes Doerfert
330d8983d2
[Offload] Move /openmp/libomptarget to /offload (#75125)
In a nutshell, this moves our libomptarget code to populate the offload
subproject.

With this commit, users need to enable the new LLVM/Offload subproject
as a runtime in their cmake configuration.
No further changes are expected for downstream code.

Tests and other components still depend on OpenMP and have also not been
renamed. The results below are for a build in which OpenMP and Offload
are enabled runtimes. In addition to the pure `git mv`, we needed to
adjust some CMake files. Nothing is intended to change semantics.

```
ninja check-offload
```
Works with the X86 and AMDGPU offload tests

```
ninja check-openmp
```
Still works but doesn't build offload tests anymore.

```
ls install/lib
```
Shows all expected libraries, incl.
- `libomptarget.devicertl.a`
- `libomptarget-nvptx-sm_90.bc`
- `libomptarget.rtl.amdgpu.so` -> `libomptarget.rtl.amdgpu.so.18git`
- `libomptarget.so` -> `libomptarget.so.18git`

Fixes: https://github.com/llvm/llvm-project/issues/75124

---------

Co-authored-by: Saiyedul Islam <Saiyedul.Islam@amd.com>
2024-04-22 09:51:33 -07:00