1use vyre::ir::Program;
9use vyre_primitives::bitset::and::bitset_and;
10use vyre_primitives::graph::csr_forward_traverse::bitset_words;
11
12pub(crate) const OP_ID: &str = "weir::scc_query";
13
14#[must_use]
24pub fn scc_query(node_count: u32, same_scc_buf: &str, query_set: &str, out: &str) -> Program {
25 let words = bitset_words(node_count);
26 vyre_harness::region::tag_program(OP_ID, bitset_and(same_scc_buf, query_set, out, words))
27}
28
29#[must_use]
31#[cfg(any(test, feature = "cpu-parity"))]
32#[deprecated(
33 note = "reference oracle only; production code must dispatch the Weir Program on a concrete GPU backend or use weir::oracle for parity evidence"
34)]
35pub(crate) fn cpu_ref(same_scc: &[u32], query_set: &[u32]) -> Vec<u32> {
36 vyre_primitives::bitset::and::cpu_ref(same_scc, query_set)
37}
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41pub struct SccQuery;
42impl super::soundness::SoundnessTagged for SccQuery {
43 fn soundness(&self) -> super::soundness::Soundness {
44 super::soundness::Soundness::Exact
45 }
46}
47
48inventory::submit! {
49 vyre_harness::OpEntry::new(
50 OP_ID,
51 || scc_query(4, "same", "query", "out"),
52 Some(|| {
53 let u32s = crate::dispatch_decode::pack_u32;
54 vec![vec![u32s(&[0b1100]), u32s(&[0b1010]), u32s(&[0])]]
55 }),
56 Some(|| {
57 let u32s = crate::dispatch_decode::pack_u32;
58 vec![vec![u32s(&[0b1000])]]
59 }),
60 )
61}
62
63#[cfg(test)]
64#[allow(deprecated)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn same_scc_query_intersects() {
70 assert_eq!(cpu_ref(&[0b1100], &[0b1010]), vec![0b1000]);
71 }
72
73 #[test]
74 fn no_match_yields_empty() {
75 assert_eq!(cpu_ref(&[0b0011], &[0b1100]), vec![0]);
76 }
77
78 #[test]
79 fn singleton_scc_self_match() {
80 assert_eq!(cpu_ref(&[0b0001], &[0b0001]), vec![0b0001]);
81 }
82
83 #[test]
84 fn distributes_per_word() {
85 assert_eq!(
86 cpu_ref(&[0xFF00, 0xF00F], &[0x0FF0, 0x0F0F]),
87 vec![0x0F00, 0x000F]
88 );
89 }
90}