vyre-emit-spirv 0.6.2

SPIR-V binary emitter for vyre KernelDescriptor. Routes through naga::Module → naga::back::spv to share substrate-neutral lowering with vyre-emit-naga.
Documentation

vyre-emit-spirv

SPIR-V binary emitter for vyre's KernelDescriptor.

Routes through vyre-emit-naga to produce a naga::Module first, then uses naga::back::spv::Writer to output a SPIR-V binary. This shares the lossless lowering work with the wgpu/naga path: both backends consume the same naga::Module, and avoids forking a second KernelOp → SPIR-V translation table.

Quick start

use vyre_lower::{
    BindingLayout, BindingSlot, BindingVisibility, Dispatch, KernelBody,
    KernelDescriptor, KernelOp, KernelOpKind, LiteralValue, MemoryClass,
};
use vyre_foundation::ir::DataType;
use vyre_emit_spirv::{emit_optimized, SPIRV_MAGIC};

let desc = KernelDescriptor {
    id: "store_seven".into(),
    bindings: BindingLayout {
        slots: vec![BindingSlot {
            slot: 0,
            element_type: DataType::U32,
            element_count: None,
            memory_class: MemoryClass::Global,
            visibility: BindingVisibility::ReadWrite,
            name: "out".into(),
        }],
    },
    dispatch: Dispatch::new(64, 1, 1),
    body: KernelBody {
        ops: vec![
            KernelOp { kind: KernelOpKind::Literal, operands: vec![0], result: Some(0) },
            KernelOp { kind: KernelOpKind::Literal, operands: vec![1], result: Some(1) },
            KernelOp {
                kind: KernelOpKind::StoreGlobal,
                operands: vec![0, 0, 1],
                result: None,
            },
        ],
        child_bodies: vec![],
        literals: vec![LiteralValue::U32(0), LiteralValue::U32(7)],
    },
};

let words = emit_optimized(&desc).unwrap();
assert_eq!(words[0], SPIRV_MAGIC);

API

  • emit(&desc) -> Result<Vec<u32>, EmitError>: lower as given. Output is SPIR-V words (the canonical representation per the spec).
  • emit_optimized(&desc) -> Result<Vec<u32>, EmitError>: recommended. Runs vyre_lower::rewrites::run_all first; debug builds also run verify via debug_assert!.
  • emit_optimized_with_stats(&desc) -> Result<(Vec<u32>, OptimizationStats), EmitError>: same as emit_optimized plus optimization metrics.
  • emit_bytes(&desc) -> Result<Vec<u8>, EmitError>: convenience for runtime loaders that want little-endian bytes.
  • emit_optimized_bytes(&desc) / emit_optimized_bytes_with_stats(&desc): bytes-axis variants that also run the optimization pipeline first.
  • emit_from_naga_module(&module) -> Result<Vec<u32>, EmitError>: lower-level entry point if you want to apply naga-level rewrites between vyre_emit_naga::emit and SPIR-V conversion.

Constants

  • SPIRV_MAGIC: u32 = 0x07230203: the SPIR-V magic word per the spec. Useful for sanity checks on emit output.

Substrate-specific patterns

patterns/ contains SPIR-V-specific analyses:

  • subgroup_capabilities: walks the descriptor for subgroup ops (Ballot, Shuffle, Add, LocalId, Size) and produces a SubgroupCapabilities { basic, ballot, shuffle, arithmetic } flag set so the host knows which VkSubgroupFeatureFlagBits to require on the pipeline.
  • workgroup_size_validation: checks dispatch.workgroup_size against VULKAN_BASELINE (or a custom DeviceLimits profile). Catches per-dim overflow, product overflow, zero-dim violations.

Run patterns::audit(&desc) for a unified SpirvAuditReport with both patterns. Run patterns::audit_optimized(&desc) to audit the post-run_all form (subgroup capability detection may report fewer required caps after dead-code elimination).

Validation

naga::valid::Validator runs before naga::back::spv::Writer, so any module that gets to Writer is structurally valid per Naga's spec compliance. The emitted SPIR-V binary therefore satisfies SPIR-V's structural requirements as far as Naga's coverage goes; optional external spirv-val validation can be wired into your CI.

Errors

  • EmitError::NagaEmit(naga_err): the upstream vyre_emit_naga call failed. Most often UnsupportedOp(...) for KernelOpKinds Naga can't represent.
  • EmitError::NagaValidation(s): Naga's validator rejected the module. Indicates a bug in this crate or in vyre-emit-naga.
  • EmitError::WriterConstruction(s) / WriterWrite(s): Naga's SPIR-V writer failed.

See also

  • vyre-lower: IR + rewrite stack + verify.
  • vyre-emit-naga: the upstream emit path this crate routes through.
  • vyre-emit-ptx: independent PTX emitter for CUDA.

License

MIT OR Apache-2.0.