Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion flang/lib/Lower/OpenMP/ClauseProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,11 @@ bool ClauseProcessor::processIsDevicePtr(
[&](const omp::clause::IsDevicePtr &clause,
const parser::CharBlock &source) {
mlir::Location location = converter.genLocation(source);
// Force a map so the descriptor is materialized on the device with the
// device address inside.
mlir::omp::ClauseMapFlags mapTypeBits =
mlir::omp::ClauseMapFlags::is_device_ptr;
mlir::omp::ClauseMapFlags::is_device_ptr |
mlir::omp::ClauseMapFlags::to;
processMapObjects(stmtCtx, location, clause.v, mapTypeBits,
parentMemberIndices, result.isDevicePtrVars,
isDeviceSyms);
Expand Down
9 changes: 9 additions & 0 deletions flang/test/Integration/OpenMP/map-types-and-sizes.f90
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ subroutine mapType_array
!$omp end target
end subroutine mapType_array

!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 8]
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 33]
subroutine mapType_is_device_ptr
use iso_c_binding, only : c_ptr
type(c_ptr) :: p
!$omp target is_device_ptr(p)
!$omp end target
end subroutine mapType_is_device_ptr

!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [4 x i64] [i64 0, i64 24, i64 8, i64 0]
!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [4 x i64] [i64 32, i64 281474976711169, i64 281474976711171, i64 281474976711187]
subroutine mapType_ptr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
op.getInReductionSyms())
result = todo("in_reduction");
};
auto checkIsDevicePtr = [&todo](auto op, LogicalResult &result) {
if (!op.getIsDevicePtrVars().empty())
result = todo("is_device_ptr");
};
auto checkLinear = [&todo](auto op, LogicalResult &result) {
if (!op.getLinearVars().empty() || !op.getLinearStepVars().empty())
result = todo("linear");
Expand Down Expand Up @@ -444,7 +440,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
checkBare(op, result);
checkDevice(op, result);
checkInReduction(op, result);
checkIsDevicePtr(op, result);
})
.Default([](Operation &) {
// Assume all clauses for an operation can be translated unless they are
Expand Down Expand Up @@ -3835,6 +3830,9 @@ convertClauseMapFlags(omp::ClauseMapFlags mlirFlags) {
auto mapTypeToBool = [&mlirFlags](omp::ClauseMapFlags flag) {
return (mlirFlags & flag) == flag;
};
const bool hasExplicitMap =
(mlirFlags & ~omp::ClauseMapFlags::is_device_ptr) !=
omp::ClauseMapFlags::none;

llvm::omp::OpenMPOffloadMappingFlags mapType =
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
Expand Down Expand Up @@ -3875,6 +3873,12 @@ convertClauseMapFlags(omp::ClauseMapFlags mlirFlags) {
if (mapTypeToBool(omp::ClauseMapFlags::attach))
mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ATTACH;

if (mapTypeToBool(omp::ClauseMapFlags::is_device_ptr)) {
mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM;
if (!hasExplicitMap)
mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL;
}

return mapType;
}

Expand Down Expand Up @@ -3996,6 +4000,9 @@ static void collectMapDataFromMapOperands(
llvm::Value *origValue = moduleTranslation.lookupValue(offloadPtr);
auto mapType = convertClauseMapFlags(mapOp.getMapType());
auto mapTypeAlways = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
bool isDevicePtr =
(mapOp.getMapType() & omp::ClauseMapFlags::is_device_ptr) !=
omp::ClauseMapFlags::none;

mapData.OriginalValue.push_back(origValue);
mapData.BasePointers.push_back(origValue);
Expand All @@ -4022,14 +4029,18 @@ static void collectMapDataFromMapOperands(
mapData.Mappers.push_back(nullptr);
}
} else {
// For is_device_ptr we need the map type to propagate so the runtime
// can materialize the device-side copy of the pointer container.
mapData.Types.push_back(
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL);
isDevicePtr ? mapType
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL);
mapData.Mappers.push_back(nullptr);
}
mapData.Names.push_back(LLVM::createMappingInformation(
mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder()));
mapData.DevicePointers.push_back(
llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
isDevicePtr ? llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer
: llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
mapData.IsAMapping.push_back(false);
mapData.IsAMember.push_back(checkIsAMember(hasDevAddrOperands, mapOp));
}
Expand Down
17 changes: 17 additions & 0 deletions mlir/test/Target/LLVMIR/omptarget-llvm.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -622,3 +622,20 @@ module attributes {omp.target_triples = ["amdgcn-amd-amdhsa"]} {
// CHECK: br label %[[VAL_40]]
// CHECK: omp.done: ; preds = %[[VAL_68]], %[[VAL_63]], %[[VAL_32]]
// CHECK: ret void

// -----

module attributes {omp.target_triples = ["amdgcn-amd-amdhsa"]} {
llvm.func @_QPomp_target_is_device_ptr(%arg0 : !llvm.ptr) {
%map = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.ptr)
map_clauses(is_device_ptr) capture(ByRef) -> !llvm.ptr {name = ""}
omp.target map_entries(%map -> %ptr_arg : !llvm.ptr) {
omp.terminator
}
llvm.return
}
}

// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 8]
// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-LABEL: define void @_QPomp_target_is_device_ptr
11 changes: 0 additions & 11 deletions mlir/test/Target/LLVMIR/openmp-todo.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -238,17 +238,6 @@ llvm.func @target_in_reduction(%x : !llvm.ptr) {

// -----

llvm.func @target_is_device_ptr(%x : !llvm.ptr) {
// expected-error@below {{not yet implemented: Unhandled clause is_device_ptr in omp.target operation}}
// expected-error@below {{LLVM Translation failed for operation: omp.target}}
omp.target is_device_ptr(%x : !llvm.ptr) {
omp.terminator
}
llvm.return
}

// -----

llvm.func @target_enter_data_depend(%x: !llvm.ptr) {
// expected-error@below {{not yet implemented: Unhandled clause depend in omp.target_enter_data operation}}
// expected-error@below {{LLVM Translation failed for operation: omp.target_enter_data}}
Expand Down
60 changes: 60 additions & 0 deletions offload/test/offloading/fortran/target-is-device-ptr.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
! Validate that a device pointer obtained via omp_get_mapped_ptr can be used
! inside a TARGET region with the is_device_ptr clause.
! REQUIRES: flang, amdgcn-amd-amdhsa

! RUN: %libomptarget-compile-fortran-run-and-check-generic

module mod
implicit none
integer, parameter :: n = 4
contains
subroutine kernel(dptr)
use iso_c_binding, only : c_ptr, c_f_pointer
implicit none

type(c_ptr) :: dptr
integer, dimension(:), pointer :: b
integer :: i

b => null()

!$omp target is_device_ptr(dptr)
call c_f_pointer(dptr, b, [n])
do i = 1, n
b(i) = b(i) + 1
end do
!$omp end target
end subroutine kernel
end module mod

program is_device_ptr_target
use iso_c_binding, only : c_ptr, c_loc, c_f_pointer
use omp_lib, only: omp_get_default_device, omp_get_mapped_ptr
use mod, only: kernel, n
implicit none

integer, dimension(n), target :: a
integer :: dev
type(c_ptr) :: dptr

a = [2, 4, 6, 8]
print '("BEFORE:", I3)', a

dev = omp_get_default_device()

!$omp target data map(tofrom: a)
dptr = omp_get_mapped_ptr(c_loc(a), dev)
call kernel(dptr)
!$omp end target data

print '("AFTER: ", I3)', a

if (all(a == [3, 5, 7, 9])) then
print '("PASS")'
else
print '("FAIL ", I3)', a
end if

end program is_device_ptr_target

!CHECK: PASS