Zero Copy getter for struct of ndarrays in rust to python #385
-
I am wondering if the following is possible (simplified version of my problem)
So far I can do it, but every time it seems to be a full copy back and forth between python and rust. use ndarray::Array1;
use numpy::{PyArray1, ToPyArray};
use pyo3::prelude::*;
// the original has 15+ different kind of array with different dimensions
pub struct Test {
pub x: Array1<f64>
}
impl Test {
pub fn new(x: Array1<f64>) ->Test {
Test {x}
}
}
// now the python class
#[pyclass]
pub struct PyTest{
pub inner: Test
}
#[pymethods]
impl PyTest {
#[new]
fn new(py: Python<'_>, x: &PyArray1<f64>) -> PyTest {
// get the length of the PyArray1
let x = x.readwrite();
let test = Test { x: x.to_owned() };
py.allow_threads(|| PyTest { test: test })
}
#[getter]
pub fn get_x(&self, py: Python<'_>) -> Py<PyArray1<f64>> {
self.test.x.to_pyarray(py).to_owned()
}
} What I am searching for is however for the getter to be zero copy so that I can call the field Is that possible? Sorry if the question is not that clear I am very confused with the interaction between python and rust and I am very new with rust. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
I think if you want to have zero-copy interactions with Python, you need to turn this around, i.e. store a NumPy array and create a #[pyclass(frozen)]
pub struct PyTest {
x: Py<PyArray1<f64>>,
}
#[pymethods]
impl PyTest {
#[new]
fn new(x: Py<PyArray1<f64>>) -> Self {
Self { x }
}
#[getter]
fn x(&self, py: Python<'_>) -> Py<PyArray1<f64>> {
self.x.clone_ref(py)
}
}
fn modify_x(test: &PyTest) {
let x = test.x.readwrite();
...
} |
Beta Was this translation helpful? Give feedback.
Sorry if I mislead you there but the
frozen
part is completely optional for this to be zero-copy. It is just more efficient if you only store references to Python objects, i.e.Py<T>
. The guide has some information on that.You mean if using that library prevents you from consuming the arrays?