Skip to content

Commit d424631

Browse files
committed
[OpenMP][MLIR] Add omp.distribute op to the OMP dialect
This patch adds the omp.distribute operation to the OMP dialect. The purpose is to be able to represent the distribute construct in OpenMP with the associated clauses. The effect of the operation is to distributes the loop iterations of the loop(s) contained inside the region across multiple teams.
1 parent c88c281 commit d424631

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,57 @@ def YieldOp : OpenMP_Op<"yield",
636636
let assemblyFormat = [{ ( `(` $results^ `:` type($results) `)` )? attr-dict}];
637637
}
638638

639+
//===----------------------------------------------------------------------===//
640+
// Distribute construct [2.9.4.1]
641+
//===----------------------------------------------------------------------===//
642+
def DistributeOp : OpenMP_Op<"distribute", [AttrSizedOperandSegments,
643+
RecursiveMemoryEffects]> {
644+
let summary = "distribute construct";
645+
let description = [{
646+
The distribute construct specifies that the iterations of one or more loop
647+
will be executed by the initial teams in the context of their implicit
648+
tasks. The iterations are distributed across the initial threads of all
649+
initial teams that execute the teams region to which the distribute region
650+
binds.
651+
652+
The distribute loop construct specifies that the iterations of the loop(s)
653+
will be executed in parallel by threads in the current context. These
654+
iterations are spread across threads that already exist in the enclosing
655+
region. The lower and upper bounds specify a half-open range: the
656+
range includes the lower bound but does not include the upper bound. If the
657+
`inclusive` attribute is specified then the upper bound is also included.
658+
659+
The `dist_schedule_static` attribute specifies the schedule for this
660+
loop, determining how the loop is distributed across the parallel threads.
661+
The optional `schedule_chunk` associated with this determines further
662+
controls this distribution.
663+
664+
// TODO: private_var, firstprivate_var, lastprivate_var, collapse
665+
}];
666+
let arguments = (ins
667+
UnitAttr:$dist_schedule_static,
668+
Optional<IntLikeType>:$chunk_size,
669+
Variadic<AnyType>:$allocate_vars,
670+
Variadic<AnyType>:$allocators_vars,
671+
OptionalAttr<OrderKindAttr>:$order_val);
672+
673+
let regions = (region AnyRegion:$region);
674+
675+
let assemblyFormat = [{
676+
oilist(`dist_schedule_static` $dist_schedule_static
677+
|`chunk_size` `(` $chunk_size `:` type($chunk_size) `)`
678+
|`order` `(` custom<ClauseAttr>($order_val) `)`
679+
|`allocate` `(`
680+
custom<AllocateAndAllocator>(
681+
$allocate_vars, type($allocate_vars),
682+
$allocators_vars, type($allocators_vars)
683+
) `)`
684+
) $region attr-dict
685+
}];
686+
687+
let hasVerifier = 1;
688+
}
689+
639690
//===----------------------------------------------------------------------===//
640691
// 2.10.1 task Construct
641692
//===----------------------------------------------------------------------===//

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,22 @@ LogicalResult SimdLoopOp::verify() {
10531053
return success();
10541054
}
10551055

1056+
//===----------------------------------------------------------------------===//
1057+
// Verifier for Distribute construct [2.9.4.1]
1058+
//===----------------------------------------------------------------------===//
1059+
1060+
LogicalResult DistributeOp::verify() {
1061+
if (this->getChunkSize() && !this->getDistScheduleStatic())
1062+
return emitOpError() << "chunk size set without "
1063+
"dist_schedule_static being present";
1064+
1065+
if (getAllocateVars().size() != getAllocatorsVars().size())
1066+
return emitError(
1067+
"expected equal sizes for allocate and allocator variables");
1068+
1069+
return success();
1070+
}
1071+
10561072
//===----------------------------------------------------------------------===//
10571073
// ReductionOp
10581074
//===----------------------------------------------------------------------===//

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,36 @@ func.func @omp_simdloop_pretty_multiple(%lb1 : index, %ub1 : index, %step1 : ind
479479
return
480480
}
481481

482+
// CHECK-LABEL: omp_distribute
483+
func.func @omp_distribute(%chunk_size : i32, %data_var : memref<i32>) -> () {
484+
// CHECK: omp.distribute
485+
"omp.distribute" () ({
486+
omp.terminator
487+
}) {} : () -> ()
488+
// CHECK: omp.distribute
489+
omp.distribute {
490+
omp.terminator
491+
}
492+
// CHECK: omp.distribute dist_schedule_static
493+
omp.distribute dist_schedule_static {
494+
omp.terminator
495+
}
496+
// CHECK: omp.distribute dist_schedule_static chunk_size(%{{.+}} : i32)
497+
omp.distribute dist_schedule_static chunk_size(%chunk_size : i32) {
498+
omp.terminator
499+
}
500+
// CHECK: omp.distribute order(concurrent)
501+
omp.distribute order(concurrent) {
502+
omp.terminator
503+
}
504+
// CHECK: omp.distribute allocate(%{{.+}} : memref<i32> -> %{{.+}} : memref<i32>)
505+
omp.distribute allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {
506+
omp.terminator
507+
}
508+
return
509+
}
510+
511+
482512
// CHECK-LABEL: omp_target
483513
func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () {
484514

0 commit comments

Comments
 (0)