Skip to main content

StagingBuffer

Struct StagingBuffer 

Source
pub struct StagingBuffer { /* private fields */ }
Expand description

A grow-on-demand, reused page-locked host buffer used to stage transfers.

See the module documentation for the performance model and for which method to reach for.

Implementations§

Source§

impl StagingBuffer

Source

pub const fn new() -> Self

Creates an empty staging buffer. No host memory is pinned until the first transfer (or an explicit reserve).

Source

pub fn with_capacity(bytes: usize) -> CudaResult<Self>

Creates a staging buffer with bytes of pinned host memory already allocated.

Pre-sizing at start-up (to the largest tensor a pipeline will move) keeps the millisecond-scale cuMemAllocHost_v2 out of the steady-state loop entirely.

§Errors
Source

pub fn capacity(&self) -> usize

Returns the current pinned capacity in bytes (0 before first use).

Source

pub fn stats(&self) -> StagingStats

Returns the usage counters. See StagingStats.

Source

pub fn auto_stage_max_bytes(&self) -> usize

Returns the size above which upload / download bypass staging.

Source

pub fn set_auto_stage_max_bytes(&mut self, bytes: usize)

Overrides the auto-select threshold (see DEFAULT_AUTO_STAGE_MAX_BYTES for how it was calibrated).

Affects only the slice-taking wrappers; upload_with and download_into always stage, because for those the pinned buffer is the caller’s working memory and there is no extra copy to regret.

Source

pub fn reserve(&mut self, bytes: usize) -> CudaResult<()>

Ensures at least bytes of pinned host memory are available.

Grow-only: a request smaller than the current capacity is a no-op, so a pipeline cycling through several tensor shapes settles at the high-water mark and never re-pins again. Growth rounds up to CAPACITY_GRANULARITY.

Any previously staged contents are discarded when the buffer grows.

§Errors
  • CudaError::InvalidValue if bytes is zero, or if rounding overflows usize.
  • Other driver errors from cuMemAllocHost_v2.
Source

pub fn shrink_to_fit(&mut self)

Releases the pinned allocation, returning capacity to 0.

Counters are preserved. The next transfer re-pins.

Source

pub fn upload_with<T, F>( &mut self, dst: &mut DeviceBuffer<T>, n: usize, stream: &Stream, fill: F, ) -> CudaResult<()>
where T: StagingPod, F: FnOnce(&mut [T]),

Uploads n elements to dst, letting fill write them directly into page-locked memory.

This is the fastest host→device path this crate offers (measured 1.55x–1.75x over DeviceBuffer::copy_from_host across 150 KiB–4.7 MiB) because the bytes fill writes are the exact bytes the DMA engine reads: there is no pageable source slice and no driver bounce buffer.

fill receives a mutable slice of exactly n elements and is expected to write all of them; anything left untouched keeps whatever the previous transfer through this buffer left there (or zeroes, on a freshly pinned allocation), and that content is uploaded as-is.

The copy is enqueued on stream — so it is ordered after work already queued there — and this call returns only once it has landed.

§Errors
  • CudaError::InvalidValue if n is zero, if n != dst.len(), if the byte size overflows, or if the pinned allocation is not aligned for T.
  • Other driver errors from cuMemAllocHost_v2 or cuMemcpyHtoDAsync_v2.
Source

pub fn download_into<T: StagingPod>( &mut self, src: &DeviceBuffer<T>, n: usize, stream: &Stream, ) -> CudaResult<&[T]>

Downloads n elements from src into page-locked memory and returns a borrowed view of them, with no copy out.

This is the fastest device→host path this crate offers (measured 1.77x–2.67x over DeviceBuffer::copy_to_host): the DMA engine writes straight into the memory the caller then reads. The returned slice borrows self and stays valid until the next call that touches the staging buffer.

The copy is enqueued on stream, so it observes the results of work already queued there; this call returns only once the data has landed and is safe to read.

§Errors
  • CudaError::InvalidValue if n is zero, if n != src.len(), if the byte size overflows, or if the pinned allocation is not aligned for T.
  • Other driver errors from cuMemAllocHost_v2 or cuMemcpyDtoHAsync_v2.
Source

pub fn upload<T: StagingPod>( &mut self, dst: &mut DeviceBuffer<T>, src: &[T], stream: &Stream, ) -> CudaResult<()>

Uploads src into dst, staging through pinned memory when that is actually faster.

A drop-in replacement for DeviceBuffer::copy_from_host with the same postcondition (the data has landed on the device when this returns) that is never slower: transfers up to auto_stage_max_bytes go through the pinned buffer, larger ones go straight to the driver’s pageable path, which pipelines better than a host memcpy into pinned memory can (see the module table).

If you control how src is produced, prefer upload_with — writing the data into pinned memory in the first place removes this method’s memcpy and wins at every size.

Ordered against stream in both paths.

§Errors
  • CudaError::InvalidValue if src is empty or src.len() != dst.len().
  • Other driver errors from the allocation or copy.
Source

pub fn download<T: StagingPod>( &mut self, dst: &mut [T], src: &DeviceBuffer<T>, stream: &Stream, ) -> CudaResult<()>

Downloads src into dst, staging through pinned memory when that is actually faster.

A drop-in replacement for DeviceBuffer::copy_to_host that is never slower; the mirror of upload, including the auto-select threshold. Prefer download_into when the caller can consume the results in place.

Unlike a bare DeviceBuffer::copy_to_host, both paths here are ordered against stream, so results produced by kernels on stream are guaranteed visible without the caller synchronising first.

§Errors
  • CudaError::InvalidValue if dst is empty or dst.len() != src.len().
  • Other driver errors from the allocation or copy.

Trait Implementations§

Source§

impl Default for StagingBuffer

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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