Skip to content

Commit d343f3a

Browse files
committed
[MLIR][omp] Add omp.workshare op
Add custom omp loop wrapper Add recursive memory effects trait to workshare Remove stray include Remove omp.workshare verifier Add assembly format for wrapper and add test Add verification and descriptions
1 parent 65f66d2 commit d343f3a

File tree

5 files changed

+179
-0
lines changed

5 files changed

+179
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ using TeamsOperands =
316316
detail::Clauses<AllocateClauseOps, IfClauseOps, NumTeamsClauseOps,
317317
PrivateClauseOps, ReductionClauseOps, ThreadLimitClauseOps>;
318318

319+
using WorkshareOperands = detail::Clauses<NowaitClauseOps>;
320+
319321
using WsloopOperands =
320322
detail::Clauses<AllocateClauseOps, LinearClauseOps, NowaitClauseOps,
321323
OrderClauseOps, OrderedClauseOps, PrivateClauseOps,

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,49 @@ def SingleOp : OpenMP_Op<"single", traits = [
287287
let hasVerifier = 1;
288288
}
289289

290+
//===----------------------------------------------------------------------===//
291+
// 2.8.3 Workshare Construct
292+
//===----------------------------------------------------------------------===//
293+
294+
def WorkshareOp : OpenMP_Op<"workshare", traits = [
295+
RecursiveMemoryEffects,
296+
], clauses = [
297+
OpenMP_NowaitClause,
298+
], singleRegion = true> {
299+
let summary = "workshare directive";
300+
let description = [{
301+
The workshare construct divides the execution of the enclosed structured
302+
block into separate units of work, and causes the threads of the team to
303+
share the work such that each unit is executed only once by one thread, in
304+
the context of its implicit task
305+
306+
This operation is used for the intermediate representation of the workshare
307+
block before the work gets divided between the threads. See the flang
308+
LowerWorkshare pass for details.
309+
}] # clausesDescription;
310+
311+
let builders = [
312+
OpBuilder<(ins CArg<"const WorkshareOperands &">:$clauses)>
313+
];
314+
}
315+
316+
def WorkshareLoopWrapperOp : OpenMP_Op<"workshare.loop_wrapper", traits = [
317+
DeclareOpInterfaceMethods<LoopWrapperInterface>,
318+
RecursiveMemoryEffects, SingleBlock
319+
], singleRegion = true> {
320+
let summary = "contains loop nests to be parallelized by workshare";
321+
let description = [{
322+
This operation wraps a loop nest that is marked for dividing into units of
323+
work by an encompassing omp.workshare operation.
324+
}];
325+
326+
let builders = [
327+
OpBuilder<(ins), [{ build($_builder, $_state, {}); }]>
328+
];
329+
let assemblyFormat = "$region attr-dict";
330+
let hasVerifier = 1;
331+
}
332+
290333
//===----------------------------------------------------------------------===//
291334
// Loop Nest
292335
//===----------------------------------------------------------------------===//

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,29 @@ LogicalResult SingleOp::verify() {
16891689
getCopyprivateSyms());
16901690
}
16911691

