daegun 1.0.0

Your all-in-one text engine. Rust, no_std, zero dependencies.
Documentation
fn scalar_coverage(a: &mut [f32], length: usize) {
    let mut height = 0.0f32;
    for slot in a.iter_mut().take(length) {
        height += *slot;
        *slot = f32::from_bits(height.to_bits() & 0x7fff_ffff).clamp(0.0, 1.0);
    }
}

fn scalar_bitmap(a: &[f32], length: usize) -> Vec<u8> {
    let mut height = 0.0f32;
    a.iter()
        .take(length)
        .map(|delta| {
            height += delta;
            (f32::from_bits(height.to_bits() & 0x7fff_ffff) * 255.9).clamp(0.0, 255.0) as u8
        })
        .collect()
}

fn scalar_tap3(cov: &[f32], w0: &[f32], w1: &[f32], w2: &[f32]) -> (f32, f32, f32) {
    let (mut s0, mut s1, mut s2) = (0.0f32, 0.0, 0.0);
    for i in 0..cov.len() {
        s0 += cov[i] * w0[i];
        s1 += cov[i] * w1[i];
        s2 += cov[i] * w2[i];
    }
    (s0, s1, s2)
}

struct Rng(u64);
impl Rng {
    fn new(seed: u64) -> Rng {
        Rng(seed | 1)
    }
    fn unit(&mut self) -> f32 {
        self.0 ^= self.0 << 13;
        self.0 ^= self.0 >> 7;
        self.0 ^= self.0 << 17;
        (self.0 >> 11) as f32 / (1u64 << 53) as f32
    }
    fn deltas(&mut self, n: usize) -> Vec<f32> {
        (0..n)
            .map(|i| {
                let u = self.unit();
                if u < 0.75 {
                    0.0
                } else if i % 97 == 0 {
                    (self.unit() - 0.5) * 2.0
                } else {
                    (self.unit() - 0.5) * 0.25
                }
            })
            .collect()
    }
}

#[test]
fn coverage_in_place_tracks_the_scalar_sum() {
    let mut rng = Rng::new(0x2545_F491_4F6C_DD1D);
    let mut worst = 0.0f32;
    let mut checked = 0usize;

    let lengths: Vec<usize> = (0..=40).chain([63, 64, 65, 255, 256, 257, 1023, 4096, 9973]).collect();
    for &n in &lengths {
        for _ in 0..40 {
            let deltas = rng.deltas(n);
            let mut a = deltas.clone();
            let mut b = deltas;
            scalar_coverage(&mut a, n);
            daegun::daerizer::daecpu::simd::coverage_in_place(&mut b, n);
            assert_eq!(a.len(), b.len(), "length {n}: the kernels returned different sizes");
            for (i, (x, y)) in a.iter().zip(&b).enumerate() {
                assert!(x.is_finite() && y.is_finite(), "length {n} slot {i}: non-finite coverage");
                assert!((0.0..=1.0).contains(y), "length {n} slot {i}: coverage {y} outside 0..=1");
                worst = worst.max((x - y).abs());
                checked += 1;
            }
        }
    }
    assert!(checked > 500_000, "only {checked} values compared");
    assert!(worst < 1e-5, "coverage diverged by {worst:.3e}, past what reordering explains");
}

#[test]
fn get_bitmap_matches_the_scalar_bytes() {
    let mut rng = Rng::new(0x9E37_79B9_7F4A_7C15);
    let mut differing = 0usize;
    let mut total = 0usize;
    let mut worst = 0i32;

    let lengths: Vec<usize> = (0..=40).chain([63, 64, 65, 255, 256, 257, 1023, 4096, 9973]).collect();
    for &n in &lengths {
        for _ in 0..40 {
            let deltas = rng.deltas(n);
            let s = scalar_bitmap(&deltas, n);
            let v = daegun::daerizer::daecpu::simd::get_bitmap(&deltas, n);
            assert_eq!(s.len(), v.len(), "length {n}: byte counts differ");
            for (x, y) in s.iter().zip(&v) {
                total += 1;
                if x != y {
                    differing += 1;
                    worst = worst.max((i32::from(*x) - i32::from(*y)).abs());
                }
            }
        }
    }
    assert!(total > 500_000, "only {total} bytes compared");
    assert!(
        worst <= 1,
        "a byte differs from the scalar collapse by {worst} levels; reordering a sum can move the \
         quantised result by one, not more",
    );
    let rate = differing as f64 / total as f64;
    assert!(
        rate < 1e-4,
        "{differing} of {total} bytes differ ({:.5}%), past the ~4-in-100,000 that summation order \
         accounts for",
        rate * 100.0,
    );
}

#[test]
fn tap_run3_tracks_the_scalar_dot_products() {
    let mut rng = Rng::new(0x1234_5678_9ABC_DEF1);
    let mut worst = 0.0f64;
    let mut checked = 0usize;

    for span in 0..=32usize {
        for _ in 0..300 {
            let cov: Vec<f32> = (0..span).map(|_| rng.unit()).collect();
            let w0: Vec<f32> = (0..span).map(|_| rng.unit() * 0.3).collect();
            let w1: Vec<f32> = (0..span).map(|_| rng.unit() * 0.3).collect();
            let w2: Vec<f32> = (0..span).map(|_| rng.unit() * 0.3).collect();
            let s = scalar_tap3(&cov, &w0, &w1, &w2);
            let v = daegun::daerizer::daecpu::simd::tap_run3(&cov, &w0, &w1, &w2);
            for (a, b) in [(s.0, v.0), (s.1, v.1), (s.2, v.2)] {
                assert!(b.is_finite(), "span {span}: non-finite sum");
                let rel = if a.abs() > 1e-6 {
                    f64::from((a - b) / a).abs()
                } else {
                    f64::from(a - b).abs()
                };
                worst = worst.max(rel);
                checked += 1;
            }
        }
    }
    assert!(checked > 25_000, "only {checked} sums compared");
    assert!(worst < 1e-5, "tap sums diverged by {worst:.3e}, past rounding");
}

#[test]
fn the_kernels_survive_degenerate_input() {
    let mut empty: [f32; 0] = [];
    daegun::daerizer::daecpu::simd::coverage_in_place(&mut empty, 0);
    assert!(daegun::daerizer::daecpu::simd::get_bitmap(&[], 0).is_empty());
    assert_eq!(daegun::daerizer::daecpu::simd::tap_run3(&[], &[], &[], &[]), (0.0, 0.0, 0.0));

    let mut one = [0.5f32];
    daegun::daerizer::daecpu::simd::coverage_in_place(&mut one, 99);
    assert_eq!(one[0], 0.5);
    assert_eq!(daegun::daerizer::daecpu::simd::get_bitmap(&[1.0], 99).len(), 1);

    let (a, b, c) = daegun::daerizer::daecpu::simd::tap_run3(&[1.0, 1.0, 1.0], &[1.0], &[1.0, 1.0], &[1.0]);
    assert_eq!((a, b, c), (1.0, 1.0, 1.0));
}