Skip to content

Commit 279e7ea

Browse files
committed
[MLIR][LinAlg][Docs] Add missing example code and other small fixes.
Fixes a few small issues in the docs. It seems one of the examples was missing the expected MLIR output due to a copy-paste typo. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D95599
1 parent c1c1944 commit 279e7ea

File tree

1 file changed

+49
-50
lines changed

1 file changed

+49
-50
lines changed

mlir/docs/Dialects/Linalg.md

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -94,22 +94,24 @@ layout, and the second one is a `memref` of 4-element vectors with a 2-strided,
9494
affine_map<(m) -> (m)>,
9595
affine_map<(m) -> (m)>
9696
]
97+
9798
#attrs = {
98-
args_in = 1,
99-
args_out = 1,
10099
indexing_maps = #accesses,
101100
iterator_types = ["parallel"]
102101
}
102+
103103
// memory layouts
104104
#identity = affine_map<(d0) -> (d0)>
105105
106106
func @example(%A: memref<?xf32, #identity>,
107107
%B: memref<?xvector<4xf32>, offset: 1, strides: [2]>) {
108-
linalg.generic #attrs %A, %B {
108+
linalg.generic #attrs
109+
ins(%A: memref<?xf32, #identity>)
110+
outs(%B: memref<?xvector<4xf32>, offset: 1, strides: [2]>) {
109111
^bb0(%a: f32, %b: vector<4xf32>):
110112
%c = "some_compute"(%a, %b): (f32, vector<4xf32>) -> (vector<4xf32>)
111113
linalg.yield %c: vector<4xf32>
112-
} : memref<?xf32, #identity>, memref<?xvector<4xf32>, offset: 1, strides: [2]>
114+
}
113115
return
114116
}
115117
```
@@ -173,34 +175,35 @@ Consider the following fully specified `linalg.generic` example. Here, the first
173175
`memref` is a 2-strided one on both of its dimensions, and the second `memref`
174176
uses an identity layout.
175177

176-
```
178+
```mlir
177179
// File name: example2.mlir
178180
#indexing_maps = [
179181
affine_map<(i, j) -> (j, i)>,
180182
affine_map<(i, j) -> (j)>
181183
]
184+
182185
#attrs = {
183-
args_in = 1,
184-
args_out = 1,
185186
indexing_maps = #indexing_maps,
186187
iterator_types = ["parallel", "parallel"]
187188
}
188189
189190
func @example(%A: memref<8x?xf32, offset: 0, strides: [2, 2]>,
190191
%B: memref<?xvector<4xf32>>) {
191-
linalg.generic #attrs %A, %B {
192+
linalg.generic #attrs
193+
ins(%A: memref<8x?xf32, offset: 0, strides: [2, 2]>)
194+
outs(%B: memref<?xvector<4xf32>>) {
192195
^bb0(%a: f32, %b: vector<4xf32>):
193196
%c = "some_compute"(%a, %b): (f32, vector<4xf32>) -> (vector<4xf32>)
194197
linalg.yield %c: vector<4xf32>
195-
}: memref<8x?xf32 , offset: 0, strides: [2, 2]>, memref<?xvector<4xf32>>
198+
}
196199
return
197200
}
198201
```
199202

200203
The property "*Reversible Mappings Between Control and Data Structures*" is
201204
materialized by a lowering into a form that will resemble:
202205

203-
```
206+
```mlir
204207
// Run: mlir-opt example2.mlir -allow-unregistered-dialect -convert-linalg-to-loops
205208
#map0 = affine_map<(d0, d1) -> (d0 * 2 + d1 * 2)>
206209
@@ -298,25 +301,24 @@ Previous examples already elaborate compute payloads with an unregistered
298301
function `"some_compute"`. The following code snippet shows what the result will
299302
be when using a concrete operation `addf`:
300303

