# Highlights

> NumKong for C++

This is the primary SDK in the project.
It is the right layer if you want exact control over dtypes, allocators, packed buffers, dispatch, and host-side partitioning.

__Full kernel surface.__
All public operation families are reachable from native code.
__No hidden threading.__
NumKong does not own a thread pool.
__No hidden allocation.__
C APIs take caller-owned buffers, and C++ wrappers make ownership explicit.
__Mixed precision by default.__
Small storage types widen into safer accumulator and output types.
__Allocator-aware containers.__
`vector`, `tensor`, `packed_matrix`, and `packed_maxsim` accept custom allocators.
__Unaligned inputs are fine.__
Packing handles internal layout itself and does not require caller-side alignment.

### Ecosystem Comparison

| Feature                      | NumKong                                                                                                                             | [OpenBLAS][openblas]                                              | [Eigen][eigen]                                                                          |
| :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------- | :-------------------------------------------------------------------------------------- |
| Operation families           | dots, distances, binary, probability, geospatial, curved, shapes, sparse, MaxSim, elementwise, reductions, cast, trig               | dense linear algebra only                                         | dense LA, some reductions and elementwise                                               |
| Precision                    | Sub-byte to Float64 dtypes; automatic widening per scalar type; Kahan-compensated summation; 0 ULP Float32/Float64 where applicable | Float32, Float64 only; same-type in/out; no compensated summation | Float16/BFloat16 partial; no Float8 or sub-byte; manual casts; no compensated summation |
| Runtime SIMD dispatch        | per call, by capability mask, across x86, Arm, RISC-V, and GPUs                                                                     | load-time CPU detection; one kernel set per process               | compile-time ISA flags only                                                             |
| Packed matrix, GEMM-like     | `packed_matrix` — pack once, reuse across query batches                                                                             | internal opaque packing per GEMM call; no persistent packed form  | no equivalent packed reuse abstraction                                                  |
| Symmetric kernels, SYRK-like | skips duplicate pairs, up to 2x speedup for self-distance                                                                           | `SSYRK`/`DSYRK` for rank-k updates                                | `.selfadjointView` for rank-k updates                                                   |
| Memory model                 | Caller-owned buffers; C++ adds `tensor<T,A>` with per-container allocators                                                          | Caller-managed buffers; no container abstraction                  | Lazy expression templates avoid most temporaries; `aligned_allocator` provided          |

[openblas]: https://github.com/OpenMathLib/OpenBLAS
[eigen]: https://gitlab.com/libeigen/eigen

