Module Spoc_core.Memory

Pure element-size helper

val bigarray_elem_size : 'a 'b. ('a, 'b) Stdlib.Bigarray.kind -> int

Byte size of each Bigarray element kind on a 64-bit target. Replaces Ctypes_static.sizeof (Ctypes.typ_of_bigarray_kind kind) so that the numeric-only path is free of ctypes. Sizes are identical to what ctypes sizeof returns on 64-bit: the underlying C representation widths.

Host bigarray -> raw pointer

val borrow_bigarray_ptr : 'a 'b. ('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t -> unit Ctypes.ptr

Data pointer of a host bigarray, valid only while ba is reachable.

Ctypes.bigarray_start cannot be used for f16: ctypes maps a Bigarray.kind to its own Ctypes_bigarray.kind GADT, and that mapping has no Float16 arm (it ends in failwith "Unsupported bigarray kind"). For f16 the pointer is built over Ctypes_bigarray.unsafe_address, the kind-independent Caml_ba_data_val; every other kind keeps the bigarray_start path.

GC roots. bigarray_start returns a MANAGED fat pointer whose value roots the bigarray; ctypes' FFI keeps that root alive across a call. A managed pointer with an arbitrary root can only be built through Obj, so the f16 pointer here is UNMANAGED: it does not root ba, and an FFI call holding only that pointer can see ba freed mid-call. The pointer returned here therefore carries an obligation for every kind: the caller keeps ba (or the vector that owns it) reachable for as long as the pointer, or any nativeint taken from it, is in use. On transfer paths that is a trailing ignore (Sys.opaque_identity ba) after the FFI call: ba is then live across the call, and if the call raises it has already returned from C, so no use of the address remains.

val with_bigarray_ptr : 'a 'b 'r. ('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t -> (unit Ctypes.ptr -> 'r) -> 'r

with_bigarray_ptr ba f calls f with the data pointer of ba. ba stays reachable until f returns, on every element kind, so a synchronous FFI call made inside f may read or write through the pointer. The pointer must not be used after f returns: an asynchronous consumer of the address needs its own root. A capturing f costs a closure allocation per call, so transfer paths use borrow_bigarray_ptr with a trailing Sys.opaque_identity instead; this helper is for cold paths such as buffer allocation.

Buffer Module Type

How a device buffer relates to the host storage of its vector.

module type BUFFER = sig ... end

A buffer packages backend-specific buffer with its operations. All transfers use raw pointers with byte sizes to avoid type parameter escaping issues in first-class modules.

val unwrap_stream_for : backend:string -> (Spoc_framework.Framework_sig.stream_ref -> 's option) -> Spoc_framework.Framework_sig.stream_ref option -> 's option

Unwrap a core stream handle for backend backend; a handle from another backend is a caller error, refused rather than ignored.

type _ buffer =
  1. | Buffer : (module BUFFER) -> 'a buffer

Buffer with phantom type parameter for element type safety. The 'a parameter is not used at runtime but ensures type-safe transfers.

Allocation

val alloc : Device.t -> int -> ('a, 'b) Stdlib.Bigarray.kind -> 'a buffer

Allocate a buffer on a device for standard Bigarray types

val alloc_custom : Device.t -> size:int -> elem_size:int -> 'a buffer

Allocate a buffer for custom types with explicit element size in bytes

Buffer Operations

val free : 'a. 'a buffer -> unit

Free a buffer

val checked_host_copy_bytes : 'a 'b. op:string -> ba:('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t -> buffer_elem_size:int -> buffer_size:int -> int

Size a bigarray<->buffer copy from the bigarray's own bytes. 'a buffer only fixes the OCaml element type, so a float32 bigarray type-checks against a float64 buffer; sizing the copy as dim x buffer elem_size then reads or writes past the bigarray. Refused (Invalid_argument) when the element sizes differ or the bigarray holds more bytes than the buffer.

val host_to_device : 'a 'b. src:('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t -> dst:'a buffer -> unit

Copy data from host bigarray to device. Converts bigarray to pointer internally. The type parameter fixes only the OCaml element type; the copy is sized from the bigarray's bytes and Invalid_argument is raised if its element size differs from the buffer's or it exceeds the buffer.

val device_to_host : 'a 'b. src:'a buffer -> dst:('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t -> unit

Copy data from device to host bigarray. Converts bigarray to pointer internally. The type parameter fixes only the OCaml element type; the copy is sized from the bigarray's bytes and Invalid_argument is raised if its element size differs from the buffer's or it exceeds the buffer.

val host_ptr_to_device : 'a. src_ptr:unit Ctypes.ptr -> dst:'a buffer -> unit

Copy data from raw pointer to device buffer (for custom types). The memory behind src_ptr must stay allocated until the call returns: the copy runs with the OCaml runtime lock released, so other domains (and their GC) run meanwhile. src_ptr itself is kept reachable across the call, which keeps memory it manages (ctypes allocate, a bigarray it was taken from with ctypes) alive; memory it merely points to is the caller's to keep.

val device_to_host_ptr : 'a. src:'a buffer -> dst_ptr:unit Ctypes.ptr -> unit

Copy data from device buffer to raw pointer (for custom types). Same lifetime rule as host_ptr_to_device, for dst_ptr.

val device_to_device : 'a. src:'a buffer -> dst:'a buffer -> unit

Copy data between device buffers (same device). The type parameter fixes only the OCaml element type; Invalid_argument is raised if the element sizes differ or the source holds more bytes than the destination.

Accessors

val size : 'a. 'a buffer -> int

Get buffer size in elements

val elem_size : 'a. 'a buffer -> int

Get buffer element size in bytes

val device : 'a. 'a buffer -> Device.t

Get buffer device

val device_ptr : 'a. 'a buffer -> nativeint

Get raw device pointer

val bind_to_kargs : 'a. 'a buffer -> Spoc_framework.Framework_sig.kargs -> int -> unit

Bind buffer to kernel args