Go · Matrix Kernels

Matrix Kernels

import "github.com/ashvardanian/NumKong" 8.0.0-rc.1 · b1f866ab

Packed kernels are the main batch-throughput path. The DotsPackedMatrix struct wraps the packed buffer with its dimensions and dtype, providing type safety.

package main

import (
	"fmt"

	nk "github.com/ashvardanian/NumKong/golang"
)

func main() {
	rows, columns, depth := 4, 8, 16
	a := make([]float32, rows*depth) // 4 query vectors of dimension 16
	b := make([]float32, columns*depth)  // 8 database vectors of dimension 16

	// Fill with sample data
	for i := range a { a[i] = float32(i % 7) }
	for i := range b { b[i] = float32(i % 5) }

	// Pack the right-hand side (once, reuse across batches)
	bPacked := nk.NewDotsPackedMatrixF32(b, columns, depth)

	// Compute A × Bᵀ
	c := make([]float64, rows*columns)
	nk.DotsPackedF32(a, bPacked, c, rows)

	// Angular and Euclidean distances use the same DotsPackedMatrix
	angDist := make([]float64, rows*columns)
	nk.AngularsPackedF32(a, bPacked, angDist, rows)

	eucDist := make([]float64, rows*columns)
	nk.EuclideansPackedF32(a, bPacked, eucDist, rows)

	fmt.Println(c[:columns]) // first row of the result matrix
}

DotsPackedF64 takes []float64 and produces []float64. DotsPackedF32 takes []float32 and produces []float64 (widened). DotsPackedI8 takes []int8 and produces []int32 (widened). DotsPackedU8 takes []uint8 and produces []uint32 (widened). The same widening pattern applies to AngularsPacked* and EuclideansPacked* variants.

§ Symmetric Kernels for SYRK-Like Workloads

Symmetric kernels compute self-similarity or self-distance matrices. They skip duplicate (i, j) and (j, i) pairs, filling only the upper triangle and mirroring the result.

package main

import (
	"fmt"

	nk "github.com/ashvardanian/NumKong/golang"
)

func main() {
	n, depth := 4, 8
	vectors := make([]float32, n*depth)
	for i := range vectors { vectors[i] = float32(i % 5) }

	// Gram matrix: all-pairs dot products
	gram := make([]float64, n*n)
	nk.DotsSymmetricF32(vectors, n, depth, gram)

	// Angular distance matrix
	angDist := make([]float64, n*n)
	nk.AngularsSymmetricF32(vectors, n, depth, angDist)

	// Euclidean distance matrix
	eucDist := make([]float64, n*n)
	nk.EuclideansSymmetricF32(vectors, n, depth, eucDist)

	fmt.Println("gram[0]:", gram[0])
	fmt.Println("angular[0,1]:", angDist[1])
	fmt.Println("euclidean[0,1]:", eucDist[1])
}

Available symmetric variants: DotsSymmetric{F64,F32,I8,U8}, AngularsSymmetric{F64,F32,I8,U8}, EuclideansSymmetric{F64,F32,I8,U8}.

§ Binary Packed and Symmetric Kernels

Binary vectors use []byte storage where depth is the number of bits. DimensionsToValues("u1", depth) gives the bytes per vector, and depth must be a multiple of DimensionsPerValue("u1"). Packing uses NewDotsPackedMatrixU1.

package main

import (
	"fmt"

	nk "github.com/ashvardanian/NumKong/golang"
)

func main() {
	n, depth := 4, 64 // 4 vectors of 64 dimensions each
	bytesPerVec := nk.DimensionsToValues("u1", depth)
	vectors := make([]byte, n*bytesPerVec)
	for i := range vectors { vectors[i] = byte(i * 37) }

	// Pack for batch queries
	columns := 2
	queryVectors := vectors[:columns*bytesPerVec]
	queryPacked := nk.NewDotsPackedMatrixU1(queryVectors, columns, depth)

	// Hamming distances: n database vectors × columns query vectors
	hammingResult := make([]uint32, n*columns)
	nk.HammingsPackedU1(vectors, queryPacked, hammingResult, n)

	// Jaccard distances
	jaccardResult := make([]float32, n*columns)
	nk.JaccardsPackedU1(vectors, queryPacked, jaccardResult, n)

	// Symmetric Hamming distance matrix
	hammingSym := make([]uint32, n*n)
	nk.HammingsSymmetricU1(vectors, n, depth, hammingSym)

	// Symmetric Jaccard distance matrix
	jaccardSym := make([]float32, n*n)
	nk.JaccardsSymmetricU1(vectors, n, depth, jaccardSym)

	fmt.Println("hamming packed:", hammingResult[:columns])
	fmt.Println("jaccard symmetric[0,1]:", jaccardSym[1])
}

API

StructDotsPackedMatrixDotsPackedMatrix holds a matrix packed once for the Dots, Angulars, Euclideans, Hammings and Jaccards Packed kernels.24
dots.go:18 ↗
type DotsPackedMatrix struct {
    // contains filtered or unexported fields
}

Construct it with the constructor of the element type, such as NewDotsPackedMatrixF32.

NewDotsPackedMatrixF32NewDotsPackedMatrixF32 packs columns float32 vectors of depth dimensions for the Packed kernels.
dots.go:78 ↗
func NewDotsPackedMatrixF32(
    b []float32,
    columns, depth int,
) DotsPackedMatrix

The slice b holds at least columns * depth values.

NewDotsPackedMatrixF64NewDotsPackedMatrixF64 packs columns float64 vectors of depth dimensions for the Packed kernels.
dots.go:61 ↗
func NewDotsPackedMatrixF64(
    b []float64,
    columns, depth int,
) DotsPackedMatrix

The slice b holds at least columns * depth values.

NewDotsPackedMatrixI8NewDotsPackedMatrixI8 packs columns int8 vectors of depth dimensions for the Packed kernels.
dots.go:95 ↗
func NewDotsPackedMatrixI8(
    b []int8,
    columns, depth int,
) DotsPackedMatrix

The slice b holds at least columns * depth values.

NewDotsPackedMatrixU1NewDotsPackedMatrixU1 packs columns binary vectors of depth dimensions for the Packed kernels.
dots.go:130 ↗
func NewDotsPackedMatrixU1(
    b []byte,
    columns, depth int,
) DotsPackedMatrix

The depth is a multiple of 8, and b holds at least columns * [DimensionsToValues]("u1", depth) bytes.

NewDotsPackedMatrixU8NewDotsPackedMatrixU8 packs columns uint8 vectors of depth dimensions for the Packed kernels.
dots.go:112 ↗
func NewDotsPackedMatrixU8(
    b []uint8,
    columns, depth int,
) DotsPackedMatrix

The slice b holds at least columns * depth values.

AngularsF32WithPoolAngularsF32WithPool is AngularsPackedF32 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:135 ↗
func (pm DotsPackedMatrix) AngularsF32WithPool(
    a []float32,
    c []float64,
    rows int,
    pool *WorkerPool,
)
AngularsF64WithPoolAngularsF64WithPool is AngularsPackedF64 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:126 ↗
func (pm DotsPackedMatrix) AngularsF64WithPool(
    a []float64,
    c []float64,
    rows int,
    pool *WorkerPool,
)
AngularsI8WithPoolAngularsI8WithPool is AngularsPackedI8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:144 ↗
func (pm DotsPackedMatrix) AngularsI8WithPool(
    a []int8,
    c []float32,
    rows int,
    pool *WorkerPool,
)
AngularsU8WithPoolAngularsU8WithPool is AngularsPackedU8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:153 ↗
func (pm DotsPackedMatrix) AngularsU8WithPool(
    a []uint8,
    c []float32,
    rows int,
    pool *WorkerPool,
)
BytesBytes returns the packed buffer.
dots.go:35 ↗
func (p DotsPackedMatrix) Bytes() []byte
ColumnsColumns returns the number of packed vectors.
dots.go:26 ↗
func (p DotsPackedMatrix) Columns() int
DTypeDType returns the element type the matrix was packed from: "f64", "f32", "i8", "u8" or "u1".
dots.go:32 ↗
func (p DotsPackedMatrix) DType() string
DepthDepth returns the number of dimensions per packed vector.
dots.go:29 ↗
func (p DotsPackedMatrix) Depth() int
DotsF32WithPoolDotsF32WithPool is DotsPackedF32 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:99 ↗
func (pm DotsPackedMatrix) DotsF32WithPool(
    a []float32,
    c []float64,
    rows int,
    pool *WorkerPool,
)
DotsF64WithPoolDotsF64WithPool is DotsPackedF64 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:90 ↗
func (pm DotsPackedMatrix) DotsF64WithPool(
    a []float64,
    c []float64,
    rows int,
    pool *WorkerPool,
)
DotsI8WithPoolDotsI8WithPool is DotsPackedI8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:108 ↗
func (pm DotsPackedMatrix) DotsI8WithPool(
    a []int8,
    c []int32,
    rows int,
    pool *WorkerPool,
)
DotsU8WithPoolDotsU8WithPool is DotsPackedU8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:117 ↗
func (pm DotsPackedMatrix) DotsU8WithPool(
    a []uint8,
    c []uint32,
    rows int,
    pool *WorkerPool,
)
EuclideansF32WithPoolEuclideansF32WithPool is EuclideansPackedF32 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:171 ↗
func (pm DotsPackedMatrix) EuclideansF32WithPool(
    a []float32,
    c []float64,
    rows int,
    pool *WorkerPool,
)
EuclideansF64WithPoolEuclideansF64WithPool is EuclideansPackedF64 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:162 ↗
func (pm DotsPackedMatrix) EuclideansF64WithPool(
    a []float64,
    c []float64,
    rows int,
    pool *WorkerPool,
)
EuclideansI8WithPoolEuclideansI8WithPool is EuclideansPackedI8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:180 ↗
func (pm DotsPackedMatrix) EuclideansI8WithPool(
    a []int8,
    c []float32,
    rows int,
    pool *WorkerPool,
)
EuclideansU8WithPoolEuclideansU8WithPool is EuclideansPackedU8 with the rows rows of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:189 ↗
func (pm DotsPackedMatrix) EuclideansU8WithPool(
    a []uint8,
    c []float32,
    rows int,
    pool *WorkerPool,
)
HammingsU1WithPoolHammingsU1WithPool is HammingsPackedU1 with the rows vectors of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:198 ↗
func (pm DotsPackedMatrix) HammingsU1WithPool(
    vectors []byte,
    c []uint32,
    rows int,
    pool *WorkerPool,
)
JaccardsU1WithPoolJaccardsU1WithPool is JaccardsPackedU1 with the rows vectors of a split across pool, each of DotsPackedMatrix.Depth dimensions, while c holds at least rows * DotsPackedMatrix.Columns entries.
dots.go:208 ↗
func (pm DotsPackedMatrix) JaccardsU1WithPool(
    vectors []byte,
    c []float32,
    rows int,
    pool *WorkerPool,
)
ShapeShape reads the columns and depth back from the header of the packed buffer.
dots.go:38 ↗
func (p DotsPackedMatrix) Shape() (columns, depth int)

Functions

AngularsPackedF32AngularsPackedF32 computes the angular distance from each of rows float32 rows of a to every packed row of b.
numkong.go:40 ↗
func AngularsPackedF32(
    a []float32,
    b DotsPackedMatrix,
    result []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

AngularsPackedF64AngularsPackedF64 computes the angular distance from each of rows float64 rows of a to every packed row of b.
numkong.go:18 ↗
func AngularsPackedF64(
    a []float64,
    b DotsPackedMatrix,
    result []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

AngularsPackedI8AngularsPackedI8 computes the angular distance from each of rows int8 rows of a to every packed row of b.
numkong.go:62 ↗
func AngularsPackedI8(
    a []int8,
    b DotsPackedMatrix,
    result []float32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

AngularsPackedU8AngularsPackedU8 computes the angular distance from each of rows uint8 rows of a to every packed row of b.
numkong.go:84 ↗
func AngularsPackedU8(
    a []uint8,
    b DotsPackedMatrix,
    result []float32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

AngularsSymmetricF32AngularsSymmetricF32 computes the angular distance between every pair of nVectors row-major float32 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:221 ↗
func AngularsSymmetricF32(
    vectors []float32,
    nVectors, depth int,
    result []float64,
)
AngularsSymmetricF32WithPoolAngularsSymmetricF32WithPool is AngularsSymmetricF32 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:297 ↗
func AngularsSymmetricF32WithPool(
    vectors []float32,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
AngularsSymmetricF64AngularsSymmetricF64 computes the angular distance between every pair of nVectors row-major float64 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:198 ↗
func AngularsSymmetricF64(
    vectors []float64,
    nVectors, depth int,
    result []float64,
)
AngularsSymmetricF64WithPoolAngularsSymmetricF64WithPool is AngularsSymmetricF64 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:282 ↗
func AngularsSymmetricF64WithPool(
    vectors []float64,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
AngularsSymmetricI8AngularsSymmetricI8 computes the angular distance between every pair of nVectors row-major int8 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:244 ↗
func AngularsSymmetricI8(
    vectors []int8,
    nVectors, depth int,
    result []float32,
)
AngularsSymmetricI8WithPoolAngularsSymmetricI8WithPool is AngularsSymmetricI8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:312 ↗
func AngularsSymmetricI8WithPool(
    vectors []int8,
    nVectors, depth int,
    result []float32,
    pool *WorkerPool,
)
AngularsSymmetricU8AngularsSymmetricU8 computes the angular distance between every pair of nVectors row-major uint8 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:267 ↗
func AngularsSymmetricU8(
    vectors []uint8,
    nVectors, depth int,
    result []float32,
)
AngularsSymmetricU8WithPoolAngularsSymmetricU8WithPool is AngularsSymmetricU8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:327 ↗
func AngularsSymmetricU8WithPool(
    vectors []uint8,
    nVectors, depth int,
    result []float32,
    pool *WorkerPool,
)
DotsPackedF32DotsPackedF32 computes the dot product of each of rows float32 rows of a with every packed row of b.
numkong.go:176 ↗
func DotsPackedF32(
    a []float32,
    b DotsPackedMatrix,
    c []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and c holds at least rows * DotsPackedMatrix.Columns entries.

DotsPackedF64DotsPackedF64 computes the dot product of each of rows float64 rows of a with every packed row of b.
numkong.go:154 ↗
func DotsPackedF64(
    a []float64,
    b DotsPackedMatrix,
    c []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and c holds at least rows * DotsPackedMatrix.Columns entries.

DotsPackedI8DotsPackedI8 computes the dot product of each of rows int8 rows of a with every packed row of b.
numkong.go:198 ↗
func DotsPackedI8(
    a []int8,
    b DotsPackedMatrix,
    c []int32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and c holds at least rows * DotsPackedMatrix.Columns entries.

DotsPackedU8DotsPackedU8 computes the dot product of each of rows uint8 rows of a with every packed row of b.
numkong.go:220 ↗
func DotsPackedU8(
    a []uint8,
    b DotsPackedMatrix,
    c []uint32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and c holds at least rows * DotsPackedMatrix.Columns entries.

DotsSymmetricF32DotsSymmetricF32 computes the dot product between every pair of nVectors float32 vectors of depth dimensions.
numkong.go:269 ↗
func DotsSymmetricF32(
    vectors []float32,
    nVectors, depth int,
    result []float64,
)

The vectors are stored row-major, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

DotsSymmetricF32WithPoolDotsSymmetricF32WithPool is DotsSymmetricF32 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:237 ↗
func DotsSymmetricF32WithPool(
    vectors []float32,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
DotsSymmetricF64DotsSymmetricF64 computes the dot product between every pair of nVectors float64 vectors of depth dimensions.
numkong.go:246 ↗
func DotsSymmetricF64(
    vectors []float64,
    nVectors, depth int,
    result []float64,
)

The vectors are stored row-major, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

DotsSymmetricF64WithPoolDotsSymmetricF64WithPool is DotsSymmetricF64 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:222 ↗
func DotsSymmetricF64WithPool(
    vectors []float64,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
DotsSymmetricI8DotsSymmetricI8 computes the dot product between every pair of nVectors int8 vectors of depth dimensions.
numkong.go:292 ↗
func DotsSymmetricI8(
    vectors []int8,
    nVectors, depth int,
    result []int32,
)

The vectors are stored row-major, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

DotsSymmetricI8WithPoolDotsSymmetricI8WithPool is DotsSymmetricI8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:252 ↗
func DotsSymmetricI8WithPool(
    vectors []int8,
    nVectors, depth int,
    result []int32,
    pool *WorkerPool,
)
DotsSymmetricU8DotsSymmetricU8 computes the dot product between every pair of nVectors uint8 vectors of depth dimensions.
numkong.go:315 ↗
func DotsSymmetricU8(
    vectors []uint8,
    nVectors, depth int,
    result []uint32,
)

The vectors are stored row-major, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

DotsSymmetricU8WithPoolDotsSymmetricU8WithPool is DotsSymmetricU8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:267 ↗
func DotsSymmetricU8WithPool(
    vectors []uint8,
    nVectors, depth int,
    result []uint32,
    pool *WorkerPool,
)
EuclideansPackedF32EuclideansPackedF32 computes the Euclidean distance from each of rows float32 rows of a to every packed row of b.
numkong.go:128 ↗
func EuclideansPackedF32(
    a []float32,
    b DotsPackedMatrix,
    result []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

EuclideansPackedF64EuclideansPackedF64 computes the Euclidean distance from each of rows float64 rows of a to every packed row of b.
numkong.go:106 ↗
func EuclideansPackedF64(
    a []float64,
    b DotsPackedMatrix,
    result []float64,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

EuclideansPackedI8EuclideansPackedI8 computes the Euclidean distance from each of rows int8 rows of a to every packed row of b.
numkong.go:150 ↗
func EuclideansPackedI8(
    a []int8,
    b DotsPackedMatrix,
    result []float32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

EuclideansPackedU8EuclideansPackedU8 computes the Euclidean distance from each of rows uint8 rows of a to every packed row of b.
numkong.go:172 ↗
func EuclideansPackedU8(
    a []uint8,
    b DotsPackedMatrix,
    result []float32,
    rows int,
)

Each row has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

EuclideansSymmetricF32EuclideansSymmetricF32 computes the Euclidean distance between every pair of nVectors row-major float32 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:313 ↗
func EuclideansSymmetricF32(
    vectors []float32,
    nVectors, depth int,
    result []float64,
)
EuclideansSymmetricF32WithPoolEuclideansSymmetricF32WithPool is EuclideansSymmetricF32 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:357 ↗
func EuclideansSymmetricF32WithPool(
    vectors []float32,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
EuclideansSymmetricF64EuclideansSymmetricF64 computes the Euclidean distance between every pair of nVectors row-major float64 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:290 ↗
func EuclideansSymmetricF64(
    vectors []float64,
    nVectors, depth int,
    result []float64,
)
EuclideansSymmetricF64WithPoolEuclideansSymmetricF64WithPool is EuclideansSymmetricF64 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:342 ↗
func EuclideansSymmetricF64WithPool(
    vectors []float64,
    nVectors, depth int,
    result []float64,
    pool *WorkerPool,
)
EuclideansSymmetricI8EuclideansSymmetricI8 computes the Euclidean distance between every pair of nVectors row-major int8 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:336 ↗
func EuclideansSymmetricI8(
    vectors []int8,
    nVectors, depth int,
    result []float32,
)
EuclideansSymmetricI8WithPoolEuclideansSymmetricI8WithPool is EuclideansSymmetricI8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:372 ↗
func EuclideansSymmetricI8WithPool(
    vectors []int8,
    nVectors, depth int,
    result []float32,
    pool *WorkerPool,
)
EuclideansSymmetricU8EuclideansSymmetricU8 computes the Euclidean distance between every pair of nVectors row-major uint8 vectors of depth dimensions, writing only entries with row <= column into result, which holds at least nVectors * nVectors entries.
numkong.go:359 ↗
func EuclideansSymmetricU8(
    vectors []uint8,
    nVectors, depth int,
    result []float32,
)
EuclideansSymmetricU8WithPoolEuclideansSymmetricU8WithPool is EuclideansSymmetricU8 with the nVectors rows split across pool, the vectors stored row-major; only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.
numkong.go:387 ↗
func EuclideansSymmetricU8WithPool(
    vectors []uint8,
    nVectors, depth int,
    result []float32,
    pool *WorkerPool,
)
HammingsPackedU1HammingsPackedU1 computes the Hamming distance from each of rows binary vectors to every packed query.
numkong.go:16 ↗
func HammingsPackedU1(
    vectors []byte,
    query DotsPackedMatrix,
    result []uint32,
    rows int,
)

Each vector has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

HammingsSymmetricU1HammingsSymmetricU1 computes the Hamming distance between every pair of nVectors binary vectors of depth dimensions.
numkong.go:39 ↗
func HammingsSymmetricU1(
    vectors []byte,
    nVectors, depth int,
    result []uint32,
)

The depth is a multiple of 8, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

HammingsSymmetricU1WithPoolHammingsSymmetricU1WithPool is HammingsSymmetricU1 with the nVectors rows split across pool.
numkong.go:402 ↗
func HammingsSymmetricU1WithPool(
    vectors []byte,
    nVectors, depth int,
    result []uint32,
    pool *WorkerPool,
)

The depth is a multiple of 8, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

JaccardsPackedU1JaccardsPackedU1 computes the Jaccard distance from each of rows binary vectors to every packed query.
numkong.go:65 ↗
func JaccardsPackedU1(
    vectors []byte,
    query DotsPackedMatrix,
    result []float32,
    rows int,
)

Each vector has DotsPackedMatrix.Depth dimensions, and result holds at least rows * DotsPackedMatrix.Columns entries.

JaccardsSymmetricU1JaccardsSymmetricU1 computes the Jaccard distance between every pair of nVectors binary vectors of depth dimensions.
numkong.go:88 ↗
func JaccardsSymmetricU1(
    vectors []byte,
    nVectors, depth int,
    result []float32,
)

The depth is a multiple of 8, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.

JaccardsSymmetricU1WithPoolJaccardsSymmetricU1WithPool is JaccardsSymmetricU1 with the nVectors rows split across pool.
numkong.go:419 ↗
func JaccardsSymmetricU1WithPool(
    vectors []byte,
    nVectors, depth int,
    result []float32,
    pool *WorkerPool,
)

The depth is a multiple of 8, and only entries with row <= column are written into result, which holds at least nVectors * nVectors entries.