ort/session/builder/
mod.rs1use alloc::{
2 borrow::Cow,
3 sync::{Arc, Weak},
4 vec::Vec
5};
6use core::{
7 any::Any,
8 ptr::{self, NonNull}
9};
10
11use smallvec::SmallVec;
12
13use crate::{
14 AsPointer, Error, environment::Environment, error::Result, logging::LoggerFunction, memory::MemoryInfo, operator::OperatorDomain, ortsys, util::with_cstr,
15 value::DynValue
16};
17
18#[cfg(feature = "api-22")]
19#[cfg_attr(docsrs, doc(cfg(feature = "api-22")))]
20mod editable;
21mod impl_commit;
22mod impl_config_keys;
23mod impl_options;
24
25#[cfg(feature = "api-22")]
26#[cfg_attr(docsrs, doc(cfg(feature = "api-22")))]
27pub use self::editable::*;
28pub use self::impl_options::*;
29
30pub type BuilderResult = Result<SessionBuilder, Error<SessionBuilder>>;
45
46pub struct SessionBuilder {
65 session_options_ptr: Arc<SessionOptionsPointer>,
66 memory_info: Option<Arc<MemoryInfo<'static>>>,
67 operator_domains: SmallVec<[Arc<OperatorDomain>; 1]>,
68 initializers: Vec<Arc<DynValue>>,
69 external_initializer_buffers: Vec<Cow<'static, [u8]>>,
70 prepacked_weights: Option<PrepackedWeights>,
71 thread_manager: Option<Arc<dyn Any>>,
72 logger: Option<Arc<LoggerFunction>>,
73 no_global_thread_pool: bool,
74 no_env_eps: bool,
75 pub(crate) environment: Arc<Environment>
76}
77
78impl Clone for SessionBuilder {
79 fn clone(&self) -> Self {
80 let mut session_options_ptr = ptr::null_mut();
81 ortsys![
82 unsafe CloneSessionOptions(self.ptr(), ptr::addr_of_mut!(session_options_ptr))
83 .expect("error cloning session options");
84 nonNull(session_options_ptr)
85 ];
86 Self {
87 session_options_ptr: Arc::new(SessionOptionsPointer::new(session_options_ptr)),
88 memory_info: self.memory_info.clone(),
89 operator_domains: self.operator_domains.clone(),
90 initializers: self.initializers.clone(),
91 external_initializer_buffers: self.external_initializer_buffers.clone(),
92 prepacked_weights: self.prepacked_weights.clone(),
93 thread_manager: self.thread_manager.clone(),
94 logger: self.logger.clone(),
95 no_global_thread_pool: self.no_global_thread_pool,
96 no_env_eps: self.no_env_eps,
97 environment: self.environment.clone()
98 }
99 }
100}
101
102impl SessionBuilder {
103 pub fn new() -> Result<Self> {
116 let environment = Environment::current()?;
117
118 let mut session_options_ptr: *mut ort_sys::OrtSessionOptions = ptr::null_mut();
119 ortsys![unsafe CreateSessionOptions(&mut session_options_ptr)?; nonNull(session_options_ptr)];
120
121 #[cfg(feature = "api-22")]
124 let _ = ortsys![@ort: unsafe SessionOptionsSetEpSelectionPolicy(session_options_ptr.as_ptr(), AutoDevicePolicy::MaxEfficiency.into()) as Result];
125
126 Ok(Self {
127 session_options_ptr: Arc::new(SessionOptionsPointer::new(session_options_ptr)),
128 memory_info: None,
129 operator_domains: SmallVec::new(),
130 initializers: Vec::new(),
131 external_initializer_buffers: Vec::new(),
132 prepacked_weights: None,
133 thread_manager: None,
134 logger: None,
135 no_global_thread_pool: false,
136 no_env_eps: false,
137 environment
138 })
139 }
140
141 #[inline]
142 pub(crate) fn add_config_entry(&mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> Result<()> {
143 let ptr = self.ptr_mut();
144 with_cstr(key.as_ref().as_bytes(), &|key| {
145 with_cstr(value.as_ref().as_bytes(), &|value| {
146 ortsys![unsafe AddSessionConfigEntry(ptr, key.as_ptr(), value.as_ptr())?];
147 Ok(())
148 })
149 })
150 }
151
152 #[cfg(feature = "api-22")]
174 #[cfg_attr(docsrs, doc(cfg(feature = "api-22")))]
175 pub fn canceler(&self) -> LoadCanceler {
176 LoadCanceler(Arc::downgrade(&self.session_options_ptr))
177 }
178
179 pub fn with_config_entry(mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> BuilderResult {
181 match self.add_config_entry(key.as_ref(), value.as_ref()) {
182 Ok(()) => Ok(self),
183 Err(e) => Err(e.with_recover(self))
184 }
185 }
186}
187
188impl AsPointer for SessionBuilder {
189 type Sys = ort_sys::OrtSessionOptions;
190
191 fn ptr(&self) -> *const Self::Sys {
192 self.session_options_ptr.as_ptr()
193 }
194}
195
196#[derive(Debug, Clone)]
200#[cfg(feature = "api-22")]
201#[cfg_attr(docsrs, doc(cfg(feature = "api-22")))]
202pub struct LoadCanceler(Weak<SessionOptionsPointer>);
203
204#[cfg(feature = "api-22")]
205unsafe impl Send for LoadCanceler {}
206#[cfg(feature = "api-22")]
207unsafe impl Sync for LoadCanceler {}
208
209#[cfg(feature = "api-22")]
210impl LoadCanceler {
211 #[cfg(feature = "api-22")]
233 #[cfg_attr(docsrs, doc(cfg(feature = "api-22")))]
234 pub fn cancel(&self) -> Result<()> {
235 if let Some(ptr) = self.0.upgrade() {
236 ortsys![unsafe SessionOptionsSetLoadCancellationFlag(ptr.as_ptr(), true)?];
237 }
238 Ok(())
239 }
240}
241
242#[derive(Debug)]
243#[repr(transparent)]
244pub(crate) struct SessionOptionsPointer(NonNull<ort_sys::OrtSessionOptions>);
245
246impl SessionOptionsPointer {
247 #[inline]
248 pub(crate) fn new(ptr: NonNull<ort_sys::OrtSessionOptions>) -> Self {
249 crate::logging::create!(SessionBuilder, ptr);
250 Self(ptr)
251 }
252
253 #[inline]
254 pub(crate) fn as_ptr(&self) -> *mut ort_sys::OrtSessionOptions {
255 self.0.as_ptr()
256 }
257}
258
259impl Drop for SessionOptionsPointer {
260 fn drop(&mut self) {
261 ortsys![unsafe ReleaseSessionOptions(self.0.as_ptr())];
262 crate::logging::drop!(SessionBuilder, self.0.as_ptr());
263 }
264}
265
266#[cfg(test)]
267mod tests {
268 use alloc::sync::Arc;
269 use core::sync::atomic::{AtomicBool, Ordering};
270
271 use super::SessionBuilder;
272
273 #[test]
274 fn test_session_builder_clone() -> crate::Result<()> {
275 let was_called = Arc::new(AtomicBool::new(false));
276 let builder = SessionBuilder::new()?.with_logger(Arc::new({
277 let was_called = Arc::clone(&was_called);
278 move |_level: crate::logging::LogLevel, _category: &str, _id: &str, _code_location: &str, _message: &str| {
279 was_called.store(true, Ordering::Release);
280 }
281 }))?;
282 let mut builder2 = builder.clone();
283 drop(builder);
284 let _session = builder2.commit_from_file("tests/data/upsample.onnx")?;
285 assert!(was_called.load(Ordering::Acquire));
286 Ok(())
287 }
288}