Skip to content

Commit 2cf1975

Browse files
authored
[MLIR][OpenMP]Add order-modifier support to Order clause (llvm#93805)
This adds order-modifier (reproducible|unconstrained) support to Order clause.
1 parent de528ff commit 2cf1975

File tree

6 files changed

+181
-10
lines changed

6 files changed

+181
-10
lines changed

mlir/include/mlir/Dialect/OpenMP/OpenMPClauseOperands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ struct NumThreadsClauseOps {
147147

148148
struct OrderClauseOps {
149149
ClauseOrderKindAttr orderAttr;
150+
OrderModifierAttr orderModAttr;
150151
};
151152

152153
struct OrderedClauseOps {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,21 @@ def DeclareTargetDeviceTypeAttr : OpenMP_EnumAttr<DeclareTargetDeviceType,
163163
let assemblyFormat = "`(` $value `)`";
164164
}
165165

166+
//===----------------------------------------------------------------------===//
167+
// order_modifer enum.
168+
//===----------------------------------------------------------------------===//
169+
170+
def OMP_OrderModReproducible : I32EnumAttrCase<"reproducible", 0>;
171+
def OMP_OrderModUnconstrained : I32EnumAttrCase<"unconstrained", 1>;
172+
def OrderModifier
173+
: I32EnumAttr<"OrderModifier", "OpenMP Order Modifier",
174+
[OMP_OrderModReproducible, OMP_OrderModUnconstrained]> {
175+
let genSpecializedAttr = 0;
176+
let cppNamespace = "::mlir::omp";
177+
}
178+
def OrderModifierAttr : EnumAttr<OpenMP_Dialect, OrderModifier,
179+
"order_mod">;
180+
166181
//===----------------------------------------------------------------------===//
167182
// sched_mod enum.
168183
//===----------------------------------------------------------------------===//

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,8 @@ def WsloopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments,
544544
UnitAttr:$simd_modifier,
545545
UnitAttr:$nowait,
546546
ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$ordered_val,
547-
OptionalAttr<OrderKindAttr>:$order_val);
547+
OptionalAttr<OrderKindAttr>:$order_val,
548+
OptionalAttr<OrderModifierAttr>:$order_mod);
548549

549550
let builders = [
550551
OpBuilder<(ins CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes)>,
@@ -568,7 +569,7 @@ def WsloopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments,
568569
$schedule_chunk_var, type($schedule_chunk_var)) `)`
569570
|`nowait` $nowait
570571
|`ordered` `(` $ordered_val `)`
571-
|`order` `(` custom<ClauseAttr>($order_val) `)`
572+
|`order` `(` custom<OrderClause>($order_val, $order_mod) `)`
572573
) custom<Wsloop>($region, $reduction_vars, type($reduction_vars),
573574
$reduction_vars_byref, $reductions) attr-dict
574575
}];
@@ -634,6 +635,7 @@ def SimdOp : OpenMP_Op<"simd", [AttrSizedOperandSegments,
634635
Optional<I1>:$if_expr,
635636
Variadic<OpenMP_PointerLikeType>:$nontemporal_vars,
636637
OptionalAttr<OrderKindAttr>:$order_val,
638+
OptionalAttr<OrderModifierAttr>:$order_mod,
637639
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$simdlen,
638640
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$safelen
639641
);
@@ -650,7 +652,7 @@ def SimdOp : OpenMP_Op<"simd", [AttrSizedOperandSegments,
650652
$alignment_values) `)`
651653
|`if` `(` $if_expr `)`
652654
|`nontemporal` `(` $nontemporal_vars `:` type($nontemporal_vars) `)`
653-
|`order` `(` custom<ClauseAttr>($order_val) `)`
655+
|`order` `(` custom<OrderClause>($order_val, $order_mod) `)`
654656
|`simdlen` `(` $simdlen `)`
655657
|`safelen` `(` $safelen `)`
656658
) $region attr-dict
@@ -732,7 +734,8 @@ def DistributeOp : OpenMP_Op<"distribute", [AttrSizedOperandSegments,
732734
Optional<IntLikeType>:$chunk_size,
733735
Variadic<AnyType>:$allocate_vars,
734736
Variadic<AnyType>:$allocators_vars,
735-
OptionalAttr<OrderKindAttr>:$order_val);
737+
OptionalAttr<OrderKindAttr>:$order_val,
738+
OptionalAttr<OrderModifierAttr>:$order_mod);
736739

