vyre-driver 0.4.1

Driver layer: registry, runtime, pipeline, routing, diagnostics. Substrate-agnostic backend machinery. Part of the vyre GPU compiler.
# vyre-driver

Substrate-agnostic backend machinery for the vyre GPU compiler.

`vyre-driver` is the second layer in vyre's four-layer model. It sits
between `vyre-foundation` (the IR + validator) and concrete backend
crates. It
owns the frozen contract every backend must implement, the registry
that routes a `Program` to the right backend, the pipeline-cache key
machinery, and the capability surface consumer tools use to decide
whether a backend can execute a given program.

```text
vyre-foundation (IR + validator)
   ↓
vyre-driver        ← you are here
   ↓
concrete driver crates
```

## Invariants

1. **Backend trait is frozen.** `VyreBackend` and `CompiledPipeline`
   signatures do not change within a major version. New capability
   flows through `BackendCapability` registration, never through trait
   mutation.
2. **Dispatch is deterministic per `(program, inputs, config)`.** Two
   calls with the same triple produce byte-identical outputs on every
   registered backend. Divergence is a backend bug, caught by the
   shadow pipeline in `shadow.rs`.
3. **Registration is side-effect-free at import.** Registering a
   backend inserts a `BackendRegistration` into the `inventory`-backed
   registry but does not initialise devices, allocate memory, or open
   adapters. Initialisation is deferred to the caller's first
   `dispatch` / `compile_native`.
4. **Precedence is stable.** `registered_backends_by_precedence()`
   returns backends in ascending `BackendPrecedence` order and this
   order is part of the public API; consumer tools rely on it to pick
   a default backend without inspecting internal state.
5. **Pipeline-cache keys hash the complete Program.** Fingerprints use
   blake3 over the canonical wire form, so two programs with identical
   IR share a cached pipeline regardless of how they were constructed.
6. **Errors carry a `Fix:` section.** Every `BackendError` variant's
   `Display` implementation ends in `Fix: <remediation>` so users do
   not need to guess at recovery.

## Boundaries

Concrete-driver isolation is part of the driver contract:

- Concrete backend crates own their own runtime objects, codegen objects,
  feature names, tests, target-specific terminology, and concrete API/type
  names such as adapter objects or launch objects.
- Shared crates and tools must not import concrete backend crates or spell
  concrete backend APIs. They depend on `vyre-driver` traits, registrations,
  capabilities, shared binding layouts, validation helpers, tuners, and
  opaque backend ids.
- If two concrete drivers need the same decision logic, move that logic here
  as a backend-neutral module. The concrete drivers keep only the target
  mechanics that cannot be shared.

`vyre-driver` does:

- Define `VyreBackend`, `CompiledPipeline`, `PendingDispatch`,
  `DispatchConfig`, `BackendCapability`, and the sealed `Backend`
  marker trait.
- Host `backend::registry` (inventory-backed discovery), `pipeline`
  (compile/dispatch indirection), `shadow` (reference-diff
  instrumentation), `migration` (deprecation + semver registries),
  `binding` (neutral ABI plans), `fusion` (cross-dispatch decisions),
  `specialization` (neutral override values), `subgroup` (operation
  taxonomy), `tuner` (candidate/cache framework), and `validation`
  (program-level preconditions plus shared validation caches).
- Expose `core_supported_ops()` so backend crates and consumer tools
  can ask "does this backend execute this Program?" without importing
  any concrete backend.

`vyre-driver` does NOT:

- Touch a GPU, open an adapter, or allocate device memory. Those are
  backend-crate responsibilities.
- Own the IR (`vyre-foundation`), the evaluator (`vyre-reference`),
  or intrinsics (`vyre-intrinsics`).
- Declare workload-specific primitives. Those live in `vyre-primitives`
  / `vyre-libs` and compose over `Program`.

## Three worked examples

### 1. Pick the best-available backend and dispatch

```rust
use vyre_driver::backend::acquire_preferred_dispatch_backend;
use vyre_foundation::ir::Program;

fn run(program: &Program, inputs: &[Vec<u8>]) -> Result<Vec<Vec<u8>>, vyre_driver::BackendError> {
    let backend = acquire_preferred_dispatch_backend()?;
    backend.dispatch(program, inputs, &Default::default())
}
```

### 2. Gate a feature on backend capability

```rust
use vyre_driver::backend::{registered_backends, core_supported_ops};
use vyre_foundation::ir::Program;

fn can_run(program: &Program) -> bool {
    let ops = core_supported_ops();
    registered_backends()
        .iter()
        .any(|reg| program.ops().all(|op| ops.contains(&op)))
}
```

### 3. Instrument with the shadow pipeline

```rust
use vyre_driver::shadow::ShadowedPipeline;
use vyre_driver::pipeline::compile;

fn compile_with_shadow(
    primary: &dyn vyre_driver::VyreBackend,
    reference: &dyn vyre_driver::VyreBackend,
    program: &vyre_foundation::ir::Program,
) -> Result<ShadowedPipeline, vyre_driver::BackendError> {
    let main = compile(primary, program)?;
    let refp = compile(reference, program)?;
    Ok(ShadowedPipeline::new(main, refp))
}
```

## Extension guide — adding a new backend

1. Create a concrete driver crate. Depend on `vyre-foundation`,
   `vyre-driver`, and any backend-neutral shared crate needed by the
   contract. Do not make shared crates depend back on the concrete driver.
2. Implement `VyreBackend` for your backend struct. Include a
   `BackendCapability` describing the ops, memory model, subgroup
   size, and max workgroup extent your hardware supports.
3. Implement `CompiledPipeline` for your cached pipeline form. It
   MUST be bit-identical to the trait's `dispatch` path.
4. Register with `inventory::submit!` — the registry picks it up at
   link time. No `lazy_static`, no initializer function.
5. Add your backend to the conformance matrix under
   `conform/vyre-conform-runner` so parity against the reference
   interpreter is enforced on every CI run.
6. Expose a `BackendPrecedence` value so callers that want "the best
   available backend" pick yours when appropriate.

See `capability.rs`, `registry.rs`, and `shadow.rs` for the exact
contracts; see `conform/vyre-conform-runner/tests/parity_matrix.rs`
for a worked wiring that brings a third-party backend online.