1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Error types for the mlx-native crate.
//!
//! All public functions return `Result<T, MlxError>` — the crate never panics.
/// Compile-time assertion that a type is Send + Sync. Used internally.
#[doc(hidden)]
#[macro_export]
macro_rules! static_assertions_send_sync {
($t:ty) => {
const _: fn() = || {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<$t>();
assert_sync::<$t>();
};
};
}
/// Unified error type for all Metal GPU operations.
#[derive(Debug, thiserror::Error)]
pub enum MlxError {
/// No Metal-capable GPU device was found on this system.
#[error("No Metal GPU device found — Apple Silicon required")]
DeviceNotFound,
/// A Metal command buffer completed with an error status.
#[error("Command buffer error: {0}")]
CommandBufferError(String),
/// An MSL shader failed to compile.
#[error("Shader compilation error for '{name}': {message}")]
ShaderCompilationError {
/// Name of the shader / kernel function that failed.
name: String,
/// Compiler diagnostic message.
message: String,
},
/// Metal buffer allocation failed (usually out of GPU memory).
#[error("Failed to allocate Metal buffer of {bytes} bytes")]
BufferAllocationError {
/// Requested allocation size in bytes.
bytes: usize,
},
/// A Metal residency set could not be created or updated.
#[error("Residency set error: {0}")]
ResidencySetError(String),
/// An argument to a public function was invalid.
#[error("Invalid argument: {0}")]
InvalidArgument(String),
/// A kernel function was not found in the compiled library.
#[error("Kernel not found: {0}")]
KernelNotFound(String),
/// An I/O error occurred (e.g. reading a safetensors file).
#[error("I/O error: {0}")]
IoError(String),
/// A safetensors file could not be parsed or contains invalid data.
#[error("Safetensors error: {0}")]
SafetensorsError(String),
/// A quantization config file could not be parsed.
#[error("Quantization config error: {0}")]
QuantConfigError(String),
/// An unsupported data type was encountered.
#[error("Unsupported dtype: {0}")]
UnsupportedDtype(String),
/// A GGUF file could not be parsed or contains invalid data.
#[error("GGUF parse error: {0}")]
GgufParseError(String),
}
/// Convenience alias used throughout the crate.
pub type Result<T> = std::result::Result<T, MlxError>;
/// Display implementation is handled by thiserror; this is a manual `Debug`
/// helper for the shader variant to keep log output readable.
impl MlxError {
/// Returns `true` if this is a transient error that *might* succeed on retry
/// (e.g. a command buffer timeout). Most errors are permanent.
pub fn is_transient(&self) -> bool {
matches!(self, MlxError::CommandBufferError(_))
}
}
// Ensure the error type itself is thread-safe.
static_assertions_send_sync!(MlxError);