Skip to main content

burn_wgpu/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3//! The [wgpu](https://github.com/gfx-rs/wgpu) runtime for [Burn](https://github.com/tracel-ai/burn)'s
4//! CubeCL backend: Vulkan, Metal, DirectX 12, OpenGL and WebGPU through one API.
5//!
6//! Applications enable Burn's `wgpu` feature and create a device with `Device::wgpu(..)`, which
7//! picks a graphics API for the platform, or configure it first with `Device::wgpu_options()`.
8//! The `vulkan`, `metal` and `webgpu` features add devices pinned to that API. Applications do not
9//! need this crate directly.
10//!
11//! This crate also re-exports the wgpu runtime types ([`WgpuDevice`], [`WgpuSetup`],
12//! [`MemoryConfiguration`], ...) for sharing an existing wgpu device with Burn, and, with the
13//! `template` feature, the API for launching hand-written WGSL kernels.
14//!
15//! # Feature flags
16//!
17//! - `std` (default): standard library support.
18//! - `fusion` (default): kernel fusion.
19//! - `autotune` (default): benchmark kernel variants at runtime and keep the fastest.
20//! - `vulkan`, `metal`, `webgpu`: devices pinned to that graphics API, using its native shader
21//!   compiler where available.
22//! - `template`: launch hand-written kernels.
23//! - `exclusive-memory-only`: never share a memory page between allocations (always the case on
24//!   wasm).
25//! - `tracing`: instrument operations with the `tracing` crate.
26
27extern crate alloc;
28
29#[cfg(feature = "template")]
30pub use burn_cubecl::{
31    kernel::{KernelMetadata, into_contiguous},
32    kernel_source,
33    template::{KernelSource, SourceKernel, SourceTemplate, build_info},
34};
35
36pub use burn_cubecl::{BoolElement, FloatElement, IntElement};
37pub use burn_cubecl::{CubeBackend, tensor::CubeTensor};
38pub use cubecl::CubeDim;
39pub use cubecl::flex32;
40
41#[cfg(feature = "metal")]
42pub use cubecl::wgpu::MslCompiler;
43#[cfg(not(target_family = "wasm"))]
44pub use cubecl::wgpu::try_init_setup;
45pub use cubecl::wgpu::{
46    AutoCompiler, MemoryConfiguration, RuntimeOptions, WgpuBackend, WgpuDevice, WgpuInitError,
47    WgpuResource, WgpuRuntime, WgpuSetup, WgpuStorage, init_device, init_device_with_api,
48    init_setup, init_setup_async, try_init_device, try_init_device_with_api, try_init_setup_async,
49    wgpu,
50};
51// Vulkan and WebGpu would have conflicting type names
52pub mod graphics {
53    pub use cubecl::wgpu::{AutoGraphicsApi, Dx12, GraphicsApi, Metal, OpenGl, Vulkan, WebGpu};
54}
55
56#[cfg(feature = "fusion")]
57type WgpuInner = burn_fusion::Fusion<CubeBackend>;
58
59#[cfg(not(feature = "fusion"))]
60type WgpuInner = CubeBackend;
61
62/// Tensor backend that uses the wgpu crate for executing GPU compute shaders.
63///
64/// This backend can target multiple graphics APIs, including:
65///   - [Vulkan][crate::graphics::Vulkan] on Linux, Windows, and Android.
66///   - [OpenGL](crate::graphics::OpenGl) on Linux, Windows, and Android.
67///   - [DirectX 12](crate::graphics::Dx12) on Windows.
68///   - [Metal][crate::graphics::Metal] on Apple hardware.
69///   - [WebGPU](crate::graphics::WebGpu) on supported browsers and `wasm` runtimes.
70///
71/// Automatic devices use [`AutoCompiler`] to select WGSL, SPIR-V or MSL, with WGSL fallback
72/// when a native compiler is unavailable. Enabling `metal` makes MSL available without changing
73/// the compiler used by unrelated devices.
74///
75/// With `metal` enabled, an explicitly selected Metal device, created with Burn's
76/// `burn::tensor::Device::metal` or [`cubecl::Device::metal_msl`], requires native MSL and panics
77/// during initialization if it is unavailable. The same applies to [`init_setup`] or
78/// [`init_setup_async`] with [`graphics::Metal`], and to [`init_device_with_api`] with
79/// [`graphics::Metal`]. Importing through [`init_device`] retains automatic compiler selection
80/// and fallback. The corresponding `try_*` functions return initialization errors instead
81/// of panicking.
82///
83/// Multiple backend features can be enabled together. The deprecated `Vulkan`, `WebGpu` and
84/// `Metal` aliases name the same backend; use [`Wgpu`] with an explicit device constructor to
85/// select the graphics API. Compiler selection follows the device and enabled features.
86///
87/// Application code configures and initializes the runtime with `Device::wgpu_options`:
88///
89/// ```rust, ignore
90/// use burn::tensor::{Device, wgpu::WgpuBackend};
91/// let device = Device::wgpu_options()
92///     .graphics_api(WgpuBackend::Vulkan)
93///     .tasks_max(32)
94///     .init()?;
95/// ```
96/// Use `init_async().await` for native async applications and browsers, or
97/// `.setup(existing_setup).init()` to share an application's existing device and queue.
98/// Initialize once, then clone the Burn device to share its runtime. The low-level
99/// [`try_init_setup_async`] and [`try_init_device`] APIs remain available for backend authors.
100///
101/// # Notes
102///
103/// When the `fusion` feature flag is enabled (the default), this backend uses [burn_fusion] to
104/// compile and optimize streams of tensor operations for improved performance. You can disable
105/// the `fusion` feature flag to remove that functionality, which might be necessary on `wasm`
106/// for now.
107pub type Wgpu = WgpuInner;
108
109/// Deprecated alias of [`Wgpu`].
110///
111/// Select Vulkan explicitly with Burn's `burn::tensor::Device::vulkan` or
112/// [`cubecl::Device::vulkan`]. Compiler selection follows the device; see [`Wgpu`].
113#[cfg(feature = "vulkan")]
114#[deprecated(
115    since = "0.22.0",
116    note = "Use `Wgpu` with `burn::tensor::Device::vulkan` to select Vulkan explicitly. This alias is identical to `Wgpu` and does not select a graphics API."
117)]
118pub type Vulkan = WgpuInner;
119
120/// Deprecated alias of [`Wgpu`].
121///
122/// Select WebGPU explicitly with Burn's `burn::tensor::Device::webgpu` or
123/// [`cubecl::Device::webgpu`]. Compiler selection follows the device; see [`Wgpu`].
124#[cfg(feature = "webgpu")]
125#[deprecated(
126    since = "0.22.0",
127    note = "Use `Wgpu` with `burn::tensor::Device::webgpu` to select WebGPU explicitly. This alias is identical to `Wgpu` and does not select a graphics API."
128)]
129pub type WebGpu = WgpuInner;
130
131/// Deprecated alias of [`Wgpu`].
132///
133/// Use Burn's `burn::tensor::Device::metal` or
134/// [`cubecl::Device::metal_msl`] to select Metal explicitly. Both select
135/// [`WgpuBackend::Metal`], which requires native MSL support with `metal` enabled and panics
136/// during initialization if it is unavailable. Automatic devices retain WGSL fallback.
137///
138/// To import an existing Metal setup with the same requirement, use
139/// `init_device_with_api::<graphics::Metal>(setup, RuntimeOptions::default())`.
140#[cfg(feature = "metal")]
141#[deprecated(
142    since = "0.22.0",
143    note = "Use `Wgpu` with `burn::tensor::Device::metal` to select Metal explicitly. This alias is identical to `Wgpu` and does not select a graphics API."
144)]
145pub type Metal = WgpuInner;
146
147#[cfg(test)]
148mod tests {
149    use super::*;
150    use burn_backend::{Backend, BoolStore, DType, DeviceOps};
151
152    fn assert_common_dtypes(device: &cubecl::Device) {
153        // Metal and Vulkan alias Wgpu; the device selects the compiler.
154        type B = Wgpu;
155        let defaults = device.defaults();
156        let scheme = defaults.quantization.scheme;
157
158        assert!(B::supports_dtype(device, DType::F32));
159        assert!(B::supports_dtype(device, DType::F16));
160        assert!(B::supports_dtype(device, DType::I64));
161        assert!(B::supports_dtype(device, DType::I32));
162        assert!(B::supports_dtype(device, DType::U64));
163        assert!(B::supports_dtype(device, DType::U32));
164        assert!(B::supports_dtype(device, DType::QFloat(scheme)));
165        assert!(!B::supports_dtype(device, DType::Bool(BoolStore::Native)));
166        assert!(B::supports_dtype(device, defaults.bool_dtype.into()));
167    }
168
169    #[cfg(any(
170        all(feature = "vulkan", not(target_family = "wasm")),
171        all(feature = "metal", target_vendor = "apple")
172    ))]
173    fn assert_fp4_dtypes(device: &cubecl::Device) {
174        use burn_backend::quantization::{QuantScheme, QuantStore, QuantValue, ScaleDtype};
175
176        // FP8 block scale storage and software conversion support NVFP4 and MXFP4.
177        let fp4 = QuantScheme::default()
178            .with_value(QuantValue::E2M1)
179            .with_store(QuantStore::PackedU32(0));
180        let nvfp4 = fp4
181            .per_block([16], ScaleDtype::UE4M3)
182            .per_tensor(ScaleDtype::F32);
183        let mxfp4 = fp4.per_block([32], ScaleDtype::UE8M0);
184        assert!(Wgpu::supports_dtype(device, DType::QFloat(nvfp4)));
185        assert!(Wgpu::supports_dtype(device, DType::QFloat(mxfp4)));
186    }
187
188    #[test]
189    fn should_support_dtypes() {
190        let device = cubecl::Device::Wgpu(WgpuDevice::default());
191        assert_common_dtypes(&device);
192    }
193
194    #[cfg(all(feature = "vulkan", not(target_family = "wasm")))]
195    #[test]
196    fn should_support_vulkan_dtypes() {
197        type B = Wgpu;
198        let device = cubecl::Device::Wgpu(WgpuDevice::default().on(WgpuBackend::Vulkan));
199        assert_common_dtypes(&device);
200
201        assert!(B::supports_dtype(&device, DType::I16));
202        assert!(B::supports_dtype(&device, DType::I8));
203        assert!(B::supports_dtype(&device, DType::U16));
204        assert!(B::supports_dtype(&device, DType::U8));
205
206        // F64 is supported through the shader_float64 feature.
207        assert!(B::supports_dtype(&device, DType::F64));
208        assert!(!B::supports_dtype(&device, DType::Flex32));
209        // BF16 supports storage and conversion, but not all scalar arithmetic operations.
210        assert!(!B::supports_dtype(&device, DType::BF16));
211
212        assert_fp4_dtypes(&device);
213    }
214
215    #[cfg(all(feature = "metal", target_vendor = "apple"))]
216    #[test]
217    fn should_support_metal_dtypes() {
218        type B = Wgpu;
219        let device = cubecl::Device::Wgpu(WgpuDevice::default().on(WgpuBackend::Metal));
220        assert_common_dtypes(&device);
221
222        assert!(B::supports_dtype(&device, DType::I16));
223        assert!(B::supports_dtype(&device, DType::I8));
224        assert!(B::supports_dtype(&device, DType::U16));
225        assert!(B::supports_dtype(&device, DType::U8));
226
227        assert!(!B::supports_dtype(&device, DType::F64));
228        // MSL 3.2 carries bfloat natively.
229        assert!(B::supports_dtype(&device, DType::BF16));
230        assert!(!B::supports_dtype(&device, DType::Flex32));
231
232        assert_fp4_dtypes(&device);
233    }
234
235    #[cfg(not(any(feature = "vulkan", feature = "metal")))]
236    #[test]
237    fn should_support_wgsl_dtypes() {
238        type B = Wgpu;
239        let device = cubecl::Device::Wgpu(WgpuDevice::default());
240        assert_common_dtypes(&device);
241
242        assert!(B::supports_dtype(&device, DType::Flex32));
243        #[cfg(target_os = "macos")]
244        assert!(!B::supports_dtype(&device, DType::F64));
245        #[cfg(not(target_os = "macos"))]
246        assert!(B::supports_dtype(&device, DType::F64));
247        assert!(!B::supports_dtype(&device, DType::BF16));
248        assert!(!B::supports_dtype(&device, DType::I16));
249        assert!(!B::supports_dtype(&device, DType::I8));
250        assert!(!B::supports_dtype(&device, DType::U16));
251        assert!(!B::supports_dtype(&device, DType::U8));
252    }
253}