Skip to content

Commit 79d9ebb

Browse files
committed
[Flang][OpenMP][MLIR] Implement close, present and ompx_hold modifiers for Flang maps
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 5d89123 commit 79d9ebb

17 files changed

+301
-72
lines changed

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,15 +1093,16 @@ bool ClauseProcessor::processMap(
10931093
}
10941094

10951095
if (typeMods) {
1096+
// TODO: Still requires "self" modifier, the latter which is OpenMP 6.0+
1097+
// and requires adding to the parser/semantic pipeline before here.
10961098
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Always))
10971099
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
1098-
// Diagnose unimplemented map-type-modifiers.
1099-
if (llvm::any_of(*typeMods, [](Map::MapTypeModifier m) {
1100-
return m != Map::MapTypeModifier::Always;
1101-
})) {
1102-
TODO(currentLocation, "Map type modifiers (other than 'ALWAYS')"
1103-
" are not implemented yet");
1104-
}
1100+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Present))
1101+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
1102+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Close))
1103+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
1104+
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::OmpxHold))
1105+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD;
11051106
}
11061107

11071108
if (iterator) {
@@ -1137,19 +1138,20 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
11371138
auto callbackFn = [&](const auto &clause, const parser::CharBlock &source) {
11381139
mlir::Location clauseLocation = converter.genLocation(source);
11391140
const auto &[expectation, mapper, iterator, objects] = clause.t;
1140-
// TODO Support motion modifiers: present, mapper, iterator.
1141-
if (expectation) {
1142-
TODO(clauseLocation, "PRESENT modifier is not supported yet");
1143-
} else if (mapper) {
1141+
1142+
// TODO Support motion modifiers: mapper, iterator.
1143+
if (mapper) {
11441144
TODO(clauseLocation, "Mapper modifier is not supported yet");
11451145
} else if (iterator) {
11461146
TODO(clauseLocation, "Iterator modifier is not supported yet");
11471147
}
1148-
constexpr llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
1148+
1149+
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
11491150
std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
11501151
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO
11511152
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
1152-
1153+
if (expectation && *expectation == omp::clause::To::Expectation::Present)
1154+
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
11531155
processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
11541156
parentMemberIndices, result.mapVars, mapSymbols);
11551157
};

flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,19 @@ class MapInfoFinalizationPass
247247
mlir::omp::TargetUpdateOp>(target))
248248
return mapTypeFlag;
249249

250-
bool hasImplicitMap =
251-
(llvm::omp::OpenMPOffloadMappingFlags(mapTypeFlag) &
252-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT) ==
250+
llvm::omp::OpenMPOffloadMappingFlags implicit =
251+
llvm::omp::OpenMPOffloadMappingFlags(mapTypeFlag) &
253252
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
254253

254+
llvm::omp::OpenMPOffloadMappingFlags close =
255+
llvm::omp::OpenMPOffloadMappingFlags(mapTypeFlag) &
256+
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
257+
258+
// TODO/FIXME: When we apply ALWAYS (an internal non-user specified always)
259+
// to the descriptor, we must remove it when CLOSE is applied, as otherwise
260+
// it'll break certain edge cases.
255261
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);
262+
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | implicit | close);
260263
}
261264

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

0 commit comments

Comments
 (0)