Skip to content

Commit b6eacef

Browse files
remove tensor new_from_host_ptr function (#125)
Remove the `Tensor::new_from_host_ptr` function since it passed along a pointer across the FFI boundary to OpenVINO that relied on the lifetime of the buffer, a `&[u8]`, which only was required to live as long as the function call. When that buffer went out of scope the pointer was invalid, causing some observed segfaults with later usage of that tensor. The offending function in this case was `Core::read_model_from_buffer`, which ended up holding on to the weights tensor until some later time. This will force all tensor creation to occur via copying (e.g., `slice::copy_from_slice`). Eventually we should work out a scheme to avoid this extra work; using `PhantomData` to propagate lifetimes started touching too much code but there is likely something else that can be done here instead.
1 parent 0045461 commit b6eacef

File tree

5 files changed

+15
-31
lines changed

5 files changed

+15
-31
lines changed

crates/openvino/src/prepostprocess.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
//! # ).expect("to read the model from file");
1313
//! # let data = fs::read("tests/fixtures/inception/tensor-1x3x299x299-f32.bgr").expect("to read the tensor from file");
1414
//! # let input_shape = Shape::new(&vec![1, 299, 299, 3]).expect("to create a new shape");
15-
//! # let tensor = Tensor::new_from_host_ptr(ElementType::F32, &input_shape, &data).expect("to create a new tensor from host pointer");
15+
//! # let mut tensor = Tensor::new(ElementType::F32, &input_shape).expect("to create a new tensor");
16+
//! # let buffer = tensor.buffer_mut().unwrap();
17+
//! # buffer.copy_from_slice(&data);
1618
//! // Insantiate a new core, read in a model, and set up a tensor with input data before performing pre/post processing
1719
//! // Pre-process the input by:
1820
//! // - converting NHWC to NCHW

crates/openvino/src/tensor.rs

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use crate::element_type::ElementType;
55
use crate::shape::Shape;
66
use crate::{drop_using_function, try_unsafe, util::Result};
77
use openvino_sys::{
8-
self, ov_shape_t, ov_tensor_create, ov_tensor_create_from_host_ptr, ov_tensor_data,
9-
ov_tensor_free, ov_tensor_get_byte_size, ov_tensor_get_element_type, ov_tensor_get_shape,
10-
ov_tensor_get_size, ov_tensor_set_shape, ov_tensor_t,
8+
self, ov_shape_t, ov_tensor_create, ov_tensor_data, ov_tensor_free, ov_tensor_get_byte_size,
9+
ov_tensor_get_element_type, ov_tensor_get_shape, ov_tensor_get_size, ov_tensor_set_shape,
10+
ov_tensor_t,
1111
};
1212

1313
/// See [`Tensor`](https://docs.openvino.ai/2023.3/api/c_cpp_api/group__ov__tensor__c__api.html).
@@ -34,30 +34,6 @@ impl Tensor {
3434
Self { ptr }
3535
}
3636

37-
/// Create a new [`Tensor`] from a host pointer.
38-
///
39-
/// # Arguments
40-
///
41-
/// * `data_type` - The data type of the tensor.
42-
/// * `shape` - The shape of the tensor.
43-
/// * `data` - The data buffer.
44-
///
45-
/// # Returns
46-
///
47-
/// A new `Tensor` object.
48-
pub fn new_from_host_ptr(data_type: ElementType, shape: &Shape, data: &[u8]) -> Result<Self> {
49-
let mut tensor: *mut ov_tensor_t = std::ptr::null_mut();
50-
let element_type: u32 = data_type as u32;
51-
let buffer = data.as_ptr() as *mut std::os::raw::c_void;
52-
try_unsafe!(ov_tensor_create_from_host_ptr(
53-
element_type,
54-
shape.as_c_struct(),
55-
buffer,
56-
std::ptr::addr_of_mut!(tensor)
57-
))?;
58-
Ok(Self { ptr: tensor })
59-
}
60-
6137
/// Get the pointer to the underlying OpenVINO tensor.
6238
#[inline]
6339
pub(crate) fn as_ptr(&self) -> *const ov_tensor_t {

crates/openvino/tests/classify-alexnet.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn classify_alexnet() -> anyhow::Result<()> {
2727
let data = fs::read(Fixture::tensor())?;
2828
let input_shape = Shape::new(&vec![1, 227, 227, 3])?;
2929
let element_type = ElementType::F32;
30-
let tensor = Tensor::new_from_host_ptr(element_type, &input_shape, &data)?;
30+
let mut tensor = Tensor::new(element_type, &input_shape)?;
31+
let buffer = tensor.buffer_mut()?;
32+
buffer.copy_from_slice(&data);
3133

3234
// Pre-process the input by:
3335
// - converting NHWC to NCHW

crates/openvino/tests/classify-inception.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn classify_inception() -> anyhow::Result<()> {
2727
let data = fs::read(Fixture::tensor())?;
2828
let input_shape = Shape::new(&vec![1, 299, 299, 3])?;
2929
let element_type = ElementType::F32;
30-
let tensor = Tensor::new_from_host_ptr(element_type, &input_shape, &data)?;
30+
let mut tensor = Tensor::new(element_type, &input_shape)?;
31+
let buffer = tensor.buffer_mut()?;
32+
buffer.copy_from_slice(&data);
3133

3234
// Pre-process the input by:
3335
// - converting NHWC to NCHW

crates/openvino/tests/classify-mobilenet.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn classify_mobilenet() -> anyhow::Result<()> {
2727
let data = fs::read(Fixture::tensor())?;
2828
let input_shape = Shape::new(&vec![1, 224, 224, 3])?;
2929
let element_type = ElementType::F32;
30-
let tensor = Tensor::new_from_host_ptr(element_type, &input_shape, &data)?;
30+
let mut tensor = Tensor::new(element_type, &input_shape)?;
31+
let buffer = tensor.buffer_mut()?;
32+
buffer.copy_from_slice(&data);
3133

3234
// Pre-process the input by:
3335
// - converting NHWC to NCHW

0 commit comments

Comments
 (0)