301-
```
304+
```mlir
302305
// File name: example3.mlir
303-
#indexing_maps = [
304-
affine_map<(i, j) -> (i, j)>,
305-
affine_map<(i, j) -> (i, j)>,
306-
affine_map<(i, j) -> (i, j)>
307-
]
306+
#map = affine_map<(i, j) -> (i, j)>
307+
308308
#attrs = {
309-
args_in = 2,
310-
args_out = 1,
311-
indexing_maps = #indexing_maps,
309+
indexing_maps = [#map, #map, #map],
312310
iterator_types = ["parallel", "parallel"]
313311
}
312+
314313
func @example(%A: memref<?x?xf32>, %B: memref<?x?xf32>, %C: memref<?x?xf32>) {
315-
linalg.generic #attrs %A, %B, %C {
316-
^bb0(%a: f32, %b: f32, %c: f32):
317-
%d = addf %a, %b : f32
318-
linalg.yield %d : f32
319-
}: memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>
314+
linalg.generic #attrs
315+
ins(%A, %B: memref<?x?xf32>, memref<?x?xf32>)
316+
outs(%C: memref<?x?xf32>) {
317+
^bb0(%a: f32, %b: f32, %c: f32):
318+
%d = addf %a, %b : f32
319+
linalg.yield %d : f32
320+
}
321+
320322
return
321323
}
322324
```
@@ -327,25 +329,20 @@ stores the result into another one (`%C`).
327329
The property "*The Compute Payload is Specified With a Region*" is materialized
328330
by a lowering into a form that will resemble:
329331

330-
```
331-
// Run: mlir-opt example3.mlir -convert-linalg-to-loops
332-
#indexing_maps = [
333-
affine_map<(i, j) -> (i, j)>,
334-
affine_map<(i, j) -> (i, j)>,
335-
affine_map<(i, j) -> (i, j)>
336-
]
337-
#attrs = {
338-
args_in = 2,
339-
args_out = 1,
340-
indexing_maps = #indexing_maps,
341-
iterator_types = ["parallel", "parallel"]
342-
}
343-
func @example(%A: memref<?x?xf32>, %B: memref<?x?xf32>, %C: memref<?x?xf32>) {
344-
linalg.generic #attrs %A, %B, %C {
345-
^bb0(%a: f32, %b: f32, %c: f32):
346-
%d = addf %a, %b : f32
347-
linalg.yield %d : f32
348-
}: memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>
332+
```mlir
333+
func @example(%arg0: memref<?x?xf32>, %arg1: memref<?x?xf32>, %arg2: memref<?x?xf32>) {
334+
%c0 = constant 0 : index
335+
%c1 = constant 1 : index
336+
%0 = dim %arg0, %c0 : memref<?x?xf32>
337+
%1 = dim %arg0, %c1 : memref<?x?xf32>
338+
scf.for %arg3 = %c0 to %0 step %c1 {
339+
scf.for %arg4 = %c0 to %1 step %c1 {
340+
%2 = load %arg0[%arg3, %arg4] : memref<?x?xf32>
341+
%3 = load %arg1[%arg3, %arg4] : memref<?x?xf32>
342+
%4 = addf %2, %3 : f32
343+
store %4, %arg2[%arg3, %arg4] : memref<?x?xf32>
344+
}
345+
}
349346
return
350347
}
351348
```
@@ -372,34 +369,36 @@ Consider the following example that adds an additional attribute
372369
`library_call="pointwise_add"` that specifies the name of an external library
373370
call we intend to use:
374371

375-
```
372+
```mlir
376373
// File name: example4.mlir
377374
#indexing_maps = [
378375
affine_map<(i, j) -> (i, j)>,
379376
affine_map<(i, j) -> (i, j)>,
380377
affine_map<(i, j) -> (i, j)>
381378
]
379+
382380
#attrs = {
383-
args_in = 2,
384-
args_out = 1,
385381
indexing_maps = #indexing_maps,
386382
iterator_types = ["parallel", "parallel"],
387383
library_call = "pointwise_add"
388384
}
385+
389386
func @example(%A: memref<?x?xf32>, %B: memref<?x?xf32>, %C: memref<?x?xf32>) {
390-
linalg.generic #attrs %A, %B, %C {
387+
linalg.generic #attrs
388+
ins(%A, %B: memref<?x?xf32>, memref<?x?xf32>)
389+
outs(%C: memref<?x?xf32>) {
391390
^bb0(%a: f32, %b: f32, %c: f32):
392391
%d = addf %a, %b : f32
393392
linalg.yield %d : f32
394-
}: memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>
393+
}
395394
return
396395
}
397396
```
398397

399398
The property "*Map To an External Library Call*" is materialized by a lowering
400399
into a form that will resemble:
401400

402-
```
401+
```mlir
403402
// Run: mlir-opt example4.mlir -convert-linalg-to-std
404403
// Note that we lower the Linalg dialect directly to the Standard dialect.
405404
// See this doc: https://mlir.llvm.org/docs/Dialects/Standard/
@@ -418,7 +417,7 @@ func @pointwise_add(memref<?x?xf32, #map0>, memref<?x?xf32, #map0>, memref<?x?xf
418417

419418
Which, after lowering to LLVM resembles:
420419

421-
```
420+
```mlir
422421
// Run: mlir-opt example4.mlir -convert-linalg-to-std | mlir-opt -convert-std-to-llvm
423422
// Some generated code are omitted here.
424423
func @example(%arg0: !llvm<"float*">, ...) {

0 commit comments

Comments
 (0)