Spoc_core.Vectorinclude module type of struct include Vector_types endinclude sig ... endtype (!'a, !'b) scalar_kind = | Float16 : (float, Stdlib.Bigarray.float16_elt) scalar_kind| Float32 : (float, Stdlib.Bigarray.float32_elt) scalar_kind| Float64 : (float, Stdlib.Bigarray.float64_elt) scalar_kind| Int32 : (int32, Stdlib.Bigarray.int32_elt) scalar_kind| Int64 : (int64, Stdlib.Bigarray.int64_elt) scalar_kind| Char : (char, Stdlib.Bigarray.int8_unsigned_elt) scalar_kind| Complex32 : (Stdlib.Complex.t, Stdlib.Bigarray.complex32_elt) scalar_kindtype location = Spoc_core_base.Make(Ctypes_ops).location = | CPU| GPU of Ctypes_ops.device_t| Both of Ctypes_ops.device_t| Stale_CPU of Ctypes_ops.device_t| Stale_GPU of Ctypes_ops.device_ttype !'a custom_type = 'a Spoc_core_base.Make(Ctypes_ops).custom_type = {elem_size : int;type_id : 'a Sarek_ir_types.Type_id.t;vector_type_id : ('a, unit) t Sarek_ir_types.Type_id.t;get : Ctypes_ops.handle -> int -> 'a;set : Ctypes_ops.handle -> int -> 'a -> unit;name : string;ir_fields : (string * Sarek_ir_types.elttype) list option;}and (!'c, !'d) kind = ('c, 'd) Spoc_core_base.Make(Ctypes_ops).kind = | Scalar : ('a, 'b) scalar_kind -> ('a, 'b) kind| Custom : 'a0 custom_type -> ('a0, unit) kindand (!'c, !'d) host_storage =
('c, 'd) Spoc_core_base.Make(Ctypes_ops).host_storage =
| Bigarray_storage : ('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t ->
('a, 'b)
host_storage| Custom_storage : {ptr : Ctypes_ops.handle;custom : 'a0 custom_type;length : int;} -> ('a0, unit) host_storageand soa_binding = Spoc_core_base.Make(Ctypes_ops).soa_binding = {soa_num_leaves : int;soa_aos_stride : int;soa_scatter : unit -> unit;soa_gather : unit -> unit;soa_to_device : Ctypes_ops.device_t -> unit;soa_leaf_bufs : Ctypes_ops.device_t -> Ctypes_ops.device_buf list;soa_from_device : Ctypes_ops.device_t -> unit;soa_free_leaves : Ctypes_ops.device_t option -> unit;soa_leaves_live : bool Stdlib.ref;}and (!'a, !'b) t = ('a, 'b) Spoc_core_base.Make(Ctypes_ops).t = {host : ('a, 'b) host_storage;device_buffers : (int, Ctypes_ops.device_buf) Stdlib.Hashtbl.t;length : int;kind : ('a, 'b) kind;mutable location : location;mutable auto_sync : bool;id : int;mutable soa : soa_binding option;}val to_bigarray_kind : ('a, 'b) scalar_kind -> ('a, 'b) Stdlib.Bigarray.kindval scalar_elem_size : ('a, 'b) scalar_kind -> intval elem_size : ('a, 'b) kind -> intval scalar_kind_name : ('a, 'b) scalar_kind -> stringval kind_name : ('a, 'b) kind -> stringval float16_type_id : float Sarek_ir_types.Type_id.tval float32_type_id : float Sarek_ir_types.Type_id.tval float64_type_id : float Sarek_ir_types.Type_id.tval int32_type_id : int32 Sarek_ir_types.Type_id.tval int64_type_id : int64 Sarek_ir_types.Type_id.tval char_type_id : char Sarek_ir_types.Type_id.tval complex32_type_id : Stdlib.Complex.t Sarek_ir_types.Type_id.tval scalar_type_id : ('a, 'b) scalar_kind -> 'a Sarek_ir_types.Type_id.tval type_id : ('a, 'b) kind -> 'a Sarek_ir_types.Type_id.tval float16_vector_type_id :
(float, Stdlib.Bigarray.float16_elt) t Sarek_ir_types.Type_id.tval float32_vector_type_id :
(float, Stdlib.Bigarray.float32_elt) t Sarek_ir_types.Type_id.tval float64_vector_type_id :
(float, Stdlib.Bigarray.float64_elt) t Sarek_ir_types.Type_id.tval int32_vector_type_id :
(int32, Stdlib.Bigarray.int32_elt) t Sarek_ir_types.Type_id.tval int64_vector_type_id :
(int64, Stdlib.Bigarray.int64_elt) t Sarek_ir_types.Type_id.tval char_vector_type_id :
(char, Stdlib.Bigarray.int8_unsigned_elt) t Sarek_ir_types.Type_id.tval complex32_vector_type_id :
(Stdlib.Complex.t, Stdlib.Bigarray.complex32_elt) t Sarek_ir_types.Type_id.tval vector_type_id : ('a, 'b) kind -> ('a, 'b) t Sarek_ir_types.Type_id.tval create_scalar :
('a, 'b) scalar_kind ->
?dev:Ctypes_ops.device_t ->
int ->
('a, 'b) tval create : ('a, 'b) kind -> ?dev:Ctypes_ops.device_t -> int -> ('a, 'b) tval create_custom :
'a custom_type ->
?dev:Ctypes_ops.device_t ->
int ->
('a, unit) tval of_bigarray :
('a, 'b) scalar_kind ->
('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t ->
('a, 'b) tval of_raw_handle : 'a custom_type -> nativeint -> int -> ('a, unit) tval has_buffer : ('a, 'b) t -> Ctypes_ops.device_t -> boolval get_buffer :
('a, 'b) t ->
Ctypes_ops.device_t ->
Ctypes_ops.device_buf optionval custom_to_bytes : 'a custom_type -> 'a -> bytesval custom_of_bytes : 'a custom_type -> bytes -> 'aval is_sub : ('a, 'b) t -> boolval depth : ('a, 'b) t -> intval parent_id : ('a, 'b) t -> int optionval sub_start : ('a, 'b) t -> int optionval sub_ok_range : ('a, 'b) t -> int optionval sub_ko_range : ('a, 'b) t -> int optionval partition_host :
('a, 'b) t ->
Ctypes_ops.device_t array ->
('a, 'b) t arrayval host_handle : ('a, 'b) t -> Ctypes_ops.handleval host_raw : ('a, 'b) t -> nativeintmodule type DEVICE_BUFFER = Vector_types.DEVICE_BUFFERRe-export DEVICE_BUFFER module type for backward compatibility
type device_buffer = (module DEVICE_BUFFER)Device buffer type alias
module Custom_helpers = Vector_types.Custom_helpersHelper functions for custom type implementations. These wrap Ctypes operations to provide simpler APIs for PPX-generated code.
val of_ctypes_ptr : 'a custom_type -> unit Ctypes.ptr -> int -> ('a, unit) tWrap an existing ctypes pointer as a custom-storage vector (shares memory).
val length : ('a, 'b) t -> intval id : ('a, 'b) t -> intval to_bigarray :
'a 'b. ('a, 'b) t ->
('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.tGet underlying Bigarray (only for scalar vectors)
val to_ctypes_ptr : ('a, 'b) Vector_types.t -> unit Ctypes.ptrval host_ptr : ('a, 'b) Vector_types.t -> nativeintval register_sync_callback : Vector_transfer.sync_callback -> unitval ensure_cpu_sync : ('a, 'b) Vector_types.t -> unitval get : 'a 'b. ('a, 'b) t -> int -> 'aGet element (works for both storage types). Auto-syncs from GPU if location is Stale_CPU and auto_sync is enabled.
val set : 'a 'b. ('a, 'b) t -> int -> 'a -> unitSet element (works for both storage types)
val (.%[]) : ('a, 'b) t -> int -> 'aIndexing operators
val (.%[]<-) : ('a, 'b) t -> int -> 'a -> unitval unsafe_get : 'a 'b. ('a, 'b) t -> int -> 'aval unsafe_set : 'a 'b. ('a, 'b) t -> int -> 'a -> unitval kernel_set : 'a 'b. ('a, 'b) t -> int -> 'a -> unitKernel-safe set: no bounds check, no location update, AND no staleness sync. After backlog-190 this is the only host writer exempt from the staleness handling set/unsafe_set/fill all now perform, so the exemption is stated rather than left as a difference a reader has to notice. It is deliberate: a per-element location update would race across the threads this function exists to serve, and the kernel already owns the buffer for the duration of the launch.
Use this in parallel kernel execution where:
val set_auto_sync : ('a, 'b) t -> bool -> unitTurn the implicit device->host read-back on vec on or off.
WHAT TURNING IT OFF MEANS, written here because this is where a caller turning it off will look, and because until now it was written nowhere: Vector_transfer.ensure_cpu_sync returns immediately when this is false, so every operation that relies on it stops pulling the device copy down. The caller takes over that duty; the operations do not fail, they read whatever host storage holds.
Three consequences that are not obvious from the flag's name:
get returns the HOST buffer on a Stale_CPU vector, i.e. the values from before the launch, with no error;set/unsafe_set no longer read-modify-write against a current buffer, so the element they write sits beside length - 1 stale ones and the location arm below correctly leaves the DEVICE copy authoritative;Soa_vector.scatter transposes out of that same host storage, so a launch result still sitting in the leaves is overwritten by pre-launch bytes rather than gathered first. Raised in review of PR #375; NOT changed there, because making the SoA path transfer anyway would be this flag not meaning what it says. Drain explicitly (Transfer.to_cpu ~force:true) before reusing such a vector.true is the default and the state every test in this repository runs in except where a case disables it deliberately to observe a specific transfer.
val auto_sync : ('a, 'b) t -> boolval is_on_cpu : ('a, 'b) t -> boolval is_on_gpu : ('a, 'b) t -> boolval is_synced : ('a, 'b) t -> boolval needs_gpu_update : ('a, 'b) t -> boolval needs_cpu_update : ('a, 'b) t -> boolhas_buffer and get_buffer are provided by Vector_types via the functor.
val location_to_string : location -> stringval to_string : ('a, 'b) t -> stringval float16 : (float, Stdlib.Bigarray.float16_elt) kindval float32 : (float, Stdlib.Bigarray.float32_elt) kindval float64 : (float, Stdlib.Bigarray.float64_elt) kindval int32 : (int32, Stdlib.Bigarray.int32_elt) kindval int64 : (int64, Stdlib.Bigarray.int64_elt) kindval char : (char, Stdlib.Bigarray.int8_unsigned_elt) kindval complex32 : (Stdlib.Complex.t, Stdlib.Bigarray.complex32_elt) kindval create_float16 :
?dev:Ctypes_ops.device_t ->
int ->
(float, Stdlib.Bigarray.float16_elt) tCreate an f16 vector. Elements are ordinary OCaml floats; every set rounds to IEEE binary16 (so 3.14159 reads back as 3.14062).
val create_float32 :
?dev:Ctypes_ops.device_t ->
int ->
(float, Stdlib.Bigarray.float32_elt) tval create_float64 :
?dev:Ctypes_ops.device_t ->
int ->
(float, Stdlib.Bigarray.float64_elt) tval create_int32 :
?dev:Ctypes_ops.device_t ->
int ->
(int32, Stdlib.Bigarray.int32_elt) tval create_int64 :
?dev:Ctypes_ops.device_t ->
int ->
(int64, Stdlib.Bigarray.int64_elt) tval fill : 'a 'b. ('a, 'b) t -> 'a -> unitFill vector with a value
val sub_vector :
('a, 'b) t ->
start:int ->
len:int ->
?ok_range:int ->
?ko_range:int ->
unit ->
('a, 'b) tCreate a subvector that shares CPU memory with parent.
Partition a vector across multiple devices. Creates subvectors, one per device, that together cover the full vector.
val gather : ('a, 'b) t array -> unitGather subvectors back to parent (sync all to CPU). Assumes subvectors were created by partition and don't overlap.
val iter : 'a 'b. ('a -> unit) -> ('a, 'b) t -> unitIterate over all elements (CPU-side, auto-syncs if needed)
val iteri : 'a 'b. (int -> 'a -> unit) -> ('a, 'b) t -> unitIterate with index
Map function over vector, creating new vector with given kind
Map with index
val map_inplace : 'a 'b. ('a -> 'a) -> ('a, 'b) t -> unitIn-place map (same type)
val fold_left : 'a 'b 'acc. ('acc -> 'a -> 'acc) -> 'acc -> ('a, 'b) t -> 'accFold left
val fold_right : 'a 'b 'acc. ('a -> 'acc -> 'acc) -> ('a, 'b) t -> 'acc -> 'accFold right
val for_all : 'a 'b. ('a -> bool) -> ('a, 'b) t -> boolCheck if all elements satisfy predicate
val exists : 'a 'b. ('a -> bool) -> ('a, 'b) t -> boolCheck if any element satisfies predicate
val find : 'a 'b. ('a -> bool) -> ('a, 'b) t -> 'a optionFind first element satisfying predicate
val find_index : 'a 'b. ('a -> bool) -> ('a, 'b) t -> int optionFind index of first element satisfying predicate
val sum : zero:'a -> add:('a -> 'a -> 'a) -> ('a, 'b) t -> 'aSum elements (requires + operation via fold)
val min_elt : compare:('a -> 'a -> int) -> ('a, 'b) t -> 'a optionFind minimum element
val max_elt : compare:('a -> 'a -> int) -> ('a, 'b) t -> 'a optionFind maximum element
val to_list : 'a 'b. ('a, 'b) t -> 'a listConvert to OCaml list
val to_array : 'a 'b. ('a, 'b) t -> 'a arrayConvert to OCaml array