You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bce2a5e
Browse filesBrowse the repository at this point in the historyBrowse files
chore(ios): simulator fallback for mlx backend (#1236)
## Description
The MLX backend cannot link or run against the iOS **Simulator** Metal
SDK (`_MTLTensorDomain` / `_MTLIOErrorDomain` are absent from the
simulator Metal SDK). This PR removes the dead simulator MLX binary and
makes model selection automatically fall back to XNNPACK on the iOS
simulator.
Changes:
- **`modelRegistry.ts`** — `resolveBackend` gains a simulator policy
(`applySimulatorPolicy`): when a model resolves to the `mlx` backend on
the iOS simulator (`react-native-device-info` `isEmulatorSync()`), it
falls back to `xnnpack` if the model ships it. An **explicitly
requested** `mlx` backend on the simulator is not silently swapped — it
throws a clear, actionable error instead of failing cryptically at
native model load. Models with no simulator-compatible backend
(multimodal Gemma) also throw at selection time, before any download.
- Multimodal Gemma is converted to a proper variant map (`mlx` /
`vulkan`) so it flows through the resolver; the dead
`Platform.OS`-ternary consts it used are removed.
- **`react-native-device-info`** added as a dependency (used by the
resolver).
- **`libbackend_mlx_simulator.a` deleted** and the xcframework rebuilt —
the `ios-arm64-simulator` slice is MLX-free; the `ios-arm64` (device)
slice keeps MLX.
The fallback/throw happens when the model accessor is called (eagerly),
i.e. before any model download starts.
### Introduces a breaking change?
- [ ] Yes
- [x] No
### Type of change
- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)
### Tested on
- [x] iOS
- [ ] Android
### Testing instructions
1. Run the LLM example app on the **iOS Simulator**, select Gemma 4 E2B
(text), and confirm it loads the XNNPACK model instead of failing on
MLX.
2. On the simulator, calling `models.llm.gemma4_e2b({ backend: 'mlx' })`
throws a clear error (MLX requires a physical device);
`models.llm.gemma4_e2b()` falls back to XNNPACK.
3. On a **physical device**, Gemma 4 E2B still resolves to MLX and runs
as before.
4. Multimodal Gemma on the simulator throws a descriptive error at
selection time (no XNNPACK multimodal build exists).
### Screenshots
<!-- N/A -->
### Related issues
<!-- N/A -->
### Checklist
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings
### Additional notes
`react-native-device-info` is a native module, so consuming apps must
have it linked (pod installed) — it ships with the example apps.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0 commit comments