Skip to content

Commit afcbcae

Browse files
authored
[mlir][OpenMP] inscan reduction modifier and scan op mlir support (llvm#114737)
Scan directive allows to specify scan reductions within an worksharing loop, worksharing loop simd or simd directive which should have an `InScan` modifier associated with it. This change adds the mlir support for the same. Related PR: [Parsing and Semantic Support for scan](llvm#102792)
1 parent a56ba1f commit afcbcae

File tree

9 files changed

+403
-59
lines changed

9 files changed

+403
-59
lines changed

mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,43 @@ class OpenMP_DoacrossClauseSkip<
334334

335335
def OpenMP_DoacrossClause : OpenMP_DoacrossClauseSkip<>;
336336

337+
//===----------------------------------------------------------------------===//
338+
// V5.2: [5.4.7] `exclusive` clause
339+
//===----------------------------------------------------------------------===//
340+
341+
class OpenMP_ExclusiveClauseSkip<
342+
bit traits = false, bit arguments = false, bit assemblyFormat = false,
343+
bit description = false, bit extraClassDeclaration = false
344+
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
345+
extraClassDeclaration> {
346+
let arguments = (ins
347+
Variadic<AnyType>:$exclusive_vars
348+
);
349+
350+
let optAssemblyFormat = [{
351+
`exclusive` `(` $exclusive_vars `:` type($exclusive_vars) `)`
352+
}];
353+
354+
let extraClassDeclaration = [{
355+
bool hasExclusiveVars() {
356+
return !getExclusiveVars().empty();
357+
}
358+
}];
359+
360+
let description = [{
361+
The exclusive clause is used on a separating directive that separates a
362+
structured block into two structured block sequences. If it
363+
is specified, the input phase excludes the preceding structured block
364+
sequence and instead includes the following structured block sequence,
365+
while the scan phase includes the preceding structured block sequence.
366+
367+
The `exclusive_vars` is a variadic list of operands that specifies the
368+
scan-reduction accumulator symbols.
369+
}];
370+
}
371+
372+
def OpenMP_ExclusiveClause : OpenMP_ExclusiveClauseSkip<>;
373+
337374
//===----------------------------------------------------------------------===//
338375
// V5.2: [10.5.1] `filter` clause
339376
//===----------------------------------------------------------------------===//
@@ -444,6 +481,43 @@ class OpenMP_HasDeviceAddrClauseSkip<
444481

445482
def OpenMP_HasDeviceAddrClause : OpenMP_HasDeviceAddrClauseSkip<>;
446483

484+
//===----------------------------------------------------------------------===//
485+
// V5.2: [5.4.7] `inclusive` clause
486+
//===----------------------------------------------------------------------===//
487+
488+
class OpenMP_InclusiveClauseSkip<
489+
bit traits = false, bit arguments = false, bit assemblyFormat = false,
490+
bit description = false, bit extraClassDeclaration = false
491+
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
492+
extraClassDeclaration> {
493+
let arguments = (ins
494+
Variadic<AnyType>:$inclusive_vars
495+
);
496+
497+
let optAssemblyFormat = [{
498+
`inclusive` `(` $inclusive_vars `:` type($inclusive_vars) `)`
499+
}];
500+
501+
let extraClassDeclaration = [{
502+
bool hasInclusiveVars() {
503+
return !getInclusiveVars().empty();
504+
}
505+
}];
506+
507+
let description = [{
508+
The inclusive clause is used on a separating directive that separates a
509+
structured block into two structured block sequences. If it is specified,
510+
the input phase includes the preceding structured block sequence and the
511+
scan phase includes the following structured block sequence.
512+
513+
The `inclusive_vars` is a variadic list of operands that specifies the
514+
scan-reduction accumulator symbols.
515+
}];
516+
}
517+
518+
def OpenMP_InclusiveClause : OpenMP_InclusiveClauseSkip<>;
519+
520+
447521
//===----------------------------------------------------------------------===//
448522
// V5.2: [15.1.2] `hint` clause
449523
//===----------------------------------------------------------------------===//
@@ -1100,6 +1174,7 @@ class OpenMP_ReductionClauseSkip<
11001174
];
11011175

11021176
let arguments = (ins
1177+
OptionalAttr<ReductionModifierAttr>:$reduction_mod,
11031178
Variadic<OpenMP_PointerLikeType>:$reduction_vars,
11041179
OptionalAttr<DenseBoolArrayAttr>:$reduction_byref,
11051180
OptionalAttr<SymbolRefArrayAttr>:$reduction_syms
@@ -1113,10 +1188,11 @@ class OpenMP_ReductionClauseSkip<
11131188

11141189
// Description varies depending on the operation.
11151190
let description = [{
1116-
Reductions can be performed by specifying reduction accumulator variables in
1117-
`reduction_vars`, symbols referring to reduction declarations in the
1118-
`reduction_syms` attribute, and whether the reduction variable should be
1119-
passed into the reduction region by value or by reference in
1191+
Reductions can be performed by specifying the reduction modifer
1192+
(`default`, `inscan` or `task`) in `reduction_mod`, reduction accumulator
1193+
variables in `reduction_vars`, symbols referring to reduction declarations
1194+
in the `reduction_syms` attribute, and whether the reduction variable
1195+
should be passed into the reduction region by value or by reference in
11201196
`reduction_byref`. Each reduction is identified by the accumulator it uses
11211197
and accumulators must not be repeated in the same reduction. A private
11221198
variable corresponding to the accumulator is used in place of the

mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,27 @@ def OrderModifier
179179
def OrderModifierAttr : EnumAttr<OpenMP_Dialect, OrderModifier,
180180
"order_mod">;
181181

182+
//===----------------------------------------------------------------------===//
183+
// reduction_modifier enum.
184+
//===----------------------------------------------------------------------===//
185+
186+
def ReductionModifierDefault : I32EnumAttrCase<"defaultmod", 0>;
187+
def ReductionModifierInscan : I32EnumAttrCase<"inscan", 1>;
188+
def ReductionModifierTask : I32EnumAttrCase<"task", 2>;
189+
190+
def ReductionModifier : OpenMP_I32EnumAttr<
191+
"ReductionModifier",
192+
"reduction modifier", [
193+
ReductionModifierDefault,
194+
ReductionModifierInscan,
195+
ReductionModifierTask
196+
]>;
197+
198+
def ReductionModifierAttr : OpenMP_EnumAttr<ReductionModifier,
199+
"reduction_modifier"> {
200+
let assemblyFormat = "`(` $value `)`";
201+
}
202+
182203
//===----------------------------------------------------------------------===//
183204
// sched_mod enum.
184205
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def ParallelOp : OpenMP_Op<"parallel", traits = [
178178

179179
let assemblyFormat = clausesAssemblyFormat # [{
180180
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
181-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
181+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
182182
$reduction_syms) attr-dict
183183
}];
184184

@@ -223,7 +223,7 @@ def TeamsOp : OpenMP_Op<"teams", traits = [
223223

224224
let assemblyFormat = clausesAssemblyFormat # [{
225225
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
226-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
226+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
227227
$reduction_syms) attr-dict
228228
}];
229229

