pub struct BufferHandle { /* private fields */ }Expand description
A declaration of a buffer’s size, alignment, device location, and sync mode.
A BufferHandle is the in-memory representation of the 16-byte buffer
handle entry in the tensor descriptor’s buffer table (see
docs/spec/metadata.md § Buffer Table). It carries the metadata needed to
locate and access a buffer but does not itself hold a pointer — the actual
memory address is communicated out-of-band via the interchange protocol or
the C ABI (see docs/impl/c-ffi.md).
§Wire layout (ADR-018 § 3, ADR-020)
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | byte_size | uint64 LE | 8 |
| 8 | alignment | uint32 LE | 4 |
| 12 | device_tag | uint8 | 1 |
| 13 | sync_mode | uint8 | 1 |
| 14 | memory_class | uint8 | 1 |
| 15 | _reserved | uint8 | 1 |
§Alignment rules
alignmentMUST be a power of two.- For non-empty buffers (
byte_size > 0):alignmentMUST be at leastMIN_BUFFER_ALIGNMENT(64 bytes). - For empty buffers (
byte_size == 0): any power-of-two alignment is valid, including1. A reader MUST NOT dereference the pointer of an empty buffer.
See docs/spec/buffer-protocol.md § Alignment for the normative rules.
§Examples
use hurray_core::{BufferHandle, DeviceTag, MemoryClass, SyncMode, MIN_BUFFER_ALIGNMENT};
// Non-empty CPU buffer, minimum SIMD alignment, default Standard class.
let handle = BufferHandle::new(1024, MIN_BUFFER_ALIGNMENT, DeviceTag::Cpu, SyncMode::ProducerSynced).unwrap();
assert_eq!(handle.byte_size(), 1024);
assert_eq!(handle.alignment(), 64);
assert_eq!(handle.device_tag(), DeviceTag::Cpu);
assert_eq!(handle.sync_mode(), SyncMode::ProducerSynced);
assert_eq!(handle.memory_class(), MemoryClass::Standard);
assert!(!handle.is_empty());
// CUDA buffer with Unified memory class.
let unified = BufferHandle::with_memory_class(
4096, 4096, DeviceTag::Cuda, SyncMode::ProducerSynced, MemoryClass::Unified,
).unwrap();
assert_eq!(unified.memory_class(), MemoryClass::Unified);
// Empty buffer — alignment 1 is valid.
let empty = BufferHandle::empty(DeviceTag::Cuda);
assert!(empty.is_empty());
assert_eq!(empty.alignment(), 1);Implementations§
Source§impl BufferHandle
impl BufferHandle
Sourcepub fn new(
byte_size: u64,
alignment: u32,
device_tag: DeviceTag,
sync_mode: SyncMode,
) -> Result<Self>
pub fn new( byte_size: u64, alignment: u32, device_tag: DeviceTag, sync_mode: SyncMode, ) -> Result<Self>
Creates a new BufferHandle with the given size, alignment, device, and sync mode.
§Errors
Error::AlignmentNotPowerOfTwo—alignmentis not a power of two.Error::AlignmentBelowMinimum—byte_size > 0andalignmentis less thanMIN_BUFFER_ALIGNMENT(64).Error::InvalidSyncMode—device_tagisDeviceTag::Cpuandsync_modeis notSyncMode::ProducerSynced(CPU buffers MUST useSYNC_PRODUCER_SYNCEDper the spec).
§Examples
use hurray_core::{BufferHandle, DeviceTag, Error, SyncMode, MIN_BUFFER_ALIGNMENT};
// Valid: non-empty CPU buffer with minimum SIMD alignment.
assert!(BufferHandle::new(512, 64, DeviceTag::Cpu, SyncMode::ProducerSynced).is_ok());
// Valid: CUDA buffer with Event sync.
assert!(BufferHandle::new(512, 64, DeviceTag::Cuda, SyncMode::Event).is_ok());
// Valid: empty buffer with alignment 1.
assert!(BufferHandle::new(0, 1, DeviceTag::Cpu, SyncMode::ProducerSynced).is_ok());
// Error: alignment is not a power of two.
assert!(matches!(
BufferHandle::new(512, 3, DeviceTag::Cpu, SyncMode::ProducerSynced),
Err(Error::AlignmentNotPowerOfTwo { alignment: 3 })
));
// Error: non-empty buffer with alignment below the 64-byte minimum.
assert!(matches!(
BufferHandle::new(512, 32, DeviceTag::Cpu, SyncMode::ProducerSynced),
Err(Error::AlignmentBelowMinimum { alignment: 32, minimum: 64 })
));
// Error: CPU buffer with non-ProducerSynced mode.
assert!(matches!(
BufferHandle::new(512, 64, DeviceTag::Cpu, SyncMode::Event),
Err(Error::InvalidSyncMode(0x01))
));Sourcepub fn with_memory_class(
byte_size: u64,
alignment: u32,
device_tag: DeviceTag,
sync_mode: SyncMode,
memory_class: MemoryClass,
) -> Result<Self>
pub fn with_memory_class( byte_size: u64, alignment: u32, device_tag: DeviceTag, sync_mode: SyncMode, memory_class: MemoryClass, ) -> Result<Self>
Creates a new BufferHandle with an explicit memory class.
Identical to BufferHandle::new but accepts a MemoryClass value.
Use this constructor when the buffer’s memory class is not MemoryClass::Standard
(e.g., CUDA managed memory, Metal shared storage, or peer-to-peer memory).
§Errors
Error::AlignmentNotPowerOfTwo—alignmentis not a power of two.Error::AlignmentBelowMinimum—byte_size > 0andalignment < 64.Error::InvalidSyncMode—device_tagisDeviceTag::Cpuandsync_modeis notSyncMode::ProducerSynced.
§Examples
use hurray_core::{BufferHandle, DeviceTag, MemoryClass, SyncMode};
// CUDA unified (managed) memory buffer.
let handle = BufferHandle::with_memory_class(
4096, 4096, DeviceTag::Cuda, SyncMode::ProducerSynced, MemoryClass::Unified,
).unwrap();
assert_eq!(handle.memory_class(), MemoryClass::Unified);
// CPU host-pinned buffer.
let pinned = BufferHandle::with_memory_class(
512, 64, DeviceTag::Cpu, SyncMode::ProducerSynced, MemoryClass::HostPinned,
).unwrap();
assert_eq!(pinned.memory_class(), MemoryClass::HostPinned);Sourcepub fn empty(device_tag: DeviceTag) -> Self
pub fn empty(device_tag: DeviceTag) -> Self
Creates an empty BufferHandle (zero bytes) on the given device.
The alignment is set to 1 — the minimum valid power-of-two for an
empty buffer — and sync_mode is always SyncMode::ProducerSynced.
This constructor is infallible.
§Examples
use hurray_core::{BufferHandle, DeviceTag, SyncMode};
let handle = BufferHandle::empty(DeviceTag::Cpu);
assert!(handle.is_empty());
assert_eq!(handle.byte_size(), 0);
assert_eq!(handle.alignment(), 1);
assert_eq!(handle.device_tag(), DeviceTag::Cpu);
assert_eq!(handle.sync_mode(), SyncMode::ProducerSynced);Sourcepub fn byte_size(self) -> u64
pub fn byte_size(self) -> u64
Returns the size of the buffer in bytes.
A value of 0 denotes an empty buffer whose backing pointer MUST NOT
be dereferenced.
§Examples
use hurray_core::{BufferHandle, DeviceTag, SyncMode};
let handle = BufferHandle::new(4096, 4096, DeviceTag::Cuda, SyncMode::Event).unwrap();
assert_eq!(handle.byte_size(), 4096);Sourcepub fn alignment(self) -> u32
pub fn alignment(self) -> u32
Returns the minimum alignment of the buffer’s base address in bytes.
Always a power of two. For non-empty buffers, always at least
MIN_BUFFER_ALIGNMENT.
§Examples
use hurray_core::{BufferHandle, DeviceTag, SyncMode, PAGE_ALIGNMENT};
let handle = BufferHandle::new(8192, PAGE_ALIGNMENT, DeviceTag::Cuda, SyncMode::Event).unwrap();
assert_eq!(handle.alignment(), 4096);Sourcepub fn device_tag(self) -> DeviceTag
pub fn device_tag(self) -> DeviceTag
Sourcepub fn sync_mode(self) -> SyncMode
pub fn sync_mode(self) -> SyncMode
Returns the SyncMode describing the producer–consumer ordering guarantee
for this buffer.
§Examples
use hurray_core::{BufferHandle, DeviceTag, SyncMode};
let handle = BufferHandle::new(1024, 64, DeviceTag::Cuda, SyncMode::ConsumerStream).unwrap();
assert_eq!(handle.sync_mode(), SyncMode::ConsumerStream);
// CPU buffers are always ProducerSynced.
let cpu = BufferHandle::new(1024, 64, DeviceTag::Cpu, SyncMode::ProducerSynced).unwrap();
assert_eq!(cpu.sync_mode(), SyncMode::ProducerSynced);Sourcepub fn memory_class(self) -> MemoryClass
pub fn memory_class(self) -> MemoryClass
Returns the MemoryClass describing how this buffer is accessible.
§Examples
use hurray_core::{BufferHandle, DeviceTag, MemoryClass, SyncMode};
// new() defaults to Standard.
let handle = BufferHandle::new(1024, 64, DeviceTag::Cuda, SyncMode::ProducerSynced).unwrap();
assert_eq!(handle.memory_class(), MemoryClass::Standard);
// with_memory_class() sets an explicit class.
let unified = BufferHandle::with_memory_class(
1024, 64, DeviceTag::Cuda, SyncMode::ProducerSynced, MemoryClass::Unified,
).unwrap();
assert_eq!(unified.memory_class(), MemoryClass::Unified);Sourcepub fn is_empty(self) -> bool
pub fn is_empty(self) -> bool
Returns true if this buffer has zero bytes (byte_size == 0).
Readers MUST NOT dereference the pointer of an empty buffer. In C ABI contexts an empty buffer MAY be represented by a null pointer.
§Examples
use hurray_core::{BufferHandle, DeviceTag, SyncMode};
assert!(BufferHandle::empty(DeviceTag::Cpu).is_empty());
assert!(!BufferHandle::new(1, 64, DeviceTag::Cpu, SyncMode::ProducerSynced).unwrap().is_empty());Trait Implementations§
Source§impl Clone for BufferHandle
impl Clone for BufferHandle
Source§fn clone(&self) -> BufferHandle
fn clone(&self) -> BufferHandle
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more