#![allow(clippy::too_many_arguments)]
use vyre::ir::Program;
use vyre_foundation::execution_plan::fusion::fuse_programs;
use vyre_primitives::bitset::and::bitset_and;
use vyre_primitives::bitset::copy::bitset_copy;
use vyre_primitives::fixpoint::bitset_fixpoint::bitset_fixpoint_warm_start;
use vyre_primitives::graph::csr_forward_traverse::{bitset_words, csr_forward_traverse};
use vyre_primitives::graph::program_graph::ProgramGraphShape;
pub(crate) const OP_ID: &str = "weir::cross_language";
pub const EDGE_KIND_FFI: u32 = 0x0001_0000;
pub const EDGE_KIND_ALL: u32 = 0xFFFF_FFFF;
pub fn cross_language(
node_count: u32,
source: &str,
sink: &str,
post_cross: &str,
current: &str,
next: &str,
changed: &str,
seed: &str,
out: &str,
) -> Result<Program, String> {
let words = bitset_words(node_count);
let edge_capacity = node_count
.checked_mul(8)
.map(|capacity| capacity.max(1))
.ok_or_else(|| {
format!(
"Fix: cross-language reachability shape for node_count={node_count} exceeds u32 edge-capacity metadata. Partition the interprocedural graph before constructing the GPU program."
)
})?;
let shape = ProgramGraphShape::new(node_count, edge_capacity);
let stage_source_seed = bitset_copy(seed, source, words);
let stage_source_reach = bitset_fixpoint_warm_start(current, next, changed, seed, words);
let stage_bridge = csr_forward_traverse(shape, current, post_cross, EDGE_KIND_FFI);
let stage_seed = bitset_copy(seed, post_cross, words);
let stage_post_cross_reach = bitset_fixpoint_warm_start(current, next, changed, seed, words);
let stage_sink = bitset_and(current, sink, out, words);
let fused = fuse_programs(&[
stage_source_seed,
stage_source_reach,
stage_bridge,
stage_seed,
stage_post_cross_reach,
stage_sink,
])
.map_err(|error| {
format!(
"Fix: cross-language reachability fusion failed for node_count={node_count}, words={words}: {error:?}"
)
})?;
Ok(vyre_harness::region::tag_program(OP_ID, fused))
}
#[must_use]
#[cfg(any(test, feature = "cpu-parity"))]
#[deprecated(
note = "reference oracle only; production code must dispatch the Weir Program on a concrete GPU backend or use weir::oracle for parity evidence"
)]
pub(crate) fn cpu_ref(
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
edge_is_ffi: &[u32],
source: &[u32],
sink: &[u32],
) -> Vec<u32> {
let nodes =
usize::try_from(node_count).expect("cross_language_cpu_ref node_count must fit host usize");
let words = nodes.checked_add(31).unwrap_or_else(|| {
panic!(
"cross_language_cpu_ref node_count={node_count} overflows host bitset word calculation. Fix: shard the oracle graph."
)
}) / 32;
crate::dispatch_decode::require_csr_shape(
"cross_language_cpu_ref",
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
)
.expect("cross_language cpu_ref oracle received malformed CSR graph");
if edge_is_ffi.len() != edge_targets.len() {
panic!(
"cross_language cpu_ref oracle received malformed FFI edge mask: expected {} words, got {}",
edge_targets.len(),
edge_is_ffi.len()
);
}
crate::dispatch_decode::require_bitset_words("cross_language_cpu_ref source", source, words)
.expect("cross_language cpu_ref oracle received malformed source bitset");
crate::dispatch_decode::require_bitset_words("cross_language_cpu_ref sink", sink, words)
.expect("cross_language cpu_ref oracle received malformed sink bitset");
let test = |bs: &[u32], n: u32| -> bool {
let n = usize::try_from(n).expect("cross_language_cpu_ref bit index must fit usize");
let w = n / 32;
let b = n % 32;
bs[w] & (1u32 << b) != 0
};
let mark = |bs: &mut [u32], n: u32| -> bool {
let n = usize::try_from(n).expect("cross_language_cpu_ref bit index must fit usize");
let w = n / 32;
let b = n % 32;
let mask = 1u32 << b;
let was_set = bs[w] & mask != 0;
if was_set {
return false;
}
bs[w] |= 1u32 << b;
true
};
let mut source_side_reach = vec![0u32; words];
let mut queue = Vec::new();
for n in 0..node_count {
if test(source, n) && mark(&mut source_side_reach, n) {
queue.push(n);
}
}
let mut cursor = 0usize;
while cursor < queue.len() {
let n = queue[cursor];
cursor += 1;
let node = usize::try_from(n).expect("cross_language_cpu_ref node index must fit usize");
let start = usize::try_from(edge_offsets[node])
.expect("cross_language_cpu_ref CSR row start must fit usize");
let end = usize::try_from(edge_offsets[node + 1])
.expect("cross_language_cpu_ref CSR row end must fit usize");
for i in start..end {
let t = edge_targets[i];
if t < node_count && mark(&mut source_side_reach, t) {
queue.push(t);
}
}
}
let mut post_cross = vec![0u32; words];
queue.clear();
for n in 0..node_count {
if !test(&source_side_reach, n) {
continue;
}
let node = usize::try_from(n).expect("cross_language_cpu_ref node index must fit usize");
let start = usize::try_from(edge_offsets[node])
.expect("cross_language_cpu_ref CSR row start must fit usize");
let end = usize::try_from(edge_offsets[node + 1])
.expect("cross_language_cpu_ref CSR row end must fit usize");
for i in start..end {
let kind = edge_kind_mask[i];
let is_ffi = edge_is_ffi[i];
if (kind & EDGE_KIND_FFI) != 0 || is_ffi != 0 {
let t = edge_targets[i];
if t < node_count && mark(&mut post_cross, t) {
queue.push(t);
}
}
}
}
let mut reach = post_cross;
let mut cursor = 0usize;
while cursor < queue.len() {
let n = queue[cursor];
cursor += 1;
let node = usize::try_from(n).expect("cross_language_cpu_ref node index must fit usize");
let start = usize::try_from(edge_offsets[node])
.expect("cross_language_cpu_ref CSR row start must fit usize");
let end = usize::try_from(edge_offsets[node + 1])
.expect("cross_language_cpu_ref CSR row end must fit usize");
for i in start..end {
let t = edge_targets[i];
if t < node_count && mark(&mut reach, t) {
queue.push(t);
}
}
}
let mut out = vec![0u32; words];
for w in 0..words {
out[w] = reach[w] & sink[w];
}
out
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CrossLanguage;
impl super::soundness::SoundnessTagged for CrossLanguage {
fn soundness(&self) -> super::soundness::Soundness {
super::soundness::Soundness::MayOver
}
}
fn release_witness_program() -> Program {
match cross_language(
4,
"source",
"sink",
"post_cross",
"current",
"next",
"changed",
"seed",
"out",
) {
Ok(program) => program,
Err(error) => {
unreachable!("weir::cross_language fixed release witness must fuse; error={error}")
}
}
}
fn release_witness_inputs() -> Vec<Vec<Vec<u8>>> {
let u32s = crate::dispatch_decode::pack_u32;
vec![vec![
u32s(&[0]), u32s(&[0b0001]), u32s(&[0]), u32s(&[0]), u32s(&[0]), u32s(&[0, 0, 0, 0]), u32s(&[0, 1, 1, 1, 1]), u32s(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), u32s(&[EDGE_KIND_FFI, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), u32s(&[0, 0, 0, 0]), u32s(&[0]), u32s(&[0b0010]), u32s(&[0]), ]]
}
fn release_witness_expected() -> Vec<Vec<Vec<u8>>> {
let u32s = crate::dispatch_decode::pack_u32;
vec![vec![
u32s(&[0b0010]), u32s(&[0b0011]), u32s(&[1]), u32s(&[0b0010]), u32s(&[0b0010]), ]]
}
inventory::submit! {
vyre_harness::OpEntry::new(
OP_ID,
release_witness_program,
Some(release_witness_inputs),
Some(release_witness_expected),
)
}
#[cfg(test)]
#[allow(deprecated)]
mod tests {
use super::*;
fn one(n: u32) -> Vec<u32> {
let w = n as usize / 32;
let b = n as usize % 32;
let mut v = vec![0u32; w + 1];
v[w] = 1u32 << b;
v
}
#[test]
fn flow_through_ffi_edge_reaches_sink() {
let edge_offsets = vec![0, 1, 2, 2];
let edge_targets = vec![1u32, 2];
let edge_kind_mask = vec![EDGE_KIND_FFI, 0x1];
let edge_is_ffi = vec![1u32, 0];
let source = one(0);
let sink = one(2);
let out = cpu_ref(
3,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&edge_is_ffi,
&source,
&sink,
);
assert!(out[0] & (1 << 2) != 0, "sink should be reached: {out:?}");
}
#[test]
fn intra_language_flow_does_not_reach_sink() {
let edge_offsets = vec![0, 1, 2, 2];
let edge_targets = vec![1u32, 2];
let edge_kind_mask = vec![0x1, 0x1];
let edge_is_ffi = vec![0u32, 0];
let source = one(0);
let sink = one(2);
let out = cpu_ref(
3,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&edge_is_ffi,
&source,
&sink,
);
assert_eq!(out, vec![0u32], "no FFI hop → no cross-lang reach: {out:?}");
}
#[test]
fn ffi_edge_after_intra_language_setup_reaches_sink() {
let edge_offsets = vec![0, 1, 2, 3, 3];
let edge_targets = vec![1u32, 2, 3];
let edge_kind_mask = vec![0x1, EDGE_KIND_FFI, 0x1];
let edge_is_ffi = vec![0u32, 1, 0];
let source = one(0);
let sink = one(3);
let out = cpu_ref(
4,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&edge_is_ffi,
&source,
&sink,
);
assert!(
out[0] & (1 << 3) != 0,
"FFI bridge after intra-language setup should reach sink: {out:?}"
);
}
#[test]
fn empty_source_yields_empty_output() {
let edge_offsets = vec![0, 1, 1];
let edge_targets = vec![1u32];
let edge_kind_mask = vec![EDGE_KIND_FFI];
let edge_is_ffi = vec![1u32];
let source = vec![0u32];
let sink = one(1);
let out = cpu_ref(
2,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&edge_is_ffi,
&source,
&sink,
);
assert_eq!(out, vec![0u32]);
}
#[test]
fn multi_step_post_cross_continuation_reaches_distant_sink() {
let edge_offsets = vec![0, 1, 2, 3, 3];
let edge_targets = vec![1u32, 2, 3];
let edge_kind_mask = vec![EDGE_KIND_FFI, 0x1, 0x1];
let edge_is_ffi = vec![1u32, 0, 0];
let source = one(0);
let sink = one(3);
let out = cpu_ref(
4,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&edge_is_ffi,
&source,
&sink,
);
assert!(out[0] & (1 << 3) != 0, "distant sink reachable: {out:?}");
}
#[test]
fn op_id_is_canonical() {
assert_eq!(OP_ID, "weir::cross_language");
}
#[test]
fn release_witness_matches_fused_program_buffer_contract() {
let program = release_witness_program();
let buffer_names = program
.buffers()
.iter()
.map(|buffer| buffer.name())
.collect::<Vec<_>>();
assert_eq!(
buffer_names,
vec![
"seed",
"source",
"current",
"next",
"changed",
"pg_nodes",
"pg_edge_offsets",
"pg_edge_targets",
"pg_edge_kind_mask",
"pg_node_tags",
"post_cross",
"sink",
"out",
],
"release witness inputs must follow fused Program::buffers order"
);
let inputs = release_witness_inputs();
let case = &inputs[0];
assert_eq!(case.len(), program.buffers().len());
for (buffer, bytes) in program.buffers().iter().zip(case.iter()) {
let expected = buffer
.static_byte_len()
.expect("release witness buffers must have valid static lengths")
.expect("release witness buffers must be statically sized");
assert_eq!(
bytes.len(),
expected,
"release witness buffer `{}` has wrong byte length",
buffer.name()
);
}
let writable_names = program
.buffers()
.iter()
.filter(|buffer| {
matches!(
buffer.access(),
vyre::ir::BufferAccess::ReadWrite | vyre::ir::BufferAccess::WriteOnly
)
})
.map(|buffer| buffer.name())
.collect::<Vec<_>>();
assert_eq!(
writable_names,
vec!["seed", "current", "changed", "post_cross", "out"]
);
assert_eq!(
release_witness_expected()[0].len(),
writable_names.len(),
"expected outputs must match writable output order"
);
}
#[test]
fn cpu_ref_rejects_malformed_csr() {
let panic = std::panic::catch_unwind(|| {
let _ = cpu_ref(2, &[1, 1, 1], &[0], &[0], &[0], &[0b1], &[0b1]);
})
.expect_err("malformed CSR must panic");
let msg = panic_message(&panic);
assert!(msg.contains("malformed CSR graph"), "got {msg}");
}
#[test]
fn cpu_ref_rejects_mismatched_ffi_mask() {
let panic = std::panic::catch_unwind(|| {
let _ = cpu_ref(2, &[0, 1, 1], &[1], &[0], &[0, 0], &[0b1], &[0b1]);
})
.expect_err("mismatched FFI mask must panic");
let msg = panic_message(&panic);
assert!(msg.contains("malformed FFI edge mask"), "got {msg}");
}
#[test]
fn cpu_ref_rejects_malformed_source_bitset() {
let panic = std::panic::catch_unwind(|| {
let _ = cpu_ref(2, &[0, 1, 1], &[1], &[0], &[0], &[0b1, 0b0], &[0b1]);
})
.expect_err("malformed source must panic");
let msg = panic_message(&panic);
assert!(msg.contains("malformed source bitset"), "got {msg}");
}
#[test]
fn cpu_ref_rejects_malformed_sink_bitset() {
let panic = std::panic::catch_unwind(|| {
let _ = cpu_ref(2, &[0, 1, 1], &[1], &[0], &[0], &[0b1], &[0b1, 0b0]);
})
.expect_err("malformed sink must panic");
let msg = panic_message(&panic);
assert!(msg.contains("malformed sink bitset"), "got {msg}");
}
fn panic_message(panic: &Box<dyn std::any::Any + Send>) -> String {
if let Some(s) = (**panic).downcast_ref::<String>() {
s.clone()
} else if let Some(s) = (**panic).downcast_ref::<&'static str>() {
(*s).to_string()
} else {
"<non-string>".to_string()
}
}
}