axonml_core/backends/mod.rs
1//! Backends - Device-Specific Implementations
2//!
3//! This module contains backend implementations for different compute devices.
4//! Each backend provides device-specific memory operations and kernel execution.
5//!
6//! # Available Backends
7//! - `cpu` - CPU backend (always available)
8//! - `cuda` - NVIDIA CUDA backend (requires `cuda` feature)
9//! - `vulkan` - Vulkan backend (requires `vulkan` feature)
10//! - `metal` - Apple Metal backend (requires `metal` feature)
11//! - `wgpu` - WebGPU backend (requires `wgpu` feature)
12//!
13//! # Backend Trait
14//!
15//! All backends implement the `Backend` trait which provides a common interface
16//! for tensor operations. This enables device-agnostic code.
17//!
18//! @version 0.1.0
19//! @author `AutomataNexus` Development Team
20
21use crate::device::DeviceCapabilities;
22
23// =============================================================================
24// Backend Modules
25// =============================================================================
26
27pub mod cpu;
28
29#[cfg(feature = "cuda")]
30pub mod cuda;
31
32#[cfg(feature = "vulkan")]
33pub mod vulkan;
34
35#[cfg(feature = "metal")]
36pub mod metal;
37
38#[cfg(feature = "wgpu")]
39pub mod wgpu_backend;
40
41// =============================================================================
42// Re-exports
43// =============================================================================
44
45pub use cpu::CpuBackend;
46
47#[cfg(feature = "cuda")]
48pub use cuda::CudaBackend;
49
50#[cfg(feature = "vulkan")]
51pub use vulkan::VulkanBackend;
52
53#[cfg(feature = "metal")]
54pub use metal::MetalBackend;
55
56#[cfg(feature = "wgpu")]
57pub use wgpu_backend::WgpuBackend;
58
59// =============================================================================
60// Backend Trait
61// =============================================================================
62
63/// Common trait for all compute backends.
64///
65/// This trait defines the interface that all backends must implement,
66/// enabling device-agnostic tensor operations.
67pub trait Backend: Send + Sync {
68 /// Returns the name of this backend.
69 fn name(&self) -> &'static str;
70
71 /// Returns whether this backend is available on the current system.
72 fn is_available(&self) -> bool;
73
74 /// Returns the device capabilities.
75 fn capabilities(&self) -> DeviceCapabilities;
76
77 /// Allocates memory on this backend.
78 fn allocate(&self, size: usize) -> *mut u8;
79
80 /// Deallocates memory on this backend.
81 fn deallocate(&self, ptr: *mut u8, size: usize);
82
83 /// Copies data from host to device.
84 fn copy_to_device(&self, dst: *mut u8, src: *const u8, size: usize);
85
86 /// Copies data from device to host.
87 fn copy_to_host(&self, dst: *mut u8, src: *const u8, size: usize);
88
89 /// Copies data within the device.
90 fn copy_device_to_device(&self, dst: *mut u8, src: *const u8, size: usize);
91
92 /// Synchronizes the device (waits for all operations to complete).
93 fn synchronize(&self);
94}
95
96// =============================================================================
97// GPU Memory Management
98// =============================================================================
99
100/// GPU memory handle for safe memory management.
101#[derive(Debug)]
102pub struct GpuMemory {
103 ptr: *mut u8,
104 size: usize,
105 device_index: usize,
106 backend_type: BackendType,
107}
108
109/// Type of backend for a GPU memory allocation.
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub enum BackendType {
112 /// CPU backend.
113 Cpu,
114 /// CUDA backend.
115 #[cfg(feature = "cuda")]
116 Cuda,
117 /// Vulkan backend.
118 #[cfg(feature = "vulkan")]
119 Vulkan,
120 /// Metal backend.
121 #[cfg(feature = "metal")]
122 Metal,
123 /// WebGPU backend.
124 #[cfg(feature = "wgpu")]
125 Wgpu,
126}
127
128impl GpuMemory {
129 /// Creates a new GPU memory handle.
130 pub fn new(ptr: *mut u8, size: usize, device_index: usize, backend_type: BackendType) -> Self {
131 Self {
132 ptr,
133 size,
134 device_index,
135 backend_type,
136 }
137 }
138
139 /// Returns the raw pointer.
140 #[must_use] pub fn ptr(&self) -> *mut u8 {
141 self.ptr
142 }
143
144 /// Returns the size in bytes.
145 #[must_use] pub fn size(&self) -> usize {
146 self.size
147 }
148
149 /// Returns the device index.
150 #[must_use] pub fn device_index(&self) -> usize {
151 self.device_index
152 }
153
154 /// Returns the backend type.
155 #[must_use] pub fn backend_type(&self) -> BackendType {
156 self.backend_type
157 }
158}
159
160// =============================================================================
161// GPU Stream/Queue Abstraction
162// =============================================================================
163
164/// GPU execution stream for async operations.
165#[derive(Debug)]
166pub struct GpuStream {
167 /// Stream handle (backend-specific).
168 handle: usize,
169 /// Device index.
170 device_index: usize,
171 /// Backend type.
172 backend_type: BackendType,
173}
174
175impl GpuStream {
176 /// Creates a new GPU stream.
177 #[must_use] pub fn new(handle: usize, device_index: usize, backend_type: BackendType) -> Self {
178 Self {
179 handle,
180 device_index,
181 backend_type,
182 }
183 }
184
185 /// Returns the stream handle.
186 #[must_use] pub fn handle(&self) -> usize {
187 self.handle
188 }
189
190 /// Returns the device index.
191 #[must_use] pub fn device_index(&self) -> usize {
192 self.device_index
193 }
194
195 /// Synchronizes this stream (waits for all operations to complete).
196 pub fn synchronize(&self) {
197 match self.backend_type {
198 BackendType::Cpu => {} // No-op for CPU
199 #[cfg(feature = "cuda")]
200 BackendType::Cuda => cuda::stream_synchronize(self.handle),
201 #[cfg(feature = "vulkan")]
202 BackendType::Vulkan => vulkan::queue_wait_idle(self.handle),
203 #[cfg(feature = "metal")]
204 BackendType::Metal => metal::command_buffer_wait(self.handle),
205 #[cfg(feature = "wgpu")]
206 BackendType::Wgpu => wgpu_backend::queue_submit(self.handle),
207 }
208 }
209}
210
211// =============================================================================
212// Device Selection Utilities
213// =============================================================================
214
215/// Returns the best available GPU backend.
216#[must_use] pub fn best_available_backend() -> BackendType {
217 #[cfg(feature = "cuda")]
218 if cuda::is_available() {
219 return BackendType::Cuda;
220 }
221
222 #[cfg(feature = "metal")]
223 if metal::is_available() {
224 return BackendType::Metal;
225 }
226
227 #[cfg(feature = "vulkan")]
228 if vulkan::is_available() {
229 return BackendType::Vulkan;
230 }
231
232 #[cfg(feature = "wgpu")]
233 if wgpu_backend::is_available() {
234 return BackendType::Wgpu;
235 }
236
237 BackendType::Cpu
238}
239
240/// Returns the number of available GPUs across all backends.
241#[must_use] pub fn gpu_count() -> usize {
242 #[allow(unused_mut)]
243 let mut count = 0_usize;
244
245 #[cfg(feature = "cuda")]
246 {
247 count += cuda::device_count();
248 }
249
250 #[cfg(feature = "vulkan")]
251 {
252 count += vulkan::device_count();
253 }
254
255 #[cfg(feature = "metal")]
256 {
257 count += metal::device_count();
258 }
259
260 #[cfg(feature = "wgpu")]
261 {
262 count += wgpu_backend::device_count();
263 }
264
265 count
266}