1use mnn_sys::*;
2use std::{ffi::CString, mem::ManuallyDrop};
3
4use crate::{BackendConfig, prelude::*};
5
6#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub enum ForwardType {
39 All,
41 #[default]
42 Auto,
44 CPU,
46 #[cfg(feature = "metal")]
47 Metal,
49 #[cfg(feature = "opencl")]
50 OpenCL,
52 #[cfg(feature = "vulkan")]
54 Vulkan,
55 #[cfg(feature = "cuda")]
57 Cuda,
58 #[cfg(feature = "coreml")]
60 CoreML,
61}
62
63impl ForwardType {
64 fn to_mnn_sys(self) -> MNNForwardType {
66 match self {
67 ForwardType::Auto => MNNForwardType::MNN_FORWARD_AUTO,
68 ForwardType::All => MNNForwardType::MNN_FORWARD_ALL,
69 ForwardType::CPU => MNNForwardType::MNN_FORWARD_CPU,
70 #[cfg(feature = "metal")]
71 ForwardType::Metal => MNNForwardType::MNN_FORWARD_METAL,
72 #[cfg(feature = "opencl")]
73 ForwardType::OpenCL => MNNForwardType::MNN_FORWARD_OPENCL,
74 #[cfg(feature = "opengl")]
75 ForwardType::OpenGL => MNNForwardType::MNN_FORWARD_OPENGL,
76 #[cfg(feature = "vulkan")]
77 ForwardType::Vulkan => MNNForwardType::MNN_FORWARD_VULKAN,
78 #[cfg(feature = "cuda")]
79 ForwardType::Cuda => MNNForwardType::MNN_FORWARD_CUDA,
80 #[cfg(feature = "coreml")]
81 ForwardType::CoreML => MNNForwardType::MNN_FORWARD_NN,
82 }
83 }
84
85 fn from_mnn_sys(mode: MNNForwardType) -> Self {
86 match mode {
87 MNNForwardType::MNN_FORWARD_AUTO => ForwardType::Auto,
88 MNNForwardType::MNN_FORWARD_ALL => ForwardType::All,
89 MNNForwardType::MNN_FORWARD_CPU => ForwardType::CPU,
90 #[cfg(feature = "metal")]
91 MNNForwardType::MNN_FORWARD_METAL => ForwardType::Metal,
92 #[cfg(feature = "opencl")]
93 MNNForwardType::MNN_FORWARD_OPENCL => ForwardType::OpenCL,
94 #[cfg(feature = "opengl")]
95 MNNForwardType::MNN_FORWARD_OPENGL => ForwardType::OpenGL,
96 #[cfg(feature = "vulkan")]
97 MNNForwardType::MNN_FORWARD_VULKAN => ForwardType::Vulkan,
98 #[cfg(feature = "cuda")]
99 MNNForwardType::MNN_FORWARD_CUDA => ForwardType::Cuda,
100 #[cfg(feature = "coreml")]
101 MNNForwardType::MNN_FORWARD_NN => ForwardType::CoreML,
102 _ => ForwardType::Auto,
103 }
104 }
105
106 fn list() -> Vec<&'static str> {
108 vec![
109 "auto",
110 "all",
111 "cpu",
112 #[cfg(feature = "metal")]
113 "metal",
114 #[cfg(feature = "opencl")]
115 "opencl",
116 #[cfg(feature = "opengl")]
117 "opengl",
118 #[cfg(feature = "vulkan")]
119 "vulkan",
120 #[cfg(feature = "cuda")]
121 "cuda",
122 #[cfg(feature = "coreml")]
123 "coreml",
124 ]
125 }
126
127 pub fn to_str(self) -> &'static str {
129 match self {
130 ForwardType::Auto => "auto",
131 ForwardType::All => "all",
132 ForwardType::CPU => "cpu",
133 #[cfg(feature = "metal")]
134 ForwardType::Metal => "metal",
135 #[cfg(feature = "opencl")]
136 ForwardType::OpenCL => "opencl",
137 #[cfg(feature = "opengl")]
138 ForwardType::OpenGL => "opengl",
139 #[cfg(feature = "vulkan")]
140 ForwardType::Vulkan => "vulkan",
141 #[cfg(feature = "cuda")]
142 ForwardType::Cuda => "cuda",
143 #[cfg(feature = "coreml")]
144 ForwardType::CoreML => "coreml",
145 }
146 }
147}
148
149impl core::str::FromStr for ForwardType {
150 type Err = MNNError;
151
152 fn from_str(s: &str) -> Result<Self, Self::Err> {
153 match s {
154 "auto" => Ok(ForwardType::Auto),
155 "all" => Ok(ForwardType::All),
156 "cpu" => Ok(ForwardType::CPU),
157 #[cfg(feature = "metal")]
158 "metal" => Ok(ForwardType::Metal),
159 #[cfg(feature = "opencl")]
160 "opencl" => Ok(ForwardType::OpenCL),
161 #[cfg(feature = "opengl")]
162 "opengl" => Ok(ForwardType::OpenGL),
163 #[cfg(feature = "vulkan")]
164 "vulkan" => Ok(ForwardType::Vulkan),
165 #[cfg(feature = "cuda")]
166 "cuda" => Ok(ForwardType::Cuda),
167 #[cfg(feature = "coreml")]
168 "coreml" => Ok(ForwardType::CoreML),
169 _ => Err(MNNError::new(crate::ErrorKind::ParseError)
170 .attach(format!(
171 "Invalid ForwardType: {s}, maybe you might need to enable feature {s}"
172 ))
173 .attach(format!(
174 "Valid ForwardType: {}",
175 ForwardType::list().join(", ")
176 ))),
177 }
178 }
179}
180
181pub struct ScheduleConfig {
225 pub(crate) inner: *mut MNNScheduleConfig,
226 pub(crate) backend_config: Option<BackendConfig>,
227 pub(crate) __marker: core::marker::PhantomData<()>,
228}
229
230impl core::fmt::Debug for ScheduleConfig {
231 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
232 f.debug_struct("ScheduleConfig")
233 .field("type", &self.get_type())
234 .field("backup_type", &self.get_backup_type())
235 .field("backend_config", &self.backend_config)
236 .finish()
237 }
238}
239
240#[cfg(feature = "serde")]
241impl serde::Serialize for ScheduleConfig {
242 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
243 use serde::ser::SerializeStruct;
244 let mut state = serializer.serialize_struct("ScheduleConfig", 3)?;
245 state.serialize_field("type", &self.get_type())?;
246 state.serialize_field("backup_type", &self.get_backup_type())?;
247 state.serialize_field("backend_config", &self.backend_config)?;
248 state.end()
249 }
250}
251
252impl Clone for ScheduleConfig {
253 fn clone(&self) -> Self {
254 unsafe {
255 let inner = mnnsc_clone(self.inner);
256 Self {
257 inner,
258 backend_config: self.backend_config.clone(),
259 __marker: core::marker::PhantomData,
260 }
261 }
262 }
263}
264
265impl Drop for ScheduleConfig {
266 fn drop(&mut self) {
267 unsafe {
268 mnn_sys::mnnsc_destroy(self.inner);
269 }
270 }
271}
272
273unsafe impl Send for ScheduleConfig {}
274
275impl Default for ScheduleConfig {
276 fn default() -> Self {
277 Self::new()
278 }
279}
280
281impl ScheduleConfig {
282 pub fn as_ptr_mut(&mut self) -> *mut MNNScheduleConfig {
284 self.inner
285 }
286
287 pub fn new() -> Self {
289 unsafe {
290 let inner = mnnsc_create();
291 Self {
292 inner,
293 backend_config: None,
294 __marker: core::marker::PhantomData,
295 }
296 }
297 }
298
299 pub fn set_save_tensors(&mut self, save_tensors: &[&str]) -> Result<&mut Self> {
309 let vec_cstring = save_tensors
310 .iter()
311 .map(|s| std::ffi::CString::new(*s).map_err(|e| error!(ErrorKind::AsciiError, e)))
312 .collect::<Result<Vec<_>>>()?;
313 let vec_cstr = vec_cstring
314 .iter()
315 .map(|s: &CString| s.as_c_str().as_ptr())
316 .collect::<Vec<_>>();
317 unsafe { mnnsc_set_save_tensors(self.inner, vec_cstr.as_ptr(), vec_cstr.len()) }
318 Ok(self)
319 }
320
321 pub fn set_type(&mut self, forward_type: ForwardType) -> &mut Self {
327 unsafe {
328 mnnsc_set_type(self.inner, forward_type.to_mnn_sys());
329 }
330 self
331 }
332
333 pub fn with_type(mut self, forward_type: ForwardType) -> Self {
335 self.set_type(forward_type);
336 self
337 }
338
339 pub fn get_type(&self) -> ForwardType {
341 unsafe { ForwardType::from_mnn_sys(mnnsc_get_type(self.inner)) }
342 }
343
344 pub fn set_num_threads(&mut self, num_threads: i32) -> &mut Self {
350 unsafe {
351 mnnsc_set_num_threads(self.inner, num_threads);
352 }
353 self
354 }
355
356 pub fn with_num_threads(mut self, num_threads: i32) -> Self {
358 self.set_num_threads(num_threads);
359 self
360 }
361
362 pub fn set_mode(&mut self, mode: i32) -> &mut Self {
368 unsafe {
369 mnnsc_set_mode(self.inner, mode);
370 }
371 self
372 }
373
374 pub fn with_mode(mut self, mode: i32) -> Self {
376 self.set_mode(mode);
377 self
378 }
379
380 pub fn set_backup_type(&mut self, backup_type: ForwardType) -> &mut Self {
386 unsafe {
387 mnnsc_set_backup_type(self.inner, backup_type.to_mnn_sys());
388 }
389 self
390 }
391
392 pub fn with_backup_type(mut self, backup_type: ForwardType) -> Self {
394 self.set_backup_type(backup_type);
395 self
396 }
397
398 pub fn get_backup_type(&self) -> ForwardType {
400 unsafe { ForwardType::from_mnn_sys(mnnsc_get_backup_type(self.inner)) }
401 }
402
403 pub fn set_backend_config(
409 &mut self,
410 backend_config: impl Into<Option<BackendConfig>>,
411 ) -> &mut Self {
412 self.backend_config = backend_config.into();
413 let ptr = if let Some(ref b) = self.backend_config {
414 b.inner
415 } else {
416 core::ptr::null_mut()
417 };
418 unsafe {
419 mnnsc_set_backend_config(self.inner, ptr);
420 }
421 self
422 }
423
424 pub fn with_backend_config(mut self, backend_config: impl Into<Option<BackendConfig>>) -> Self {
426 self.set_backend_config(backend_config);
427 self
428 }
429}
430
431#[derive(Debug)]
433pub struct ScheduleConfigs {
434 pub(crate) inner: Vec<*const MNNScheduleConfig>,
435 pub(crate) backend_configs: Vec<Option<BackendConfig>>,
436}
437
438impl Drop for ScheduleConfigs {
439 fn drop(&mut self) {
440 unsafe {
441 for i in self.inner.iter() {
442 mnnsc_destroy(*i.cast());
443 }
444 }
445 }
446}
447
448impl ScheduleConfigs {
449 pub fn push(&mut self, config: ScheduleConfig) {
451 let mut config = ManuallyDrop::new(config);
452 self.inner.push(config.inner);
453 self.backend_configs.push(config.backend_config.take());
454 }
455
456 pub fn with_capacity(capacity: usize) -> Self {
458 Self {
459 inner: Vec::with_capacity(capacity),
460 backend_configs: Vec::with_capacity(capacity),
461 }
462 }
463
464 pub const fn new() -> Self {
466 Self {
467 inner: Vec::new(),
468 backend_configs: Vec::new(),
469 }
470 }
471}
472
473impl Default for ScheduleConfigs {
474 fn default() -> Self {
475 Self::new()
476 }
477}
478
479impl FromIterator<ScheduleConfig> for ScheduleConfigs {
480 fn from_iter<T: IntoIterator<Item = ScheduleConfig>>(iter: T) -> Self {
481 let iter = iter.into_iter();
482 let mut ret = Self::with_capacity(iter.size_hint().1.unwrap_or_default());
483 iter.for_each(|item| {
484 ret.push(item);
485 });
486 ret
487 }
488}
489
490unsafe impl Send for ScheduleConfigs {}