Skip to content

Load a method whose constant name collides with another method's - #21959

Open
shoumikhin wants to merge 1 commit into
pytorch:mainfrom
shoumikhin:cuda-constant-fqn-collision
Open

Load a method whose constant name collides with another method's#21959
shoumikhin wants to merge 1 commit into
pytorch:mainfrom
shoumikhin:cuda-constant-fqn-collision

Conversation

@shoumikhin

@shoumikhin shoumikhin commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Replaces #21706, whose branch history was rewritten by accident and which GitHub then
closed. Same change, rebuilt on main.

The problem

A program can hold several methods, for example one that fills a cache from a prompt and
one that runs a single step. The CUDA delegate can share a constant between them so one
copy of a weight serves every method that uses it. Sharing is keyed on the constant's
name.

That key is not reliable on its own. AOTInductor names a lifted constant by its position
within one compiled module, so two methods can each own a _tensor_constant2 holding
completely unrelated data. Sharing that pair points both methods at the same storage, and
one of them then reads the wrong weights.

Until now the first such collision failed the whole load:

Constant '_tensor_constant2' in method 'decode' is incompatible with the cached
version from a previous method. Refusing to share.

So a valid program, two methods that happen to have same-named constants, could not be
loaded at all.

The change

Compare the cached tensor against the one the current method expects. When they differ,
leave this method's own constant in place rather than failing the load, and keep the
cached copy for whichever method it does match.

What is covered, and what is not

The comparison happens where the weights blob is loaded, so it covers any method that has
at least one constant the cache has not seen yet. That is the common case.

A method whose constant names are all already cached is not covered. Checking it would
mean re-uploading the weights blob to compare against, and that has to happen for every
such method, which raises peak device memory enough to fail a large model. An earlier
version of this change did exactly that and three of the four muse-glimmer end to end
jobs died with CUDA error: out of memory. So that case still shares on the name alone,
as it did before, and the comment at the cache lookup says so. Fixing it properly needs a
way to read the cached constants' metadata without a blob round trip.

The comparison is also on tensor metadata only: dtype, rank, sizes, strides, device type
and device index. It does not compare the data, and it cannot, because both handles point
at device memory. Two constants that agree on all of that while holding different values
would still be shared. This narrows the problem rather than eliminating it, and it turns a
hard failure into a working load for the case it does cover.

Test plan

  • Built the delegate and loaded a two-method program whose constant names collide where
    one method has a constant the cache has not seen. Both methods load, and the log names
    the constant that was not shared.
  • Loaded a two-method program with genuinely shared constants and confirmed sharing still
    happens, so the change does not disable the optimisation it guards.
  • Ran the existing CUDA runtime unit tests.

There is no automated regression test for the collision case. Building one needs a
two-method program with colliding constant names and a GPU to run it on, which the unit
test targets in this directory do not have. Reverting this change would not fail any test
in the repository today.

Copilot AI lite review requested due to automatic review settings August 20, 2026 00:36
@pytorch-bot

pytorch-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

✅ No Failures

As of commit 6da3cd5 with merge base 3caaaca (image):
💚 Looks good so far! There are no failures yet. 💚

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 20, 2026
@shoumikhin
shoumikhin force-pushed the cuda-constant-fqn-collision branch from 591542c to 8251a71 Compare August 20, 2026 03:40
Copilot AI review requested due to automatic review settings August 20, 2026 03:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 20, 2026 03:43
@shoumikhin
shoumikhin force-pushed the cuda-constant-fqn-collision branch from 8251a71 to 8b20c37 Compare August 20, 2026 03:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

A program can hold several methods, for example one that fills a cache from a
prompt and one that runs a single step. The CUDA delegate can share a constant
between them so one copy of a weight serves every method that uses it. Sharing is
keyed on the constant's name.

That key is not reliable on its own. AOTInductor names a lifted constant by its
position within one compiled module, so two methods can each own a
`_tensor_constant2` holding unrelated data. Sharing that pair points both methods
at the same storage and one of them reads the wrong weights. Until now the first
such collision failed the whole load, so a valid program with two same-named
constants could not be loaded at all.

Compare the cached tensor against the one this method expects, and when they
differ leave this method's own constant in place rather than failing. The cached
copy stays for whichever method it does match.

The comparison happens where the weights blob is loaded, so it covers methods that
have at least one constant the cache has not seen. A method whose names are all
already cached has nothing to compare against without re-uploading the blob, which
costs too much device memory to do on every method, so that case still shares on
the name alone. The comment at the cache lookup says so.

The comparison is on tensor metadata: dtype, rank, sizes, strides, device type and
device index. It does not compare the data and cannot, because both handles point
at device memory. Two constants agreeing on all of that while holding different
values would still be shared.
@shoumikhin
shoumikhin force-pushed the cuda-constant-fqn-collision branch from 8b20c37 to 6da3cd5 Compare August 20, 2026 03:56
Copilot AI review requested due to automatic review settings August 20, 2026 03:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin shoumikhin added the release notes: runtime Changes related to the core runtime which loads the program methods, initializes delegates, and runs label Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. release notes: runtime Changes related to the core runtime which loads the program methods, initializes delegates, and runs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants