Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

russell_lab blas build #75

Closed
m4b opened this issue Feb 11, 2024 · 2 comments
Closed

russell_lab blas build #75

m4b opened this issue Feb 11, 2024 · 2 comments

Comments

@m4b
Copy link

m4b commented Feb 11, 2024

Hello, nice library!

On my archlinux system, I have openblas installed, and it's headers are at /usr/include/openblas/cblas.h; for whatever reason, when building I get this error:

  running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-4" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-o" "/home/m4b/git/russell/target/debug/build/russell_lab-8efc726f530eb1fc/out/c_code/interface_blas.o" "-c" "c_code/interface_blas.c"
  cargo:warning=c_code/interface_blas.c:18:10: fatal error: cblas.h: No such file or directory

  cargo:warning=   18 | #include "cblas.h"

  cargo:warning=      |          ^~~~~~~~~

  cargo:warning=compilation terminated.

  exit status: 1

  --- stderr

In attempting to debug, I discovered I can pass:

RUSSELL_LAB_USE_INTEL_MKL=1

However, more rustish would (probably) be to use a feature flag to opt into using the intel api.

Regardless I think finding the headers should succeed, it looks like this else branch in the build.rs needs slightly better handling:

        // 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");

There is also pkgconf which people usually use for this purpose to find headers, etc., e.g.:

pkgconf --cflags-only-I cblas
-I/usr/include/openblas

returns the correct path (and there is a rust crate to use at build time for this).

Lastly, and this is only partially related, the only function I'm using here is: https://docs.rs/russell_lab/0.7.2/russell_lab/matrix/fn.mat_pseudo_inverse.html

which works perfectly for me (thank you, it's results are identical in my test cases to the matlab and octave pinv), and it would be more ideal if this were pure rust and I could opt out of the blas linkage, but that is probably infeasible, and anyway, another issue entirely :)

Anyway, thanks for the great library!

@cpmech
Copy link
Owner

cpmech commented Feb 12, 2024

Hi, thank you for your suggestions! I've implemented most of them in the crate version 0.8.0 (pull request: #76)

First, Concerning cblas.h on Arch Linux, I've added a search to /usr/include/openblas in build.rs (see 15777b9). Hence, all should work now even without Intel MKL.

Second, it is a great idea to use Rust's features approach! So, I've implemented two optional features:

  • (default) no feature specification required. The code works with default dependencies
  • local_libs will require the sparse solvers compiled in /usr/local/...
  • intel_mkl (will enable local_libs too) will require the installation of Intel tools

For instance, to use Intel MKL:

cargo build --features intel_mkl

Third, I've tried to use pkg-config here, but will need more time to properly use it. I also want to see if more libraries are needed. So, this goes to my TODO list for now 😊

Good to hear that the pseudo inverse matches Octave's pinv (and Matlab). They use the same code base, effectively (OpenBLAS or Intel MKL). It would be hard to replace these ancient libraries...

Cheers.

@m4b
Copy link
Author

m4b commented Feb 12, 2024

Nice that was fast!

I tested latest git, and can confirm, this now works without env variables on my system, out of the box, and building with --features intel_mkl works as well, great stuff!

On that note, w.r.t. features the only general recommendation I've heard is that they are "additive" (i.e., two separate crates both dependent on a library with two features, one turning on one feature, and another crate turning on a separate feature, does not cause breakage in the downstream crate that might include both, as it has an "action at a distance feel", e.g., they change the signature of a function, depending on which is set, etc.); given how you've implemented it, this seems to satisfy this condition, though it can be tricky/not feasible when it comes to different build flags, using different native libraries, etc.

Thanks for working on this library :) will close this issue as confirmed it is fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants