Contributing guide#

This guide summarizes how to set up a development environment, follow project conventions, run checks locally, and align with the CI pipeline. For test commands and layout, see Testing Guide. The repository root CONTRIBUTING.md summarizes key contribution guidelines, such as branch naming conventions, commit message style, and pull request requirements.

1. Development setup#

  1. Clone the repository (include submodules):

    git clone --recurse-submodules https://github.com/AMD-AGI/Primus.git
    cd Primus
    
  2. Install Python dependencies:

    pip install -r requirements.txt
    
  3. Install pre-commit hooks (recommended):

    pip install pre-commit
    pre-commit install
    
  4. Optional—JAX / MaxText work:

    pip install -r requirements-jax.txt
    
  5. Quick verification (from the repository root, with Primus on your PATH or via the bundled launcher):

    ./primus-cli direct -- benchmark gemm --M 4096 --N 4096 --K 4096
    

2. Code style#

Configuration lives in .pre-commit-config.yaml. Hooks run automatically on git commit after pre-commit install.

Tool

Version

Purpose

black

24.8.0

Python formatter, line length 110

isort

5.13.2

Import sorting, profile black

autoflake

2.3.1

Removes unused imports and variables (see hook args for star imports and __init__)

shellcheck

0.10.0.1 (shellcheck-py)

Shell script analysis

pre-commit-hooks

v4.0.1

trailing-whitespace, end-of-file-fixer, check-yaml, check-added-large-files, check-merge-conflict

Manual one-off runs (repository root):

black --line-length=110 .
isort --profile black .
autoflake --remove-all-unused-imports --remove-unused-variables --expand-star-imports --ignore-init-module-imports --recursive --in-place .

CI runs pre-commit run --all-files --show-diff-on-failure, so lint behavior follows .pre-commit-config.yaml rather than a separate hand-written list of formatter commands.

3. Branch naming convention#

Format:

<type>/<scope>/<short-description>

Types: feat, fix, docs, refactor, test, chore, ci

Scope (optional): engine, model, scheduler, docs, tests, config, or another short area name.

Examples:

  • feat/model/implement-moe-routing

  • fix/engine/init-error

4. Commit convention#

Follow Conventional Commits:

<type>(<scope>): <description>

Examples:

  • feat(model): add MOE routing functionality

  • fix(engine): resolve initialization error

5. Testing requirements#

Before opening a pull request, run the following from the repository root:

  • Shell integration tests:

    bash ./tests/runner/run_all_tests.sh
    
  • Python unit tests:

    pytest tests/unit_tests/ --maxfail=1 -s
    
  • Backend / trainer tests (GPU, datasets, and sometimes Hugging Face tokens): run the relevant file under tests/trainer/ when your change touches that backend. See Testing Guide.

  • Pre-commit on all files:

    pre-commit run --all-files
    

6. Pull request process#

  1. Fork the repository (unless you have write access and use a feature branch).

  2. Create a branch that follows the naming convention above.

  3. Implement changes and commit using the commit message convention.

  4. Run tests and pre-commit locally.

  5. Push and open a pull request with a clear description.

  6. Reference related issues when applicable.

  7. Request reviewers.

  8. Address review feedback.

  9. Ensure CI passes (lint and unit tests on the paths your PR triggers).

7. CI pipeline#

The workflow .github/workflows/ci.yaml defines how changes are validated.

Triggers: workflow_dispatch, pushes to main, tags matching v*, and pull requests.

Jobs (high level):

  • code-lint: Ubuntu, Python 3.12—installs pre-commit and runs pre-commit run --all-files --show-diff-on-failure, so the checks (black, isort, autoflake, shellcheck, and the pre-commit-hooks set) follow .pre-commit-config.yaml exactly.

  • build-docker: Builds and pushes Docker images (depends on code-lint).

  • run-unittest-torch: Self-hosted GPU runner—installs dependencies (including Primus-Turbo and AITER as defined in the workflow), runs bash ./tests/runner/run_all_tests.sh, pytest on tests/unit_tests/ (with a few deselected tests), then Megatron and TorchTitan trainer tests with DATA_PATH, MASTER_PORT, HSA_NO_SCRATCH_RECLAIM=1, and HF_TOKEN where required.

  • run-unittest-jax: JAX runner—installs requirements-jax.txt, runs shell tests and python ./tests/run_unit_tests.py --jax with CI-specific environment variables.

Lint checks mirror the pre-commit stack. Trainer jobs require GPU resources and shared secrets (for example HF_TOKEN) in the hosted environment.

For a focused description of local vs CI test commands, see Testing Guide.