Skip to content

Commit f117881

Browse files
authored
[Flang][OpenMP][MLIR] Implement close, present and ompx_hold modifiers for Flang maps (#129586)
This PR adds an initial implementation for the map modifiers close, present and ompx_hold, primarily just required adding the appropriate map type flags to the map type bits. In the case of ompx_hold it required adding the map type to the OpenMP dialect. Close has a bit of a problem when utilised with the ALWAYS map type on descriptors, so it is likely we'll have to make sure close and always are not applied to the descriptor simultaneously in the future when we apply always to the descriptors to facilitate movement of descriptor information to device for consistency, however, we may find an alternative to this with further investigation. For the moment, it is a TODO/Note to keep track of it.
1 parent 8dd160f commit f117881

17 files changed

+293
-75
lines changed

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,15 +1029,15 @@ bool ClauseProcessor::processMap(
10291029
}
10301030

10311031
if (typeMods) {
1032+
// TODO: Still requires "self" modifier, an OpenMP 6.0+ feature
10321033
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Always))
10331034
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
1034-
// Diagnose unimplemented map-type-modifiers.
1035-
if (llvm::any_of(*typeMods, [](Map::MapTypeModifier m) {
1036-
return m != Map::MapTypeModifier::Always;
1037-
})) {
1038-
TODO(currentLocation, "Map type modifiers (other than 'ALWAYS')"
1039-
" are not implemented yet");
1040-
}
1035+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Present))
1036+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
1037+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Close))
1038+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
1039+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::OmpxHold))
1040+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD;
10411041
}
10421042

10431043
if (iterator) {
@@ -1073,19 +1073,20 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
10731073
auto callbackFn = [&](const auto &clause, const parser::CharBlock &source) {
10741074
mlir::Location clauseLocation = converter.genLocation(source);
10751075
const auto &[expectation, mapper, iterator, objects] = clause.t;
1076-
// TODO Support motion modifiers: present, mapper, iterator.
1077-
if (expectation) {
1078-
TODO(clauseLocation, "PRESENT modifier is not supported yet");
1079-
} else if (mapper) {
1076+
1077+
// TODO Support motion modifiers: mapper, iterator.
1078+
if (mapper) {
10801079
TODO(clauseLocation, "Mapper modifier is not supported yet");
10811080
} else if (iterator) {
10821081
TODO(clauseLocation, "Iterator modifier is not supported yet");
10831082
}
1084-
constexpr llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
1083+
1084+
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
10851085
std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
10861086
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO
10871087
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
1088-
1088+
if (expectation && *expectation == omp::clause::To::Expectation::Present)
1089+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
10891090
processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
10901091
parentMemberIndices, result.mapVars, mapSymbols);
10911092
};

flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,15 @@ class MapInfoFinalizationPass
243243
/// where necessary, although it does not seem strictly required.
244244
unsigned long getDescriptorMapType(unsigned long mapTypeFlag,
245245
mlir::Operation *target) {
246+
using mapFlags = llvm::omp::OpenMPOffloadMappingFlags;
246247
if (llvm::isa_and_nonnull<mlir::omp::TargetExitDataOp,
247248
mlir::omp::TargetUpdateOp>(target))
248249
return mapTypeFlag;
249250

250-
bool hasImplicitMap =
251-
(llvm::omp::OpenMPOffloadMappingFlags(mapTypeFlag) &
252-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT) ==
253-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
254-
255-
return llvm::to_underlying(
256-
hasImplicitMap
257-
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO |
258-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT
259-
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
251+
mapFlags flags = mapFlags::OMP_MAP_TO |
252+
(mapFlags(mapTypeFlag) &
253+
(mapFlags::OMP_MAP_IMPLICIT | mapFlags::OMP_MAP_CLOSE));
254+
return llvm::to_underlying(flags);
260255
}
261256

262257
mlir::omp::MapInfoOp genDescriptorMemberMaps(mlir::omp::MapInfoOp op,

flang/test/Integration/OpenMP/map-types-and-sizes.f90

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
! added to this directory and sub-directories.
77
!===----------------------------------------------------------------------===!
88

9-
!RUN: %flang_fc1 -emit-llvm -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -flang-deprecated-no-hlfir %s -o - | FileCheck %s
9+
!RUN: %flang_fc1 -emit-llvm -fopenmp -fopenmp-version=51 -fopenmp-targets=amdgcn-amd-amdhsa -flang-deprecated-no-hlfir %s -o - | FileCheck %s
1010

1111
!===============================================================================
1212
! Check MapTypes for target implicit captures
@@ -39,6 +39,37 @@ subroutine mapType_ptr
3939
!$omp end target
4040
end subroutine mapType_ptr
4141

42+
!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4]
43+
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4097]
44+
subroutine map_present_target_data
45+
integer :: x
46+
!$omp target data map(present, to: x)
47+
!$omp end target data
48+
end subroutine
49+
50+
!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4]
51+
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4097]
52+
subroutine map_present_update
53+
integer :: x
54+
!$omp target update to(present: x)
55+
end subroutine
56+
57+
!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4]
58+
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 1027]
59+
subroutine map_close
60+
integer :: x
61+
!$omp target data map(close, tofrom: x)
62+
!$omp end target data
63+
end subroutine
64+
65+
!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 4]
66+
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 8195]
67+
subroutine map_ompx_hold
68+
integer :: x
69+
!$omp target data map(ompx_hold, tofrom: x)
70+
!$omp end target data
71+
end subroutine
72+
4273
!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [4 x i64] [i64 0, i64 24, i64 8, i64 0]
4374
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [4 x i64] [i64 32, i64 281474976711169, i64 281474976711171, i64 281474976711187]
4475
subroutine mapType_allocatable

flang/test/Lower/OpenMP/Todo/from-expectation-modifier.f90

Lines changed: 0 additions & 8 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/map-modifiers-close.f90

Lines changed: 0 additions & 10 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/map-modifiers-ompxhold.f90

Lines changed: 0 additions & 11 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/map-modifiers-present.f90

Lines changed: 0 additions & 11 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/to-expectation-modifier.f90

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=51 %s -o - | FileCheck %s
2+
3+
subroutine map_present_target_data
4+
integer :: x
5+
!CHECK: %[[MAP:.*]] = omp.map.info {{.*}} map_clauses(present, to) {{.*}} {name = "x"}
6+
!CHECK: omp.target_data map_entries(%[[MAP]] : {{.*}}) {
7+
!$omp target data map(present, to: x)
8+
!$omp end target data
9+
end subroutine
10+
11+
subroutine map_present_update
12+
integer :: x
13+
!CHECK: %[[MAP:.*]] = omp.map.info {{.*}} map_clauses(present, to) {{.*}} {name = "x"}
14+
!CHECK: omp.target_update map_entries(%[[MAP]] : {{.*}})
15+
!$omp target update to(present: x)
16+
end subroutine
17+
18+
subroutine map_close
19+
integer :: x
20+
!CHECK: %[[MAP:.*]] = omp.map.info {{.*}} map_clauses(close, tofrom) {{.*}} {name = "x"}
21+
!CHECK: omp.target_data map_entries(%[[MAP]] : {{.*}}) {
22+
!$omp target data map(close, tofrom: x)
23+
!$omp end target data
24+
end subroutine
25+
26+
subroutine map_ompx_hold
27+
integer :: x
28+
!CHECK: %[[MAP:.*]] = omp.map.info {{.*}} map_clauses(ompx_hold, tofrom) {{.*}} {name = "x"}
29+
!CHECK: omp.target_data map_entries(%[[MAP]] : {{.*}}) {
30+
!$omp target data map(ompx_hold, tofrom: x)
31+
!$omp end target data
32+
end subroutine

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,8 +1458,8 @@ uint64_t mapTypeToBitFlag(uint64_t value,
14581458
/// Parses a map_entries map type from a string format back into its numeric
14591459
/// value.
14601460
///
1461-
/// map-clause = `map_clauses ( ( `(` `always, `? `close, `? `present, `? (
1462-
/// `to` | `from` | `delete` `)` )+ `)` )
1461+
/// map-clause = `map_clauses ( ( `(` `always, `? `implicit, `? `ompx_hold, `?
1462+
/// `close, `? `present, `? ( `to` | `from` | `delete` `)` )+ `)` )
14631463
static ParseResult parseMapClause(OpAsmParser &parser, IntegerAttr &mapType) {
14641464
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
14651465
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
@@ -1477,6 +1477,9 @@ static ParseResult parseMapClause(OpAsmParser &parser, IntegerAttr &mapType) {
14771477
if (mapTypeMod == "implicit")
14781478
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
14791479

1480+
if (mapTypeMod == "ompx_hold")
1481+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD;
1482+
14801483
if (mapTypeMod == "close")
14811484
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
14821485

@@ -1526,6 +1529,9 @@ static void printMapClause(OpAsmPrinter &p, Operation *op,
15261529
if (mapTypeToBitFlag(mapTypeBits,
15271530
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT))
15281531
mapTypeStrs.push_back("implicit");
1532+
if (mapTypeToBitFlag(mapTypeBits,
1533+
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD))
1534+
mapTypeStrs.push_back("ompx_hold");
15291535
if (mapTypeToBitFlag(mapTypeBits,
15301536
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE))
15311537
mapTypeStrs.push_back("close");

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,12 @@ func.func @omp_target_data (%if_cond : i1, %device : si32, %device_ptr: memref<i
825825
%mapv6 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""}
826826
omp.target_exit_data if(%if_cond) device(%device : si32) nowait map_entries(%mapv6 : memref<?xi32>)
827827

828+
// CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(ompx_hold, to) capture(ByRef) -> memref<?xi32> {name = ""}
829+
// CHECK: omp.target_data map_entries(%[[MAP_A]] : memref<?xi32>)
830+
%mapv7 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(ompx_hold, to) capture(ByRef) -> memref<?xi32> {name = ""}
831+
omp.target_data map_entries(%mapv7 : memref<?xi32>) {
832+
omp.terminator
833+
}
828834
return
829835
}
830836

offload/test/Inputs/target-use-dev-ptr.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ int check_result(int *host_ptr, int *dev_ptr) {
2121
return 0;
2222
}
2323
}
24+
25+
int check_equality(void *host_ptr, void *dev_ptr) {
26+
return dev_ptr == host_ptr;
27+
}

offload/test/offloading/fortran/target-use-dev-ptr.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ end function get_ptr
1818
integer(c_int) function check_result(host, dev) BIND(C)
1919
USE, intrinsic :: iso_c_binding
2020
implicit none
21-
type(c_ptr), intent(in) :: host, dev
21+
type(c_ptr), value, intent(in) :: host, dev
2222
end function check_result
2323
end interface
2424

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
! Basic test that checks that when ompx_hold is in use we cannot delete the data
2+
! until the ompx_hold falls out of scope, and verifies this via the utilisation of
3+
! present.
4+
! REQUIRES: flang, amdgpu
5+
! RUN: %libomptarget-compile-fortran-generic
6+
! RUN: %libomptarget-run-fail-generic 2>&1 \
7+
! RUN: | %fcheck-generic
8+
9+
program ompx_hold
10+
implicit none
11+
integer :: presence_check
12+
13+
!CHECK-NOT: omptarget message: device mapping required by 'present' map type modifier does not exist for host address{{.*}}
14+
!$omp target data map(ompx_hold, tofrom: presence_check)
15+
!$omp target exit data map(delete: presence_check)
16+
!$omp target map(present, tofrom: presence_check)
17+
presence_check = 10
18+
!$omp end target
19+
!$omp end target data
20+
21+
!CHECK: omptarget message: device mapping required by 'present' map type modifier does not exist for host address{{.*}}
22+
!$omp target data map(tofrom: presence_check)
23+
!$omp target exit data map(delete: presence_check)
24+
!$omp target map(present, tofrom: presence_check)
25+
presence_check = 20
26+
!$omp end target
27+
!$omp end target data
28+
29+
end program
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
! This checks that the basic functionality of map type present functions as
2+
! expected, emitting an omptarget error when the data is not present.
3+
! REQUIRES: flang, amdgpu
4+
! RUN: %libomptarget-compile-fortran-generic
5+
! RUN: %libomptarget-run-fail-generic 2>&1 \
6+
! RUN: | %fcheck-generic
7+
8+
! NOTE: This should intentionally fatal error in omptarget as it's not
9+
! present, as is intended.
10+
subroutine target_data_not_present()
11+
double precision, dimension(:), allocatable :: arr
12+
integer, parameter :: N = 16
13+
integer :: i
14+
15+
allocate(arr(N))
16+
17+
!$omp target data map(present,alloc:arr)
18+
19+
!$omp target
20+
do i = 1,N
21+
arr(i) = 42.0d0
22+
end do
23+
!$omp end target
24+
25+
!$omp end target data
26+
27+
deallocate(arr)
28+
return
29+
end subroutine
30+
31+
program map_present
32+
implicit none
33+
call target_data_not_present()
34+
end program
35+
36+
!CHECK: omptarget message: device mapping required by 'present' map type modifier does not exist for host address{{.*}}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
! This checks that the basic functionality of map type present functions as
2+
! expected, no-op'ng when present
3+
! REQUIRES: flang, amdgpu
4+
! RUN: %libomptarget-compile-fortran-run-and-check-generic
5+
6+
subroutine target_data_present()
7+
double precision, dimension(:), allocatable :: arr
8+
integer, parameter :: N = 16
9+
integer :: i
10+
11+
allocate(arr(N))
12+
13+
arr(:) = 10.0d0
14+
15+
!$omp target data map(tofrom:arr)
16+
17+
!$omp target data map(present,alloc:arr)
18+
19+
!$omp target
20+
do i = 1,N
21+
arr(i) = 42.0d0
22+
end do
23+
!$omp end target
24+
25+
!$omp end target data
26+
27+
!$omp end target data
28+
29+
print *, arr
30+
31+
deallocate(arr)
32+
33+
return
34+
end subroutine
35+
36+
program map_present
37+
implicit none
38+
call target_data_present()
39+
end program
40+
41+
!CHECK: 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42. 42.

0 commit comments

Comments
 (0)