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
impl StagingBuffer
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates an empty staging buffer. No host memory is pinned until the
first transfer (or an explicit reserve).
Sourcepub fn with_capacity(bytes: usize) -> CudaResult<Self>
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
CudaError::InvalidValueifbytesis zero.- Other driver errors from
cuMemAllocHost_v2.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the current pinned capacity in bytes (0 before first use).
Sourcepub fn stats(&self) -> StagingStats
pub fn stats(&self) -> StagingStats
Returns the usage counters. See StagingStats.
Sourcepub fn auto_stage_max_bytes(&self) -> usize
pub fn auto_stage_max_bytes(&self) -> usize
Sourcepub fn set_auto_stage_max_bytes(&mut self, bytes: usize)
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.
Sourcepub fn reserve(&mut self, bytes: usize) -> CudaResult<()>
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::InvalidValueifbytesis zero, or if rounding overflowsusize.- Other driver errors from
cuMemAllocHost_v2.
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Releases the pinned allocation, returning capacity to 0.
Counters are preserved. The next transfer re-pins.
Sourcepub fn upload_with<T, F>(
&mut self,
dst: &mut DeviceBuffer<T>,
n: usize,
stream: &Stream,
fill: F,
) -> CudaResult<()>
pub fn upload_with<T, F>( &mut self, dst: &mut DeviceBuffer<T>, n: usize, stream: &Stream, fill: F, ) -> CudaResult<()>
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::InvalidValueifnis zero, ifn != dst.len(), if the byte size overflows, or if the pinned allocation is not aligned forT.- Other driver errors from
cuMemAllocHost_v2orcuMemcpyHtoDAsync_v2.
Sourcepub fn download_into<T: StagingPod>(
&mut self,
src: &DeviceBuffer<T>,
n: usize,
stream: &Stream,
) -> CudaResult<&[T]>
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::InvalidValueifnis zero, ifn != src.len(), if the byte size overflows, or if the pinned allocation is not aligned forT.- Other driver errors from
cuMemAllocHost_v2orcuMemcpyDtoHAsync_v2.
Sourcepub fn upload<T: StagingPod>(
&mut self,
dst: &mut DeviceBuffer<T>,
src: &[T],
stream: &Stream,
) -> CudaResult<()>
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::InvalidValueifsrcis empty orsrc.len() != dst.len().- Other driver errors from the allocation or copy.
Sourcepub fn download<T: StagingPod>(
&mut self,
dst: &mut [T],
src: &DeviceBuffer<T>,
stream: &Stream,
) -> CudaResult<()>
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::InvalidValueifdstis empty ordst.len() != src.len().- Other driver errors from the allocation or copy.