Skip to main content

vyre_self_substrate/graph/exploded/
mod.rs

1//! Exploded-supergraph (IFDS encoding) substrate consumer.
2//!
3//! Wires the primitive-owned exploded-supergraph reference builder (zero
4//! prior consumers) into the substrate so the optimizer can build
5//! interprocedural-dataflow graphs directly. The IFDS encoding packs
6//! `(proc_id, block_id, fact_id)` into a u32 node id, then composes
7//! intra-/inter-procedural edges + GEN/KILL flow into a CSR ready for
8//! reachability/closure analysis.
9
10mod dispatch;
11
12#[cfg(any(test, feature = "cpu-parity"))]
13mod reference;
14
15#[cfg(test)]
16mod tests;
17
18pub use dispatch::{
19    build_ifds_csr_via, build_ifds_csr_via_into, build_ifds_csr_via_with_scratch_into,
20};
21
22#[cfg(any(test, feature = "cpu-parity"))]
23pub use reference::{
24    reference_build_ifds_csr, reference_canonicalize_csr_within_rows, try_reference_build_ifds_csr,
25};
26
27use vyre_primitives::graph::exploded::{
28    dense_to_encoded, encoded_to_dense, ifds_node_count_saturating, IfdsCsrProgramCacheKey,
29    IfdsCsrRuleColumns, IfdsCsrRuleInputFingerprint, IfdsCsrStaticInputKey,
30};
31
32use crate::graph::dispatch_bridge::{CachedProgram, ProgramCache};
33
34/// Caller-owned GPU dispatch scratch for exploded IFDS CSR construction.
35#[derive(Debug, Default)]
36pub struct IfdsCsrGpuScratch {
37    rule_columns: IfdsCsrRuleColumns,
38    rule_fingerprint: Option<IfdsCsrRuleInputFingerprint>,
39    inputs: Vec<Vec<u8>>,
40    static_input_key: Option<IfdsCsrStaticInputKey>,
41    row_cursor: Vec<u32>,
42    col_len_words: Vec<u32>,
43    program_cache: ProgramCache<IfdsCsrProgramCacheKey, CachedIfdsCsrProgram>,
44}
45
46type CachedIfdsCsrProgram = CachedProgram;
47
48impl IfdsCsrGpuScratch {
49    #[cfg(test)]
50    fn program_builds(&self) -> usize {
51        self.program_cache.builds()
52    }
53}
54
55/// Total node count of the exploded supergraph for the given
56/// dimensions. Equivalent to `row_ptr.len() - 1` after the CSR is
57/// built; useful when the caller needs to size frontier bitsets
58/// before invoking [`reference_build_ifds_csr`].
59#[must_use]
60pub fn ifds_node_count(num_procs: u32, blocks_per_proc: u32, facts_per_proc: u32) -> u32 {
61    ifds_node_count_saturating(num_procs, blocks_per_proc, facts_per_proc)
62}
63
64/// Helper: round-trip a dense index through the packed encoding and
65/// back. Used by callers that emit findings keyed on the packed id
66/// but operate on dense indices internally.
67#[must_use]
68pub fn round_trip_dense(dense: u32, blocks_per_proc: u32, facts_per_proc: u32) -> Option<u32> {
69    let encoded = dense_to_encoded(dense, blocks_per_proc, facts_per_proc)?;
70    encoded_to_dense(encoded, blocks_per_proc, facts_per_proc)
71}