1#[cfg(feature = "cuda")]
25use std::any::Any;
26
27#[cfg(feature = "cuda")]
28mod cubecl;
29#[cfg(any(feature = "cuda", feature = "webgpu"))]
30mod event_domain_admission;
31#[cfg(any(feature = "cuda", feature = "webgpu"))]
32mod event_retirement;
33#[cfg(any(feature = "cuda", feature = "webgpu"))]
34mod kernels;
35#[cfg(any(feature = "cuda", feature = "webgpu"))]
36mod native_permutation;
37#[cfg(feature = "webgpu")]
38pub mod webgpu;
39
40#[cfg(feature = "cuda")]
42pub mod cuda {
43 pub use super::cubecl::{
44 cuda_capabilities, cuda_devices, cuda_runtime_engine_registration,
45 cuda_runtime_hardware_class, download_tensor, gpu_available, upload_tensor,
46 with_cuda_exec_session, CudaBackend, CudaComputeCapability, CudaDeviceError, CudaDeviceId,
47 CudaDeviceInfo, CudaDeviceUuid, CudaExecSession, CudaExtensionCache,
48 CudaExtensionCacheGuard, CudaRuntime, CudaRuntimeIdentity, GpuExtensionCapability,
49 };
50
51 pub mod cubecl {
58 pub use super::super::cubecl::session_cubecl::Session;
59 pub use ::cubecl::prelude::{ArrayArg, CubeCount, CubeDim, TensorBinding};
61 }
62
63 pub mod raw {
65 pub use super::super::cubecl::raw::{
66 CudaResourceGuard, DeviceBytes, Function, KernelArg, LaunchConfig, Module,
67 NvrtcOptions, Session, StreamRef, TensorMut, TensorRef,
68 };
69 }
70}
71
72#[cfg(feature = "webgpu")]
74pub mod apple {
75 pub use super::webgpu::{AppleContext, AppleTransferStats};
76}
77
78#[cfg(any(feature = "cuda", feature = "webgpu"))]
79use tenferro_tensor::*;
80
81#[cfg(feature = "cuda")]
82pub(crate) mod backend {
83 pub use tenferro_tensor::backend::*;
84}
85
86#[cfg(feature = "cuda")]
87pub(crate) mod config {
88 pub use tenferro_tensor::config::*;
89}
90
91#[cfg(feature = "cuda")]
92pub(crate) mod types {
93 pub(crate) use crate::CubeclBuffer;
94 pub use tenferro_tensor::types::*;
95}
96
97#[cfg(feature = "cuda")]
100pub(crate) struct CubeclBuffer {
101 handle: cubecl_runtime::server::Handle,
102 byte_len: usize,
103 device_ordinal: usize,
104 allocation_domain: AllocationDomainId,
105 allocation_id: AllocationId,
106}
107
108#[cfg(feature = "cuda")]
109static NEXT_CUDA_ALLOCATION_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1);
110
111#[cfg(feature = "cuda")]
112impl std::fmt::Debug for CubeclBuffer {
113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114 f.debug_struct("CubeclBuffer")
115 .field("byte_len", &self.byte_len)
116 .field("device_ordinal", &self.device_ordinal)
117 .field("allocation_domain", &self.allocation_domain)
118 .field("allocation_id", &self.allocation_id)
119 .finish()
120 }
121}
122
123#[cfg(feature = "cuda")]
124impl CubeclBuffer {
125 pub(crate) fn new(
126 handle: cubecl_runtime::server::Handle,
127 byte_len: usize,
128 device_ordinal: usize,
129 allocation_domain: AllocationDomainId,
130 ) -> Self {
131 Self {
132 handle,
133 byte_len,
134 device_ordinal,
135 allocation_domain,
136 allocation_id: AllocationId::from_backend_id(
137 NEXT_CUDA_ALLOCATION_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
138 ),
139 }
140 }
141
142 pub(crate) fn handle(&self) -> &cubecl_runtime::server::Handle {
143 &self.handle
144 }
145
146 pub(crate) fn element_len<T: 'static>(&self) -> usize {
147 let element_size = std::mem::size_of::<T>();
148 debug_assert!(element_size != 0 && self.byte_len.is_multiple_of(element_size));
149 self.byte_len / element_size
150 }
151
152 pub(crate) fn device_ordinal(&self) -> usize {
153 self.device_ordinal
154 }
155
156 pub(crate) fn allocation_domain(&self) -> AllocationDomainId {
157 self.allocation_domain
158 }
159}
160
161#[cfg(feature = "cuda")]
162impl<T: Send + Sync + 'static> BackendStorage<T> for CubeclBuffer {
163 fn backend_family(&self) -> &'static str {
164 "cubecl"
165 }
166
167 fn len(&self) -> usize {
168 self.element_len::<T>()
169 }
170
171 fn allocation_domain(&self) -> Option<AllocationDomainId> {
172 Some(self.allocation_domain)
173 }
174
175 fn allocation_id(&self) -> Option<AllocationId> {
176 Some(self.allocation_id)
177 }
178
179 fn prepare_device_access(
180 &self,
181 request: DeviceAccessRequest<'_>,
182 ) -> std::result::Result<Box<dyn PreparedDeviceAccess>, DeviceAccessError> {
183 Ok(Box::new(crate::cubecl::dispatch::prepare_cubecl_access(
184 self, request,
185 )?))
186 }
187
188 fn as_any(&self) -> &dyn Any {
189 self
190 }
191}