Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/scripts/run_cargo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Run `cargo` with the given arguments, or skip where no Rust toolchain is installed.

The cargo pre-commit hooks go through this so that `pre-commit run --all-files` works
without Rust; CI installs Rust, so the `style` job still runs them.
"""

from __future__ import annotations

import shutil
import subprocess
import sys


def main() -> int:
cargo = shutil.which("cargo")
if cargo is None:
print(
"cargo is not on PATH, so this Rust hook is skipped; install Rust "
"(https://rustup.rs) to run it."
)
return 0
return subprocess.call([cargo, *sys.argv[1:]])


if __name__ == "__main__":
raise SystemExit(main())
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [python, c-cpp]
language: [python, c-cpp, rust]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/test_on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ jobs:
- '.github/workflows/_build_solver_wheels.yml'
pybamm:
- 'packages/pybamm/**'
- 'packages/pybamm-rust/**'
- 'pyproject.toml'
- 'uv.lock'
- 'noxfile.py'
Expand Down Expand Up @@ -103,6 +104,50 @@ jobs:
echo "macos_runners=$macos"
} >> "$GITHUB_OUTPUT"

rust_msrv:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.pybamm == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
name: Rust MSRV (1.89)
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install the MSRV toolchain
run: rustup toolchain install 1.89 --profile minimal --no-self-update
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: packages/pybamm-rust
key: msrv-1.89
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Check against the declared MSRV
run: >
cargo +1.89 check --manifest-path packages/pybamm-rust/Cargo.toml
--locked --all-targets --all-features

rust_tests:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.pybamm == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
name: Rust tests
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: packages/pybamm-rust
key: tests
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Run the Rust test suite
run: >
cargo test --manifest-path packages/pybamm-rust/Cargo.toml
--locked --workspace --all-features

style:
runs-on: ubuntu-latest
permissions:
Expand All @@ -125,6 +170,15 @@ jobs:
with:
python-version: 3.12

# Pinned, as each Rust release adds pedantic and nursery lints that `-D warnings` fails on.
- name: Install the pinned Rust toolchain
run: |
rustup toolchain install 1.99.1 --profile minimal --component clippy,rustfmt --no-self-update
rustup default 1.99.1
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: packages/pybamm-rust
save-if: ${{ github.ref == 'refs/heads/main' }}
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
with:
version: "latest"
Expand Down Expand Up @@ -355,6 +409,8 @@ jobs:
needs:
- changes
- style
- rust_msrv
- rust_tests
- build_solver
- run_unit_tests
- run_coverage
Expand Down
20 changes: 18 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ ci:
autoupdate_commit_msg: "chore: update pre-commit hooks"
autofix_commit_msg: "style: pre-commit fixes"
autoupdate_schedule: "weekly"
# No base ref here, so comment-slop would scan nothing; `style` gates it.
skip: [comment-slop]
# No base ref or Rust toolchain here; the `style` CI job gates these.
skip: [comment-slop, cargo-fmt, cargo-clippy]

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down Expand Up @@ -83,3 +83,19 @@ repos:
additional_dependencies: [pyyaml]
files: ^\.github/(workflows/test_on_push\.yml|scripts/check_ci_gate\.py)$
pass_filenames: false
# Skipped, saying so, where cargo is not installed.
- id: cargo-fmt
name: cargo fmt
entry: python .github/scripts/run_cargo.py fmt --manifest-path packages/pybamm-rust/Cargo.toml --all
language: python
types: [rust]
pass_filenames: false
verbose: true
- id: cargo-clippy
name: cargo clippy
entry: python .github/scripts/run_cargo.py clippy --quiet --manifest-path packages/pybamm-rust/Cargo.toml --all-targets --all-features
language: python
types: [rust]
pass_filenames: false
verbose: true
args: ["--", "-D", "warnings"]
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
## Features

- Replaced Codacy with open checks that also run locally. Ruff's `flake8-bandit` (`S`) rules replace Bandit, and CodeQL scans the Python and C++ code. `nox -s type-check` runs Pyrefly over `pybamm`, which now type-checks cleanly, and a new type error fails CI. clang-tidy reports solver findings to code scanning as an advisory check. ([#5974](https://github.com/pybamm-team/PyBaMM/pull/5974))
- Added `pybamm-core` (`packages/pybamm-rust`), a Rust expression compiler: an arena DAG with simplification, CSE and zero propagation, a typed IR, scalar and lane-batched interpreters, and forward-mode AD. CI runs `cargo test`, an MSRV check, `cargo fmt`, `cargo clippy` and CodeQL. ([#5956](https://github.com/pybamm-team/PyBaMM/pull/5956))
- `pybamm-core` evaluates transcendentals through the platform C library, as CasADi does: bitwise identical across evaluation paths, last-bit differences across platforms. `pow` is exact for exponents `0`, `1`, `2` and `-1`; `erf`, `asinh` and IEEE 754-2019 `minimum`/`maximum` use `libm`. ([#5956](https://github.com/pybamm-team/PyBaMM/pull/5956))

## Bug fixes

Expand Down
7 changes: 7 additions & 0 deletions packages/pybamm-rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/target/
*/target/
*.so
*.dylib
*.pyd
.venv/
uv.lock
Loading
Loading