Skip to content

Latest commit

 

History

History
464 lines (351 loc) · 15.3 KB

File metadata and controls

464 lines (351 loc) · 15.3 KB

Contributing to OrthoRoute

OrthoRoute is a GPU-accelerated autorouter for difficult KiCad boards. It uses PathFinder negotiated congestion on a multi-layer Manhattan lattice and supports NVIDIA CUDA, Apple Silicon/Metal, and a CPU fallback.

This is real routing software built from research code. Some parts are cleanly separated; some parts, especially UnifiedPathFinder, are still very large and stateful. Focused changes with evidence are much easier to review than heroic rewrites.

Project communication stays on GitHub:

  • Use Issues for bugs and concrete feature requests.
  • Use Discussions for design questions and open-ended ideas.
  • Use pull requests for code review. There will not be a separate Discord or Slack.

Current platform

  • KiCad: 10.0 or newer
  • Plugin API: Native Python IPC plugin with plugin.json
  • Distribution: KiCad PCM metadata v2 and an Install-from-File ZIP
  • Python runtime: 3.11 or newer for the KiCad plugin
  • Acceleration:
    • NVIDIA CUDA 12 through CuPy on Windows and Linux
    • MLX/Metal on Apple Silicon
    • CPU fallback for development and compatibility
  • Tests: 512 tests currently collected, with hardware- and KiCad-dependent tests skipped when their runtime is unavailable
  • Current release: v1.0.0

The repository can move quickly, so do not copy test counts, timings, or hardware claims into new documentation unless they are generated by a repeatable command.

Set up a development checkout

Prerequisites

  • Git
  • Python 3.11 or 3.12
  • KiCad 10 for plugin or IPC work
  • Enough memory for the board and routing grid under test
  • Optional accelerator:
    • an NVIDIA GPU with a working CUDA 12 driver; or
    • an Apple Silicon Mac for MLX/Metal development

Windows PowerShell

git clone https://github.com/bbenchoff/OrthoRoute.git
Set-Location OrthoRoute

py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pytest tests/unit

macOS or Linux

git clone https://github.com/bbenchoff/OrthoRoute.git
cd OrthoRoute

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pytest tests/unit

requirements.txt is the contributor environment and includes test and documentation tools. requirements-kicad.txt is intentionally smaller: KiCad installs it into the plugin's isolated runtime. Keep development-only packages out of requirements-kicad.txt.

Check accelerator availability

CUDA:

python -c "import cupy as cp; print(cp.cuda.runtime.getDeviceCount())"

Apple Silicon/Metal:

python -c "import mlx.core as mx; print(mx.default_device())"

An unavailable accelerator should not make ordinary CPU tests fail. Use pytest.importorskip, a platform marker, or an explicit skip reason for tests that genuinely require hardware.

Repository map

OrthoRoute/
├── main.py                       # Plugin, CLI, and ORP/ORS headless entrypoint
├── build.py                      # Build, validate, archive, and deploy plugin
├── plugin.json                   # KiCad native IPC action manifest
├── requirements-kicad.txt        # Isolated KiCad runtime dependencies
├── orthoroute/
│   ├── algorithms/               # Manhattan router and CPU/GPU/Metal solvers
│   ├── application/              # Commands, queries, orchestration, interfaces
│   ├── domain/                   # Board/routing models and domain services
│   ├── infrastructure/           # KiCad, GPU, persistence, serialization
│   ├── presentation/             # PyQt GUI, plugin adapter, shared pipeline
│   └── shared/                   # Configuration, exceptions, utilities
├── tests/                        # Unit, package, smoke, and regression tests
├── benchmarks/                   # Synthetic boards and route analysis tools
├── scripts/                      # Debugging, deployment, and visualization tools
├── TestBoards/                   # Tracked regression board
└── docs/                         # Design, tuning, packaging, and optimization docs

The intended dependency direction is inward:

presentation ─┐
infrastructure ├─> application ─> domain
algorithms ────┘

Important boundaries:

  • domain/ must not import KiCad, GUI, filesystem, network, application, or infrastructure code.
  • Convert KiCad nanometres to domain millimetres at the adapter boundary.
  • Normalize KiCad layer names before passing them into domain or algorithm code.
  • Keep I/O and concrete integrations in infrastructure/.
  • Put UI behavior in presentation/; do not bury GUI work in the router.
  • Define external contracts under application/interfaces/ and inject their implementations.

Repository-specific rules also live under .github/instructions/. Read the applicable file before changing domain, KiCad IPC, or unified_pathfinder.py.

Run OrthoRoute during development

Show the supported commands:

python main.py --help

Common modes:

