Skip to content

Commit 4e52e6a

Browse files
authored
[MLIR][OpenMP] Document entry block argument-defining clauses (NFC) (#109811)
This patch adds general information on the proposed approach to unify the handling and representation of clauses that define entry block arguments attached to operations that accept them.
1 parent c63112a commit 4e52e6a

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

mlir/docs/Dialects/OpenMPDialect/_index.md

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ and optional list of `traits`, a list of `clauses` where all the applicable
132132
would have to be defined in the operation's body are the `summary` and
133133
`description`. For the latter, only the operation itself would have to be
134134
defined, and the description for its clause-inherited arguments is appended
135-
through the inherited `clausesDescription` property.
135+
through the inherited `clausesDescription` property. By convention, the list of
136+
clauses for an operation must be specified in alphabetical order.
136137

137138
If the operation is intended to have a single region, this is better achieved by
138139
setting the `singleRegion=true` template argument of `OpenMP_Op` rather manually
@@ -285,7 +286,76 @@ argument's type:
285286
specific `mlir::Attribute` subclass) will be used instead.
286287
- Other attribute types will be represented with their `storageType`.
287288
- It will create `<Name>Operands` structure for each operation, which is an
288-
empty structure subclassing all operand structures defined for the corresponding `OpenMP_Op`'s clauses.
289+
empty structure subclassing all operand structures defined for the corresponding
290+
`OpenMP_Op`'s clauses.
291+
292+
### Entry Block Argument-Defining Clauses
293+
294+
In their MLIR representation, certain OpenMP clauses introduce a mapping between
295+
values defined outside the operation they are applied to and entry block
296+
arguments for the region of that MLIR operation. This enables, for example, the
297+
introduction of private copies of the same underlying variable defined outside
298+
the MLIR operation the clause is attached to. Currently, clauses with this
299+
property can be classified into three main categories:
300+
- Map-like clauses: `map`, `use_device_addr` and `use_device_ptr`.
301+
- Reduction-like clauses: `in_reduction`, `reduction` and `task_reduction`.
302+
- Privatization clauses: `private`.
303+
304+
All three kinds of entry block argument-defining clauses use a similar custom
305+
assembly format representation, only differing based on the different pieces of
306+
information attached to each kind. Below, one example of each is shown:
307+
308+
```mlir
309+
omp.target map_entries(%x -> %x.m, %y -> %y.m : !llvm.ptr, !llvm.ptr) {
310+
// Use %x.m, %y.m in place of %x and %y...
311+
}
312+
313+
omp.wsloop reduction(@add.i32 %x -> %x.r, byref @add.f32 %y -> %y.r : !llvm.ptr, !llvm.ptr) {
314+
// Use %x.r, %y.r in place of %x and %y...
315+
}
316+
317+
omp.parallel private(@x.privatizer %x -> %x.p, @y.privatizer %y -> %y.p : !llvm.ptr, !llvm.ptr) {
318+
// Use %x.p, %y.p in place of %x and %y...
319+
}
320+
```
321+
322+
As a consequence of parsing and printing the operation's first region entry
323+
block argument names together with the custom assembly format of these clauses,
324+
entry block arguments (i.e. the `^bb0(...):` line) must not be explicitly
325+
defined for these operations. Additionally, it is not possible to implement this
326+
feature while allowing each clause to be independently parsed and printed,
327+
because they need to be printed/parsed together with the corresponding
328+
operation's first region. They must have a well-defined ordering in which
329+
multiple of these clauses are specified for a given operation, as well.
330+
331+
The parsing/printing of these clauses together with the region provides the
332+
ability to define entry block arguments directly after the `->`. Forcing a
333+
specific ordering between these clauses makes the block argument ordering
334+
well-defined, which is the property used to easily match each clause with the
335+
entry block arguments defined by it.
336+
337+
Custom printers and parsers for operation regions based on the entry block
338+
argument-defining clauses they take are implemented based on the
339+
`{parse,print}BlockArgRegion` functions, which take care of the sorting and
340+
formatting of each kind of clause, minimizing code duplication resulting from
341+
this approach. One example of the custom assembly format of an operation taking
342+
the `private` and `reduction` clauses is the following:
343+
344+
```tablegen
345+
let assemblyFormat = clausesAssemblyFormat # [{
346+
custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
347+
$private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
348+
$reduction_syms) attr-dict
349+
}];
350+
```
351+
352+
The `BlockArgOpenMPOpInterface` has been introduced to simplify the addition and
353+
handling of these kinds of clauses. It holds `num<ClauseName>BlockArgs()`
354+
functions that by default return 0, to be overriden by each clause through the
355+
`extraClassDeclaration` property. Based on these functions and the expected
356+
alphabetical sorting between entry block argument-defining clauses, it
357+
implements `get<ClauseName>BlockArgs()` functions that are the intended method
358+
of accessing clause-defined block arguments.
289359

290360
## Loop-Associated Directives
291361

0 commit comments

Comments
 (0)