av_denoise_core/accelerate.rs
1//! The hardware backends kernels can run on.
2//!
3//! An [`Accelerator`] names a backend rather than a specific piece of
4//! hardware. Which physical GPU it lands on is chosen separately, with
5//! [`crate::Device`].
6//!
7//! Only the backends whose crate feature is enabled exist at compile
8//! time, so a build without the `cuda` feature has no `Accelerator::Cuda`
9//! variant at all.
10//!
11//! [`Denoiser::create`](crate::Denoiser::create) takes a list of these
12//! and uses the first one that starts successfully, which lets a program
13//! prefer a fast backend and quietly fall back to a slower one.
14//!
15//! ```no_run
16//! use av_denoise_core::accelerate::get_default_accelerators;
17//!
18//! // Every backend this build supports, in the order to try them.
19//! let preferred = get_default_accelerators();
20//! # let _ = preferred;
21//! ```
22//!
23//! A list can also be written out by hand, such as
24//! `vec![Accelerator::Cuda, Accelerator::Vulkan]` to prefer the vendor
25//! backend and fall back to the portable one.
26//!
27//! Every accelerator here runs kernels on a GPU. There is no software
28//! backend, because the collaborative filter aggregates through atomic
29//! floating-point adds and cubecl's CPU runtime does not implement
30//! atomics. [`crate::Device::Cpu`] still selects a software *device*
31//! where the platform offers one, such as lavapipe under Vulkan.
32
33use strum_macros::{Display, EnumIter, EnumString, IntoStaticStr};
34
35#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoStaticStr, EnumString, EnumIter, Display)]
36#[strum(serialize_all = "snake_case")]
37/// A hardware backend that kernels can run on.
38pub enum Accelerator {
39 #[cfg(any(feature = "cuda", docsrs))]
40 #[cfg_attr(docsrs, doc(cfg(feature = "cuda")))]
41 /// Runs kernels through the Nvidia CUDA backend.
42 ///
43 /// Nvidia GPUs only.
44 Cuda,
45 #[cfg(any(feature = "vulkan", docsrs))]
46 #[cfg_attr(docsrs, doc(cfg(feature = "vulkan")))]
47 /// Runs kernels through the wgpu Vulkan backend.
48 ///
49 /// This is the lightest and most portable option, because it works
50 /// on any platform and GPU that supports basic compute shaders.
51 Vulkan,
52 #[cfg(any(feature = "metal", docsrs))]
53 #[cfg_attr(docsrs, doc(cfg(feature = "metal")))]
54 /// Runs kernels through the wgpu Metal backend.
55 ///
56 /// This is the only option on Apple Silicon.
57 Metal,
58 #[cfg(any(feature = "rocm", docsrs))]
59 #[cfg_attr(docsrs, doc(cfg(feature = "rocm")))]
60 /// Runs kernels through the AMD ROCm backend.
61 ///
62 /// WARNING: ROCm is *not* the recommended backend for AMD GPUs, it is slower and often
63 /// plagued with issues from drivers, vulkan will almost certainly be faster and
64 /// less buggy.
65 ///
66 /// AMD GPUs only.
67 Rocm,
68}
69
70/// Returns every accelerator this build enables, in the order to try
71/// them.
72pub fn get_default_accelerators() -> Vec<Accelerator> {
73 use strum::IntoEnumIterator;
74
75 let mut accelerator = Vec::new();
76 for enabled in Accelerator::iter() {
77 accelerator.push(enabled);
78 }
79
80 accelerator
81}