Skip to content
Merged
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
14 changes: 10 additions & 4 deletions .github/workflows/Github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ jobs:
- uses: actions/checkout@v4
- name: Install OpenBLAS / LAPACK
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev liblapack-dev gfortran
- name: Build
- name: Build (OpenBLAS from source)
run: cargo build --verbose --features O3-openblas
- name: Run tests
- name: Run tests (OpenBLAS from source)
run: cargo test --verbose --features O3-openblas
- name: Build (system OpenBLAS via pkg-config)
run: cargo build --verbose --features O3-openblas-system
- name: Run tests (system OpenBLAS via pkg-config)
run: cargo test --verbose --features O3-openblas-system

pure-rust:
name: Pure-Rust feature set
Expand Down Expand Up @@ -75,17 +79,19 @@ jobs:
# HDF5 features (nc / netcdf) are excluded because they need an external
# toolchain (vendor BLAS, HDF5 headers) or a non-Linux platform rather than
# being a code problem; plot / pyo3 are exercised by the dedicated plot job.
# openblas-src alone (default-features = false) has no TLS backend for its
# source download, so it is only meaningful through O3-openblas-system.
- name: Each feature builds on its own
run: >
cargo hack build --each-feature --optional-deps --keep-going
--exclude-features O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src
--exclude-features O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,openblas-src
# Pairwise (depth 2) coverage over the pure-Rust / numerical features. The
# heavy compile units (arrow / parquet) and the backend / HDF5 / Python
# features are excluded so the target dir does not blow up on a CI runner.
- name: Pairwise feature powerset (pure-Rust / numerical)
run: >
cargo hack build --feature-powerset --depth 2 --optional-deps --keep-going
--exclude-features O3,O3-openblas,O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,arrow,parquet
--exclude-features O3,O3-openblas,O3-openblas-system,O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,openblas-src,arrow,parquet

plot:
name: plot (pyo3 + matplotlib)
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ blas = { version = "0.22", optional = true }
lapack = { version = "0.19", optional = true }
blas-src = { version = "0.14", optional = true, default-features = false }
lapack-src = { version = "0.13", optional = true, default-features = false }
# Only used to forward the `system` feature to the `openblas-src` instance
# that `blas-src` / `lapack-src` already pull in (see `O3-openblas-system`).
openblas-src = { version = "0.10", optional = true, default-features = false }
serde = { version = "1.0", features = ["derive"], optional = true }
rkyv = { version = "0.8", optional = true }
json = { version = "0.12", optional = true }
Expand Down Expand Up @@ -106,6 +109,9 @@ rand = ["dep:rand", "dep:rand_distr"]
O3 = ["blas", "lapack"]
# Convenience flags that bundle a backend choice for `O3`.
O3-openblas = ["O3", "blas-src/openblas", "lapack-src/openblas"]
# Same as `O3-openblas`, but links the OpenBLAS already installed on the
# system (found via pkg-config) instead of compiling OpenBLAS from source.
O3-openblas-system = ["O3-openblas", "openblas-src/system"]
O3-accelerate = ["O3", "blas-src/accelerate", "lapack-src/accelerate"]
O3-mkl = ["O3", "blas-src/intel-mkl-dynamic-parallel", "lapack-src/intel-mkl-dynamic-parallel"]
O3-netlib = ["O3", "blas-src/netlib", "lapack-src/netlib"]
Expand Down
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ For accelerated linear algebra, plotting, or DataFrame I/O, enable the matching
Peroxide provides various features.