1692+
//===----------------------------------------------------------------------===//
1693+
// WorkshareOp
1694+
//===----------------------------------------------------------------------===//
1695+
1696+
void WorkshareOp::build(OpBuilder &builder, OperationState &state,
1697+
const WorkshareOperands &clauses) {
1698+
WorkshareOp::build(builder, state, clauses.nowait);
1699+
}
1700+
1701+
//===----------------------------------------------------------------------===//
1702+
// WorkshareLoopWrapperOp
1703+
//===----------------------------------------------------------------------===//
1704+
1705+
LogicalResult WorkshareLoopWrapperOp::verify() {
1706+
if (!isWrapper())
1707+
return emitOpError() << "must be a loop wrapper";
1708+
if (getNestedWrapper())
1709+
return emitError() << "nested wrappers not supported";
1710+
if (!(*this)->getParentOfType<WorkshareOp>())
1711+
return emitError() << "must be nested in an omp.workshare";
1712+
return success();
1713+
}
1714+
16921715
//===----------------------------------------------------------------------===//
16931716
// WsloopOp
16941717
//===----------------------------------------------------------------------===//

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,3 +2545,45 @@ func.func @omp_taskloop_invalid_composite(%lb: index, %ub: index, %step: index)
25452545
} {omp.composite}
25462546
return
25472547
}
2548+
2549+
// -----
2550+
func.func @nested_wrapper(%idx : index) {
2551+
omp.workshare {
2552+
// expected-error @below {{nested wrappers not supported}}
2553+
omp.workshare.loop_wrapper {
2554+
omp.simd {
2555+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2556+
omp.yield
2557+
}
2558+
omp.terminator
2559+
}
2560+
omp.terminator
2561+
}
2562+
omp.terminator
2563+
}
2564+
return
2565+
}
2566+
2567+
// -----
2568+
func.func @not_wrapper() {
2569+
omp.workshare {
2570+
// expected-error @below {{must be a loop wrapper}}
2571+
omp.workshare.loop_wrapper {
2572+
omp.terminator
2573+
}
2574+
omp.terminator
2575+
}
2576+
return
2577+
}
2578+
2579+
// -----
2580+
func.func @missing_workshare(%idx : index) {
2581+
// expected-error @below {{must be nested in an omp.workshare}}
2582+
omp.workshare.loop_wrapper {
2583+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2584+
omp.yield
2585+
}
2586+
omp.terminator
2587+
}
2588+
return
2589+
}

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2810,3 +2810,72 @@ func.func @omp_target_private(%map1: memref<?xi32>, %map2: memref<?xi32>, %priv_
28102810

28112811
return
28122812
}
2813+
2814+
// CHECK-LABEL: func @omp_workshare
2815+
func.func @omp_workshare() {
2816+
// CHECK: omp.workshare {
2817+
omp.workshare {
2818+
"test.payload"() : () -> ()
2819+
// CHECK: omp.terminator
2820+
omp.terminator
2821+
}
2822+
return
2823+
}
2824+
2825+
// CHECK-LABEL: func @omp_workshare_nowait
2826+
func.func @omp_workshare_nowait() {
2827+
// CHECK: omp.workshare nowait {
2828+
omp.workshare nowait {
2829+
"test.payload"() : () -> ()
2830+
// CHECK: omp.terminator
2831+
omp.terminator
2832+
}
2833+
return
2834+
}
2835+
2836+
// CHECK-LABEL: func @omp_workshare_multiple_blocks
2837+
func.func @omp_workshare_multiple_blocks() {
2838+
// CHECK: omp.workshare {
2839+
omp.workshare {
2840+
cf.br ^bb2
2841+
^bb2:
2842+
// CHECK: omp.terminator
2843+
omp.terminator
2844+
}
2845+
return
2846+
}
2847+
2848+
// CHECK-LABEL: func @omp_workshare.loop_wrapper
2849+
func.func @omp_workshare.loop_wrapper(%idx : index) {
2850+
// CHECK-NEXT: omp.workshare {
2851+
omp.workshare {
2852+
// CHECK-NEXT: omp.workshare.loop_wrapper
2853+
omp.workshare.loop_wrapper {
2854+
// CHECK-NEXT: omp.loop_nest
2855+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2856+
omp.yield
2857+
}
2858+
omp.terminator
2859+
}
2860+
omp.terminator
2861+
}
2862+
return
2863+
}
2864+
2865+
// CHECK-LABEL: func @omp_workshare.loop_wrapper_attrs
2866+
func.func @omp_workshare.loop_wrapper_attrs(%idx : index) {
2867+
// CHECK-NEXT: omp.workshare {
2868+
omp.workshare {
2869+
// CHECK-NEXT: omp.workshare.loop_wrapper {
2870+
omp.workshare.loop_wrapper {
2871+
// CHECK-NEXT: omp.loop_nest
2872+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2873+
omp.yield
2874+
}
2875+
omp.terminator
2876+
// CHECK: } {attr_in_dict}
2877+
} {attr_in_dict}
2878+
omp.terminator
2879+
}
2880+
return
2881+
}

0 commit comments

Comments
 (0)