Documentation
¶
Overview ¶
Package floats provides SIMD-accelerated reductions over float32 and float64 slices — the dot product, sum, min, max, Euclidean (L2) distance and cosine similarity that sit at the heart of vector search, embeddings and numerics. It is pure Go (CGO_ENABLED=0, stable Go, no GOEXPERIMENT): the hot reduction loops are SIMD assembly generated by go-asmgen on all six of Go's 64-bit SIMD targets — amd64 (AVX2+FMA), arm64 (NEON FMLA), ppc64le (VSX), s390x (vector facility), riscv64 (RVV) and loong64 (LSX) — with a portable scalar fallback everywhere else, all on a plain `go build`.
Operations ¶
For both []float32 (the Float32 functions) and []float64:
Dot(a, b) a·b = Σ aᵢbᵢ Sum(a) Σ aᵢ Min(a) / Max(a) the minimum / maximum element Distance(a, b) ‖a−b‖₂ = √Σ(aᵢ−bᵢ)² CosineSimilarity(a, b) a·b / (‖a‖₂‖b‖₂)
Dot, Distance and CosineSimilarity require len(a) == len(b) and panic otherwise. Min and Max panic on an empty slice. Sum of an empty slice is 0.
For []float64, the in-place elementwise updates (BLAS level 1) behind iterative solvers, QR and LU:
Axpy(α, x, y) yᵢ = fma(α, xᵢ, yᵢ) (y += αx) Xpby(x, β, y) yᵢ = fma(β, yᵢ, xᵢ) (y = x + βy) AxpyDot(α, x, y, w) y += αx, then returns Σ yᵢwᵢ (one pass) Scale(α, x) xᵢ = α·xᵢ
They operate on the first len(x) elements and panic if y (or w) is shorter. Unlike the reductions, the updated slices are bit-identical on every architecture: each element is rounded once, exactly as math.FMA rounds it (AVX2 FMA on amd64, NEON FMLA on arm64, the math.FMA loop elsewhere). Only AxpyDot's returned sum is a reduction and follows the rules below.
Floating-point determinism ¶
A SIMD reduction does not add its terms left-to-right: it keeps several independent accumulator lanes (for instruction-level parallelism) and folds them together at the end, so the rounding differs from a naïve scalar loop. To stay deterministic and architecture-independent, the scalar reference used internally and by the tests (sumLanes / dotLanes / …) reduces in the *same* lane-blocked order the kernels use (laneCount lanes), and the SIMD result is required to agree with it to a tight, documented ULP bound across every architecture (the differential tests and FuzzDot/FuzzDistance enforce this). For the similarity use case (cosine / Euclidean distance) bit-exact equality with a naïve scalar loop is neither required nor meaningful; correctness to a few ULP is.
Index ¶
- func Axpy(alpha float64, x, y []float64)
- func AxpyDot(alpha float64, x, y, w []float64) float64
- func CosineSimilarity(a, b []float64) float64
- func Distance(a, b []float64) float64
- func Dot(a, b []float64) float64
- func Float32CosineSimilarity(a, b []float32) float32
- func Float32Distance(a, b []float32) float32
- func Float32Dot(a, b []float32) float32
- func Float32Max(a []float32) float32
- func Float32Min(a []float32) float32
- func Float32Sum(a []float32) float32
- func Max(a []float64) float64
- func Min(a []float64) float64
- func Scale(alpha float64, x []float64)
- func Sum(a []float64) float64
- func Xpby(x []float64, beta float64, y []float64)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Axpy ¶ added in v0.4.0
Axpy computes y[i] += alpha*x[i] for i < len(x), fused: y[i] = math.FMA(alpha, x[i], y[i]). Elements of y past len(x) are left untouched. It panics if len(y) < len(x).
func AxpyDot ¶ added in v0.4.0
AxpyDot computes y[i] += alpha*x[i] for i < len(x) exactly as Axpy does and returns Σ y[i]*w[i] over the updated elements, in one pass over the three slices — the residual update and its norm in conjugate gradient (r -= αAp; rr = r·r is AxpyDot(-α, Ap, r, r)). It panics if len(y) < len(x) or len(w) < len(x).
func CosineSimilarity ¶
CosineSimilarity returns a·b / (‖a‖₂‖b‖₂), a value in [-1, 1] measuring the angle between a and b — the standard relevance score for embedding vectors. It panics if len(a) != len(b). If either vector has zero magnitude the result is NaN (0/0), matching the mathematical definition.
func Distance ¶
Distance returns the Euclidean (L2) distance ‖a−b‖₂ = √Σ(aᵢ−bᵢ)². It panics if len(a) != len(b).
func Float32CosineSimilarity ¶
Float32CosineSimilarity returns a·b / (‖a‖₂‖b‖₂) over float32 slices — the relevance score for float32 embedding vectors. It panics if len(a) != len(b). If either vector has zero magnitude the result is NaN.
func Float32Distance ¶
Float32Distance returns the Euclidean (L2) distance ‖a−b‖₂ over float32 slices. The squared-difference sum is accumulated in float32 and the square root taken in float64 for accuracy. It panics if len(a) != len(b).
func Float32Dot ¶
Float32Dot returns the dot product a·b = Σ aᵢbᵢ over float32 slices, accumulated in float32. It panics if len(a) != len(b).
func Float32Max ¶
Float32Max returns the largest element of a. It panics if a is empty. If a contains a NaN the result is NaN.
func Float32Min ¶
Float32Min returns the smallest element of a. It panics if a is empty. If a contains a NaN the result is NaN.
func Float32Sum ¶
Float32Sum returns Σ aᵢ over a float32 slice, accumulated in float32. The sum of an empty slice is 0.
func Max ¶
Max returns the largest element of a. It panics if a is empty. If a contains a NaN the result is NaN.
func Min ¶
Min returns the smallest element of a. It panics if a is empty. If a contains a NaN the result is NaN.
Types ¶
This section is empty.