737740
let regions = (region AnyRegion:$region);
738741

@@ -743,7 +746,7 @@ def DistributeOp : OpenMP_Op<"distribute", [AttrSizedOperandSegments,
743746
let assemblyFormat = [{
744747
oilist(`dist_schedule_static` $dist_schedule_static
745748
|`chunk_size` `(` $chunk_size `:` type($chunk_size) `)`
746-
|`order` `(` custom<ClauseAttr>($order_val) `)`
749+
|`order` `(` custom<OrderClause>($order_val, $order_mod) `)`
747750
|`allocate` `(`
748751
custom<AllocateAndAllocator>(
749752
$allocate_vars, type($allocate_vars),

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,45 @@ static void printScheduleClause(OpAsmPrinter &p, Operation *op,
433433
p << ", simd";
434434
}
435435

436+
//===----------------------------------------------------------------------===//
437+
// Parser and printer for Order Clause
438+
//===----------------------------------------------------------------------===//
439+
440+
// order ::= `order` `(` [order-modifier ':'] concurrent `)`
441+
// order-modifier ::= reproducible | unconstrained
442+
static ParseResult parseOrderClause(OpAsmParser &parser,
443+
ClauseOrderKindAttr &kindAttr,
444+
OrderModifierAttr &modifierAttr) {
445+
StringRef enumStr;
446+
SMLoc loc = parser.getCurrentLocation();
447+
if (parser.parseKeyword(&enumStr))
448+
return failure();
449+
if (std::optional<OrderModifier> enumValue =
450+
symbolizeOrderModifier(enumStr)) {
451+
modifierAttr = OrderModifierAttr::get(parser.getContext(), *enumValue);
452+
if (parser.parseOptionalColon())
453+
return failure();
454+
loc = parser.getCurrentLocation();
455+
if (parser.parseKeyword(&enumStr))
456+
return failure();
457+
}
458+
if (std::optional<ClauseOrderKind> enumValue =
459+
symbolizeClauseOrderKind(enumStr)) {
460+
kindAttr = ClauseOrderKindAttr::get(parser.getContext(), *enumValue);
461+
return success();
462+
}
463+
return parser.emitError(loc, "invalid clause value: '") << enumStr << "'";
464+
}
465+
466+
static void printOrderClause(OpAsmPrinter &p, Operation *op,
467+
ClauseOrderKindAttr kindAttr,
468+
OrderModifierAttr modifierAttr) {
469+
if (modifierAttr)
470+
p << stringifyOrderModifier(modifierAttr.getValue()) << ":";
471+
if (kindAttr)
472+
p << stringifyClauseOrderKind(kindAttr.getValue());
473+
}
474+
436475
//===----------------------------------------------------------------------===//
437476
// Parser, printer and verifier for ReductionVarList
438477
//===----------------------------------------------------------------------===//
@@ -1682,7 +1721,8 @@ void WsloopOp::build(OpBuilder &builder, OperationState &state,
16821721
/*reductions=*/nullptr, /*schedule_val=*/nullptr,
16831722
/*schedule_chunk_var=*/nullptr, /*schedule_modifier=*/nullptr,
16841723
/*simd_modifier=*/false, /*nowait=*/false,
1685-
/*ordered_val=*/nullptr, /*order_val=*/nullptr);
1724+
/*ordered_val=*/nullptr, /*order_val=*/nullptr,
1725+
/*order_modifier=*/nullptr);
16861726
state.addAttributes(attributes);
16871727
}
16881728

@@ -1697,7 +1737,8 @@ void WsloopOp::build(OpBuilder &builder, OperationState &state,
16971737
makeArrayAttr(ctx, clauses.reductionDeclSymbols),
16981738
clauses.scheduleValAttr, clauses.scheduleChunkVar,
16991739
clauses.scheduleModAttr, clauses.scheduleSimdAttr,
1700-
clauses.nowaitAttr, clauses.orderedAttr, clauses.orderAttr);
1740+
clauses.nowaitAttr, clauses.orderedAttr, clauses.orderAttr,
1741+
clauses.orderModAttr);
17011742
}
17021743

17031744
LogicalResult WsloopOp::verify() {
@@ -1726,8 +1767,8 @@ void SimdOp::build(OpBuilder &builder, OperationState &state,
17261767
// privatizers, reductionDeclSymbols.
17271768
SimdOp::build(builder, state, clauses.alignedVars,
17281769
makeArrayAttr(ctx, clauses.alignmentAttrs), clauses.ifVar,
1729-
clauses.nontemporalVars, clauses.orderAttr, clauses.simdlenAttr,
1730-
clauses.safelenAttr);
1770+
clauses.nontemporalVars, clauses.orderAttr,
1771+
clauses.orderModAttr, clauses.simdlenAttr, clauses.safelenAttr);
17311772
}
17321773

17331774
LogicalResult SimdOp::verify() {
@@ -1762,7 +1803,8 @@ void DistributeOp::build(OpBuilder &builder, OperationState &state,
17621803
// TODO Store clauses in op: privateVars, privatizers.
17631804
DistributeOp::build(builder, state, clauses.distScheduleStaticAttr,
17641805
clauses.distScheduleChunkSizeVar, clauses.allocateVars,
1765-
clauses.allocatorVars, clauses.orderAttr);
1806+
clauses.allocatorVars, clauses.orderAttr,
1807+
clauses.orderModAttr);
17661808
}
17671809

17681810
LogicalResult DistributeOp::verify() {

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,26 @@ func.func @order_value(%lb : index, %ub : index, %step : index) {
250250
}
251251
}
252252

253+
// -----
254+
func.func @reproducible_order(%lb : index, %ub : index, %step : index) {
255+
// expected-error @below {{invalid clause value: 'default'}}
256+
omp.wsloop order(reproducible:default) {
257+
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
258+
omp.yield
259+
}
260+
omp.terminator
261+
}
262+
}
263+
// -----
264+
func.func @unconstrained_order(%lb : index, %ub : index, %step : index) {
265+
// expected-error @below {{invalid clause value: 'default'}}
266+
omp.wsloop order(unconstrained:default) {
267+
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
268+
omp.yield
269+
}
270+
omp.terminator
271+
}
272+
}
253273
// -----
254274

