Skip to content

Cover a CUDA model with weights in the wheel smoke test - #22089

Open
shoumikhin wants to merge 1 commit into
mainfrom
cuda-wheel-weights-blob
Open

Cover a CUDA model with weights in the wheel smoke test#22089
shoumikhin wants to merge 1 commit into
mainfrom
cuda-wheel-weights-blob

Conversation

@shoumikhin

@shoumikhin shoumikhin commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

The CUDA rows of the wheel smoke test export one model through the CUDA delegate and run it. That model is x + y, so it has no weights.

A model with no weights needs nothing from the delegate's external data file, so it runs whether or not that path works. The CUDA delegate does not put weights in the .pte. It writes them to a separate file named aoti_cuda_blob.ptd, and the caller has to hand that file back at load time. Every runner script in this repository passes it by name. Nothing in the smoke test loaded one, so a wheel that could not produce or consume that file would pass the check and ship.

What this changes

A second model, a small nn.Linear, in the same child process:

  • export it through CudaPartitioner and write both the .pte and the data file,
  • assert the program actually carries a CUDA delegate, so a partitioner that silently declined the model cannot pass this check on the portable kernels,
  • assert the data file is present under the name the runners expect,
  • assert the data file is larger than the one the weightless model above produces, by at least the size of this model's weight matrix,
  • load the program with the data file and compare the result against eager.

Only the x86_64 rows execute this, the same as the existing check. The aarch64 rows have no GPU on their validation runner and keep skipping with a printed reason.

Why the size check is written as a difference

A data file is written even when the model has no weights, and it is not small. Measured on sm_80, the weightless model above produces a 256-byte file: a container around an empty payload. So any fixed lower bound below 256 is satisfied by a file with nothing in it, and a check like size >= weight_bytes for a small model is true no matter what the delegate did.

Instead the check writes the weightless program's data file in the same run, which costs nothing because that program is already compiled, and subtracts. That keeps working if the container format changes size later, which a hardcoded 256 would not.

Comparing against the sum over parameters() would not work either. Measured on sm_80 with this model, the delegate wrote the 128-byte weight into the data file and kept the 16-byte bias out, so that sum is not a bound on what the file has to hold. The check uses the weight matrix only.

Test plan

Ran the new child code on a Linux x86_64 machine with an sm_80 GPU, against a published nightly CUDA wheel. Both models pass:

PASS: a CUDA-delegated model ran on sm_80 and matched eager
PASS: a CUDA-delegated model with weights ran on sm_80 from a 384-byte aoti_cuda_blob.ptd carrying 128 bytes of weights, and matched eager

The delegate log on that run names a real content hash for the weights blob, not the hash of an empty one.

Also confirmed the new check is meaningful in both directions.

Loading the same weighted program without the data file gives:

[cuda_backend.cpp:1242] weights_blob '...' not found or update fn is null
[cuda_allocator.cpp:87] cudaMemcpy D2H failed: an illegal memory access was encountered
RuntimeError: Failed to execute method forward, error: 0x1

And if the delegate wrote an empty data file for the weighted model, the measured numbers give 256 minus 256, a difference of 0, against a 128-byte weight matrix, so the assertion fires. The previous version of this check did not: it compared the raw file size against the parameter total, and 256 is already larger than 144, so it would have passed on an empty file.

Copilot AI lite review requested due to automatic review settings August 24, 2026 17:16
@pytorch-bot

pytorch-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

⏳ No Failures, 40 Pending

As of commit cbbe528 with merge base 9a2d135 (image):
💚 Looks good so far! There are no failures yet. 💚

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

@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 24, 2026

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.

@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

The CUDA rows of the wheel smoke test export one model through the CUDA
delegate and run it. That model is an add of two inputs, so it has no
weights.

A model with no weights needs nothing from the delegate's external data
file, so it runs whether or not that path works. The CUDA delegate does
not put weights in the .pte. It writes them to a separate file named
aoti_cuda_blob.ptd, and the caller has to hand that file back at load
time. Every runner script in this repository passes it by name. Nothing
in the smoke test loaded one, so a wheel that could not produce or
consume that file passed the check and shipped.

Add a second model, a small linear layer, to the same child process:

- export it through the CUDA partitioner and write both the .pte and the
  data file,
- assert the program actually carries a CUDA delegate, so a partitioner
  that silently declined the model cannot pass this check on the
  portable kernels,
- assert the data file is present under the name the runners expect,
- assert the data file is larger than the one the weightless model above
  produces, by at least the size of this model's weight matrix,
- load the program with the data file and compare the result against
  eager.

The size check is written as a difference rather than a threshold on
purpose. A data file is written even when there are no weights, and it
is not small: measured on sm_80, the weightless model produces a
256-byte container around an empty payload. Any fixed lower bound below
that is satisfied by an empty file, so the check has to calibrate
itself. It writes the weightless program's data file in the same run and
subtracts. Comparing against the sum over parameters() would not work
either: measured on sm_80, the delegate wrote this Linear's 128-byte
weight into the data file and kept its 16-byte bias out, so that sum is
not a bound on what the file has to hold.

Test plan: ran the new child code on a Linux x86_64 machine with an
sm_80 GPU against a published nightly CUDA wheel. Both models pass:

  PASS: a CUDA-delegated model ran on sm_80 and matched eager
  PASS: a CUDA-delegated model with weights ran on sm_80 from a
  384-byte aoti_cuda_blob.ptd carrying 128 bytes of weights, and
  matched eager

The delegate log on that run names a real content hash for the weights
blob, not the hash of an empty one.

Also confirmed the check is meaningful in both directions. Loading the
same weighted program without the data file makes the delegate report
the weights as not found, and the run then fails inside forward with an
illegal memory access. And if the delegate wrote an empty data file for
the weighted model, the measured numbers give a difference of 0 against
a 128-byte weight matrix, so the assertion fires.
Copilot AI review requested due to automatic review settings August 24, 2026 18:36
@shoumikhin
shoumikhin force-pushed the cuda-wheel-weights-blob branch from 58d3b1a to cbbe528 Compare August 24, 2026 18:36

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.

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants