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