Load a method whose constant name collides with another method's - #21706
Load a method whose constant name collides with another method's#21706shoumikhin wants to merge 1 commit into
Conversation
Loading a multi-method program with cross-method weight sharing can fail:
Constant '_tensor_constant2': size mismatch at dim 0 (cached=8448, new=6656)
Constant '_tensor_constant2' in method 'decode' is incompatible with the
cached version from a previous method. Refusing to share.
Constants lifted out of a graph are named by position within one compiled
module, so two methods can each own a "_tensor_constant2" holding unrelated
data. Sharing is keyed on that name, and a name alone is not evidence that two
methods refer to the same tensor.
Refusing to alias mismatched storage is right, but failing the whole load is
too strong: the method has its own copy of the constant and can use it. Decline
to share that one constant instead, and let every constant that does match go
on being shared.
The cache lookup runs before the tensors can be compared, so a name hit is
provisional. A constant rejected after extraction has to be excluded from the
user-managed pairs as well, or the method is left pointing at nothing.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21706
Note: Links to docs will display an error until the docs builds have been completed. ❌ 3 New Failures, 3 Unrelated FailuresAs of commit daf2840 with merge base 48741ac ( NEW FAILURES - The following jobs have failed:
BROKEN TRUNK - The following jobs failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
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 unique. A constant lifted out of a graph is named by its position within one
compiled module, so the first method's third constant and the second method's third constant are
both called
_tensor_constant2, and they usually hold different data. Loading such a programfails:
The program is fine. Each method carries its own copy of the constant and can run with it. Only
the attempt to treat two unrelated tensors as one fails.
The change
Refusing to alias mismatched storage is correct, so that check stays. What changes is the
response: decline to share that one constant and let the method use its own copy, rather than
failing the load for the whole program. Constants that do match go on being shared exactly as
before, so a program with no collisions behaves identically.
One detail matters for correctness. The cache lookup runs before the tensors can be compared, so
a name match is only provisional at that point. A constant rejected after extraction has to be
left out of the user-managed pairs too, otherwise the method is pointed at a tensor it did not
ask for.
Scope
This fixes the load failure and nothing else. On the program used to test it, the run is not yet
deterministic across repeats, and that is also true before this change when sharing is turned
off, so it is a separate pre-existing issue rather than something this introduces or resolves.
Testing
Built the CUDA delegate from source on Linux x86_64 and ran a three-method program whose methods
have colliding constant names, comparing the same program and runner against an unmodified
delegate:
The first row is the failure above. The second shows the program itself is loadable, which is
what makes failing the load the wrong response.