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:
The selected RNG is shown during CMake configuration:
Parallel Streams
For parallel simulations, each thread should use an independent stream. Initialize streams using:
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
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.