NanoGEMM ⚡
NanoGEMM is a minimalist, bare-metal General Matrix Multiplication (GEMM) engine designed for sub-microsecond CPU inference and high-performance computing in Python.
Built with direct AVX2 / FMA (256-bit SIMD) assembly-level register tiling and cache blocking, NanoGEMM eliminates the heavy function-call dispatch, thread-pool barriers, and memory-packing overhead of heavyweight BLAS libraries (OpenBLAS, MKL) for small-to-medium tensors.
🚀 Performance Benchmarks
Measured on Intel/AMD x86-64 CPU (AVX2 + FMA) against NumPy 2.2.3 (single-precision float32):
| Matrix Dimension | NumPy 2.2.3 Latency | NanoGEMM Latency | Speedup Factor | NanoGEMM Throughput |
|---|---|---|---|---|
16 x 16 |
3.21 µs |
1.23 µs (C: 0.65 µs) |
🚀 2.83x FASTER | 2.83 GFLOPS |
32 x 32 |
5.75 µs |
2.74 µs (C: 2.18 µs) |
🚀 2.26x FASTER | 15.13 GFLOPS |
64 x 64 |
18.70 µs |
17.76 µs (C: 16.39 µs) |
🚀 1.10x FASTER | 27.08 GFLOPS |
128 x 128 |
114.07 µs |
182.46 µs |
0.60x |
23.42 GFLOPS |
256 x 256 |
426.24 µs |
1501.24 µs |
0.28x |
22.35 GFLOPS |
💡 Why is NanoGEMM faster on small/medium matrices?
Traditional BLAS engines incur 3–10 µs of fixed overhead per invocation due to dynamic runtime dispatch, argument sanitization, thread synchronization, and packing buffers. NanoGEMM utilizes a zero-allocation, direct register-tiled microkernel that executes in sub-microsecond time immediately upon invocation.
⚙️ Benchmark Environment & Test Configuration
| Parameter | Specification |
|---|---|
| CPU Architecture | x86-64 with AVX2 (256-bit SIMD) + FMA3 support |
| Execution Model | Single-Core / Single-Threaded (1 Thread) for NanoGEMM (zero thread-pool overhead) |
| NumPy Baseline | NumPy 2.2+ linked against OpenBLAS (standard runtime) |
| C Compiler | GCC (-O3 -mavx2 -mfma) / MSVC (/O2 /arch:AVX2) |
| Methodology | Median latency across 10,000 iterations per size with cache pre-warming |
| Data Type | IEEE-754 Single-Precision (float32), contiguous C-order layout |
📌 Single-Thread Design Note: NanoGEMM runs strictly on a single CPU core without thread pools, pthreads, or mutex barriers. For small matrices ($16 \times 16$ to $64 \times 64$), thread synchronization in OpenMP costs more cycles than the matrix multiply itself. NumPy/OpenBLAS incurs dispatch latency, whereas NanoGEMM enters CPU registers directly.
🛠 Architectural Design
1. Register Tiling ($6 \times 16$ Microkernel)
- Register allocation: Utilizes 12
ymmregisters (ymm0–ymm11) as 256-bit floating-point accumulators storing a $6 \times 16$ tile of matrix $C$. - Vector broadcast & FMA: Two
ymmregisters load vectors from $B$, while individual scalar elements of $A$ are broadcast acrossymmusing_mm256_set1_psand accumulated via fused multiply-add (_mm256_fmadd_ps). - Zero Spilling: Fits completely inside the 16 available x86-64 YMM registers without stack eviction.
2. Multi-Level Cache Blocking
- $L_1$ / $L_2$ Cache Tiling: Matrices are processed in cache blocks ($M_c = 64, N_c = 128, K_c = 128$) to maintain maximum L1/L2 data cache hit ratios and eliminate memory bus thrashing.
- Vectorized Edge Handling: Arbitrary matrix dimensions (non-multiples of 6 or 16) are processed using boundary SIMD edge loops without padding or buffer allocations.
Matrix A (M x K) Matrix B (K x N)
[ . . . . . . . . ] [ . . . ymm0 . . . ]
[ . . . . . . . . ] [ . . . ymm1 . . . ]
[ a0 a1 a2 a3 . . ] x [ . . . . . . . . ]
[ . . . . . . . . ] [ . . . . . . . . ]
[ . . . . . . . . ]
│ │
└──────────────┬──────────────┘
▼
Matrix C (6 x 16 Tile)
[ ymm0 ymm1 ] -> Row 0
[ ymm2 ymm3 ] -> Row 1
[ ymm4 ymm5 ] -> Row 2
[ ymm6 ymm7 ] -> Row 3
[ ymm8 ymm9 ] -> Row 4
[ ymm10 ymm11 ] -> Row 5
📦 Installation & Quickstart
Installation via PyPI (Recommended)
pip install nanogemm
# or with uv
uv add nanogemm
Python Compatibility: Fully tested and verified across Python 3.9 through 3.15 (including 3.15.0rc2).
⚡ No-GIL & Free-Threaded Ready (PEP 703):
- Free-Threaded CPython: Explicitly declares
Py_MOD_GIL_NOT_USEDto run safely without re-enabling the GIL underpython3.13t,3.14t, and3.15t.- GIL-Releasing Operations: Automatically releases the GIL (
Py_BEGIN_ALLOW_THREADS) during hardware SIMD execution, allowing Python threads (threading.Thread,ThreadPoolExecutor) to run matrix multiplications concurrently across multiple CPU cores without lock contention.
Build from Source
git clone https://github.com/eminsk/nanogemm.git
cd nanogemm
pip install -e .
Python Usage
import nanogemm as ng
import numpy as np
# Verify SIMD hardware acceleration
print("Active ISA:", ng.get_simd_isa())
# Output: Active ISA: AVX2+FMA (256-bit SIMD, 6x16 register tiling)
# Allocate input matrices
A = np.random.randn(32, 64).astype(np.float32)
B = np.random.randn(64, 128).astype(np.float32)
# Direct hardware-accelerated MatMul: C = A @ B
C = ng.matmul(A, B)
# Or with pre-allocated zero-copy output buffer for maximum performance:
out = np.empty((32, 128), dtype=np.float32)
ng.matmul(A, B, out=out)
# Standard BLAS SGEMM interface: C = alpha * (A @ B) + beta * C
res = ng.sgemm(A, B, alpha=2.0, beta=0.5, c=out)
🧪 Testing & Verification
Run the comprehensive correctness test suite comparing NanoGEMM with NumPy reference outputs across random uniforms, normals, non-square dimensions, and prime shapes:
python tests/test_correctness.py
Run the official benchmark against your installed NumPy BLAS:
python benchmarks/bench_vs_numpy.py
⚡ Standalone Flat Assembler (FASM) 32-bit & 64-bit Engines
NanoGEMM includes native standalone assembly implementations written in Flat Assembler (FASM) for both 64-bit and 32-bit architectures in the asm/ directory:
- x86-64 Engine (
asm/nanogemm64.dll,asm/test_nanogemm64.exe):- Microkernel with $4 \times 16$ and $4 \times 8$ register-tiled AVX2+FMA instructions (
vfmadd231ps,vbroadcastss,vmovups). - Complies strictly with the Microsoft x64 ABI (preserving non-volatile registers
RBX,RSI,RDI,R12–R15,XMM6–XMM15). - Peak throughput exceeding 38–40 GFLOPS on a single CPU core.
- Microkernel with $4 \times 16$ and $4 \times 8$ register-tiled AVX2+FMA instructions (
- x86 32-bit Engine (
asm/nanogemm32.dll,asm/test_nanogemm32.exe):- Vectorized $4 \times 4$ SSE2 microkernel (
movups,shufps,mulps,addps) usingcdeclcalling convention. - Compatible with all 32-bit x86 environments and 64-bit Windows via WoW64 with zero external dependencies.
- Delivers 13–15 GFLOPS in pure 32-bit mode.
- Vectorized $4 \times 4$ SSE2 microkernel (
Building & Running FASM Tests
:: Build all 4 binaries and run native executable suites
cd asm
build.bat
:: Run Python verification and NumPy comparison suite
python tests/test_fasm.py
🌐 High-Performance Systems Ecosystem
NanoGEMM is developed by @eminsk as part of an engineering ecosystem focused on low-level hardware performance, assembly programming, and native desktop computing:
- 🎥 screenvideo — Lightweight desktop screen recorder featuring WASAPI loopback audio and a standalone pure x64 Flat Assembler (FASM) native edition.
- 📊 xlsx_vievers — Desktop spreadsheet processor with 80+ formula functions, Chart Wizard, and hardware-accelerated SIMD SSE2 math engine.
- 📈 yfinance-ta-patterns — Candlestick pattern scanner and AI ranking suite powered by TA-Lib and quantitative backtesting.
- 🔍 StackOverflowAPI — Desktop client for Stack Overflow built with CustomTkinter and native FASM x64 search client.
📄 License
MIT License — Copyright (c) 2026 eminsk.
Metadata
Release files for nanogemm 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nanogemm-0.3.2.tar.gz | 79.4 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| nanogemm-0.3.2-cp315-cp315-win_amd64.whl | CPython 3.15 | CPython 3.15 | Windows x86-64 | Details |
| nanogemm-0.3.2-cp314-cp314-win_amd64.whl | CPython 3.14 | CPython 3.14 | Windows x86-64 | Details |
| nanogemm-0.3.2-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
| nanogemm-0.3.2-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
Total release size: 324.6 kB
Release files / nanogemm-0.3.2.tar.gz
| Download URL | nanogemm-0.3.2.tar.gz |
|---|---|
| Size | 79.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7eb6a2b42bc6a687feb1fc5229c8c7213da607c6dae69687830e11e900544b78
|
|
BLAKE2b-256 checksum How to use checksums |
f8cba0fd43913cabc90556940b1374378c83df0d8917e65cc8bc452249187fa2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / nanogemm-0.3.2-cp315-cp315-win_amd64.whl
| Download URL | nanogemm-0.3.2-cp315-cp315-win_amd64.whl |
|---|---|
| Size | 62.0 kB |
| Tags | CPython 3.15 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
0d8243610c43b46d8852467077968729c048099e724ab4ec47b67e8718048084
|
|
BLAKE2b-256 checksum How to use checksums |
f93cc46b5b6ad6a83194ec28971e41c02dea21c61dec049b849bf6d481d1bbdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / nanogemm-0.3.2-cp314-cp314-win_amd64.whl
| Download URL | nanogemm-0.3.2-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 62.0 kB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
3cccc41c04e70e8677be40908e217ed1aff1452fb7eaec7d2d2237d423ab5e21
|
|
BLAKE2b-256 checksum How to use checksums |
96d1ca4ba251efd81490ec127ce540112a8564747ffbce7ebf4297dd781bdece
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / nanogemm-0.3.2-cp313-cp313-win_amd64.whl
| Download URL | nanogemm-0.3.2-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 60.6 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
40072b073a851486fee600173298ed4a6f59115cc4be4030e0c45e32bcb482ee
|
|
BLAKE2b-256 checksum How to use checksums |
14435eab531b073dc6a2fc008d233082ec645225acaa51135dc329af8a4b0447
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / nanogemm-0.3.2-cp312-cp312-win_amd64.whl
| Download URL | nanogemm-0.3.2-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 60.6 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e72cf35b0f89f13557dd8b67e61f339141083c1cec4095d6dee9344b8079a466
|
|
BLAKE2b-256 checksum How to use checksums |
652391cafecbd3e2bf81867adf2e2333391afa1f51f39d6203e3fcebd407b6b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|