Skip to content

Commit 570b8b4

Browse files
authored
Extend pipeline helper to schedules (#70)
So we can share the same bundles across pipelines and schedules.
1 parent ebf0789 commit 570b8b4

File tree

3 files changed

+60
-22
lines changed

3 files changed

+60
-22
lines changed

examples/ingress/torch/compile_model.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ def lower_to_llvm(module: ir.Module) -> ir.Module:
3535
add_bundle(pm, PassBundles.BufferizationBundle)
3636
add_bundle(pm, PassBundles.CleanupBundle)
3737

38+
# Middle-end lowering.
39+
add_bundle(pm, PassBundles.MLIRLoweringBundle)
40+
3841
# Lower to LLVM.
3942
add_bundle(pm, PassBundles.LLVMLoweringBundle)
4043
add_bundle(pm, PassBundles.CleanupBundle)

examples/workload/example.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
from mlir.dialects import transform
1919
from mlir.execution_engine import ExecutionEngine
2020

21-
from lighthouse.pipeline.helper import apply_registered_pass, canonicalize, match
21+
from lighthouse.pipeline.helper import (
22+
PassBundles,
23+
apply_bundle,
24+
match,
25+
)
2226
from lighthouse.workload import Workload, execute, benchmark
2327

2428

@@ -141,21 +145,15 @@ def schedule_module(
141145
op_name="builtin.module",
142146
deduplicate=True,
143147
)
144-
mod = apply_registered_pass(mod, "one-shot-bufferize")
145-
mod = apply_registered_pass(mod, "convert-linalg-to-loops")
146-
transform.apply_cse(mod)
147-
canonicalize(mod)
148+
mod = apply_bundle(mod, PassBundles.BufferizationBundle)
149+
mod = apply_bundle(mod, PassBundles.MLIRLoweringBundle)
150+
mod = apply_bundle(mod, PassBundles.CleanupBundle)
148151

149152
if stop_at_stage == "bufferized":
150153
transform.YieldOp()
151154
return schedule_module
152155

153-
mod = apply_registered_pass(mod, "convert-scf-to-cf")
154-
mod = apply_registered_pass(mod, "finalize-memref-to-llvm")
155-
mod = apply_registered_pass(mod, "convert-cf-to-llvm")
156-
mod = apply_registered_pass(mod, "convert-arith-to-llvm")
157-
mod = apply_registered_pass(mod, "convert-func-to-llvm")
158-
mod = apply_registered_pass(mod, "reconcile-unrealized-casts")
156+
mod = apply_bundle(mod, PassBundles.LLVMLoweringBundle)
159157
transform.YieldOp()
160158

161159
return schedule_module

lighthouse/pipeline/helper.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@
44
from mlir.dialects.transform import structured
55

66

7+
class Pass:
8+
"""
9+
A simple wrapper class for MLIR passes.
10+
The options can be serialized into a string for consumption by the PassManager.
11+
Or used directly with the Transform Schedule by passing the options as a dictionary.
12+
"""
13+
14+
def __init__(self, name: str, options: dict = {}):
15+
self.name = name
16+
self.options = options
17+
18+
def __str__(self) -> str:
19+
"""serialize name + options dictionary for pass manager consumption"""
20+
if not self.options:
21+
return self.name
22+
options_str = " ".join(f"{key}={value}" for key, value in self.options.items())
23+
return f"{self.name}{{{options_str}}}"
24+
25+
726
class PassBundles:
827
"""
928
Predefined pass bundles for common transformations. These are not exhaustive and can be extended as needed.
@@ -12,30 +31,48 @@ class PassBundles:
1231

1332
# All in one bufferization bundle. This is self consistent and should be used together.
1433
BufferizationBundle = [
15-
"one-shot-bufferize{function-boundary-type-conversion=identity-layout-map bufferize-function-boundaries}",
16-
"drop-equivalent-buffer-results",
17-
"buffer-deallocation-pipeline",
34+
Pass(
35+
"one-shot-bufferize",
36+
{
37+
"function-boundary-type-conversion": "identity-layout-map",
38+
"bufferize-function-boundaries": True,
39+
},
40+
),
41+
Pass("drop-equivalent-buffer-results"),
42+
# This last pass only works with the pass manager, not schedules.
43+
# Pass("buffer-deallocation-pipeline"),
44+
]
45+
46+
# Lowers most dialects to basic control flow.
47+
MLIRLoweringBundle = [
48+
Pass("convert-linalg-to-loops"),
1849
]
1950

2051
# Lowers most dialects to LLVM Dialect
2152
LLVMLoweringBundle = [
22-
"convert-linalg-to-loops",
23-
"convert-scf-to-cf",
24-
"convert-to-llvm",
25-
"reconcile-unrealized-casts",
53+
Pass("convert-scf-to-cf"),
54+
Pass("convert-to-llvm"),
55+
Pass("reconcile-unrealized-casts"),
2656
]
2757

2858
# Canonicalization bundle. This is a set of passes that can be used to clean up the IR after transformations.
2959
CleanupBundle = [
30-
"cse",
31-
"canonicalize",
60+
Pass("cse"),
61+
Pass("canonicalize"),
3262
]
3363

3464

3565
# Utility function to add a bundle of passes to a PassManager. This can be used to easily add a predefined set of passes to a pipeline.
36-
def add_bundle(pm: PassManager, bundle: list[str]) -> None:
66+
def add_bundle(pm: PassManager, bundle: list[Pass]) -> None:
67+
for p in bundle:
68+
pm.add(str(p))
69+
70+
71+
# Utility function to add a bundle of passes to a Schedule. This can be used to easily add a predefined set of passes to a pipeline.
72+
def apply_bundle(op, bundle: list[Pass], *args, **kwargs) -> None:
3773
for p in bundle:
38-
pm.add(p)
74+
op = apply_registered_pass(op, p.name, options=p.options, *args, **kwargs)
75+
return op
3976

4077

4178
# Utility function to add a bundle of passes to a Transform Schedule. This can be used to easily add a predefined set of passes to a pipeline.

0 commit comments

Comments
 (0)