Constant LANES
const LANES: usize = 8;Expand description
∂q/∂z: rung i’s par quote against pillar j, on the solved curve.
Built from par_rate, which is generic over the scalar and a pure function
of the curve — so one forward pass seeded at pillar j prices every rung and
yields one whole column. n passes give the matrix.
This is the quantity the calibration Jacobian inverts. The alternative
decomposition — ∂r/∂z scaled by ∂r_i/∂q_i — needs a derivative with
respect to a scalar inside an instrument, and instruments hold their terms
as f64: the genericity in this library is in the view, not the trade. The
two agree, since ∂q_i/∂z_j = −(∂r_i/∂z_j)/(∂r_i/∂q_i), but only this one is
reachable without a rebuild-with-a-new-quote seam on every instrument arm.
Every entry is computed. ∂q/∂z is lower triangular exactly when no rung
reads past its own pillar, and tests/residual_jacobian_structure.rs
measures a real dual-curve ladder that does — one cell, small, and five
orders of magnitude above the difference’s noise floor. A triangular solve
would be almost right, which is the worst kind.
How many pillars one forward pass carries.
A pass prices every rung, so the cost of the matrix is
⌈n/LANES⌉ · n valuations: widening the mode divides the pass count, and
with it the number of times the whole ladder is re-priced. K is a const
generic in the backend, so it cannot be n.
Measured on bootstrap_4 and bootstrap_40, one width per build:
| lanes | n = 4 | n = 40 |
|---|---|---|
1 (Jet1) | — | 1234 µs |
| 4 | 6.73 µs | 580 µs |
| 8 | 6.82 µs | 440 µs |
| 16 | 7.23 µs | 433 µs |
Eight costs 1.1% at the small end and lands within 1.5% of the best at the large end; sixteen buys that 1.5% for 7.4% on a four-rung ladder, and four gives up 32% on a forty-rung one. The whole calibration is 183 µs without a Jacobian at n = 40, so eight lanes put the matrix at +140% of the solve where a one-lane mode would have put it at +575%.
The lane width is one axis; the mode is the other. The table above never
timed the arm with a different asymptote — one recording of every rung and
one n-direction vector sweep — so benches/mode_crossover.rs holds a
Jacobian-shape group (jacobian_ladder_4, jacobian_ladder_40) measuring
it beside the eight-lane mode on the same ladders. Both arms there price on
the public lift path (lift, view, resolve, par_rate), not this
module’s block loop, which is why its absolute figures are not the table’s:
the ratio between modes is what it adds.
| arm (public path) | par, n = 4 | par, n = 8 | par, n = 16 | par, n = 40 | OIS, n = 50 |
|---|---|---|---|---|---|
jet1_per_pillar | 5.04 µs | 25.4 µs | 145 µs | 1910 µs | not timed |
jetk_8 | 1.89 µs | 5.01 µs | 27.7 µs | 374 µs | 2490 µs |
reverse_vector_warm | 2.28 µs | 6.44 µs | 25.1 µs | 197 µs | 793 µs |
| sweep’s adjoint buffer | 4.5 KB | 27 KB | 183 KB | 2.5 MB | 8.9 MB |
Measured 2026-10-17 and -18 on an Apple M4 Pro against the sibling xad-rs
checkout (1.0.0, commit 7cd9838), rustc 1.99.1. One eight-lane pass beats
the sweep at four pillars by 1.2× and at eight by 1.3×; two passes lose to
it at sixteen by 1.1×; at forty the sweep is 1.9× faster than five passes,
and on the fifty-rung overnight ladder of ois_bootstrap_50, whose every
floating coupon walks a daily strip, 3.1× — against a whole calibration
there of about 5.2 ms. The crossover is between eight and sixteen pillars.
The sweep pays for its asymptote in the buffer, one f64 per recorded
variable per rung.
That is the route, and route holds it: ladders of at most
REVERSE_FROM pillars take the eight-lane engine, one pass; larger
ladders take one reverse recording and the vector sweep — unless a
recording is already open on the thread, in which case the eight-lane
engine serves whatever the size, because recordings do not nest.
End to end, under the route (benches/hot_paths.rs, bench profile, same
machine, 2026-10-18):
| bench | before | routed |
|---|---|---|
bootstrap_4 (lanes either way) | 10.9 µs | 11.3 µs |
bootstrap_40 | 625 µs | 565 µs |
ois_bootstrap_50 | 5.18 ms | 3.58 ms |
The overnight ladder keeps the whole of what the arm table promised. The forty-pillar par ladder keeps less, about 10%, because its Jacobian is a smaller share of the calibration than the “+140% of the solve” above was measured at: timed inside the library under the bench profile, the whole calibration is 663 µs with the eight-lane engine and 583 µs with the reverse one, while the engines alone are 487 µs and 200 µs. The rest of the calibration — the solve, the check, the inversion, the refit it keeps — has grown since that decomposition was taken, and it is not re-derived here.