Interface Backend
- All Known Implementing Classes:
SimdBackend
double[] arrays. Implementations may be a
pure-Java scalar loop or a SIMD-using variant; RealVectorPrimitives dispatches to the
implementation it picks at static-init time.
Implementations live in com.apple.foundationdb.linear (scalar) and
com.apple.foundationdb.linear.simd (SIMD). The interface is public only because
the SIMD implementation in the sub-package has to be able to implements it; this is not
a stable extension point for external callers.
All array-mutating methods are permitted to write to an output array that aliases an input
(e.g. add(a, b, a)) — the operations are per-element and have no cross-element data
dependencies. Reduction methods return a scalar and do not mutate inputs.
Callers must ensure array length consistency before invoking these methods; implementations may
assume a.length == b.length == out.length and skip length checks for speed.
-
Method Summary
Modifier and TypeMethodDescriptionvoidaddInto(double[] a, double[] b, double[] out) Computes the element-wise sumout[i] = a[i] + b[i]for everyi.voidaddInto(double[] a, double scalar, double[] out) Computes the broadcast sumout[i] = a[i] + scalarfor everyi.doubledot(double[] a, double[] b) Returns the dot productΣ a[i] * b[i]as a singledouble.doubledot(double[] a, double[] b, int from, int length) Returns the dot productΣ_{i ∈ [from, from+length)} a[i] * b[i]over a contiguous slice of two arrays.doubleeuclideanSquared(double[] a, double[] b) Returns the squared Euclidean distanceΣ (a[i] - b[i])^2as a singledouble.doublel2SquaredNorm(double[] a) Returns the squared L2 normΣ a[i] * a[i]as a singledouble.doublel2SquaredNorm(double[] a, int from, int length) Returns the squared L2 normΣ_{i ∈ [from, from+length)} a[i] * a[i]over a contiguous slice.voidmultiplyAddInto(double scalar, double[] x, double[] y, double[] out, int from, int length) Computes the AXPY-shaped fused multiply-addout[i] = scalar * x[i] + y[i]for everyiin[from, from+length).voidmultiplyInto(double[] a, double scalar, double[] out) Computes the broadcast productout[i] = a[i] * scalarfor everyi.name()Returns a short, human-readable identifier of this backend (e.g.voidsubtractInto(double[] a, double[] b, double[] out) Computes the element-wise differenceout[i] = a[i] - b[i]for everyi.voidsubtractInto(double[] a, double scalar, double[] out) Computes the broadcast differenceout[i] = a[i] - scalarfor everyi.
-
Method Details
-
name
Returns a short, human-readable identifier of this backend (e.g."scalar"or"simd[Species[double, 8, ...]]"). Used by the dispatch logger and theBackendSelectionTestto confirm which implementation is active.- Returns:
- a non-null label that uniquely identifies this backend at runtime
-
addInto
void addInto(@Nonnull double[] a, @Nonnull double[] b, @Nonnull double[] out) Computes the element-wise sumout[i] = a[i] + b[i]for everyi.outmay aliasaorb— each lane is loaded from its source positions before any value is written back, so in-place updates such asaddInto(x, y, x)are supported.- Parameters:
a- left operandb- right operandout- destination array; receivesa + bcomponent-wise. Must have the same length asaandb
-
addInto
void addInto(@Nonnull double[] a, double scalar, @Nonnull double[] out) Computes the broadcast sumout[i] = a[i] + scalarfor everyi.outmay aliasa.- Parameters:
a- left operandscalar- value broadcast across every component ofaout- destination array; receivesa + scalarcomponent-wise. Must have the same length asa
-
subtractInto
void subtractInto(@Nonnull double[] a, @Nonnull double[] b, @Nonnull double[] out) Computes the element-wise differenceout[i] = a[i] - b[i]for everyi.outmay aliasaorb.- Parameters:
a- minuendb- subtrahendout- destination array; receivesa - bcomponent-wise. Must have the same length asaandb
-
subtractInto
void subtractInto(@Nonnull double[] a, double scalar, @Nonnull double[] out) Computes the broadcast differenceout[i] = a[i] - scalarfor everyi.outmay aliasa.- Parameters:
a- minuendscalar- value broadcast across every component ofaout- destination array; receivesa - scalarcomponent-wise. Must have the same length asa
-
multiplyInto
void multiplyInto(@Nonnull double[] a, double scalar, @Nonnull double[] out) Computes the broadcast productout[i] = a[i] * scalarfor everyi. Used indirectly byRealVectorPrimitives.normalizeInto(double[], double[])to scale a vector by1 / l2Norm.outmay aliasa.- Parameters:
a- operandscalar- value broadcast across every component ofaout- destination array; receivesa * scalarcomponent-wise. Must have the same length asa
-
multiplyAddInto
void multiplyAddInto(double scalar, @Nonnull double[] x, @Nonnull double[] y, @Nonnull double[] out, int from, int length) Computes the AXPY-shaped fused multiply-addout[i] = scalar * x[i] + y[i]for everyiin[from, from+length). Indices outside the slice are not touched.AXPY (
A · X Plus Y) is the BLAS Level 1 building block of most accumulator-style inner loops in linear algebra — Householder QR, Gram-Schmidt, conjugate-gradient updates, gradient steps. Standard BLASdaxpy(n, α, x, incx, y, incy)is the in-place formy := α·x + y; this method is the more general 3-operand formout := α·x + y, which collapses to the in-place case whenoutaliasesy. The parameter order matches BLAS (scalar first, multiplied source next, addend next, then destination).The backend exposes only this most general form; the convenience in-place wrapper lives in
RealVectorPrimitives.multiplyAddInto(double, double[], double[], int, int)and just calls this method without == y. Implementations fuse the multiply-add into a single hardware FMA where supported (loady, FMA against scalar-broadcast andx, store intoout).Aliasing:
outmay alias eitherxory; the per-lane loads happen before the store, so in-place updates are well-defined.xandyshould not alias each other unless the caller actually wants(1 + scalar) · x.- Parameters:
scalar- broadcast multiplierαapplied to everyx[i]x- source vector; read-only over the slicey- addend vector; read-only over the slice (unless aliased without)out- destination; receivesscalar · x + ycomponent-wise over the slicefrom- inclusive start indexlength- number of elements to write
-
dot
double dot(@Nonnull double[] a, @Nonnull double[] b) Returns the dot productΣ a[i] * b[i]as a singledouble.SIMD implementations typically use fused multiply-add and may sum partial lanes in a different order than a strict left-to-right scalar accumulation, so the low-order bits of the result can differ from a scalar reference by a few ULPs. Callers that depend on bit-exact reproducibility should force the scalar backend via
-Dfdb.vector.simd=scalar.- Parameters:
a- left operandb- right operand; must have the same length asa- Returns:
- the dot product of
aandb
-
dot
double dot(@Nonnull double[] a, @Nonnull double[] b, int from, int length) Returns the dot productΣ_{i ∈ [from, from+length)} a[i] * b[i]over a contiguous slice of two arrays. Used by routines (Householder QR, partial reductions) that operate on sub-arrays without materializing copies.Same reduction-order caveat as
dot(double[], double[]).- Parameters:
a- left operandb- right operand; must overlap the slice[from, from+length)withafrom- inclusive start index intoaandblength- number of elements to multiply-and-sum; the slice[from, from+length)must lie within both arrays- Returns:
- the dot product over the slice
-
l2SquaredNorm
double l2SquaredNorm(@Nonnull double[] a) Returns the squared L2 normΣ a[i] * a[i]as a singledouble. Equivalent todot(a, a)but typically faster because it requires only one array load per lane.Same reduction-order caveat as
dot(double[], double[]).- Parameters:
a- vector to take the norm of- Returns:
- the squared L2 norm of
a
-
l2SquaredNorm
double l2SquaredNorm(@Nonnull double[] a, int from, int length) Returns the squared L2 normΣ_{i ∈ [from, from+length)} a[i] * a[i]over a contiguous slice. Same fused-load optimization asl2SquaredNorm(double[]); same reduction-order caveat asdot(double[], double[]).- Parameters:
a- vector to take the partial norm offrom- inclusive start indexlength- number of elements; the slice[from, from+length)must lie withina- Returns:
- the squared L2 norm over the slice
-
euclideanSquared
double euclideanSquared(@Nonnull double[] a, @Nonnull double[] b) Returns the squared Euclidean distanceΣ (a[i] - b[i])^2as a singledouble. Equivalent todot(a - b, a - b)but fused into a single pass that avoids materializing the difference vector.Same reduction-order caveat as
dot(double[], double[]).- Parameters:
a- left operandb- right operand; must have the same length asa- Returns:
- the squared Euclidean distance between
aandb
-