Neural evaluation
A 768-wide HalfKAv2_hm network with 32 king buckets. Its int16 accumulators follow every move incrementally, and the int8 layers behind them run on AVX-512 VNNI or AVX2.
UCI chess engine NNUE C++23
A free, open-source chess engine. A neural network judges each position, a modern alpha-beta search looks ahead, and every change to how it plays is measured over thousands of games before it ships.
GPL-3.0 Windows, Linux and macOS works in any UCI interface
Inside the engine
Luminex pairs a quantized neural network with a hand-crafted fallback, behind a search built from the techniques that define modern engines.
A 768-wide HalfKAv2_hm network with 32 king buckets. Its int16 accumulators follow every move incrementally, and the int8 layers behind them run on AVX-512 VNNI or AVX2.
Principal variation search with aspiration windows, null-move pruning, singular extensions, ProbCut, razoring, futility and late-move pruning, and late-move reductions.
Killer and counter moves, continuation and capture history, static exchange evaluation, and correction history that tunes static scores from what the search finds.
Lazy SMP: each search thread keeps its own network accumulators and shares one transposition table with the others.
Without a network file, a hand-crafted evaluation takes over: material, piece-square tables, mobility, passed pawns and king safety. The engine says so instead of failing quietly.
Load it in Cute Chess, Arena, Banksia, En Croissant or any other UCI interface. MultiPV, pondering, win/draw/loss output and Polyglot opening books are built in.
The network
A move changes only the pieces that moved, so the first layer is updated with a few vector additions instead of being recomputed. Select a layer to see what it does.
Every piece on its square, seen from each side and indexed by one of 32 king buckets (HalfKAv2_hm). About 32 of the 24,576 inputs are active in a position.
The feature transformer: one int16 accumulator per side. A move adds and subtracts a few weight rows; a king move into a new bucket rebuilds that side.
Side to move first, then the opponent. Each value is clamped to [0, 1] and squared, the squared clipped ReLU that gives the small layers more to work with.
int8 weights. On AVX-512 VNNI hardware one instruction multiplies and accumulates 64 byte pairs.
int8 weights followed by another SCReLU.
A score in centipawns from the side to move's point of view, which the search uses at every node it evaluates.
By distillation: positions from Leela Chess Zero self-play, each relabeled with the score of a deep Stockfish search. The loss weights quiet positions, the ones the search actually evaluates, above captures and leaves positions in check out.
The released network, luminex_sfq_i8.nnue, was trained this way. The data for the next round is public.
Testing
Luminex runs its own OpenBench instance. A candidate change plays the current engine until a sequential probability ratio test can tell a gain from noise.
Each change comes with the mechanism it relies on and how it was checked.
Continuous integration compiles every target on Linux, Windows and macOS.
Games at 10+0.1 against the current engine, until the test accepts a gain between 0 and 5 Elo or rejects it.
A pass merges. Results inside the error margin are decided openly, numbers in the commit.
Download
Older CPUs: Windows compatibility build and Linux SSE4.2 build.
Keep luminex_sfq_i8.nnue next to the program and the engine loads it by itself. Add Luminex to your chess interface as a UCI engine, or talk to it directly:
uci
setoption name Threads value 4
setoption name Hash value 256
isready
position startpos moves e2e4
go movetime 2000
With a C++23 compiler (GCC 13, Clang 15 or MSVC 2022 and newer) and CMake 3.20 or newer:
git clone https://github.com/changcheng967/Luminex.git
cd Luminex
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release