Skip to content

[WIP][Offload] Introduce ATTACH map-type support for pointer attachment. #149036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

abhinavgaba
Copy link
Contributor

@abhinavgaba abhinavgaba commented Jul 16, 2025

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:

  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!

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, the two possible maps 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!
Copy link

github-actions bot commented Jul 16, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

// (4) and (1) are both trying to modify the device memory corresponding to
// &p. We need to ensure that (4) happens last.
//
// One possible solution to this could be to insert a "device barrier" before
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adurang, please check if this is a proper description of your suggestion.

@agozillon
Copy link
Contributor

Out of interest, will this change break any of the existing possible mappings clang used to emit (such as B and C in your examples in the description)? I ask as Flang's mappings are based on the way Clang currently handles its mapping, so if this breaks any pre-existing map behaviour, then there's a possibility it'll break a chunk of Flang OpenMP's offload capabilities.

It's of course more than fine if it does, but would be good to know ahead of time if there's things that we'd need to address on the Flang side immediately or if we can more slowly phase in the attach system once this PR has landed :-)

There's a chunk of fortran OpenMP map tests in check-offload (not a comprehensive set, but it is a good cursory view on if anything might be broken by the changeset) that can be ran to help verify if things are reasonably okay.

As an unrelated side note, would be nice if we could align the mapping systems in Flang/Clang one day...

@abhinavgaba
Copy link
Contributor Author

This change will only affect cases where the compiler emits ATTACH maps. So, the existing PTR_AND_OBJ maps still work as-is.

The only potential impact is that we will be keeping track of any new allocations and their sizes in a hashmap. But that information will not be used if no ATTACH map is encountered.

The initial PR for emitting ATTACH maps for clang (abhinavgaba#1), which this change was verified with, only uses the ATTACH maps for when the base-pointer that is eligible for attachment is a scalar variable that's not a member of a struct (like the example in the description). For other cases, like: int **p; ... map(p[0][1]), clang still uses PTR_AND_OBJ maps for now.

And the map from case B is fairly common. Even for case A, it's used as the first map. And it's used for mapping array-elements/array-sections based on arrays, like int a[10]; ... map(a[1:2])

@agozillon
Copy link
Contributor

This change will only affect cases where the compiler emits ATTACH maps. So, the existing PTR_AND_OBJ maps still work as-is.

The only potential impact is that we will be keeping track of any new allocations and their sizes in a hashmap. But that information will not be used if no ATTACH map is encountered.

The initial PR for emitting ATTACH maps for clang (abhinavgaba#1), which this change was verified with, only uses the ATTACH maps for when the base-pointer that is eligible for attachment is a scalar variable that's not a member of a struct (like the example in the description). For other cases, like: int **p; ... map(p[0][1]), clang still uses PTR_AND_OBJ maps for now.

And the map from case B is fairly common. Even for case A, it's used as the first map. And it's used for mapping array-elements/array-sections based on arrays, like int a[10]; ... map(a[1:2])

Thank you very much for clarifying! Excited for the addition, just not so much any potential work moving flang over to it ;-) but has to be done and I imagine it'll give us more flexibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants