1use 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#[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 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}