Development and contributing#

Repository and environment#

Path

Contents

src/evomo/algorithms/

Algorithm implementations and public exports

src/evomo/operators/

Selection and reusable operators

src/evomo/problems/

Numerical, constrained, and neuroevolution problems

src/evomo/workflows/

Connections between algorithms, problems, and monitors

src/evomo/metrics/

Solution quality metrics

src/evomo/utils/

Tensor, evaluation output, and state helpers

unit_test/

Algorithm, operator, and problem tests

docs/

Documentation, examples, and build configuration

Check the existing Python environment and CUDA setup before installing the editable package and development tools:

python -m pip install -e .
python -m pip install pytest ruff

Extending algorithms#

Subclass EvoX’s Algorithm and follow existing state management patterns. Use Mutable for population, fitness, and other state updated each generation. For buffers whose shapes are known only after the first evaluation, see evomo.utils.register_lazy_buffer. Call the problem through the workflow-provided evaluate, initialize state in init_step, and implement each generation in step.

For a new public algorithm, update the imports and __all__ in src/evomo/algorithms/__init__.py. Keep class names and constructor interfaces clear. Document the actual calling contracts of parameters such as selection_op, along with implementation changes and paper references.

Tensor implementation conventions#

  • Preserve devices and dtypes. Create constants on the input device and avoid hidden CPU allocations.

  • Prefer batched operations. Minimize .item(), tensor-dependent Python branches, and dynamic-size indexing in compiled hot paths.

  • Preserve ranking, selection, and update semantics when using fixed-shape masks or scatter/gather operations.

  • Non-domination ranks start at 0; a boolean selection mask is not a replacement for ranks.

  • Preserve constraint violations through evaluation, comparison, selection, and state updates.

  • Read the sorting backend guide before adding optional backends; keep PyTorch as the default.

Validating changes#

Run relevant tests from the repository root, for example:

python -m pytest unit_test/problems/test_dtlz.py -q
python -m pytest unit_test/operators/test_non_dominate.py -q
python -m pytest unit_test/algorithms/test_moea.py -q

Selection and normalization changes should cover duplicate points, constant objectives, degenerate objective ranges, nonfinite values, and constraint handling. Validate eager and compiled execution for compilation-sensitive changes, initializing the workflow before compiling step. Distinguish unsupported toolchains or devices from algorithm failures, and report only the configurations actually tested.

Run checks on changed Python files only, for example:

python -m ruff check src/evomo/algorithms/nsga2.py
python -m ruff format --check src/evomo/algorithms/nsga2.py

The project uses 128-character lines and LF line endings. Keep changes scoped and preserve unrelated user edits. Isolate experimental scripts and outputs; do not commit local environments, caches, or temporary performance data.

Maintaining bilingual documentation#

Install the separate documentation dependencies and treat build warnings as failures:

python -m pip install -r docs/requirements.txt
python -m sphinx -b html -W --keep-going docs docs/_build/html

English is the primary source under docs/. Chinese chapters mirror the same relative paths under docs/zh_CN/. Update both language versions when changing a guide, keeping parameters, formulas, limitations, and examples consistent. Add new chapters to both homepages. The page language switch maps matching paths automatically; generated API pages remain shared in English and link back to both language homepages.

API documentation is generated by statically parsing source code without importing PyTorch, Brax, or JAX. Guides use MyST Markdown. Keep complete scripts in docs/examples/ and include the same scripts in both languages through literalinclude. After editing examples, verify their imports, shapes, and devices. Documentation builds do not execute scripts and do not establish runtime, GPU, or compilation support.

See docs/README.md for build details. .readthedocs.yaml supplies hosting build configuration; publishing still requires connecting the repository in Read the Docs.