pub mod common;
pub mod cpu;
#[cfg(feature = "cuda")]
pub mod cuda;
#[cfg(feature = "opencl")]
pub mod opencl;
#[cfg(feature = "metal")]
pub mod metal;
#[cfg(feature = "rocm")]
pub mod rocm;
#[cfg(feature = "vulkan")]
pub mod vulkan;
pub use common::*;
pub use cpu::CpuFallbackBackend;
#[cfg(feature = "cuda")]
pub use cuda::{CudaBackend, CudaContext, CudaPerformanceStats};
#[cfg(feature = "opencl")]
pub use opencl::{OpenClBackend, OpenClContext, OpenClPerformanceStats};
#[cfg(feature = "metal")]
pub use metal::MetalBackend;
#[cfg(feature = "rocm")]
pub use rocm::RocmBackend;
#[cfg(feature = "vulkan")]
pub use vulkan::VulkanBackend;
pub fn select_best_backend() -> Box<dyn GpuBackend> {
#[cfg(feature = "cuda")]
if let Ok(backend) = CudaBackend::new() {
if backend.is_available() {
return Box::new(backend);
}
}
#[cfg(feature = "opencl")]
if let Ok(backend) = OpenClBackend::new() {
if backend.is_available() {
return Box::new(backend);
}
}
#[cfg(feature = "metal")]
if let Ok(backend) = MetalBackend::new() {
if backend.is_available() {
return Box::new(backend);
}
}
#[cfg(feature = "rocm")]
if let Ok(backend) = RocmBackend::new() {
if backend.is_available() {
return Box::new(backend);
}
}
#[cfg(feature = "vulkan")]
if let Ok(backend) = VulkanBackend::new() {
if backend.is_available() {
return Box::new(backend);
}
}
Box::new(CpuFallbackBackend::new())
}
pub fn available_backends() -> Vec<Box<dyn GpuBackend>> {
let mut backends = Vec::new();
backends.push(Box::new(CpuFallbackBackend::new()) as Box<dyn GpuBackend>);
#[cfg(feature = "cuda")]
if let Ok(backend) = CudaBackend::new() {
if backend.is_available() {
backends.push(Box::new(backend));
}
}
#[cfg(feature = "opencl")]
if let Ok(backend) = OpenClBackend::new() {
if backend.is_available() {
backends.push(Box::new(backend));
}
}
#[cfg(feature = "metal")]
if let Ok(backend) = MetalBackend::new() {
if backend.is_available() {
backends.push(Box::new(backend));
}
}
#[cfg(feature = "rocm")]
if let Ok(backend) = RocmBackend::new() {
if backend.is_available() {
backends.push(Box::new(backend));
}
}
#[cfg(feature = "vulkan")]
if let Ok(backend) = VulkanBackend::new() {
if backend.is_available() {
backends.push(Box::new(backend));
}
}
backends
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cpu_fallback_always_available() {
let backend = CpuFallbackBackend::new();
assert!(backend.is_available());
assert_eq!(backend.name(), "CPU Fallback");
}
#[test]
fn test_select_best_backend() {
let backend = select_best_backend();
assert!(backend.is_available());
assert!(!backend.name().is_empty());
}
#[test]
fn test_available_backends() {
let backends = available_backends();
assert!(!backends.is_empty());
for backend in backends {
assert!(backend.is_available());
}
}
}