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