intel / openvino-rs

Rust bindings for OpenVINO™
Apache License 2.0
82 stars 23 forks source link

Unable to find an existing installation of library: tbb #61

Closed chemicstry closed 1 year ago

chemicstry commented 1 year ago

I'm using openvino 2022.3.0 on ubuntu 22.04 and encountered the following building error:

The following warnings were emitted during compilation:

warning: Found library to link against: /home/user/openvino_2022.3.0/runtime/lib/intel64/libopenvino.so
warning: Found library to link against: /home/user/openvino_2022.3.0/runtime/lib/intel64/libopenvino_c.so

error: failed to run custom build command for `openvino-sys v0.4.2 (https://github.com/intel/openvino-rs#0bc3a8f1)`

Caused by:
  process didn't exit successfully: `/home/user/test/target/release/build/openvino-sys-ff82748da3e36088/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=build.rs
  cargo:rerun-if-changed=Cargo.toml
  cargo:rerun-if-changed=src/generated/mod.rs
  cargo:rerun-if-changed=src/generated/functions.rs
  cargo:rerun-if-changed=src/generated/types.rs
  cargo:rerun-if-changed=src/linking/dynamic.rs
  cargo:rerun-if-changed=src/linking/runtime.rs
  cargo:rerun-if-changed=src/linking/mod.rs
  cargo:rerun-if-changed=src/lib.rs
  cargo:rustc-cfg=feature="dynamic-linking"
  cargo:warning=Found library to link against: /home/user/openvino_2022.3.0/runtime/lib/intel64/libopenvino.so
  cargo:warning=Found library to link against: /home/user/openvino_2022.3.0/runtime/lib/intel64/libopenvino_c.so

  --- stderr
  thread 'main' panicked at 'Unable to find an existing installation of library: tbb', /home/user/.cargo/git/checkouts/openvino-rs-d79b91ff7f77ee0b/372f4c7/crates/openvino-sys/build.rs:152:13

OpenVino is built from source using:

git clone -b 2022.3.0 https://github.com/openvinotoolkit/openvino.git
cd openvino/
git submodule update --init --recursive
chmod +x install_build_dependencies.sh
sudo ./install_build_dependencies.sh 
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make --jobs=$(nproc --all)
cmake --install . --prefix ~/openvino_2022.3.0

It seems that it can't find libtbb, because it is in different path than defined search paths:

