Skip to content

Random Number Generators

Thor provides several random number generator (RNG) implementations for Monte Carlo simulations. This page documents the available RNGs, their quality, and how to test them.

Available RNGs

RNG Period Quality Multi-Stream Recommended
xoshiro128++ 2^128 - 1 Excellent Yes Yes (default)
Philox4x32R10 2^128 Excellent Yes Yes (parallel)
PCG32 2^64 Excellent Yes Yes
PCG32fast 2^32 Poor Limited No

xoshiro128++ (Default)

The default RNG for Thor. A fast, high-quality generator with excellent statistical properties.

  • Period: 2^128 - 1
  • State size: 128 bits (4 × 32-bit)
  • PractRand: Passed 32GB single-stream, 8GB multi-stream (16 streams)

Philox4x32R10

A counter-based RNG designed for parallel computing by D.E. Shaw Research. Ideal for GPU workloads.

  • Period: 2^128
  • State size: 128-bit counter + 64-bit key
  • PractRand: Passed 32GB single-stream, 8GB multi-stream
  • Advantage: Statistically independent streams by design

PCG32

The Permuted Congruential Generator with excellent statistical quality.

  • Period: 2^64
  • State size: 128 bits (64-bit state + 64-bit increment)
  • PractRand: Passed 32GB single-stream, 8GB multi-stream (16 streams)
  • Note: Slower on GPU due to 64-bit operations

PCG32fast

A simplified PCG variant optimized for speed. Not recommended due to poor statistical quality.

  • Period: 2^32 (short!)
  • State size: 32 bits
  • PractRand: Failed at 1GB (FPF-14+6/16 test)

Changing the RNG

The RNG is selected at compile time via CMake:

# Use xoshiro128++ (default)
cmake -S . -B build -DTHOR_RNG_TYPE=xoshiro

# Use Philox (best for parallel/GPU)
cmake -S . -B build -DTHOR_RNG_TYPE=philox

# Use PCG32
cmake -S . -B build -DTHOR_RNG_TYPE=pcg32

Valid options: xoshiro (default), philox, pcg32

After changing, rebuild Thor:

cmake --build <build_dir> --target thor

The selected RNG is shown during CMake configuration:

-- RNG type: xoshiro (ID: 0)

Parallel Streams

For parallel simulations, each thread should use an independent stream. Initialize streams using:

RNG rng;
rng.set_seed(global_seed);
rng.set_sequence(thread_id);  // Creates independent stream

All recommended RNGs (xoshiro128++, Philox, PCG32) pass multi-stream statistical tests.

Statistical Testing with PractRand

Thor includes scripts for testing RNG quality using PractRand.

Install PractRand

./scripts/install_practrand.sh

This downloads, builds, and installs PractRand to ~/.local/bin/.

Run Tests

# Quick test (10 seconds)
./scripts/run_practrand.sh 10s xoshiro

# Thorough test (1GB of data)
./scripts/run_practrand.sh 1GB xoshiro

# Multi-stream test (4 interleaved streams)
./scripts/run_practrand.sh 8GB xoshiro 4

# Test all RNGs
./scripts/run_practrand.sh 1GB all

Interpreting Results

  • "no anomalies": RNG passed all tests
  • "unusual": Minor deviation, generally acceptable
  • "suspicious": Worth investigating but not a failure
  • "FAIL": RNG has statistical flaws, do not use

CI Testing

Thor includes automated CI testing for RNG quality. A weekly GitHub Actions job runs PractRand tests on all "reliable" RNGs.

Reliable RNGs

Each RNG class has a static constexpr bool reliable field indicating whether it should be tested in CI:

RNG Reliable Reason
xoshiro128++ Yes Passed 32GB single + 8GB multi-stream
Philox4x32R10 Yes Passed 32GB single + 8GB multi-stream
PCG32 Yes Passed 32GB single + 8GB multi-stream
PCG32fast No Failed at 1GB
Ranq1 No Comparison RNG only
Rascas No Catastrophic failures

Workflow Details

  • Schedule: Weekly on Sundays at 3:00 AM UTC
  • Path triggers: Runs when src/rngs/** or test scripts are modified
  • Test: 1GB PractRand for each reliable RNG
  • Manual trigger: Available via workflow_dispatch

To run locally:

# Quick test
./scripts/run_practrand.sh 256MB reliable

# Full CI test
./scripts/run_practrand.sh 1GB reliable

Comparison RNGs

Thor also includes RNG implementations from other projects for comparison testing:

RNG Source Quality Notes
Ranq1 COLT (Numerical Recipes) Adequate Passed 32GB, lacks proper stream support
Rascas RASCAS project Broken Catastrophic failures, do not use

These are available in tests/rng_stdout_generator but not recommended for production use.