This guide covers building mortie with its Rust-accelerated morton indexing functions.
- Python 3.10 or later
- Rust toolchain (rustc, cargo)
- Python packages: numpy
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/envDownload and run rustup-init.exe
rustc --version
cargo --versionThe Rust side is a cargo workspace with two members:
| path | crate | contents |
|---|---|---|
./ (root manifest) |
mortie, library mortie_rustie |
the pyo3 extension: geometry, coverage/MOC, the rayon batch kernels, the Arrow FFI, and every #[pyfunction]. Sources in src_rust/, benches in src_rust/benches/. |
mortie-core/ |
mortie-core |
the packed-word codec only: the bit layout, encode/decode, order/truncation/containment arithmetic, the decimal-string grammar, and the (depth, nested-ipix) ↔ packed-word pivot primitives. |
mortie-core has no dependencies — not pyo3, not numpy, not rayon, not a
HEALPix crate — so a Rust project can depend on the codec alone. That is a
contract, not an accident: mortie-core/tests/dep_contract.rs fails the suite if
the crate's manifest ever declares a dependency table.
Neither crate is published to crates.io yet, so cargo add mortie-core finds
nothing today; the crate is only available from this repository. Publishing
mortie-core is tracked separately in issue #201.
mortie_rustie depends on mortie-core and re-exports it, so
mortie_rustie::decimal_morton and mortie_rustie::morton resolve exactly as
they did before the split, and nothing about the Python surface changes. The
wheel is still built from the root manifest by maturin, which pulls the path
dependency into the build (and into the sdist) automatically.
For local development with Rust acceleration:
# Clone repository
git clone https://github.com/espg/mortie.git
cd mortie
# Install maturin (Rust-Python build tool)
pip install maturin
# Build and install in development mode
maturin develop --release
# Or for debugging with symbols
maturin developBuild optimized wheels for distribution:
# Build wheel for current platform
maturin build --release
# Output will be in target/wheels/
ls -lh target/wheels/pytest -v# Both workspace members
cargo test
# The codec crate on its own (no pyo3, so no Python needed to link)
cargo test -p mortie-corecargo test on the root package needs the extension-module symbols resolved
lazily on every platform, since pyo3's extension-module feature deliberately
skips linking libpython. The invocation below is the macOS remedy only:
-undefined dynamic_lookup is a Mach-O linker option, so it does nothing on
Linux or Windows — those need their own equivalent, which is not documented here
because it has not been verified against this workspace.
# macOS
RUSTFLAGS="-C link-arg=-undefined -C link-arg=dynamic_lookup" cargo testcargo test -p mortie-core needs no flag on any platform — the codec crate
links nothing.
cargo benchPre-built wheels are available for common platforms:
pip install mortieThis will automatically use the Rust implementation if a wheel is available for your platform.
- Uses manylinux wheels for broad compatibility
- Supports x86_64 and aarch64 architectures
- Separate wheels for Intel (x86_64) and Apple Silicon (aarch64)
- Minimum macOS version: 10.12
- Requires Visual Studio Build Tools or equivalent
- Supports x86_64 architecture
maturin develop --release- Full optimizations (opt-level = 3)
- Link-time optimization (LTO)
- Stripped binaries
- ~30-50% faster than debug builds
maturin develop- Includes debug symbols
- Faster compilation
- Easier debugging with rust-gdb/rust-lldb
maturin develop --profile profiling- Optimized but with debug symbols
- Useful for performance profiling
pip install --upgrade maturin# Install rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Or update existing installation
rustup updateEnsure you have Visual Studio Build Tools installed:
- Download from: https://visualstudio.microsoft.com/downloads/
- Install "Desktop development with C++"
- Restart terminal and try again
The Rust extension wasn't built. Run:
maturin develop --releaseClean build artifacts:
cargo clean
maturin develop --release
pytest -vPerformance comparison of Rust vs Python (reference) implementations:
| Benchmark | Rust | Python (reference) | Speedup |
|---|---|---|---|
| Scalar operations | 0.14 µs | 10.69 µs | 78.6x |
| Small arrays (1K) | 1.93 ms | 4.14 ms | 2.1x |
| Large arrays (100K) | 1.85 ms | 410.59 ms | 222.2x |
| Real-world (1.2M coords) | 102.51 ms | 5109.15 ms | 49.8x |
The Rust implementation provides dramatic performance improvements, especially for large datasets.
GitHub Actions automatically builds wheels for:
- Linux (x86_64, aarch64)
- macOS (x86_64, aarch64)
- Windows (x86_64)
- Python 3.10, 3.11, 3.12, 3.13
See .github/workflows/build-wheels.yml for details.
When modifying Rust code:
- Run Rust tests:
cargo test - Run Python tests:
pytest -v - Run benchmarks:
cargo bench - Format code:
cargo fmt - Check lints:
cargo clippy