folly::reproducible_accumulator

Reproducible floating-point accumulator via binned floating-point arithmetic.

Synopsis

Declared in <folly/math/ReproducibleAccumulator.h>

class reproducible_accumulator;

Description

Guarantees bitwise-identical sums regardless of summation order, assuming IEEE 754 arithmetic. Based on the ReproBLAS algorithm by Ahrens, Nguyen, and Demmel (https://bebop.cs.berkeley.edu/reproblas/).

Accuracy: the error has two components (see error_bound()). The first grows as O(N * epsilon * max_abs_val), proportional to element count and the largest element magnitude — not the condition number. The second is O(epsilon * |sum|), independent of N. This is much more accurate than naive summation (whose error grows as O(N * epsilon * |sum|) and is sensitive to catastrophic cancellation), and comparable to Kahan summation in practice — though the asymptotic bound has an N-dependent term that Kahan lacks. The tradeoff is order-independence: unlike Kahan, the result is bitwise identical regardless of summation order.

Note: error_bound() uses a tighter formula based on the internal bin scale factor, which can be violated on highly ill-conditioned data (condition number >> 1). The O(N * epsilon * max_abs_val) bound above always holds.

Performance: operator+= (one-at-a-time) costs roughly 4x a naive FP add due to the serial dependency chain through Fold bin levels. The batch add(first, last) method uses multiple independent accumulators for instruction-level parallelism, reducing this to roughly 3x for inputs of 128 elements or more. For smaller inputs, add() falls back to the serial path to avoid accumulator merge overhead.

Cross-type conversion (e.g., between reproducible_accumulator<float> and reproducible_accumulator<double>) is intentionally not supported. The internal bin structures are incompatible across types, so any conversion must collapse the accumulator to a scalar, discarding the bin state. Use .value() to extract the scalar and construct/assign from that explicitly:

reproducible_accumulator<double> d = acc_float.value();

Member Functions

NameDescription
reproducible_accumulator [constructor]Constructors
~reproducible_accumulator [destructor]Destroys the accumulator.
operator= Assignment operators
add add overloads
operator+= Addition assignment operators
operator- Returns the negative of this binned fp
operator-= Subtraction assignment operators
renorm Renormalizes the accumulator. Must be called at least every endurance() deposits when using unsafe_add().
set_max_abs_val Updates the accumulator's bin structure to accommodate values up to mav in absolute value. Must be called before unsafe_add() when the maximum absolute value of subsequent deposits is known in advance.
unsafe_add Deposits x into the accumulator without updating bins or renormalizing. The caller must ensure set_max_abs_val() has been called and renorm() is called every endurance() deposits.
value Convert this binned fp into its native floating-point representation
zero Set the binned fp to zero
operator ftype Explicitly convert this binned fp to its native floating-point type
operator== Determines if two binned fp are equal

Static Member Functions

NameDescription
endurance Returns the maximum number of unsafe_add() deposits allowed between renorm() calls.
error_bound Get binned fp summation error bound

Friends

NameDescription
folly::operator-Returns the difference of two accumulators.
folly::operator+Returns the sum of two accumulators.

Parameters

NameDescription
ftypeFloating-point data type; either float or double
FoldThe fold; use 3 as a default unless you understand it.