Uh oh!
There was an error while loading. Please reload this page.
Add the MLX backend product to the SwiftPM package template - #22259
Closed
shoumikhin wants to merge 4 commits into
Closed
Add the MLX backend product to the SwiftPM package template#22259shoumikhin wants to merge 4 commits into
shoumikhin wants to merge 4 commits into
Conversation
The published SwiftPM manifest is generated from this template, so the platform floor a consumer sees is set here, not in the main branch's Package.swift. Raising it to macOS 14 is what lets the MLX backend be offered through the package. MLX requires a macOS 14 deployment target and fails to build below it, so the package that ships MLX must declare at least that. iOS is already at 17, which is above MLX's iOS floor, so only macOS moves. This drops support for macOS 12 and 13 for the whole package, including consumers that only use XNNPACK or Core ML. macOS 14 shipped in September 2023. Test Plan: Materialized the template the way the release job does, substituting the version and checksum placeholders, and confirmed `swift package dump-package` parses it and reports the macOS platform as 14.0.
Companion to the change that adds MLX to the Apple frameworks. The published SwiftPM manifest is generated from this template, so the backend_mlx product and its resource bundle have to be declared here too, or the released package would be missing them. Adds the backend_mlx product with its Metal, Foundation and QuartzCore framework links, and a shared backend_mlx_resources target that carries the per-platform Metal kernel libraries. The release job commits those libraries to this branch beside the manifest. Each is included only when present so the manifest still resolves before the release job has produced them.
The resource list was gated on FileManager.fileExists with a path relative to the process working directory. SwiftPM evaluates a dependency's manifest with the consumer's directory as the cwd, so every slice looked absent, the list came out empty, and no bundle was produced at all. The build stayed green and the MLX delegate faulted later at Metal device init, with nothing pointing at the cause. Measured from a consumer package: 0 of 3 metallibs shipped before, 3 of 3 after, in executorch_backend_mlx_resources.bundle, which is the name the delegate is compiled to look for. An in-place build and swift package dump-package both reported the resources correctly either way, which is why this was not caught. The release job commits all three files before publishing, so declare them unconditionally rather than probing for them. Foundation is no longer needed.
The comment said a missing slice is reported at resolve time. Measured: swift package resolve emits nothing at all, and the "Invalid Resource ... File not found" warning appears when a consumer builds. It is also only a warning, so the build still succeeds; the change makes the failure visible, not fatal.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22259
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 Unclassified FailureAs of commit 0e56f2b with merge base 1d467d0 ( UNCLASSIFIED FAILURE - DrCI could not classify the following job because the workflow did not run on the merge base. The failure may be pre-existing on trunk or introduced by this PR:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
shoumikhin
commented
Aug 28, 2026
ContributorAuthor
Superseded by a branch carrying two further review fixes: the comment no longer implies the main-side manifest is wrong for using FileManager.fileExists (it anchors with #filePath and is correct), and the single-use path local is inlined to match the sibling style. Reopening rather than leaving those unaddressed, since this repository blocks direct pushes to a branch once it has an open PR. |
This was referenced Aug 28, 2026
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.
Supersedes #22204. Same change, plus the fix for a defect that made the new resource bundle empty for every real consumer.
What #22204 got wrong
The metallib resource list was gated on
FileManager.default.fileExistswith a path relative to the process working directory:SwiftPM evaluates a dependency's manifest with the consumer's directory as the working directory, not the dependency's checkout. So every slice looked absent,
compactMapreturned[], and SwiftPM emitted no bundle at all. The build stayed green with no warning, and the MLX delegate would fault later at Metal device init inside a consumer's app with nothing pointing at the cause.Measured from a real consumer package, with all three metallibs committed and present in the resolved checkout:
That bundle name is what
backends/mlx/CMakeLists.txtcompiles in asSWIFTPM_BUNDLE, so it is the name the delegate actually looks for.Why it was easy to miss
Every in-place check passes.
swift package dump-packagerun inside the package root reports all three resources, and--package-pathchdirs to the package root too, so it is equally blind. Only resolving the package as a dependency exposes it. The release job's own guards check for unsubstituted checksums and for products without frameworks, neither of which can see this.The fix
Declare the three slices unconditionally instead of probing for them. The release job commits all three files to this branch before publishing, so the probe was guarding against a state that does not occur on a published branch.
import Foundationis no longer needed, and the base template did not have it.What a genuinely missing slice does now, measured rather than assumed:
So this makes the failure visible, not fatal. That is still a large improvement over the old form, which shipped zero of three metallibs with no diagnostic of any kind, but it is worth being precise: SwiftPM does not fail a build on a missing declared resource.
Landing
This half and the
main-side half (#22203) both need to be live before the next Apple publish run. Order between them does not matter: each single-sided state trips one of the release job's two guards and exits 1 beforegit push -f, so nothing broken is published either way. Verified by replaying the substitution and both guards for all three states.