vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
// Unsigned maximum of two u32 values.

use crate::ir::{Expr, Program};
use crate::ops::primitive;
use crate::ops::{AlgebraicLaw, OpSpec, U32_OUTPUTS, U32_U32_INPUTS};


pub const LAWS: &[AlgebraicLaw] = &[
    AlgebraicLaw::Commutative,
    AlgebraicLaw::Associative,
    AlgebraicLaw::Identity { element: 0 },
    AlgebraicLaw::Idempotent,
    AlgebraicLaw::Absorbing { element: u32::MAX },
    AlgebraicLaw::DistributiveOver {
        over_op: "primitive.math.min",
    },
    AlgebraicLaw::LatticeAbsorption {
        dual_op: "primitive.math.min",
    },
];

/// Unsigned maximum operation.
#[derive(Debug, Clone, Copy, Default)]
pub struct Max;

impl Max {
    /// Declarative operation specification.
    ///
    /// Laws are declared as explicit `AlgebraicLaw` values on `SPEC`.
    pub const SPEC: OpSpec = OpSpec::composition_inlinable(
        "primitive.math.max",
        U32_U32_INPUTS,
        U32_OUTPUTS,
        LAWS,
        Self::program,
    );

    /// Build the canonical IR program.
    ///
    /// # Examples
    ///
    /// ```
    /// use vyre::ir::Expr;
    /// use vyre::ops::primitive::max::Max;
    ///
    /// let _expr = Expr::select(Expr::ge(Expr::u32(7), Expr::u32(3)), Expr::u32(7), Expr::u32(3));
    /// let program = Max::program();
    /// assert!(!program.entry().is_empty());
    /// ```
    #[must_use]
    pub fn program() -> Program {
        primitive::binary_u32_program(|a, b| Expr::select(Expr::ge(a.clone(), b.clone()), a, b))
    }
}