Skip to main content

cubecl_utils_rs/
errors.rs

1//! Errors in `cubecl-utils-rs`.
2
3use thiserror::Error;
4
5use cubecl::server::ServerError;
6
7/// All error variants that can occur across `cubecl-utils-rs` operations.
8///
9/// Marked `#[non_exhaustive]` so that added variants do not break a downstream
10/// exhaustive `match`. Match on the variants you care about and keep a `_` arm.
11///
12/// Every variant here describes a condition that CubeCL itself reports either
13/// silently or in the wrong place. See the crate-level docs for why that
14/// matters.
15#[derive(Debug, Error)]
16#[non_exhaustive]
17pub enum CubeclUtilsErrors {
18    /// A dispatch exceeds the device's per-dimension cube-count limit.
19    ///
20    /// Not a soft failure on wgpu: the launch is rejected on the CubeCL server
21    /// thread, that thread dies, and every subsequent call on the client
22    /// returns an unrelated `CallError` from somewhere else entirely.
23    #[error(
24        "Kernel '{kernel}' requested a cube count of {requested:?}, but this device's limit is \
25         {limit:?}."
26    )]
27    CubeCountExceeded {
28        /// Name of the kernel whose dispatch was rejected
29        kernel: &'static str,
30        /// Requested cube count as `(x, y, z)`
31        requested: (u32, u32, u32),
32        /// Per-dimension device limit as `(x, y, z)`
33        limit: (u32, u32, u32),
34    },
35
36    /// A flat cube count cannot be expressed as a 2D grid within the limit.
37    ///
38    /// Reachable only when `total_cubes` exceeds `max_dim * max_dim`, i.e. past
39    /// roughly 4.29e9 cubes against a 65535 limit.
40    #[error(
41        "A grid of {total_cubes} cubes does not fit a 2D decomposition bounded by {max_dim} per \
42         dimension."
43    )]
44    GridTooLarge {
45        /// Flat cube count that was requested
46        total_cubes: u32,
47        /// Per-dimension limit the decomposition had to respect
48        max_dim: u32,
49    },
50
51    /// A single buffer exceeds the device's per-binding size limit.
52    ///
53    /// Over-sized bindings are rejected without an error surfacing: the kernel
54    /// does no work and returns zeros, so the condition is caught on the host
55    /// before the allocation instead.
56    #[error(
57        "A GPU buffer of {requested} bytes exceeds this device's per-binding limit of {limit} \
58         bytes."
59    )]
60    BindingTooLarge {
61        /// Bytes the buffer requires
62        requested: u64,
63        /// Per-binding limit reported by the device
64        limit: u64,
65    },
66
67    /// A kernel's shared-memory footprint exceeds the device's per-workgroup
68    /// budget.
69    ///
70    /// Carries the budget so the caller can report what would have fitted.
71    /// Apple Silicon reports 32768 bytes, which is at the low end of what
72    /// desktop hardware offers but above the 16384 that some integrated parts
73    /// report.
74    #[error(
75        "Kernel '{kernel}' needs {requested} bytes of shared memory, but this device offers only \
76         {available} bytes per workgroup."
77    )]
78    SharedMemoryExceeded {
79        /// Name of the kernel whose staging does not fit
80        kernel: &'static str,
81        /// Bytes the kernel would allocate
82        requested: usize,
83        /// Bytes the device offers per workgroup
84        available: usize,
85    },
86
87    /// Propagate errors from the CubeCL runtime.
88    #[error("Error from the cubecl runtime: {0}")]
89    CubeClServerError(#[from] ServerError),
90}