1use ruda_kernel::dsl as kernel_dsl;
2use std::marker::PhantomData;
3
4use ruda_kernel::library::tensor::View;
5use ruda_kernel::library::tensor::launch::ViewArg;
6use ruda_kernel::library::tensor::layout::Coords1d;
7use ruda_kernel::library::tensor::layout::VirtualLayout;
8use ruda_kernel::library::tensor::layout::VirtualLayoutLaunch;
9use ruda_kernel::dsl::unexpanded;
10use ruda_kernel::dsl::prelude::*;
11use ruda_kernel::dsl::zspace::metadata::Metadata;
12use ruda_kernel::dsl::zspace::shape;
13use ruda_kernel::dsl::zspace::strides;
14use ruda_kernel::tiling::launch::tma::{remap_storage_for_tma, tma_meta_tiled, transpose_inner_for_tma};
15use ruda_kernel::tiling::{InputBinding, MatrixLayout, stage::SwizzleMode};
16
17use crate::kernel_ir::components::global::memory::{
18 BatchLayout, BatchLayoutLaunch, GlobalLayout, GlobalLayoutConfig, GlobalLayoutLaunch,
19 GlobalScaleLayout, NoopLayout, NoopLayoutLaunch, SimpleTmaGlobalLayout,
20 SimpleTmaGlobalLayoutLaunch,
21};
22use crate::kernel_ir::{
23 definition::{Blueprint as _, MatmulElems, MatmulProblem, MatmulVectorSizes},
24 routines::Routine,
25};
26
27define_scalar!(pub Lhs);
28define_scalar!(pub Rhs);
29define_scalar!(pub Acc);
30
31define_size!(pub LhsSize);
32define_size!(pub RhsSize);
33define_size!(pub AccSize);
34
35pub type InputArg<MA> =
37 <MA as MatmulArgs>::Input<Vector<Lhs, LhsSize>, Vector<Rhs, RhsSize>, Vector<Acc, AccSize>>;
38
39pub type OutputArg<MA> = <MA as MatmulArgs>::Output<Vector<Acc, AccSize>>;
41
42pub type ConfigArg<MA> = <MA as MatmulArgs>::Config;
44
45pub type InputRuntimeArg<MA, R> = <InputArg<MA> as LaunchArg>::RuntimeArg<R>;
47
48pub type ConfigRuntimeArg<MA, R> = <ConfigArg<MA> as LaunchArg>::RuntimeArg<R>;
50
51pub type OutputRuntimeArg<MA, R> = <OutputArg<MA> as LaunchArg>::RuntimeArg<R>;
53
54pub type BatchedCoords = (usize, u32, u32);
55
56pub trait ConcreteInputsFactory<A: Routine<()>>: LaunchArg {
59 #[allow(clippy::too_many_arguments)]
60 fn create<R: Runtime>(
61 lhs: InputBinding<R>,
62 rhs: InputBinding<R>,
63 blueprint: &A::Blueprint,
64 problem: &MatmulProblem,
65 vector_sizes: &MatmulVectorSizes,
66 dtypes: &MatmulElems,
67 ) -> Self::RuntimeArg<R>;
68}
69
70pub trait ConcreteOutputFactory<A: Routine<()>>: LaunchArg {
73 #[allow(clippy::too_many_arguments)]
74 fn create<R: Runtime>(
75 out: TensorBinding<R>,
76 blueprint: &A::Blueprint,
77 problem: &MatmulProblem,
78 vector_sizes: &MatmulVectorSizes,
79 dtypes: &MatmulElems,
80 ) -> Self::RuntimeArg<R>;
81}
82
83pub trait RuntimeConfig: LaunchArg + RudaType + Clone + Send + Sync {}
84impl<T: LaunchArg + RudaType + Clone + Send + Sync> RuntimeConfig for T {}
85
86#[ruda]
87pub trait MatmulArgs: Send + Sync + 'static + Clone {
89 type Input<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>: LaunchArg + RudaType;
91
92 type Output<EO: RudaPrimitive>: LaunchArg + RudaType;
94
95 type Config: RuntimeConfig;
97
98 type State<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>: RudaType;
101
102 fn init_state<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
104 input: &Self::Input<Lhs, Rhs, EO>,
105 output: &mut Self::Output<EO>,
106 config: Self::Config,
107 #[comptime] lhs_layout_config: GlobalLayoutConfig,
108 #[comptime] rhs_layout_config: GlobalLayoutConfig,
109 #[comptime] out_layout_config: GlobalLayoutConfig,
110 ) -> Self::State<Lhs, Rhs, EO>;
111
112 fn view_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
113 _state: &Self::State<Lhs, Rhs, EO>,
114 ) -> View<Lhs, BatchedCoords> {
115 unexpanded!()
116 }
117 fn batch_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
118 _state: &Self::State<Lhs, Rhs, EO>,
119 _batch: usize,
120 ) -> usize {
121 unexpanded!()
122 }
123 fn view_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
124 _state: &Self::State<Lhs, Rhs, EO>,
125 ) -> View<Rhs, BatchedCoords> {
126 unexpanded!()
127 }
128 fn batch_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
129 _state: &Self::State<Lhs, Rhs, EO>,
130 _batch: usize,
131 ) -> usize {
132 unexpanded!()
133 }
134 fn view_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
135 _state: &Self::State<Lhs, Rhs, EO>,
136 ) -> ComptimeOption<View<EO, BatchedCoords>> {
137 unexpanded!()
138 }
139 fn batch_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
140 _state: &Self::State<Lhs, Rhs, EO>,
141 _batch: usize,
142 ) -> usize {
143 unexpanded!()
144 }
145 fn view_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
146 _state: &mut Self::State<Lhs, Rhs, EO>,
147 ) -> View<EO, BatchedCoords, ReadWrite> {
148 unexpanded!()
149 }
150 fn batch_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
151 _state: &Self::State<Lhs, Rhs, EO>,
152 _batch: usize,
153 ) -> usize {
154 unexpanded!()
155 }
156
157 fn runtime_config<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
158 _state: &Self::State<Lhs, Rhs, EO>,
159 ) -> Self::Config {
160 unexpanded!()
161 }
162}
163
164#[derive(Clone, Copy)]
165pub enum TensorInputIdent {
167 Lhs,
168 Rhs,
169}
170
171#[derive(Clone)]
172pub struct TensorArgs<Config: RuntimeConfig = ()> {
176 _config: PhantomData<Config>,
177}
178
179#[derive(RudaLaunch, RudaType, Clone, Copy)]
180pub struct TensorInputs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, Acc: RudaPrimitive> {
182 lhs_batch: VirtualLayout<Coords1d, Coords1d>,
184 lhs: View<Lhs, BatchedCoords>,
185 rhs_batch: VirtualLayout<Coords1d, Coords1d>,
187 rhs: View<Rhs, BatchedCoords>,
188 acc_batch: ComptimeOption<VirtualLayout<Coords1d, Coords1d>>,
190 acc: ComptimeOption<View<Acc, BatchedCoords>>,
191}
192
193impl<Lhs: RudaPrimitive, Rhs: RudaPrimitive, Acc: RudaPrimitive, A: Routine<()>>
194 ConcreteInputsFactory<A> for TensorInputs<Lhs, Rhs, Acc>
195{
196 fn create<R: Runtime>(
197 lhs: InputBinding<R>,
198 rhs: InputBinding<R>,
199 blueprint: &A::Blueprint,
200 problem: &MatmulProblem,
201 vector_sizes: &MatmulVectorSizes,
202 _dtypes: &MatmulElems,
203 ) -> Self::RuntimeArg<R> {
204 let view = |handle: InputBinding<R>, config: GlobalLayoutConfig, vector_size| match handle {
205 InputBinding::Normal(handle, _dtype) => {
206 let layout = GlobalLayoutLaunch::from_handle(&handle, vector_size, config);
207 ViewArg::new_tensor::<GlobalLayout>(handle.into_tensor_arg(), layout)
208 }
209 InputBinding::Quantized {
210 data,
211 scale,
212 shape,
213 scheme,
214 ..
215 } => {
216 let (data_layout, scales_layout) = GlobalLayoutLaunch::from_quantized_handle(
217 &data,
218 &scale,
219 &shape,
220 problem,
221 scheme,
222 vector_size,
223 config,
224 );
225 let data_view =
226 ViewArg::new_tensor::<GlobalLayout>(data.into_tensor_arg(), data_layout);
227 let scales_view = ViewArg::new_tensor::<GlobalScaleLayout>(
228 scale.into_tensor_arg(),
229 scales_layout,
230 );
231 ViewArg::new_quantized(data_view, scales_view, scheme)
232 }
233 };
234 let batch_layout = |handle: &InputBinding<R>| match handle {
235 InputBinding::Normal(handle, _dtype) => {
236 let layout = BatchLayoutLaunch::from_handle(handle, problem);
237 VirtualLayoutLaunch::new::<BatchLayout>(layout)
238 }
239 InputBinding::Quantized { .. } => {
240 VirtualLayoutLaunch::new::<NoopLayout>(NoopLayoutLaunch::new())
241 }
242 };
243
244 TensorInputsLaunch::new(
245 batch_layout(&lhs),
246 view(lhs, blueprint.lhs_global_layout_config(), vector_sizes.lhs),
247 batch_layout(&rhs),
248 view(rhs, blueprint.rhs_global_layout_config(), vector_sizes.rhs),
249 ComptimeOptionArgs::None,
250 ComptimeOptionArgs::None,
251 )
252 }
253}
254
255#[derive(RudaType, RudaLaunch, Clone, Copy)]
256pub struct TensorOutput<EG: RudaPrimitive> {
257 view: View<EG, BatchedCoords, ReadWrite>,
258 batch: VirtualLayout<Coords1d, Coords1d>,
259}
260
261impl<EG: RudaPrimitive, A: Routine<()>> ConcreteOutputFactory<A> for TensorOutput<EG> {
262 fn create<R: Runtime>(
263 out: TensorBinding<R>,
264 blueprint: &A::Blueprint,
265 problem: &MatmulProblem,
266 vector_sizes: &MatmulVectorSizes,
267 _dtypes: &MatmulElems,
268 ) -> Self::RuntimeArg<R> {
269 let layout = GlobalLayoutLaunch::from_handle(
270 &out,
271 vector_sizes.out,
272 blueprint.out_global_layout_config(),
273 );
274 let batch = BatchLayoutLaunch::from_handle(&out, problem);
275 let view = ViewArg::new_tensor::<GlobalLayout>(out.into_tensor_arg(), layout);
276 TensorOutputLaunch::new(view, VirtualLayoutLaunch::new::<BatchLayout>(batch))
277 }
278}
279
280#[ruda]
281impl<Config: RuntimeConfig> MatmulArgs for TensorArgs<Config> {
282 type Output<EO: RudaPrimitive> = TensorOutput<EO>;
283 type Input<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive> =
284 TensorInputs<Lhs, Rhs, EO>;
285 type Config = Config;
286 type State<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive> =
287 (TensorInputs<Lhs, Rhs, EO>, TensorOutput<EO>, Config);
288
289 fn init_state<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
290 input: &Self::Input<Lhs, Rhs, EO>,
291 output: &mut Self::Output<EO>,
292 config: Self::Config,
293 #[comptime] _lhs_layout_config: GlobalLayoutConfig,
294 #[comptime] _rhs_layout_config: GlobalLayoutConfig,
295 #[comptime] _out_layout_config: GlobalLayoutConfig,
296 ) -> Self::State<Lhs, Rhs, EO> {
297 (*input, *output, config)
298 }
299
300 fn view_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
301 state: &Self::State<Lhs, Rhs, EO>,
302 ) -> View<Lhs, BatchedCoords> {
303 state.0.lhs
304 }
305
306 fn batch_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
307 state: &Self::State<Lhs, Rhs, EO>,
308 batch: usize,
309 ) -> usize {
310 state.0.lhs_batch.to_source_pos(batch)
311 }
312
313 fn view_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
314 state: &Self::State<Lhs, Rhs, EO>,
315 ) -> View<Rhs, BatchedCoords> {
316 state.0.rhs
317 }
318
319 fn batch_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
320 state: &Self::State<Lhs, Rhs, EO>,
321 batch: usize,
322 ) -> usize {
323 state.0.rhs_batch.to_source_pos(batch)
324 }
325
326 fn view_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
327 state: &Self::State<Lhs, Rhs, EO>,
328 ) -> ComptimeOption<View<EO, BatchedCoords>> {
329 state.0.acc
330 }
331
332 fn batch_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
333 state: &Self::State<Lhs, Rhs, EO>,
334 batch: usize,
335 ) -> usize {
336 #[comptime]
337 #[comptime]
338 match state.0.acc_batch {
339 ComptimeOption::Some(layout) => layout.to_source_pos(batch),
340 ComptimeOption::None => batch,
341 }
342 }
343
344 fn view_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
345 state: &mut Self::State<Lhs, Rhs, EO>,
346 ) -> View<EO, BatchedCoords, ReadWrite> {
347 state.1.view
348 }
349
350 fn batch_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
351 state: &Self::State<Lhs, Rhs, EO>,
352 batch: usize,
353 ) -> usize {
354 state.1.batch.to_source_pos(batch)
355 }
356
357 fn runtime_config<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
358 state: &Self::State<Lhs, Rhs, EO>,
359 ) -> Self::Config {
360 state.2.clone()
361 }
362}
363
364#[derive(Clone)]
365pub struct TensorMapArgs<Config: RuntimeConfig = ()> {
369 _config: PhantomData<Config>,
370}
371
372#[derive(RudaLaunch, RudaType, Clone, Copy)]
373pub struct TensorMapInputs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive> {
375 pub lhs: View<Lhs, BatchedCoords>,
377 pub rhs: View<Rhs, BatchedCoords>,
379 pub acc: ComptimeOption<View<EO, BatchedCoords>>,
381 pub acc_batch: ComptimeOption<VirtualLayout<Coords1d, Coords1d>>,
383}
384
385impl<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive, A: Routine<()>>
386 ConcreteInputsFactory<A> for TensorMapInputs<Lhs, Rhs, EO>
387{
388 fn create<R: Runtime>(
389 lhs_handle: InputBinding<R>,
390 rhs_handle: InputBinding<R>,
391 blueprint: &A::Blueprint,
392 problem: &MatmulProblem,
393 _vector_sizes: &MatmulVectorSizes,
394 dtypes: &MatmulElems,
395 ) -> Self::RuntimeArg<R> {
396 let lhs = lhs_handle.into_data();
397 let rhs = rhs_handle.into_data();
398
399 let tiling_scheme = blueprint.tiling_scheme();
400 let stage_m = tiling_scheme.elements_per_stage_along_m();
401 let stage_n = tiling_scheme.elements_per_stage_along_n();
402 let stage_k = tiling_scheme.elements_per_stage_along_k();
403
404 let stage_size_lhs = match blueprint.swizzle_modes().lhs {
408 SwizzleMode::None => match problem.lhs_layout {
409 MatrixLayout::RowMajor => {
410 shape![1, stage_m as usize, tiling_scheme.tile_size.k as usize]
411 }
412 MatrixLayout::ColMajor => {
413 shape![1, stage_k as usize, tiling_scheme.tile_size.m as usize]
414 }
415 },
416 _ => match problem.lhs_layout {
417 MatrixLayout::RowMajor => {
418 shape![1, stage_m as usize, stage_k as usize]
419 }
420 MatrixLayout::ColMajor => {
421 shape![1, stage_k as usize, stage_m as usize]
422 }
423 },
424 };
425 let stage_size_rhs = match blueprint.swizzle_modes().rhs {
426 SwizzleMode::None => match problem.rhs_layout {
427 MatrixLayout::RowMajor => {
428 shape![1, stage_k as usize, tiling_scheme.tile_size.n as usize]
429 }
430 MatrixLayout::ColMajor => {
431 shape![1, stage_n as usize, tiling_scheme.tile_size.k as usize]
432 }
433 },
434 _ => match problem.rhs_layout {
435 MatrixLayout::RowMajor => {
436 shape![1, stage_k as usize, stage_n as usize]
437 }
438 MatrixLayout::ColMajor => {
439 shape![1, stage_n as usize, stage_k as usize]
440 }
441 },
442 };
443
444 let lhs_rank = lhs.shape.len();
445 let mut lhs_shape = shape![
446 problem.lhs_batches.iter().product(),
447 lhs.shape[lhs_rank - 2],
448 lhs.shape[lhs_rank - 1],
449 ];
450 let mut lhs_strides = if lhs_rank > 2 {
451 lhs.strides[lhs_rank - 3..].into()
452 } else {
453 strides![lhs.strides[0], lhs.strides[1]]
454 };
455
456 let rhs_rank = rhs.shape.len();
457 let mut rhs_shape = shape![
458 problem.rhs_batches.iter().product(),
459 rhs.shape[rhs_rank - 2],
460 rhs.shape[rhs_rank - 1],
461 ];
462 let mut rhs_strides = if rhs_rank > 2 {
463 rhs.strides[rhs_rank - 3..].into()
464 } else {
465 strides![rhs.strides[0], rhs.strides[1]]
466 };
467
468 let lhs_transposed =
469 transpose_inner_for_tma(&mut lhs_shape, &mut lhs_strides, problem.lhs_layout);
470 let rhs_transposed =
471 transpose_inner_for_tma(&mut rhs_shape, &mut rhs_strides, problem.rhs_layout);
472
473 if lhs_strides.len() == 2 {
475 let stride = lhs_strides[0];
476 lhs_strides.insert(0, stride);
477 }
478 if rhs_strides.len() == 2 {
479 let stride = rhs_strides[0];
480 rhs_strides.insert(0, stride);
481 }
482
483 let meta_lhs = tma_meta_tiled(
484 Metadata::new(lhs_shape.clone(), lhs_strides),
485 stage_size_lhs,
486 remap_storage_for_tma(dtypes.lhs_stage),
487 blueprint.swizzle_modes().lhs.into(),
488 );
489
490 let meta_rhs = tma_meta_tiled(
491 Metadata::new(rhs_shape.clone(), rhs_strides),
492 stage_size_rhs,
493 remap_storage_for_tma(dtypes.rhs_stage),
494 blueprint.swizzle_modes().rhs.into(),
495 );
496
497 let lhs = TensorMapArg {
498 tensor: lhs.into_tensor_arg(),
499 metadata: meta_lhs,
500 _kind: PhantomData,
501 };
502 let rhs = TensorMapArg {
503 tensor: rhs.into_tensor_arg(),
504 metadata: meta_rhs,
505 _kind: PhantomData,
506 };
507
508 let view = |buffer, shape: &[usize], transposed| {
509 let batches = shape[0];
510 let (rows, cols) = match transposed {
511 true => (shape[2] as u32, shape[1] as u32),
512 false => (shape[1] as u32, shape[2] as u32),
513 };
514 let shape = (batches, rows, cols);
515 let layout = SimpleTmaGlobalLayoutLaunch::new(transposed, shape);
516 ViewArg::new_tensor_map_tiled::<SimpleTmaGlobalLayout>(buffer, layout)
517 };
518
519 TensorMapInputsLaunch::new(
520 view(lhs, &lhs_shape, lhs_transposed),
521 view(rhs, &rhs_shape, rhs_transposed),
522 ComptimeOptionArgs::None,
523 ComptimeOptionArgs::None,
524 )
525 }
526}
527
528#[ruda]
529impl<Config: RuntimeConfig> MatmulArgs for TensorMapArgs<Config> {
530 type Input<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive> =
531 TensorMapInputs<Lhs, Rhs, EO>;
532 type Output<EO: RudaPrimitive> = TensorOutput<EO>;
533 type Config = Config;
534 type State<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive> =
535 (TensorMapInputs<Lhs, Rhs, EO>, TensorOutput<EO>, Config);
536
537 fn init_state<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
538 input: &Self::Input<Lhs, Rhs, EO>,
539 output: &mut Self::Output<EO>,
540 config: Self::Config,
541 #[comptime] _lhs_layout_config: GlobalLayoutConfig,
542 #[comptime] _rhs_layout_config: GlobalLayoutConfig,
543 #[comptime] _out_layout_config: GlobalLayoutConfig,
544 ) -> Self::State<Lhs, Rhs, EO> {
545 (*input, *output, config)
546 }
547
548 fn view_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
549 state: &Self::State<Lhs, Rhs, EO>,
550 ) -> View<Lhs, BatchedCoords> {
551 state.0.lhs
552 }
553
554 fn batch_lhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
555 _state: &Self::State<Lhs, Rhs, EO>,
556 batch: usize,
557 ) -> usize {
558 batch
559 }
560
561 fn view_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
562 state: &Self::State<Lhs, Rhs, EO>,
563 ) -> View<Rhs, BatchedCoords> {
564 state.0.rhs
565 }
566
567 fn batch_rhs<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
568 _state: &Self::State<Lhs, Rhs, EO>,
569 batch: usize,
570 ) -> usize {
571 batch
572 }
573
574 fn view_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
575 state: &Self::State<Lhs, Rhs, EO>,
576 ) -> ComptimeOption<View<EO, BatchedCoords>> {
577 state.0.acc
578 }
579
580 fn batch_acc<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
581 state: &Self::State<Lhs, Rhs, EO>,
582 batch: usize,
583 ) -> usize {
584 #[comptime]
585 #[comptime]
586 match state.0.acc_batch {
587 ComptimeOption::Some(layout) => layout.to_source_pos(batch),
588 ComptimeOption::None => batch,
589 }
590 }
591
592 fn view_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
593 state: &mut Self::State<Lhs, Rhs, EO>,
594 ) -> View<EO, BatchedCoords, ReadWrite> {
595 state.1.view
596 }
597
598 fn batch_out<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
599 state: &Self::State<Lhs, Rhs, EO>,
600 batch: usize,
601 ) -> usize {
602 state.1.batch.to_source_pos(batch)
603 }
604
605 fn runtime_config<Lhs: RudaPrimitive, Rhs: RudaPrimitive, EO: RudaPrimitive>(
606 state: &Self::State<Lhs, Rhs, EO>,
607 ) -> Self::Config {
608 state.2.clone()
609 }
610}