Ir.AssignmentsAssignment computations over tensor nodes.
type init_data = | Broadcast of Base.floatHost-backed scalar fill of the inferred shape, including its committed padding. Unlike Reshape, this does not constrain the number of elements.
| Reshape of Ndarray.t| Keep_shape_no_padding of Ndarray.t| Padded of {data : Ndarray.t;padding : Ops.axis_padding Base.array;padded_value : Base.float;}val sexp_of_init_data : init_data -> Sexplib0.Sexp.tval sexp_of_buffer : buffer -> Sexplib0.Sexp.ttype fetch_op = | Constant of Base.float| Constant_bits of Base.int64| Constant_fill of Base.float Base.array| Range_over_offsets| Slice of {batch_idx : Indexing.static_symbol;sliced : Tnode.t;}| Embed_symbol of Indexing.static_symbol| Embed_self_id| Embed_dim of Indexing.variable_refval sexp_of_fetch_op : fetch_op -> Sexplib0.Sexp.tval sexp_of_accum_rhs : accum_rhs -> Sexplib0.Sexp.ttype t = | Noop| Seq of t * t| Block_comment of Base.string * t| Accum_op of {initialize_neutral : Base.bool;accum : Ops.binop;lhs : Tnode.t;rhs : accum_rhs;projections : Indexing.projections Utils.Lazy.t;projections_debug : Base.string;}| Set_vec_unop of {op : Ops.vec_unop;lhs : Tnode.t;rhs : buffer;projections : Indexing.projections Utils.Lazy.t;projections_debug : Base.string;}| Fetch of {array : Tnode.t;fetch_op : fetch_op;dims : Base.int Base.array Utils.Lazy.t;}val sexp_of_t : t -> Sexplib0.Sexp.tFolds f over the LEAF statements (Accum_op, Set_vec_unop, Fetch) in execution order, skipping the Noop / Seq / Block_comment scaffolding. Descending is what this module's queries and the tests' finders used to each write for themselves, and forgetting to descend through a Block_comment loses statements silently -- so the recursion is written once. f still matches on t (the leaf kinds mean different things to different queries), and its scaffolding arm is unreachable (gh-ocannl-818 would give the leaves a type of their own).
fold_leaves for a f that only has effects.
val sexp_of_side : side -> Sexplib0.Sexp.tval side_of_sexp : Sexplib0.Sexp.t -> sidemodule Fragment : sig ... endA code fragment generated from a tensor, identified by its owner node and side (gh-ocannl-1724): (t.value, Fwd) is t's forward code; (t.grad, Bprop) is t's backprop code, the code propagating from t.grad into its children's gradients.
type comp = {asgns : t;embedded_nodes : Base.Set.M(Ir.Tnode).t;owned : Base.Set.M(Fragment).t;The tensor-generated code fragments this computation carries. Context.compile refuses a computation owning a fragment some routine of its compilation lineage already owns.
requires : Base.Set.M(Fragment).t;The backprop fragments its gradient writes flow into that it does not carry itself. Context.run refuses the routine unless a routine of its own lineage (never a sibling) owns each one.
zeroes : Base.Set.M(Ir.Tnode).t;The gradients whose tensor-generated zeroing this computation carries (gh-ocannl-1744): a tensor's zero_grads and whatever is sequenced from it.
accumulates : Base.Set.M(Ir.Tnode).t;The gradients its tensor-generated backprop accumulates into (gh-ocannl-1744): the operands' gradients a tensor's own gradient code writes, and its embedded children's. Context.compile refuses a computation accumulating into a gradient that another routine of its lineage accumulates into, unless a zeroing compiled before both, and carried by neither, resets it; and one accumulating into a gradient whose propagation (its Bprop fragment) an earlier routine of the lineage already carries.
accumulation_runs : Base.int Base.Map.M(Ir.Tnode).t;For a gradient in accumulates and not in zeroes, the runs of this computation one reset of the gradient deliberately spans (gh-ocannl-1781); absent means one. Context.run refuses a routine that has already accumulated into such a gradient's buffer that many times since the buffer was last reset -- by a run of a routine zeroing it, or by a write from outside a run. Train.grad_update ~accum_steps:k states k: the explicit opt-in for gradient accumulation over micro-steps.
}Computations based on assignments. Tensor construction fills in all five sets; zeroing owns and requires nothing (it fills zeroes only), and initialization and hand-written %cd assignments fill none: a hand-written write to a gradient neither contributes nor resets.
val sexp_of_comp : comp -> Sexplib0.Sexp.tval comp :
?owned:Base.Set.M(Fragment).t ->
?requires:Base.Set.M(Fragment).t ->
?zeroes:Base.Set.M(Ir.Tnode).t ->
?accumulates:Base.Set.M(Ir.Tnode).t ->
?accumulation_runs:Base.int Base.Map.M(Ir.Tnode).t ->
embedded:Base.Set.M(Ir.Tnode).t ->
t ->
compThe computation constructor; owned, requires, zeroes, accumulates and accumulation_runs default to empty.
val empty_comp : compval context_nodes : plc:Tnode.Placements.t -> t -> Tnode.t_setval collect_nodes_guess_output : t -> Tnode.t_set * Tnode.t_setval collect_written : t -> Tnode.t_setRuns the computations in order, uniting their nodes, fragments and gradient sets; a gradient two members state different accumulation_runs for keeps the smaller, a member accumulating into it without zeroing it and stating nothing counting as one. Raises Utils.User_error, naming the fragment, when two members own the same fragment (gh-ocannl-1746): owned is a set, so the copy would otherwise run twice unseen -- for a backprop fragment, a double-counted gradient.
val collect_neutral_elem : t -> Base.float Base.optionval to_low_level :
?static_indices:Indexing.static_symbol Base.list ->
t ->
Low_level.tval to_doc :
?name:Base.string ->
?static_indices:Indexing.static_symbol Base.list ->
Base.unit ->
t ->
PPrint.documentval get_name_exn : t -> Base.stringval lower :
?rewrite_target:Rewrites.target ->
?blends_value_selects:Base.bool ->
Low_level.optimize_ctx ->
unoptim_ll_source:(PPrint.document -> Base.unit) Base.option ->
ll_source:(PPrint.document -> Base.unit) Base.option ->
cd_source:(PPrint.document -> Base.unit) Base.option ->
name:Base.string ->
Indexing.static_symbol Base.list ->
t ->
Low_level.optimizedLowers and optimizes t. blends_value_selects is the rendering backend's fact, passed on to Low_level.optimize (gh-ocannl-1775); Backends.lower_assignments always states it.