Skip to content

Commit 34d233e

Browse files
committed
Refactor InductorBackend: simplify config template and torch.compile integration
- Rename to for clarity - Remove redundant and templates (merge into ) - Add mutual exclusion check: exactly one of template/mode/options can be specified - Remove global config modification; use torch.compile's parameter directly - Clean up mapping (template no longer affects mode) - Update tests to reflect template exclusivity and parameter changes - Simplify __call__ with inline conditional kwargs expansion Templates now exclusively control torch._inductor.config options, while is passed directly to torch.compile without interference.
1 parent cf2571a commit 34d233e

2 files changed

Lines changed: 175 additions & 260 deletions

File tree

graph_net_bench/torch/backend/inductor_backend.py

Lines changed: 55 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@
33
from .graph_compiler_backend import GraphCompilerBackend
44

55

6-
# Predefined Inductor config templates.
7-
# Each template maps to a set of torch._inductor.config overrides.
8-
# Reference: https://github.com/pytorch/pytorch/blob/main/torch/_inductor/config.py
9-
#
10-
# Note: These are extension to PyTorch's official "mode" concept.
11-
# PyTorch modes: "default", "reduce-overhead", "max-autotune", "max-autotune-no-cudagraphs"
12-
# These templates provide additional config combinations for specific use cases.
6+
# Predefined Inductor config templates for GraphNet.
7+
# Each template maps to a set of torch._inductor.config options.
138
_INDUCTOR_CONFIG_TEMPLATES = {
149
"triton": {
1510
# Default Triton code generation (Inductor's default behavior).
@@ -21,31 +16,16 @@
2116
# Reference: torch._inductor.config.cpp_wrapper
2217
"cpp_wrapper": True,
2318
},
24-
"cutlass": {
25-
# Enable max-autotune to potentially use CUTLASS-based GEMM kernels.
26-
# CUTLASS backend requires separate installation.
27-
# Reference: torch._inductor.config.max_autotune_gemm_backends
28-
"max_autotune": True,
29-
"max_autotune_gemm": True,
30-
"epilogue_fusion": True,
31-
"coordinate_descent_tuning": True,
32-
},
33-
"aten": {
34-
# Enable autotune fallback to ATen kernels for debugging.
35-
# This causes Inductor to fall back to ATen (eager) kernels
36-
# when autotuning finds them faster. Useful for debugging.
37-
# Reference: torch._inductor.config.autotune_fallback_to_aten
38-
"autotune_fallback_to_aten": True,
39-
},
4019
"cudagraphs": {
4120
# Enable CUDA Graphs to reduce kernel launch overhead.
4221
# Reference: torch._inductor.config.triton.cudagraphs
43-
# Note: Prefer using mode="reduce-overhead" for official support.
22+
# NOTE: CUDA Graphs does not support dynamic shapes or graph breaks, so it is
23+
# highly recommended to use only for inference with fixed input shapes.
24+
# Prefer using mode="reduce-overhead" for official support.
4425
"triton.cudagraphs": True,
4526
},
4627
"max_autotune": {
4728
# Enable comprehensive autotuning across all backends.
48-
# Equivalent to torch.compile(mode="max-autotune") with extra options.
4929
"max_autotune": True,
5030
"max_autotune_gemm": True,
5131
"coordinate_descent_tuning": True,
@@ -59,111 +39,88 @@
5939
},
6040
"tma": {
6141
# Enable persistent matmul kernels with TMA (Tensor Memory Accelerator).
42+
# Reference: torch._inductor.config.triton.enable_persistent_tma_matmul
6243
# NOTE: This config has graceful fallback behavior:
6344
# - On NVIDIA H100+ (Hopper, CC >= 9.0): Enables TMA persistent kernels
6445
# - On other GPUs (A100, AMD, etc.): Enables non-TMA persistent kernels as fallback
65-
# Reference: torch._inductor.config.triton.enable_persistent_tma_matmul
6646
"triton.enable_persistent_tma_matmul": True,
6747
},
6848
}
6949

70-
# Map template names to torch.compile mode strings where applicable.
71-
# Reference: https://pytorch.org/docs/stable/generated/torch.compile.html
72-
_TEMPLATE_TO_COMPILE_MODE = {
73-
"cudagraphs": "reduce-overhead",
74-
"max_autotune": "max-autotune",
75-
}
76-
77-
78-
def _set_nested_attr(config_module, key, value):
79-
"""Set a possibly nested attribute on a config module.
80-
81-
For example, key="triton.cudagraphs" sets config_module.triton.cudagraphs = value.
82-
"""
83-
parts = key.split(".")
84-
obj = config_module
85-
for part in parts[:-1]:
86-
obj = getattr(obj, part)
87-
setattr(obj, parts[-1], value)
88-
8950

