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

Update Openvino API to 2.0 #91

Merged
merged 29 commits into from
Apr 24, 2024
Merged

Conversation

rahulchaphalkar
Copy link
Contributor

Updated to the new API 2.0

Some notes about the tests -
classify-mobilenet, classify-alexnet, and classify-inception required image tensor layout to be NHWC.
detect-inception required slight modifications in the expected results noted in the comments, like the actual results starting from 1st element instead of 0th.

@abrown

openvino-sys crate builds and tests pass with api 2.0 with some caveats

update openvino api to 2.0, classify-mobilenet working test

remove comments and outdated files

cleanup, change methods in impl based on parameters

alexnet test

fix samples/tests, start tests for tensor

add tests

tests continue

fix version test, add tests to lib

update and add docs

Add Result<>, fix tests

cargo fmt

fix warnings in request.rs of unused imports

delete vscode file

change to accept variadic args with '...'

link macro format

format link macro
Copy link
Contributor

@abrown abrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is almost there — thanks for all this work! Most of my comments are minor nits and easily fixable except for two bigger problems:

  • our handling of the instance: *mut ... fields needs to be very safe: there's a dangling null pointer in there somewhere and I would prefer if we just made all of those fields private to avoid any munging with the pointer. For the structs that are built somewhere else, we can always add a private fn new(instance: *mut ...) -> Self { Self { instance } }.
  • the pre- and post-processing is just... confusing: maybe just do the best you can with doc tests and comments and we can refactor this later. I see that the C++ has what is called a PrePostProcessor which operates on a Model and then eventually one build()s the new thing. The C API is a bit more confusing so that might be what is going on here.

//! openvino_sys::library::load().expect("to have an OpenVINO library available");
//! let version = unsafe { CStr::from_ptr(openvino_sys::ie_c_api_version().api_version) };
//! assert!(version.to_string_lossy().starts_with("2"));
//! ```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep any doc examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't see this as added back in in the final PR state.

crates/openvino-sys/upstream Outdated Show resolved Hide resolved
crates/openvino/src/core.rs Outdated Show resolved Hide resolved
crates/openvino/src/core.rs Outdated Show resolved Hide resolved
crates/openvino/src/core.rs Outdated Show resolved Hide resolved
crates/xtask/src/codegen.rs Outdated Show resolved Hide resolved
crates/xtask/src/codegen.rs Outdated Show resolved Hide resolved
crates/xtask/src/codegen.rs Outdated Show resolved Hide resolved
crates/openvino/tests/detect-inception.rs Outdated Show resolved Hide resolved
crates/openvino/tests/detect-inception.rs Outdated Show resolved Hide resolved
@BTOdell
Copy link
Contributor

BTOdell commented Apr 3, 2024

Really nice to see this work getting done. Thank you!

I'm in the process of porting my company's Python app to Rust, and these API 2.0 bindings are required. I was about to start this conversion process myself since I knew from a couple months ago that these Rust bindings were outdated for the 2024.0 release of OpenVINO.

I've been reviewing this PR and I have some feedback:

  1. "Getter" functions should not be prefixed with "get_". This is a standard Rust naming convention: https://rust-lang.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter
  2. There are a couple instances where the struct name is included in the struct's function names and results in overly verbose naming.
  3. Functions that take file paths as inputs should use &Path instead of &str.
  4. There are some places where enums (instead of plain strings) could be used to make the Rust API more discoverable and less error prone. For example, pre-defined Layout variants.

I will continue reviewing this PR and submit any more feedback I have.

Thanks again! 🎉

@abrown
Copy link
Contributor

abrown commented Apr 3, 2024

