1use ruda_kernel::dsl as kernel_dsl;
8use ruda_kernel::dsl::Runtime;
9use ruda_kernel::dsl::client::ComputeClient;
10use rublas::kernel_ir::{
11 components::tile::TileMatmulKind,
12 definition::{MatmulElems, TilingBlueprint},
13 routines::{BlueprintStrategy, Routine as MatmulRoutine, TilingArgs},
14};
15
16use crate::convolution::components::ConvolutionOperation;
17use crate::convolution::definition::ConvBlueprint;
18
19fn blueprint_operation(blueprint: &ConvBlueprint) -> ConvolutionOperation {
20 match blueprint {
21 ConvBlueprint::Forward(_) => ConvolutionOperation::Forward,
22 ConvBlueprint::BackwardData(_) => ConvolutionOperation::BackwardData,
23 ConvBlueprint::BackwardWeight(_) => ConvolutionOperation::BackwardWeight,
24 }
25}
26
27use crate::convolution::{
28 components::{ConvSetupError, global::args::RuntimeArgs},
29 kernels::{backward_data, backward_weight, forward},
30 launch::{
31 ConvAlgorithm, ConvolutionArgs, ConvolutionInputs, Strategy, strategy::AcceleratedTileKind,
32 },
33 routines::{
34 Routine,
35 simple::{
36 SimpleAsyncCyclicConv, SimpleAsyncStridedConv, SimpleAsyncTmaConv,
37 SimpleSyncCyclicConv, SimpleSyncStridedConv, SimpleSyncTilewiseConv,
38 },
39 specialized::{
40 SpecializedAsyncCyclicConv, SpecializedAsyncStridedConv, SpecializedTmaConv,
41 },
42 },
43};
44
45pub(crate) fn tile_kind_to_dispatch(kind: AcceleratedTileKind) -> TileMatmulKind {
47 match kind {
48 AcceleratedTileKind::Cmma => TileMatmulKind::Cmma,
49 AcceleratedTileKind::Mma => TileMatmulKind::Mma,
50 }
51}
52
53#[allow(clippy::result_large_err)]
59pub fn launch_ref<R: Runtime, const N_SPATIAL: usize>(
60 strategy: &Strategy,
61 client: &ComputeClient<R>,
62 inputs: ConvolutionInputs<R>,
63 args: ConvolutionArgs<N_SPATIAL>,
64 dtypes: MatmulElems,
65) -> Result<(), ConvSetupError> {
66 let (algorithm, tile_kind, forced_matmul) = match strategy {
67 Strategy::Inferred {
68 algorithm,
69 tile_kind,
70 } => (*algorithm, *tile_kind, None),
71 Strategy::Forced {
72 algorithm,
73 blueprint,
74 } => {
75 debug_assert_eq!(
76 inputs.operation(),
77 blueprint_operation(blueprint),
78 "Strategy::Forced blueprint variant does not match the inputs operation",
79 );
80 let matmul = blueprint.matmul().clone();
81 (*algorithm, AcceleratedTileKind::Cmma, Some(matmul))
85 }
86 };
87
88 if inputs.operation() == ConvolutionOperation::BackwardData
90 && algorithm == ConvAlgorithm::SimpleAsyncTma
91 {
92 return Err(crate::convolution::kernels::backward_data::launch::unsupported_tma_error());
93 }
94
95 dispatch_routine::<R, N_SPATIAL>(
96 algorithm,
97 tile_kind,
98 forced_matmul,
99 client,
100 inputs,
101 args,
102 dtypes,
103 )
104}
105
106#[allow(clippy::result_large_err, clippy::too_many_arguments)]
109fn dispatch_routine<R: Runtime, const N_SPATIAL: usize>(
110 algorithm: ConvAlgorithm,
111 tile_kind: AcceleratedTileKind,
112 forced_matmul: Option<TilingBlueprint>,
113 client: &ComputeClient<R>,
114 inputs: ConvolutionInputs<R>,
115 args: ConvolutionArgs<N_SPATIAL>,
116 dtypes: MatmulElems,
117) -> Result<(), ConvSetupError> {
118 let kind = tile_kind_to_dispatch(tile_kind);
119 match algorithm {
120 ConvAlgorithm::SimpleSyncCyclic => dispatch_inputs::<R, N_SPATIAL, SimpleSyncCyclicConv>(
121 client,
122 inputs,
123 args,
124 kind,
125 forced_matmul,
126 dtypes,
127 ),
128 ConvAlgorithm::SimpleSyncStrided => dispatch_inputs::<R, N_SPATIAL, SimpleSyncStridedConv>(
129 client,
130 inputs,
131 args,
132 kind,
133 forced_matmul,
134 dtypes,
135 ),
136 ConvAlgorithm::SimpleSyncTilewise => {
137 dispatch_inputs::<R, N_SPATIAL, SimpleSyncTilewiseConv>(
138 client,
139 inputs,
140 args,
141 kind,
142 forced_matmul,
143 dtypes,
144 )
145 }
146 ConvAlgorithm::SimpleAsyncCyclic => dispatch_inputs::<R, N_SPATIAL, SimpleAsyncCyclicConv>(
147 client,
148 inputs,
149 args,
150 kind,
151 forced_matmul,
152 dtypes,
153 ),
154 ConvAlgorithm::SimpleAsyncStrided => {
155 dispatch_inputs::<R, N_SPATIAL, SimpleAsyncStridedConv>(
156 client,
157 inputs,
158 args,
159 kind,
160 forced_matmul,
161 dtypes,
162 )
163 }
164 ConvAlgorithm::SimpleAsyncTma => dispatch_inputs::<R, N_SPATIAL, SimpleAsyncTmaConv>(
165 client,
166 inputs,
167 args,
168 kind,
169 forced_matmul,
170 dtypes,
171 ),
172 ConvAlgorithm::SpecializedAsyncCyclic => {
173 dispatch_inputs::<R, N_SPATIAL, SpecializedAsyncCyclicConv>(
174 client,
175 inputs,
176 args,
177 kind,
178 forced_matmul,
179 dtypes,
180 )
181 }
182 ConvAlgorithm::SpecializedAsyncStrided => {
183 dispatch_inputs::<R, N_SPATIAL, SpecializedAsyncStridedConv>(
184 client,
185 inputs,
186 args,
187 kind,
188 forced_matmul,
189 dtypes,
190 )
191 }
192 ConvAlgorithm::SpecializedTma => dispatch_inputs::<R, N_SPATIAL, SpecializedTmaConv>(
193 client,
194 inputs,
195 args,
196 kind,
197 forced_matmul,
198 dtypes,
199 ),
200 }
201}
202
203#[allow(clippy::result_large_err, clippy::too_many_arguments)]
209fn dispatch_inputs<R: Runtime, const N_SPATIAL: usize, Rt: Routine<Blueprint = TilingBlueprint>>(
210 client: &ComputeClient<R>,
211 inputs: ConvolutionInputs<R>,
212 args: ConvolutionArgs<N_SPATIAL>,
213 tile_matmul: TileMatmulKind,
214 forced_matmul: Option<TilingBlueprint>,
215 dtypes: MatmulElems,
216) -> Result<(), ConvSetupError>
217where
218 Rt::Args: forward::args::ConcreteArgs<Rt::MatmulRoutine>
219 + backward_data::args::ConcreteArgs<Rt::MatmulRoutine>
220 + backward_weight::args::ConcreteArgs<Rt::MatmulRoutine>,
221 Rt::Strategy: TilingArgs,
222{
223 let blueprint_strategy = build_blueprint_strategy::<Rt>(tile_matmul, forced_matmul);
224
225 match inputs {
226 ConvolutionInputs::Forward {
227 input,
228 weight,
229 bias,
230 out,
231 } => forward::launch::launch_internal::<R, N_SPATIAL, Rt>(
232 client,
233 input,
234 weight,
235 bias,
236 out,
237 args,
238 &blueprint_strategy,
239 dtypes,
240 ),
241 ConvolutionInputs::BackwardData {
242 out_grad,
243 weights,
244 in_grad,
245 } => backward_data::launch::launch_internal::<R, N_SPATIAL, Rt>(
246 client,
247 out_grad,
248 weights,
249 in_grad,
250 args,
251 &blueprint_strategy,
252 dtypes,
253 ),
254 ConvolutionInputs::BackwardWeight {
255 input,
256 out_grad,
257 weight_grad,
258 } => backward_weight::launch::launch_internal::<R, N_SPATIAL, Rt>(
259 client,
260 input,
261 out_grad,
262 weight_grad,
263 args,
264 &blueprint_strategy,
265 dtypes,
266 ),
267 }
268}
269
270fn build_blueprint_strategy<Rt: Routine<Blueprint = TilingBlueprint>>(
274 tile_matmul: TileMatmulKind,
275 forced_matmul: Option<TilingBlueprint>,
276) -> BlueprintStrategy<RuntimeArgs, Rt::MatmulRoutine>
277where
278 Rt::Strategy: TilingArgs,
279{
280 match forced_matmul {
281 Some(matmul) => BlueprintStrategy::Forced(matmul),
282 None => {
283 let mut s = <Rt::MatmulRoutine as MatmulRoutine<RuntimeArgs>>::Strategy::default();
284 s.set_tile_matmul(tile_matmul);
285 BlueprintStrategy::Inferred(s)
286 }
287 }
288}