cubek_convolution/kernels/forward/
launch.rs1use crate::{
2 components::{ConvSetupError, ConvolutionOperation, ConvolutionProblem, Dimensionality},
3 forward::args::ConcreteArgs,
4 kernels::forward::selector::launch_kernel_concrete,
5 launch::ConvolutionArgs,
6 routines::Routine,
7};
8use cubecl::{client::Client, prelude::*};
9use cubek_matmul::{
10 definition::{AvailableVectorSizes, MatmulElems},
11 routine::BlueprintStrategy,
12};
13use cubek_std::{InputBinding, MatrixLayout};
14
15#[allow(clippy::result_large_err, clippy::too_many_arguments)]
20pub(crate) fn launch_internal<const N_SPATIAL: usize, Rt: Routine>(
21 client: &Client,
22 input: InputBinding,
23 weight: InputBinding,
24 bias: Option<InputBinding>,
25 out: 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 input,
49 weight,
50 bias,
51 out,
52 (&stride, &padding, &dilation),
53 dimensionality,
54 blueprint_strategy,
55 dtypes,
56 )
57}
58
59#[allow(clippy::too_many_arguments)]
60fn launch_with_routine<Rt: Routine>(
61 client: &Client,
62 input: InputBinding,
63 weight: InputBinding,
64 bias: Option<InputBinding>,
65 out: TensorBinding,
66 (stride, padding, dilation): (&[usize], &[usize], &[usize]),
67 dimensionality: Dimensionality,
68 blueprint_strategy: &BlueprintStrategy<Rt::MatmulRoutine>,
69 dtypes: MatmulElems,
70) -> Result<(), ConvSetupError>
71where
72 Rt::Args: ConcreteArgs<Rt::MatmulRoutine>,
73{
74 let rank = input.data().shape.len();
75 let dim_c = rank - 1;
76
77 let n = input.data().shape[0];
78 let c = input.data().shape[dim_c];
79
80 let out_c = weight.data().shape[0];
81
82 let in_shape = &input.data().shape[1..dim_c];
83 let kernel_shape = &weight.data().shape[1..dim_c];
84 let out_shape = &out.shape[1..dim_c];
85
86 let op = ConvolutionOperation::Forward;
87
88 let input_data = Rt::correct_layout(client, input.clone().into_data(), dtypes.lhs_global, op)?;
89 let weight_data =
90 Rt::correct_layout(client, weight.clone().into_data(), dtypes.rhs_global, op)?;
91
92 let mut input = input.clone();
93 let mut weight = weight.clone();
94
95 *input.data_mut() = input_data;
96 *weight.data_mut() = weight_data;
97
98 let address_type = input
99 .required_address_type()
100 .max(weight.required_address_type())
101 .max(
102 bias.clone()
103 .map(|bias| bias.required_address_type())
104 .unwrap_or_default(),
105 )
106 .max(out.required_address_type(dtypes.acc_global.size()));
107
108 let problem = ConvolutionProblem {
109 m: n * out_shape.iter().product::<usize>(),
110 n: out_c,
111 k: c * kernel_shape.iter().product::<usize>(),
112 lhs_strides: input.data().strides.clone(),
113 rhs_strides: weight.data().strides.clone(),
114 lhs_layout: MatrixLayout::RowMajor,
115 rhs_layout: MatrixLayout::ColMajor,
116 kernel_size: kernel_shape.iter().map(|it| *it as u32).collect(),
117 stride: stride.iter().map(|it| *it as u32).collect(),
118 padding: padding.iter().map(|it| *it as i32).collect(),
119 dilation: dilation.iter().map(|it| *it as u32).collect(),
120
121 batches: n,
122 in_shape: in_shape.into(),
123 out_shape: out_shape.into(),
124 channels: c,
125 out_channels: out_c,
126
127 padded_channels: c,
128 operation: op,
129
130 dimensionality,
131 global_dtypes: dtypes.as_global_elems(),
132 address_type,
133 };
134
135 launch_kernel::<Rt>(
136 client,
137 input,
138 weight,
139 bias,
140 out,
141 problem,
142 blueprint_strategy,
143 dtypes,
144 )
145}
146
147#[allow(clippy::result_large_err, clippy::too_many_arguments)]
148pub fn launch_kernel<Rt: Routine>(
149 client: &Client,
150 input: InputBinding,
151 weight: InputBinding,
152 bias: Option<InputBinding>,
153 out: TensorBinding,
154 problem: ConvolutionProblem,
155 blueprint_strategy: &BlueprintStrategy<Rt::MatmulRoutine>,
156 dtypes: MatmulElems,
157) -> Result<(), ConvSetupError>
158where
159 Rt::Args: ConcreteArgs<Rt::MatmulRoutine>,
160{
161 let mut vector_sizes = Rt::filter_vector_sizes(AvailableVectorSizes::from_type_sizes(
164 client,
165 input.data_elem_size(),
166 weight.data_elem_size(),
167 dtypes.acc_global.size(),
168 ))
169 .filter_lhs_with_tensor(
170 &input.data().strides,
171 &input.data().shape,
172 MatrixLayout::RowMajor,
173 )
174 .filter_rhs_with_tensor(
175 &weight.data().strides,
176 &weight.data().shape,
177 MatrixLayout::RowMajor,
178 )
179 .filter_out_with_tensor(&out.strides, &out.shape)
180 .pick_max()?;
181
182 if input.scale().is_some() {
185 vector_sizes.lhs = 1;
186 }
187 if weight.scale().is_some() {
188 vector_sizes.rhs = 1;
189 }
190
191 launch_kernel_concrete::<Rt::Args, Rt::MatmulRoutine>(
192 client,
193 input,
194 weight,
195 bias,
196 out,
197 problem,
198 vector_sizes,
199 blueprint_strategy,
200 &dtypes,
201 )
202}