Spoc_core.RuntimeRe-export framework dims helpers to avoid duplicate types
val dims1d : int -> Spoc_framework.Framework_sig.dimsval dims2d : int -> int -> Spoc_framework.Framework_sig.dimsval dims3d : int -> int -> int -> Spoc_framework.Framework_sig.dimsval init_device : ?framework:string -> unit -> Device.tInitialize the runtime and get the best available device
val all_devices : ?framework:string -> unit -> Device.t arrayGet all available devices
val kernel_cache : (string, Kernel.t) Spoc_framework.Guarded_cache.tOuter kernel memo, keyed by Spoc_framework.Compile_cache.make_key so this layer uses the same key shape as the per-backend caches underneath it — not the same key. Their device component is the backend-local device index; this layer spans backends, so its device component must be globally unique and is built from the global Device.t.id (see compile_kernel). That difference is why Device.reset, which retires the global id space without perturbing any backend-local one, has to drop this layer and only this one. Guarded against concurrent multi-domain access by Spoc_framework.Guarded_cache (this is the cross-backend entry point most multi-domain code hits).
The key MUST include device identity. Device.t.framework is the backend name, shared by every device of that backend, so keying on it alone aliases all of them — and Kernel.compile_cached closes the specific backend kernel into the Kernel.t it returns, so a hit would hand device B a kernel built for device A and silently produce wrong results.
destroy is a no-op because the backend handles are owned by the per-backend caches reached through Kernel.compile_cached — this layer holds only memoization and must never release anything. That does NOT make this layer safe to leave alone during teardown: those backend caches release the handles these Kernel.t closures capture, so the layer has to be dropped whenever they are (see the Cache_hooks registrations below).
For the same reason the cache is created ~invalidated_by_clear:true: its values BORROW the backend caches' handles, so a build still in flight when a clear runs closes over a handle the clear releases, and installing it afterwards would poison the memo for the rest of the process.
val device_is_of_backend : backend:Stdlib.String.t -> Device.t -> boolDoes global device d belong to the backend family backend? Backends register either under the family name ("HIP") or as a "<family>/<variant>" refinement of it ("CUDA/PTX", "CUDA/C"), and a single backend API module can back several of those, so both spellings must match. Mirrors Device.resolve_framework.
Compile a kernel from source, with caching.
val set_args : Device.t -> arg list -> Kernel.argsCreate arguments from a list
val run_kernel :
Kernel.t ->
args:Kernel.args ->
grid:dims ->
block:dims ->
?shared_mem:int ->
unit ->
unitRun a kernel with the given arguments
val run :
Device.t ->
name:string ->
source:string ->
args:arg list ->
grid:dims ->
block:dims ->
?shared_mem:int ->
unit ->
unitHigh-level run function: compile (if needed) and execute.
val alloc_float32 : Device.t -> int -> float Memory.bufferMemory allocation shortcuts
val alloc_float64 : Device.t -> int -> float Memory.bufferval alloc_int32 : Device.t -> int -> int32 Memory.bufferval alloc_int64 : Device.t -> int -> int64 Memory.bufferval alloc_custom : Device.t -> size:int -> elem_size:int -> 'a Memory.bufferAllocate a buffer for custom types with explicit element size
val to_device :
src:('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t ->
dst:'a Memory.buffer ->
unitHost-to-device transfer
val from_device :
src:'a Memory.buffer ->
dst:('a, 'b, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t ->
unitDevice-to-host transfer
val to_device_ptr : src_ptr:unit Ctypes.ptr -> dst:'a Memory.buffer -> unitHost-to-device transfer for custom types (raw pointer)
val from_device_ptr : src:'a Memory.buffer -> dst_ptr:unit Ctypes.ptr -> unitDevice-to-host transfer for custom types (raw pointer)
val free : 'a Memory.buffer -> unitFree a buffer