Skip to content

Commit 4fbe523

Browse files
committed
[MLIR][OpenMP] NFC: Document loop representation
This patch describes the loop wrapper approach to represent loop-associated constructs in the OpenMP MLIR dialect and documents current limitations and ongoing efforts.
1 parent 47e8403 commit 4fbe523

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

mlir/docs/Dialects/OpenMPDialect/_index.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,59 @@ corresponding operation, except if it is explicitly skipped as described
231231
[above](#overriding-clause-inherited-properties). This way, in case of a later
232232
tablegen failure while processing OpenMP dialect operations, earlier messages
233233
triggered by that pass can point to a likely solution.
234+
235+
## Loop-Associated Directives
236+
237+
Loop-associated OpenMP constructs are represented in the dialect as loop wrapper
238+
operations. These implement the `LoopWrapperInterface`, which enforces a series
239+
of restrictions upon the operation:
240+
- It contains a single region with a single block; and
241+
- Its block contains exactly two operations: another loop wrapper or
242+
`omp.loop_nest` operation and a terminator.
243+
244+
This approach splits the representation for a loop nest and the loop-associated
245+
constructs that specify how its iterations are executed, possibly across various
246+
SIMD lanes (`omp.simd`), threads (`omp.wsloop`), teams of threads
247+
(`omp.distribute`) or tasks (`omp.taskloop`). The ability to directly nest
248+
multiple loop wrappers to impact the execution of a single loop nest is used to
249+
represent composite constructs in a modular way.
250+
251+
The `omp.loop_nest` operation represents a collapsed rectangular loop nest that
252+
must always be wrapped by at least one loop wrapper, which defines how it is
253+
intended to be executed. It serves as a simpler and more restrictive
254+
representation of OpenMP loops while a more general approach to support
255+
non-rectangular loop nests, loop transformations and non-perfectly nested loops
256+
based on a new `omp.canonical_loop` definition is developed.
257+
258+
The following example shows how a `parallel {do,for}` construct would be
259+
represented:
260+
```mlir
261+
omp.parallel ... {
262+
...
263+
omp.wsloop ... {
264+
omp.loop_nest (%i) : index = (%lb) to (%ub) step (%step) {
265+
%a = load %a[%i] : memref<?xf32>
266+
%b = load %b[%i] : memref<?xf32>
267+
%sum = arith.addf %a, %b : f32
268+
store %sum, %c[%i] : memref<?xf32>
269+
omp.yield
270+
}
271+
omp.terminator
272+
}
273+
...
274+
omp.terminator
275+
}
276+
```
277+
278+
### Loop Transformations
279+
280+
In addition to the worksharing loop-associated constructs described above, the
281+
OpenMP specification also defines a set of loop transformation constructs. They
282+
replace the associated loop(s) before worksharing constructs are executed on the
283+
generated loop(s). Some examples of such constructs are `tile` and `unroll`.
284+
285+
A general approach for representing these types of OpenMP constructs has not yet
286+
been implemented, but it is closely linked to the `omp.canonical_loop` work.
287+
Nevertheless, loop transformation that the `collapse` clause for loop-associated
288+
worksharing constructs defines can be represented by introducing multiple
289+
bounds, step and induction variables to the `omp.loop_nest` operation.

0 commit comments

Comments
 (0)