use crate::node::Node;
use crate::request::InferRequest;
use crate::{
cstr, drop_using_function, try_unsafe, util::Result, PartialShape, PropertyKey, RwPropertyKey,
};
use openvino_sys::{
ov_compiled_model_create_infer_request, ov_compiled_model_free, ov_compiled_model_get_property,
ov_compiled_model_get_runtime_model, ov_compiled_model_input, ov_compiled_model_input_by_index,
ov_compiled_model_input_by_name, ov_compiled_model_inputs_size, ov_compiled_model_output,
ov_compiled_model_output_by_index, ov_compiled_model_output_by_name,
ov_compiled_model_outputs_size, ov_compiled_model_set_property, ov_compiled_model_t,
ov_model_const_input_by_index, ov_model_const_output_by_index, ov_model_free,
ov_model_inputs_size, ov_model_is_dynamic, ov_model_outputs_size, ov_model_t,
};
use std::borrow::Cow;
use std::ffi::CStr;
pub struct Model {
ptr: *mut ov_model_t,
}
drop_using_function!(Model, ov_model_free);
unsafe impl Send for Model {}
unsafe impl Sync for Model {}
impl Model {
#[inline]
pub(crate) fn from_ptr(ptr: *mut ov_model_t) -> Self {
Self { ptr }
}
#[inline]
pub(crate) fn as_ptr(&self) -> *const ov_model_t {
self.ptr
}
pub fn get_inputs_len(&self) -> Result<usize> {
let mut num: usize = 0;
try_unsafe!(ov_model_inputs_size(self.ptr, &mut num))?;
Ok(num)
}
pub fn get_outputs_len(&self) -> Result<usize> {
let mut num: usize = 0;
try_unsafe!(ov_model_outputs_size(self.ptr, &mut num))?;
Ok(num)
}
pub fn get_input_by_index(&self, index: usize) -> Result<Node> {
let mut node = std::ptr::null_mut();
try_unsafe!(ov_model_const_input_by_index(
self.ptr,
index,
std::ptr::addr_of_mut!(node)
))?;
Ok(Node::from_ptr(node))
}
pub fn get_output_by_index(&self, index: usize) -> Result<Node> {
let mut node = std::ptr::null_mut();
try_unsafe!(ov_model_const_output_by_index(
self.ptr,
index,
std::ptr::addr_of_mut!(node)
))?;
Ok(Node::from_ptr(node))
}
pub fn get_const_output_by_index(&self, index: usize) -> Result<Node> {
let mut node = std::ptr::null_mut();
try_unsafe!(ov_model_const_output_by_index(
self.ptr,
index,
std::ptr::addr_of_mut!(node)
))?;
Ok(Node::from_ptr(node))
}
pub fn is_dynamic(&self) -> bool {
unsafe { ov_model_is_dynamic(self.ptr) }
}
pub fn reshape_single_input(&mut self, partial_shape: &PartialShape) -> Result<()> {
try_unsafe!(openvino_sys::ov_model_reshape_single_input(
self.ptr,
partial_shape.as_c_struct()
))
}
pub fn reshape_input_by_name(
&mut self,
tensor_name: &str,
partial_shape: &PartialShape,
) -> Result<()> {
let name = cstr!(tensor_name);
try_unsafe!(openvino_sys::ov_model_reshape_input_by_name(
self.ptr,
name.as_ptr(),
partial_shape.as_c_struct()
))
}
pub fn reshape(&mut self, partial_shapes: &[(&str, &PartialShape)]) -> Result<()> {
let mut c_names = Vec::with_capacity(partial_shapes.len());
let mut c_shapes = Vec::with_capacity(partial_shapes.len());
let mut names_keep_alive = Vec::with_capacity(partial_shapes.len());
for (name, partial_shape) in partial_shapes {
let c_name = cstr!(*name);
c_names.push(c_name.as_ptr());
names_keep_alive.push(c_name);
c_shapes.push(partial_shape.as_c_struct());
}
try_unsafe!(openvino_sys::ov_model_reshape(
self.ptr,
c_names.as_mut_ptr(),
c_shapes.as_ptr(),
partial_shapes.len()
))
}
pub fn reshape_by_port_indexes(
&mut self,
partial_shapes: &[(usize, &PartialShape)],
) -> Result<()> {
let mut c_indexes = Vec::with_capacity(partial_shapes.len());
let mut c_shapes = Vec::with_capacity(partial_shapes.len());
for (index, partial_shape) in partial_shapes {
c_indexes.push(*index);
c_shapes.push(partial_shape.as_c_struct());
}
try_unsafe!(openvino_sys::ov_model_reshape_by_port_indexes(
self.ptr,
c_indexes.as_ptr(),
c_shapes.as_ptr(),
partial_shapes.len()
))
}
pub fn reshape_by_ports(&mut self, partial_shapes: &[(&Node, &PartialShape)]) -> Result<()> {
let mut c_ports = Vec::with_capacity(partial_shapes.len());
let mut c_shapes = Vec::with_capacity(partial_shapes.len());
for (node, partial_shape) in partial_shapes {
c_ports.push(node.as_ptr() as *const openvino_sys::ov_output_port_t);
c_shapes.push(partial_shape.as_c_struct());
}
try_unsafe!(openvino_sys::ov_model_reshape_by_ports(
self.ptr,
c_ports.as_mut_ptr(),
c_shapes.as_ptr(),
partial_shapes.len()
))
}
}
pub struct CompiledModel {
ptr: *mut ov_compiled_model_t,
}
drop_using_function!(CompiledModel, ov_compiled_model_free);
unsafe impl Send for CompiledModel {}
impl CompiledModel {
pub(crate) fn from_ptr(ptr: *mut ov_compiled_model_t) -> Self {
Self { ptr }
}
pub fn create_infer_request(&mut self) -> Result<InferRequest> {
let mut infer_request = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_create_infer_request(
self.ptr,
std::ptr::addr_of_mut!(infer_request)
))?;
Ok(InferRequest::from_ptr(infer_request))
}
pub fn get_input_size(&self) -> Result<usize> {
let mut input_size: usize = 0;
try_unsafe!(ov_compiled_model_inputs_size(self.ptr, &mut input_size))?;
Ok(input_size)
}
pub fn get_input(&self) -> Result<Node> {
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_input(
self.ptr,
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_input_by_index(&self, index: usize) -> Result<Node> {
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_input_by_index(
self.ptr,
index,
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_input_by_name(&self, name: &str) -> Result<Node> {
let name = cstr!(name);
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_input_by_name(
self.ptr,
name.as_ptr(),
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_output_size(&self) -> Result<usize> {
let mut output_size: usize = 0;
try_unsafe!(ov_compiled_model_outputs_size(self.ptr, &mut output_size))?;
Ok(output_size)
}
pub fn get_output(&self) -> Result<Node> {
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_output(
self.ptr,
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_output_by_index(&self, index: usize) -> Result<Node> {
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_output_by_index(
self.ptr,
index,
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_output_by_name(&self, name: &str) -> Result<Node> {
let name = cstr!(name);
let mut port = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_output_by_name(
self.ptr,
name.as_ptr(),
std::ptr::addr_of_mut!(port)
))?;
Ok(Node::from_ptr(port))
}
pub fn get_runtime_model(&self) -> Result<Model> {
let mut ptr = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_get_runtime_model(
self.ptr,
std::ptr::addr_of_mut!(ptr)
))?;
Ok(Model { ptr })
}
pub fn get_property(&self, key: &PropertyKey) -> Result<Cow<'_, str>> {
let ov_prop_key = cstr!(key.as_ref());
let mut ov_prop_value = std::ptr::null_mut();
try_unsafe!(ov_compiled_model_get_property(
self.ptr,
ov_prop_key.as_ptr(),
std::ptr::addr_of_mut!(ov_prop_value)
))?;
let rust_prop = unsafe { CStr::from_ptr(ov_prop_value) }.to_string_lossy();
Ok(rust_prop)
}
pub fn set_property(&mut self, key: &RwPropertyKey, value: &str) -> Result<()> {
let ov_prop_key = cstr!(key.as_ref());
let ov_prop_value = cstr!(value);
try_unsafe!(ov_compiled_model_set_property(
self.ptr,
ov_prop_key.as_ptr(),
ov_prop_value.as_ptr(),
))?;
Ok(())
}
}