allocate_aligned_bytes
→std::shared_ptr<std::byte[]>int allocate_aligned_bytes(int nbytes, Device device)Allocates an aligned, optionally-pooled byte buffer of nbytes.
The returned shared_ptr<std::byte[]> owns the block via a custom
deleter that either (a) returns the block to the thread-local pool —
for CPU allocations up to 4 MB whose class still has free slots — or
(b) calls std::free directly, for large allocations, full pool
slots, and non-CPU devices. In both paths the deleter also fires the
matching MemoryTracker::track_free hook.
On every successful allocation the matching
MemoryTracker::track_alloc hook is fired, so per-device
counters stay in sync with the live byte total.
Parameters
nbytesstd::size_t0 returns an empty shared_ptr (no allocation, no tracker update).deviceDevice= NoneMemoryTracker counter bank is updated and (b) whether the pool path is taken — only Device::CPU is poolable. Defaults to Device::CPU.Returns
std::shared_ptr<std::byte[]>Owning handle to a kCpuAlignment-aligned byte buffer at least nbytes long. Empty when nbytes == 0. The capacity may exceed nbytes for pooled allocations (rounded up to the next power of two ≥ kCpuAlignment).
Raises
OutOfMemoryposix_memalign failed. The exception carries the requested size, the current live bytes, and the historical peak for the target device so the caller can format an informative message.Notes
The pool is thread-local, so allocation and deallocation are lock-free on the fast path. Cached blocks are released when the owning thread exits. Blocks freed on a different thread than the one that allocated them still work correctly, but they will be returned to the freeing thread's pool — long-running thread-pool workloads with cross-thread tensor ownership may therefore observe slight imbalance in retained free-list size.
Examples
auto block = allocate_aligned_bytes(1024); // CPU, pooled
auto huge = allocate_aligned_bytes(64 << 20); // CPU, bypass pool
auto gpu = allocate_aligned_bytes(N, Device::GPU); // GPU, tracker only