fcmaes-rust
Choosing an optimization tool? Start with the shared solver-selection and agent guide or the optimization ecosystem overview. This repository supplies native Rust black-box, multi-objective and quality-diversity optimizers, Python bindings, and a source-built job worker. The guide also covers Python objectives, LP/MIP and smooth constrained NLPs.
Slides (PDF) · Book (PDF) · YouTube video
fcmaes-rust is a native Rust implementation of fast, parallel,
gradient-free optimization algorithms and selected fcmaes application
examples. The optimizer implementation in fcmaes-core is 100% Rust: it does
not compile, link, load, or call the original fast-cma-es C++ implementation.
Optimizer numerics, retry coordination, random-number generation, fitness
evaluation, and parallel execution all run in Rust.
fcmaes-rust reimplements the algorithm set of
fast-cma-es natively in Rust
rather than wrapping it, and is an alternative for both Rust and Python
users via its PyO3 API. For objectives written in Python, prefer the Python library
fast-cma-es: it uses
multiprocessing, so Python objectives evaluate in parallel. The PyO3
API here is the better fit when the objective itself is in Rust.
In this project, “port” means that algorithms were translated, reimplemented, and tested in Rust. It does not mean an FFI wrapper around the old C++ code; the public API documentation explains the algorithms through their primary literature and records implementation-specific behavior explicitly.
The repository is a standalone Cargo workspace. GTOP models and example objective functions also execute in Rust. This includes the Mazda mass and constraint response surfaces: their compact model data is embedded in the example crate and evaluated by native Rust code. The Buckingham–Pi example also implements dimension-matrix enumeration, numerical nullspace analysis, regression, and continuous-exponent optimization directly in Rust; it has no BuckinghamPy dependency.
Experimental surrogate optimization
The new source-only fcmaes-surrogate crate and fcmaes.surrogate/1 job
profile implement small-budget exact-GP optimization with synchronous batches
and a cancellable Rust simulation API. Current limits are 32 coordinates,
256 new plus warm observations, and eight inner threads per task. See the
API guide (it links the executable tutorial),
measured results and
reviewed roadmap. Thompson-sampling TuRBO, asynchronous scheduling and
large-budget handoff are future milestones. In an
equal-budget comparison with
BoTorch, egobox, scikit-optimize and Optuna it reached the lowest median
final regret of the GP methods on four of five small problems at 1–3 orders
of magnitude less proposal time; for separable or many-modal problems with
tens of variables, BiteOpt retry (fcmaes.retry/1) remained better.
Core design principle: improve results for the same wait
Independent retry turns otherwise idle CPU cores into additional chances to
find a better solution before the user’s deadline. Many useful stochastic,
local, and third-party optimizers execute one search on one thread. The generic
fcmaes_core::retry coordinator runs independent instances concurrently and
returns the best retained result; the wrapped optimizer does not have to be an
fcmaes implementation.
The controlled GTOP equal-wall experiment
wrapped the external, serial cmaes crate and compared one restart lane with
16 lanes on a 16-physical-core Ryzen 9 9950X. Both arms waited approximately
4.000 seconds per pair. Across 100 paired seeds on each of seven problems,
retry improved the mean returned objective on 7/7 problems. It won
86–96/100 pairs, close to the roughly 94% expected when independent retry gets
about 15 times as many starts:
| Equal-wall evidence | Serial external CMA-ES | Through fcmaes retry |
|---|---|---|
| User-visible wall time | 4.000109–4.000150 s | 4.000440–4.000523 s |
| Mean active cores | 1.00 | 15.99–16.00 |
| Problems with the better mean | 0/7 | 7/7 |
| Cassini1 target successes | 38/100 | 100/100 |
This is the practical library design claim: on that fixed machine and protocol, retry bought better mean quality for the same wait by spending more aggregate CPU work. The paired win rate mainly confirms that the scheduler delivered those extra independent opportunities; the mean and sdev quantify their effect on the returned distribution. This is not a theorem for every objective or budget. The full quality, wall-time, and work-accounting tables are in the benchmark report; variability fell on five problems but rose on SAGAS and Tandem.
Two complementary ways to spend the cores
Retry is not the only parallelism boundary. All population-based fcmaes-core optimizers expose ask/tell or an equivalent whole-population batch interface. The caller asks for candidates, evaluates them concurrently on CPU workers, a GPU, a simulator farm, or remote services, and tells the optimizer the ordered results. This often gives the largest wall-time benefit when one objective evaluation is expensive.
| Parallel strategy | Unit of parallel work | Best fit | Main effect at fixed wall time |
|---|---|---|---|
Independent retry | Complete optimizer runs | Multimodal problems; serial internal algorithms; cheap to moderately costly objectives | Explores more independent basins and improves the distribution of the returned best |
| Population ask/tell | Candidates from one optimizer generation | Expensive simulations, training jobs, hardware tests, or remote evaluations | Advances one search through more generations during the same wait |
DE, active CMA-ES, CR-FM-NES, PGPE, BiteOpt, and MODE provide direct ask/tell interfaces. MAP-Elites and Diversifier provide equivalent batch evaluators and ordered archive updates. Dual Annealing is the deliberate exception: its next point depends on the preceding point and score, so it has no population to evaluate concurrently. Retry can still parallelize independent Dual Annealing runs. Both forms can be combined, but partition the available workers between outer retries and inner batch evaluation to avoid oversubscription. See the optimizer guide.
Implementation facts
| Feature | Implementation |
|---|---|
| Optimizer core | 100% native Rust in fcmaes-core |
| Legacy C++ optimization backend | None; no C++ library is compiled, linked, loaded, or invoked |
| Core build | Standard Cargo build; no project build.rs, CMake, or C/C++ compiler |
| Parallelism | Independent retry workers plus ask/tell and ordered Rayon population batches |
| Objective functions | Native Rust closures and batch evaluators |
| Python integration | Optional PyO3 extension that exposes the Rust core; Python is not an optimizer backend |
To build only the reusable optimizer library, a Rust toolchain is sufficient:
cargo build --release -p fcmaes-core
This statement deliberately applies to the optimizer core. Building every
optional workspace component can additionally require Python for fcmaes-py
and native tooling pulled in by data-compression or network dependencies used
by examples. Those integrations do not contain or restore the historical C++
optimizer backend.
Workspace
| Crate | Purpose |
|---|---|
fcmaes-core | Optimizers, fitness handling, RNG, retry, multi-objective optimization, and quality diversity |
fcmaes-gtop | Internal native GTOP objective library shared by the examples and Python package |
examples (fcmaes-examples) | Native GTOP problems, application objectives, benchmarks, and executable examples |
fcmaes-py | Optional PyO3 extension for embedding the Rust implementation in a Python package |
foundations/ | Standalone standard suites, Lennard-Jones scaling, audited quality indicators, and seven compact lessons |
tutorials/* | Twenty-two standalone application workspaces spanning simulation, astrodynamics, circuits, mechanics, energy, routing, hydraulics, ML, and other domains; see the tutorial index |
Only two registry artifacts are published: fcmaes-core on crates.io and the
fcmaes-rust binding distribution on PyPI. fcmaes-gtop is an internal
source dependency marked publish = false; examples/ and tutorials/ are
available only from this GitHub repository and are not included in either
registry package.
The application tutorials are intentionally not root workspace members. Each keeps its application-specific dependencies, artifacts, and lockfile isolated; run its Cargo commands from that tutorial directory.
New users can start with the
Foundations guide: eight classic scalar functions,
ZDT1–4/ZDT6, DTLZ1–7, a Lennard-Jones scaling study, a seven-step lesson ladder, and exact/typed-sampled
multi-objective quality indicators. foundations/ is a user guide rather than
an application tutorial, so the simulator-in-the-loop tutorial count remains
twenty-two.
The optimizer-boundary guide records why the core stops at bounded gradient-free global methods and evidence utilities. Corrected paired experiments keep Nelder–Mead, Bayesian optimization, and gradient solvers behind the retry adapter boundary instead of adding them as core algorithms or dependencies.
Tutorial evidence map
The tutorial index is the exhaustive catalogue. This shorter map highlights the main experimental decisions and validation results.
Multi-objective and quality-diversity evidence
Seventeen application tutorials retain multi-objective optimization. MAP-Elites campaigns are recorded for NeXosim, Rapier, ReBop, Brahe, atmospheric source localization, room ventilation, RustPower, sindr circuit design, quadruped locomotion, phased-array register codebooks, and energy-hub sizing.
- Descriptor redesign can help. In RustPower, direct decision variables produced only 4% archive coverage. Emergent behavior coordinates reached 68% mean coverage over three seeds at the same 100k-evaluation budget. Constrained MODE remains primary because the near-unique asset architecture survived the descriptor change.
- A completed QD campaign can still fail its evidence gate. The SmartCore study separates fixed-fold tuning, model selection, and frozen final evaluation. Replacing two highly correlated descriptors increased range-study occupancy from 16/400 to 91/400 cells, but the subsequent 49.0%-coverage campaign still failed held-out niche retention.
- Accepted descriptor gates. The phased-array study reaches 40.83% coverage and 95.07% holdout niche retention on its corrected 12×10 grid. The energy-hub study follows its accepted native-grid pilot with a 64-elite portfolio and an independent 8,760-hour chronological hydrogen replay.
- Rejected descriptor gates are published too. The field-service, water-network, and truss-sizing studies reject unstable or weakly retained repertoires instead of presenting them as successful QD results.
Selected application protocols
- Policy search: the neural-controller tutorial compares PGPE and CR-FM-NES on a 118-parameter controller using common scenarios, disjoint validation, and a frozen 1,024-scenario final test.
- Fixed-sequence astrodynamics: the GTOC1 tutorial applies coordinated DE–CMA-ES and incumbent-seeded retry to the real 87-variable EVEEEJSJA low-thrust tour. It explains why its VSOP2013 result is not an official DE405 re-scoring.
- Split-brain route discovery: the GTOC1 route-search tutorial keeps a provider-independent agent boundary. Its seed-42 L0 audit finds 15 admissible random routes, 24 evolutionary routes, and none from MiniMax-M3. The three promoted random controls all fail L1 closure, so independent seeds, matched promotion, and a validated L2 finalist remain open requirements.
- Circuits and optics: the sindr study combines interpolated AC features, retry, MODE, and an E12 catalogue. The gate-driver front passes timestep refinement and a 49-design ngspice comparison. The optical-lens study validates its dependency-free ray tracer before optimizing a Cooke-triplet front.
- Robust locomotion: the quadruped tutorial makes quality diversity the primary result and uses five-seed held-out terrain replay rather than treating training coverage as robustness.
- Specialist baselines: the network-coverage tutorial validates its kernel and certificates before optimization. Its marginal-greedy prefix frontier dominates every finite MODE point, so the tutorial recommends the specialist method for that frozen submodular formulation.
Reproducibility
Tutorial result directories contain the canonical raw evidence and generated
SVGs needed to reproduce the published pages from a clean clone. Schema-driven
tutorials use run.json; room ventilation and neural policy search also check
aggregate CSVs and plots spanning multiple seeds and validation studies.
Implemented algorithms include Differential Evolution, active CMA-ES,
CR-FM-NES, PGPE, Dual Annealing, BiteOpt, MODE, CVT-MAP-Elites, the
Diversifier, independent retry, coordinated retry, and weighted
multi-objective retry. ParetoArchive2D keeps the exact non-dominated front
and hypervolume of all points evaluated on a two-objective problem, next to
any optimizer (guide).
The example crate includes GTOP mission optimization, Mazda factory-design objectives, stock-strategy optimization, material-flow planning, flexible job-shop and harvesting, multi-UAV task assignment, spherical t-design, transfer scheduling, Buckingham–Pi dimensional analysis, damped control, F-8 aircraft control, and Lotka-Volterra control.
Quick start
Install the released packages
Inside a Rust application, add the published optimizer library:
cargo add fcmaes-core
The crate is imported in Rust as fcmaes_core.
Python users install the published binding distribution with:
python -m pip install fcmaes-rust
It imports as fcmaes_rust; its optimizer backend is the same native Rust
implementation:
import fcmaes_rust
print(fcmaes_rust.__version__)
print(fcmaes_rust.phase1_build_info())
A compatible prebuilt wheel requires neither a local Rust toolchain nor a C/C++ compiler. Published wheels support CPython 3.11 through 3.13. Building the Python package from its source distribution does require Rust.
Install from source
Everything in this repository builds from source with Rust alone; Python is needed only for the Python package. Requirements:
- git and Rust 1.88 or newer (
rustupfrom https://rustup.rs). Rust 1.88 is the tested minimum for the edition-2024 source and the locked dependency set; CI checks it explicitly. - For the Python package: CPython 3.11 to 3.13,
pip, and the build backendmaturin(installed automatically bypip install .).
Our own dependencies are fetched by Cargo, so no second checkout is needed:
the job worker, the experiment runner and the GTOC1 tutorial depend on the
shared job API, optimization-jobs,
as a git dependency at the revision pinned in Cargo.toml (needs network
access to GitHub on the first build; cargo fetch --locked prepares an
offline build). fcmaes-core and the Python package depend on crates.io
crates only.
git clone https://github.com/dietmarwo/fcmaes-rust
cd fcmaes-rust
cargo test --workspace --locked
cargo build --release --workspace --locked
Python package from the checkout, in a virtual environment:
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install . # builds the Rust extension
python -c "import fcmaes_rust; print(fcmaes_rust.phase1_build_info())"
For development, python -m pip install "maturin>=1.7,<2" numpy scipy pytest
and maturin develop --release --locked install an editable build;
python -m pytest runs the binding tests. Without a matching wheel,
pip install fcmaes-rust also builds from the source distribution and then
needs the Rust toolchain.
Unreleased fcmaes-core changes are available to other Rust projects as a
git dependency:
[dependencies]
fcmaes-core = { git = "https://github.com/dietmarwo/fcmaes-rust" }
The job worker and the runner build together
(cargo build --release --locked -p optimization-runner -p fcmaes-job-worker);
see the job API guide.
RELEASING.md describes the registry releases.
Run a small native optimization:
cargo run --release -p fcmaes-examples --bin jobshop -- --evals 2000
Run a GTOP retry workload:
cargo run --release -p fcmaes-examples --bin gtop-examples -- \
--problem cassini1 --retries 16 --evaluations 5000 --workers 16 --seed 1
With fcmaes-rust installed, run the repository’s active CMA-ES Python
example with:
python examples/python/test_cma.py
Documentation
- Rendered user guide and tutorial book
- Generated
fcmaes-coreAPI reference - AI problem-solving context, with its task index (“Start here”), and the short agent guide (build, test and documentation checks)
- Security and numerical-integrity reporting
- Getting started
- Choosing an optimizer
- Architecture and implementation boundaries
- Optimizer guide
- Retry and multi-objective retry
- Native experiment runner (
fcmaes-run) - Shared optimization job API (
optimization-run, andoptimization-mcpfor agents) - Native examples and benchmarks
- Combinatorial encoding cookbook
- Buckingham–Pi dimensional-analysis example
- Native Rust application-optimization tutorials
- NeXosim production-line tutorial
- Rapier trebuchet tutorial
- ReBop stochastic-oscillator tutorial
- Split-brain oscillator topology-search tutorial
- Brahe satellite-constellation tutorial
- RustPower voltage-control tutorial
- Atmospheric source-localization tutorial
- Room-ventilation optimization tutorial
- ML hyperparameter-optimization tutorial
- Neural-controller policy-search tutorial
- GTOC1 “Save the Earth” tutorial
- Split-brain GTOC1 route-search tutorial
- sindr circuit-design tutorial
- thevenin transient gate-driver tutorial
- Pure-Rust optical lens-design tutorial
- Rapier quadruped gait-repertoire tutorial
- Hardware-quantized phased-array codebook tutorial
- Bilevel energy-hub sizing tutorial
- Random-key field-service routing tutorial
- Water-network pump-scheduling tutorial
- Truss topology and catalogue-section sizing tutorial
- Weighted network-coverage tutorial
- Optional PyO3 bindings
- Release history
- Publishing checklist
- Development and testing
- Recorded native benchmark results
Generate the complete API reference with:
cargo doc --workspace --no-deps --open
Build the rendered guide locally with mdBook 0.5.4:
python scripts/check_doc_consistency.py
python scripts/build_book.py
python scripts/check_book_links.py
The builder stages canonical repository files under target/; it does not
maintain duplicate copies of the guides or tutorial results.
Optimizer comparison
Equal-budget GTOP results
The reproducible GTOP optimizer comparison
uses 100 experiments per problem and a common 240,000-evaluation cap. fcmaes
has the best mean optimum on six of seven problems. Its independent BiteOpt
retry arm has the lowest mean optimizer wall time per actual evaluation on all
seven, at 142–310 ns/evaluation. Raw total wall time is not the headline speed
measure because plain cmaes CMA-ES stops protectively after using only
7.4%–58.8% of its allowance. The exception in mean solution quality is Tandem,
where adaptive BIPOP-CMA-ES leads the equal-budget table but does not reach the
-1493 target.
Tandem stress test
In the pre-registered Tandem stress test, BIPOP-CMA-ES reached 0/1,000 targets: its best result was -1410.050665 after 9,466,290,846 actual evaluations. In contrast, fcmaes coordinated DE→CMA retry reached the target in 85/100 experiments with a mean of 230,727,025 evaluations. Across their complete campaigns, the 100 fcmaes experiments used 23.07 billion actual evaluations, 2.44 times the 9.47 billion used by the 1,000-retry stress test. These are separate budget regimes and allocations: the equal-budget table supports the controlled comparison, while the larger coordinated result demonstrates the benefit of adaptive retry coordination on a hard problem. The original Python/C++ fcmaes performance table reports a similar 81/100 Tandem success rate; the linked report records both results and their exact parallel execution models.
Controlled CMA-ES implementation diagnostic
The separate controlled active CMA-ES implementation diagnostic
holds the objective and parallel architecture much closer between
fcmaes-core and cmaes 0.2.2. Its complete 20-pair campaign finds no
universal quality winner:
cmaesleads serial throughput on cheap and high-dimensional cases.fcmaes-coreleads median aggregate throughput under equal 16-instance multistart.- Protective-stop behavior differs substantially and is reported rather than normalized away.
The easy analytic functions isolate implementation effects; they are not recommended CMA-ES workloads. At 100 µs objective cost, the serial speed gap is already negligible.
Equal-wall parallel retry
The complementary
GTOP equal-wall retry experiment plugs
that external, single-threaded cmaes implementation into
fcmaes_core::retry. Its primary 100-pair experiment compares the
best-objective mean/sdev returned by one serial restart lane and by 16 lanes
after the same four-second wait. Measured wall mean/sdev checks fairness;
starts, evaluations, CPU time, and active cores expose the deliberately higher
parallel work. This demonstrates that retry is an optimizer adapter rather
than a facility reserved for fcmaes algorithms.
In the completed seven-problem campaign:
- retry improves mean objective on every case and wins 86–96 of 100 pairs;
- it reduces standard deviation on five cases but increases it on SAGAS and Tandem; and
- both arms measure about 4.000 seconds, at roughly 1 versus 16 active cores.
Because the retry arm completed about 15 times as many independent starts, iid restart order statistics alone predict a win rate near 15/16, or 94%. The observed wins are consistent with that baseline; the improved means measure the distributional benefit relevant to the user.
A separate five-pair pilot retains equal-work scheduler-scaling evidence but is not part of the practical quality claim.
Data-backed examples
The examples are self-contained by default:
- Trading includes an offline adjusted-close cache and can optionally refresh it through Yahoo Finance.
- Mazda bundles its decision table and compact response-surface data under
examples/data/; neither binary needs or accepts an external model path. The Mazda data notice records provenance and the benchmark’s acknowledgement request. - The Multi-UAV data and compatibility notice documents the native task-assignment port and source benchmark.
- The Buckingham notice records the dimension-matrix catalog’s provenance and the numerical port’s deliberately narrower scope than BuckinghamPy.
Both Mazda drivers accept --workers N for ordered parallel objective batches;
use --workers 16 for sixteen evaluation threads or --workers 0 to select
available parallelism.
This public workspace intentionally contains only the Rust port and its related documentation, native examples, benchmark results, and optional Rust bindings. Historical Python/C++ implementations and port-planning material are not part of this repository.
License
The Rust source and documentation are MIT licensed; see LICENSE. The embedded Mazda benchmark data retains its recorded provenance and acknowledgement request; see the Mazda data notice.