Skip to content

Commit 3e732aa

Browse files
committed
openvino-finder: locate plugins.xml
This change adds a `find_plugins_xml` function to `openvino-finder` to locate the XML configuration describing the plugin libraries. In previous versions, the `plugins.xml` file was in the same directory as the shared library; in v2022.3, however, APT installations of OpenVINO have the `plugins.xml` file in a versioned sub-directory (e.g., `openvino-2022.3.0/`). When no path is provided to `Core::new`, this change will now search for the latest library and discover the `plugins.xml` file based on that. There are several escape hatches for specifying the path directly: pass the path directly to `Core::new` or set the `OPENVINO_PLUGINS_XML` environment variable.
1 parent 1512f8c commit 3e732aa

File tree

5 files changed

+80
-22
lines changed

5 files changed

+80
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/openvino-finder/src/lib.rs

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ use std::env;
1111
use std::fs;
1212
use std::path::{Path, PathBuf};
1313

14+
// We search for the library in various different places and early-return if we find it.
15+
macro_rules! check_and_return {
16+
($path: expr) => {
17+
log::debug!("Searching in: {}", $path.display());
18+
if $path.is_file() {
19+
log::info!("Found library at path: {}", $path.display());
20+
return Some($path);
21+
}
22+
};
23+
}
24+
1425
/// Find the path to an OpenVINO library. This will try:
1526
/// - the `OPENVINO_INSTALL_DIR` environment variable with several subdirectories appended
1627
/// - the `INTEL_OPENVINO_DIR` environment variable with several subdirectories appended
@@ -25,17 +36,6 @@ pub fn find(library_name: &str) -> Option<PathBuf> {
2536
);
2637
log::info!("Attempting to find library: {}", file);
2738

28-
// We search for the library in various different places and early-return if we find it.
29-
macro_rules! check_and_return {
30-
($path: expr) => {
31-
log::debug!("Searching in: {}", $path.display());
32-
if $path.is_file() {
33-
log::info!("Found library at path: {}", $path.display());
34-
return Some($path);
35-
}
36-
};
37-
}
38-
3939
// Search using the `OPENVINO_BUILD_DIR` environment variable; this may be set by users of the
4040
// `openvino-rs` library.
4141
if let Some(build_dir) = env::var_os(ENV_OPENVINO_BUILD_DIR) {
@@ -112,6 +112,7 @@ pub fn find(library_name: &str) -> Option<PathBuf> {
112112
const ENV_OPENVINO_INSTALL_DIR: &str = "OPENVINO_INSTALL_DIR";
113113
const ENV_OPENVINO_BUILD_DIR: &str = "OPENVINO_BUILD_DIR";
114114
const ENV_INTEL_OPENVINO_DIR: &str = "INTEL_OPENVINO_DIR";
115+
const ENV_OPENVINO_PLUGINS_XML: &str = "OPENVINO_PLUGINS_XML";
115116

116117
cfg_if! {
117118
if #[cfg(any(target_os = "linux"))] {
@@ -163,6 +164,47 @@ const KNOWN_BUILD_SUBDIRECTORIES: &[&str] = &[
163164
"temp/tbb/lib",
164165
];
165166

167+
/// Find the path to the `plugins.xml` configuration file.
168+
///
169+
/// OpenVINO records the location of its plugin libraries in a `plugins.xml` file. This file is
170+
/// examined by OpenVINO on initialization; not knowing the location to this file can lead to
171+
/// inference errors later (e.g., `Inference(GeneralError)`). OpenVINO uses the `plugins.xml` file
172+
/// to load target-specific libraries on demand for performing inference. The `plugins.xml` file
173+
/// maps targets (e.g., CPU) to their target-specific implementation library.
174+
///
175+
/// This file can be found in multiple locations, depending on the installation mechanism. For TAR
176+
/// installations, it is found in the same directory as the OpenVINO libraries themselves. For
177+
/// DEB/RPM installations, it is found in a version-suffixed directory beside the OpenVINO libraries
178+
/// (e.g., `openvino-2022.3.0/plugins.xml`).
179+
///
180+
/// This function will check:
181+
/// - the `OPENVINO_PLUGINS_XML` environment variable--this is specific to this library
182+
/// - the same directory as the `openvino_c` shared library, as discovered by [find]
183+
/// - the latest version directory beside the `openvino_c` shared library (i.e.,
184+
/// `openvino-<version>/`)
185+
pub fn find_plugins_xml() -> Option<PathBuf> {
186+
const FILE_NAME: &str = "plugins.xml";
187+
188+
// The `OPENVINO_PLUGINS_XML` should point directly to the file.
189+
if let Some(path) = env::var_os(ENV_OPENVINO_PLUGINS_XML) {
190+
return Some(PathBuf::from(path));
191+
}
192+
193+
// Check in the same directory as the `openvino_c` library; e.g.,
194+
// `/opt/intel/openvino_.../runtime/lib/intel64/plugins.xml`.
195+
let library = find("openvino_c")?;
196+
let library_parent_dir = library.parent()?;
197+
check_and_return!(library_parent_dir.join(FILE_NAME));
198+
199+
// Check in OpenVINO's special system installation directory; e.g.,
200+
// `/usr/lib/x86_64-linux-gnu/openvino-2022.3.0/plugins.xml`.
201+
let filenames = list_directory(library_parent_dir)?;
202+
let versions = get_suffixes(filenames, "openvino-");
203+
let path = build_latest_version(library_parent_dir, "openvino-", versions)?.join("plugins.xml");
204+
check_and_return!(path);
205+
206+
None
207+
}
166208

167209
#[inline]
168210
fn list_directory(dir: &Path) -> Option<impl IntoIterator<Item = String>> {
@@ -224,4 +266,19 @@ mod test {
224266
))
225267
);
226268
}
269+
270+
/// This test shows how the finder would discover the latest `plugins.xml` directory on an
271+
/// APT installation.
272+
#[test]
273+
fn find_latest_plugin_xml() {
274+
let path = build_latest_version(
275+
&PathBuf::from("/usr/lib/x86_64-linux-gnu"),
276+
"openvino-",
277+
vec!["2022.3.0".into(), "2023.1.0".into(), "2022.1.0".into()],
278+
);
279+
assert_eq!(
280+
path,
281+
Some(PathBuf::from("/usr/lib/x86_64-linux-gnu/openvino-2023.1.0"))
282+
);
283+
}
227284
}