@BTOdell, I think I'll take a pass or two after this merges to move this towards "ergonomic Rust." I'll definitely keep your suggestions in mind as I do that (and you're welcome to contribute PRs!). With this PR, I'm more concerned that the basic functionality and correctness remains in place; we can always smooth things out in follow-on PRs before the next release.

@BTOdell
Copy link
Contributor

BTOdell commented Apr 3, 2024

I'll be sure to open a PR with the suggestions. I based my fork from Rahul's fork and going to work from there.

Currently trying to get this crate building on my Windows machine, but having linking errors:
LINK : fatal error LNK1181: cannot open input file 'openvino.lib'
openvino-finder successfully finds the openvino.dll and openvino_c.dll; not sure why it's trying to link against a .lib.

@BTOdell BTOdell mentioned this pull request Apr 4, 2024
6 tasks
@rahulchaphalkar
Copy link
Contributor Author

@abrown Thanks for the detailed review and suggestions, I have addressed your feedback (kept a few conversations unresolved in case you wanted to go through my comments).
I have also opened 2 new issues - #93 to separately keep track on adding a new test similar to detect-inception, since detect-inception is outdated and based on a demo which no longer exists.
#94 for adding examples and docs specifically for PreProcessing functionality

@BTOdell thanks for reviewing the PR as well as providing good feedback! I have created a separate issue #95 to keep track of the changes that you suggested in your comment above.

Copy link
Contributor

@abrown abrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only big thing to resolve is the recent addition of anyhow; let's talk offline about that. For efficiency's sake, I'll just start committing some of the small suggestions from this review.

crates/openvino/src/model.rs Outdated Show resolved Hide resolved
@@ -16,6 +16,7 @@ exclude = ["/tests"]
openvino-sys = { path = "../openvino-sys", version = "0.6.0" }
openvino-finder = { path = "../openvino-finder", version = "0.6.0" }
thiserror = "1.0"
anyhow = "1.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why we would need to import this: just using the regular Result with the appropriate error type from this crate should be good enough.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see, you're just using anyhow for easier testing... in that case I'll just move it to [dev-dependencies] so that it is available during testing but not required by users of the crate.

crates/openvino/src/layout.rs Outdated Show resolved Hide resolved
crates/openvino/src/lib.rs Outdated Show resolved Hide resolved
crates/openvino/src/model.rs Outdated Show resolved Hide resolved
crates/openvino/src/port.rs Outdated Show resolved Hide resolved
crates/openvino/src/port.rs Outdated Show resolved Hide resolved
}

///Create a new [`Port`] from [`ov_output_const_port_t`].
pub(crate) fn new(instance: *mut ov_output_const_port_t) -> Result<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to return a Result when there is no chance for an error.

Suggested change
pub(crate) fn new(instance: *mut ov_output_const_port_t) -> Result<Self> {
pub(crate) fn new(instance: *mut ov_output_const_port_t) -> Self {

crates/openvino/src/shape.rs Outdated Show resolved Hide resolved
//! openvino_sys::library::load().expect("to have an OpenVINO library available");
//! let version = unsafe { CStr::from_ptr(openvino_sys::ie_c_api_version().api_version) };
//! assert!(version.to_string_lossy().starts_with("2"));
//! ```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't see this as added back in in the final PR state.

crates/openvino/Cargo.toml Outdated Show resolved Hide resolved
Comment on lines 41 to 44
/// Create a new shape object from ov_shape_t.
pub(crate) fn new_from_instance(instance: ov_shape_t) -> Result<Self> {
Ok(Self { instance })
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Create a new shape object from ov_shape_t.
pub(crate) fn new_from_instance(instance: ov_shape_t) -> Result<Self> {
Ok(Self { instance })
}
/// Create a new shape object from `ov_shape_t`.
pub(crate) fn new_from_instance(instance: ov_shape_t) -> Self {
Self { instance }
}

Comment on lines 46 to 49
/// Returns the rank of the shape.
pub fn get_rank(&self) -> Result<i64> {
Ok(self.instance.rank)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and many other places we return a Result unnecessarily.

Suggested change
/// Returns the rank of the shape.
pub fn get_rank(&self) -> Result<i64> {
Ok(self.instance.rank)
}
/// Returns the rank of the shape.
pub fn get_rank(&self) -> i64 {
self.instance.rank
}

Copy link
Contributor

@abrown abrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed up some of the small stuff but can't push to this branch so I can't get rid of Model::new and unnecessary returns of Result. Otherwise looks great!

Copy link
Contributor

@abrown abrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the work on this!

@abrown abrown merged commit 7efb30d into intel:main Apr 24, 2024
15 checks passed
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

Successfully merging this pull request may close these issues.

3 participants