# Native plugin process; KiCad must be running with its API server enabled
python main.py plugin

# IPC CLI; the requested board must already be open in PCB Editor
python main.py cli TestBoards/TestBackplane.kicad_pcb

# Route an exported board without a running KiCad GUI
python main.py headless input.ORP -o output.ORS

# Force the headless ORP/ORS workflow onto the CPU
python main.py headless input.ORP -o output.ORS --cpu-only

# Small built-in algorithm checks
python main.py --test-manhattan
python main.py --test-via

The cli command is not a standalone .kicad_pcb parser: it connects to the running KiCad instance. The headless command operates on OrthoRoute's .ORP and .ORS formats; see ORP/ORS file formats.

Build and test the KiCad plugin

Build both distributable archives:

python build.py

Outputs:

  • build/OrthoRoute-<version>-KiCad-PCM.zip — recommended KiCad 10 Install from File package
  • build/OrthoRoute-<version>-KiCad-IPC.zip — manual native IPC archive

Build and install into a local development copy of KiCad:

python build.py --deploy --kicad-version 10.0

Then:

  1. Enable the API server under Preferences > Plugins.
  2. Restart PCB Editor.
  3. Wait for KiCad to finish creating the plugin's Python environment.
  4. Open a board and launch OrthoRoute from Tools > External Plugins.

Clean generated packages with:

python build.py --clean

Generated build/ content is ignored by Git. Do not commit ZIPs or unpacked package trees. Release assets belong on the GitHub release.

For package changes, always run:

python -m pytest tests/test_kicad_plugin_package.py
python build.py

The package test checks the native manifest, runtime dependencies, cache exclusion, manual ZIP, PCM layout, metadata v2, and deployment targets. See Plugin Manager integration for the archive format and official repository workflow.

Testing expectations

Run tests through the active Python interpreter so the intended environment is unambiguous:

# Entire suite
python -m pytest

# Fast unit tests
python -m pytest tests/unit

# Synthetic CPU/GPU smoke routing
python -m pytest tests/regression/test_smoke.py

# Plugin packaging only
python -m pytest tests/test_kicad_plugin_package.py

Some tests skip when KiCad, CUDA, or Metal is unavailable. A skip with a specific hardware reason is acceptable; silently swallowing an import or turning a real failure into a skip is not.

The regular suite uses short backplane samples. The full backplane regression is opt-in because it is expensive:

$env:ORTHO_RUN_FULL_REGRESSION = '1'
python -m pytest tests/regression/test_backplane.py
Remove-Item Env:ORTHO_RUN_FULL_REGRESSION

Tests that consume a live routing log search the repository logs/ directory. Set ORTHO_LOG_DIR to use another location:

$env:ORTHO_LOG_DIR = 'C:\path\to\plugin\logs'
python -m pytest tests/regression/test_backplane.py
Remove-Item Env:ORTHO_LOG_DIR

Read tests/README.md and the golden regression guide before changing baselines. Do not loosen a golden threshold merely to make a regression pass.

Debugging and performance work

Enable detailed logs:

$env:ORTHO_DEBUG = '1'
python main.py --test-manhattan
Remove-Item Env:ORTHO_DEBUG

Normal mode keeps console and file output deliberately quiet. Debug mode writes detailed routing and profiling records. Avoid logging inside paint loops, per-edge loops, or per-net hot paths unless it is guarded by debug mode.

Use a deterministic synthetic benchmark for performance changes:

python benchmarks/run_benchmark.py --cpu --connectors 2 --pins 16 --layers 4
python benchmarks/run_benchmark.py --gpu --connectors 4 --pins 40 --layers 8

Benchmark output under benchmarks/results/ is ignored. Record the command, commit, hardware, backend, seed, board dimensions, route completion, convergence, DRC result, runtime, and peak memory when making a performance claim.

For a routing optimization:

  1. Capture a before result using the same command and seed.
  2. Make one focused change.
  3. Run targeted tests and the full suite.
  4. Capture the after result on the same hardware.
  5. Check route quality, overuse, via conflicts, layer usage, and KiCad DRC—not only elapsed time.
  6. Add or update a dated note under docs/optimization/ for a material result.

Router invariants

Changes in orthoroute/algorithms/manhattan/ need extra care:

  • Preserve the frozen graph/CSR structure after graph construction.
  • Preserve (x, y, layer) <-> global node ID round trips.
  • Preserve preferred horizontal/vertical layer discipline unless the change explicitly targets guided or bidirectional routing.
  • Keep pad escape and portal generation before net request parsing.
  • Keep edge, via-column, and barrel usage accounting reversible and deterministic.
  • Treat zero-overuse convergence, successful geometry emission, and KiCad DRC as separate checks.
  • Compare CPU, CUDA, and Metal path cost—not exact node sequences when equal-cost ties are valid.
  • Do not claim a route is manufacturing-clean without running KiCad DRC on the emitted board.

