vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
//! Hex decode operation as an IR composition.

/// CPU-independent IR kernel for contiguous hexadecimal byte runs.
pub mod kernel {
    use super::super::shared::{and, hex_nibble, BYTE_BOUNDED_LAWS};
    use crate::ir::{BufferDecl, DataType, Expr, Node, Program};
    use crate::ops::{OpSpec, BYTES_TO_BYTES_INPUTS, BYTES_TO_BYTES_OUTPUTS};

    /// GPU region decoder for contiguous hexadecimal byte runs.
    #[derive(Debug, Clone, Copy, Default)]
    pub struct HexDecode;

    impl HexDecode {
        /// Declarative operation specification.
        pub const SPEC: OpSpec = OpSpec::composition(
            "decode.hex",
            BYTES_TO_BYTES_INPUTS,
            BYTES_TO_BYTES_OUTPUTS,
            BYTE_BOUNDED_LAWS,
            Self::program,
        );

        /// Build the canonical IR program.
        #[must_use]
        pub fn program() -> Program {
            let idx = Expr::var("idx");
            let input_idx = Expr::mul(idx.clone(), Expr::u32(2));
            Program::new(
                vec![
                    BufferDecl::read("input", 0, DataType::Bytes),
                    BufferDecl::output("out", 1, DataType::Bytes),
                ],
                [64, 1, 1],
                vec![
                    Node::let_bind("idx", Expr::gid_x()),
                    Node::if_then(
                        and(
                            Expr::lt(
                                Expr::add(input_idx.clone(), Expr::u32(1)),
                                Expr::buf_len("input"),
                            ),
                            Expr::lt(idx.clone(), Expr::buf_len("out")),
                        ),
                        vec![
                            Node::let_bind(
                                "hi",
                                hex_nibble(Expr::load("input", input_idx.clone())),
                            ),
                            Node::let_bind(
                                "lo",
                                hex_nibble(Expr::load(
                                    "input",
                                    Expr::add(input_idx, Expr::u32(1)),
                                )),
                            ),
                            Node::store(
                                "out",
                                idx,
                                Expr::bitor(
                                    Expr::shl(Expr::var("hi"), Expr::u32(4)),
                                    Expr::var("lo"),
                                ),
                            ),
                        ],
                    ),
                ],
            )
        }
    }
}

pub use kernel::HexDecode;