weirflow 0.1.0

GPU-first dataflow analysis primitives for Vyre and Santh compiler pipelines.
Documentation
//! Unified column-splitting helpers for IFDS CSR edge preparation.

/// Split a slice of tuples into parallel column vectors.
///
/// If every column vector already has length `rows.len()`, values are written
/// in-place via indexed assignment (the "stable-len" fast-path). Otherwise
/// vectors are cleared and repopulated.
pub(crate) fn split_columns_into<T: ColumnRow>(
    rows: &[T],
    columns: &mut [&mut Vec<u32>],
    field_names: &[&'static str],
) -> Result<(), String> {
    assert_eq!(columns.len(), T::N, "column count mismatch");
    assert_eq!(field_names.len(), T::N, "field name count mismatch");

    let stable_len = columns.iter().all(|c| c.len() == rows.len());
    for (col, name) in columns.iter_mut().zip(field_names.iter()) {
        crate::staging_reserve::reserve_vec(col, rows.len(), name)?;
    }
    if stable_len {
        for (index, row) in rows.iter().enumerate() {
            row.write_into(index, columns);
        }
    } else {
        for col in columns.iter_mut() {
            col.clear();
        }
        for row in rows {
            row.push_into(columns);
        }
    }
    Ok(())
}

/// Trait for row types that can be decomposed into `u32` columns.
pub(crate) trait ColumnRow: Copy {
    /// Number of columns produced by this row type.
    const N: usize;
    /// Write this row's values into `columns` at `index`.
    fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]);
    /// Push this row's values onto the end of each column vector.
    fn push_into(&self, columns: &mut [&mut Vec<u32>]);
}

impl ColumnRow for (u32, u32, u32) {
    const N: usize = 3;
    fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]) {
        columns[0][index] = self.0;
        columns[1][index] = self.1;
        columns[2][index] = self.2;
    }
    fn push_into(&self, columns: &mut [&mut Vec<u32>]) {
        columns[0].push(self.0);
        columns[1].push(self.1);
        columns[2].push(self.2);
    }
}

impl ColumnRow for (u32, u32, u32, u32) {
    const N: usize = 4;
    fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]) {
        columns[0][index] = self.0;
        columns[1][index] = self.1;
        columns[2][index] = self.2;
        columns[3][index] = self.3;
    }
    fn push_into(&self, columns: &mut [&mut Vec<u32>]) {
        columns[0].push(self.0);
        columns[1].push(self.1);
        columns[2].push(self.2);
        columns[3].push(self.3);
    }
}