255275
func.func @if_not_allowed(%lb : index, %ub : index, %step : index, %bool_var : i1) {
@@ -485,6 +505,26 @@ func.func @omp_simd_order_value(%lb : index, %ub : index, %step : index) {
485505

486506
// -----
487507

508+
func.func @omp_simd_reproducible_order(%lb : index, %ub : index, %step : index) {
509+
// expected-error @below {{invalid clause value: 'default'}}
510+
omp.simd order(reproducible:default) {
511+
omp.loop_nest (%iv) : index = (%arg0) to (%arg1) step (%arg2) {
512+
omp.yield
513+
}
514+
}
515+
return
516+
}
517+
// -----
518+
func.func @omp_simd_unconstrained_order(%lb : index, %ub : index, %step : index) {
519+
// expected-error @below {{invalid clause value: 'default'}}
520+
omp.simd order(unconstrained:default) {
521+
omp.loop_nest (%iv) : index = (%arg0) to (%arg1) step (%arg2) {
522+
omp.yield
523+
}
524+
}
525+
return
526+
}
527+
// -----
488528
func.func @omp_simd_pretty_simdlen(%lb : index, %ub : index, %step : index) -> () {
489529
// expected-error @below {{op attribute 'simdlen' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}}
490530
omp.simd simdlen(0) {
@@ -2131,6 +2171,36 @@ func.func @omp_distribute_nested_wrapper(%data_var : memref<i32>) -> () {
21312171

21322172
// -----
21332173

2174+
func.func @omp_distribute_order() -> () {
2175+
// expected-error @below {{invalid clause value: 'default'}}
2176+
omp.distribute order(default) {
2177+
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {
2178+
omp.yield
2179+
}
2180+
}
2181+
return
2182+
}
2183+
// -----
2184+
func.func @omp_distribute_reproducible_order() -> () {
2185+
// expected-error @below {{invalid clause value: 'default'}}
2186+
omp.distribute order(reproducible:default) {
2187+
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {
2188+
omp.yield
2189+
}
2190+
}
2191+
return
2192+
}
2193+
// -----
2194+
func.func @omp_distribute_unconstrained_order() -> () {
2195+
// expected-error @below {{invalid clause value: 'default'}}
2196+
omp.distribute order(unconstrained:default) {
2197+
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {
2198+
omp.yield
2199+
}
2200+
}
2201+
return
2202+
}
2203+
// -----
21342204
omp.private {type = private} @x.privatizer : i32 alloc {
21352205
^bb0(%arg0: i32):
21362206
%0 = arith.constant 0.0 : f32

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,22 @@ func.func @omp_wsloop_pretty(%lb : index, %ub : index, %step : index, %data_var
502502
omp.terminator
503503
}
504504

505+
// CHECK: omp.wsloop nowait order(reproducible:concurrent) {
506+
// CHECK-NEXT: omp.loop_nest
507+
omp.wsloop order(reproducible:concurrent) nowait {
508+
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
509+
omp.yield
510+
}
511+
omp.terminator
512+
}
513+
// CHECK: omp.wsloop nowait order(unconstrained:concurrent) {
514+
// CHECK-NEXT: omp.loop_nest
515+
omp.wsloop order(unconstrained:concurrent) nowait {
516+
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
517+
omp.yield
518+
}
519+
omp.terminator
520+
}
505521
// CHECK: omp.wsloop {
506522
// CHECK-NEXT: omp.simd
507523
// CHECK-NEXT: omp.loop_nest
@@ -652,6 +668,18 @@ func.func @omp_simd_pretty_order(%lb : index, %ub : index, %step : index) -> ()
652668
omp.yield
653669
}
654670
}
671+
// CHECK: omp.simd order(reproducible:concurrent)
672+
omp.simd order(reproducible:concurrent) {
673+
omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {
674+
omp.yield
675+
}
676+
}
677+
// CHECK: omp.simd order(unconstrained:concurrent)
678+
omp.simd order(unconstrained:concurrent) {
679+
omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {
680+
omp.yield
681+
}
682+
}
655683
return
656684
}
657685

@@ -711,6 +739,18 @@ func.func @omp_distribute(%chunk_size : i32, %data_var : memref<i32>, %arg0 : i3
711739
omp.yield
712740
}
713741
}
742+
// CHECK: omp.distribute order(reproducible:concurrent)
743+
omp.distribute order(reproducible:concurrent) {
744+
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {
745+
omp.yield
746+
}
747+
}
748+
// CHECK: omp.distribute order(unconstrained:concurrent)
749+
omp.distribute order(unconstrained:concurrent) {
750+
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {
751+
omp.yield
752+
}
753+
}
714754
// CHECK: omp.distribute allocate(%{{.+}} : memref<i32> -> %{{.+}} : memref<i32>)
715755
omp.distribute allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {
716756
omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {

0 commit comments

Comments
 (0)