- `default` - Pure Rust (No dependencies of architecture - Perfect cross compilation)
- `O3` - BLAS & LAPACK (Perfect performance but little bit hard to set-up - Strongly recommend to look [Peroxide with BLAS](https://github.com/Axect/Peroxide_BLAS))
- `O3-openblas` / `O3-openblas-system` / `O3-accelerate` / `O3-mkl` / `O3-netlib` - BLAS & LAPACK accelerated linear algebra; pick one backend flag (see [Pre-requisite](#pre-requisite))
- `plot` - With matplotlib of python, we can draw any plots.
- `complex` - With complex numbers (vector, matrix and integral)
- `parallel` - With some parallel functions
Expand All @@ -76,7 +76,7 @@ Peroxide provides various features.
- `serde` - serialization with [Serde](https://serde.rs/).
- `rkyv` - serialization with [rkyv](https://rkyv.org).

If you want to do high performance computation and more linear algebra, then choose `O3` feature.
If you want to do high performance computation and more linear algebra, then choose one of the `O3-*` backend features.
If you don't want to depend C/C++ or Fortran libraries, then choose `default` feature.
If you want to draw plot with some great templates, then choose `plot` feature.

Expand Down Expand Up @@ -267,25 +267,27 @@ The three groups below depend on external libraries or runtimes; install the rel
Those crates only provide function signatures, so the link backend that supplies the actual `dgemv_` / `dpotrf_` / ... symbols must be selected separately.
The simplest path is to enable one of the convenience flags below; each pulls in [`blas-src`](https://crates.io/crates/blas-src) and [`lapack-src`](https://crates.io/crates/lapack-src) with the matching backend.

| Convenience flag | Backend | Typical platform / use case |
| ----------------- | ------------------ | --------------------------------------- |
| `O3-openblas` | OpenBLAS | Linux, Windows, macOS via Homebrew |
| `O3-accelerate` | Apple Accelerate | macOS (no extra system install) |
| `O3-mkl` | Intel MKL | Intel CPUs, vendor-tuned performance |
| `O3-netlib` | Netlib reference | Portability, lowest performance |
| Convenience flag | Backend | Build-time requirements |
| -------------------- | ----------------------------- | ------------------------------------------------ |
| `O3-openblas` | OpenBLAS, compiled from source | C + Fortran toolchain, `make`, network access |
| `O3-openblas-system` | System-installed OpenBLAS | `pkg-config` + the OpenBLAS system package |
| `O3-accelerate` | Apple Accelerate | macOS only (no extra system install) |
| `O3-mkl` | Intel MKL | Intel's redistributable (fetched automatically) |
| `O3-netlib` | Netlib reference, compiled from source | `cmake` + Fortran toolchain (lowest performance) |

If you need a backend not in the list above (for example BLIS or R's BLAS), enable the bare `O3` flag and add `blas-src` / `lapack-src` to your downstream binary's `Cargo.toml` with the appropriate features yourself.
`O3-openblas` does **not** use a system-installed OpenBLAS: the [`openblas-src`](https://crates.io/crates/openblas-src) crate downloads the OpenBLAS source tarball during the cargo build and compiles it, so it needs `gcc`, `gfortran`, `make`, and network access, but no BLAS system package.
The download happens over HTTPS through `openblas-src`'s default `rustls` TLS backend; if you depend on `openblas-src` directly with `default-features = false` (as some older guides suggest), you must re-enable one of its `rustls` / `native-tls` features yourself or the build will fail.

System libraries still need to be present on the host for `O3-openblas` and `O3-netlib`; install them with:
`O3-openblas-system` skips the source build and links the OpenBLAS already installed on the host, discovered via `pkg-config`:

| Platform | Install |
| --------------------- | ---------------------------------------------------- |
| Debian / Ubuntu | `sudo apt install libopenblas-dev liblapack-dev` |
| Fedora / RHEL | `sudo dnf install openblas-devel lapack-devel` |
| Arch Linux | `sudo pacman -S openblas lapack` |
| macOS (Homebrew) | `brew install openblas lapack` |
| Debian / Ubuntu | `sudo apt install libopenblas-dev` |
| Fedora / RHEL | `sudo dnf install openblas-devel` |
| Arch Linux | `sudo pacman -S openblas` |
| macOS (Homebrew) | `brew install openblas` |

`O3-accelerate` and `O3-mkl` ship their own backend (Apple's framework and Intel's redistributable, respectively), so they need no further system packages.
If you need a backend not in the list above (for example BLIS or R's BLAS), enable the bare `O3` flag and add `blas-src` / `lapack-src` to your downstream binary's `Cargo.toml` with the appropriate features yourself.

> **Note:** `O3-accelerate` only builds on Apple targets. Enabling it on Linux or Windows fails while compiling `accelerate-src` with ``error: library kind `framework` is only supported on Apple targets``; pick `O3-openblas`, `O3-mkl`, or `O3-netlib` instead. For the same reason, exclude `O3-accelerate` (and `O3-mkl` / `O3-netlib` unless their toolchains are installed) when running tools like `cargo hack --each-feature` on Linux.

Expand Down Expand Up @@ -335,6 +337,7 @@ cargo add peroxide --features "<FEATURES>" # opt-in features
| Goal | Command |
| ------------------------------------------------- | ------------------------------------------------------------------------- |
| Linear algebra on Linux / Windows | `cargo add peroxide --features O3-openblas` |
| Linear algebra with system OpenBLAS | `cargo add peroxide --features O3-openblas-system` |
| Linear algebra on macOS | `cargo add peroxide --features O3-accelerate` |
| Plotting via Python / matplotlib | `cargo add peroxide --features plot` |
| DataFrame + Parquet I/O | `cargo add peroxide --features parquet` |
Expand All @@ -350,7 +353,8 @@ The remaining single-crate flags exist so advanced users can pull in just one op

| Flag | Requires | Purpose |
| ---------------- | ----------------------- | ------------------------------------------------------------- |
| `O3-openblas` | OpenBLAS | BLAS / LAPACK accelerated linear algebra (Linux / Windows) |
| `O3-openblas` | OpenBLAS (from source) | BLAS / LAPACK accelerated linear algebra (Linux / Windows) |
| `O3-openblas-system` | OpenBLAS (system) | Same, linking the system-installed OpenBLAS via pkg-config |
| `O3-accelerate` | Apple Accelerate | Same, using the Accelerate framework on macOS |
| `O3-mkl` | Intel MKL | Same, using Intel MKL |
| `O3-netlib` | Netlib | Same, using the reference Netlib BLAS |
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
//!
//! ## Useful tips for features
//!
//! * If you want to use _QR_, _SVD_, or _Cholesky Decomposition_, you should use the `O3` feature. These decompositions are not implemented in the `default` feature.
//! * If you want to use _QR_, _SVD_, or _Cholesky Decomposition_, enable one of the BLAS backend features: `O3-openblas` (compiles OpenBLAS from source), `O3-openblas-system` (links the system-installed OpenBLAS), `O3-accelerate`, `O3-mkl`, or `O3-netlib`. These decompositions are not implemented in the `default` feature. The bare `O3` flag is an advanced escape hatch that expects you to supply a `blas-src` / `lapack-src` backend yourself.
//!
//! * If you want to save your numerical results, consider using the `parquet` or `nc` features, which correspond to the `parquet` and `netcdf` file formats, respectively. These formats are much more efficient than `csv` and `json`.
//!
Expand All @@ -165,6 +165,10 @@ extern crate lapack;
extern crate blas_src as _;
#[cfg(feature = "lapack-src")]
extern crate lapack_src as _;
// `O3-openblas-system` re-exposes `openblas-src` directly so its `system`
// feature can be forwarded; link the crate here for the same reason.
#[cfg(feature = "openblas-src")]
extern crate openblas_src as _;

#[cfg(feature = "plot")]
extern crate pyo3;
Expand Down
Loading