vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
//! In-core registry gate for operations that are about to be lowered to GPU code.
//!
//! `vyre-conform` depends on `vyre`, so this module provides the first-pass
//! certificate check inside `vyre` itself. Before an operation ID is allowed
//! to reach WGSL lowering or handwritten kernel compilation, it must be
//! registered in the in-core operation registry. This module is the narrow
//! runtime contract that keeps uncertified IR from ever touching a backend.
//!
//! The gate is intentionally thin: it treats registry membership as proof of
//! conformance. Future versions can swap the lookup for sealed certificate
//! verification without changing any runtime callers.

use std::fmt;

/// Failure returned when runtime code attempts to lower an uncertified operation.
///
/// The registry gate rejects any operation that is not present in the generated
/// registry. The error message includes an actionable `Fix:` hint so that
/// backend authors know exactly how to register the missing op.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RegistryGateError {
    op_id: String,
}

impl RegistryGateError {
    pub(crate) fn new(op_id: &str) -> Self {
        Self {
            op_id: op_id.to_string(),
        }
    }

    /// Returns the operation ID that failed the registry gate.
    ///
    /// This identifier can be used to locate the missing registration in
    /// `rules/op/` or to diagnose why a frontend-generated op was
    /// not enrolled in the certificate chain.
    #[must_use]
    pub fn op_id(&self) -> &str {
        &self.op_id
    }
}

impl fmt::Display for RegistryGateError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Fix: op {} lowered to WGSL without registry certificate; run vyre-conform certification or register the op in rules/op/.",
            self.op_id
        )
    }
}

impl std::error::Error for RegistryGateError {}

/// Checks that an operation ID is present in the current conform registry view.
///
/// The in-core registry is generated at build time from the spec files under
/// `rules/op/`. If the ID is missing, the operation has not passed
/// the registry gate and must not be lowered to backend code.
///
/// # Errors
///
/// Returns [`RegistryGateError`] when `op_id` is not registered. The error
/// includes a `Fix:` hint directing the caller to register the op.
///
/// # Examples
///
/// ```
/// use vyre::ops::registry::gate::check_certificate;
///
/// // Assuming `primitive.bitwise.xor` is registered:
/// assert!(check_certificate("primitive.bitwise.xor").is_ok());
/// ```
pub fn check_certificate(op_id: &str) -> std::result::Result<(), RegistryGateError> {
    if crate::ops::registry::lookup(op_id).is_some() {
        Ok(())
    } else {
        Err(RegistryGateError::new(op_id))
    }
}

/// Verifies that an operation ID has a current registry certificate.
///
/// This is a stable alias for [`check_certificate`]. Runtime callers that
/// need to assert conformance before lowering should use this function so
/// that future certificate-verification changes do not require call-site
/// rewrites.
///
/// # Errors
///
/// Returns [`RegistryGateError`] when `op_id` is missing from the registry.
///
/// # Examples
///
/// ```
/// use vyre::ops::registry::gate::verify_certificate;
///
/// assert!(verify_certificate("primitive.bitwise.xor").is_ok());
/// ```
pub fn verify_certificate(op_id: &str) -> std::result::Result<(), RegistryGateError> {
    check_certificate(op_id)
}

/// Verifies that a program carries a registered entry operation ID.
///
/// Every [`crate::ir::Program`] produced by the standard operation library
/// carries an entry op ID. This function extracts that ID and asserts that
/// it has a registry certificate. Anonymous programs are rejected because
/// they cannot be traced back to a certified operation definition.
///
/// # Errors
///
/// Returns [`RegistryGateError`] when the program is anonymous or its
/// operation ID is missing from the registry.
///
/// # Examples
///
/// ```no_run
/// use vyre::{ir::Program, ops::registry::gate::verify_program_certificate};
///
/// let program = Program::new(vec![], [1, 1, 1], vec![]);
/// let result = verify_program_certificate(&program);
/// ```
pub fn verify_program_certificate(
    program: &crate::ir::Program,
) -> std::result::Result<(), RegistryGateError> {
    let op_id = program.entry_op_id().unwrap_or("<anonymous>");
    verify_certificate(op_id)
}