Skip to content

Commit 31393ee

Browse files
authored
[flang][OpenMP] Generate implicit mapping for reduction variable. (#15)
* Generate implicit mapping for reduction variable. The result of the reduction was not being copied back to reduction variable on the host. To sidestep this problem, an explicit map(tofrom: var) has to be added in the code to get the result back. This patch tries to solve this problem by generating an implicit tofrom mapping for reduction variable. All variables used in the target region (and without an explicit mapping) gets an implcit mapping in getTargetOP. We switch on TO,FROM bits for reduction varibles on this mapping. * Move code to get the reduction variables into separate function.
1 parent 687b076 commit 31393ee

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

flang/lib/Lower/OpenMP.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,9 @@ class ClauseProcessor {
643643
llvm::SmallVectorImpl<mlir::Location> *mapSymLocs = nullptr,
644644
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
645645
*mapSymbols = nullptr) const;
646+
bool processTargetReduction(
647+
llvm::SmallVector<const Fortran::semantics::Symbol *> &reductionSymbols)
648+
const;
646649
bool processReduction(
647650
mlir::Location currentLocation,
648651
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
@@ -1095,6 +1098,21 @@ class ReductionProcessor {
10951098
return decl;
10961099
}
10971100

1101+
static void addReductionSym(
1102+
const Fortran::parser::OmpReductionClause &reduction,
1103+
llvm::SmallVector<const Fortran::semantics::Symbol *> &Symbols) {
1104+
const auto &objectList{
1105+
std::get<Fortran::parser::OmpObjectList>(reduction.t)};
1106+
1107+
for (const Fortran::parser::OmpObject &ompObject : objectList.v) {
1108+
if (const auto *name{
1109+
Fortran::parser::Unwrap<Fortran::parser::Name>(ompObject)}) {
1110+
if (const Fortran::semantics::Symbol * symbol{name->symbol})
1111+
Symbols.push_back(symbol);
1112+
}
1113+
}
1114+
}
1115+
10981116
/// Creates a reduction declaration and associates it with an OpenMP block
10991117
/// directive.
11001118
static void addReductionDecl(
@@ -2011,6 +2029,17 @@ bool ClauseProcessor::processMap(
20112029
});
20122030
}
20132031

2032+
bool ClauseProcessor::processTargetReduction(
2033+
llvm::SmallVector<const Fortran::semantics::Symbol *> &reductionSymbols)
2034+
const {
2035+
return findRepeatableClause<ClauseTy::Reduction>(
2036+
[&](const ClauseTy::Reduction *reductionClause,
2037+
const Fortran::parser::CharBlock &) {
2038+
ReductionProcessor rp;
2039+
rp.addReductionSym(reductionClause->v, reductionSymbols);
2040+
});
2041+
}
2042+
20142043
bool ClauseProcessor::processReduction(
20152044
mlir::Location currentLocation,
20162045
llvm::SmallVectorImpl<mlir::Value> &reductionVars,
@@ -3153,6 +3182,7 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
31533182
llvm::SmallVector<mlir::Type> mapSymTypes;
31543183
llvm::SmallVector<mlir::Location> mapSymLocs;
31553184
llvm::SmallVector<const Fortran::semantics::Symbol *> mapSymbols;
3185+
llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols;
31563186

31573187
ClauseProcessor cp(converter, clauseList);
31583188
cp.processDevice(stmtCtx, deviceOperand);
@@ -3178,6 +3208,9 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
31783208
.getIsTargetDevice())
31793209
cp.processNowait(nowaitAttr);
31803210

3211+
if (outerCombined)
3212+
cp.processTargetReduction(reductionSymbols);
3213+
31813214
// 5.8.1 Implicit Data-Mapping Attribute Rules
31823215
// The following code follows the implicit data-mapping rules to map all the
31833216
// symbols used inside the region that have not been explicitly mapped using
@@ -3222,7 +3255,11 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
32223255
if (auto refType = baseOp.getType().dyn_cast<fir::ReferenceType>())
32233256
eleType = refType.getElementType();
32243257

3225-
if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
3258+
// Do a tofrom map for reduction variables.
3259+
if (llvm::find(reductionSymbols, &sym) != reductionSymbols.end()) {
3260+
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
3261+
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
3262+
} else if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
32263263
captureKind = mlir::omp::VariableCaptureKind::ByCopy;
32273264
} else if (!fir::isa_builtin_cptr_type(eleType)) {
32283265
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
3+
! This test checks that if reduction clause is on a combined target
4+
! construct, there is an implicit map(tofrom) for each reduction variable.
5+
6+
! construct with target
7+
subroutine omp_target_combined
8+
implicit none
9+
integer(kind = 8) :: s1
10+
integer(kind = 8) :: s2
11+
integer(kind = 4) :: i
12+
s1 = 1
13+
s2 = 1
14+
!$omp target teams distribute parallel do reduction(+:s1) reduction(+:s2)
15+
do i=1,1000
16+
s1 = s1 + i
17+
s2 = s2 + i
18+
end do
19+
!$omp end target teams distribute parallel do
20+
return
21+
end subroutine omp_target_combined
22+
!CHECK-LABEL: func.func @_QPomp_target_combined() {
23+
!CHECK: omp.map_info var_ptr({{.*}} : !fir.ref<i64>, i64) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i64> {name = "s1"}
24+
!CHECK: omp.map_info var_ptr({{.*}} : !fir.ref<i64>, i64) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i64> {name = "s2"}
25+
!CHECK: omp.map_info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"}
26+
27+
subroutine omp_target_team_separate
28+
implicit none
29+
integer(kind = 8) :: s3
30+
integer i
31+
s3 = 1
32+
!$omp target
33+
s3 = 2
34+
!$omp teams distribute parallel do reduction(+:s3)
35+
do i=1,1000
36+
s3 = s3 + i
37+
end do
38+
!$omp end teams distribute parallel do
39+
!$omp end target
40+
return
41+
end subroutine omp_target_team_separate
42+
!CHECK-LABEL: func.func @_QPomp_target_team_separate() {
43+
!CHECK: omp.map_info var_ptr({{.*}} : !fir.ref<i64>, i64) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i64> {name = "s3"}

0 commit comments

Comments
 (0)