Skip to main content

LANES

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:

lanesn = 4n = 40
1 (Jet1)—1234 µs
46.73 µs580 µs
86.82 µs440 µs
167.23 µs433 µ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 = 4par, n = 8par, n = 16par, n = 40OIS, n = 50
jet1_per_pillar5.04 µs25.4 µs145 µs1910 µsnot timed
jetk_81.89 µs5.01 µs27.7 µs374 µs2490 µs
reverse_vector_warm2.28 µs6.44 µs25.1 µs197 µs793 µs
sweep’s adjoint buffer4.5 KB27 KB183 KB2.5 MB8.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):

benchbeforerouted
bootstrap_4 (lanes either way)10.9 µs11.3 µs
bootstrap_40625 µs565 µs
ois_bootstrap_505.18 ms3.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.