Skip to main content

MemoryTracker

Struct MemoryTracker 

Source
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:

  1. No swap: When VRAM runs out, allocations fail immediately
  2. Fragmentation: Repeated allocations can fragment the heap
  3. 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

Source

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.

Source

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
Source

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)
Source

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.

Source

pub fn deallocate(&self, bytes: usize)

Record a memory deallocation.

§Arguments
  • bytes - Number of bytes freed
Source

pub fn allocated_bytes(&self) -> usize

Get currently allocated bytes.

Source

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.

Source

pub fn limit_bytes(&self) -> usize

Get configured memory limit (0 = unlimited).

Source

pub fn estimate_with_overhead(&self, shape: &[usize], dtype: DType) -> usize

Estimate required memory with overhead factor applied.

§Arguments
  • shape - Tensor dimensions
  • dtype - Data type
§Returns

Estimated bytes including overhead buffer.

Source

pub fn would_fit(&self, bytes: usize) -> bool

Check if an allocation would fit within limits.

§Arguments
  • bytes - Proposed allocation size
§Returns

true if allocation would succeed.

Source

pub fn reset(&self)

Reset the tracker to initial state.

§Why Reset

Between training epochs or inference batches, resetting allows tracking per-phase memory usage without creating new tracker instances.

Trait Implementations§

Source§

impl Debug for MemoryTracker

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for MemoryTracker

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,