diff --git a/mlir/docs/Dialects/Linalg.md b/mlir/docs/Dialects/Linalg.md --- a/mlir/docs/Dialects/Linalg.md +++ b/mlir/docs/Dialects/Linalg.md @@ -50,7 +50,34 @@ operations with *index-free semantics* (resp. *indexing semantics*). The properties of these generic ops are the result of applying the guiding principles described in the [Rationale Document](../Rationale/RationaleLinalgDialect.md). -They are listed next, with a brief example and discussion for each. +These properties are illustrated in the following sections by examining this example code snippet: + +```mlir +// File name: linalg_example.mlir +#accesses = [ + affine_map<(d0) -> (d0)>, + affine_map<(d0) -> (d0)> +] +#attrs = { + args_in = 1, + args_out = 1, + indexing_maps = #accesses, + iterator_types = ["parallel"] +} + +// This function operates on two `memref` objects that store scalar and +// vector respectively, by an arbitrary function named "some_compute". +// "some_compute" applies on elements from both `memref`s in a pair-wise manner. +func @example(%A: memref, + %B: memref>) { + linalg.generic #attrs %A, %B { + ^bb0(%a: f32, %b: vector<4xf32>): + %c = "some_compute"(%a, %b): (f32, vector<4xf32>) -> (vector<4xf32>) + linalg.yield %c: vector<4xf32> + } : memref, memref> + return +} +``` #### Property 1: Input and Output Operands Define The Iteration Space A `linalg.generic` op fully *derives* the specification of its iteration space @@ -60,34 +87,23 @@ according to their type. This notion of IR localization bears some resemblance to [URUK](http://icps.u-strasbg.fr/~bastoul/research/papers/GVBCPST06-IJPP.pdf). -Consider the following, partially specified, `linalg.generic` example: -``` -#attrs = {args_in: 1, args_out: 1} -func @example(%A: memref, - %B: memref>) { - linalg.generic #attrs (%2, %3): memref, - memref> - return -} -``` - The property "*Input and Output Operands Define The Iteration Space*" is materialized by a lowering into a form that will resemble: + ``` -func @example(%A: memref, - %B: memref>) { - %M = "dim" %A, 0: index - %N = "dim" %B, 0: index - %eq = eq %M, %N: i1 // iteration space is consistent with data - assert(%eq): (i1) -> () - for %i = 0 to %M { - %a = load %A[%i]: memref - %b = load %B[%i]: memref, layout2> - // compute arg types match elemental tensor types - %c = "some_compute"(%a, %b): (f32, vector<4xf32>) -> (vector<4xf32>) - store %c, %B[%i]: memref, layout2> +module { + func @example(%arg0: memref, %arg1: memref>) { + %c0 = constant 0 : index + %c1 = constant 1 : index + %0 = dim %arg0, %c0 : memref + scf.for %arg2 = %c0 to %0 step %c1 { + %1 = load %arg0[%arg2] : memref + %2 = load %arg1[%arg2] : memref> + %3 = "some_compute"(%1, %2) : (f32, vector<4xf32>) -> vector<4xf32> + store %3, %arg1[%arg2] : memref> + } + return } - return } ```