#[non_exhaustive]pub enum CubeDevice {
Cuda(CudaDevice),
Hip(AmdDevice),
Metal(MetalDevice),
Wgpu(WgpuDevice),
Cpu(CpuDevice),
}Expand description
The device a cube tensor lives on.
One type across every runtime: which runtime a tensor runs on is what its device says, not what its type is. A device of any runtime.
A value names both the runtime and the device on it. A value can name a runtime the build does not link — the enum is the same in every build — and it is reaching for a client that then fails.
use cubecl::Device;
let client = Device::default().client();
println!("running on {}", client.name());Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Cuda(CudaDevice)
A device of the CUDA runtime.
Hip(AmdDevice)
A device of the HIP runtime.
Metal(MetalDevice)
A device of the native Metal runtime.
Wgpu(WgpuDevice)
A device of the wgpu runtime, on its default compiler.
Cpu(CpuDevice)
The device of the CPU runtime.
Implementations§
Source§impl Device
Naming one device rather than taking Device::default.
impl Device
Naming one device rather than taking Device::default.
Each asks the runtime whether the machine really has what was named, so a
device that would only fail at the client call is an error here instead.
They are in every build: a runtime this one left out is
DeviceUnavailable::NotLinked, not a function that went missing.
use cubecl::Device;
// The second GPU if there is one, otherwise whatever this machine has.
let device = Device::cuda(1).or_else(|_| Device::cpu())?;
let client = device.client();Sourcepub fn cpu() -> Result<Device, DeviceUnavailable>
pub fn cpu() -> Result<Device, DeviceUnavailable>
The CPU device.
Sourcepub fn cuda(index: usize) -> Result<Device, DeviceUnavailable>
pub fn cuda(index: usize) -> Result<Device, DeviceUnavailable>
The CUDA device at index, counting the GPUs CUDA reports.
Sourcepub fn rocm(index: usize) -> Result<Device, DeviceUnavailable>
pub fn rocm(index: usize) -> Result<Device, DeviceUnavailable>
The ROCm device at index, counting the GPUs HIP reports.
Sourcepub fn metal(kind: MetalDevice) -> Result<Device, DeviceUnavailable>
pub fn metal(kind: MetalDevice) -> Result<Device, DeviceUnavailable>
The native Metal device kind names.
The Metal runtime proper. Reaching Metal through wgpu’s MSL backend is
Device::wgpu instead, and hands back a wgpu device.
Sourcepub fn wgpu(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn wgpu(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The device kind names, on whichever graphics API this machine offers.
The portable one: which API it comes up on — and so which shader
compiler it is fed — is the runtime’s to settle, best first, from the
enabled features and what the machine has. Naming the API instead is
vulkan and its siblings.
Sourcepub fn vulkan(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn vulkan(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The Vulkan device kind names — and so SPIR-V, where the build and
the adapter allow it.
Naming a graphics API is a promise the machine has to keep: this fails where the device is not reachable on Vulkan, rather than quietly coming up on something else. The same device on two APIs is two devices, each with an id and a client of its own.
use cubecl::{Device, device::WgpuDeviceKind};
let client = Device::vulkan(WgpuDeviceKind::default())?.client();Sourcepub fn dx12(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn dx12(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The DirectX 12 device kind names. See vulkan for
what naming an API promises.
Sourcepub fn gl(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn gl(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The OpenGL device kind names. See vulkan for what
naming an API promises.
Sourcepub fn webgpu(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn webgpu(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The WebGPU device kind names — the browser’s own. See
vulkan for what naming an API promises.
Sourcepub fn metal_msl(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
pub fn metal_msl(kind: WgpuDeviceKind) -> Result<Device, DeviceUnavailable>
The device kind names on Metal’s own API, reached through wgpu — and
so MSL, where the build allows it.
Not the native Metal runtime, which is Device::metal and a
different device altogether.
Sourcepub fn on(self, backend: WgpuBackend) -> Result<Device, DeviceUnavailable>
pub fn on(self, backend: WgpuBackend) -> Result<Device, DeviceUnavailable>
This device on backend, where the machine has it there.
For the caller holding a device already and wanting it on a particular API. Only the API named is asked: where the device came up by default says nothing about whether this one has it.
Sourcepub fn client(&self) -> Client
pub fn client(&self) -> Client
The compute client of this device, initialized on first use.
§Panics
Where this build does not link the device’s runtime.
Sourcepub fn can_read_tensor(&self, shape: &Shape, strides: &Strides) -> bool
pub fn can_read_tensor(&self, shape: &Shape, strides: &Strides) -> bool
Whether a tensor with shape and strides can be read as it lies, or
has to be made contiguous first. A property of the runtime, which is why
it is asked of the device rather than of the client.
§Panics
Where this build does not link the device’s runtime.
Sourcepub fn enumerate(device_id: DeviceId) -> Vec<DeviceId>
pub fn enumerate(device_id: DeviceId) -> Vec<DeviceId>
The ids of every device sharing device_id’s runtime and device type —
and for a wgpu device, its graphics API, the same adapter on another
being another device.
Takes and returns ids in Device’s own encoding, so a caller holding
one id can ask what else is on that device’s runtime without unpacking
the runtime itself. Whatever device_id spends the high byte on comes
back on every id, untouched.
Sourcepub fn enumerate_all() -> Vec<Device>
pub fn enumerate_all() -> Vec<Device>
Every device of every runtime this build links.
What a caller listing “the devices” wants, now that one type covers them all — a runtime with no hardware present contributes nothing.
Sourcepub fn utilization(&self) -> Result<DeviceUtilization, UtilizationUnavailable>
pub fn utilization(&self) -> Result<DeviceUtilization, UtilizationUnavailable>
How busy this device is, by the counter its card’s driver or its platform keeps: NVML
for an NVIDIA card, gpu_busy_percent for an AMD one and the idle residency of an Intel
one on Linux, the GPU engine counters Task Manager reads on Windows, the accelerator’s
statistics in the I/O Registry on macOS, and the processor times for the CPU.
The card decides which counter answers, not the runtime, so an NVIDIA card reads the same through CUDA as through wgpu. Asking creates the device’s client, and a card’s counter is opened the first time it is asked and kept for the life of the process.
The Intel, Windows and CPU counters measure the time between two readings. A reading
covers the time since the card was last asked, by any caller, and the first is
UtilizationUnavailable::NoPreviousReading.
use cubecl::Device;
match Device::default().utilization() {
Ok(utilization) => println!("{}% busy", utilization.busy_percent),
Err(reason) => println!("no reading: {reason}"),
}Trait Implementations§
Source§impl Default for Device
Available on any_runtime only.The default device of the most capable runtime with hardware to run on.
impl Default for Device
any_runtime only.The default device of the most capable runtime with hardware to run on.
Walks the runtimes this build links, most capable first, and takes the first that reports a device — so a binary that links both CUDA and wgpu lands on wgpu when it turns out there is no NVIDIA card, rather than naming a device it cannot reach.
The last runtime in that order is taken without asking. There is nothing left to fall back to, so its answer cannot change the outcome, and a build that links one runtime — the usual one — probes nothing at all. Where a probe does run, its result is kept for the life of the process: a device appearing or disappearing later goes unnoticed.
Source§impl Device for Device
Available on any_runtime only.What lets this stand in wherever a runtime’s own device type did: burn’s
backends take a device through this trait, and are handed this one.
impl Device for Device
any_runtime only.What lets this stand in wherever a runtime’s own device type did: burn’s backends take a device through this trait, and are handed this one.
Only where a runtime is linked, since the trait asks for a default.
impl Eq for Device
Source§impl From<CudaDevice> for Device
impl From<CudaDevice> for Device
Source§fn from(device: CudaDevice) -> Device
fn from(device: CudaDevice) -> Device
Source§impl From<MetalDevice> for Device
impl From<MetalDevice> for Device
Source§fn from(device: MetalDevice) -> Device
fn from(device: MetalDevice) -> Device
Source§impl From<WgpuDevice> for Device
impl From<WgpuDevice> for Device
Source§fn from(device: WgpuDevice) -> Device
fn from(device: WgpuDevice) -> Device
impl StructuralPartialEq for Device
Auto Trait Implementations§
impl Freeze for Device
impl RefUnwindSafe for Device
impl Send for Device
impl Sync for Device
impl Unpin for Device
impl UnsafeUnpin for Device
impl UnwindSafe for Device
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneExpand for Twhere
T: Clone,
impl<T> CloneExpand for Twhere
T: Clone,
fn __expand_clone_method(&self, _: &Scope) -> T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CompilationArg for T
impl<T> CompilationArg for T
Source§fn dynamic_cast<Arg>(&self) -> Argwhere
Arg: CompilationArg,
fn dynamic_cast<Arg>(&self) -> Argwhere
Arg: CompilationArg,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<K, Q> Equivalent<Q> for K
impl<K, Q> Equivalent<Q> for K
Source§fn equivalent(&self, key: &Q) -> bool
fn equivalent(&self, key: &Q) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more