@@ -282,7 +282,7 @@ def SectionsOp : OpenMP_Op<"sections", traits = [
282282

283283
let assemblyFormat = clausesAssemblyFormat # [{
284284
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
285-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
285+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
286286
$reduction_syms) attr-dict
287287
}];
288288

@@ -469,7 +469,7 @@ def LoopOp : OpenMP_Op<"loop", traits = [
469469

470470
let assemblyFormat = clausesAssemblyFormat # [{
471471
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
472-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
472+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
473473
$reduction_syms) attr-dict
474474
}];
475475

@@ -521,7 +521,7 @@ def WsloopOp : OpenMP_Op<"wsloop", traits = [
521521

522522
let assemblyFormat = clausesAssemblyFormat # [{
523523
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
524-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
524+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
525525
$reduction_syms) attr-dict
526526
}];
527527

@@ -575,7 +575,7 @@ def SimdOp : OpenMP_Op<"simd", traits = [
575575

576576
let assemblyFormat = clausesAssemblyFormat # [{
577577
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
578-
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
578+
$private_syms, $reduction_mod, $reduction_vars, type($reduction_vars), $reduction_byref,
579579
$reduction_syms) attr-dict
580580
}];
581581

@@ -782,7 +782,7 @@ def TaskloopOp : OpenMP_Op<"taskloop", traits = [
782782
custom<InReductionPrivateReductionRegion>(
783783
$region, $in_reduction_vars, type($in_reduction_vars),
784784
$in_reduction_byref, $in_reduction_syms, $private_vars,
785-
type($private_vars), $private_syms, $reduction_vars,
785+
type($private_vars), $private_syms, $reduction_mod, $reduction_vars,
786786
type($reduction_vars), $reduction_byref, $reduction_syms) attr-dict
787787
}];
788788

@@ -1706,6 +1706,26 @@ def CancellationPointOp : OpenMP_Op<"cancellation_point", clauses = [
17061706
let hasVerifier = 1;
17071707
}
17081708

1709+
def ScanOp : OpenMP_Op<"scan", [
1710+
AttrSizedOperandSegments, MemoryEffects<[MemWrite]>
1711+
], clauses = [
1712+
OpenMP_InclusiveClause, OpenMP_ExclusiveClause]> {
1713+
let summary = "scan directive";
1714+
let description = [{
1715+
The scan directive allows to specify scan reductions. It should be
1716+
enclosed within a parent directive along with which a reduction clause
1717+
with `inscan` modifier must be specified. The scan directive allows to
1718+
split code blocks into input phase and scan phase in the region
1719+
enclosed by the parent.
1720+
}] # clausesDescription;
1721+
1722+
let builders = [
1723+
OpBuilder<(ins CArg<"const ScanOperands &">:$clauses)>
1724+
];
1725+
1726+
let hasVerifier = 1;
1727+
}
1728+
17091729
//===----------------------------------------------------------------------===//
17101730
// 2.19.5.7 declare reduction Directive
17111731
//===----------------------------------------------------------------------===//

mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ struct ParallelOpLowering : public OpRewritePattern<scf::ParallelOp> {
451451
/* private_vars = */ ValueRange(),
452452
/* private_syms = */ nullptr,
453453
/* proc_bind_kind = */ omp::ClauseProcBindKindAttr{},
454+
/* reduction_mod = */ nullptr,
454455
/* reduction_vars = */ llvm::SmallVector<Value>{},
455456
/* reduction_byref = */ DenseBoolArrayAttr{},
456457
/* reduction_syms = */ ArrayAttr{});

0 commit comments

Comments
 (0)