9051
class InductorBackend(GraphCompilerBackend):
9152
"""Inductor backend with configurable config template selection.
9253
9354
Supported config keys:
94-
template (str): One of "triton", "cpp_wrapper", "cutlass", "aten",
55+
fullgraph (bool): Whether to compile the entire model into a single graph.
56+
Defaults to False. Passed to torch.compile.
57+
dynamic (bool | None): Whether to enable dynamic shape support.
58+
Defaults to None. Passed to torch.compile.
59+
graph_net_inductor_config_template (str): One of "triton", "cpp_wrapper",
9560
"cudagraphs", "max_autotune", "freezing", "tma".
96-
Applies a predefined set of Inductor config overrides.
97-
Note: These are extensions to PyTorch's official "mode" concept.
61+
GraphNet predefined Inductor config templates.
9862
mode (str): torch.compile mode. One of "default", "reduce-overhead",
99-
"max-autotune", "max-autotune-no-cudagraphs".
100-
If a template implies a mode, that is used unless explicitly overridden.
101-
freezing (bool): Enable/disable model freezing before compilation.
102-
inductor_config (dict): Arbitrary torch._inductor.config overrides.
103-
Keys can be dotted paths (e.g. "triton.cudagraphs").
104-
These are applied last and override everything else.
63+
"max-autotune". Passed directly to torch.compile.
64+
options (dict): Direct torch.compile options dict.
65+
66+
NOTE: `torch.compile` does not allow `mode` and `options` to be specified together.
67+
Therefore `graph_net_inductor_config_template` (which provides `options`),
68+
`mode` and `options` are mutually exclusive with each other.
10569
10670
Reference:
107-
- PyTorch modes: https://pytorch.org/docs/stable/generated/torch.compile.html
71+
- PyTorch compile: https://pytorch.org/docs/stable/generated/torch.compile.html
10872
- Inductor configs: https://github.com/pytorch/pytorch/blob/main/torch/_inductor/config.py
10973
"""
11074

11175
def __init__(self, config):
11276
super().__init__(config)
113-
self._template = config.get("template", None)
114-
self._mode = config.get("mode", None)
115-
self._freezing = config.get("freezing", None)
116-
self._inductor_config = config.get("inductor_config", {})
117-
118-
def _build_inductor_overrides(self):
119-
"""Collect all Inductor config overrides from template + explicit config."""
120-
overrides = {}
121-
122-
# 1. Apply template defaults
123-
if self._template is not None:
124-
if self._template not in _INDUCTOR_CONFIG_TEMPLATES:
125-
raise ValueError(
126-
f"Unknown Inductor config template: {self._template!r}. "
127-
f"Available templates: {sorted(_INDUCTOR_CONFIG_TEMPLATES.keys())}"
128-
)
129-
overrides.update(_INDUCTOR_CONFIG_TEMPLATES[self._template])
130-
131-
# 2. Apply top-level convenience flags
132-
if self._freezing is not None:
133-
overrides["freezing"] = self._freezing
77+
self._config_template = config.get("graph_net_inductor_config_template")
78+
self._mode = config.get("mode")
79+
self._fullgraph = config.get("fullgraph", False)
80+
self._dynamic = config.get("dynamic")
81+
self._options = config.get("options")
82+
83+
# Mutually exclusive: exactly one of template / mode / options can be specified
84+
provided = [self._config_template, self._mode, self._options]
85+
if sum(1 for x in provided if x is not None) > 1:
86+
raise ValueError(
87+
"Specify exactly one of 'graph_net_inductor_config_template', "
88+
"'mode', or 'options', not multiple."
89+
)
13490

135-
# 3. Apply explicit inductor_config overrides (highest priority)
136-
overrides.update(self._inductor_config)
91+
def _build_options(self):
92+
if self._options:
93+
return self._options
13794

138-
return overrides
95+
if self._config_template:
96+
if self._config_template not in _INDUCTOR_CONFIG_TEMPLATES:
97+
raise ValueError(
98+
f"Unknown config template: {self._config_template!r}. "
99+
f"Available: {sorted(_INDUCTOR_CONFIG_TEMPLATES.keys())}"
100+
)
101+
return _INDUCTOR_CONFIG_TEMPLATES[self._config_template]
139102

140-
def _resolve_compile_mode(self):
141-
"""Determine the torch.compile mode string."""
142-
if self._mode is not None:
143-
return self._mode
144-
if self._template in _TEMPLATE_TO_COMPILE_MODE:
145-
return _TEMPLATE_TO_COMPILE_MODE[self._template]
146-
return "default"
103+
return {}
147104

148105
def __call__(self, model):
149-
import torch._inductor.config as inductor_config
106+
final_options = self._build_options()
150107

151-
overrides = self._build_inductor_overrides()
152-
compile_mode = self._resolve_compile_mode()
153-
154-
if self._template or self._inductor_config:
108+
if self._config_template is not None or self._options is not None:
155109
print(
156-
f"[InductorBackend] template={self._template!r}, mode={compile_mode!r}, "
157-
f"overrides={overrides}",
110+
f"[InductorBackend] graph_net_inductor_config_template={self._config_template!r}, "
111+
f"mode={self._mode!r}, options={final_options}",
158112
file=sys.stderr,
159113
flush=True,
160114
)
161115

162-
# Apply Inductor config overrides
163-
for key, value in overrides.items():
164-
_set_nested_attr(inductor_config, key, value)
165-
166-
return torch.compile(model, backend="inductor", mode=compile_mode)
116+
return torch.compile(
117+
model,
118+
backend="inductor",
119+
fullgraph=self._fullgraph,
120+
dynamic=self._dynamic,
121+
**({"mode": self._mode} if self._mode is not None else {}),
122+
**({"options": final_options} if final_options else {}),
123+
)
167124

168125
def synchronize(self):
169126
if torch.cuda.is_available():

0 commit comments

Comments
 (0)