1use crate::error::{PyResult, RonnError};
4use numpy::PyArray1;
5use pyo3::prelude::*;
6use pyo3::types::PyDict;
7use ronn_api::InferenceSession;
8use std::collections::HashMap;
9
10#[pyclass(name = "Session")]
24pub struct PySession {
25 inner: InferenceSession,
26}
27
28impl PySession {
29 pub fn new(session: InferenceSession) -> Self {
30 Self { inner: session }
31 }
32}
33
34#[pymethods]
35impl PySession {
36 fn run(&self, py: Python, inputs: &PyDict) -> PyResult<PyObject> {
53 let mut input_tensors: HashMap<String, ronn_core::Tensor> = HashMap::new();
55
56 for (key, value) in inputs.iter() {
57 let name: String = key.extract()?;
58
59 let tensor = if let Ok(array) = value.downcast::<PyArray1<f32>>() {
61 let data: Vec<f32> = array.to_vec()?;
62 let shape = vec![array.len()];
63 ronn_core::Tensor::from_data(
64 data,
65 shape,
66 ronn_core::DataType::F32,
67 ronn_core::TensorLayout::RowMajor,
68 )
69 .map_err(RonnError::from)?
70 } else {
71 return Err(RonnError(format!("Unsupported input type for '{}'", name)));
72 };
73
74 input_tensors.insert(name, tensor);
75 }
76
77 let inputs_ref: HashMap<&str, ronn_core::Tensor> = input_tensors
79 .iter()
80 .map(|(k, v)| (k.as_str(), v.clone()))
81 .collect();
82
83 let output_tensors = self.inner.run(inputs_ref).map_err(RonnError::from)?;
85
86 let result = PyDict::new(py);
88 for (name, tensor) in output_tensors {
89 let data: Vec<f32> = tensor.to_vec().unwrap_or_else(|_| vec![]);
91 let array = PyArray1::from_vec(py, data);
92 result.set_item(name, array)?;
93 }
94
95 Ok(result.into())
96 }
97
98 fn __repr__(&self) -> String {
99 "Session(...)".to_string()
100 }
101}