- The fp16 lie
- The exported models declare fp16 outputs. Core ML hands back fp32 at runtime. Reading the bytes as declared produced spatially-correlated garbage: blobby smudges that read as a bad model rather than a bad cast, which made it expensive. I root-caused it by dumping the candidate mask tables and fixed it by branching on the dtype Core ML returns.
- A harness that compiles the shipping source
- Tools/edgetam-harness.swift builds the app’s real provider and renderer files into a macOS command-line tool, runs them over photographs and writes composited PNGs. I look at a segmentation or glow change on a Mac, against fixed inputs, before it reaches the device.
- Screen-space glow
- The renderer transforms the 256² mask into view coordinates before any Core Image filtering, so blur radii are screen sizes and the pipeline renders the same at any mask resolution. Every layer derives from the mask boundary (morphology gradient, gain, then the blooms), with a blur and re-threshold pass that turns a ragged model mask into a continuous outline.
- Where each model runs
- The image encoder runs wherever Core ML wants it, Neural Engine included. I pin the mask decoder to CPU and GPU, because the ANE compiler rejects its transposed convolutions.
- One camera session
- Remote, discovery and mapping are modes of a single ARSession. A mode switch never calls session.run with a reset, so the camera image never restarts or blanks; the overlay changes and the room stays where it was underneath.
- Swift 6 strict concurrency
- Throughout, with explicit ownership-transfer wrappers for the non-Sendable CoreVideo types that cross into the background segmentation tasks.
- A fallback that isn’t a dead end
- If the EdgeTAM models fail to load, the app falls back to Apple Vision’s foreground-instance segmentation behind the same provider protocol. Worse masks, same app.