cubecl_core/frontend/container/slice/
launch.rs1use alloc::boxed::Box;
2use core::marker::PhantomData;
3
4use crate::{frontend::container::slice, prelude::*};
5use cubecl_ir::Id;
6use cubecl_runtime::runtime::Runtime;
7use serde::{Deserialize, Serialize};
8
9#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
10pub struct BufferCompilationArg {
11 pub inplace: Option<Id>,
12}
13
14pub struct BufferBinding<R: Runtime> {
16 pub handle: cubecl_runtime::server::Binding,
17 pub(crate) length: [usize; 1],
18 runtime: PhantomData<R>,
19}
20
21pub enum BufferArg<R: Runtime> {
22 Handle {
24 handle: BufferBinding<R>,
26 },
27 Alias {
29 input_pos: usize,
31 length: [usize; 1],
33 },
34}
35
36impl<R: Runtime> BufferArg<R> {
37 pub unsafe fn from_raw_parts(handle: cubecl_runtime::server::Handle, length: usize) -> Self {
43 unsafe {
44 BufferArg::Handle {
45 handle: BufferBinding::from_raw_parts(handle, length),
46 }
47 }
48 }
49 pub unsafe fn from_raw_parts_binding(
55 binding: cubecl_runtime::server::Binding,
56 length: usize,
57 ) -> Self {
58 unsafe {
59 BufferArg::Handle {
60 handle: BufferBinding::from_raw_parts_binding(binding, length),
61 }
62 }
63 }
64
65 pub fn alias(input_pos: usize, length: usize) -> Self {
66 Self::Alias {
67 input_pos,
68 length: [length],
69 }
70 }
71
72 pub fn size(&self) -> usize {
73 match self {
74 BufferArg::Handle { handle } => handle.length[0],
75 BufferArg::Alias { length, .. } => length[0],
76 }
77 }
78
79 pub fn shape(&self) -> &[usize] {
80 match self {
81 BufferArg::Handle { handle } => &handle.length,
82 BufferArg::Alias { length, .. } => length,
83 }
84 }
85}
86
87impl<R: Runtime> BufferBinding<R> {
88 pub unsafe fn from_raw_parts(handle: cubecl_runtime::server::Handle, length: usize) -> Self {
94 unsafe { Self::from_raw_parts_binding(handle.binding(), length) }
95 }
96
97 pub unsafe fn from_raw_parts_binding(
103 handle: cubecl_runtime::server::Binding,
104 length: usize,
105 ) -> Self {
106 Self {
107 handle,
108 length: [length],
109 runtime: PhantomData,
110 }
111 }
112
113 pub fn into_tensor(self) -> TensorBinding<R> {
115 let shape = self.length.into();
116
117 TensorBinding {
118 handle: self.handle,
119 strides: [1].into(),
120 shape,
121 runtime: PhantomData,
122 }
123 }
124}
125
126impl<C: CubePrimitive> LaunchArg for Box<[C]> {
127 type RuntimeArg<R: Runtime> = BufferArg<R>;
128 type CompilationArg = BufferCompilationArg;
129
130 fn register<R: Runtime>(
131 arg: Self::RuntimeArg<R>,
132 launcher: &mut KernelLauncher<R>,
133 ) -> Self::CompilationArg {
134 <[C]>::register(arg, launcher)
135 }
136
137 fn expand(arg: &Self::CompilationArg, builder: &mut KernelBuilder) -> NativeExpand<Box<[C]>> {
138 <[C]>::expand(arg, builder).expand.into()
139 }
140}
141
142impl<C: CubePrimitive> LaunchArg for [C] {
143 type RuntimeArg<R: Runtime> = BufferArg<R>;
144 type CompilationArg = BufferCompilationArg;
145
146 fn register<R: Runtime>(
147 arg: Self::RuntimeArg<R>,
148 launcher: &mut KernelLauncher<R>,
149 ) -> Self::CompilationArg {
150 let ty = launcher.with_scope(|scope| C::__expand_as_type(scope));
151 let inplace = match &arg {
152 BufferArg::Handle { .. } => None,
153 BufferArg::Alias { input_pos, .. } => Some(*input_pos as Id),
154 };
155 launcher.register_buffer(arg, ty);
156
157 BufferCompilationArg { inplace }
158 }
159
160 fn expand(arg: &Self::CompilationArg, builder: &mut KernelBuilder) -> NativeExpand<[C]> {
161 let buffer = match arg.inplace {
162 Some(id) => builder.inplace(id),
163 None => builder.buffer(C::__expand_as_type(&builder.scope)),
164 };
165 let scope = &builder.scope;
166 let len = expand_buffer_length_native(scope, buffer);
167 let slice_var =
168 slice::from_raw_parts::<C>(scope, buffer, 0usize.into_expand(scope), len.into());
169 slice_var.expand.into()
170 }
171}