pub struct MemoryTracker { /* private fields */ }Expand description
Memory usage tracker for GPU operations.
Tracks allocated and peak memory usage across operations. Thread-safe via atomics.
§Why This Struct
Unlike CPU memory which is managed by the OS, GPU memory requires explicit tracking because:
- No swap: When VRAM runs out, allocations fail immediately
- Fragmentation: Repeated allocations can fragment the heap
- Debugging: Memory leaks on GPU are harder to diagnose than CPU leaks
§Usage Pattern
use rust_ai_core::MemoryTracker;
let tracker = MemoryTracker::new();
// Before allocation
tracker.allocate(1024 * 1024).expect("allocation should succeed"); // 1 MB
// After freeing
tracker.deallocate(1024 * 1024);
println!("Peak usage: {} bytes", tracker.peak_bytes());Implementations§
Source§impl MemoryTracker
impl MemoryTracker
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new memory tracker with no limit.
§Why No Default Limit
Different GPUs have vastly different VRAM capacities (4GB to 80GB+). Setting a default limit would either be too restrictive for high-end cards or meaningless for consumer cards. Users should set limits explicitly.
Sourcepub fn with_limit(limit_bytes: usize) -> Self
pub fn with_limit(limit_bytes: usize) -> Self
Create a tracker with a memory limit.
§Arguments
limit_bytes- Maximum allowed allocation in bytes
§Why Memory Limits
Setting a limit below actual VRAM capacity reserves space for:
- CUDA context overhead (~200-500 MB)
- Framework allocations (PyTorch/Candle tensor cache)
- Other processes sharing the GPU
Sourcepub fn with_overhead_factor(self, factor: f64) -> Self
pub fn with_overhead_factor(self, factor: f64) -> Self
Set a custom overhead factor for estimates.
§Arguments
factor- Multiplier applied to estimates (default: 1.1)
Sourcepub fn allocate(&self, bytes: usize) -> Result<()>
pub fn allocate(&self, bytes: usize) -> Result<()>
Record a memory allocation.
§Arguments
bytes- Number of bytes allocated
§Returns
Ok(()) if allocation is within limits.
§Errors
Returns CoreError::OutOfMemory if allocation would exceed the limit.
§Why Track Allocations
Explicit tracking catches memory issues early. Without tracking, OOM errors occur deep in CUDA kernels with unhelpful error messages.
Sourcepub fn deallocate(&self, bytes: usize)
pub fn deallocate(&self, bytes: usize)
Sourcepub fn allocated_bytes(&self) -> usize
pub fn allocated_bytes(&self) -> usize
Get currently allocated bytes.
Sourcepub fn peak_bytes(&self) -> usize
pub fn peak_bytes(&self) -> usize
Get peak allocation during tracker lifetime.
§Why Track Peak
Peak usage is more useful than current usage for capacity planning. It shows the high-water mark needed to complete a workload.
Sourcepub fn limit_bytes(&self) -> usize
pub fn limit_bytes(&self) -> usize
Get configured memory limit (0 = unlimited).
Sourcepub fn estimate_with_overhead(&self, shape: &[usize], dtype: DType) -> usize
pub fn estimate_with_overhead(&self, shape: &[usize], dtype: DType) -> usize
Trait Implementations§
Source§impl Debug for MemoryTracker
impl Debug for MemoryTracker
Auto Trait Implementations§
impl !Freeze for MemoryTracker
impl RefUnwindSafe for MemoryTracker
impl Send for MemoryTracker
impl Sync for MemoryTracker
impl Unpin for MemoryTracker
impl UnwindSafe for MemoryTracker
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more