1pub mod allocation;
12pub mod management;
13pub mod vendors;
14
15use std::collections::HashMap;
16use std::ffi::c_void;
17use std::ptr::NonNull;
18use std::sync::{Arc, Mutex};
19use std::time::{Duration, Instant};
20
21pub use allocation::{
23 AllocationStrategy, AllocationStrategyManager, AllocatorType, ArenaAllocator, BuddyAllocator,
24 MemoryPool, SlabAllocator, UnifiedAllocator, UnifiedConfig,
25};
26
27use allocation::strategies::AllocationStats;
28
29pub use management::{
30 AccessType, DefragmentationEngine, EvictionEngine, GarbageCollectionEngine,
31 IntegratedMemoryManager, ManagementStats, MemoryManagementConfig, MemoryManagementError,
32 MemoryRegion, PrefetchingEngine,
33};
34
35use management::eviction_policies::{CacheObject, ObjectPriority, ObjectType, RegionType};
36
37pub use vendors::{
38 CudaConfig, CudaError, CudaMemoryBackend, CudaMemoryType, GpuBackendFactory, GpuVendor,
39 MetalConfig, MetalError, MetalMemoryBackend, MetalMemoryType, OneApiConfig, OneApiError,
40 OneApiMemoryBackend, OneApiMemoryType, RocmConfig, RocmError, RocmMemoryBackend,
41 RocmMemoryType, UnifiedGpuBackend, UnifiedGpuError, UnifiedMemoryStats, VendorConfig,
42};
43
44#[derive(Debug, Clone)]
46pub struct GpuMemorySystemConfig {
47 pub vendor_config: VendorConfig,
49 pub allocation_config: UnifiedConfig,
51 pub management_config: MemoryManagementConfig,
53 pub system_config: SystemConfig,
55}
56
57#[derive(Debug, Clone)]
59pub struct SystemConfig {
60 pub enable_unified_interface: bool,
62 pub enable_cross_vendor_sharing: bool,
64 pub enable_performance_monitoring: bool,
66 pub monitoring_interval: Duration,
68 pub memory_budget: f64,
70 pub enable_auto_optimization: bool,
72 pub optimization_interval: Duration,
74 pub enable_memory_compression: bool,
76 pub thread_pool_size: usize,
78}
79
80impl Default for SystemConfig {
81 fn default() -> Self {
82 Self {
83 enable_unified_interface: true,
84 enable_cross_vendor_sharing: false,
85 enable_performance_monitoring: true,
86 monitoring_interval: Duration::from_millis(500),
87 memory_budget: 0.9,
88 enable_auto_optimization: true,
89 optimization_interval: Duration::from_secs(60),
90 enable_memory_compression: false,
91 thread_pool_size: 4,
92 }
93 }
94}
95
96impl Default for GpuMemorySystemConfig {
97 fn default() -> Self {
98 let vendor = GpuBackendFactory::get_preferred_vendor();
99 Self {
100 vendor_config: GpuBackendFactory::create_default_config(vendor),
101 allocation_config: UnifiedConfig::default(),
102 management_config: MemoryManagementConfig::default(),
103 system_config: SystemConfig::default(),
104 }
105 }
106}
107
108pub struct GpuMemorySystem {
110 gpu_backend: UnifiedGpuBackend,
112 allocation_engine: UnifiedAllocator,
114 memory_manager: IntegratedMemoryManager,
116 config: GpuMemorySystemConfig,
118 stats: SystemStats,
120 memory_regions: HashMap<*mut c_void, MemoryAllocation>,
122 monitoring_enabled: bool,
124 last_optimization: Instant,
126}
127
128#[derive(Debug, Clone)]
130pub struct MemoryAllocation {
131 pub ptr: *mut c_void,
132 pub size: usize,
133 pub allocator_type: AllocatorType,
134 pub vendor_memory_type: String,
135 pub allocated_at: Instant,
136 pub last_accessed: Option<Instant>,
137 pub access_count: u64,
138 pub ref_count: u32,
139}
140
141#[derive(Debug, Clone, Default)]
143pub struct SystemStats {
144 pub total_allocations: u64,
145 pub total_deallocations: u64,
146 pub bytes_allocated: u64,
147 pub bytes_deallocated: u64,
148 pub active_allocations: u64,
149 pub peak_memory_usage: usize,
150 pub fragmentation_ratio: f64,
151 pub allocation_efficiency: f64,
152 pub vendor_stats: UnifiedMemoryStats,
153 pub allocation_stats: AllocationStats,
154 pub management_stats: ManagementStats,
155 pub uptime: Duration,
156 pub optimization_cycles: u64,
157}
158
159impl GpuMemorySystem {
160 pub fn new(config: GpuMemorySystemConfig) -> Result<Self, GpuMemorySystemError> {
162 let mut gpu_backend = UnifiedGpuBackend::new(config.vendor_config.clone())?;
164
165 let mut total_size =
167 (config.system_config.memory_budget * gpu_backend.get_total_memory() as f64) as usize;
168
169 if config.allocation_config.enable_buddy {
171 total_size = total_size.next_power_of_two();
172 }
173
174 let base_ptr = gpu_backend
175 .allocate(total_size)
176 .map_err(GpuMemorySystemError::BackendError)?;
177
178 let allocation_engine = UnifiedAllocator::new(
180 unsafe { NonNull::new_unchecked(base_ptr as *mut u8) },
181 total_size,
182 config.allocation_config.clone(),
183 )
184 .map_err(|e| GpuMemorySystemError::AllocationError(format!("{:?}", e)))?;
185
186 let memory_manager = IntegratedMemoryManager::new(config.management_config.clone());
188
189 Ok(Self {
190 gpu_backend,
191 allocation_engine,
192 memory_manager,
193 config,
194 stats: SystemStats::default(),
195 memory_regions: HashMap::new(),
196 monitoring_enabled: false,
197 last_optimization: Instant::now(),
198 })
199 }
200
201 pub fn auto_create() -> Result<Self, GpuMemorySystemError> {
203 let config = GpuMemorySystemConfig::default();
204 Self::new(config)
205 }
206
207 pub fn start(&mut self) -> Result<(), GpuMemorySystemError> {
209 if self.config.system_config.enable_performance_monitoring {
211 self.memory_manager
212 .start_background_management()
213 .map_err(|e| GpuMemorySystemError::ManagementError(format!("{}", e)))?;
214 self.monitoring_enabled = true;
215 }
216
217 Ok(())
221 }
222
223 pub fn allocate(
225 &mut self,
226 size: usize,
227 alignment: Option<usize>,
228 ) -> Result<*mut c_void, GpuMemorySystemError> {
229 let start_time = Instant::now();
230
231 let allocator_type = self.choose_allocator(size);
233
234 let ptr_nonnull =
236 self.allocation_engine
237 .allocate(size, allocator_type.clone(), alignment)?;
238
239 let ptr = ptr_nonnull.as_ptr() as *mut c_void;
241
242 let allocation = MemoryAllocation {
244 ptr,
245 size,
246 allocator_type,
247 vendor_memory_type: self.get_vendor_memory_type(),
248 allocated_at: Instant::now(),
249 last_accessed: Some(Instant::now()),
250 access_count: 1,
251 ref_count: 1,
252 };
253
254 self.memory_regions.insert(ptr, allocation);
256
257 self.update_allocation_stats(size, start_time.elapsed());
259
260 self.handle_memory_pressure()?;
262
263 Ok(ptr)
264 }
265
266 pub fn free(&mut self, ptr: *mut c_void) -> Result<(), GpuMemorySystemError> {
268 let start_time = Instant::now();
269
270 let allocation = self
272 .memory_regions
273 .remove(&ptr)
274 .ok_or_else(|| GpuMemorySystemError::InvalidPointer("Pointer not found".to_string()))?;
275
276 self.allocation_engine
278 .free(ptr, allocation.allocator_type)?;
279
280 self.update_deallocation_stats(allocation.size, start_time.elapsed());
282
283 Ok(())
284 }
285
286 pub fn reallocate(
288 &mut self,
289 ptr: *mut c_void,
290 new_size: usize,
291 ) -> Result<*mut c_void, GpuMemorySystemError> {
292 let allocation = self
294 .memory_regions
295 .get(&ptr)
296 .ok_or_else(|| GpuMemorySystemError::InvalidPointer("Pointer not found".to_string()))?;
297
298 let old_size = allocation.size;
299 let allocator_type = allocation.allocator_type.clone();
300
301 if let Ok(new_ptr) = self
303 .allocation_engine
304 .reallocate(ptr, new_size, allocator_type)
305 {
306 if new_ptr == ptr {
307 if let Some(allocation) = self.memory_regions.get_mut(&ptr) {
309 allocation.size = new_size;
310 allocation.last_accessed = Some(Instant::now());
311 allocation.access_count += 1;
312 }
313 return Ok(ptr);
314 }
315 }
316
317 let new_ptr = self.allocate(new_size, None)?;
319
320 unsafe {
322 std::ptr::copy_nonoverlapping(
323 ptr as *const u8,
324 new_ptr as *mut u8,
325 old_size.min(new_size),
326 );
327 }
328
329 self.free(ptr)?;
331
332 Ok(new_ptr)
333 }
334
335 pub fn record_access(
337 &mut self,
338 ptr: *mut c_void,
339 access_type: AccessType,
340 ) -> Result<(), GpuMemorySystemError> {
341 if let Some(allocation) = self.memory_regions.get_mut(&ptr) {
342 allocation.last_accessed = Some(Instant::now());
343 allocation.access_count += 1;
344
345 self.memory_manager
347 .update_access_pattern(ptr, allocation.size, access_type)?;
348 }
349
350 Ok(())
351 }
352
353 pub fn get_memory_info(&self, ptr: *mut c_void) -> Option<&MemoryAllocation> {
355 self.memory_regions.get(&ptr)
356 }
357
358 pub fn get_stats(&mut self) -> SystemStats {
360 self.stats.vendor_stats = self.gpu_backend.get_memory_stats();
362
363 let unified_stats = self.allocation_engine.get_stats();
365 self.stats.allocation_stats = AllocationStats {
366 total_allocations: unified_stats.total_allocations,
367 total_deallocations: unified_stats.total_deallocations,
368 cache_hits: unified_stats.routing_cache_hits,
369 cache_misses: unified_stats.routing_decisions - unified_stats.routing_cache_hits,
370 fragmentation_events: 0, total_allocated_bytes: unified_stats.bytes_allocated,
372 peak_allocated_bytes: unified_stats.peak_memory_usage as u64,
373 average_allocation_size: if unified_stats.total_allocations > 0 {
374 (unified_stats.bytes_allocated as f64) / (unified_stats.total_allocations as f64)
375 } else {
376 0.0
377 },
378 allocation_latency_ms: unified_stats.average_allocation_time_ns / 1_000_000.0,
379 };
380
381 self.stats.management_stats = self.memory_manager.get_stats().clone();
383
384 self.calculate_system_metrics();
386
387 self.stats.clone()
388 }
389
390 pub fn optimize(&mut self) -> Result<(), GpuMemorySystemError> {
392 if !self.config.system_config.enable_auto_optimization {
393 return Ok(());
394 }
395
396 let now = Instant::now();
397 if now.duration_since(self.last_optimization)
398 < self.config.system_config.optimization_interval
399 {
400 return Ok(());
401 }
402
403 let memory_regions: HashMap<usize, management::MemoryRegion> = self
405 .memory_regions
406 .iter()
407 .enumerate()
408 .map(|(i, (ptr, alloc))| {
409 let mut objects = HashMap::new();
410 objects.insert(
411 *ptr as usize,
412 CacheObject {
413 address: *ptr as usize,
414 size: alloc.size,
415 created_at: alloc.allocated_at,
416 last_access: alloc.last_accessed.unwrap_or(alloc.allocated_at),
417 access_count: alloc.access_count as u32,
418 access_frequency: alloc.access_count as f64,
419 priority: ObjectPriority::Normal,
420 kernel_context: None,
421 object_type: ObjectType::Data,
422 eviction_cost: 1.0,
423 replacement_cost: 1.0,
424 },
425 );
426
427 (
428 *ptr as usize,
429 management::MemoryRegion {
430 base_addr: *ptr as usize,
431 size: alloc.size,
432 objects,
433 region_type: RegionType::Buffer,
434 pressure: 0.0,
435 last_eviction: None,
436 },
437 )
438 })
439 .collect();
440
441 let _ = self
442 .memory_manager
443 .run_garbage_collection(&memory_regions)?;
444
445 self.allocation_engine.optimize_strategies()?;
447
448 self.memory_manager.optimize_policies()?;
450
451 if self.stats.fragmentation_ratio > 0.3 {
453 let _ = self.memory_manager.defragment(&memory_regions)?;
454 }
455
456 self.last_optimization = now;
457 self.stats.optimization_cycles += 1;
458
459 Ok(())
460 }
461
462 fn handle_memory_pressure(&mut self) -> Result<(), GpuMemorySystemError> {
464 let memory_usage_ratio = self.calculate_memory_usage_ratio();
465
466 if memory_usage_ratio > self.config.system_config.memory_budget {
467 let memory_regions: HashMap<usize, management::MemoryRegion> = self
468 .memory_regions
469 .iter()
470 .enumerate()
471 .map(|(i, (ptr, alloc))| {
472 let mut objects = HashMap::new();
473 objects.insert(
474 *ptr as usize,
475 CacheObject {
476 address: *ptr as usize,
477 size: alloc.size,
478 created_at: alloc.allocated_at,
479 last_access: alloc.last_accessed.unwrap_or(alloc.allocated_at),
480 access_count: alloc.access_count as u32,
481 access_frequency: alloc.access_count as f64,
482 priority: ObjectPriority::Normal,
483 kernel_context: None,
484 object_type: ObjectType::Data,
485 eviction_cost: 1.0,
486 replacement_cost: 1.0,
487 },
488 );
489
490 (
491 *ptr as usize,
492 management::MemoryRegion {
493 base_addr: *ptr as usize,
494 size: alloc.size,
495 objects,
496 region_type: RegionType::Buffer,
497 pressure: 0.0,
498 last_eviction: None,
499 },
500 )
501 })
502 .collect();
503
504 self.memory_manager
505 .handle_memory_pressure(memory_usage_ratio, &memory_regions)?;
506 }
507
508 Ok(())
509 }
510
511 fn choose_allocator(&self, size: usize) -> AllocatorType {
513 if size < 1024 {
515 AllocatorType::Slab } else if size < 1024 * 1024 {
517 AllocatorType::Buddy } else {
519 AllocatorType::Arena }
521 }
522
523 fn get_vendor_memory_type(&self) -> String {
525 match self.gpu_backend.get_vendor() {
526 GpuVendor::Nvidia => "Device".to_string(),
527 GpuVendor::Amd => "Device".to_string(),
528 GpuVendor::Intel => "Device".to_string(),
529 GpuVendor::Apple => "Private".to_string(),
530 GpuVendor::Unknown => "Unknown".to_string(),
531 }
532 }
533
534 fn update_allocation_stats(&mut self, size: usize, duration: Duration) {
536 self.stats.total_allocations += 1;
537 self.stats.bytes_allocated += size as u64;
538 self.stats.active_allocations += 1;
539
540 if self.stats.bytes_allocated > self.stats.peak_memory_usage as u64 {
541 self.stats.peak_memory_usage = self.stats.bytes_allocated as usize;
542 }
543 }
544
545 fn update_deallocation_stats(&mut self, size: usize, _duration: Duration) {
547 self.stats.total_deallocations += 1;
548 self.stats.bytes_deallocated += size as u64;
549 self.stats.active_allocations = self.stats.active_allocations.saturating_sub(1);
550 }
551
552 fn calculate_memory_usage_ratio(&self) -> f64 {
554 let total_memory = self.get_total_gpu_memory();
555 let used_memory = self.stats.bytes_allocated - self.stats.bytes_deallocated;
556 used_memory as f64 / total_memory as f64
557 }
558
559 fn get_total_gpu_memory(&self) -> usize {
561 match self.gpu_backend.get_vendor() {
563 GpuVendor::Nvidia => 8 * 1024 * 1024 * 1024, GpuVendor::Amd => 16 * 1024 * 1024 * 1024, GpuVendor::Intel => 12 * 1024 * 1024 * 1024, GpuVendor::Apple => 32 * 1024 * 1024 * 1024, GpuVendor::Unknown => 4 * 1024 * 1024 * 1024, }
569 }
570
571 fn calculate_system_metrics(&mut self) {
573 let total_allocated = self
575 .memory_regions
576 .values()
577 .map(|alloc| alloc.size)
578 .sum::<usize>();
579 let total_managed = self.stats.vendor_stats.bytes_allocated;
580 self.stats.fragmentation_ratio = if total_managed > 0 {
581 1.0 - (total_allocated as f64 / total_managed as f64)
582 } else {
583 0.0
584 };
585
586 self.stats.allocation_efficiency = if self.stats.total_allocations > 0 {
588 let successful_allocations = self.stats.total_allocations;
589 successful_allocations as f64 / self.stats.total_allocations as f64
590 } else {
591 1.0
592 };
593 }
594}
595
596unsafe impl Send for GpuMemorySystem {}
604unsafe impl Sync for GpuMemorySystem {}
605
606#[derive(Debug)]
608pub enum GpuMemorySystemError {
609 BackendError(UnifiedGpuError),
610 AllocationError(String),
611 ManagementError(String),
612 InvalidPointer(String),
613 SystemNotStarted,
614 ConfigurationError(String),
615 OptimizationFailed(String),
616 InternalError(String),
617}
618
619impl std::fmt::Display for GpuMemorySystemError {
620 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
621 match self {
622 GpuMemorySystemError::BackendError(err) => write!(f, "Backend error: {}", err),
623 GpuMemorySystemError::AllocationError(msg) => write!(f, "Allocation error: {}", msg),
624 GpuMemorySystemError::ManagementError(msg) => write!(f, "Management error: {}", msg),
625 GpuMemorySystemError::InvalidPointer(msg) => write!(f, "Invalid pointer: {}", msg),
626 GpuMemorySystemError::SystemNotStarted => write!(f, "System not started"),
627 GpuMemorySystemError::ConfigurationError(msg) => {
628 write!(f, "Configuration error: {}", msg)
629 }
630 GpuMemorySystemError::OptimizationFailed(msg) => {
631 write!(f, "Optimization failed: {}", msg)
632 }
633 GpuMemorySystemError::InternalError(msg) => write!(f, "Internal error: {}", msg),
634 }
635 }
636}
637
638impl std::error::Error for GpuMemorySystemError {}
639
640impl From<UnifiedGpuError> for GpuMemorySystemError {
641 fn from(err: UnifiedGpuError) -> Self {
642 GpuMemorySystemError::BackendError(err)
643 }
644}
645
646impl From<allocation::AllocationError> for GpuMemorySystemError {
647 fn from(err: allocation::AllocationError) -> Self {
648 GpuMemorySystemError::AllocationError(format!("{}", err))
649 }
650}
651
652impl From<MemoryManagementError> for GpuMemorySystemError {
653 fn from(err: MemoryManagementError) -> Self {
654 GpuMemorySystemError::ManagementError(format!("{}", err))
655 }
656}
657
658pub struct ThreadSafeGpuMemorySystem {
660 system: Arc<Mutex<GpuMemorySystem>>,
661}
662
663impl ThreadSafeGpuMemorySystem {
664 pub fn new(config: GpuMemorySystemConfig) -> Result<Self, GpuMemorySystemError> {
665 let system = GpuMemorySystem::new(config)?;
666 Ok(Self {
667 system: Arc::new(Mutex::new(system)),
668 })
669 }
670
671 pub fn allocate(
672 &self,
673 size: usize,
674 alignment: Option<usize>,
675 ) -> Result<*mut c_void, GpuMemorySystemError> {
676 let mut system = self.system.lock().unwrap();
677 system.allocate(size, alignment)
678 }
679
680 pub fn free(&self, ptr: *mut c_void) -> Result<(), GpuMemorySystemError> {
681 let mut system = self.system.lock().unwrap();
682 system.free(ptr)
683 }
684
685 pub fn get_stats(&self) -> SystemStats {
686 let mut system = self.system.lock().unwrap();
687 system.get_stats()
688 }
689
690 pub fn optimize(&self) -> Result<(), GpuMemorySystemError> {
691 let mut system = self.system.lock().unwrap();
692 system.optimize()
693 }
694}
695
696#[cfg(test)]
697mod tests {
698 use super::*;
699
700 fn create_test_config() -> GpuMemorySystemConfig {
702 let mut config = GpuMemorySystemConfig::default();
703 config.system_config.memory_budget = 0.001; if let VendorConfig::Cuda(ref mut cuda_config) = config.vendor_config {
707 cuda_config.enable_memory_pools = false;
708 }
709 config
710 }
711
712 #[test]
713 fn test_system_creation() {
714 let config = create_test_config();
715 let system = GpuMemorySystem::new(config);
716 assert!(system.is_ok() || system.is_err());
718 }
719
720 #[test]
721 fn test_auto_create() {
722 let system = GpuMemorySystem::auto_create();
724 assert!(system.is_ok() || system.is_err());
725 }
726
727 #[test]
728 fn test_thread_safe_wrapper() {
729 let config = create_test_config();
730 let system = ThreadSafeGpuMemorySystem::new(config);
731 assert!(system.is_ok() || system.is_err());
733 }
734
735 #[test]
736 fn test_allocator_selection() {
737 let config = create_test_config();
738 if let Ok(system) = GpuMemorySystem::new(config) {
740 assert_eq!(system.choose_allocator(512), AllocatorType::Slab);
741 assert_eq!(system.choose_allocator(64 * 1024), AllocatorType::Buddy);
742 assert_eq!(
743 system.choose_allocator(2 * 1024 * 1024),
744 AllocatorType::Arena
745 );
746 }
747 }
748}