diff --git a/.github/workflows/test_and_coverage.yml b/.github/workflows/test_and_coverage.yml index 143ce8d5..8f101a60 100644 --- a/.github/workflows/test_and_coverage.yml +++ b/.github/workflows/test_and_coverage.yml @@ -7,7 +7,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Libraries run: | - bash zscripts/01-ubuntu-openblas-debian.bash + bash case-a-openblas-debian.bash - name: Install Rust run: | rustup toolchain install nightly --component llvm-tools-preview @@ -20,9 +20,9 @@ jobs: curl -LsSf https://github.com/taiki-e/cargo-llvm-cov/releases/latest/download/cargo-llvm-cov-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin - name: Generate code coverage run: | - cargo llvm-cov --all-features --workspace --ignore-filename-regex 'build.rs|mem_check.rs|solve_matrix_market.rs' --lcov --output-path lcov.info + cargo llvm-cov --workspace --ignore-filename-regex 'build.rs|mem_check.rs|solve_matrix_market.rs' --lcov --output-path lcov.info - name: Upload to codecov.io - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{secrets.CODECOV_TOKEN}} files: lcov.info diff --git a/.github/workflows/test_with_compiled_libs.yml b/.github/workflows/test_with_compiled_libs.yml deleted file mode 100644 index 66389bf5..00000000 --- a/.github/workflows/test_with_compiled_libs.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Test with Compiled Libs -on: [pull_request] -jobs: - test_with_compiled_libs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install Libraries - run: | - bash zscripts/02-ubuntu-openblas-compile.bash - - name: Run tests - env: - RUSSELL_SPARSE_USE_LOCAL_MUMPS: 1 - RUSSELL_SPARSE_USE_LOCAL_UMFPACK: 1 - run: | - RUST_BACKTRACE=1 cargo test diff --git a/.github/workflows/test_with_intel_mkl.yml b/.github/workflows/test_with_intel_mkl.yml index 7f8a1879..379a52c0 100644 --- a/.github/workflows/test_with_intel_mkl.yml +++ b/.github/workflows/test_with_intel_mkl.yml @@ -7,12 +7,8 @@ jobs: - uses: actions/checkout@v4 - name: Install Libraries run: | - bash zscripts/03-ubuntu-intel-mkl-compile.bash + bash case-b-intel-mkl-local-libs.bash - name: Run tests - env: - RUSSELL_LAB_USE_INTEL_MKL: 1 - RUSSELL_SPARSE_USE_LOCAL_MUMPS: 1 - RUSSELL_SPARSE_USE_LOCAL_UMFPACK: 1 - RUSSELL_SPARSE_WITH_INTEL_DSS: 1 run: | - RUST_BACKTRACE=1 cargo test + RUST_BACKTRACE=1 cargo test --features intel_mkl + diff --git a/.github/workflows/test_with_local_libs.yml b/.github/workflows/test_with_local_libs.yml new file mode 100644 index 00000000..6ae129fa --- /dev/null +++ b/.github/workflows/test_with_local_libs.yml @@ -0,0 +1,13 @@ +name: Test with local libs +on: [pull_request] +jobs: + test_with_local_libs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Libraries + run: | + bash case-a-openblas-local-libs.bash + - name: Run tests + run: | + RUST_BACKTRACE=1 cargo test --features local_libs diff --git a/.vscode/settings.json b/.vscode/settings.json index 1ca351b4..20a9269e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "cSpell.words": [ "aiᵢⱼ", + "archlinux", "Arioli", "BLACS", "blasint", @@ -23,6 +24,7 @@ "dsyrk", "dtype", "Flannery", + "gfortran", "ifort", "IIIₛ", "ᵢⱼₖₗ", @@ -36,12 +38,14 @@ "ldvl", "ldvr", "ldvt", + "libmetis", "linalg", "lredrhs", "lrhs", "lsol", "lwork", "memcheck", + "msgpass", "nelt", "odyad", "oneapi", diff --git a/README.md b/README.md index 61032f2c..c0121904 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![codecov](https://codecov.io/gh/cpmech/russell/graph/badge.svg?token=PQWSKMZQXT)](https://codecov.io/gh/cpmech/russell) [![Test & Coverage](https://github.com/cpmech/russell/actions/workflows/test_and_coverage.yml/badge.svg)](https://github.com/cpmech/russell/actions/workflows/test_and_coverage.yml) -[![Test with Compiled Libs](https://github.com/cpmech/russell/actions/workflows/test_with_compiled_libs.yml/badge.svg)](https://github.com/cpmech/russell/actions/workflows/test_with_compiled_libs.yml) +[![Test with local libs](https://github.com/cpmech/russell/actions/workflows/test_with_local_libs.yml/badge.svg)](https://github.com/cpmech/russell/actions/workflows/test_with_local_libs.yml) [![Test with Intel MKL](https://github.com/cpmech/russell/actions/workflows/test_with_intel_mkl.yml/badge.svg)](https://github.com/cpmech/russell/actions/workflows/test_with_intel_mkl.yml) ![Bertrand Russell](Bertrand_Russell_1957.jpg) @@ -15,19 +15,18 @@ * [Crates](#crates) * [Installation on Debian/Ubuntu/Linux](#installation) * [Installation on macOS](#macos) +* [Number of threads](#threads) * [Examples](#examples) * [Todo list](#todo) * [Code coverage](#coverage) ## Introduction -**Russell** (Rust Scientific Library) assists in developing scientific computations using the Rust language. Our initial focus is on numerical methods and solvers for sparse linear systems and differential equations; however, anything is possible 😉. +**Russell** (Rust Scientific Library) assists in developing scientific computations using the Rust language. The "main" crate here is [russell_lab](https://github.com/cpmech/russell/tree/main/russell_lab), a **mat**rix-vector **lab**oratory, which provides the fundamental `Vector` and `Matrix` structures and several functions to perform linear algebra computations. Thus, we recommend looking at [russell_lab](https://github.com/cpmech/russell/tree/main/russell_lab) first. -The next interesting crate is [russell_sparse](https://github.com/cpmech/russell/tree/main/russell_sparse), which implements sparse matrix structures such as COO (coordinates), CSC (compressed sparse column), and CSR (compressed sparse row) formats. `russell_sparse` also wraps powerful linear system solvers such as [UMFPACK](https://github.com/DrTimothyAldenDavis/SuiteSparse) and [MUMPS](https://mumps-solver.org). - -This library aims to wrap the best solutions (e.g., UMFPACK) while maintaining a very **clean** and idiomatic Rust code. See our [Todo list](#todo). The code must also be simple to use and thoroughly tested with a minimum [coverage](#coverage) of 95%. +Next, we recommend looking at the [russell_sparse](https://github.com/cpmech/russell/tree/main/russell_sparse) crate, which implements sparse matrix structures such as COO (coordinates), CSC (compressed sparse column), and CSR (compressed sparse row) formats. `russell_sparse` also wraps powerful linear system solvers such as [UMFPACK](https://github.com/DrTimothyAldenDavis/SuiteSparse) and [MUMPS](https://mumps-solver.org). ## Crates @@ -46,88 +45,83 @@ External associated and recommended crates: ## Installation on Debian/Ubuntu/Linux -**Russell** depends on external (non-Rust) packages for linear algebra and the solution of large sparse linear systems. For instance, the following need to be installed: +**Russell** depends on external (non-Rust) packages for linear algebra and the solution of large sparse linear systems. The following libraries are required: -* [OpenBLAS](https://github.com/OpenMathLib/OpenBLAS) **xor** [Intel MKL](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2023-2/overview.html) -* [UMFPACK](https://github.com/DrTimothyAldenDavis/SuiteSparse) and [MUMPS](https://mumps-solver.org) -* (optional) [Intel DSS](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2023-2/direct-sparse-solver-dss-interface-routines.html) +* [OpenBLAS](https://github.com/OpenMathLib/OpenBLAS) or [Intel MKL](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2023-2/overview.html) +* [MUMPS](https://mumps-solver.org) and [UMFPACK](https://github.com/DrTimothyAldenDavis/SuiteSparse) -The above packages may be installed via `apt`; however the Debian packages may lack features that boost performance (e.g., Metis ordering for MUMPS is missing in Debian). Therefore, we may compile UMFPACK and MUMPS locally and install them in `/usr/local`. +Note that MUMPS in Debian lacks some features (e.g., Metis). Also, MUMPS in Debian is linked with OpenMPI, which may cause issues when using other MPI libraries (see, e.g., [msgpass](https://github.com/cpmech/msgpass)). Thus, an option is available to use **locally compiled** MUMPS (and UMFPACK). Furthermore, when using Intel MKL, MUMPS and UMFPACK must be locally compiled because they need to be linked with the MKL libraries. -In summary, we have three options: +In summary, the following options are available: -1. Use the standard Debian packages based on OpenBLAS (default) -2. Compile MUMPS and UMFPACK with OpenBLAS -3. Compile MUMPS and UMFPACK with Intel MKL (and enable the Intel DSS solver) +* **Case A:** OpenBLAS with the default Debian libraries +* **Case A:** OpenBLAS with locally compiled libraries +* **Case B:** Intel MKL with locally compiled libraries -Options 2 and 3 require the following environment variables: +### Case A: OpenBLAS -```bash -export RUSSELL_SPARSE_USE_LOCAL_MUMPS=1 -export RUSSELL_SPARSE_USE_LOCAL_UMFPACK=1 -``` +#### Default Debian packages -Option 3 also requires the following environment variables: +Run: ```bash -export RUSSELL_LAB_USE_INTEL_MKL=1 -export RUSSELL_SPARSE_WITH_INTEL_DSS=1 +bash case-a-openblas-debian.bash ``` -For convenience, you may use the scripts in the [russell/zscripts](https://github.com/cpmech/russell/tree/main/zscripts) directory. +#### Locally compiled libraries (feature = local_libs) -**1.** Use the standard Debian packages based on OpenBLAS: +Run: ```bash -bash zscripts/01-ubuntu-openblas-debian.bash +bash case-a-openblas-local-libs.bash ``` -**2. (xor)** compile MUMPS and UMFPACK with OpenBLAS: +Then, add `local_libs` to your Cargo.toml or use `cargo build --features local_libs` -```bash -bash zscripts/02-ubuntu-openblas-compile.bash -``` +### Case B: Intel MKL (feature = intel_mkl) -**3. (xor)** compile MUMPS and UMFPACK with Intel MKL: +Run: ```bash -bash zscripts/03-ubuntu-intel-mkl-compile.bash +bash case-b-intel-mkl-local-libs.bash ``` -The compiled MUMPS files will be installed in `/usr/local/include/mumps` and `/usr/local/lib/mumps`. +Then, add `intel_mkl` to your Cargo.toml or use `cargo build --features intel_mkl` (note that the `local_libs` feature will be automatically enabled). -The compiled UMFPACK files will be installed in `/usr/local/include/umfpack` and `/usr/local/lib/umfpack`. +### Resulting files -### Number of threads +If locally compiled, the above scripts will save the resulting files in `/usr/local/lib/{mumps,umfpack}` and `/usr/local/include/{mumps,umfpack}`. -By default, OpenBLAS will use all available threads, including Hyper-Threads that may worsen the performance. Thus, it is best to set the following environment variable: +## Installation on macOS + +Currently, only OpenBLAS has been tested on macOS. + +First, install [Homebrew](https://brew.sh/). Then, run: ```bash -export OPENBLAS_NUM_THREADS= +brew install lapack openblas ``` -Substitute `` with the correct value from your system. - -Furthermore, if working on a multi-threaded application where the solver should not be multi-threaded on its own (e.g., running parallel calculations in an optimization tool), you may set: +Next, we must set the `LIBRARY_PATH`: ```bash -export OPENBLAS_NUM_THREADS=1 +export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix)/opt/lapack/lib:$(brew --prefix)/opt/openblas/lib ``` -## Installation on macOS - -At this time, only OpenBLAS has been tested on macOS---we still need to study how to use MUMPS and UMFPACK on macOS. +## Number of threads -First, install [Homebrew](https://brew.sh/). Then, run: +By default, OpenBLAS will use all available threads, including Hyper-Threads that may worsen the performance. Thus, it is best to set the following environment variable: ```bash -brew install lapack openblas +export OPENBLAS_NUM_THREADS= ``` -Next, we must set the `LIBRARY_PATH`: +Substitute `` with the correct value from your system. + +Furthermore, if working on a multi-threaded application where the solver should not be multi-threaded on its own (e.g., running parallel calculations in an optimization tool), you may set: ```bash -export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix)/opt/lapack/lib:$(brew --prefix)/opt/openblas/lib +export OPENBLAS_NUM_THREADS=1 ``` ## Examples @@ -303,7 +297,7 @@ fn main() -> Result<(), StrError> { // 3 . 4 . 6 // . -1 -3 2 . // . . 1 . . - // . 4 2 . 1 + // . 4 2 . 1 let mut coo = SparseMatrix::new_coo(ndim, ndim, nnz, None, false)?; coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate @@ -356,12 +350,12 @@ fn main() -> Result<(), StrError> { - [x] Implement more examples - [ ] Implement more benchmarks - [x] Wrap Intel MKL (option for OpenBLAS) - - [x] Add more complex numbers functions + - [x] Add more complex number functions - [ ] Add fundamental functions to `russell_lab` - [ ] Implement the modified Bessel functions - [ ] Implement some numerical methods in `russell_lab` - [ ] Implement Brent's solver - - [ ] Implement solver for the cubic equation + - [ ] Implement a solver for the cubic equation - [x] Implement numerical derivation - [x] Implement numerical Jacobian function - [ ] Implement Newton's method for nonlinear systems @@ -378,13 +372,13 @@ fn main() -> Result<(), StrError> { - [x] Implement the C-interface to Intel DSS - [ ] Write the conversion from COO to CSC in Rust - [ ] Possibly re-write (after benchmarking) the conversion from COO to CSR - - [ ] Re-study the possibility to wrap SuperLU (see deleted branch) + - [ ] Re-study the possibility of wrapping SuperLU (see deleted branch) - [ ] Improve crate `russell_stat` - [x] Add probability distribution functions - [x] Implement drawing of ASCII histograms - [ ] Improve the `russell_tensor` crate - [x] Implement functions to calculate invariants - - [x] Implement first and second order derivatives of invariants + - [x] Implement first and second-order derivatives of invariants - [x] Implement some high-order derivatives - [ ] Implement standard continuum mechanics tensors - [ ] Make it possible to install Russell on Windows and macOS @@ -395,18 +389,18 @@ fn main() -> Result<(), StrError> { ### Sunburst -The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively. +The innermost circle is the entire project; folders are moving away from the center, then a single file. Each slice's size and color represent the number of statements and the coverage, respectively. ![Sunburst](https://codecov.io/gh/cpmech/russell/graphs/sunburst.svg?token=PQWSKMZQXT) ### Grid -Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively. +Each block represents a single file in the project. The size and color of each block are described by the number of statements and the coverage, respectively. ![Grid](https://codecov.io/gh/cpmech/russell/graphs/tree.svg?token=PQWSKMZQXT) ### Icicle -The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively. +The top section represents the entire project. Proceeding with folders and, finally, individual files. Each slice's size and color define the number of statements and the coverage, respectively. ![Icicle](https://codecov.io/gh/cpmech/russell/graphs/icicle.svg?token=PQWSKMZQXT) diff --git a/zscripts/01-ubuntu-openblas-debian.bash b/case-a-openblas-debian.bash similarity index 100% rename from zscripts/01-ubuntu-openblas-debian.bash rename to case-a-openblas-debian.bash diff --git a/zscripts/02-ubuntu-openblas-compile.bash b/case-a-openblas-local-libs.bash similarity index 100% rename from zscripts/02-ubuntu-openblas-compile.bash rename to case-a-openblas-local-libs.bash diff --git a/zscripts/03-ubuntu-intel-mkl-compile.bash b/case-b-intel-mkl-local-libs.bash similarity index 100% rename from zscripts/03-ubuntu-intel-mkl-compile.bash rename to case-b-intel-mkl-local-libs.bash diff --git a/russell_lab/Cargo.toml b/russell_lab/Cargo.toml index 0d345449..cc7f40d5 100644 --- a/russell_lab/Cargo.toml +++ b/russell_lab/Cargo.toml @@ -11,6 +11,9 @@ readme = "README.md" categories = ["mathematics", "science"] keywords = ["matrix", "vector", "linspace"] +[features] +intel_mkl = [] + [dependencies] criterion = "0.5" num-complex = { version = "0.4", features = ["serde"] } diff --git a/russell_lab/README.md b/russell_lab/README.md index d77aacc0..5bf1c251 100644 --- a/russell_lab/README.md +++ b/russell_lab/README.md @@ -70,7 +70,7 @@ fn main() -> Result<(), StrError> { ]); let a_copy = a.clone(); - // compute pseudo-inverse matrix (because it's square) + // compute pseudo-inverse matrix let mut ai = Matrix::new(2, 3); mat_pseudo_inverse(&mut ai, &mut a)?; diff --git a/russell_lab/build.rs b/russell_lab/build.rs index a5222b9b..c48bb8ac 100644 --- a/russell_lab/build.rs +++ b/russell_lab/build.rs @@ -1,46 +1,46 @@ -use std::env; - +#[cfg(feature = "intel_mkl")] const MKL_VERSION: &str = "2023.2.0"; +#[cfg(feature = "intel_mkl")] +fn handle_intel_mkl() { + // Intel MKL + cc::Build::new() + .file("c_code/interface_blas.c") + .include(format!("/opt/intel/oneapi/mkl/{}/include", MKL_VERSION)) + .define("USE_INTEL_MKL", None) + .compile("c_code_interface_blas"); + println!( + "cargo:rustc-link-search=native=/opt/intel/oneapi/mkl/{}/lib/intel64", + MKL_VERSION + ); + println!( + "cargo:rustc-link-search=native=/opt/intel/oneapi/compiler/{}/linux/compiler/lib/intel64_lin", + MKL_VERSION + ); + println!("cargo:rustc-link-lib=mkl_intel_lp64"); + println!("cargo:rustc-link-lib=mkl_intel_thread"); + println!("cargo:rustc-link-lib=mkl_core"); + println!("cargo:rustc-link-lib=pthread"); + println!("cargo:rustc-link-lib=m"); + println!("cargo:rustc-link-lib=dl"); + println!("cargo:rustc-link-lib=iomp5"); + println!("cargo:rustc-cfg=use_intel_mkl"); +} + +#[cfg(not(feature = "intel_mkl"))] +fn handle_intel_mkl() { + // OpenBLAS + cc::Build::new() + .file("c_code/interface_blas.c") + .include("/usr/include/openblas") // for archlinux + .compile("c_code_interface_blas"); + println!("cargo:rustc-link-lib=dylib=openblas"); + println!("cargo:rustc-link-lib=dylib=lapack"); +} + fn main() { // math functions cc::Build::new().file("c_code/math_functions.c").compile("c_code"); - - // option - let use_intel_mkl = match env::var("RUSSELL_LAB_USE_INTEL_MKL") { - Ok(v) => v == "1" || v.to_lowercase() == "true", - Err(_) => false, - }; - - if use_intel_mkl { - // Intel MKL - cc::Build::new() - .file("c_code/interface_blas.c") - .include(format!("/opt/intel/oneapi/mkl/{}/include", MKL_VERSION)) - .define("USE_INTEL_MKL", None) - .compile("c_code_interface_blas"); - println!( - "cargo:rustc-link-search=native=/opt/intel/oneapi/mkl/{}/lib/intel64", - MKL_VERSION - ); - println!( - "cargo:rustc-link-search=native=/opt/intel/oneapi/compiler/{}/linux/compiler/lib/intel64_lin", - MKL_VERSION - ); - println!("cargo:rustc-link-lib=mkl_intel_lp64"); - println!("cargo:rustc-link-lib=mkl_intel_thread"); - println!("cargo:rustc-link-lib=mkl_core"); - println!("cargo:rustc-link-lib=pthread"); - println!("cargo:rustc-link-lib=m"); - println!("cargo:rustc-link-lib=dl"); - println!("cargo:rustc-link-lib=iomp5"); - println!("cargo:rustc-cfg=use_intel_mkl"); - } else { - // OpenBLAS - cc::Build::new() - .file("c_code/interface_blas.c") - .compile("c_code_interface_blas"); - println!("cargo:rustc-link-lib=dylib=openblas"); - println!("cargo:rustc-link-lib=dylib=lapack"); - } + // BLAS functions + handle_intel_mkl(); } diff --git a/russell_lab/src/matrix/mat_pseudo_inverse.rs b/russell_lab/src/matrix/mat_pseudo_inverse.rs index d7abbc24..660e6079 100644 --- a/russell_lab/src/matrix/mat_pseudo_inverse.rs +++ b/russell_lab/src/matrix/mat_pseudo_inverse.rs @@ -41,7 +41,7 @@ const SINGLE_VALUE_RCOND: f64 = 1e-15; /// ]); /// let a_copy = a.clone(); /// -/// // compute pseudo-inverse matrix (because it's square) +/// // compute pseudo-inverse matrix /// let mut ai = Matrix::new(2, 3); /// mat_pseudo_inverse(&mut ai, &mut a)?; /// diff --git a/russell_sparse/Cargo.toml b/russell_sparse/Cargo.toml index d4be9f23..57595ef3 100644 --- a/russell_sparse/Cargo.toml +++ b/russell_sparse/Cargo.toml @@ -11,6 +11,10 @@ readme = "README.md" categories = ["mathematics", "science"] keywords = ["matrix", "sparse", "solver"] +[features] +local_libs = [] +intel_mkl = ["local_libs"] + [dependencies] russell_lab = { path = "../russell_lab", version = "0.7.1" } structopt = "0.3" diff --git a/russell_sparse/build.rs b/russell_sparse/build.rs index 1f27978f..a09f77b6 100644 --- a/russell_sparse/build.rs +++ b/russell_sparse/build.rs @@ -1,81 +1,75 @@ -use std::env; - +#[cfg(feature = "intel_mkl")] const MKL_VERSION: &str = "2023.2.0"; -fn main() { - // compile the MUMPS interface - let use_local_mumps = match env::var("RUSSELL_SPARSE_USE_LOCAL_MUMPS") { - Ok(v) => v == "1" || v.to_lowercase() == "true", - Err(_) => false, - }; - if use_local_mumps { - cc::Build::new() - .file("c_code/interface_mumps.c") - .include("/usr/local/include/mumps") - .compile("c_code_interface_mumps"); - println!("cargo:rustc-link-search=native=/usr/local/lib/mumps"); - println!("cargo:rustc-link-lib=dylib=dmumps_cpmech"); - println!("cargo:rustc-cfg=local_mumps"); - } else { - cc::Build::new() - .file("c_code/interface_mumps.c") - .compile("c_code_interface_mumps"); - println!("cargo:rustc-link-lib=dylib=dmumps_seq"); - } +#[cfg(feature = "local_libs")] +fn handle_local_libs() { + // local MUMPS + cc::Build::new() + .file("c_code/interface_mumps.c") + .include("/usr/local/include/mumps") + .compile("c_code_interface_mumps"); + println!("cargo:rustc-link-search=native=/usr/local/lib/mumps"); + println!("cargo:rustc-link-lib=dylib=dmumps_cpmech"); + println!("cargo:rustc-cfg=local_mumps"); + // local UMFPACK + cc::Build::new() + .file("c_code/interface_umfpack.c") + .include("/usr/local/include/umfpack") + .compile("c_code_interface_umfpack"); + println!("cargo:rustc-link-search=native=/usr/local/lib/umfpack"); + println!("cargo:rustc-link-lib=dylib=umfpack"); + println!("cargo:rustc-cfg=local_umfpack"); +} - // compile the UMFPACK interface - let use_local_umfpack = match env::var("RUSSELL_SPARSE_USE_LOCAL_UMFPACK") { - Ok(v) => v == "1" || v.to_lowercase() == "true", - Err(_) => false, - }; - if use_local_umfpack { - cc::Build::new() - .file("c_code/interface_umfpack.c") - .include("/usr/local/include/umfpack") - .compile("c_code_interface_umfpack"); - println!("cargo:rustc-link-search=native=/usr/local/lib/umfpack"); - println!("cargo:rustc-link-lib=dylib=umfpack"); - println!("cargo:rustc-cfg=local_umfpack"); - } else { - cc::Build::new() - .file("c_code/interface_umfpack.c") - .include("/usr/include/suitesparse") - .compile("c_code_interface_umfpack"); - println!("cargo:rustc-link-lib=dylib=umfpack"); - } +#[cfg(not(feature = "local_libs"))] +fn handle_local_libs() { + // MUMPS + cc::Build::new() + .file("c_code/interface_mumps.c") + .compile("c_code_interface_mumps"); + println!("cargo:rustc-link-lib=dylib=dmumps_seq"); + // UMFPACK + cc::Build::new() + .file("c_code/interface_umfpack.c") + .include("/usr/include/suitesparse") + .compile("c_code_interface_umfpack"); + println!("cargo:rustc-link-lib=dylib=umfpack"); +} - // compile the Intel DSS interface - let with_intel_dss = match env::var("RUSSELL_SPARSE_WITH_INTEL_DSS") { - Ok(v) => v == "1" || v.to_lowercase() == "true", - Err(_) => false, - }; - if with_intel_dss { - // Find the link libs with - // pkg-config --libs mkl-dynamic-lp64-iomp - cc::Build::new() - .file("c_code/interface_intel_dss.c") - .include(format!("/opt/intel/oneapi/mkl/{}/include", MKL_VERSION)) - .define("WITH_INTEL_DSS", None) - .compile("c_code_interface_intel_dss"); - println!( - "cargo:rustc-link-search=native=/opt/intel/oneapi/mkl/{}/lib/intel64", - MKL_VERSION - ); - println!( - "cargo:rustc-link-search=native=/opt/intel/oneapi/compiler/{}/linux/compiler/lib/intel64_lin", - MKL_VERSION - ); - println!("cargo:rustc-link-lib=mkl_intel_lp64"); - println!("cargo:rustc-link-lib=mkl_intel_thread"); - println!("cargo:rustc-link-lib=mkl_core"); - println!("cargo:rustc-link-lib=pthread"); - println!("cargo:rustc-link-lib=m"); - println!("cargo:rustc-link-lib=dl"); - println!("cargo:rustc-link-lib=iomp5"); - println!("cargo:rustc-cfg=with_intel_dss"); - } else { - cc::Build::new() - .file("c_code/interface_intel_dss.c") - .compile("c_code_interface_intel_dss"); - } +#[cfg(feature = "intel_mkl")] +fn handle_intel_mkl() { + // Find the link libs with: pkg-config --libs mkl-dynamic-lp64-iomp + cc::Build::new() + .file("c_code/interface_intel_dss.c") + .include(format!("/opt/intel/oneapi/mkl/{}/include", MKL_VERSION)) + .define("WITH_INTEL_DSS", None) + .compile("c_code_interface_intel_dss"); + println!( + "cargo:rustc-link-search=native=/opt/intel/oneapi/mkl/{}/lib/intel64", + MKL_VERSION + ); + println!( + "cargo:rustc-link-search=native=/opt/intel/oneapi/compiler/{}/linux/compiler/lib/intel64_lin", + MKL_VERSION + ); + println!("cargo:rustc-link-lib=mkl_intel_lp64"); + println!("cargo:rustc-link-lib=mkl_intel_thread"); + println!("cargo:rustc-link-lib=mkl_core"); + println!("cargo:rustc-link-lib=pthread"); + println!("cargo:rustc-link-lib=m"); + println!("cargo:rustc-link-lib=dl"); + println!("cargo:rustc-link-lib=iomp5"); + println!("cargo:rustc-cfg=with_intel_dss"); +} + +#[cfg(not(feature = "intel_mkl"))] +fn handle_intel_mkl() { + cc::Build::new() + .file("c_code/interface_intel_dss.c") + .compile("c_code_interface_intel_dss"); +} + +fn main() { + handle_local_libs(); + handle_intel_mkl(); } diff --git a/russell_sparse/zscripts/memcheck.bash b/russell_sparse/zscripts/memcheck.bash index 948ef76f..adcddfff 100755 --- a/russell_sparse/zscripts/memcheck.bash +++ b/russell_sparse/zscripts/memcheck.bash @@ -1,23 +1,25 @@ #!/bin/bash -if [[ -z "${RUSSELL_SPARSE_WITH_INTEL_DSS}" ]]; then - WITH_DSS="0" -else - WITH_DSS="${RUSSELL_SPARSE_WITH_INTEL_DSS}" +# the first argument is the "mkl" option +BLAS_LIB=${1:-""} + +FEAT="" +if [ "${BLAS_LIB}" = "mkl" ]; then + FEAT="--features intel_mkl" fi -cargo build +cargo build $FEAT -cargo valgrind run --bin mem_check +VALGRIND="cargo valgrind run $FEAT" -cargo valgrind run --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d -cargo valgrind run --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d -g mumps -if [[ "$WITH_DSS" == "1" ]]; then - cargo valgrind run --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d --genie dss -fi +$VALGRIND --bin mem_check -cargo valgrind run --example nonlinear_system_4eqs -- -cargo valgrind run --example nonlinear_system_4eqs -- -g mumps +$VALGRIND --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d +$VALGRIND --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d -g mumps if [[ "$WITH_DSS" == "1" ]]; then - cargo valgrind run --example nonlinear_system_4eqs -- -g dss + $VALGRIND --bin solve_matrix_market -- data/matrix_market/bfwb62.mtx -d --genie dss fi + +$VALGRIND --example nonlinear_system_4eqs -- +$VALGRIND --example nonlinear_system_4eqs -- -g mumps +$VALGRIND --example nonlinear_system_4eqs -- -g dss