Skip to main content

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}