Skip to content

Commit 8afea0d

Browse files
authored
[OpenMP][MLIR] Preserve to/from flags in mapper base entry for mappers (#159799)
With declare mapper, the parent base entry was emitted as `TARGET_PARAM` only. The mapper received a map-type without `to/from`, causing components to degrade to `alloc`-only (no copies), breaking allocatable payload mapping. This PR preserves the map-type bits from the parent. This fixes #156466.
1 parent 6e977aa commit 8afea0d

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,11 +4089,30 @@ static llvm::omp::OpenMPOffloadMappingFlags mapParentWithMembers(
40894089
assert(!ompBuilder.Config.isTargetDevice() &&
40904090
"function only supported for host device codegen");
40914091

4092-
// Map the first segment of our structure
4093-
combinedInfo.Types.emplace_back(
4092+
// Map the first segment of the parent. If a user-defined mapper is attached,
4093+
// include the parent's to/from-style bits (and common modifiers) in this
4094+
// base entry so the mapper receives correct copy semantics via its 'type'
4095+
// parameter. Also keep TARGET_PARAM when required for kernel arguments.
4096+
llvm::omp::OpenMPOffloadMappingFlags baseFlag =
40944097
isTargetParams
40954098
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM
4096-
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE);
4099+
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
4100+
4101+
// Detect if this mapping uses a user-defined mapper.
4102+
bool hasUserMapper = mapData.Mappers[mapDataIndex] != nullptr;
4103+
if (hasUserMapper) {
4104+
using mapFlags = llvm::omp::OpenMPOffloadMappingFlags;
4105+
// Preserve relevant map-type bits from the parent clause. These include
4106+
// the copy direction (TO/FROM), as well as commonly used modifiers that
4107+
// should be visible to the mapper for correct behaviour.
4108+
mapFlags parentFlags = mapData.Types[mapDataIndex];
4109+
mapFlags preserve = mapFlags::OMP_MAP_TO | mapFlags::OMP_MAP_FROM |
4110+
mapFlags::OMP_MAP_ALWAYS | mapFlags::OMP_MAP_CLOSE |
4111+
mapFlags::OMP_MAP_PRESENT | mapFlags::OMP_MAP_OMPX_HOLD;
4112+
baseFlag |= (parentFlags & preserve);
4113+
}
4114+
4115+
combinedInfo.Types.emplace_back(baseFlag);
40974116
combinedInfo.DevicePointers.emplace_back(
40984117
mapData.DevicePointers[mapDataIndex]);
40994118
combinedInfo.Mappers.emplace_back(mapData.Mappers[mapDataIndex]);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
! This test validates that declare mapper for a derived type with an
2+
! allocatable component preserves TO/FROM semantics for the component,
3+
! ensuring the payload is copied back to the host on target exit.
4+
5+
! REQUIRES: flang, amdgpu
6+
7+
! RUN: %libomptarget-compile-fortran-run-and-check-generic
8+
9+
program target_declare_mapper_allocatable
10+
implicit none
11+
12+
type :: real_t
13+
real, allocatable :: real_arr(:)
14+
end type real_t
15+
16+
! Map the allocatable array payload via a named mapper.
17+
!$omp declare mapper (xyz : real_t :: t) map(tofrom: t%real_arr)
18+
19+
type(real_t) :: r
20+
integer :: i
21+
logical :: ok
22+
23+
allocate(r%real_arr(10))
24+
r%real_arr = 1.0
25+
26+
!$omp target map(mapper(xyz), tofrom: r)
27+
do i = 1, size(r%real_arr)
28+
r%real_arr(i) = 3.0
29+
end do
30+
!$omp end target
31+
32+
ok = .true.
33+
do i = 1, size(r%real_arr)
34+
if (r%real_arr(i) /= 3.0) ok = .false.
35+
end do
36+
if (ok) then
37+
print *, "Test passed!"
38+
else
39+
print *, "Test failed!"
40+
do i = 1, size(r%real_arr)
41+
print *, r%real_arr(i)
42+
end do
43+
end if
44+
45+
deallocate(r%real_arr)
46+
end program target_declare_mapper_allocatable
47+
48+
! CHECK: Test passed!

0 commit comments

Comments
 (0)