Skip to content

Commit c03fd37

Browse files
authored
[flang] Changes to map variables in link clause of declare target (#83643)
As per the OpenMP standard, "If a variable appears in a link clause on a declare target directive that does not have a device_type clause with the nohost device-type-description then it is treated as if it had appeared in a map clause with a map-type of tofrom" is an implicit mapping rule. Before this change, such variables were mapped as to by default.
1 parent 5d59fa9 commit c03fd37

File tree

4 files changed

+151
-34
lines changed

4 files changed

+151
-34
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,21 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
11201120
if (auto refType = baseOp.getType().dyn_cast<fir::ReferenceType>())
11211121
eleType = refType.getElementType();
11221122

1123-
if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
1123+
// If a variable is specified in declare target link and if device
1124+
// type is not specified as `nohost`, it needs to be mapped tofrom
1125+
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
1126+
mlir::Operation *op = mod.lookupSymbol(converter.mangleName(sym));
1127+
auto declareTargetOp =
1128+
llvm::dyn_cast_if_present<mlir::omp::DeclareTargetInterface>(op);
1129+
if (declareTargetOp && declareTargetOp.isDeclareTarget()) {
1130+
if (declareTargetOp.getDeclareTargetCaptureClause() ==
1131+
mlir::omp::DeclareTargetCaptureClause::link &&
1132+
declareTargetOp.getDeclareTargetDeviceType() !=
1133+
mlir::omp::DeclareTargetDeviceType::nohost) {
1134+
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
1135+
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
1136+
}
1137+
} else if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
11241138
captureKind = mlir::omp::VariableCaptureKind::ByCopy;
11251139
} else if (!fir::isa_builtin_cptr_type(eleType)) {
11261140
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s
3+
!RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
4+
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
5+
6+
program test_link
7+
8+
integer :: test_int = 1
9+
!$omp declare target link(test_int)
10+
11+
integer :: test_array_1d(3) = (/1,2,3/)
12+
!$omp declare target link(test_array_1d)
13+
14+
integer, pointer :: test_ptr1
15+
!$omp declare target link(test_ptr1)
16+
17+
integer, target :: test_target = 1
18+
!$omp declare target link(test_target)
19+
20+
integer, pointer :: test_ptr2
21+
!$omp declare target link(test_ptr2)
22+
23+
!CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_int"}
24+
!$omp target
25+
test_int = test_int + 1
26+
!$omp end target
27+
28+
29+
!CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.array<3xi32>>, !fir.array<3xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{%.*}}) -> !fir.ref<!fir.array<3xi32>> {name = "test_array_1d"}
30+
!$omp target
31+
do i = 1,3
32+
test_array_1d(i) = i * 2
33+
end do
34+
!$omp end target
35+
36+
allocate(test_ptr1)
37+
test_ptr1 = 1
38+
!CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr1"}
39+
!$omp target
40+
test_ptr1 = test_ptr1 + 1
41+
!$omp end target
42+
43+
!CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_target"}
44+
!$omp target
45+
test_target = test_target + 1
46+
!$omp end target
47+
48+
49+
!CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr2"}
50+
test_ptr2 => test_target
51+
!$omp target
52+
test_ptr2 = test_ptr2 + 1
53+
!$omp end target
54+
55+
end

openmp/libomptarget/test/offloading/fortran/declare-target-array-in-target-region.f90

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
! Offloading test with a target region mapping a declare target
2+
! Fortran array writing some values to it and checking the host
3+
! correctly receives the updates made on the device.
4+
! REQUIRES: flang
5+
! UNSUPPORTED: nvptx64-nvidia-cuda-LTO
6+
! UNSUPPORTED: aarch64-unknown-linux-gnu
7+
! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
8+
! UNSUPPORTED: x86_64-pc-linux-gnu
9+
! UNSUPPORTED: x86_64-pc-linux-gnu-LTO
10+
11+
! RUN: %libomptarget-compile-fortran-run-and-check-generic
12+
module test_0
13+
implicit none
14+
INTEGER :: arr1(10) = (/0,0,0,0,0,0,0,0,0,0/)
15+
INTEGER :: arr2(10) = (/0,0,0,0,0,0,0,0,0,0/)
16+
!$omp declare target link(arr1) enter(arr2)
17+
INTEGER :: scalar = 1
18+
!$omp declare target link(scalar)
19+
end module test_0
20+
21+
subroutine test_with_array_link_and_tofrom()
22+
use test_0
23+
integer :: i = 1
24+
integer :: j = 11
25+
!$omp target map(tofrom:arr1, i, j)
26+
do while (i <= j)
27+
arr1(i) = i;
28+
i = i + 1
29+
end do
30+
!$omp end target
31+
32+
! CHECK: 1 2 3 4 5 6 7 8 9 10
33+
PRINT *, arr1(:)
34+
end subroutine test_with_array_link_and_tofrom
35+
36+
subroutine test_with_array_link_only()
37+
use test_0
38+
integer :: i = 1
39+
integer :: j = 11
40+
!$omp target map(i, j)
41+
do while (i <= j)
42+
arr1(i) = i + 1;
43+
i = i + 1
44+
end do
45+
!$omp end target
46+
47+
! CHECK: 2 3 4 5 6 7 8 9 10 11
48+
PRINT *, arr1(:)
49+
end subroutine test_with_array_link_only
50+
51+
subroutine test_with_array_enter_only()
52+
use test_0
53+
integer :: i = 1
54+
integer :: j = 11
55+
!$omp target map(i, j)
56+
do while (i <= j)
57+
arr2(i) = i + 1;
58+
i = i + 1
59+
end do
60+
!$omp end target
61+
62+
! CHECK: 0 0 0 0 0 0 0 0 0 0
63+
PRINT *, arr2(:)
64+
end subroutine test_with_array_enter_only
65+
66+
subroutine test_with_scalar_link_only()
67+
use test_0
68+
!$omp target
69+
scalar = 10
70+
!$omp end target
71+
72+
! CHECK: 10
73+
PRINT *, scalar
74+
end subroutine test_with_scalar_link_only
75+
76+
program main
77+
call test_with_array_link_and_tofrom()
78+
call test_with_array_link_only()
79+
call test_with_array_enter_only()
80+
call test_with_scalar_link_only()
81+
end program

0 commit comments

Comments
 (0)