Skip to content

jorgenhanssen/grail

Repository files navigation

Grail

CCRL 40/15 License: GPL-3.0 Rust

Grail is a hobby chess engine written in Rust. Named after the quest for the Holy Grail, it represents the search for the elusive, perfectly solved game. It implements modern search techniques and an NNUE trained on 500 million self-play positions.

Usage

Grail is a command-line engine designed for Standard Chess. It requires a UCI-compatible chess GUI (such as Arena, BanksiaGUI, or Cutechess) to play.

Getting Started

  1. Download: Grab the zip for your OS from the Releases page and extract it.
  2. Install: Open your chess GUI and add the right binary (see table below).
  3. Play: Start a game or analysis session!

Which binary should I use?

Each release includes builds optimized for different CPU architectures:

OS Binary Supported CPUs
Linux / Windows x86-64-v4 Intel Skylake-X/Ice Lake+ (2017+), AMD Zen 4+ (2022+)
Linux / Windows x86-64-v3 Intel Haswell+ (2013+), AMD Zen 2+ (2019+)
macOS arm64 Apple Silicon (M1/M2/M3/M4)

Tip

Not sure? On Windows/Linux, try x86-64-v4 first for best performance. If the engine crashes on startup, use x86-64-v3 instead - it has wider compatibility.

For technical details, see x86-64 Microarchitecture Levels.

A note for macOS users

macOS blocks unsigned binaries by default. Apple wants me to pay $99/year to sign the binary so you can avoid typing this command. So instead, after downloading, just run:

xattr -d com.apple.quarantine ~/Downloads/grail-arm64

and you should be able to run it! 🍎

Configuration

Once added to your GUI, you can configure the engine via the UCI options:

  • Hash: Size of the transposition table in MB (Default: 256).
  • Threads: Number of search threads (Default: 1).
  • MultiPV: Number of principal variations to search (Default: 1).
  • NNUE: Toggle between Neural Network (NNUE) and Hand-Crafted (HCE) evaluation (Default: true).
  • Move Overhead: Time buffer in milliseconds to account for communication lag (Default: 10).

The engine supports standard time controls (increment, sudden death, moves to go) and analysis modes (fixed depth, infinite).

Play Against Grail Online

You can challenge the latest version of Grail on Lichess, running on a 1 vCPU Northflank instance with 256 MB hash.

For Developers

Building from Source

Prerequisites: Rust nightly toolchain (Grail uses portable_simd and generic_const_exprs).

Quick Start:

git clone https://github.com/jorgenhanssen/grail.git
cd grail
rustup override set nightly
make grail

This builds the release binary at target/release/grail.

Build Targets

The project includes a Makefile for convenience:

  • make grail (default): Builds the release binary.
  • make tunable: Builds with exposed parameters for SPSA tuning.
  • make generate: Builds the data generation tool for NNUE training.
  • make train: Builds the NNUE trainer (auto-detects CUDA/Metal).
  • make clean: Cleans the build directory.

Benchmarking

Runs depth-15 searches on standard perft positions:

cargo bench --bench search

For profiling with flamegraph:

CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph --bench search -- --bench

NNUE Data Generation & Training

Grail includes tools to generate training data and train its own NNUE networks.

Data Generation

Generate self-play games to create a dataset:

make generate
./target/release/generate --book books/your_opening_book.epd

Arguments:

  • --book: Path to an opening book in EPD format (required).
  • --depth: Search depth for each move (default: 10).
  • --pv-lines: Number of PV lines to search at each decision point (default: 1).
  • --threads: Number of threads (default: number of logical CPUs).
  • --nnue: Use NNUE for evaluation instead of HCE (default: false).

Generated data is saved to nnue/data/YYYY-MM-DD-HH:MM.csv.

Training

Train a new network using the generated data:

make train  # Auto-detects GPU support (CUDA/Metal)
./target/release/train

The trainer loads all CSV files from nnue/data/ and saves the best model to nnue/model.safetensors.

Arguments:

  • --batch-size: Batch size for training (default: 8192).
  • --learning-rate: Initial learning rate (default: 0.001).
  • --epochs: Number of epochs to train (default: 100).
  • --workers: Number of worker threads for data loading (default: 4).
  • --val-ratio: Fraction of data to use for validation (default: 0.1).
  • --test-ratio: Fraction of data to use for testing (default: 0.01).
  • --lr-decay: Learning rate decay factor (default: 0.95).
  • --patience: Epochs without improvement before early stopping (default: 2).
  • --shard-size-mb: Size of each data shard in megabytes (default: 500).
  • --wdl: WDL blending weight, 0.0 = pure eval, 1.0 = pure WDL (default: 0.3).
  • --init-model: Save a randomly initialized model and exit.

Acknowledgements

  • Chess Programming Wiki - A very helpful resource for chess programming concepts and techniques.
  • Thanks to various engine testers, such as the CCRL, for testing and ranking Grail.
  • Opening books in /books sourced from the Stockfish opening books and the computer chess community.

About

Hobby UCI chess engine written in Rust

Resources

License

Stars

Watchers

Forks

Contributors

Languages