cubek_convolution/kernels/backward_data/
launch.rs1use crate::{
2 backward_data::args::ConcreteArgs,
3 components::{ConvSetupError, ConvolutionOperation, ConvolutionProblem, Dimensionality},
4 kernels::backward_data::selector::launch_kernel_concrete,
5 launch::ConvolutionArgs,
6 routines::Routine,
7};
8use cubecl::{client::Client, prelude::*};
9use cubek_matmul::{
10 definition::{AvailableVectorSizes, MatmulElems, MatmulSetupError},
11 routine::BlueprintStrategy,
12};
13use cubek_std::{InputBinding, MatrixLayout};
14
15#[allow(clippy::result_large_err, clippy::too_many_arguments)]
21pub(crate) fn launch_internal<const N_SPATIAL: usize, Rt: Routine>(
22 client: &Client,
23 out_grad: InputBinding,
24 weights: InputBinding,
25 in_grad: TensorBinding,
26 args: ConvolutionArgs<N_SPATIAL>,
27 blueprint_strategy: &BlueprintStrategy<Rt::MatmulRoutine>,
28 dtypes: MatmulElems,
29) -> Result<(), ConvSetupError>
30where
31 Rt::Args: ConcreteArgs<Rt::MatmulRoutine>,
32{
33 let ConvolutionArgs {
34 stride,
35 padding,
36 dilation,
37 } = args;
38
39 let dimensionality = match N_SPATIAL {
40 1 => Dimensionality::Dim1,
41 2 => Dimensionality::Dim2,
42 3 => Dimensionality::Dim3,
43 other => unimplemented!("Unsupported dimensionality {other}"),
44 };
45
46 launch_with_routine::<Rt>(
47 client,
48 out_grad,
49 weights,
50 in_grad,
51 (&stride, &padding, &dilation),
52 dimensionality,
53 blueprint_strategy,
54 dtypes,
55 )
56}
57
58#[allow(clippy::too_many_arguments)]
59fn launch_with_routine<Rt: Routine>(
60 client: &Client,
61 out_grad: InputBinding,
62 weights: InputBinding,
63 in_grad: TensorBinding,
64 (stride, padding, dilation): (&[usize], &[usize], &[usize]),
65 dimensionality: Dimensionality,
66 blueprint_strategy: &BlueprintStrategy<Rt::MatmulRoutine>,
67 dtypes: MatmulElems,
68) -> Result<(), ConvSetupError>
69where
70 Rt::Args: ConcreteArgs<Rt::MatmulRoutine>,
71{
72 let rank = in_grad.shape.len();
73 let dim_c = rank - 1;
74
75 let n = in_grad.shape[0];
76 let c = in_grad.shape[dim_c];
77
78 let out_c = out_grad.shape()[dim_c];
79
80 let in_shape = &in_grad.shape[1..dim_c];
81 let kernel_shape = &weights.shape()[1..dim_c];
82 let out_shape = &out_grad.shape()[1..dim_c];
83
84 let op = ConvolutionOperation::BackwardData;
85
86 let out_grad_tmp = out_grad.clone();
87 let weights_tmp = weights.clone();
88
89 let out_grad_data =
90 Rt::correct_layout(client, out_grad_tmp.into_data(), dtypes.lhs_global, op)?;
91 let weights_data = Rt::correct_layout(client, weights_tmp.into_data(), dtypes.rhs_global, op)?;
92
93 let mut out_grad = out_grad.clone();
94 let mut weights = weights.clone();
95
96 *out_grad.data_mut() = out_grad_data;
97 *weights.data_mut() = weights_data;
98
99 let address_type = out_grad
100 .required_address_type()
101 .max(weights.required_address_type())
102 .max(in_grad.required_address_type(dtypes.acc_global.size()));
103
104 let problem = ConvolutionProblem {
105 m: n * in_shape.iter().product::<usize>(),
106 n: c,
107 k: out_c * kernel_shape.iter().product::<usize>(),
108
109 lhs_strides: out_grad.data().strides.clone(),
110 rhs_strides: weights.data().strides.clone(),
111 lhs_layout: MatrixLayout::RowMajor,
112 rhs_layout: MatrixLayout::RowMajor,
113 kernel_size: kernel_shape.iter().map(|it| *it as u32).collect(),
114 stride: stride.iter().map(|it| *it as u32).collect(),
115 padding: padding.iter().map(|it| *it as i32).collect(),
116 dilation: dilation.iter().map(|it| *it as u32).collect(),
117
118 batches: n,
119 in_shape: in_shape.into(),
120 out_shape: out_shape.into(),
121 channels: c,
122 out_channels: out_c,
123
124 padded_channels: out_c,
125 operation: op,
126
127 dimensionality,
128 global_dtypes: dtypes.as_global_elems(),
129 address_type,
130 };
131
132 launch_kernel::<Rt>(
133 client,
134 out_grad,
135 weights,
136 in_grad,
137 problem,
138 blueprint_strategy,
139 dtypes,
140 )
141}
142
143#[allow(clippy::result_large_err, clippy::too_many_arguments)]
144pub fn launch_kernel<Rt: Routine>(
145 client: &Client,
146 out_grad: InputBinding,
147 weights: InputBinding,
148 in_grad: TensorBinding,
149 problem: ConvolutionProblem,
150 blueprint_strategy: &BlueprintStrategy<Rt::MatmulRoutine>,
151 dtypes: MatmulElems,
152) -> Result<(), ConvSetupError>
153where
154 Rt::Args: ConcreteArgs<Rt::MatmulRoutine>,
155{
156 let vector_sizes = Rt::filter_vector_sizes(AvailableVectorSizes::from_type_sizes(
159 client,
160 out_grad.data_elem_size(),
161 weights.data_elem_size(),
162 dtypes.acc_global.size(),
163 ))
164 .filter_lhs_with_tensor(
165 &out_grad.data().strides,
166 &out_grad.data().shape,
167 MatrixLayout::RowMajor,
168 )
169 .filter_rhs_with_tensor(
170 &weights.data().strides,
171 &weights.data().shape,
172 MatrixLayout::RowMajor,
173 )
174 .filter_out_with_tensor(&in_grad.strides, &in_grad.shape)
175 .pick_max()?;
176
177 launch_kernel_concrete::<Rt::Args, Rt::MatmulRoutine>(
178 client,
179 out_grad,
180 weights,
181 in_grad,
182 problem,
183 vector_sizes,
184 blueprint_strategy,
185 &dtypes,
186 )
187}
188
189#[allow(dead_code)]
193pub(crate) fn unsupported_tma_error() -> ConvSetupError {
194 ConvSetupError::Matmul(MatmulSetupError::InvalidConfig(Box::new(
195 "Data backprop doesn't yet work with current TMA tiling strategy",
196 )))
197}