MCPcopy Create free account
hub / github.com/pytorch/pytorch / _replace_pattern

Function _replace_pattern

torch/fx/subgraph_rewriter.py:221–343  ·  view source on GitHub ↗
(
    gm: GraphModule,
    pattern: Union[Callable, Graph, GraphModule],
    replacement: Union[Callable, Graph, GraphModule],
    match_filters: Optional[List[Callable[["InternalMatch", Graph, Graph], bool]]] = None,  # type: ignore[name-defined]
    ignore_literals: bool = False,
)

Source from the content-addressed store, hash-verified

219
220
221def _replace_pattern(
222 gm: GraphModule,
223 pattern: Union[Callable, Graph, GraphModule],
224 replacement: Union[Callable, Graph, GraphModule],
225 match_filters: Optional[List[Callable[["InternalMatch", Graph, Graph], bool]]] = None, # type: ignore[name-defined]
226 ignore_literals: bool = False,
227) -> List[ReplacedPatterns]:
228
229 from torch.fx.passes.utils.matcher_utils import SubgraphMatcher, InternalMatch
230
231 if match_filters is None:
232 match_filters = []
233
234 # Get the graphs for `gm`, `pattern`, `replacement`
235 original_graph: Graph = gm.graph
236
237 if isinstance(pattern, GraphModule):
238 pattern_graph = pattern.graph
239 elif isinstance(pattern, Graph):
240 pattern_graph = pattern
241 else:
242 pattern_graph = symbolic_trace(pattern).graph
243
244 if isinstance(replacement, GraphModule):
245 replacement_graph = replacement.graph
246 elif isinstance(replacement, Graph):
247 replacement_graph = replacement
248 else:
249 replacement_graph = symbolic_trace(replacement).graph
250
251 matcher = SubgraphMatcher(pattern_graph, match_output=False, match_placeholder=False,
252 remove_overlapping_matches=True, ignore_literals=ignore_literals)
253 _matches: List[InternalMatch] = matcher.match(original_graph)
254
255 # Filter out matches that don't match the filter
256 _matches = [
257 m for m in _matches
258 if all(match_filter(m, original_graph, pattern_graph)
259 for match_filter in match_filters)
260 ]
261
262 replacement_placeholders = [n for n in replacement_graph.nodes if n.op == "placeholder"]
263
264 # As we progressively replace nodes, we'll need to keep track of how the match results should change
265 match_changed_node: Dict[Node, Node] = {}
266
267 match_and_replacements = []
268 for match in _matches:
269
270 # Build connecting between replacement graph's input and original graph input producer node
271
272 # Initialize `val_map` with mappings from placeholder nodes in
273 # `replacement` to their corresponding node in `original_graph`
274 assert len(match.placeholder_nodes) == len(replacement_placeholders)
275 val_map: Dict[Node, Node] = {}
276 for rn, gn in zip(replacement_placeholders, match.placeholder_nodes):
277 if isinstance(gn, Node):
278 val_map[rn] = match_changed_node.get(gn, gn)

Callers 2

replace_patternFunction · 0.85

Calls 15

matchMethod · 0.95
symbolic_traceFunction · 0.90
SubgraphMatcherClass · 0.90
isinstanceFunction · 0.85
listFunction · 0.85
iterFunction · 0.85
reversedFunction · 0.85
ReplacedPatternsClass · 0.85
_replace_attributesFunction · 0.85
graph_copyMethod · 0.80
replace_all_uses_withMethod · 0.80
allFunction · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…