Ir.Ndarraymodule Lazy = Utils.LazyN-dimensional arrays: a precision-handling wrapper for Bigarray.Genarray and its utilities.
val bigarray_start_not_managed : ('ocaml, 'elt_t) bigarray -> Ctypes_ptr.voidpval big_ptr_to_string : ('a, 'b) bigarray -> Base.String.tval sexp_of_bigarray : ('a, 'b) bigarray -> Base.Sexp.ttype byte_nd = (Base.char, Ops.uint8_elt) bigarraytype uint16_nd = (Base.int, Ops.uint16_elt) bigarraytype int32_nd = (Base.int32, Ops.int32_elt) bigarraytype uint32_nd = (Base.int32, Ops.int32_elt) bigarraytype int64_nd = (Base.int64, Ops.int64_elt) bigarraytype uint64_nd = (Base.int64, Ops.int64_elt) bigarraytype uint4x32_nd = (Stdlib.Complex.t, Stdlib.Bigarray.complex64_elt) bigarraytype half_nd = (Base.float, Ops.float16_elt) bigarraytype bfloat16_nd = (Base.int, Ops.uint16_elt) bigarraytype fp8_nd = (Base.char, Ops.uint8_elt) bigarraytype single_nd = (Base.float, Ops.float32_elt) bigarraytype double_nd = (Base.float, Ops.float64_elt) bigarrayval sexp_of_byte_nd : byte_nd -> Base.Sexp.tval sexp_of_uint16_nd : uint16_nd -> Base.Sexp.tval sexp_of_int32_nd : int32_nd -> Base.Sexp.tval sexp_of_uint32_nd : uint32_nd -> Base.Sexp.tval sexp_of_int64_nd : int64_nd -> Base.Sexp.tval sexp_of_uint64_nd : uint64_nd -> Base.Sexp.tval sexp_of_uint4x32_nd : uint4x32_nd -> Base.Sexp.tval sexp_of_half_nd : half_nd -> Base.Sexp.tval sexp_of_bfloat16_nd : bfloat16_nd -> Base.Sexp.tval sexp_of_fp8_nd : fp8_nd -> Base.Sexp.tval sexp_of_single_nd : single_nd -> Base.Sexp.tval sexp_of_double_nd : double_nd -> Base.Sexp.tval sexp_of_t : t -> Sexplib0.Sexp.tval as_array : ('ocaml, 'elt_t) Ops.precision -> ('ocaml, 'elt_t) bigarray -> tval precision_to_bigarray_kind :
('ocaml, 'elt_t) Ops.precision ->
('ocaml, 'elt_t) Stdlib.Bigarray.kindval precision_string : t -> stringval default_kind : (Base.float, Ops.float32_elt) Ops.precisiontype 'r apply_with_prec = {f : 'ocaml 'elt_t. ('ocaml, 'elt_t) Ops.precision ->
('ocaml, 'elt_t) bigarray ->
'r;}val apply_with_prec : 'a apply_with_prec -> t -> 'aval create_bigarray_of_prec :
('ocaml, 'elt_t) Ops.precision ->
int array ->
('ocaml, 'elt_t) bigarrayval create_bigarray :
('ocaml, 'elt_t) Ops.precision ->
dims:int array ->
padding:('a * float) option ->
('ocaml, 'elt_t) bigarrayval apply : 'a apply_as_bigarray -> t -> 'aval apply2 : 'a apply2_as_bigarray -> t -> t -> 'aval dims : t -> int arrayval get_fatptr_not_managed :
t ->
('a option, unit Ctypes_static.typ) Ctypes_memory.Fat.tval get_voidptr_not_managed : t -> Base.unit Ctypes.ptrHelper function to adjust indices by adding left padding when padding is specified
Helper function to compute end index for iteration, respecting padding margins
val set_from_float :
?padding:??? ->
t ->
Base__Int.t Base.Array.t ->
Base.Float.t ->
unitval fill_from_float : t -> Base.Float.t -> unitval fold_as_float :
?padding:??? ->
init:'a ->
f:('a -> Base__Int.t Base.Array.t -> Base.float -> 'a) ->
t ->
'aval size_in_bytes : t -> intval get_as_float :
?padding:??? ->
t ->
Base__Int.t Base.Array.t ->
Base.Float.tval retrieve_2d_points :
?from_axis:??? ->
?padding:??? ->
xdim:int ->
ydim:int ->
t ->
(Base.Float.t * Base.Float.t) Base.Array.tval retrieve_1d_points :
?from_axis:??? ->
?padding:??? ->
xdim:int ->
t ->
Base.Float.t Base.Array.tval retrieve_flat_values : ?padding:??? -> t -> Base.Float.t Base.Array.tval set_flat_values : ?padding:??? -> t -> Base.Float.t Base.Array.t -> unitval c_ptr_to_string : t -> Base.String.tval ptr_to_string_hum : t -> Base.String.tval to_native : t -> Ctypes_ptr.voidpval hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_valueval hash_fold_t :
Base__.Ppx_hash_lib.Std.Hash.state ->
t ->
Base__.Ppx_hash_lib.Std.Hash.stateval hash_t : t -> Base__Ppx_hash_lib.Std.Hash.hash_valueval copy_with_padding :
source:t ->
target:t ->
padding:Ops.axis_padding Base.array ->
Base.unitCopies the whole of source onto the parts of target skipping over padding margins -- requires that source dimensions + padding = target dimensions.
val mappable_file_region :
prec:Ops.prec ->
byte_offset:Base.int ->
nbytes:Base.int ->
Base.boolWhether a prec-typed region of nbytes bytes at byte_offset of a file may be wrapped by map_file_array rather than decoded (gh-ocannl-588). Three conditions, none of them about the caller's format: a mapping is read in the host's byte order while the payload formats here are little-endian; Unix.map_file has no empty mapping; and the data pointer it hands back sits at byte_offset exactly, so an offset that is not a multiple of the element size would make a misaligned typed pointer -- undefined behaviour, and a trap on strict targets. That last one is easy to assume away: a format may align its payloads by construction and still put a wide one at an odd offset once a narrow payload precedes it. Whether the file's bytes are the buffer's bytes (no padding, no re-layout) is the caller's half of the question.
val map_file_array :
?shared:??? ->
Ops.prec ->
dims:Base.int Base.array ->
byte_offset:Base.int ->
Unix.file_descr ->
tWraps the dims-shaped region of the file fd starting at byte_offset as an ndarray of precision prec, via Unix.map_file (gh-ocannl-467).
The returned array owns its mapping: the runtime unmaps it when the array is collected, and the mapping stays valid after fd is closed. byte_offset need not be page aligned -- the runtime maps from the enclosing page (on Windows, allocation-granularity) boundary and offsets the data pointer accordingly.
With ~shared:false (the default) the mapping is copy-on-write: writes to the array stay private to the process and never reach the file.
A mapped array is read with the host's byte order, whereas the payloads written by write_payload_to_channel are little-endian, so the caller is responsible for checking Stdlib.Sys.big_endian before mapping a payload. The mapping is not counted in get_used_memory: its pages are file-backed, not heap.
See Bigarray.reshape. The view shares nd's data, so it keeps nd itself alive: nd is the wrapper carrying the get_used_memory finalizer, and collecting it while a view still holds the bytes would end their accounting early.
val init_array :
debug:Base.string ->
Ops.prec ->
dims:Base.int Base.array ->
padding:(Ops.axis_padding Base.Array.t * float) option ->
f:(Base.int Base.array -> Base.float) ->
tInitializes an array using a function from indices to values. Note: dims must include padding if padding is specified, but the callback f indices operate in the before-padding space.
This function is slow as it performs unboxing at each index. Generate and wrap a bigarray if efficiency is a concern.
convert prec src is a fresh ndarray of precision prec with src's dimensions and values (converted through float); src itself when the precision already matches. Padding is not carried — the source's raw dims are used as-is. Load-time conversion for data-backed tensors (gh-ocannl-492): the inference-side counterpart of the training recipe's cast twins.
Bytes currently held by live host arrays created through create_array (and therefore init_array, which delegates to it). A live gauge, not a cumulative total: the allocation adds and the array's finalizer subtracts, so the count returns to its earlier value once the arrays are collected. Since finalizers only run at collection time, a reading right after dropping the arrays can still include them -- force a Stdlib.Gc.full_major first. A reshape view is not counted on its own but keeps its source's bytes counted, since it shares them; a map_file_array mapping is not counted at all. The backends' own device-side counters are separate (see Context.get_used_memory).
val int_dims_to_string :
?with_axis_numbers:??? ->
?padding:??? ->
Base.Int.t Base.Array.t ->
Base.String.tDimensions to string, "x"-separated, e.g. 1x2x3 for batch dims 1, input dims 3, output dims 2. Outputs "-" for empty dimensions.
val log_debug_info : from_log_level:int -> t -> unitLogs information about the array on the default ppx_minidebug runtime, if from_log_level > Utlis.settings.with_log_level.
val render_array :
?brief:??? ->
?prefix:??? ->
?entries_per_axis:??? ->
?labels:??? ->
indices:Base__Int.t Base.Array.t ->
t ->
PrintBox.tPrints 0-based indices entries out of arr, where a number between -5 and -1 in an axis means to print out the axis, and a non-negative number means to print out only the indexed dimension of the axis. Prints up to entries_per_axis or entries_per_axis+1 entries per axis, possibly with ellipsis in the middle. labels provides the axis labels for all axes (use "" or "_" for no label). The last label corresponds to axis -1 etc. The printed out axes are arranged as:
-1: a horizontal segment in an inner rectangle (i.e. column numbers of the inner rectangle),-2: a sequence of segments in a line of text (i.e. column numbers of an outer rectangle),-3: a vertical segment in an inner rectangle (i.e. row numbers of the inner rectangle),-4: a vertical sequence of segments (i.e. column numbers of an outer rectangle),-5: a sequence of screens of text (i.e. stack numbers of outer rectangles).val to_doc :
?prefix:??? ->
?entries_per_axis:??? ->
?labels:??? ->
indices:Base__Int.t Base.Array.t ->
t ->
PPrint.documentval to_doc_inline :
num_batch_axes:Base__Int.t ->
num_output_axes:Base__Int.t ->
num_input_axes:Base__Int.t ->
?axes_spec:??? ->
t ->
PPrint.documentPrints the whole array in an inline syntax.
Compute the C-layout linear offset from multi-dimensional index and dims.
val count_logical_elems : ?padding:??? -> t -> Base__Int.tCount the number of logical (unpadded) elements in an ndarray.
val write_payload_to_channel : ?padding:??? -> t -> Stdlib.Out_channel.t -> intWrite the logical (unpadded) payload of an ndarray to a channel in native binary format (little-endian). Returns the number of bytes written.
val read_payload_from_channel :
?padding:??? ->
t ->
Stdlib.in_channel ->
int ->
Base.unitRead native binary data from a channel into an ndarray, populating only the logical (unpadded) region.
Which path ingest_payload took for one payload. The two produce equal values by construction, so this -- and the running ingestion_counts -- is the only way to observe which one ran.
(mapped, decoded) payload counts since the start of the process: how many payloads ingest_payload wrapped as file mappings, and how many it decoded into fresh host buffers. One pair for every reader that ingests through ingest_payload -- checkpoints and safetensors alike -- so a caller interested in a single file's split reads it before and after that file's payloads. For tests, and for diagnosing a load that decodes more than expected.
val ingest_payload :
?padding:??? ->
?mmap:??? ->
debug:Base.string ->
Ops.prec ->
dims:Base.int Base.array ->
byte_offset:Base.int ->
nbytes:Base.int ->
Stdlib.in_channel ->
t * ingestionIngests one payload of a little-endian binary file: the dims-shaped, prec-typed region of nbytes bytes at byte_offset of ic, as a mapping of the file where that is byte-equivalent (gh-ocannl-467, gh-ocannl-587) and otherwise as a fresh host buffer decoded from the channel. Returns the array and which of the two ran; both are counted in ingestion_counts.
A mapping is byte-equivalent when the file's bytes are the buffer's bytes. Three of the four conditions are the caller's format speaking through the arguments: ?padding means the payload holds only the logical region, which read_payload_from_channel has to scatter into the padded buffer; an empty dims has no mapping to take; and nbytes must be exactly the buffer, which also rejects a header claiming a byte length its dimensions and precision do not add up to. The fourth is mappable_file_region, the conditions the mapping itself imposes -- host byte order, non-emptiness, and element alignment of byte_offset, which no format guarantees for free: a packed layout puts a wide payload at an odd offset as soon as a narrow one precedes it. ?mmap:false declines mapping outright, for a caller that offers the choice.
The mapping is taken from the descriptor behind ic -- the channel the caller read the file's header through -- and NOT from a fresh open of its path: a concurrent atomic save would put a different inode at that name, and the offsets, extents and precisions being mapped describe the file this read started on. The mapping outlives the descriptor, and the directory entry, so nothing here depends on the file staying put; it is the returned array that owns it, and the caller's remaining duty is to keep whatever holds ic alive across this call.