Add a CoreML rung on macOS
The macOS ladder was the CPU provider alone, with CoreML listed as a gap. It is now CoreML, then the CPU, then tract — unmeasured, since nobody here has a Mac, and safe to ship unmeasured because the probe's clock rejects a CoreML slower than the CPU and `attempt` refuses one that crashes. - `Rung::CoreMl`, a compiling rung like TensorRT: an ML Program with every compute unit allowed, falling back to the CPU until each model's program is built. The embedder stays on the CPU, as on the Hexagon (§7). - The cache is one directory per model and runtime version. CoreML keys a model committed from memory on its input and node names, not its weights (ONNX Runtime 1.29, coreml_execution_provider.cc), so two exports of one architecture would otherwise share a program. - The fingerprint on macOS is the chip and the OS release, which ships CoreML. - The desktop looks for the runtime in the bundle's Contents/Frameworks and Homebrew's prefixes; fetch-desktop-runtime.sh on a Mac downloads ONNX Runtime 1.29.0 for Apple silicon, which carries CoreML. docs/dev/macos.md says what exists, how to build it, and which log lines to ask a Mac user for.
This commit is contained in:
@@ -151,10 +151,14 @@ winning:
|
||||
| Linux / Windows, NVIDIA GPU | TensorRT, f32 model, fp16 engine | CUDA provider, f32 | ORT CPU, f32 | tract |
|
||||
| Linux, AMD GPU with ROCm | MIGraphX, f32 model, fp16 program | ORT CPU, f32 | — | tract |
|
||||
| Linux / Windows, no GPU stack | ORT CPU, f32 | — | — | tract |
|
||||
| macOS ⁵ | ORT CPU, f32 | — | — | tract |
|
||||
| macOS ⁵ | CoreML, f32 model, ML Program | ORT CPU, f32 | — | tract |
|
||||
|
||||
⁵ CoreML is the obvious rung and is unmeasured; it is listed so its absence is a gap and not an
|
||||
oversight.
|
||||
⁵ **Unmeasured**, and the one exception to the rule below: nobody here has a Mac. The rung is on
|
||||
the ladder because the probe makes a wrong guess cheap — a CoreML that is slower than the CPU is
|
||||
rejected by §4's clock, one that errors is recorded as failed, and one that takes the process
|
||||
down is refused on the third launch (§4, `attempt`). The embedder stays on the CPU (§7). The first
|
||||
macOS log that shows a probe line is this row's measurement; [macos.md](macos.md) says what to
|
||||
ask for.
|
||||
|
||||
Deliberately **not** on any ladder, with the measurement that excluded each: NNAPI (no driver),
|
||||
XNNPACK (slower than CPU, aborts on SCRFD), WebGPU (slower than CPU), the Adreno through QNN (works,
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# macOS
|
||||
|
||||
macOS is out of scope for v1 ([requirements.md](requirements.md)), and nobody working on
|
||||
DarkRoom has a Mac. This page records what exists anyway, and how a macOS build is set up so
|
||||
that someone who does have one can send back enough to fix what they hit.
|
||||
|
||||
## 1. What exists
|
||||
|
||||
- **Inference** ([inference.md §2](inference.md)). The macOS ladder is CoreML, then ONNX
|
||||
Runtime's CPU provider, then tract. CoreML is unmeasured. The probe decides whether it is used,
|
||||
and the crash guard (§4, `attempt`) covers the case where the provider takes the process down.
|
||||
The device fingerprint is the chip (`machdep.cpu.brand_string`) and the OS release, because
|
||||
CoreML ships with the OS.
|
||||
- **Where files go** ([`dr_plat::dirs`](../../platform/dr-plat/src/dirs.rs)). The Unix rules,
|
||||
except the state directory (the log and crash records), which is `~/Library/Logs/darkroom`.
|
||||
- **A diagnostic build**, described in §3.
|
||||
|
||||
The rest is not built, packaged or run on macOS by anyone here. This covers the window,
|
||||
Metal through wgpu, the display profile (FR-DSP-8 asks X11 and Wayland), the keyring, the
|
||||
bundle, and signing. `dr-plat` sends every non-Android Unix to the X11/Wayland dependencies.
|
||||
|
||||
## 2. Building
|
||||
|
||||
The Rust side compile-checks from Linux:
|
||||
|
||||
rustup target add aarch64-apple-darwin
|
||||
cargo check --target aarch64-apple-darwin -p dr-inference-engine --features native
|
||||
|
||||
Linking needs Apple's SDK, which means a Mac. On one:
|
||||
|
||||
cargo build --profile diagnostic -p darkroom-desktop
|
||||
./tools/fetch-desktop-runtime.sh # ONNX Runtime 1.29.0 with CoreML, Apple silicon only
|
||||
|
||||
The fetch script puts `libonnxruntime.dylib` in the user's `runtime/` directory, next to the
|
||||
models. The app also looks in `Contents/Frameworks` of its own bundle, and in Homebrew's
|
||||
`/opt/homebrew/lib` and `/usr/local/lib`. Homebrew's build may not include CoreML; the probe
|
||||
reports that as a failed rung and uses the CPU.
|
||||
|
||||
**For whoever packages it.** A notarised app runs with the hardened runtime, whose library
|
||||
validation refuses to `dlopen` a library signed by another team. A bundled
|
||||
`Contents/Frameworks/libonnxruntime.dylib` must be signed with the app. A runtime the user
|
||||
fetched needs the `com.apple.security.cs.disable-library-validation` entitlement, or it will not
|
||||
load, and the app will be the tract build without saying why beyond one log line.
|
||||
|
||||
## 3. The diagnostic build
|
||||
|
||||
Every macOS build is in the hands of someone who can send a log but cannot attach a debugger,
|
||||
so it is set up to log like a debug build while running at release speed.
|
||||
|
||||
- **The log says more.** With no `RUST_LOG`, the desktop's default filter is `debug` for every
|
||||
`dr_*` crate, for `darkroom_desktop`, and for `onnxruntime`. That last one is ONNX Runtime's
|
||||
own session log, which the engine forwards into `log` on every platform (`session.rs`,
|
||||
`with_runtime_log`). At `debug` it includes how many nodes each provider took. At `trace`
|
||||
(`RUST_LOG=onnxruntime=trace`) it lists every node's placement, which is long. The log cap is
|
||||
the same as everywhere (two files of 4 MiB).
|
||||
- **Backtraces have line numbers.** `--profile diagnostic` is release plus line tables. On
|
||||
macOS the tables go into a `.dSYM` beside the executable, and the backtrace in a crash record
|
||||
finds them only if the `.dSYM` stays next to the binary. Keep it in the bundle.
|
||||
|
||||
## 4. What to ask a Mac user for
|
||||
|
||||
`~/Library/Logs/darkroom/darkroom.log`, plus `darkroom.log.1` if present, after the first launch
|
||||
and after the first scan with faces. Console.app lists it under *Log Reports*. The Settings
|
||||
diagnostics bundle collects the same files. The lines that answer the open questions are:
|
||||
|
||||
| Line | What it tells us |
|
||||
|---|---|
|
||||
| `inference: ONNX Runtime … from …` / `inference: runtime tract` | Whether a runtime was found, and which one |
|
||||
| `inference: floor … ms on the CPU provider` | The CPU number for §2's table |
|
||||
| `inference: CoreML session built in … s` | CoreML's first compile of the probe model |
|
||||
| `inference: CoreML rejected: …` / `failed: …` | Why the CPU was kept |
|
||||
| `onnxruntime` lines naming `CoreMLExecutionProvider::GetCapability` | How much of the graph CoreML took |
|
||||
| `inference: the app died during …` | The crash guard fired, and on what |
|
||||
| `inference: compiling … for CoreML` / `ready on CoreML in … s` | Each model's compile, and any that CoreML refused |
|
||||
|
||||
Also ask for the settings row (*Settings › About › Inference*), which is one line and says the
|
||||
same in short. When one of these logs comes back with CoreML numbers, they go into
|
||||
[inference.md §1–2](inference.md), and footnote ⁵ becomes a measurement.
|
||||
@@ -146,7 +146,7 @@ _None._
|
||||
| FR-PLAT-LIN-2 | [`platform/dr-plat/src/display.rs:1`](../../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../../platform/dr-plat/src/display/x11.rs#L1) |
|
||||
| FR-PLAT-WIN-1 | [`platform/dr-plat/src/dirs.rs:1`](../../platform/dr-plat/src/dirs.rs#L1) |
|
||||
| FR-PLAT-WIN-2 | [`apps/darkroom-desktop/build.rs:1`](../../apps/darkroom-desktop/build.rs#L1), [`apps/darkroom-desktop/src/main.rs:6`](../../apps/darkroom-desktop/src/main.rs#L6), [`ui/dr-ui/src/launch_ui.rs:937`](../../ui/dr-ui/src/launch_ui.rs#L937) |
|
||||
| FR-PLAT-WIN-3 | [`apps/darkroom-desktop/src/main.rs:19`](../../apps/darkroom-desktop/src/main.rs#L19) |
|
||||
| FR-PLAT-WIN-3 | [`apps/darkroom-desktop/src/main.rs:35`](../../apps/darkroom-desktop/src/main.rs#L35) |
|
||||
| FR-RAW-1 | [`core/dr-decode/src/lib.rs:266`](../../core/dr-decode/src/lib.rs#L266), [`core/dr-types/src/lib.rs:135`](../../core/dr-types/src/lib.rs#L135), [`core/dr-types/src/lib.rs:206`](../../core/dr-types/src/lib.rs#L206) |
|
||||
| FR-RAW-2 | [`core/dr-decode/src/decoder.rs:1`](../../core/dr-decode/src/decoder.rs#L1), [`core/dr-decode/src/decoder.rs:26`](../../core/dr-decode/src/decoder.rs#L26), [`core/dr-decode/src/decoder.rs:59`](../../core/dr-decode/src/decoder.rs#L59), [`core/dr-decode/src/decoder.rs:95`](../../core/dr-decode/src/decoder.rs#L95), [`ui/dr-ui/src/decoder_seam.rs:185`](../../ui/dr-ui/src/decoder_seam.rs#L185), [`ui/dr-ui/src/decoder_seam.rs:1`](../../ui/dr-ui/src/decoder_seam.rs#L1), [`ui/dr-ui/src/decoder_seam.rs:216`](../../ui/dr-ui/src/decoder_seam.rs#L216), [`ui/dr-ui/src/decoder_seam.rs:257`](../../ui/dr-ui/src/decoder_seam.rs#L257), [`ui/dr-ui/src/export.rs:1238`](../../ui/dr-ui/src/export.rs#L1238), [`ui/dr-ui/src/export.rs:973`](../../ui/dr-ui/src/export.rs#L973), [`ui/dr-ui/src/import.rs:96`](../../ui/dr-ui/src/import.rs#L96), [`ui/dr-ui/src/library/sweep.rs:322`](../../ui/dr-ui/src/library/sweep.rs#L322), [`ui/dr-ui/src/library/sweep.rs:654`](../../ui/dr-ui/src/library/sweep.rs#L654), [`ui/dr-ui/src/library/thumbnails_gen.rs:109`](../../ui/dr-ui/src/library/thumbnails_gen.rs#L109), [`ui/dr-ui/src/merge.rs:119`](../../ui/dr-ui/src/merge.rs#L119), [`ui/dr-ui/src/repairs.rs:243`](../../ui/dr-ui/src/repairs.rs#L243) |
|
||||
| FR-RAW-3 | [`core/dr-decode/src/lib.rs:162`](../../core/dr-decode/src/lib.rs#L162), [`core/dr-decode/src/lib.rs:564`](../../core/dr-decode/src/lib.rs#L564), [`core/dr-decode/src/locate.rs:1435`](../../core/dr-decode/src/locate.rs#L1435), [`core/dr-gpu/src/demosaic.rs:1063`](../../core/dr-gpu/src/demosaic.rs#L1063), [`core/dr-gpu/src/demosaic.rs:1409`](../../core/dr-gpu/src/demosaic.rs#L1409), [`core/dr-gpu/src/demosaic.rs:868`](../../core/dr-gpu/src/demosaic.rs#L868), [`core/dr-gpu/tests/hot_pixels.rs:1`](../../core/dr-gpu/tests/hot_pixels.rs#L1) |
|
||||
|
||||
Reference in New Issue
Block a user