Skip to content

Commit fa6e0dd

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 wrong replace Fix wsloopwrapperop Fix op tests
1 parent c526eb8 commit fa6e0dd

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

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

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

316+
//===----------------------------------------------------------------------===//
317+
// 2.8.3 Workshare Construct
318+
//===----------------------------------------------------------------------===//
319+
320+
def WorkshareOp : OpenMP_Op<"workshare", traits = [
321+
RecursiveMemoryEffects,
322+
], clauses = [
323+
OpenMP_NowaitClause,
324+
], singleRegion = true> {
325+
let summary = "workshare directive";
326+
let description = [{
327+
The workshare construct divides the execution of the enclosed structured
328+
block into separate units of work, and causes the threads of the team to
329+
share the work such that each unit is executed only once by one thread, in
330+
the context of its implicit task
331+
332+
This operation is used for the intermediate representation of the workshare
333+
block before the work gets divided between the threads. See the flang
334+
LowerWorkshare pass for details.
335+
}] # clausesDescription;
336+
337+
let builders = [
338+
OpBuilder<(ins CArg<"const WorkshareOperands &">:$clauses)>
339+
];
340+
}
341+
342+
def WorkshareLoopWrapperOp : OpenMP_Op<"workshare.loop_wrapper", traits = [
343+
DeclareOpInterfaceMethods<LoopWrapperInterface>, NoTerminator,
344+
RecursiveMemoryEffects, SingleBlock
345+
], singleRegion = true> {
346+
let summary = "contains loop nests to be parallelized by workshare";
347+
let description = [{
348+
This operation wraps a loop nest that is marked for dividing into units of
349+
work by an encompassing omp.workshare operation.
350+
}];
351+
352+
let builders = [
353+
OpBuilder<(ins), [{ build($_builder, $_state, {}); }]>
354+
];
355+
let assemblyFormat = "$region attr-dict";
356+
let hasVerifier = 1;
357+
}
358+
316359
//===----------------------------------------------------------------------===//
317360
// Loop Nest
318361
//===----------------------------------------------------------------------===//

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,27 @@ LogicalResult SingleOp::verify() {
18971897
getCopyprivateSyms());
18981898
}
18991899

1900+
//===----------------------------------------------------------------------===//
1901+
// WorkshareOp
1902+
//===----------------------------------------------------------------------===//
1903+
1904+
void WorkshareOp::build(OpBuilder &builder, OperationState &state,
1905+
const WorkshareOperands &clauses) {
1906+
WorkshareOp::build(builder, state, clauses.nowait);
1907+
}
1908+
1909+
//===----------------------------------------------------------------------===//
1910+
// WorkshareLoopWrapperOp
1911+
//===----------------------------------------------------------------------===//
1912+
1913+
LogicalResult WorkshareLoopWrapperOp::verify() {
1914+
if (!(*this)->getParentOfType<WorkshareOp>())
1915+
return emitError() << "must be nested in an omp.workshare";
1916+
if (getNestedWrapper())
1917+
return emitError() << "cannot be composite";
1918+
return success();
1919+
}
1920+
19001921
//===----------------------------------------------------------------------===//
19011922
// LoopWrapperInterface
19021923
//===----------------------------------------------------------------------===//

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,44 @@ func.func @omp_loop_invalid_binding(%lb : index, %ub : index, %step : index) {
26202620
omp.yield
26212621
}
26222622
}
2623+
return
2624+
}
2625+
2626+
// -----
2627+
func.func @nested_wrapper(%idx : index) {
2628+
omp.workshare {
2629+
// expected-error @below {{cannot be composite}}
2630+
omp.workshare.loop_wrapper {
2631+
omp.simd {
2632+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2633+
omp.yield
2634+
}
2635+
} {omp.composite}
2636+
}
2637+
omp.terminator
2638+
}
2639+
return
2640+
}
2641+
2642+
// -----
2643+
func.func @not_wrapper() {
2644+
omp.workshare {
2645+
// expected-error @below {{op nested in loop wrapper is not another loop wrapper or `omp.loop_nest`}}
2646+
omp.workshare.loop_wrapper {
2647+
%0 = arith.constant 0 : index
2648+
}
2649+
omp.terminator
2650+
}
2651+
return
2652+
}
26232653

2654+
// -----
2655+
func.func @missing_workshare(%idx : index) {
2656+
// expected-error @below {{must be nested in an omp.workshare}}
2657+
omp.workshare.loop_wrapper {
2658+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2659+
omp.yield
2660+
}
2661+
}
26242662
return
26252663
}

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,3 +2789,70 @@ func.func @omp_loop(%lb : index, %ub : index, %step : index) {
27892789

27902790
return
27912791
}
2792+
2793+
// CHECK-LABEL: func @omp_workshare
2794+
func.func @omp_workshare() {
2795+
// CHECK: omp.workshare {
2796+
omp.workshare {
2797+
"test.payload"() : () -> ()
2798+
// CHECK: omp.terminator
2799+
omp.terminator
2800+
}
2801+
return
2802+
}
2803+
2804+
// CHECK-LABEL: func @omp_workshare_nowait
2805+
func.func @omp_workshare_nowait() {
2806+
// CHECK: omp.workshare nowait {
2807+
omp.workshare nowait {
2808+
"test.payload"() : () -> ()
2809+
// CHECK: omp.terminator
2810+
omp.terminator
2811+
}
2812+
return
2813+
}
2814+
2815+
// CHECK-LABEL: func @omp_workshare_multiple_blocks
2816+
func.func @omp_workshare_multiple_blocks() {
2817+
// CHECK: omp.workshare {
2818+
omp.workshare {
2819+
cf.br ^bb2
2820+
^bb2:
2821+
// CHECK: omp.terminator
2822+
omp.terminator
2823+
}
2824+
return
2825+
}
2826+
2827+
// CHECK-LABEL: func @omp_workshare_loop_wrapper
2828+
func.func @omp_workshare_loop_wrapper(%idx : index) {
2829+
// CHECK-NEXT: omp.workshare {
2830+
omp.workshare {
2831+
// CHECK-NEXT: omp.workshare.loop_wrapper
2832+
omp.workshare.loop_wrapper {
2833+
// CHECK-NEXT: omp.loop_nest
2834+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2835+
omp.yield
2836+
}
2837+
}
2838+
omp.terminator
2839+
}
2840+
return
2841+
}
2842+
2843+
// CHECK-LABEL: func @omp_workshare_loop_wrapper_attrs
2844+
func.func @omp_workshare_loop_wrapper_attrs(%idx : index) {
2845+
// CHECK-NEXT: omp.workshare {
2846+
omp.workshare {
2847+
// CHECK-NEXT: omp.workshare.loop_wrapper {
2848+
omp.workshare.loop_wrapper {
2849+
// CHECK-NEXT: omp.loop_nest
2850+
omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {
2851+
omp.yield
2852+
}
2853+
// CHECK: } {attr_in_dict}
2854+
} {attr_in_dict}
2855+
omp.terminator
2856+
}
2857+
return
2858+
}

0 commit comments

Comments
 (0)