$ ldconfig -p | grep libtbb
        libtbbmalloc_proxy.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbbmalloc_proxy.so.2
        libtbbmalloc_proxy.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbbmalloc_proxy.so
        libtbbmalloc.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbbmalloc.so.2
        libtbbmalloc.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbbmalloc.so
        libtbb.so.12 (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbb.so.12
        libtbb.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbb.so.2
        libtbb.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libtbb.so

Setting export LD_LIBRARY_PATH=/lib/x86_64-linux-gnu/ fixes the problem. I'm not sure where exactly the cause is, maybe Ubuntu 22.04 moved libtbb from /usr/lib to /lib/x86_64-linux-gnu?

abrown commented 1 year ago

Thanks for the report. The reason for this is a hole in the openvino-finder code. It doesn't understand how to find shared libraries on the default system paths. In the new 2023 release, OpenVINO will install itself to more traditional locations (like /lib/x86_64-linux-gnu, e.g.) so the openvino-finder will have to gain this ability soon-ish. I have been mulling over how to best do this without listing all the locations for all of the supported OSes (suggestions welcome!).

chemicstry commented 1 year ago

In the new 2023 release, OpenVINO will install itself to more traditional locations (like /lib/x86_64-linux-gnu, e.g.) so the openvino-finder will have to gain this ability soon-ish.

This is awesome. It was a struggle each time I needed to install OpenVino (except pip versions). The setupvars.sh is also weird, I would expect the installed library to be always available like all other libs.

I have been mulling over how to best do this without listing all the locations for all of the supported OSes (suggestions welcome!).

I think good examples here are gstreamer-rs and opencv-rust. Both of them primarily use pkg-config, which is the prefered method for linux, but works okay for mac and windows too. In addition to that, opencv also uses cmake and vcpkg as fallback methods. Listing all search paths is pretty uncommon. Environment variables are mostly used to override auto discovery.

abrown commented 1 year ago

Yeah, I had looked at pkg-config but was concerned about the non-Linux OSes. The biggest roadblock at the moment is being able to test this in those environments.

abrown commented 1 year ago

Took a look at this today and found some problems:

Problem #1: the pkg-config crate expects to be used at build time, not run time (and we have a --features runtime-linking need)

Problem #2: it doesn't find the openvino_c library

chemicstry commented 1 year ago

Problem #1: the pkg-config crate expects to be used at build time, not run time (and we have a --features runtime-linking need)

Yeah it's supposed to only be used in build.rs. Not sure if using it at runtime has issues. Btw, what is the purpose of runtime linking and how is it different from dynamic? Is it so that user can specify lib path at runtime?

  • it expects to shell out to call the pkg-config binary — is this a performance concern?

I don't see a reason why it would be. pkg-config is used by many C/C++ build systems and Rust libs. For end users openvino's build.rs would only be invoked once for initial clean build. Subsequent incremental builds do not invoke build.rs unless openvino-rs itself is modified.

  • additionally it emits cargo build.rs text; I was able to disable this with .env_metadata(false).cargo_metadata(false)

It is important, because it emits rerun-if-changed commands to rerun build.rs when environment variables for pkg-config are changed.

Problem #2: it doesn't find the openvino_c library

  • we would need to have a file like /usr/lib64/pkgconfig/openvino_c.pc, I think, but OpenVINO does not install this

I wonder if you could use the regular openvino.pc? It seems to include both openvino and openvino_c. You could filter out the C++ libs.

  • I also do not see a tbb.pc file, which may also be necessary (re: this issue)

It works for me on Ubuntu 22.04. pkg-config --debug tbb shows that it uses /usr/lib/x86_64-linux-gnu/pkgconfig/tbb.pc. What OS were you using?

abrown commented 1 year ago

I'm on Fedora, so there might be some differences there.

Let me explain a bit about openvino-finder: the openvino crate is used by Wasmtime for one of its wasi-nn backends. The Wasmtime binary doesn't want to have a library dependency on openvino; in other words, Wasmtime should work fine whether OpenVINO is installed on the system or not. If it is, then wasi-nn function calls will need to be satisfied by a shared library that is loaded at runtime (e.g., dlopen). The openvino-finder crate locates the shared library (see find for the logic there) and the openvino-sys crate binds to it using the libloading crate (which on Linux eventually delegates to dlopen). All of this runtime-linking behavior is enabled with --features runtime-linking. But, since users may also want to link directly to the OpenVINO libraries (I call this "dynamic linking" in the build.rs), that is also a possibility in the build.rs file; this case re-uses openvino-finder but emits the right Cargo incantations in build.rs.

Hopefully that explains the complexity here: we need to support both dynamic and runtime linking and the support needs to be reliable. And there's another twist: with OpenVINO 2022.3 (I misspoke earlier, it is not 2023), the files can be either on the system paths (when installing from an RPM, DEB, etc.) or on the custom paths that openvino-finder already understands (when installing from a TAR or ZIP). I can't "just use pkg-config" because I would like this to work everywhere (not just Ubuntu) and with different kinds of installation methods. I'm still thinking through what the options are — suggestions welcome!

chemicstry commented 1 year ago

Thanks for the in depth explanation. The runtime linking issue is now clear. I assume there are other libraries that do runtime linking (not even necessarily rust), it would be interesting to see how they do it. I will report when if I find any examples worth considering.

The reason why I'm suggesting pkg-config is because that's what I observed from the whole linux ecosystem. Almost all gnu and alike libraries have pkg-config scripts so it's not an Ubuntu thing. The biggest problem with pkg-config is probably windows, which is a bit of a wild west in terms of library auto discovery.

abrown commented 1 year ago

I believe this should now all be fixed in v0.5.0 — let me know what you think!