vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
//! TODO: <OP_NAME> specification - describe the operation in one sentence.
//!
//! Copy this file to `src/specs/primitive/<name>.rs`, then fill every TODO
//! slot before registering the operation:
//!
//! - TODO id: stable identifier, for example `primitive.bitwise.rotr`
//! - TODO cpu_fn: standard Rust byte reference; use little-endian u32 encoding
//! - TODO wgsl_fn: `fn vyre_op(index: u32, input_len: u32) -> u32`
//! - TODO laws: every true and useful algebraic law
//! - TODO equivalence_classes: at minimum `EquivalenceClass::universal(...)`
//! - TODO boundary_values: use `binary_common_boundaries()` or
//!   `unary_common_boundaries()` when those cover the operation
//!
//! After saving the copied file:
//!
//! 1. Add `pub mod <name>;` to `src/specs/primitive/mod.rs`.
//! 2. Add `<name>::spec()` to the `specs()` function in
//!    `src/specs/primitive/mod.rs`.
//! 3. Run `cargo test --test algebra_self_test` from `vyre-conform/`.

use super::{AlgebraicLaw, BoundaryValue, EquivalenceClass};
use crate::OpSpec;

fn read_u32_le(input: &[u8], offset: usize) -> Option<u32> {
    let bytes = input.get(offset..offset + 4)?;
    Some(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}

fn cpu(input: &[u8]) -> Vec<u8> {
    // TODO cpu_fn:
    // - Handle short input by returning `vec![0; 4]`.
    // - Decode each u32 from little-endian bytes.
    // - Implement the exact operation semantics in standard Rust.
    // - Return exactly one u32 encoded with `to_le_bytes().to_vec()`.
    if input.len() < 8 {
        return vec![0; 4];
    }

    let left = read_u32_le(input, 0).expect("length checked above");
    let right = read_u32_le(input, 4).expect("length checked above");
    let result = {
        // TODO: replace this expression with the operation.
        // Example shape only: `left.<operation>(right)`.
        TODO_REPLACE_WITH_OPERATION_RESULT(left, right)
    };

    result.to_le_bytes().to_vec()
}

fn wgsl() -> String {
    // TODO wgsl_fn:
    // - Keep this exact function signature.
    // - Read inputs from `input.data[0u]`, `input.data[1u]`, etc.
    // - Match `cpu` for every edge case, including short-input defaults,
    //   masked shifts, overflow, and zero rotation where relevant.
    r"
fn vyre_op(index: u32, input_len: u32) -> u32 {
    let left = input.data[0u];
    let right = input.data[1u];
    return TODO_REPLACE_WITH_OPERATION_RESULT(left, right);
}
"
    .to_string()
}

/// Build the conformance specification for this operation.
pub fn spec() -> OpSpec {
    let mut spec = super::make_spec(
        "TODO: primitive.category.name",
        super::binary_u32_sig(),
        cpu,
        wgsl,
    );

    // TODO laws:
    // Read `docs/algebra/laws/` and declare every law that is true.
    // Leave this empty only when no available law is true and useful.
    spec.laws = vec![
        // AlgebraicLaw::Commutative,
        // AlgebraicLaw::Associative,
        // AlgebraicLaw::Identity { element: 0 },
    ];

    // TODO equivalence_classes:
    // Use a universal class only when the operation has no semantic branches.
    // Add `EquivalenceClass::specific(...)` entries for distinct paths such as
    // divide-by-zero, shift >= 32, rotation by zero, or saturation boundaries.
    spec.equivalence_classes = vec![EquivalenceClass::universal("TODO: all valid inputs")];

    // TODO boundary_values:
    // Use the common helper when sufficient, otherwise list every transition,
    // zero case, max case, overflow point, and one-past-edge explicitly.
    spec.boundary_values = super::binary_common_boundaries();
    // For unary operations, use:
    // spec.boundary_values = super::unary_common_boundaries();
    // For operation-specific binary boundaries, use:
    // spec.boundary_values = vec![
    //     BoundaryValue::binary("zero_zero", 0, 0),
    //     BoundaryValue::binary("max_max", u32::MAX, u32::MAX),
    // ];

    spec
}