UnifiedPathFinder is over 11,000 lines today. Do not perform a whole-file cleanup, rename pass, formatting pass, or architecture rewrite. For an extraction:

  1. Add a characterization test for the current behavior.
  2. Extract one cohesive responsibility.
  3. Preserve the public method and result schema.
  4. Run the test before and after.
  5. Run the full suite and a representative benchmark.
  6. Keep behavior changes out of the same commit.

Good contribution areas

Useful contributions include:

  • KiCad 10 IPC integration tests and adapter mocks
  • PCM installation testing across Windows, macOS, and Linux
  • submission and maintenance of official KiCad repository metadata
  • CUDA/CPU and Metal/CPU solver parity tests
  • DRC accuracy for tracks, blind/buried vias, keepouts, and pad escapes
  • reproducible routing-quality and layer-capacity benchmarks
  • small, tested extractions from UnifiedPathFinder
  • GUI responsiveness and cancellation behavior
  • documentation corrections backed by current commands or results

Open an issue before starting a large algorithm change, new dependency, file format change, broad refactor, or GUI redesign. Small bug fixes, tests, and documentation corrections can go directly to a pull request.

Code style

  • Match the surrounding style and keep diffs focused.
  • Use type hints for new public APIs.
  • Add docstrings where behavior, units, ownership, or invariants are not obvious.
  • Prefer explicit result assertions over “did not crash” tests.
  • Mock I/O boundaries, not domain behavior.
  • Do not mechanically reformat unrelated legacy code.
  • Do not add a dependency when a standard-library solution is sufficient.
  • Add runtime dependencies to the correct file:
    • contributor/tooling dependency: requirements.txt
    • packaged KiCad runtime dependency: requirements-kicad.txt
  • Never commit credentials, local paths, logs, checkpoints, build artifacts, generated benchmark results, KiCad backups, or user board data without permission.

Pull request workflow

  1. Fork the repository and create a focused branch:

    git switch -c fix/descriptive-name
  2. Add or update tests with the implementation.

  3. Run the smallest relevant tests while iterating.

  4. Run the full suite before opening the pull request.

  5. For KiCad-facing changes, deploy and exercise the plugin in KiCad 10.

  6. For routing changes, include before/after metrics and DRC evidence.

  7. Push your branch and open a pull request.

A useful pull request description includes:

## What

What changed?

## Why

What failure, limitation, or use case does this address?

## Validation

- Commands run
- Pass/skip counts
- KiCad version and operating system, when relevant
- CPU/GPU/Metal hardware, when relevant
- Before/after route metrics and DRC results, when relevant

## Risks

What invariants or workflows could this affect?

Keep commits reviewable. Separate behavior changes, refactors, generated baselines, and documentation when practical.

Maintainer release checklist

The package version currently comes from setup.py; build.py uses it in the archive names and PCM metadata.

  1. Update the version and versioned download links.
  2. Run the full test suite.
  3. Run the package tests.
  4. Build both ZIPs from a clean commit.
  5. Validate the PCM metadata and native manifest against the current KiCad schemas.
  6. Tag the exact release commit as v<version>.
  7. Publish both ZIPs on the GitHub release:
    • PCM ZIP for end users
    • manual IPC ZIP for development and troubleshooting
  8. Download the published assets and verify their SHA-256 digests.
  9. Update or submit the separate metadata entry for KiCad's official package repository.

Do not put repository-only download URL, checksum, or size fields into the metadata.json embedded inside the PCM archive.

Reporting bugs

Include:

  • OrthoRoute version or commit
  • KiCad version
  • operating system and Python version
  • CPU/GPU/Metal hardware and driver/runtime versions
  • board size, copper layer count, grid pitch, and approximate net/pad counts
  • exact steps to reproduce
  • expected and actual behavior
  • relevant log excerpt
  • a shareable minimal board or .ORP file when possible
  • KiCad DRC report for geometry problems

Remove proprietary board data, credentials, and unrelated personal information before attaching files.

Security and conduct

Do not post private board files, credentials, access tokens, or customer data. For a vulnerability that should not be public immediately, contact the maintainer privately through the address associated with the GitHub account instead of attaching exploit details to a public issue.

Be direct, argue from evidence, and criticize the code rather than the person. Spam, harassment, and abusive behavior will be removed.

Thanks for helping make the weird GPU autorouter more reliable.