Skip to main content

handwired_rs/
emit.rs

1//! Builder functions ("macros") that expand familiar expressions into operations.
2//!
3//! Ported from handwired's `numeric-ui-core.ts`. Each function documents when
4//! its result is exact; see handwired's docs/expressions.md for the cost tables.
5
6use crate::circuit::{Circuit, OpKind, RoundingPointKind};
7use crate::numeric::{
8    EXACT_GRID_STEPS, Range, fround, largest_grid, lowest_power_of_two, pow2, power_of_two_exponent_at_least,
9    smallest_grid,
10};
11use crate::wire::{Lin, Term, Wire};
12
13/// `max(0, value)`.
14pub fn emit_relu(circuit: &mut Circuit, value: Wire) -> Wire {
15    circuit.reglu(1.0, value)
16}
17
18/// `max(a, b)` rebuilt through a rounded difference: `b + relu(a - b)`.
19/// Not always exactly one of the operands; see [`emit_maximum_exact`].
20pub fn emit_maximum(circuit: &mut Circuit, a: Wire, b: Wire) -> Wire {
21    let difference = circuit.round_affine(a - b);
22    let positive = emit_relu(circuit, difference);
23    let result = circuit.round_affine(b + positive);
24    let (a_range, b_range) = (circuit.range(a), circuit.range(b));
25    if a_range.min >= 0.0 && a_range.max <= 1.0 && b_range.min >= 0.0 && b_range.max <= 1.0 {
26        circuit.assume_range(result, 0.0, 1.0);
27    }
28    result
29}
30
31/// `min(a, b)` rebuilt through a rounded difference: `a - relu(a - b)`, e.g.
32/// 0.29998779 for min(f(1000.37), f(0.3)). See [`emit_minimum_exact`].
33pub fn emit_minimum(circuit: &mut Circuit, a: Wire, b: Wire) -> Wire {
34    let difference = circuit.round_affine(a - b);
35    let positive = emit_relu(circuit, difference);
36    let result = circuit.round_affine(a - positive);
37    if circuit.is_non_negative(a)
38        && circuit.is_non_negative(b)
39        && circuit.range(a).is_finite()
40        && circuit.range(b).is_finite()
41    {
42        let maximum = fround(circuit.range(a).max);
43        circuit.assume_range(result, 0.0, maximum);
44    }
45    result
46}
47
48/// `gate ? on : off` for a gate of exactly 0 or 1. Both sides always compute.
49pub fn emit_select(circuit: &mut Circuit, gate: Wire, off: Wire, on: Wire) -> Wire {
50    circuit.select(gate, off, on)
51}
52
53/// `!bit` for an exact bit.
54pub fn emit_not(circuit: &mut Circuit, bit: Wire) -> Wire {
55    circuit.affine(1.0 - bit)
56}
57
58/// `bits.all()`: `relu(sum - (n - 1))`, exact for exact bits.
59pub fn emit_and(circuit: &mut Circuit, bits: &[Wire]) -> Wire {
60    let sum = Lin::new(bits.iter().map(|&bit| (bit, 1.0)).collect(), 1.0 - bits.len() as f64);
61    circuit.reglu(1.0, sum)
62}
63
64/// `bits.any()`: `1 - relu(1 - sum)`, exact for exact bits.
65pub fn emit_or(circuit: &mut Circuit, bits: &[Wire]) -> Wire {
66    let missing = Lin::new(bits.iter().map(|&bit| (bit, -1.0)).collect(), 1.0);
67    let none = circuit.relu(missing);
68    circuit.affine(1.0 - none)
69}
70
71/// `Math.round(x)` for |x| below 2^22: FP32 values within 2^23..2^24 are whole
72/// numbers, so adding and then subtracting 2^23 + 2^22 rounds (ties to even).
73/// Both steps are marked rounding points.
74pub fn emit_round(circuit: &mut Circuit, value: Wire) -> Wire {
75    const SHIFT: f64 = 12_582_912.0; // 2^23 + 2^22
76    let shifted = circuit.round_affine(value + SHIFT);
77    let rounded = circuit.round_affine(shifted - SHIFT);
78    circuit.mark_rounding_point(shifted);
79    circuit.mark_rounding_point(rounded);
80    rounded
81}
82
83#[derive(Copy, Clone, Debug, PartialEq, Eq)]
84pub enum Relation {
85    Greater,
86    AtLeast,
87    Less,
88    AtMost,
89    Equal,
90}
91
92impl Relation {
93    /// The relation as written in source, e.g. `">="`.
94    pub fn symbol(self) -> &'static str {
95        match self {
96            Relation::Greater => ">",
97            Relation::AtLeast => ">=",
98            Relation::Less => "<",
99            Relation::AtMost => "<=",
100            Relation::Equal => "==",
101        }
102    }
103
104    /// The comparison on native f32 values, the oracle every bit must match.
105    pub fn holds(self, a: f32, b: f32) -> bool {
106        match self {
107            Relation::Greater => a > b,
108            Relation::AtLeast => a >= b,
109            Relation::Less => a < b,
110            Relation::AtMost => a <= b,
111            Relation::Equal => a == b,
112        }
113    }
114}
115
116#[derive(Copy, Clone, Debug, Default)]
117pub struct CompareOptions {
118    /// End with a boolean atom instead of a ReLU stage: fewer layers, but the
119    /// executor must keep FP32 rounding at the atom, and backprop rejects it
120    /// unless it is told to pass gradients straight through.
121    pub end_with_boolean: bool,
122}
123
124#[derive(Copy, Clone, Debug, PartialEq, Eq)]
125enum SignTest {
126    Greater,
127    AtLeast,
128    Equal,
129}
130
131#[derive(Copy, Clone, Debug)]
132struct CompareOperand {
133    wire: Option<Wire>,
134    value: f64,
135    range: Range,
136    grid: Option<f64>,
137}
138
139fn compare_operand(circuit: &Circuit, operand: Wire) -> CompareOperand {
140    circuit.assert_wire(operand);
141    if let Some(constant) = circuit.constant_value(operand) {
142        let value = fround(constant);
143        assert!(value.is_finite(), "a constant comparison operand must be finite");
144        // -0 and +0 compare equal, so a zero constant becomes +0.
145        let value = if value == 0.0 { 0.0 } else { value };
146        return CompareOperand {
147            wire: None,
148            value,
149            range: Range::new(value, value),
150            grid: Some(if value == 0.0 { f64::INFINITY } else { lowest_power_of_two(value) }),
151        };
152    }
153    CompareOperand { wire: Some(operand), value: 0.0, range: circuit.range(operand), grid: circuit.grid(operand) }
154}
155
156/// `[a relation b]` as an exact bit, equal to the native f32 comparison for
157/// every pair of values within the declared ranges. Both operands need finite
158/// declared ranges. When both lie on grids, the bit is built from the integer
159/// `D = (a - b) / grid` in 2 or 3 operations; otherwise a sign cascade lifts
160/// every nonzero `f(a - b)`, down to 2^-149, to at least 1.
161pub fn emit_compare(circuit: &mut Circuit, a: Wire, relation: Relation, b: Wire) -> Wire {
162    emit_compare_with(circuit, a, relation, b, CompareOptions::default())
163}
164
165pub fn emit_compare_with(circuit: &mut Circuit, a: Wire, relation: Relation, b: Wire, options: CompareOptions) -> Wire {
166    let mut left = compare_operand(circuit, a);
167    let mut right = compare_operand(circuit, b);
168    if matches!(relation, Relation::Less | Relation::AtMost) {
169        std::mem::swap(&mut left, &mut right);
170    }
171    let test = match relation {
172        Relation::Greater | Relation::Less => SignTest::Greater,
173        Relation::AtLeast | Relation::AtMost => SignTest::AtLeast,
174        Relation::Equal => SignTest::Equal,
175    };
176    if left.wire.is_none() && right.wire.is_none() {
177        let holds = match test {
178            SignTest::Greater => left.value > right.value,
179            SignTest::AtLeast => left.value >= right.value,
180            SignTest::Equal => left.value == right.value,
181        };
182        return circuit.constant(if holds { 1.0 } else { 0.0 });
183    }
184    for operand in [left, right] {
185        assert!(
186            operand.range.is_finite(),
187            "emit_compare needs finite declared ranges on both operands, got {}..{}",
188            operand.range.min,
189            operand.range.max
190        );
191    }
192    // A wire equals itself for every value its finite range allows.
193    if left.wire == right.wire {
194        return circuit.constant(if test == SignTest::Greater { 0.0 } else { 1.0 });
195    }
196    let difference_bound = (left.range.max - right.range.min).abs().max((left.range.min - right.range.max).abs());
197    assert!(fround(difference_bound).is_finite(), "the difference of the declared operand ranges can overflow FP32");
198    let mut terms: Vec<Term> = Vec::new();
199    if let Some(wire) = left.wire {
200        terms.push((wire, 1.0));
201    }
202    if let Some(wire) = right.wire {
203        terms.push((wire, -1.0));
204    }
205    // At most one side is a constant, so the bias is exactly that constant or its negation.
206    let bias = left.value - right.value;
207    let bit = match emit_grid_compare(circuit, &left, &right, &terms, bias, test, options.end_with_boolean) {
208        Some(bit) => bit,
209        None => emit_cascade_compare(circuit, &terms, bias, fround(difference_bound), test, options.end_with_boolean),
210    };
211    circuit.assume_range(bit, 0.0, 1.0);
212    circuit.assume_grid(bit, 1.0);
213    if bit.index() >= circuit.source_size() {
214        let index = bit.index() - circuit.source_size();
215        circuit.operations[index].comparison_bit = true;
216    }
217    bit
218}
219
220/// The largest magnitude of any product or partial sum of bias + Σ coefficient
221/// × operand, added in stored order, from the declared operand ranges.
222fn largest_partial_sum(terms: &[Term], bias: f64, ranges: &[Range]) -> f64 {
223    let (mut minimum, mut maximum, mut largest) = (bias, bias, bias.abs());
224    for &(wire, coefficient) in terms {
225        let range = ranges[wire.index()];
226        let (low, high) = if coefficient >= 0.0 {
227            (coefficient * range.min, coefficient * range.max)
228        } else {
229            (coefficient * range.max, coefficient * range.min)
230        };
231        minimum += low;
232        maximum += high;
233        largest = largest.max(low.abs()).max(high.abs()).max(minimum.abs()).max(maximum.abs());
234    }
235    largest
236}
237
238fn scaled_terms(terms: &[Term], factor: f64) -> Vec<Term> {
239    terms.iter().map(|&(wire, coefficient)| (wire, coefficient * factor)).collect()
240}
241
242/// Integer bits for operands on grids. Returns `None` when an operand has no
243/// grid or the ranges are too wide, and the caller builds a sign cascade.
244fn emit_grid_compare(
245    circuit: &mut Circuit,
246    left: &CompareOperand,
247    right: &CompareOperand,
248    terms: &[Term],
249    bias: f64,
250    test: SignTest,
251    end_with_boolean: bool,
252) -> Option<Wire> {
253    let grid = left.grid?.min(right.grid?);
254    let largest_steps = |circuit: &Circuit, sign: f64, offset: f64| {
255        largest_partial_sum(&scaled_terms(terms, sign / grid), sign * bias / grid + offset, &circuit.ranges)
256    };
257    let mut emitted = Vec::new();
258    let bit;
259    if end_with_boolean {
260        // The score 0.5 + (D - offset) × 2^-24 is a multiple of 2^-24 within
261        // 0.25..0.75 while every partial sum stays within 2^22 grid steps.
262        let score_scale = pow2(-24) / grid;
263        let fits = match test {
264            SignTest::Equal => {
265                largest_steps(circuit, 1.0, 0.0) <= pow2(22) && largest_steps(circuit, -1.0, 0.0) <= pow2(22)
266            }
267            _ => largest_steps(circuit, 1.0, if test == SignTest::Greater { -1.0 } else { 0.0 }) <= pow2(22),
268        };
269        if !(fits && score_scale >= smallest_grid() && score_scale <= largest_grid()) {
270            return None;
271        }
272        let mut emit_atom = |circuit: &mut Circuit, sign: f64, offset: f64| {
273            let score =
274                Lin::new(scaled_terms(terms, sign * score_scale), 0.5 + (sign * bias / grid - offset) * pow2(-24));
275            let atom = circuit.append(OpKind::Boolean, score, Lin::default(), true, None);
276            emitted.push(atom);
277            atom
278        };
279        if test == SignTest::Equal {
280            let at_least = emit_atom(circuit, 1.0, 0.0);
281            let at_most = emit_atom(circuit, -1.0, 0.0);
282            bit = circuit.reglu(1.0, at_least + at_most - 1.0);
283            emitted.push(bit);
284        } else {
285            bit = emit_atom(circuit, 1.0, if test == SignTest::Greater { 1.0 } else { 0.0 });
286        }
287    } else {
288        let scale = 1.0 / grid;
289        // The bit's own sum, 1 - ramp, adds one more step.
290        let fits = match test {
291            SignTest::Equal => {
292                largest_steps(circuit, 1.0, 0.0) < EXACT_GRID_STEPS
293                    && largest_steps(circuit, -1.0, 0.0) < EXACT_GRID_STEPS
294            }
295            _ => largest_steps(circuit, -1.0, if test == SignTest::Greater { 1.0 } else { 0.0 }) < EXACT_GRID_STEPS,
296        };
297        if !(fits && scale <= largest_grid()) {
298            return None;
299        }
300        bit = emit_integer_bit(circuit, test, &mut emitted, |circuit, sign, offset| {
301            let ramp = Lin::new(scaled_terms(terms, sign * scale), sign * bias / grid + offset);
302            circuit.append(OpKind::Reglu, Lin::constant(1.0), ramp, true, None)
303        });
304    }
305    for wire in emitted {
306        circuit.record_rounding_point(wire, RoundingPointKind::IntegerBit);
307    }
308    Some(bit)
309}
310
311/// The exact bit of D > 0, D >= 0 or D == 0, when every value of D is 0 or at
312/// least 1 away from 0. `emit_ramp(sign, offset)` builds `relu(sign × D + offset)`:
313/// D >= 0 is `relu(1 - relu(-D))`, D > 0 is `relu(1 - relu(1 - D))`, and
314/// D == 0 is `relu(1 - relu(D) - relu(-D))`.
315fn emit_integer_bit(
316    circuit: &mut Circuit,
317    test: SignTest,
318    emitted: &mut Vec<Wire>,
319    mut emit_ramp: impl FnMut(&mut Circuit, f64, f64) -> Wire,
320) -> Wire {
321    let ramps = if test == SignTest::Equal {
322        vec![emit_ramp(circuit, 1.0, 0.0), emit_ramp(circuit, -1.0, 0.0)]
323    } else {
324        vec![emit_ramp(circuit, -1.0, if test == SignTest::Greater { 1.0 } else { 0.0 })]
325    };
326    let bit = circuit.reglu(1.0, Lin::new(ramps.iter().map(|&ramp| (ramp, -1.0)).collect(), 1.0));
327    emitted.extend(ramps);
328    emitted.push(bit);
329    bit
330}
331
332/// Every nonzero FP32 difference, down to 2^-149, lifted to at least 1.
333const FULL_LIFT_EXPONENT: i32 = 149;
334/// Every nonzero FP32 difference lifted to at least 2^-45, which a final
335/// rounding stage with scale 2^22 resolves.
336const ROUNDING_STAGE_LIFT_EXPONENT: i32 = 104;
337
338#[derive(Copy, Clone, Debug, PartialEq)]
339struct CascadeStage {
340    scale: f64,
341    limit: f64,
342}
343
344/// Stages of `min(limit, scale × input)`. Multiplying by a power of two only
345/// changes the exponent, and `min(limit, x) = x - relu(x - limit)` is exact
346/// while x is at most 2^24 × limit.
347fn plan_sign_cascade(difference_bound: f64, lift_exponent: i32) -> Vec<CascadeStage> {
348    let bound_exponent = power_of_two_exponent_at_least(difference_bound.max(smallest_grid()));
349    let mut stages = Vec::new();
350    let mut limit_exponent = bound_exponent;
351    let mut gain_exponent = 0;
352    while stages.is_empty() || limit_exponent > 0 || gain_exponent < lift_exponent {
353        let next_limit_exponent = (limit_exponent - 24).max(0);
354        // A coefficient above 2^127 isn't an FP32 value.
355        let room = (24 + next_limit_exponent - limit_exponent).min(127);
356        let scale_exponent = room.min((lift_exponent - gain_exponent).max(0));
357        stages.push(CascadeStage { scale: pow2(scale_exponent), limit: pow2(next_limit_exponent) });
358        limit_exponent = next_limit_exponent;
359        gain_exponent += scale_exponent;
360    }
361    stages
362}
363
364struct Cascade {
365    difference: Wire,
366    difference_sign: f64,
367}
368
369impl Cascade {
370    /// After clamp stage k, the output is min(limit_k, scale_1 × ... × scale_k × relu(sign × d)).
371    fn emit_clamp_stages(
372        &self,
373        circuit: &mut Circuit,
374        sign: f64,
375        stages: &[CascadeStage],
376        emitted: &mut Vec<Wire>,
377    ) -> Wire {
378        let mut stage_output = self.difference;
379        for (index, &CascadeStage { scale, limit }) in stages.iter().enumerate() {
380            let (scaled_term, above_limit) = if index == 0 {
381                // The first stage reads the signed difference as written, and keeps only its positive side.
382                let gate: Vec<Term> = vec![(self.difference, sign * self.difference_sign * scale)];
383                let scaled_positive =
384                    circuit.append(OpKind::Reglu, Lin::constant(1.0), Lin::new(gate.clone(), 0.0), true, None);
385                let above_limit = circuit.append(OpKind::Reglu, Lin::constant(1.0), Lin::new(gate, -limit), true, None);
386                emitted.push(scaled_positive);
387                ((scaled_positive, 1.0), above_limit)
388            } else {
389                let above_limit = circuit.reglu(1.0, stage_output * scale - limit);
390                ((stage_output, scale), above_limit)
391            };
392            // Its own operation: copied into the next stage, the regrouped partial sums would round.
393            stage_output = circuit.round_affine(Lin::new(vec![scaled_term, (above_limit, -1.0)], 0.0));
394            circuit.assume_range(stage_output, 0.0, limit);
395            emitted.push(above_limit);
396            emitted.push(stage_output);
397        }
398        stage_output
399    }
400}
401
402fn emit_cascade_compare(
403    circuit: &mut Circuit,
404    terms: &[Term],
405    bias: f64,
406    difference_bound: f64,
407    test: SignTest,
408    end_with_boolean: bool,
409) -> Wire {
410    let mut emitted = Vec::new();
411    // For finite FP32 operands, f(a - b) is 0 exactly when a == b, and otherwise
412    // has the sign of a - b, since subnormal values fill the gap next to 0.
413    let cascade = if bias == 0.0 && terms.len() == 1 {
414        Cascade { difference: terms[0].0, difference_sign: terms[0].1 }
415    } else {
416        let difference = circuit.round_affine(Lin::new(terms.to_vec(), bias));
417        emitted.push(difference);
418        Cascade { difference, difference_sign: 1.0 }
419    };
420    let lift = if end_with_boolean { ROUNDING_STAGE_LIFT_EXPONENT } else { FULL_LIFT_EXPONENT };
421    let stages = plan_sign_cascade(difference_bound, lift);
422    let bit;
423    if end_with_boolean {
424        let score_scale = pow2(22);
425        if test == SignTest::Greater {
426            let stage_output = cascade.emit_clamp_stages(circuit, 1.0, &stages, &mut emitted);
427            // The f32 value just below 0.5, so d = 0 rounds to 0.
428            let just_below_half = 0.5 - pow2(-25);
429            let score_above_zero = circuit.reglu(1.0, stage_output * score_scale + just_below_half);
430            let score_above_one = circuit.reglu(1.0, stage_output * score_scale + (just_below_half - 1.0));
431            let score = circuit.affine(score_above_zero - score_above_one);
432            circuit.assume_range(score, 0.0, 1.0);
433            emitted.push(score_above_zero);
434            emitted.push(score_above_one);
435            bit = circuit.boolean(score);
436        } else {
437            let mut gate = vec![(cascade.emit_clamp_stages(circuit, -1.0, &stages, &mut emitted), -score_scale)];
438            if test == SignTest::Equal {
439                gate.push((cascade.emit_clamp_stages(circuit, 1.0, &stages, &mut emitted), -score_scale));
440            }
441            let score = circuit.reglu(1.0, Lin::new(gate, 0.5));
442            emitted.push(score);
443            bit = circuit.boolean(score);
444        }
445        emitted.push(bit);
446    } else {
447        let final_scale = stages.last().unwrap().scale;
448        let clamp_stages = &stages[..stages.len() - 1];
449        if clamp_stages.is_empty() {
450            // One stage lifts the signed difference itself, so D = scale × d is 0 or at least 1 away from 0.
451            bit = emit_integer_bit(circuit, test, &mut emitted, |circuit, sign, offset| {
452                let gate = Lin::new(vec![(cascade.difference, sign * cascade.difference_sign * final_scale)], offset);
453                circuit.append(OpKind::Reglu, Lin::constant(1.0), gate, true, None)
454            });
455        } else if test == SignTest::Greater {
456            // scale × stage is 0 when d <= 0, and at least 1 when d > 0.
457            let stage = cascade.emit_clamp_stages(circuit, 1.0, clamp_stages, &mut emitted);
458            let not_greater = circuit.reglu(1.0, 1.0 - stage * final_scale);
459            bit = circuit.reglu(1.0, 1.0 - not_greater);
460            emitted.push(not_greater);
461            emitted.push(bit);
462        } else {
463            let mut gate = vec![(cascade.emit_clamp_stages(circuit, -1.0, clamp_stages, &mut emitted), -final_scale)];
464            if test == SignTest::Equal {
465                gate.push((cascade.emit_clamp_stages(circuit, 1.0, clamp_stages, &mut emitted), -final_scale));
466            }
467            bit = circuit.reglu(1.0, Lin::new(gate, 1.0));
468            emitted.push(bit);
469        }
470    }
471    for wire in emitted {
472        circuit.record_rounding_point(wire, RoundingPointKind::SignCascade);
473    }
474    bit
475}
476
477/// `min(a, b)` as exactly one of the operands, e.g. f(0.3) for min(f(1000.37), f(0.3)).
478/// Ties return `a`. Needs finite declared ranges, like [`emit_compare`].
479pub fn emit_minimum_exact(circuit: &mut Circuit, a: Wire, b: Wire) -> Wire {
480    let a_is_smaller = emit_compare(circuit, a, Relation::AtMost, b);
481    let a_range = compare_operand(circuit, a).range;
482    let b_range = compare_operand(circuit, b).range;
483    emit_select_operand(circuit, a_is_smaller, b, a, a_range.min.min(b_range.min), a_range.max.min(b_range.max))
484}
485
486/// `max(a, b)` as exactly one of the operands. Ties return `a`.
487pub fn emit_maximum_exact(circuit: &mut Circuit, a: Wire, b: Wire) -> Wire {
488    let a_is_larger = emit_compare(circuit, a, Relation::AtLeast, b);
489    let a_range = compare_operand(circuit, a).range;
490    let b_range = compare_operand(circuit, b).range;
491    emit_select_operand(circuit, a_is_larger, b, a, a_range.min.max(b_range.min), a_range.max.max(b_range.max))
492}
493
494/// `min(max(value, minimum), maximum)`, as exactly one of the operands.
495pub fn emit_clamp_exact(circuit: &mut Circuit, value: Wire, minimum: Wire, maximum: Wire) -> Wire {
496    let at_least_minimum = emit_maximum_exact(circuit, value, minimum);
497    emit_minimum_exact(circuit, at_least_minimum, maximum)
498}
499
500/// `on × relu(bit) + off × relu(1 - bit)` for an exact bit: exactly the
501/// selected operand, up to the sign of zero.
502fn emit_select_operand(circuit: &mut Circuit, bit: Wire, off: Wire, on: Wire, minimum: f64, maximum: f64) -> Wire {
503    let selected_on = circuit.reglu(on, bit);
504    let selected_off = circuit.reglu(off, 1.0 - bit);
505    let result = circuit.affine(selected_on + selected_off);
506    circuit.assume_range(result, minimum, maximum);
507    result
508}
509
510#[cfg(test)]
511mod tests {
512    use super::*;
513
514    #[test]
515    fn cascade_plan_matches_handwired_comment() {
516        // "a bound of 16,384 with liftExponent 149 gives scales 2^10, 2^24, 2^24, 2^24, 2^24, 2^24 and 2^19, all with limit 1"
517        let scales: Vec<f64> =
518            plan_sign_cascade(16_384.0, FULL_LIFT_EXPONENT).iter().map(|stage| stage.scale.log2()).collect();
519        assert_eq!(scales, vec![10.0, 24.0, 24.0, 24.0, 24.0, 24.0, 19.0]);
520        assert!(plan_sign_cascade(16_384.0, FULL_LIFT_EXPONENT).iter().all(|stage| stage.limit == 1.0));
521    }
522}