vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
use crate::ir::{BufferDecl, DataType, Expr, Node, Program};
use crate::ops::{AlgebraicLaw, OpSpec};

// Two's-complement negation of an i32 value.



pub const INPUTS: &[DataType] = &[DataType::I32];

pub const OUTPUTS: &[DataType] = &[DataType::I32];

pub const LAWS: &[AlgebraicLaw] = &[AlgebraicLaw::Involution];

/// Signed i32 negation operation.
#[derive(Debug, Clone, Copy, Default)]
pub struct Neg;

impl Neg {
    /// Declarative operation specification.
    pub const SPEC: OpSpec =
        OpSpec::composition_inlinable("primitive.math.neg", INPUTS, OUTPUTS, LAWS, Self::program);

    /// Build the canonical IR program.
    #[must_use]
    pub fn program() -> Program {
        let idx = Expr::var("idx");
        Program::new(
            vec![
                BufferDecl::read("a", 0, DataType::I32),
                BufferDecl::output("out", 1, DataType::I32),
            ],
            [64, 1, 1],
            vec![
                Node::let_bind("idx", Expr::gid_x()),
                Node::if_then(
                    Expr::lt(idx.clone(), Expr::buf_len("out")),
                    vec![Node::store(
                        "out",
                        idx.clone(),
                        Expr::cast(
                            DataType::I32,
                            Expr::negate(Expr::cast(DataType::U32, Expr::load("a", idx))),
                        ),
                    )],
                ),
            ],
        )
    }
}

// Backend-specific lowering tripwires for signed negation.

// WGSL lowering marker for `primitive.math.neg`.
//
// Not a stub: this is a zero-overhead Category A marker. `Neg::program`
// builds concrete IR through `core/src/ops/primitive/math/neg/kernel.rs`; `core/src/lower/wgsl_cast.rs + core/src/lower/wgsl/expr.rs` emits WGSL.
// `core/tests/conformance.rs::conformance_all_primitives` verifies
// lowered GPU bytes are bit-exact against the conform CPU reference.
//
// ```wgsl
// _vyre_store_out(idx, bitcast<i32>((~bitcast<u32>(_vyre_load_a(idx)) + 1u)));
// ```