use crate::region::wrap_anonymous;
use vyre::ir::{BufferAccess, BufferDecl, DataType, Expr, Node, Program};
#[must_use]
pub fn unpack_4bit_f32(input: &str, output: &str, n: u32) -> Program {
let i = Expr::var("i");
let u32_idx = Expr::div(i.clone(), Expr::u32(8));
let shift = Expr::mul(Expr::rem(i.clone(), Expr::u32(8)), Expr::u32(4));
let val = Expr::bitand(Expr::shr(Expr::load(input, u32_idx), shift), Expr::u32(0xF));
let body = vec![
Node::let_bind("i", Expr::InvocationId { axis: 0 }),
Node::if_then(
Expr::lt(i.clone(), Expr::u32(n)),
vec![Node::Store {
buffer: output.into(),
index: i,
value: Expr::cast(DataType::F32, val),
}],
),
];
Program::wrapped(
vec![
BufferDecl::storage(input, 0, BufferAccess::ReadOnly, DataType::U32).with_count(n / 8),
BufferDecl::output(output, 1, DataType::F32).with_count(n),
],
[64, 1, 1],
vec![wrap_anonymous(
"vyre-libs::representation::unpack_4bit_f32",
body,
)],
)
}
inventory::submit! {
crate::harness::OpEntry {
id: "vyre-libs::representation::unpack_4bit_f32",
build: || unpack_4bit_f32("input", "output", 16),
test_inputs: Some(|| {
vec![vec![
crate::test_support::byte_pack::u32_bytes(&[0x7654_3210, 0xFEDC_BA98]), ]]
}),
expected_output: Some(|| {
let values: Vec<f32> = (0u32..16).map(|v| v as f32).collect();
let bytes = vyre_primitives::wire::pack_f32_slice(&values);
vec![vec![bytes]]
}),
category: None,
}
}