Module Device.Buffer
Existentially-packed device buffers.
A buffer is either a base buffer (directly allocated) or a view into a base buffer at a byte offset. Views share the base buffer's backing storage.
Buffers start unallocated. Call allocate or ensure_allocated to materialise backing storage. Each buffer has a globally unique id assigned at creation. A GC finaliser calls deallocate when the buffer becomes unreachable.
Reference counting (uop_refcount, add_ref) is managed externally by the compiler runtime and is not used for deallocation.
Types
Constructors
val create :
device:string ->
size:int ->
dtype:Tolk_uop.Dtype.t ->
?spec:Buffer_spec.t ->
Allocator.packed ->
tcreate ~device ~size ~dtype ?spec allocator is an unallocated base buffer for size elements of dtype on device.
spec defaults to Buffer_spec.default.
val view : t -> size:int -> dtype:Tolk_uop.Dtype.t -> offset:int -> tview b ~size ~dtype ~offset is a view into b starting at byte offset and spanning size elements of dtype. The view shares the base buffer's allocator and spec.
Raises Invalid_argument if offset is negative, >= nbytes b, or if the resulting view extends past the root base buffer.
Identity and metadata
val id : t -> intid b is b's globally unique identifier.
val base_id : t -> intbase_id b is the unique identifier of b's root base buffer. Equal to id b when b is itself a base buffer.
val device : t -> stringdevice b is the device name b is bound to.
val size : t -> intsize b is the element count.
val dtype : t -> Tolk_uop.Dtype.tdtype b is the element dtype.
val spec : t -> Buffer_spec.tspec b is the buffer specification.
val nbytes : t -> intnbytes b is the size in bytes (size b * Dtype.itemsize (dtype b)).
val offset : t -> intoffset b is the byte offset into the base buffer. 0 for base buffers.
Allocation
val allocate : t -> unitallocate b materialises backing storage for b. For views, ensures the base buffer is allocated first, then creates the offset view via the allocator.
Raises Invalid_argument if b is already allocated, or if b is a view and the allocator does not support Allocator.t.offset.
val ensure_allocated : t -> unitensure_allocated b calls allocate if b is not yet initialised. No-op otherwise.
val is_allocated : t -> boolis_allocated b is true iff the base buffer's backing storage exists.
val is_initialized : t -> boolis_initialized b is true iff this specific buffer or view has its own storage pointer set. A view can be uninitialised even when the base buffer is allocated.
val deallocate : t -> unitdeallocate b releases backing storage if allocated. For base buffers, frees via the allocator. For views, detaches from the base buffer. No-op if already deallocated.
Raises Invalid_argument if b is a base buffer that still has allocated views.
val supports_offset : t -> boolsupports_offset b is true iff b's allocator provides offset views.
supports_transfer dst src is true iff dst's allocator provides native transfer and dst and src are on the same backend prefix (for example "METAL" for "METAL:0" and "METAL:1").
val allocator : t -> Allocator.packedallocator b is the allocator of b's base buffer.
Reference counting
val uop_refcount : t -> intuop_refcount b is the base buffer's UOp reference count.
add_ref b cnt increments the base buffer's UOp reference count by cnt and returns b.
Data transfer
val copyin : t -> bytes -> unitcopyin b src copies src into b.
Raises Invalid_argument if Bytes.length src <> nbytes b or if b is not allocated.
val copyout : t -> bytes -> unitcopyout b dst copies the contents of b into dst.
Raises Invalid_argument if Bytes.length dst <> nbytes b or if b is not allocated.
val as_bytes : t -> bytesas_bytes b is a fresh bytes value containing the contents of b. Equivalent to allocating Bytes.create (nbytes b) and calling copyout.
transfer ~dst ~src copies src into dst via dst's allocator transfer hook when supports_transfer is true. Returns true when native transfer was used and false when no transfer hook is available. Both buffers are allocated if transfer is used.
Raises Invalid_argument if dst and src differ in size or dtype.
copy_between ~dst ~src copies the contents of src into dst via a host-memory bounce buffer. Both buffers are allocated if needed.
Raises Invalid_argument if size dst <> size src or dtype dst <> dtype src.
val addr : t -> nativeintaddr b is the device address of b. Allocates b if needed.