File size: 2,708 Bytes
5e84645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! VectorHD core spike — the hot kernel of the analytic MAP optimizer, in Rust.
//!
//! Feasibility evidence only; not production code. Ports two functions from
//! `src/vectorhd/analytic/`:
//!
//! * `coverage` — the exact signed-area cell rasterizer (`raster.polygon_coverage`)
//! * `gradient` — the boundary-integral gradient (`jacobian.geometry_gradient`), stopped at
//!   polyline vertices
//!
//! plus `energy`, the composite + `E_data` reduction that sits between them.
//!
//! **Why the vertex-level contract matters for equivalence.** The Python side evaluates flattened
//! vertices as `bernstein(linspace(0,1,12)) @ control_points` — a BLAS `dgemm`. That matmul is not
//! bit-reproducible by any scalar loop ordering (FMA + blocking), and `np.linspace` is not
//! `i/(m-1)` either. By taking *already-sampled vertices* as its input, this crate never performs
//! either operation, so neither can contribute error to the equivalence gate. The Bernstein chain
//! rule back to control points stays in Python, where it is a negligible dense matmul.
//!
//! No `unsafe` outside the wasm ABI shims in `wasm.rs`, which are documented individually.

pub mod coverage;
pub mod energy;
pub mod gradient;
pub mod handle;
pub mod model;
pub mod priors;
pub mod window;

pub mod wasm;

#[cfg(feature = "python")]
pub mod python;

use model::Vectors;
use std::collections::HashMap;

/// Everything one kernel pass produces.
pub struct Computed {
    /// Per-region absolute coverage, in face order.
    pub coverage: Vec<(i64, Vec<f64>)>,
    pub image: Vec<f64>,
    pub e_data: f64,
    pub gradients: HashMap<i64, Vec<Vec<[f64; 2]>>>,
}

/// One full kernel pass: coverage → composite/energy → gradient, exactly the sequence one
/// optimizer step performs (and exactly what `scripts/bench_python_kernel.py` times).
pub fn kernel_pass(v: &Vectors, target: &[f64]) -> Computed {
    let coverage = coverage::region_coverages(v);
    let image = energy::compose(v, &coverage);
    let e_data = energy::e_data(&image, target, v.l0);
    let gradients = gradient::vertex_gradients(v, &image, target);
    Computed {
        coverage,
        image,
        e_data,
        gradients,
    }
}

/// Per-region `(sum, sum-of-squares)` checksums, compensated — matches the exporter's goldens.
pub fn coverage_checksums(cov: &[(i64, Vec<f64>)]) -> Vec<(i64, model::Checksum)> {
    cov.iter()
        .map(|(lb, c)| {
            (
                *lb,
                model::Checksum {
                    sum: energy::sum_compensated(c.iter().copied()),
                    sumsq: energy::sum_compensated(c.iter().map(|x| x * x)),
                },
            )
        })
        .collect()
}