Interface Backend

All Known Implementing Classes:
SimdBackend

@API(INTERNAL) public interface Backend
Per-component vector arithmetic primitives on 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 Type
    Method
    Description
    void
    addInto(double[] a, double[] b, double[] out)
    Computes the element-wise sum out[i] = a[i] + b[i] for every i.
    void
    addInto(double[] a, double scalar, double[] out)
    Computes the broadcast sum out[i] = a[i] + scalar for every i.
    double
    dot(double[] a, double[] b)
    Returns the dot product Σ a[i] * b[i] as a single double.
    double
    dot(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.
    double
    euclideanSquared(double[] a, double[] b)
    Returns the squared Euclidean distance Σ (a[i] - b[i])^2 as a single double.
    double
    l2SquaredNorm(double[] a)
    Returns the squared L2 norm Σ a[i] * a[i] as a single double.
    double
    l2SquaredNorm(double[] a, int from, int length)
    Returns the squared L2 norm Σ_{i ∈ [from, from+length)} a[i] * a[i] over a contiguous slice.
    void
    multiplyAddInto(double scalar, double[] x, double[] y, double[] out, int from, int length)
    Computes the AXPY-shaped fused multiply-add out[i] = scalar * x[i] + y[i] for every i in [from, from+length).
    void
    multiplyInto(double[] a, double scalar, double[] out)
    Computes the broadcast product out[i] = a[i] * scalar for every i.
    Returns a short, human-readable identifier of this backend (e.g.
    void
    subtractInto(double[] a, double[] b, double[] out)
    Computes the element-wise difference out[i] = a[i] - b[i] for every i.
    void
    subtractInto(double[] a, double scalar, double[] out)
    Computes the broadcast difference out[i] = a[i] - scalar for every i.
  • Method Details

    • name

      @Nonnull String name()
      Returns a short, human-readable identifier of this backend (e.g. "scalar" or "simd[Species[double, 8, ...]]"). Used by the dispatch logger and the BackendSelectionTest to 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 sum out[i] = a[i] + b[i] for every i.

      out may alias a or b — each lane is loaded from its source positions before any value is written back, so in-place updates such as addInto(x, y, x) are supported.

      Parameters:
      a - left operand
      b - right operand
      out - destination array; receives a + b component-wise. Must have the same length as a and b
    • addInto

      void addInto(@Nonnull double[] a, double scalar, @Nonnull double[] out)
      Computes the broadcast sum out[i] = a[i] + scalar for every i.

      out may alias a.

      Parameters:
      a - left operand
      scalar - value broadcast across every component of a
      out - destination array; receives a + scalar component-wise. Must have the same length as a
    • subtractInto

      void subtractInto(@Nonnull double[] a, @Nonnull double[] b, @Nonnull double[] out)
      Computes the element-wise difference out[i] = a[i] - b[i] for every i.

      out may alias a or b.

      Parameters:
      a - minuend
      b - subtrahend
      out - destination array; receives a - b component-wise. Must have the same length as a and b
    • subtractInto

      void subtractInto(@Nonnull double[] a, double scalar, @Nonnull double[] out)
      Computes the broadcast difference out[i] = a[i] - scalar for every i.

      out may alias a.

      Parameters:
      a - minuend
      scalar - value broadcast across every component of a
      out - destination array; receives a - scalar component-wise. Must have the same length as a
    • multiplyInto

      void multiplyInto(@Nonnull double[] a, double scalar, @Nonnull double[] out)
      Computes the broadcast product out[i] = a[i] * scalar for every i. Used indirectly by RealVectorPrimitives.normalizeInto(double[], double[]) to scale a vector by 1 / l2Norm.

      out may alias a.

      Parameters:
      a - operand
      scalar - value broadcast across every component of a
      out - destination array; receives a * scalar component-wise. Must have the same length as a
    • multiplyAddInto

      void multiplyAddInto(double scalar, @Nonnull double[] x, @Nonnull double[] y, @Nonnull double[] out, int from, int length)
      Computes the AXPY-shaped fused multiply-add out[i] = scalar * x[i] + y[i] for every i in [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 BLAS daxpy(n, α, x, incx, y, incy) is the in-place form y := α·x + y; this method is the more general 3-operand form out := α·x + y, which collapses to the in-place case when out aliases y. 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 with out == y. Implementations fuse the multiply-add into a single hardware FMA where supported (load y, FMA against scalar-broadcast and x, store into out).

      Aliasing: out may alias either x or y; the per-lane loads happen before the store, so in-place updates are well-defined. x and y should not alias each other unless the caller actually wants (1 + scalar) · x.

      Parameters:
      scalar - broadcast multiplier α applied to every x[i]
      x - source vector; read-only over the slice
      y - addend vector; read-only over the slice (unless aliased with out)
      out - destination; receives scalar · x + y component-wise over the slice
      from - inclusive start index
      length - number of elements to write
    • dot

      double dot(@Nonnull double[] a, @Nonnull double[] b)
      Returns the dot product Σ a[i] * b[i] as a single double.

      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 operand
      b - right operand; must have the same length as a
      Returns:
      the dot product of a and b
    • 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 operand
      b - right operand; must overlap the slice [from, from+length) with a
      from - inclusive start index into a and b
      length - 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 single double. Equivalent to dot(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 as l2SquaredNorm(double[]); same reduction-order caveat as dot(double[], double[]).
      Parameters:
      a - vector to take the partial norm of
      from - inclusive start index
      length - number of elements; the slice [from, from+length) must lie within a
      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])^2 as a single double. Equivalent to dot(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 operand
      b - right operand; must have the same length as a
      Returns:
      the squared Euclidean distance between a and b