[llvm-branch-commits] [mlir] [MLIR][OpenMP][Docs] NFC: Document compound constructs representation (PR #107236)
Sergio Afonso via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Sep 5 03:25:43 PDT 2024
https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/107236
>From da68c8b8be9588251bb4342e869a52035fc45a8e Mon Sep 17 00:00:00 2001
From: Sergio Afonso <safonsof at amd.com>
Date: Wed, 4 Sep 2024 13:21:22 +0100
Subject: [PATCH 1/2] [MLIR][OpenMP] NFC: Document compound constructs
representation
This patch documents the MLIR representation of OpenMP compound constructs
discussed in
[this](https://discourse.llvm.org/t/rfc-representing-combined-composite-constructs-in-the-openmp-dialect/76986)
and
[this](https://discourse.llvm.org/t/rfc-disambiguation-between-loop-and-block-associated-omp-parallelop/79972)
RFC.
---
mlir/docs/Dialects/OpenMPDialect/_index.md | 114 +++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/mlir/docs/Dialects/OpenMPDialect/_index.md b/mlir/docs/Dialects/OpenMPDialect/_index.md
index 65b9c5d79f73e9..28ebb1fe3cf3f8 100644
--- a/mlir/docs/Dialects/OpenMPDialect/_index.md
+++ b/mlir/docs/Dialects/OpenMPDialect/_index.md
@@ -287,3 +287,117 @@ been implemented, but it is closely linked to the `omp.canonical_loop` work.
Nevertheless, loop transformation that the `collapse` clause for loop-associated
worksharing constructs defines can be represented by introducing multiple
bounds, step and induction variables to the `omp.loop_nest` operation.
+
+## Compound Construct Representation
+
+The OpenMP specification defines certain shortcuts that allow specifying
+multiple constructs in a single directive, which are referred to as compound
+constructs (e.g. `parallel do` contains the `parallel` and `do` constructs).
+These can be further classified into [combined](#combined-constructs) and
+[composite](#composite-constructs) constructs. This section describes how they
+are represented in the dialect.
+
+When clauses are specified for compound constructs, the OpenMP specification
+defines a set of rules to decide to which leaf constructs they apply, as well as
+potentially introducing some other implicit clauses. These rules must be taken
+into account by those creating the MLIR representation, since it is a per-leaf
+representation that expects these rules to have already been followed.
+
+### Combined Constructs
+
+Combined constructs are semantically equivalent to specifying one construct
+immediately nested inside another. This property is used to simplify the dialect
+by representing them through the operations associated to each leaf construct.
+For example, `target teams` would be represented as follows:
+
+```mlir
+omp.target ... {
+ ...
+ omp.teams ... {
+ ...
+ omp.terminator
+ }
+ ...
+ omp.terminator
+}
+```
+
+### Composite Constructs
+
+Composite constructs are similar to combined constructs in that they specify the
+effect of one construct being applied immediately after another. However, they
+group together constructs that cannot be directly nested into each other.
+Specifically, they group together multiple loop-associated constructs that apply
+to the same collapsed loop nest.
+
+As of version 5.2 of the OpenMP specification, the list of composite constructs
+is the following:
+ - `{do,for} simd`;
+ - `distribute simd`;
+ - `distribute parallel {do,for}`;
+ - `distribute parallel {do,for} simd`; and
+ - `taskloop simd`.
+
+Even though the list of composite constructs is relatively short and it would
+also be possible to create dialect operations for each, it was decided to
+allow attaching multiple loop wrappers to a single loop instead. This minimizes
+redundancy in the dialect and maximizes its modularity, since there is a single
+operation for each leaf construct regardless of whether it can be part of a
+composite construct. On the other hand, this means the `omp.loop_nest` operation
+will have to be interpreted differently depending on how many and which loop
+wrappers are attached to it.
+
+To simplify the detection of operations taking part in the representation of a
+composite construct, the `ComposableOpInterface` was introduced. Its purpose is
+to handle the `omp.composite` discardable dialect attribute that can optionally
+be attached to these operations. Operation verifiers will ensure its presence is
+consistent with the context the operation appears in, so that it is valid when
+the attribute is present if and only if it represents a leaf of a composite
+construct.
+
+For example, the `distribute simd` composite construct is represented as
+follows:
+
+```mlir
+omp.distribute ... {
+ omp.simd ... {
+ omp.loop_nest (%i) : index = (%lb) to (%ub) step (%step) {
+ ...
+ omp.yield
+ }
+ omp.terminator
+ } {omp.composite}
+ omp.terminator
+} {omp.composite}
+```
+
+One exception to this is the representation of the
+`distribute parallel {do,for}` composite construct. The presence of a
+block-associated `parallel` leaf construct would introduce many problems if it
+was allowed to work as a loop wrapper. In this case, the "hoisted `omp.parallel`
+representation" is used instead. This consists in making `omp.parallel` the
+parent operation, with a nested `omp.loop_nest` wrapped by `omp.distribute` and
+`omp.wsloop` (and `omp.simd`, in the `distribute parallel {do,for} simd` case).
+
+This approach works because `parallel` is a parallelism-generating construct,
+whereas `distribute` is a worksharing construct impacting the higher level
+`teams`, making the ordering between these constructs not cause semantic
+mismatches. This property is also exploited by LLVM's SPMD-mode.
+
+```mlir
+omp.parallel ... {
+ ...
+ omp.distribute ... {
+ omp.wsloop ... {
+ omp.loop_nest (%i) : index = (%lb) to (%ub) step (%step) {
+ ...
+ omp.yield
+ }
+ omp.terminator
+ } {omp.composite}
+ omp.terminator
+ } {omp.composite}
+ ...
+ omp.terminator
+} {omp.composite}
+```
>From 5989ece71a78e23c9e0ef870909d17126c7188c1 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <safonsof at amd.com>
Date: Thu, 5 Sep 2024 11:25:30 +0100
Subject: [PATCH 2/2] Address review comments
---
mlir/docs/Dialects/OpenMPDialect/_index.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/docs/Dialects/OpenMPDialect/_index.md b/mlir/docs/Dialects/OpenMPDialect/_index.md
index 28ebb1fe3cf3f8..c12a899d158864 100644
--- a/mlir/docs/Dialects/OpenMPDialect/_index.md
+++ b/mlir/docs/Dialects/OpenMPDialect/_index.md
@@ -381,8 +381,8 @@ parent operation, with a nested `omp.loop_nest` wrapped by `omp.distribute` and
This approach works because `parallel` is a parallelism-generating construct,
whereas `distribute` is a worksharing construct impacting the higher level
-`teams`, making the ordering between these constructs not cause semantic
-mismatches. This property is also exploited by LLVM's SPMD-mode.
+`teams` construct, making the ordering between these constructs not cause
+semantic mismatches. This property is also exploited by LLVM's SPMD-mode.
```mlir
omp.parallel ... {
More information about the llvm-branch-commits
mailing list