Uh oh!
There was an error while loading. Please reload this page.
Remove the MPS backend from the SwiftPM package - #22182
Merged
Merged
Conversation
The MPS backend is being removed from the runtime, so this template must stop asking for it. The release job fills one `__SHA256_<framework>__` placeholder per framework that was actually built and uploaded. Once MPS is no longer built, nothing substitutes `__SHA256_backend_mps__`, and the published manifest would carry the literal placeholder text as a checksum plus a download URL for an archive that was never uploaded. That failure would be quiet and wide. The manifest still parses, so nothing complains at generation time, and SwiftPM downloads every binary target during resolution rather than only the ones a project uses. So every consumer of the package would fail to resolve it, not only projects that wanted MPS. Test Plan: Ran the release job's substitution steps against this template using exactly the framework list that remains after MPS is removed from the runtime build. Before this change, two placeholders were left unsubstituted (`__SHA256_backend_mps__` and `__SHA256_backend_mps_debug__`), and the resulting manifest still parsed, which is what makes the failure quiet. After this change no placeholder is left, the generated manifest parses, and it declares 16 products and 18 binary targets with no reference to MPS and no unsubstituted checksum. Every wrapper target still has its matching stub directory, and no stub directory is left orphaned.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22182
Note: Links to docs will display an error until the docs builds have been completed. This comment was automatically generated by Dr. CI and updates every 15 minutes. |
shoumikhin
commented
Aug 26, 2026
ContributorAuthor
Companion to #22181, which removes the MPS backend from the runtime, the build |
metascroy
approved these changes
Aug 26, 2026
Uh oh!
There was an error while loading. Please reload this page.
shoumikhin added a commit
that referenced
this pull request
Aug 26, 2026
The MPS backend was deprecated in ExecuTorch 1.2 and its own deprecation notices say it will be removed in 1.4. The tree is now at 1.5.0, so the removal is overdue. Delete it. MPS delegated model execution to Apple's MPSGraph framework. The replacements its deprecation notice names are still here: Core ML for general Apple acceleration, and the Metal backend for macOS GPU work. What goes away: - `backends/apple/mps/` and `examples/apple/mps/` - the `EXECUTORCH_BUILD_MPS` build option, and the places that set it - the `backend_mps` SwiftPM product and its Apple framework build rules - the `--mps` export flag, the `backend.mps.enabled` config key, and `get_mps_partitioner` - the MPS CI jobs, benchmark configurations, and documentation pages - `EXECUTORCH_BUILD_KERNELS_TORCHAO_MPS`, which built torchao's Metal kernels for this runtime. Those kernels include a header from this backend and call into its namespace, so they cannot outlive it. The option was off by default and set by nothing in the tree. Two things that look like MPS are deliberately kept, because they are unrelated to this backend: - The Metal backend links Apple's MetalPerformanceShaders framework directly for some fallback operations. That is a system library, not this delegate. - `TORCHAO_BUILD_EXPERIMENTAL_MPS` builds torchao's own Metal kernels for eager PyTorch. It never sets `TORCHAO_BUILD_EXECUTORCH_OPS`, so it does not reach the variant that depended on this backend. `--device mps` in an export script is PyTorch's device name for Apple GPUs, and `MPS` in a codegen fixture is a PyTorch dispatch key. Both stay. Removed documentation pages redirect to the backend overview, which lists the Apple alternatives, rather than returning 404. Callers passing `-DEXECUTORCH_BUILD_MPS=ON` will find the option is gone. CMake reports it as an unused variable rather than failing, and the build produces a runtime without the backend, which is the correct end state. The `--mps` flag of the Apple framework script is rejected outright, since that script validates its arguments. Test Plan: No test exercises this backend after the change, so verification focused on proving nothing else broke. Configured the Apple build and the LLM build to completion. Both previously turned this backend on by default, and both configure with it absent. Then built and linked the example runner: it contains no symbol from this backend, still registers Core ML and XNNPACK, and runs a delegated model to the correct result. The two source lists in the build glue are consumed positionally, so both were checked to still be the same length, and every list name the build asks for was confirmed to still resolve. Ran the benchmark configuration logic directly: the iOS configuration list no longer offers this backend, one model's expected list matches, and no disabled entry names a configuration that no longer exists. Parsed the changed workflow files as YAML and confirmed no job remains. Parsed both Xcode projects and confirmed no reference to the removed package product and no dangling object references. Checked the SwiftPM manifest still has a stub directory for every product it declares, and no orphan directories. Built the affected documentation table with Sphinx and MyST to confirm it still renders as a table rather than being replaced by a parse error, which is what a row with the wrong number of cells causes. Confirmed every redirect target resolves to a real page, and that no remaining cross-reference points at a deleted one. Syntax-checked the changed shell scripts, and confirmed formatting and lint are clean on the changed Python, CMake and HTML files. Finally, swept the tree with a word-boundary search rather than a token search, and audited every remaining match. What remains is PyTorch's device name, a PyTorch dispatch key, torchao's eager Metal kernels, tokenizer vocabulary entries, Arm Corstone board names, and historical notes under `.wiki/`. Also make the SwiftPM release step check that the manifest and the built frameworks describe the same set, in both directions, since each failure is silent on its own. A placeholder with no framework publishes literal text where a checksum belongs: eight consecutive nightly manifests in August 2025 shipped that way, which makes the package unresolvable for every consumer rather than only users of that product. A framework with no product is the reverse, and matters here because release branches share one template, so a branch that still builds a removed framework would drop the product from the manifest silently. Both checks run only on a publishing run, so a template that is momentarily out of step with a branch does not redden unrelated pull requests. Removing a framework is exactly the change that exercises this, so the guard belongs with it. Verified the guard against the real manifests from that incident: it fails on the affected days, naming the surviving placeholders, and passes on the day the incident ended. The guard compares each built framework against the product base name, because the manifest declares each product once and synthesises its debug variant in Swift. The SwiftPM package needs a matching change on its own branch: #22182.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The MPS backend is being removed from the runtime, so this template must stop
asking for it.
The release job fills one
__SHA256_<framework>__placeholder per frameworkthat was actually built and uploaded. Once MPS is no longer built, nothing
substitutes
__SHA256_backend_mps__, and the published manifest would carry theliteral placeholder text as a checksum plus a download URL for an archive that
was never uploaded.
That failure would be quiet and wide. The manifest still parses, so nothing
complains at generation time, and SwiftPM downloads every binary target during
resolution rather than only the ones a project uses. So every consumer of the
package would fail to resolve it, not only projects that wanted MPS.
Test Plan:
Ran the release job's substitution steps against this template using exactly the
framework list that remains after MPS is removed from the runtime build.
Before this change, two placeholders were left unsubstituted
(
__SHA256_backend_mps__and__SHA256_backend_mps_debug__), and the resultingmanifest still parsed, which is what makes the failure quiet.
After this change no placeholder is left, the generated manifest parses, and it
declares 16 products and 18 binary targets with no reference to MPS and no
unsubstituted checksum. Every wrapper target still has its matching stub
directory, and no stub directory is left orphaned.
Note on ordering: this targets the
swiftpmbranch and is safe to land in eitherorder relative to the runtime removal. If it lands first, the release job simply
substitutes a placeholder that no longer exists, which is a no-op, and the
generated manifest is still complete. Verified by running the substitution with a
checksum list that still included MPS.
Note for operators: the template branch is shared with release branches
This template branch is checked out by the Apple workflow on
mainand on everyrelease/*branch, so the change reaches more than one publishing path.release/1.0still builds the removed framework, still checks out this sametemplate, and force-pushes the result to a fixed
swiftpm-1.0.0branch thatapplications can pin. Unlike
main, it has no guardrail step that aborts when thetarget branch already exists. So re-dispatching the Apple workflow on
release/1.0after this lands would republish
swiftpm-1.0.0with the product silently missing,and a pinned application would fail to resolve.
Nothing is scheduled on that branch (it last moved in November 2025), so this is a
constraint to be aware of rather than an imminent break, and it needs no change
here. If a
release/1.0Apple run is ever needed again, that branch needs thissame template change first.