numkong

repository·main·Indexed 23 days ago

https://github.com/ashvardanian/numkong

A portable mixed-precision math, linear-algebra, and retrieval library featuring over 2000 SIMD kernels for x86, Arm, RISC-V, LoongArch, Power, and WebAssembly. It supports numeric types from 4-bit integers to 128-bit complex numbers, providing high-performance implementations for dot products, Euclidean and angular distances, binary metrics (Hamming, Jaccard), probability metrics (KL divergence, JS distance), and geospatial metrics (Haversine, Vincenty). Includes Go bindings with support for PackedMatrix batch workloads, symmetric kernels, and ColBERT-style MaxSim late interaction.

Tokens
99.9K
Snippets
139
Records
234
Agent score
83%

What's inside numkong

  1. Calculate Set Similarity Measures in NumKong

    main

    NumKong provides optimized implementations for Hamming and Jaccard distance measures, which are essential for locality-sensitive hashing, MinHash sketches, and binary feature matching.

    Hamming Distance

    Counts the number of positions where elements differ.

    • Binary vectors (packed octets): Counts the popcount of the XOR result.
    • Byte-level vectors: Counts the number of mismatched bytes.

    Jaccard Distance

    Measures the dissimilarity of two sets.

    • Binary vectors: Calculated as $1 - \frac{|A \cap B|}{|A \cup B|}$ using bitwise AND/OR and popcount.
    • Word-level vectors (MinHash signatures): Calculated as the fraction of non-matching elements: $1 - \frac{\sum [a_i = b_i]}{n}$.
    import numpy as np
    
    def hamming_bits(a: np.ndarray, b: np.ndarray) -> int:
        return np.unpackbits(np.bitwise_xor(a, b)).sum()
    
    def jaccard_bits(a: np.ndarray, b: np.ndarray) -> float:
        intersection = np.unpackbits(np.bitwise_and(a, b)).sum()
        union = np.unpackbits(np.bitwise_or(a, b)).sum()
        return 1 - intersection / union if union else 0
    
    def jaccard_words(a: np.ndarray, b: np.ndarray) -> float:
        return 1 - np.mean(a == b)
  2. Batched Dot Products in NumKong

    main
    NumKong provides highly optimized batched dot product implementations designed for high throughput and numerical stability. The library includes specialized kernels for different hardware architectures and data types, including support for ARM SME (Scalable Matrix Extension) and NEON, as well as optimizations for Intel Sapphire Rapids (AMX).
  3. Understand Point Cloud Alignment performance in NumKong

    main

    NumKong provides high-performance kernels for point cloud alignment, specifically for computing RMSD (Root Mean Square Deviation), Kabsch, and Umeyama algorithms.

    Performance Metrics

    • Throughput: Measured in mp/s (millions of 3D points aligned per second).
    • Accuracy: Reported as mean ULP (units in last place), representing the average number of representable floating-point values between the result and the exact answer.
    • Complexity: Each alignment computes centroids, covariance, and a 3×3 SVD over $N$ point pairs, resulting in $O(N)$ cost per alignment.

    Benchmarking Configuration

    Performance is tested across different input sizes controlled by the NK_MESH_POINTS environment variable (standard tests use 256, 1024, and 4096 points).

  4. Trigonometric functions in NumKong

    main

    NumKong provides element-wise trigonometric functions for dense vectors. The functions operate on input angles provided in radians and return output values of the same length.

    Supported functions:

    • Sine (sin): Maps $\mathbb{R} \to [-1, 1]$.
    • Cosine (cos): Maps $\mathbb{R} \to [-1, 1]$.
    • Arc tangent (atan): Maps $\mathbb{R} \to (-\frac{\pi}{2}, \frac{\pi}{2})$.

    Numerical accuracy:

    • f32: Approximately 3 ulp error bounds.
    • f64: Faithful rounding.
    import numpy as np
    
    # Conceptual usage pattern
    def sin(a: np.ndarray) -> np.ndarray:
        return np.sin(a)
    
    def cos(a: np.ndarray) -> np.ndarray:
        return np.cos(a)
    
    def atan(a: np.ndarray) -> np.ndarray:
        return np.arctan(a)
  5. Use Scalar Math Primitives in NumKong

    main

    NumKong provides single-element math operations designed as building blocks for vectorized kernels. These primitives include square root, reciprocal square root, fused multiply-add (FMA), and saturating integer arithmetic. They are implemented with per-ISA (Instruction Set Architecture) optimizations to ensure high performance and numerical stability.

    Key mathematical operations provided:

    • Reciprocal square root: $\text{rsqrt}(x) = \frac{1}{\sqrt{x}}$
    • Fused multiply-add: $\text{fma}(a, b, c) = a \cdot b + c$
    • Saturating addition: $\text{sat_add}(a, b) = \text{clamp}(a + b, \text{T_MIN}, \text{T_MAX})$
  6. Horizontal Reductions in NumKong

    main

    NumKong provides optimized horizontal reduction operations designed for high performance across various backends. These reductions focus on balancing latency, throughput, and numerical stability. Key features include:

    • Input & Output Types: Support for various numeric types.
    • Optimizations: Includes auto-vectorization, loop unrolling, and strided access across backends.
    • Numerical Stability: Implements Kahan-Neumaier compensated summation to minimize rounding errors.
    • Advanced Reductions:
      • Fused Moments: Calculates multiple moments in a single pass.
      • Integer Saturation: Handles sum-of-squares with integer saturation.
      • Recursive Blocking: Prevents counter overflow.
      • NaN-Aware Extrema Tracking: Robustly tracks minimum and maximum values even in the presence of NaNs.
    • Performance: Optimized for modern hardware, including Intel Sapphire Rapids.
  7. Sparse Vector Operations in NumKong

    main

    NumKong provides high-performance primitives for sparse vector operations, specifically designed for inverted-index search, sparse feature matching, and graph intersection queries. The library implements two primary operations:

    1. Set Intersection: Counts the number of common elements between two sorted arrays of unique indices.
    2. Sparse Dot Product: Calculates the sum of products of weights at matching indices between two sparse vectors.

    The design separates index streams from weight streams, allowing these primitives to be composed into batched sparse operations and future sparse GEMM (General Matrix Multiply) workloads.

    import numpy as np
    
    # Conceptual representation of NumKong's logic
    def intersect(a_indices: np.ndarray, b_indices: np.ndarray) -> int:
        return len(np.intersect1d(a_indices, b_indices))
    
    def sparse_dot(a_indices: np.ndarray, a_weights: np.ndarray, 
                   b_indices: np.ndarray, b_weights: np.ndarray) -> float:
        common = np.intersect1d(a_indices, b_indices, return_indices=True)
        return np.dot(a_weights[common[1]], b_weights[common[2]])
  8. Compute curved space distances in NumKong

    main

    NumKong provides optimized implementations for distance functions in curved metric spaces, specifically for Gaussian process inference, metric learning, and statistical distance measures.

    Supported operations include:

    • Bilinear forms: Computes $a^T C b$ for real vectors or $a^H C b$ (Hermitian inner products) for complex vectors using a metric tensor $C$.
    • Mahalanobis distance: Generalizes Euclidean distance to account for correlations between dimensions using the formula $\sqrt{(a - b)^T C (a - b)}$.
    import numpy as np
    
    # Pseudocode representation of NumKong operations
    def bilinear(a: np.ndarray, b: np.ndarray, C: np.ndarray) -> float:
        return a @ C @ b
    
    def mahalanobis(a: np.ndarray, b: np.ndarray, C: np.ndarray) -> float:
        diff = a - b
        return np.sqrt(diff @ C @ diff)
    
    def bilinear_complex(a: np.ndarray, b: np.ndarray, C: np.ndarray) -> complex:
        return np.conj(a) @ C @ b
  9. Compute geospatial distances with Haversine and Vincenty

    main

    NumKong provides two primary methods for computing geodesic distances between points on Earth's surface using arrays of latitude/longitude pairs in radians:

    1. Haversine: Computes the great-circle distance on a perfect sphere. Use this for faster, less precise calculations.
    2. Vincenty: Solves the inverse geodesic problem on the WGS-84 oblate spheroid. Use this for high-precision requirements (convergence threshold of $10^{-12}$ radians, approximately 6 micrometers accuracy).

    Input Requirements:

    • Coordinates must be in radians.
    • Input/Output types support f32 (32-bit single precision) and f64 (64-bit double precision).
    • Output distances are returned in meters.
    import numpy as np
    
    def haversine(lat1, lon1, lat2, lon2, R=6371000):
        dlat = lat2 - lat1
        dlon = lon2 - lon1
        a = np.sin(dlat / 2) ** 2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2) ** 2
        return 2 * R * np.arcsin(np.sqrt(a))
  10. NumKong design principles

    main

    NumKong is designed for high-performance mixed-precision numerics with the following constraints:

    • No Loop Unrolling/Scalar Tails: Avoids inflating binary size and instruction-cache pressure; uses masked loads to handle boundaries instead of serial scalar loops.
    • No Thread/Memory Management: Compatible with any parallelism model and any allocator/alignment.
    • No Traditional BLAS APIs: Moves beyond simple $C = \alpha AB + eta C$ to support specialized operations like Bilinear forms and MaxSim scoring.
    • Saturated Arithmetic: Prefers saturated arithmetic to avoid overflows in reductions.
    • Flexible Dispatch: Supports both compile-time dispatch (for known hardware) and run-time dispatch (for heterogeneous fleets).
  11. cGo Integration and Memory Safety rules

    main

    The Go package is a cGo wrapper. When using it, observe the following rules regarding memory and safety:

    Memory Management:

    • Ownership: The slice backing arrays remain owned by Go. NumKong does not wrap slices in extra heap-owning tensor objects.
    • Pinning: Go automatically pins slice backing arrays for the duration of each cGo call; no manual runtime.Pinner is required.
    • Lifecycle: PackedMatrix and MaxSimPacked structs hold strong Go references to their []byte buffers, keeping them alive for GC as long as the struct is reachable.

    Safety and Validation:

    • Panics: Length mismatches and insufficient slice capacity will cause a panic across all functions.
    • Validation: Constructors validate that input slices are large enough for the specified dimensions. Batch functions validate both input and output slice sizes.
    • Empty Slices: Empty slices return zero for scalar outputs instead of crashing.
    • Symmetric Matrices: Output matrices for symmetric operations must be exactly $n imes n$ in size.
  12. How trigonometric range reduction works in NumKong

    main

    To maintain high precision, NumKong uses Cody-Waite Range Reduction. All trigonometric kernels reduce the input angle to the interval $[-\pi/4, \pi/4]$ before polynomial evaluation.

    Instead of a single-part subtraction which can lose up to 3 bits of precision for large multiples of $\pi$, NumKong splits $\pi$ into high and low parts ($\pi_{\text{hi}} + \pi_{\text{lo}}$). The reduction is performed as:

    reduced = (x - n * pi_hi) - n * pi_lo

    This two-part split preserves the full mantissa. The quadrant index $n = \text{round}(x / \pi)$ is used to select the appropriate trigonometric identity (e.g., sine-cosine swap or sign flip) via a 2-bit branch.