Skip to content

[fx] Fix quadratic name generation in _NamespaceBase.create_name#176515

Closed
anijain2305 wants to merge 2 commits intogh/anijain2305/1062/basefrom
gh/anijain2305/1062/head
Closed

[fx] Fix quadratic name generation in _NamespaceBase.create_name#176515
anijain2305 wants to merge 2 commits intogh/anijain2305/1062/basefrom
gh/anijain2305/1062/head

Conversation

@anijain2305
Copy link
Contributor

@anijain2305 anijain2305 commented Mar 5, 2026

Stack from ghstack (oldest at bottom):

create_name stores its counter under base_count[base] (e.g. "sin") but
was looking it up under base_count[candidate] (e.g. "sin_1"). When the
candidate already has a numeric suffix the lookup always misses, so the
while-loop that probes for a free name starts from the regex-extracted
number instead of the stored counter — degrading to O(existing_names)
per call.

This makes repeated node_copy of the same subgraph (as done by
inline_invoke_subgraph) quadratic: for an 80-layer model the pass went
from ~100ms to ~4.6s.

Fix: look up base_count[base] to match the store.

Authored with Claude.

create_name stores its counter under base_count[base] (e.g. "sin") but
was looking it up under base_count[candidate] (e.g. "sin_1").  When the
candidate already has a numeric suffix the lookup always misses, so the
while-loop that probes for a free name starts from the regex-extracted
number instead of the stored counter — degrading to O(existing_names)
per call.

This makes repeated node_copy of the same subgraph (as done by
inline_invoke_subgraph) quadratic: for an 80-layer model the pass went
from ~100ms to ~4.6s.

Fix: look up base_count[base] to match the store.

Authored with Claude.

[ghstack-poisoned]
@pytorch-bot pytorch-bot bot added the release notes: fx release notes category label Mar 5, 2026
@pytorch-bot
Copy link

pytorch-bot bot commented Mar 5, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/176515

Note: Links to docs will display an error until the docs builds have been completed.

❌ 1 New Failure, 2 Unrelated Failures

As of commit 94cc0bb with merge base bdbf4a1 (image):

NEW FAILURE - The following job has failed:

FLAKY - The following job failed but was likely due to flakiness present on trunk:

UNSTABLE - The following job is marked as unstable, possibly due to flakiness on trunk:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

…e_name"


create_name stores its counter under base_count[base] (e.g. "sin") but
was looking it up under base_count[candidate] (e.g. "sin_1").  When the
candidate already has a numeric suffix the lookup always misses, so the
while-loop that probes for a free name starts from the regex-extracted
number instead of the stored counter — degrading to O(existing_names)
per call.

This makes repeated node_copy of the same subgraph (as done by
inline_invoke_subgraph) quadratic: for an 80-layer model the pass went
from ~100ms to ~4.6s.

Fix: look up base_count[base] to match the store.

Authored with Claude.

[ghstack-poisoned]
@anijain2305 anijain2305 requested review from zou3519 March 5, 2026 01:01
@anijain2305 anijain2305 added ciflow/inductor ciflow/dynamo Trigger jobs ran periodically on main for dynamo tests ci-no-td Do not run TD on this PR labels Mar 5, 2026
@pytorchmergebot
Copy link
Collaborator

Starting merge as part of PR stack under #176452

@pytorchmergebot
Copy link
Collaborator

Starting merge as part of PR stack under #176452

pytorchmergebot pushed a commit that referenced this pull request Mar 5, 2026
…76452)

is_from_source(source, target) previously only compared at the root of
the ChainedSource hierarchy. This meant that
is_from_source(AttrSource(X, 'c'), X) returned False when X was itself
a ChainedSource (e.g. UnspecializedNNModuleSource(GlobalSource(...))),
because the function walked past X all the way to the root before
comparing.

Check source == target at each level before recursing so that
intermediate sources are correctly recognized as ancestors.

Authored with Claude.

Pull Request resolved: #176452
Approved by: https://github.com/williamwen42
ghstack dependencies: #176515
wdvr added a commit to wdvr/pytorch that referenced this pull request Mar 9, 2026
pytorchmergebot pushed a commit that referenced this pull request Mar 9, 2026
…ame (#176515)" (#176948)

## Summary
Reverts #176515.

This is a prerequisite for reverting the full `[fx] Move _Namespace to C++` series (#170962), which was reverted internally due to S627920 but the revert was never exported to GitHub.

The quadratic fix patches `torch/csrc/fx/graph.cpp` which was introduced by #170962. This revert must land first so that #170962 can be cleanly reverted afterwards.

## Test plan
CI — this revert removes a bugfix from C++ code that will itself be reverted in a follow-up PR.
Pull Request resolved: #176948
Approved by: https://github.com/izaitsevfb, https://github.com/huydhn
pytorchmergebot pushed a commit that referenced this pull request Mar 11, 2026
## Summary

Reverts #170946

This reverts commit fa27d4f.

The two stacked PRs (#170962 and #170973) have already been reverted on main:
- `0a06050b` Revert "[fx] Move _FindNodesLookupTable and _node_list to C++ (#170973)"
- `2ee3377b` Revert "[fx] Move _Namespace to C++ (#170962)"
- `fb60dd58` Revert "[fx] Fix quadratic name generation in _NamespaceBase.create_name (#176515)"

The only merge conflict was in `torch/fx/node.py` due to a type annotation modernization PR (#176308, `Optional[X]` → `X | None`). The conflict was resolved by keeping the modern annotation style while restoring the original Python implementation.

## Test plan
CI

Pull Request resolved: #177047
Approved by: https://github.com/huydhn
anijain2305 added a commit that referenced this pull request Mar 12, 2026
reland of #176515 but earlier the file already moved to C++, so sending a python only change.

[ghstack-poisoned]
anijain2305 added a commit that referenced this pull request Mar 12, 2026
reland of #176515 but earlier the file already moved to C++, so sending a python only change.

ghstack-source-id: e0bdb29
Pull Request resolved: #177217
pytorchmergebot pushed a commit that referenced this pull request Mar 12, 2026
reland of #176515 but earlier the file already moved to C++, so sending a python only change.
Pull Request resolved: #177217
Approved by: https://github.com/jansel, https://github.com/zou3519
sandy-gags pushed a commit to sandy-gags/pytorch that referenced this pull request Mar 12, 2026
create_name stores its counter under base_count[base] (e.g. "sin") but
was looking it up under base_count[candidate] (e.g. "sin_1").  When the
candidate already has a numeric suffix the lookup always misses, so the
while-loop that probes for a free name starts from the regex-extracted
number instead of the stored counter — degrading to O(existing_names)
per call.

This makes repeated node_copy of the same subgraph (as done by
inline_invoke_subgraph) quadratic: for an 80-layer model the pass went
from ~100ms to ~4.6s.

Fix: look up base_count[base] to match the store.

Authored with Claude.

ghstack-source-id: 9951e62
Pull Request resolved: pytorch/pytorch#176515
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-no-td Do not run TD on this PR ciflow/dynamo Trigger jobs ran periodically on main for dynamo tests ciflow/inductor Merged release notes: fx release notes category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants