#[cfg(feature = "cuda")]
use std::any::Any;
#[cfg(feature = "cuda")]
mod cubecl;
#[cfg(any(feature = "cuda", feature = "webgpu"))]
mod event_domain_admission;
#[cfg(any(feature = "cuda", feature = "webgpu"))]
mod event_retirement;
#[cfg(any(feature = "cuda", feature = "webgpu"))]
mod kernels;
#[cfg(any(feature = "cuda", feature = "webgpu"))]
mod native_permutation;
#[cfg(feature = "webgpu")]
pub mod webgpu;
#[cfg(feature = "cuda")]
pub mod cuda {
pub use super::cubecl::{
cuda_capabilities, cuda_devices, cuda_runtime_engine_registration,
cuda_runtime_hardware_class, download_tensor, gpu_available, upload_tensor,
with_cuda_exec_session, CudaBackend, CudaDeviceError, CudaDeviceId, CudaDeviceInfo,
CudaExecSession, CudaRuntime, CudaRuntimeIdentity,
};
#[doc(hidden)]
pub mod interop {
pub use super::super::cubecl::interop::*;
pub use super::super::cubecl::{CudaExtensionCache, CudaExtensionCacheGuard};
}
}
#[cfg(feature = "webgpu")]
pub mod apple {
pub use super::webgpu::{AppleContext, AppleTransferStats};
}
#[cfg(any(feature = "cuda", feature = "webgpu"))]
use tenferro_tensor::*;
#[cfg(feature = "cuda")]
pub(crate) mod backend {
pub use tenferro_tensor::backend::*;
}
#[cfg(feature = "cuda")]
pub(crate) mod config {
pub use tenferro_tensor::config::*;
}
#[cfg(feature = "cuda")]
pub(crate) mod types {
pub(crate) use crate::CubeclBuffer;
pub use tenferro_tensor::types::*;
}
#[cfg(feature = "cuda")]
pub(crate) struct CubeclBuffer {
handle: cubecl_runtime::server::Handle,
byte_len: usize,
device_ordinal: usize,
allocation_domain: AllocationDomainId,
allocation_id: AllocationId,
}
#[cfg(feature = "cuda")]
static NEXT_CUDA_ALLOCATION_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1);
#[cfg(feature = "cuda")]
impl std::fmt::Debug for CubeclBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CubeclBuffer")
.field("byte_len", &self.byte_len)
.field("device_ordinal", &self.device_ordinal)
.field("allocation_domain", &self.allocation_domain)
.field("allocation_id", &self.allocation_id)
.finish()
}
}
#[cfg(feature = "cuda")]
impl CubeclBuffer {
pub(crate) fn new(
handle: cubecl_runtime::server::Handle,
byte_len: usize,
device_ordinal: usize,
allocation_domain: AllocationDomainId,
) -> Self {
Self {
handle,
byte_len,
device_ordinal,
allocation_domain,
allocation_id: AllocationId::from_backend_id(
NEXT_CUDA_ALLOCATION_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
),
}
}
pub(crate) fn handle(&self) -> &cubecl_runtime::server::Handle {
&self.handle
}
pub(crate) fn element_len<T: 'static>(&self) -> usize {
let element_size = std::mem::size_of::<T>();
debug_assert!(element_size != 0 && self.byte_len.is_multiple_of(element_size));
self.byte_len / element_size
}
pub(crate) fn device_ordinal(&self) -> usize {
self.device_ordinal
}
pub(crate) fn allocation_domain(&self) -> AllocationDomainId {
self.allocation_domain
}
}
#[cfg(feature = "cuda")]
impl<T: Send + Sync + 'static> BackendStorage<T> for CubeclBuffer {
fn backend_family(&self) -> &'static str {
"cubecl"
}
fn len(&self) -> usize {
self.element_len::<T>()
}
fn allocation_domain(&self) -> Option<AllocationDomainId> {
Some(self.allocation_domain)
}
fn allocation_id(&self) -> Option<AllocationId> {
Some(self.allocation_id)
}
fn prepare_device_access(
&self,
request: DeviceAccessRequest<'_>,
) -> std::result::Result<Box<dyn PreparedDeviceAccess>, DeviceAccessError> {
Ok(Box::new(crate::cubecl::dispatch::prepare_cubecl_access(
self, request,
)?))
}
fn as_any(&self) -> &dyn Any {
self
}
}