[Mlir-commits] [mlir] [MLIR][Linalg][Docs] Add forms to Linalg rationale docs (PR #156859)
Renato Golin
llvmlistbot at llvm.org
Mon Sep 8 06:42:54 PDT 2025
https://github.com/rengolin updated https://github.com/llvm/llvm-project/pull/156859
>From f02a88b06601480dce258009b152d15ef70fb379 Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Wed, 3 Sep 2025 11:27:25 +0100
Subject: [PATCH 1/4] [MLIR][Linalg][Docs] Add forms to Linalg rationale docs
As discussed in:
* https://discourse.llvm.org/t/rfc-linalg-forms/87994/
* https://discourse.llvm.org/t/rfc-extend-linalg-elemwise-named-ops-semantics/83927
* https://discourse.llvm.org/t/rfc-op-explosion-in-linalg/82863/1
* https://discourse.llvm.org/t/rfc-mlir-linalg-operation-tree/83586
---
mlir/docs/Rationale/RationaleLinalgDialect.md | 87 ++++++++++++++++---
1 file changed, 73 insertions(+), 14 deletions(-)
diff --git a/mlir/docs/Rationale/RationaleLinalgDialect.md b/mlir/docs/Rationale/RationaleLinalgDialect.md
index 8975b0a7d515e..4426d3fb9b3c2 100644
--- a/mlir/docs/Rationale/RationaleLinalgDialect.md
+++ b/mlir/docs/Rationale/RationaleLinalgDialect.md
@@ -411,6 +411,20 @@ and is used as a lowering target for Linalg, enabling further transformations
and combination of semantically-loaded and lower-level inputs. As such, Linalg
is intended to complement Affine rather than replace it.
+### Summary of Existing Alternatives a Picture<a name="observationssummary"></a>
+Lastly, we summarize our observations of lessons from [Prior
+Art](#prior-art)---when viewed under the lense of our [Core Guiding
+Principles](#guiding_principles)---with the following picture.
+
+<img width="1200" alt="MLIR Codegen Flow"
+src="https://user-images.githubusercontent.com/10148468/73613904-2f720a00-45c8-11ea-8265-1c856c02525b.png">
+
+This figure is not meant to be perfectly accurate but a rough map of how we view
+the distribution of structural information in existing systems, from a
+codegen-friendly angle. Unsurprisingly, the
+[Linalg Dialect](../Dialects/Linalg/_index.md) and its future evolutions aspire
+to a position in the top-right of this map.
+
## Core Guiding Principles<a name="guiding_principles"></a>
### Transformations and Simplicity First<a name="transformations_first"></a>
@@ -506,6 +520,65 @@ potential by introducing lower-level IR ops and *smaller* Linalg ops.
This gradually reduces the potential, all the way to Loops + VectorOps
and LLVMIR.
+### Interchangeability of Forms<a name="forms"></a>
+
+Linalg's various forms (named, generic) also carry information, and that
+information should be preserved as much as possible during the progressive
+lowering. A `matmul` operation is a special case of a `contract` operation,
+which in turn is a special case of `generic` operation. Transformations on
+the more special forms should not be converted to the more generic ones
+unnecessarily, in the same way that they should not be broken down into
+loops + arithmetic if they can still be represented as a Linalg op.
+
+#### Generic, Category, Named<a name="generic_category_named"></a>
+
+The core Linalg operation tree has three forms:
+* **Generic:** Represented by `linalg.generic` and can encode all perfectly-nested
+loop operations.
+* **Category:** Represented by `linalg.contract` and `linalg.elementwise`,
+which are special (einsum) forms of the `generic` operation.
+* **Named:** All _named_ forms that can lower to either _category_ or
+_generic_ forms. For example, `linalg.matmul`, `linalg.add`, etc.
+
+Unlike lowering to loops, the different Linalg forms that are derived from
+`linalg.generic` are *equivalent*. It should always be possible to convert
+a named operation into a generic and back to named, if the semantics is
+preserved. The various forms in the Linalg dialect are meant to facilitate
+pattern matching (single operations or DAGs) and to be able to consider
+different forms as *canonical* for different transforms.
+
+#### Special Operations<a name="special_ops"></a>
+
+Not all Linalg operations represent perfectly nested loops, and therefore
+cannot be represented as a `linalg.generic`. There are two kinds of Linalg
+operations that fall into this category:
+* **Composite:** Operations that compose multiple Linalg operations, for
+example `linalg.softmax`. These can be converted to a DAG of Linalg operations
+(in any form).
+* **Special Named:** Operations that are usually matched against library calls
+or special lowering, but can only be lowered to a combination of Linalg and
+non-Linalg operations, for example `linalg.*conv*`, `linalg.winograd*`,
+`linalg.pooling*`, etc.
+
+#### Canonical Forms<a name="canonical_forms"></a>
+
+With multiple (often exchangeable) forms, and with transformation simplicity
+in mind, compilers should aim for reducing matching and replacing complexity
+as much as possible. When matching a single operation with a complex pattern,
+having all the information from a `generic` is useful to iteratively match
+different patterns in turn. However, when assembling a DAG of operations to
+form a pattern, it's much simpler to match against named operations (like
+`max` + `div` + `reduce` + `broadcast`) than their generic counterparts.
+
+This is where the interchangeability of forms comes in handy. Linalg has the
+ability to specialize and generalize in order to convert the IR to a form that
+is easier for a particular type of transform. With forms being semantically
+equivalent, one can convert back-and-forth throughout the various transforms
+to match the needs of each transform. For that particular transform, such
+form can be considered _canonical_ and therefore "expected" for the pattern
+to _match_. This reduces complexity of pattern matchers and simplifies compiler
+pipelines.
+
### Composable and Declarative Transformations<a name="declarative_transformations"></a>
Complex and impactful transformations need not be hard to manipulate, write or
maintain. Mixing XLA-style high-level op semantics knowledge with generic
@@ -606,17 +679,3 @@ Considering the *potential* described during the discussion on
transformation would dictate that the potential remains constant.
In contrast, Linalg advocates for ***monotonicity*** under
transformations.
-
-### Summary of Existing Alternatives a Picture<a name="observationssummary"></a>
-Lastly, we summarize our observations of lessons from [Prior
-Art](#prior-art)---when viewed under the lense of our [Core Guiding
-Principles](#guiding_principles)---with the following picture.
-
-<img width="1200" alt="MLIR Codegen Flow"
-src="https://user-images.githubusercontent.com/10148468/73613904-2f720a00-45c8-11ea-8265-1c856c02525b.png">
-
-This figure is not meant to be perfectly accurate but a rough map of how we view
-the distribution of structural information in existing systems, from a
-codegen-friendly angle. Unsurprisingly, the
-[Linalg Dialect](../Dialects/Linalg/_index.md) and its future evolutions aspire
-to a position in the top-right of this map.
>From 5173b90a06c407027a940ca892007e6c3c0fa979 Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Thu, 4 Sep 2025 16:31:29 +0100
Subject: [PATCH 2/4] revert unrelated change
---
mlir/docs/Rationale/RationaleLinalgDialect.md | 28 +++++++++----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/mlir/docs/Rationale/RationaleLinalgDialect.md b/mlir/docs/Rationale/RationaleLinalgDialect.md
index 4426d3fb9b3c2..9f85921c43b81 100644
--- a/mlir/docs/Rationale/RationaleLinalgDialect.md
+++ b/mlir/docs/Rationale/RationaleLinalgDialect.md
@@ -411,20 +411,6 @@ and is used as a lowering target for Linalg, enabling further transformations
and combination of semantically-loaded and lower-level inputs. As such, Linalg
is intended to complement Affine rather than replace it.
-### Summary of Existing Alternatives a Picture<a name="observationssummary"></a>
-Lastly, we summarize our observations of lessons from [Prior
-Art](#prior-art)---when viewed under the lense of our [Core Guiding
-Principles](#guiding_principles)---with the following picture.
-
-<img width="1200" alt="MLIR Codegen Flow"
-src="https://user-images.githubusercontent.com/10148468/73613904-2f720a00-45c8-11ea-8265-1c856c02525b.png">
-
-This figure is not meant to be perfectly accurate but a rough map of how we view
-the distribution of structural information in existing systems, from a
-codegen-friendly angle. Unsurprisingly, the
-[Linalg Dialect](../Dialects/Linalg/_index.md) and its future evolutions aspire
-to a position in the top-right of this map.
-
## Core Guiding Principles<a name="guiding_principles"></a>
### Transformations and Simplicity First<a name="transformations_first"></a>
@@ -679,3 +665,17 @@ Considering the *potential* described during the discussion on
transformation would dictate that the potential remains constant.
In contrast, Linalg advocates for ***monotonicity*** under
transformations.
+
+### Summary of Existing Alternatives a Picture<a name="observationssummary"></a>
+Lastly, we summarize our observations of lessons from [Prior
+Art](#prior-art)---when viewed under the lense of our [Core Guiding
+Principles](#guiding_principles)---with the following picture.
+
+<img width="1200" alt="MLIR Codegen Flow"
+src="https://user-images.githubusercontent.com/10148468/73613904-2f720a00-45c8-11ea-8265-1c856c02525b.png">
+
+This figure is not meant to be perfectly accurate but a rough map of how we view
+the distribution of structural information in existing systems, from a
+codegen-friendly angle. Unsurprisingly, the
+[Linalg Dialect](../Dialects/Linalg/_index.md) and its future evolutions aspire
+to a position in the top-right of this map.
>From 829c235693a42e26aff8b2c8d998243e073d79cf Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Fri, 5 Sep 2025 14:44:41 +0100
Subject: [PATCH 3/4] in a generic
---
mlir/docs/Rationale/RationaleLinalgDialect.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/docs/Rationale/RationaleLinalgDialect.md b/mlir/docs/Rationale/RationaleLinalgDialect.md
index 9f85921c43b81..c337bc82193b9 100644
--- a/mlir/docs/Rationale/RationaleLinalgDialect.md
+++ b/mlir/docs/Rationale/RationaleLinalgDialect.md
@@ -551,7 +551,7 @@ non-Linalg operations, for example `linalg.*conv*`, `linalg.winograd*`,
With multiple (often exchangeable) forms, and with transformation simplicity
in mind, compilers should aim for reducing matching and replacing complexity
as much as possible. When matching a single operation with a complex pattern,
-having all the information from a `generic` is useful to iteratively match
+having all the information in a `generic` is useful to iteratively match
different patterns in turn. However, when assembling a DAG of operations to
form a pattern, it's much simpler to match against named operations (like
`max` + `div` + `reduce` + `broadcast`) than their generic counterparts.
>From 2f99df5444ab8641ffe689ef3234072c49a945cb Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Mon, 8 Sep 2025 14:42:44 +0100
Subject: [PATCH 4/4] Apply suggestions from code review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Andrzej WarzyĆski <andrzej.warzynski at gmail.com>
---
mlir/docs/Rationale/RationaleLinalgDialect.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/docs/Rationale/RationaleLinalgDialect.md b/mlir/docs/Rationale/RationaleLinalgDialect.md
index c337bc82193b9..c573085acc339 100644
--- a/mlir/docs/Rationale/RationaleLinalgDialect.md
+++ b/mlir/docs/Rationale/RationaleLinalgDialect.md
@@ -516,7 +516,7 @@ the more special forms should not be converted to the more generic ones
unnecessarily, in the same way that they should not be broken down into
loops + arithmetic if they can still be represented as a Linalg op.
-#### Generic, Category, Named<a name="generic_category_named"></a>
+#### The Linalg Forms
The core Linalg operation tree has three forms:
* **Generic:** Represented by `linalg.generic` and can encode all perfectly-nested
@@ -528,7 +528,7 @@ _generic_ forms. For example, `linalg.matmul`, `linalg.add`, etc.
Unlike lowering to loops, the different Linalg forms that are derived from
`linalg.generic` are *equivalent*. It should always be possible to convert
-a named operation into a generic and back to named, if the semantics is
+a named operation into a generic and back to named, if the semantics are
preserved. The various forms in the Linalg dialect are meant to facilitate
pattern matching (single operations or DAGs) and to be able to consider
different forms as *canonical* for different transforms.
More information about the Mlir-commits
mailing list