Adding a backend or kernel#
A new backend is complete only when its source, package resources, parity, physical evidence, and consumer integration land together.
1. Choose the owning domain#
Place the implementation under IO, detector, DPC, display, SSB, or another existing scientific domain. If no domain owns the operation, define the backend-neutral contract before writing accelerator code.
Do not create cuda_*, mps_*, metal_*, or webgpu_* public workflows.
Public callers select a backend through the domain API and receive the same
result/provenance model.
2. Freeze the reference#
Record the current public call, fixture hash, parameters, output shape/dtype, output hashes, floating metrics, and accepted tolerances. Include odd and rectangular geometry and incomplete edge bins where applicable.
The backend under development cannot generate its own acceptance golden.
4. Package the source#
Update the appropriate package-data or SwiftPM resources and add a source
presence/compile test. Browser sources remain beside their scientific domain.
Native clients consume Swift products rather than copied .metal files.
5. Add parity and hardware evidence#
Update tests/parity/backend_matrix.json, add focused numerical tests, and run
the qualified physical-device gate. Record source revision, hardware/runtime,
memory, stage timings, and run-level results using the
benchmark methodology.
6. Integrate consumers#
Test each supported client through a local package override. Publish the shared package first, then pin clients to the exact verified revision. A copied kernel or client-side compatibility fork is not an integration.
7. Migrate paths safely#
Move one domain per commit. A moved module keeps no import-only compatibility shim or alias: every caller, in this repository and in every downstream package that imports the old path, changes in the same coordinated change. Repeat the parity gates before the move lands.