Skip to main content

paired_timing_report/
paired_timing_report.rs

1//! Report one paired speed measurement the way every #932 gate reports it.
2//!
3//! Times the compiled order-four curve/wiggle pullback bundle
4//! (`fast_channel::curve_wiggle_bundle4`, the sparse build-time expansion of
5//! nine top channels) against the nine channels evaluated separately by the
6//! universal partition sum (`fast_channel::faa_top4`, exactly the canonical
7//! oracle the bundle is pinned to), with `paired_timing`: interleaved per
8//! repetition, order randomised, ratios kept per repetition, and the summary
9//! line carrying `median_ratio`, `wins`, `resolution` and `position_bias`.
10//! Run it on a host to see the instrument's resolution there before reading
11//! any gate's verdict from that host:
12//!
13//! ```text
14//! cargo run --release -p gam-math --example paired_timing_report
15//! ```
16//!
17//! This example is also the harness's reachability root: `paired_timing` is
18//! linked by no shipped artifact (tests measure with it), and a kept example
19//! is what a dead-code sweep keyed on artifact symbol tables honours.
20
21use gam_math::fast_channel::{curve_wiggle_bundle4, faa_top4};
22use gam_math::paired_timing::{SpeedGate, batched, paired_interleaved};
23
24#[inline(never)]
25fn compiled_bundle4(x: [f64; 17]) -> [f64; 9] {
26    curve_wiggle_bundle4(
27        [x[0], x[1], x[2], x[3]],
28        [x[4], x[5], x[6]],
29        [x[7], x[9], x[10], x[11]],
30        [x[8], x[12], x[13], x[14]],
31        [x[15], x[16]],
32    )
33}
34
35/// The nine channels as nine evaluations of the universal rule: the canonical
36/// form the bundle's oracle pins it to.
37#[inline(never)]
38fn canonical_bundle4(x: [f64; 17]) -> [f64; 9] {
39    let [
40        m1,
41        m2,
42        m3,
43        m4,
44        q_u,
45        q_v,
46        q_uv,
47        a,
48        b,
49        a_u,
50        a_v,
51        a_uv,
52        b_u,
53        b_v,
54        b_uv,
55        xi_u,
56        xi_v,
57    ] = x;
58    let xi_uv = xi_u * xi_v;
59    let q = [
60        [
61            0.0, a, a, b, q_u, a_u, a_u, b_u, q_v, a_v, a_v, b_v, q_uv, a_uv, a_uv, b_uv,
62        ],
63        [
64            0.0, a, 1.0, 0.0, q_u, a_u, 0.0, 0.0, q_v, a_v, 0.0, 0.0, q_uv, a_uv, 0.0, 0.0,
65        ],
66        [
67            0.0, a, 0.0, 1.0, q_u, a_u, xi_u, 0.0, q_v, a_v, xi_v, 0.0, q_uv, 0.0, 0.0, 0.0,
68        ],
69        [
70            0.0, a, 0.0, 0.0, q_u, 0.0, 0.0, xi_u, q_v, 0.0, 0.0, xi_v, 0.0, 0.0, xi_uv, 0.0,
71        ],
72        [
73            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, xi_uv,
74        ],
75        [
76            0.0, 1.0, 1.0, 0.0, q_u, 0.0, 0.0, 0.0, q_v, 0.0, 0.0, 0.0, q_uv, 0.0, 0.0, 0.0,
77        ],
78        [
79            0.0, 0.0, 1.0, 0.0, q_u, xi_u, 0.0, 0.0, q_v, xi_v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
80        ],
81        [
82            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, xi_uv, 0.0, 0.0,
83        ],
84        [
85            0.0, 0.0, 0.0, 0.0, 0.0, xi_u, xi_u, 0.0, 0.0, xi_v, xi_v, 0.0, 0.0, 0.0, 0.0, 0.0,
86        ],
87    ];
88    std::array::from_fn(|output| faa_top4([m1, m2, m3, m4], &q[output]))
89}
90
91fn main() {
92    let input: [f64; 17] = std::array::from_fn(|index| 0.35 + 0.07 * (index as f64 + 1.0).sin());
93    for (compiled, canonical) in compiled_bundle4(input).iter().zip(canonical_bundle4(input).iter()) {
94        assert!((compiled - canonical).abs() <= 1e-12 * canonical.abs().max(1.0));
95    }
96    let timing = paired_interleaved(
97        15,
98        2_000,
99        0x9320_AB,
100        batched(64, |nudge| {
101            let mut x = input;
102            x[4] += nudge;
103            compiled_bundle4(x).iter().sum()
104        }),
105        batched(64, |nudge| {
106            let mut x = input;
107            x[4] += nudge;
108            canonical_bundle4(x).iter().sum()
109        }),
110    );
111    println!("{}", timing.summary("compiled_bundle4", "nine_top_channels"));
112    // The two contracts a gate can carry, printed the way a gate prints them.
113    let mut gate = SpeedGate::open("PAIRED-TIMING-REPORT");
114    gate.faster("order=4 bundle", &timing, "compiled_bundle4", "nine_top_channels");
115    gate.not_slower("order=4 bundle", &timing, "compiled_bundle4", "nine_top_channels");
116    gate.finish();
117}