cubecl_tile/space/walk/
portion.rs1use cubecl::prelude::*;
4
5use crate::{ComputeScope, Coverage, CubeAxis, Level, Region, Walk, WalkExpand};
6
7#[derive(CubeType)]
15pub struct Portion {
16 regions: Walk,
18 first: usize,
20 start: usize,
22 end: usize,
23 stride: usize,
25 run_length: usize,
27 run: usize,
29}
30
31#[cube]
32impl Portion {
33 pub fn touched(&self) -> usize {
35 self.regions.total()
36 }
37
38 pub fn region(&self, i: usize) -> Region {
40 self.regions.region(i)
41 }
42
43 pub fn index(&self, i: usize) -> usize {
46 self.first + i
47 }
48
49 pub fn steps(&self, i: usize) -> (usize, usize) {
51 let base = (self.first + i) * self.stride;
52 let from = select(base < self.start, self.start - base, 0);
53 let to = select(self.end < base + self.stride, self.end - base, self.stride);
54 (from, to - from)
55 }
56
57 pub fn holders(&self, i: usize) -> (usize, usize) {
60 let base = (self.first + i) * self.stride;
61 let first_run = self.run_holding(base);
62 let last_run = self.run_holding(base + self.stride - 1);
63 (first_run, last_run + 1 - first_run)
64 }
65
66 pub fn run(&self) -> usize {
68 self.run
69 }
70
71 pub fn starts_in(&self, i: usize, run: usize) -> bool {
74 run * self.run_length >= (self.first + i) * self.stride
75 }
76
77 fn run_holding(&self, step: usize) -> usize {
79 step / self.run_length
80 }
81}
82
83#[cube]
84impl Walk {
85 pub fn portion(self, #[comptime] below: Level) -> Portion {
87 let instances = comptime!(
88 self.level
89 .shared_by()
90 .expect("Walk::portion: this level distributes no grid as one; say `shared_by`")
91 );
92 let stride = self.region(0).over(&below).total();
93 let steps = self.total() * stride;
94 let run = match comptime!(self.level.coverage()) {
95 Coverage::Distribute(ComputeScope::Cube) => CubeAxis::position(CubeAxis::X),
96 Coverage::Distribute(ComputeScope::Plane) => {
97 ComputeScope::position(ComputeScope::Plane)
98 }
99 Coverage::Distribute(ComputeScope::PlaneGroup { planes }) => {
100 ComputeScope::position(comptime!(ComputeScope::PlaneGroup { planes }))
101 }
102 Coverage::Distribute(ComputeScope::Unit) | Coverage::Walk => {
103 panic!(
104 "Walk::portion: only cubes, plane groups or planes share a grid as one index"
105 )
106 }
107 };
108 let run_length = steps.div_ceil(instances);
109 let start = (run * run_length).min(steps);
110 let end = (start + run_length).min(steps);
111 let first = start / stride;
112 let touched = select(start < end, (end - 1) / stride + 1 - first, 0);
114 Portion {
115 regions: self.range(first, touched),
116 first,
117 start,
118 end,
119 stride,
120 run_length,
121 run,
122 }
123 }
124}