Skip to content

Rust implementation of intermediate representation (IR) for imaginary-time propagators

License

MIT, Apache-2.0 licenses found

Licenses found

MIT
LICENSE
Apache-2.0
LICENSE-APACHE
Notifications You must be signed in to change notification settings

SpM-lab/sparse-ir-rs

Repository files navigation

SparseIR Rust Workspace

sparse-ir sparse-ir-capi docs.rs sparse-ir docs.rs sparse-ir-capi

High-performance Rust implementation of the sparse intermediate representation (IR) for quantum many-body physics.

Most end users should start from the ecosystem documentation / tutorials and use the full-featured Python/Julia libraries; this workspace focuses on Rust crates and low-level bindings.

Documentation

Start here: Ecosystem Documentation (theory + usage across all languages)

Resource Description
Python/Julia Tutorials Interactive tutorials with Jupyter notebooks
Rust API: sparse-ir (docs.rs) Core Rust crate API documentation
Rust API: sparse-ir-capi (docs.rs) C-API Rust crate API documentation

Quick start (Rust)

  • Use the Rust API docs: docs.rs/sparse-ir
  • Run the round-trip example (DLR/IR/sampling):
cargo run --example roundtrip --release

What’s in this workspace

Rust users typically depend on the crates below. Users of other languages typically use the bindings (via the C API).

Rust crates

  • sparse-ir — Core Rust implementation of IR basis, DLR, and sampling (README, docs.rs)
  • sparse-ir-capi — Rust crate providing a C-compatible API (shared library + C header) (README, docs.rs)

Bindings (other languages)

Language Component Notes
C/C++ sparse-ir-capi C-compatible shared library (README, docs.rs)
Fortran fortran/ Bindings via C-API (README)
Python pylibsparseir Thin wrapper for the C-API (not user-facing) (README)

Full-featured wrappers (external)

Note: the name sparse-ir is used both for the Rust crate (sparse-ir) and the full-featured Python project below.

Project Language Notes
sparse-ir (Python) Python Full-featured Python library (recommended for most users)
SparseIR.jl (Julia) Julia Full-featured Julia implementation

Examples

Rust examples

Example Description
sparse-ir/examples/roundtrip.rs Complete DLR/IR/sampling cycle with round-trip tests
sparse-ir/examples/basisgen.rs Basis generation and sampling point validation tests
sparse-ir/tests/readme_examples.rs Basic usage examples

Fortran examples

Example Description
fortran/examples/second_order_perturbation_fort.f90 Second-order perturbation theory

C/C++ integration tests

Test Description
cxx_tests/cinterface_core.cxx Core C-API tests
cxx_tests/cinterface_integration.cxx DLR/IR round-trip tests

References

  • sparse-ir: optimal compression and sparse sampling of many-body propagators
    Markus Wallerberger, Samuel Badr, Shintaro Hoshino, Fumiya Kakizawa, Takashi Koretsune, Yuki Nagai, Kosuke Nogaki, Takuya Nomoto, Hitoshi Mori, Junya Otsuki, Soshun Ozaki, Rihito Sakurai, Constanze Vogel, Niklas Witt, Kazuyoshi Yoshimi, Hiroshi Shinaoka
    arXiv:2206.11762 | SoftwareX 21, 101266 (2023)

License

This workspace is dual-licensed under the terms of the MIT license and the Apache License (Version 2.0).

Some components incorporate third-party code under Apache-2.0, such as the col_piv_qr module in the sparse-ir crate, which is based on nalgebra.
See sparse-ir/README.md and LICENSE-APACHE for details.


Development

Project structure

sparseir-rust/
├── sparse-ir/           # Core Rust library (crates.io: sparse-ir)
│   ├── src/             # Source code
│   ├── examples/        # Rust examples
│   └── tests/           # Integration tests
├── sparse-ir-capi/      # C-compatible API (shared library)
├── python/              # Python thin wrapper (pylibsparseir)
│   ├── pylibsparseir/   # ctypes bindings to C-API
│   └── tests/           # Python tests
├── fortran/             # Fortran bindings via C-API
│   ├── src/             # Fortran modules
│   ├── examples/        # Example programs
│   └── test/            # Test programs
├── cxx_tests/           # C/C++ integration tests
├── capi_benchmark/      # C-API benchmarks
├── notebook/            # Technical notes (algorithms, design)
└── docs/                # Development documentation