crates/openvino/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ exclude = [
1616

1717
[dependencies]
1818
openvino-sys = { path = "../openvino-sys", version = "0.4.2" }
19+
openvino-finder = { path = "../openvino-finder", version = "0.4.2" }
1920
thiserror = "1.0.20"
2021

2122
[dev-dependencies]

crates/openvino/src/core.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@ impl Core {
3030
openvino_sys::library::load().map_err(LoadingError::SystemFailure)?;
3131

3232
let file = match xml_config_file {
33-
None => format!(
34-
"{}/plugins.xml",
35-
openvino_sys::library::find()
36-
.ok_or(LoadingError::CannotFindPath)?
37-
.parent()
38-
.ok_or(LoadingError::NoParentDirectory)?
39-
.display()
40-
),
33+
None => openvino_finder::find_plugins_xml()
34+
.ok_or(LoadingError::CannotFindPluginPath)?
35+
.to_str()
36+
.ok_or(LoadingError::CannotStringifyPath)?
37+
.to_string(),
4138
Some(f) => f.to_string(),
4239
};
4340
let mut instance = std::ptr::null_mut();

crates/openvino/src/error.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ pub enum LoadingError {
7979
#[error("system failed to load shared libraries (see https://github.com/intel/openvino-rs/blob/main/crates/openvino-finder): {0}")]
8080
SystemFailure(String),
8181
#[error("cannot find path to shared libraries (see https://github.com/intel/openvino-rs/blob/main/crates/openvino-finder)")]
82-
CannotFindPath,
83-
#[error("no parent directory found for shared library path")]
84-
NoParentDirectory,
82+
CannotFindLibraryPath,
83+
#[error("cannot find path to XML plugin configuration (see https://github.com/intel/openvino-rs/blob/main/crates/openvino-finder)")]
84+
CannotFindPluginPath,
85+
#[error("unable to convert path to a UTF-8 string (see https://doc.rust-lang.org/std/path/struct.Path.html#method.to_str)")]
86+
CannotStringifyPath,
8587
}

0 commit comments

Comments
 (0)