use std::sync::Arc;
use vyre::ir::{BufferAccess, BufferDecl, DataType, Expr, Ident, Node, Program};
use vyre::DispatchConfig;
use vyre_driver_cuda::cuda_factory;
fn anchor_wrapper_program(node_count: u32) -> Program {
let words = node_count.div_ceil(32);
let body = vec![
Node::let_bind("gid", Expr::InvocationId { axis: 0 }),
Node::let_bind("word_idx", Expr::shr(Expr::var("gid"), Expr::u32(5))),
Node::let_bind(
"bit_mask",
Expr::shl(Expr::u32(1), Expr::bitand(Expr::var("gid"), Expr::u32(31))),
),
Node::let_bind("anchor_word", Expr::load("anchor", Expr::var("word_idx"))),
Node::let_bind(
"anchor_bit",
Expr::bitand(Expr::var("anchor_word"), Expr::var("bit_mask")),
),
Node::store(
"result",
Expr::var("gid"),
Expr::select(
Expr::ne(Expr::var("anchor_bit"), Expr::u32(0)),
Expr::u32(1),
Expr::u32(0),
),
),
];
Program::wrapped(
vec![
BufferDecl::storage("anchor", 0, BufferAccess::ReadOnly, DataType::U32)
.with_count(words),
BufferDecl::storage("result", 1, BufferAccess::ReadWrite, DataType::U32)
.with_count(node_count),
],
[256, 1, 1],
vec![Node::Region {
generator: Ident::from("weir::tests::df::anchor_bit_codegen"),
source_region: None,
body: Arc::new(vec![Node::if_then(
Expr::lt(Expr::InvocationId { axis: 0 }, Expr::u32(node_count)),
body,
)]),
}],
)
}
#[test]
fn anchor_bit_codegen_fires_at_every_node_id() {
let backend = cuda_factory().unwrap_or_else(|error| {
panic!(
"CUDA adapter acquisition failed for anchor_bit codegen probe: {error}. \
Fix: repair the CUDA driver/runtime probe; Weir GPU codegen tests must not skip."
)
});
const NODE_COUNT: u32 = 65536;
let words = NODE_COUNT.div_ceil(32);
let program = anchor_wrapper_program(NODE_COUNT);
let cfg = DispatchConfig::default();
let probe_nodes: &[u32] = &[
0, 1, 24, 30, 31, 32, 33, 39, 42, 52, 70, 100, 1000, 4096, 65535,
];
for &node_id in probe_nodes {
let mut anchor = vec![0u32; words as usize];
anchor[(node_id / 32) as usize] |= 1u32 << (node_id % 32);
let anchor_b: Vec<u8> = vyre_primitives::wire::pack_u32_slice(&anchor);
let result_b: Vec<u8> = vec![0u8; (NODE_COUNT as usize) * 4];
let inputs: [&[u8]; 2] = [&anchor_b, &result_b];
let outputs = backend
.dispatch_borrowed(&program, &inputs, &cfg)
.unwrap_or_else(|e| panic!("dispatch failed at node {node_id}: {e}"));
let result = vyre_primitives::wire::decode_u32_le_bytes_all(&outputs[0]);
let observed = result[node_id as usize];
eprintln!(
"node_id={node_id:>5} word_idx={} bit={:#010x} result[{node_id}]={observed}",
node_id / 32,
1u32 << (node_id % 32),
);
assert_eq!(
observed, 1,
"FAILED at node {node_id}: anchor_word_idx={}, expected result[{node_id}]=1, got {observed}. \
The substrate's shr+bitand+load+store pattern miscompiled for this gid. \
Bisects the recall bug to vyre-driver-cuda codegen, not surgec lowering.",
node_id / 32,
);
for (i, w) in result.iter().enumerate() {
if i as u32 != node_id {
assert_eq!(
*w, 0,
"spurious finding at gid {i} when only node {node_id} should fire (result[{i}]={w})"
);
}
}
}
}