Build

From the workspace root:

cargo build            # build all crates in debug mode
cargo build --release  # optimized build

The default build uses the pure-Rust faer backend for matrix–matrix products.
Faer is reasonably fast, but usually considerably slower than an optimized BLAS implementation.

To enable system BLAS (LP64) for the Rust sparse-ir crate at compile time, use:

cargo build -p sparse-ir --features system-blas

With system-blas, the default GEMM backend becomes BLAS at compile time. Regardless of the feature, arbitrary BLAS function pointers (LP64/ILP64) can be injected at runtime via the C API or the internal GEMM dispatcher.

Test

Rust tests

cargo test --all-targets --release   # recommended for speed

C++ integration tests

Tests C-API with different BLAS configurations (default, OpenBLAS LP64, OpenBLAS ILP64):

cd cxx_tests && ./run_with_rust_capi.sh

Fortran tests

cd fortran && ./test_with_rust_capi.sh

Python tests

cd python && uv sync && uv run pytest tests/ -v

See .github/workflows/ for CI configurations.

Benchmarks

C API benchmarks

cd capi_benchmark && ./run_with_rust_capi.sh

Version management

Version consistency check

Check version consistency across the workspace:

python3 check_version.py

This script reads the canonical version from [workspace.package] in Cargo.toml and warns if Julia (julia/build_tarballs.jl) or Python (python/pyproject.toml) versions don't match.

Releasing a new version

The release process is done in two stages because Julia bindings depend on the published crates.io version:

Stage 1: Rust + Python version bump

  1. Update the version in Cargo.toml:

    [workspace.package]
    version = "0.8.0"  # Update this
    
    [workspace.dependencies]
    sparse-ir = { version = "0.8.0", path = "sparse-ir" }  # And this
  2. Update the Python bindings version in python/pyproject.toml:

    [project]
    version = "0.8.0"  # Update this
  3. Verify version consistency and test publishing (dry run):

    python3 check_version.py
    cd sparse-ir && cargo publish --dry-run
    cd ../sparse-ir-capi && cargo publish --dry-run
    cd ..
  4. Create a PR for the version bump:

    git checkout -b release/v0.8.0
    git add Cargo.toml python/pyproject.toml
    git commit -m "chore: bump version to 0.8.0"
    git push origin release/v0.8.0

    Then create a PR on GitHub and get it reviewed.

  5. After the PR is merged, get the merge commit hash and create a tag:

    git checkout main
    git pull origin main
    COMMIT_HASH=$(git rev-parse HEAD)
    echo "Merge commit: $COMMIT_HASH"
    git tag v0.8.0
    git push origin v0.8.0
  6. Publish to crates.io:

    cd sparse-ir && cargo publish
    cd ../sparse-ir-capi && cargo publish

Stage 2: Julia version bump (after crates.io publication)

After the new version is published to crates.io and available:

  1. Update julia/build_tarballs.jl using the update script:

    julia julia/update_build_tarballs.jl v0.8.0

    This script automatically:

    • Updates the version number
    • Fetches and updates the commit hash for the tag
    • Updates the comment with the tag reference
  2. Verify version consistency:

    python3 check_version.py
  3. Create a PR for the Julia version bump:

    git checkout -b update-julia-v0.8.0
    git add julia/build_tarballs.jl
    git commit -m "chore: bump Julia bindings version to 0.8.0"
    git push origin update-julia-v0.8.0

    Then create a PR on GitHub and get it reviewed.

  4. After the PR is merged, follow the Julia package release process (Yggdrasil PR, etc.)

About

Rust implementation of intermediate representation (IR) for imaginary-time propagators

Resources

License

MIT, Apache-2.0 licenses found

Licenses found

MIT
LICENSE
Apache-2.0
LICENSE-APACHE

Stars

Watchers

Forks

Packages

No packages published

Contributors 5