cubek_std/routine/
grid.rs1use crate::Hardware;
2use crate::microkernel::{CubeFootprint, CubePlanes, KernelEstimate};
3use crate::routine::{ADMITTED_PLAN_RUNS, LaunchSettings};
4use cubecl::CubeCount;
5use cubecl::client::Client;
6use cubecl::tile::launch::Grid as LaunchGrid;
7use cubecl::tile::launch::Refusal;
8use cubecl::tile::{Launcher, Partitioning, Space};
9use cubecl_environment::sync::{Arc, SyncOnceCell};
10
11#[derive(Debug, Clone)]
16pub struct Grid {
17 pub launch: LaunchSettings,
19 pub shared_memory: usize,
21 launcher: SettledLauncher,
23}
24
25#[derive(Clone, Default)]
29struct SettledLauncher(Arc<SyncOnceCell<Launcher>>);
30
31impl core::fmt::Debug for SettledLauncher {
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 f.write_str("SettledLauncher")
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct CubeResources {
40 pub plane_width: u32,
42 pub shared_memory: usize,
44}
45
46impl Grid {
47 pub fn launcher(
56 &self,
57 client: &Client,
58 settle: impl FnOnce() -> (Partitioning, Space),
59 ) -> Launcher {
60 self.launcher
61 .0
62 .get_or_init(|| {
63 let (kernel, concrete) = settle();
64 Launcher::new(
65 client,
66 kernel,
67 &concrete,
68 LaunchGrid::Stated {
69 cube_count: self.launch.cube_count.clone(),
70 cube_dim: self.launch.cube_dim,
71 },
72 )
73 .and_then(|launcher| launcher.holding(self.shared_memory))
74 .expect(ADMITTED_PLAN_RUNS)
75 })
76 .clone()
77 }
78
79 pub fn new(
86 hw: &Hardware,
87 partitioning: &Partitioning,
88 cube: CubeResources,
89 ) -> Result<Self, Refusal> {
90 let launch = LaunchSettings {
91 cube_dim: partitioning.cube_dim(cube.plane_width),
92 cube_count: partitioning.cube_count(),
93 vectors: (),
94 }
95 .validate(hw)?;
96 let available = hw.shared_memory_budget();
97 if cube.shared_memory > available {
98 return Err(Refusal::SharedMemoryPastDevice {
99 bytes: cube.shared_memory,
100 most: available,
101 });
102 }
103 Ok(Self {
104 launch,
105 shared_memory: cube.shared_memory,
106 launcher: SettledLauncher::default(),
107 })
108 }
109
110 pub fn cubes(&self) -> Option<u64> {
112 match self.launch.cube_count {
113 CubeCount::Static(x, y, z) => Some(u64::from(x) * u64::from(y) * u64::from(z)),
114 CubeCount::Dynamic(_) => None,
115 }
116 }
117
118 pub fn planes(&self) -> CubePlanes {
120 CubePlanes {
121 count: self.launch.cube_dim.y as usize,
122 width: self.launch.cube_dim.x as usize,
123 }
124 }
125}
126
127impl From<&Grid> for KernelEstimate {
128 fn from(grid: &Grid) -> Self {
130 Self {
131 cubes: grid.cubes(),
132 cube: CubeFootprint {
133 units: grid.launch.units_per_cube(),
134 shared_memory: grid.shared_memory,
135 },
136 demand: None,
137 staging: None,
138 work: None,
139 }
140 }
141}