Repository navigation
[CoreAI] Add a coreai_compute_unit backend option - #24375
Merged
Merged
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24375
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. |
Contributor
|
@claude review effort=max |
SS-JIA
approved these changes
Oct 31, 2026
metascroy
force-pushed
the
coreai-expose-compute-unit
branch
from
November 2, 2026 23:27
99b0908 to
d05c245
Compare
Expose the Core AI SDK's SpecializationOptions configurations as a runtime backend option: default, cpu_only, prefer_cpu, prefer_gpu and prefer_neural_engine. The selection feeds the loader's specialization identity, so each value is specialized and cached under its own key.
metascroy
force-pushed
the
coreai-expose-compute-unit
branch
from
November 3, 2026 18:59
d05c245 to
d703edf
Compare
This PR needs a
|
…ers collide testComputeUnitsMapToSDKSpecializationOptions fails on CI runners with fewer distinct identifiers than compute units, but passes locally with the same macOS and Xcode. Include each unit's options and identifier in the failure message to show which units collide.
The SDK limits allowed compute units to the hardware, so on CPU-only CI runners .default and .cpuOnly resolve to the same options and correctly share an identifier. Instead of expecting one distinct identifier per compute unit, require two identifiers to match exactly when their options do.
Renames the Core AI delegate manifest's `packaging` values so they name the embedded format instead of where it's stored. Stacked on #24375. ## Why `"inline"` and `"aot_compiled_inline"` describe storage (embedded in the `.pte`), which is the same for both formats. They don't say what is actually different: a portable `.aimodel` versus AOT-compiled `.aimodelc` bundles. The runtime also used a third vocabulary, `"source"` / `"aot"`, in logs and the cache identity. "source" already meant something else there: the bundle copy the runtime writes to the cache for the SDK, which happens for AOT bundles too. ## Changes | Where | Before | After | |---|---|---| | Manifest `packaging` | `"inline"` / `"aot_compiled_inline"` | `"aimodel"` / `"aimodelc"` | | Python `AssetPackaging` (`compiler/preprocess.py`) | `INLINE` / `AOT_COMPILED_INLINE` | `AIMODEL` / `AIMODELC` | | Runtime manifest check (`runtime/coreai_manifest.mm`) | accepts the old values; AOT detected by an `aot_compiled_` prefix | accepts only the new values; AOT means `== "aimodelc"` | | Specialization log (`coreai_load_coordinator.mm`) | `kind=source` / `kind=aot` | `kind=aimodel` / `kind=aimodelc` | | Cache identity (`coreai_cache_key.mm`) | `"source"` / `"aot"` | `"aimodel"` / `"aimodelc"` | Test fixtures, test labels and the README follow the new names. In the README, "source" now only means the copy written for the SDK. ## Compatibility * **Old PTEs:** this is a manifest format change. PTEs exported with the old names fail to load with `Unsupported Core AI packaging; expected aimodel or aimodelc` and must be re-exported. * **Existing caches:** the cache identity changes, so existing bookmarks aren't found and each model specializes again on its first load. Old entries stay on disk unused. ## Test plan * `test_preprocess.py`: 25/25 passed, including the real `coreai-build` AOT test. * Native: all 6 CTest targets pass (`coreai_host_test`, `coreai_pte_export_test`, `coreai_swift_bridge_test`, `coreai_sdk_source_lifetime_test`, `coreai_runtime_smoke`, `coreai_multithread_test`). The native fixtures are regenerated and carry `packaging: "aimodel"`. * Manual end-to-end with a standalone runner on an M4 Max: * Portable PTE: `kind=aimodel`, outputs match the reference. * AOT PTE: first load `kind=aimodelc` with exact outputs; second load restores from the cache bookmark. * A PTE exported before this change is rejected with the error above. * ufmt, flake8 and clang-format are clean.
This branch was previously deployed
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 free
to 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.
Adds a
coreai_compute_unitbackend option for the Core AI delegate, set the same way ascoreai_cache_dir. It selects which compute units Core AI may use when it specializes a model on the device.Stacked on #24374.
Option values
Each value is exactly one of the configurations the Core AI SDK provides through
SpecializationOptions:SpecializationOptionsdefault(or absent).defaultcpu_only.cpuOnlyprefer_cpuinit(preferredComputeUnitKind: .cpu)prefer_gpuinit(preferredComputeUnitKind: .gpu)prefer_neural_engineinit(preferredComputeUnitKind: .neuralEngine)The option mirrors the SDK and adds nothing of its own:
cpu_onlyis the only restriction. A preference maximizes use of that unit but falls back to any allowed unit for operations it can't run.Implementation
coreai_backend.mmreads the option duringinit, next tocoreai_cache_dir. Unknown values, non-string values and null fail withInvalidArgumentbefore a loader is created. The error lists the valid values.ETCoreAIBridge.hadds anETCoreAIComputeUnitenum, andETCoreAICreateModelLoadernow takes it.ETCoreAIModelLoader.swiftmaps each value to the matchingSpecializationOptions.defaultkeeps its existing identity, so bookmarks from before this change still restore.clear_cache_for_ptestill removes every variant of a PTE.default, because eviction doesn't depend on specialization.Test plan
coreai_host_testpasses. A new delegate test checks that each value reaches the loader factory, that a missing option meansdefault, and that unknown and non-string values are rejected before a loader is created.coreai_swift_bridge_testpasses. A new Swift test checks that each value builds exactly the expectedSpecializationOptions, that the five values have five different cache identities, and thatdefaultkeeps the"default"identity.