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
//! Shared CubeCL helpers: GPU tensors, device-limit queries and validated
//! dispatch geometry. No algorithms and no kernels.
//!
//! # Why this exists
//!
//! A CubeCL kernel dispatched with `launch_unchecked` that busts a device limit
//! does not fail loudly:
//!
//! - Over-allocating **shared memory** makes the kernel do no work. It writes
//! nothing, returns zeros and reports no error. Downstream code then reads
//! uninitialised memory, which surfaces as an absurd index or a distance in
//! an index slot rather than as anything pointing at the kernel.
//! - Over-sizing a **binding** does the same.
//! - Busting the **cube-count** limit is worse: the launch is rejected on the
//! CubeCL server thread, that thread dies, and the next unrelated call on the
//! client returns a `CallError` from somewhere else entirely.
//!
//! So device limits are a correctness concern, not a tuning one, and they are
//! easy to get wrong when every machine to hand reports the same numbers. Apple
//! Silicon via wgpu reports 32 KiB of shared memory, 65535 cubes per grid
//! dimension and a plane size pinned to exactly 32. None of that is portable.
//!
//! # Design
//!
//! Every limit decision is a pure function of [`GpuLimits`]. Only
//! [`GpuLimits::from_client`] and the [`GpuTensor`] constructors touch a
//! `ComputeClient`; everything else takes limits as data.
//!
//! That is what makes the awkward cases testable. Asserting that a staging plan
//! shrinks correctly on a 16 KiB device, or that a workgroup rounds to whole
//! wave64 planes, needs no such device to be present.
//!
//! ```no_run
//! # use cubecl::prelude::*;
//! use cubecl_utils_rs::prelude::*;
//!
//! # fn demo<R: Runtime>(client: &ComputeClient<R>, n_blocks: u32) -> Result<(), CubeclUtilsErrors> {
//! let limits = GpuLimits::from_client(client);
//! let (gx, gy) = grid_2d(n_blocks, &limits)?;
//! let count = checked_cube_count("my_kernel", gx, gy, 1, &limits)?;
//! # Ok(())
//! # }
//! ```
pub use crateCubeclUtilsErrors;
pub use crate;
pub use crate;
pub use crateGpuTensor;
pub use crateCubeclFloat;