sokuto_runtime/engine/
provider.rs1use ort::ep::ExecutionProvider as OrtExecutionProvider;
7use ort::session::builder::SessionBuilder;
8
9use crate::engine::config::ExecutionProvider;
10use crate::error::{Result, RuntimeError};
11
12pub fn register_execution_providers(
17 builder: &mut SessionBuilder,
18 preferred: &[ExecutionProvider],
19 enable_mem_arena: bool,
20) -> Result<ExecutionProvider> {
21 for provider in preferred {
22 match provider {
23 ExecutionProvider::Auto => {
24 #[cfg(target_os = "macos")]
26 let sub_preferred = [ExecutionProvider::CoreML, ExecutionProvider::CPU];
27 #[cfg(not(target_os = "macos"))]
28 let sub_preferred = [
29 ExecutionProvider::TensorRT,
30 ExecutionProvider::CUDA,
31 ExecutionProvider::CPU,
32 ];
33 if let Ok(active) =
34 register_execution_providers(builder, &sub_preferred, enable_mem_arena)
35 {
36 return Ok(active);
37 }
38 }
39 ExecutionProvider::CoreML => {
40 #[cfg(feature = "coreml")]
41 {
42 use ort::ep::coreml::CoreML;
43 let ep = CoreML::default();
44 match ep.is_available() {
45 Ok(true) => match ep.register(builder) {
46 Ok(()) => {
47 tracing::info!(
48 "CoreML Execution Provider が正常に登録されました。"
49 );
50 return Ok(ExecutionProvider::CoreML);
51 }
52 Err(e) => {
53 tracing::warn!(
54 "CoreML の登録に失敗しました ({e})。CPU にフォールバックします。"
55 );
56 }
57 },
58 Ok(false) => {
59 tracing::info!(
60 "CoreML は利用可能ではありません。次の EP を試行します。"
61 );
62 }
63 Err(e) => {
64 tracing::warn!("CoreML 利用可否確認中にエラーが発生しました: {e}。");
65 }
66 }
67 }
68 #[cfg(not(feature = "coreml"))]
69 {
70 tracing::debug!(
71 "CoreML feature は未コンパイルです。CPU にフォールバックします。"
72 );
73 }
74 }
75 ExecutionProvider::CUDA => {
76 #[cfg(feature = "cuda")]
77 {
78 use ort::ep::cuda::CUDA;
79 let ep = CUDA::default();
80 match ep.is_available() {
81 Ok(true) => match ep.register(builder) {
82 Ok(()) => {
83 tracing::info!("CUDA Execution Provider が正常に登録されました。");
84 return Ok(ExecutionProvider::CUDA);
85 }
86 Err(e) => {
87 tracing::warn!(
88 "CUDA の登録に失敗しました ({e})。CPU にフォールバックします。"
89 );
90 }
91 },
92 Ok(false) => {
93 tracing::info!("CUDA は利用可能ではありません。次の EP を試行します。");
94 }
95 Err(e) => {
96 tracing::warn!("CUDA 利用可否確認中にエラーが発生しました: {e}。");
97 }
98 }
99 }
100 #[cfg(not(feature = "cuda"))]
101 {
102 tracing::debug!(
103 "CUDA feature は未コンパイルです。CPU にフォールバックします。"
104 );
105 }
106 }
107 ExecutionProvider::TensorRT => {
108 #[cfg(feature = "tensorrt")]
109 {
110 use ort::ep::tensorrt::TensorRT;
111 let ep = TensorRT::default();
112 match ep.is_available() {
113 Ok(true) => match ep.register(builder) {
114 Ok(()) => {
115 tracing::info!(
116 "TensorRT Execution Provider が正常に登録されました。"
117 );
118 return Ok(ExecutionProvider::TensorRT);
119 }
120 Err(e) => {
121 tracing::warn!(
122 "TensorRT の登録に失敗しました ({e})。CPU にフォールバックします。"
123 );
124 }
125 },
126 Ok(false) => {
127 tracing::info!(
128 "TensorRT は利用可能ではありません。次の EP を試行します。"
129 );
130 }
131 Err(e) => {
132 tracing::warn!("TensorRT 利用可否確認中にエラーが発生しました: {e}。");
133 }
134 }
135 }
136 #[cfg(not(feature = "tensorrt"))]
137 {
138 tracing::debug!(
139 "TensorRT feature は未コンパイルです。CPU にフォールバックします。"
140 );
141 }
142 }
143 ExecutionProvider::CPU => {
144 let ep = ort::ep::CPU::default().with_arena_allocator(enable_mem_arena);
145 ep.register(builder).map_err(|e| {
146 RuntimeError::ExecutionProviderError(format!(
147 "CPUExecutionProvider の登録に失敗しました: {e}。"
148 ))
149 })?;
150 tracing::info!(
151 "CPU Execution Provider が正常に登録されました (メモリアリーナ: {enable_mem_arena})。"
152 );
153 return Ok(ExecutionProvider::CPU);
154 }
155 }
156 }
157
158 let ep = ort::ep::CPU::default().with_arena_allocator(enable_mem_arena);
160 ep.register(builder).map_err(|e| {
161 RuntimeError::ExecutionProviderError(format!(
162 "CPUExecutionProvider への最終フォールバックに失敗しました: {e}。"
163 ))
164 })?;
165 tracing::info!(
166 "CPU Execution Provider への最終フォールバックが完了しました (メモリアリーナ: {enable_mem_arena})。"
167 );
168 Ok(ExecutionProvider::CPU)
169}