use crate::ir::{DataType, Program};
mod metadata;
pub use vyre_spec::AlgebraicLaw;
pub mod discovered {
include!(concat!(env!("OUT_DIR"), "/walked_ops.rs"));
}
pub mod cpu_op;
pub use cpu_op::{CategoryAOp, CpuOp};
pub use metadata::{Backend, Category, Compose, IntrinsicDescriptor};
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub struct OpSpec {
id: &'static str,
category: Category,
inputs: &'static [DataType],
outputs: &'static [DataType],
laws: &'static [AlgebraicLaw],
inlinable: bool,
compose: Compose,
}
impl OpSpec {
#[must_use]
pub const fn composition(
id: &'static str,
inputs: &'static [DataType],
outputs: &'static [DataType],
laws: &'static [AlgebraicLaw],
compose: fn() -> Program,
) -> Self {
Self {
id,
category: Category::A,
inputs,
outputs,
laws,
inlinable: false,
compose: Compose::Composition(compose),
}
}
#[must_use]
pub const fn composition_inlinable(
id: &'static str,
inputs: &'static [DataType],
outputs: &'static [DataType],
laws: &'static [AlgebraicLaw],
compose: fn() -> Program,
) -> Self {
Self {
id,
category: Category::A,
inputs,
outputs,
laws,
inlinable: true,
compose: Compose::Composition(compose),
}
}
#[must_use]
pub const fn intrinsic(
id: &'static str,
inputs: &'static [DataType],
outputs: &'static [DataType],
laws: &'static [AlgebraicLaw],
backend_availability: fn(&Backend) -> bool,
intrinsic: IntrinsicDescriptor,
) -> Self {
Self {
id,
category: Category::C {
backend_availability,
},
inputs,
outputs,
laws,
inlinable: false,
compose: Compose::Intrinsic(intrinsic),
}
}
#[must_use]
pub const fn id(&self) -> &'static str {
self.id
}
#[must_use]
pub const fn category(&self) -> Category {
self.category
}
#[must_use]
pub const fn inputs(&self) -> &'static [DataType] {
self.inputs
}
#[must_use]
pub const fn outputs(&self) -> &'static [DataType] {
self.outputs
}
#[must_use]
pub const fn laws(&self) -> &'static [AlgebraicLaw] {
self.laws
}
#[must_use]
pub const fn inlinable(&self) -> bool {
self.inlinable
}
#[must_use]
pub const fn compose(&self) -> Compose {
self.compose
}
#[must_use]
pub fn program(&self) -> Option<Program> {
match self.compose {
Compose::Composition(build) => Some(build().with_entry_op_id(self.id)),
Compose::Intrinsic(_) => None,
}
}
#[must_use]
pub fn available_on(&self, backend: &Backend) -> bool {
match self.category {
Category::A => true,
Category::C {
backend_availability,
} => backend_availability(backend),
}
}
}
pub const BYTES_TO_BYTES_INPUTS: &[DataType] = &[DataType::Bytes];
pub const BYTES_TO_BYTES_OUTPUTS: &[DataType] = &[DataType::Bytes];
pub const BYTES_TO_U32_OUTPUTS: &[DataType] = &[DataType::U32];
pub const U32_INPUTS: &[DataType] = &[DataType::U32];
pub const U32_U32_INPUTS: &[DataType] = &[DataType::U32, DataType::U32];
pub const U32_OUTPUTS: &[DataType] = &[DataType::U32];
pub const F32_INPUTS: &[DataType] = &[DataType::F32];
pub const F32_F32_INPUTS: &[DataType] = &[DataType::F32, DataType::F32];
pub const F32_F32_F32_INPUTS: &[DataType] = &[DataType::F32, DataType::F32, DataType::F32];
pub const F32_OUTPUTS: &[DataType] = &[DataType::F32];
pub const I32_OUTPUTS: &[DataType] = &[DataType::I32];
pub const BOOL_OUTPUTS: &[DataType] = &[DataType::Bool];
pub mod buffer;
pub mod compression;
pub mod crypto;
pub mod data_movement;
pub mod decode;
pub mod encode;
pub mod graph;
pub mod hash;
pub mod match_ops;
pub mod primitive;
pub mod reductions;
pub mod registry;
pub mod rule;
pub mod scan;
pub mod security_detection;
pub mod sort;
pub mod stats;
pub mod string;
pub mod string_matching;
pub mod string_similarity;
pub mod workgroup;
#[cfg(test)]
pub mod fixtures;