1mod access_graph;
6pub mod artifacts;
7#[path = "benchmark_statistics.rs"]
8pub mod benchmark;
9mod buffer_pool;
10pub mod bundle;
11mod dependency_frontier;
12pub mod fabric;
13pub mod image;
14pub mod inference;
15pub mod jobs;
16pub mod plan_cache;
17pub mod residency;
18mod runtime;
19mod target;
20pub mod tensor;
21pub use access_graph::{AccessGraph, AccessView};
22pub use buffer_pool::{BufferPool, PooledBuffer};
23pub use runtime::*;
24pub mod execution;
26#[path = "loom/model.rs"]
27pub mod model;
28pub use execution::{Access, Completion, Runtime};
29pub mod gpu {
32 pub use crate::runtime::*;
33}
34pub use target::{TARGET_KEY, Target};
35pub mod loom;
36#[cfg(feature = "npu")]
37pub mod npu;
38
39#[cfg(doctest)]
42#[doc = include_str!("../README.md")]
43pub struct Readme;
44
45#[derive(Debug, thiserror::Error)]
47#[non_exhaustive]
48pub enum Error {
49 #[error("resource busy: {0}")]
51 Busy(String),
52 #[error("unsupported capability: {0}")]
54 Unsupported(String),
55 #[error("device execution failed: {0}")]
57 DeviceLost(String),
58 #[error("{backend} {operation} failed ({code}): {message}")]
60 Backend {
61 backend: &'static str,
63 operation: &'static str,
65 code: i32,
67 message: Box<str>,
70 },
71 #[error("{source}")]
73 Execution {
74 #[source]
76 source: std::sync::Arc<Error>,
77 },
78 #[error("execution cancelled")]
80 Cancelled,
81 #[error("{0}")]
83 Message(String),
84 #[error("Loom compilation failed: {message}")]
86 Compile {
87 message: String,
89 diagnostics: Vec<loom::Diagnostic>,
91 },
92 #[error("{0}")]
94 Io(#[from] std::io::Error),
95 #[error("{0}")]
97 Json(#[from] serde_json::Error),
98 #[error("{0}")]
100 Library(#[from] libloading::Error),
101 #[error("{0}")]
103 Download(#[source] Box<ureq::Error>),
104 #[error("{context}: {message}")]
107 Runtime {
108 context: String,
110 code: i32,
112 message: String,
114 },
115 #[error("{context}: {source}")]
117 Context {
118 context: String,
120 #[source]
121 source: Box<Error>,
123 },
124}
125impl Error {
126 pub fn context(self, context: impl Into<String>) -> Self {
128 Self::Context {
129 context: context.into(),
130 source: Box::new(self),
131 }
132 }
133}
134pub type Result<T> = std::result::Result<T, Error>;
136
137pub mod runner;
138
139pub(crate) fn cached_init<T: Clone>(
141 cache: &std::sync::Mutex<Option<T>>,
142 initialize: impl FnOnce() -> Result<T>,
143) -> Result<T> {
144 let mut cached = cache
145 .lock()
146 .map_err(|_| Error::Message("initialization cache poisoned".into()))?;
147 if let Some(value) = cached.as_ref() {
148 return Ok(value.clone());
149 }
150 let value = initialize()?;
151 *cached = Some(value.clone());
152 Ok(value)
153}
154
155#[cfg(test)]
156mod initialization_tests {
157 #[test]
158 fn failures_retry_and_concurrent_success_initializes_once() {
159 use std::sync::{
160 Mutex,
161 atomic::{AtomicUsize, Ordering},
162 };
163 let cache = Mutex::new(None);
164 assert!(
165 super::cached_init(&cache, || Err::<usize, _>(super::Error::Message(
166 "transient".into()
167 )))
168 .is_err()
169 );
170 let calls = AtomicUsize::new(0);
171 std::thread::scope(|scope| {
172 for _ in 0..8 {
173 scope.spawn(|| {
174 assert_eq!(
175 super::cached_init(&cache, || {
176 calls.fetch_add(1, Ordering::Relaxed);
177 Ok(42)
178 })
179 .unwrap(),
180 42
181 );
182 });
183 }
184 });
185 assert_eq!(calls.load(Ordering::Relaxed), 1);
186 }
187}