Skip to content

Commit c62cd28

Browse files
authored
[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)`.
1 parent ffe973a commit c62cd28

File tree

5 files changed

+94
-1
lines changed

5 files changed

+94
-1
lines changed

offload/include/OpenMP/Mapping.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class MappingConfig {
3333
MappingConfig() {
3434
BoolEnvar ForceAtomic = BoolEnvar("LIBOMPTARGET_MAP_FORCE_ATOMIC", true);
3535
UseEventsForAtomicTransfers = ForceAtomic;
36+
37+
BoolEnvar TreatAttachAutoAsAlwaysEnvar(
38+
"LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS", false);
39+
TreatAttachAutoAsAlways = TreatAttachAutoAsAlwaysEnvar;
3640
}
3741

3842
public:
@@ -44,6 +48,13 @@ class MappingConfig {
4448
/// Flag to indicate if we use events to ensure the atomicity of
4549
/// map clauses or not. Can be modified with an environment variable.
4650
bool UseEventsForAtomicTransfers = true;
51+
52+
/// Flag to indicate if attach(auto) should be treated as attach(always).
53+
/// This forces pointer attachments to occur between a pointer an a pointee,
54+
/// for something like `map(p[:])` even when both were already present on the
55+
/// device before encountering the construct. Can be modified with
56+
/// an environment variable.
57+
bool TreatAttachAutoAsAlways = false;
4758
};
4859

4960
/// Information about shadow pointers.

offload/libomptarget/omptarget.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,11 @@ int processAttachEntries(DeviceTy &Device, AttachInfoTy &AttachInfo,
779779
ODBG(ODT_Mapping) << "Processing " << AttachInfo.AttachEntries.size()
780780
<< " deferred ATTACH map entries";
781781

782+
bool TreatAttachAutoAsAlways = MappingConfig::get().TreatAttachAutoAsAlways;
783+
if (TreatAttachAutoAsAlways)
784+
ODBG(ODT_Mapping) << "Treating ATTACH(auto) as ATTACH(always) because "
785+
<< "LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS is true";
786+
782787
int Ret = OFFLOAD_SUCCESS;
783788
bool IsFirstPointerAttachment = true;
784789
for (size_t EntryIdx = 0; EntryIdx < AttachInfo.AttachEntries.size();
@@ -799,7 +804,8 @@ int processAttachEntries(DeviceTy &Device, AttachInfoTy &AttachInfo,
799804
<< ", PtrSize=" << PtrSize << ", MapType=0x"
800805
<< llvm::utohexstr(MapType);
801806

802-
const bool IsAttachAlways = MapType & OMP_TGT_MAPTYPE_ALWAYS;
807+
bool IsAttachAlways =
808+
(MapType & OMP_TGT_MAPTYPE_ALWAYS) || TreatAttachAutoAsAlways;
803809

804810
// Lambda to check if a pointer was newly allocated
805811
auto WasNewlyAllocated = [&](void *Ptr, const char *PtrName) {

offload/test/lit.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ if 'ROCR_VISIBLE_DEVICES' in os.environ:
2121
if 'LIBOMPTARGET_DEBUG' in os.environ:
2222
config.environment['LIBOMPTARGET_DEBUG'] = os.environ['LIBOMPTARGET_DEBUG']
2323

24+
# Allow running tests with attach auto treated as always
25+
if 'LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS' in os.environ:
26+
config.environment['LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS'] = os.environ['LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS']
27+
2428
# Allow running the tests with nextgen plugins when available
2529
if 'LIBOMPTARGET_NEXTGEN_PLUGINS' in os.environ:
2630
config.environment['LIBOMPTARGET_NEXTGEN_PLUGINS'] = os.environ['LIBOMPTARGET_NEXTGEN_PLUGINS']
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %libomptarget-compile-generic
2+
//
3+
// RUN: env LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS=1 \
4+
// RUN: env LIBOMPTARGET_DEBUG=1 \
5+
// RUN: %libomptarget-run-generic 2>&1 \
6+
// RUN: | %fcheck-generic -check-prefix=DEBUG
7+
//
8+
// RUN: env LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS=1 \
9+
// RUN: %libomptarget-run-generic 2>&1 \
10+
// RUN: | %fcheck-generic -check-prefix=CHECK
11+
12+
// Ensure that under LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS, the pointer
13+
// attachment for map(p[0:0]) happens as if the user had specified the
14+
// attach(always) map-type-modifier.
15+
16+
#include <omp.h>
17+
#include <stdio.h>
18+
19+
int x[10];
20+
int *p;
21+
22+
void f1() {
23+
#pragma omp target enter data map(to : p)
24+
#pragma omp target enter data map(to : x)
25+
26+
p = &x[0];
27+
int **p_mappedptr = (int **)omp_get_mapped_ptr(&p, omp_get_default_device());
28+
int *x0_mappedptr =
29+
(int *)omp_get_mapped_ptr(&x[0], omp_get_default_device());
30+
int *p0_deviceaddr = NULL;
31+
32+
printf("p_mappedptr %s null\n", p_mappedptr == (int **)NULL ? "==" : "!=");
33+
printf("x0_mappedptr %s null\n", x0_mappedptr == (int *)NULL ? "==" : "!=");
34+
// CHECK: p_mappedptr != null
35+
// CHECK: x0_mappedptr != null
36+
37+
#pragma omp target enter data map(to : p[0 : 0]) // Implies: attach(auto)
38+
// clang-format off
39+
// DEBUG: omptarget --> Treating ATTACH(auto) as ATTACH(always) because LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS is true
40+
// clang-format on
41+
42+
#pragma omp target map(present, alloc : p) map(from : p0_deviceaddr)
43+
{
44+
p0_deviceaddr = &p[0];
45+
}
46+
47+
printf("p0_deviceaddr %s x0_mappedptr\n",
48+
p0_deviceaddr == x0_mappedptr ? "==" : "!=");
49+
// CHECK: p0_deviceaddr == x0_mappedptr
50+
51+
#pragma omp target exit data map(delete : x, p)
52+
}
53+
54+
int main() { f1(); }

openmp/docs/design/Runtimes.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ variables is defined below.
735735
* ``LIBOMPTARGET_STACK_SIZE=<Num>``
736736
* ``LIBOMPTARGET_SHARED_MEMORY_SIZE=<Num>``
737737
* ``LIBOMPTARGET_MAP_FORCE_ATOMIC=[TRUE/FALSE] (default TRUE)``
738+
* ``LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS=[TRUE/FALSE] (default FALSE)``
738739
* ``LIBOMPTARGET_JIT_OPT_LEVEL={0,1,2,3} (default 3)``
739740
* ``LIBOMPTARGET_JIT_SKIP_OPT=[TRUE/FALSE] (default FALSE)``
740741
* ``LIBOMPTARGET_JIT_REPLACEMENT_OBJECT=<in:Filename> (object file)``
@@ -1088,6 +1089,23 @@ value of the ``LIBOMPTARGET_MAP_FORCE_ATOMIC`` environment variable.
10881089
The default behavior of LLVM 14 is to force atomic maps clauses, prior versions
10891090
of LLVM did not.
10901091

1092+
LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS
1093+
"""""""""""""""""""""""""""""""""""""""""
1094+
1095+
By default, OpenMP attach operations only perform pointer attachment
1096+
when mapping an expression with a base-pointer/base-referring-pointer,
1097+
when either the pointer or the pointee was newly allocated on a
1098+
map-entering directive (aka ``attach(auto)`` as per OpenMP 6.1 TR14).
1099+
1100+
When ``LIBOMPTARGET_TREAT_ATTACH_AUTO_AS_ALWAYS`` is set to ``true``,
1101+
ATTACH map entries without the ALWAYS flag are implicitly treated as if
1102+
the ALWAYS flag was set. This forces pointer attachments to occur even when
1103+
the pointee/pointer were not newly allocated (similar to OpenMP 6.1
1104+
TR14's ``attach(always)`` map-type-modifier), thereby treating
1105+
``attach(auto))`` as ``attach(always)``. This can be used for
1106+
experimentation, or as a workaround for programs compiled without
1107+
``-fopenmp-version=61``.
1108+
10911109
.. _libomptarget_jit_opt_level:
10921110

10931111
LIBOMPTARGET_JIT_OPT_LEVEL

0 commit comments

Comments
 (0)