ModelGraph
A graph: the compiled form of an ONNX model or the recording trace() produces. compile() and trace() return it as built; it is optimized when wanted (optimize()), then finalized (finalize()), then run. run() binds inputs by position or by name and returns the outputs in output_names() order.
device (property)
The device the graph serves on: the one its compile's weights or to() named, else where its operators sit (the first one's device when they sit on several). A graph with no operators reports the CPU.
__init__
__init__(self, /, *args, **kwargs)
Initialize self. See help(type(self)) for accurate signature.
add_constant
add_constantadd_constant(self, tensor: clika_runtime._core.Tensor) -> object
add_constant(self, tensor: clika_runtime._core.Tensor) -> object
add_constant(tensor) -> Value
A new constant holding tensor's bytes (a handle, no copy) that nothing reads yet; set_input() and replace_all_uses_with() take the Value it returns, and constants() lists it. Once an operator reads it, it lives while something reads it, like every constant; finalize() drops it if nothing reads it by then. Raises InvalidArgumentError for a tensor with no data (a traced or a meta tensor).
add_input
add_inputadd_input(self, spec: clika_runtime._core.TensorSpec) -> object
add_input(self, spec: clika_runtime._core.TensorSpec) -> object
add_input(spec) -> Node
A new graph input named spec.name, last in input_names(), with the dtype and dims of spec: a dynamic dim (-1) takes its size at run(), and dims that share a dim_names entry share that size. Returns its Input node, whose value (output(0)) the other edits take. Raises InvalidArgumentError for an empty name, a name a node carries already, and a dim that is neither positive nor -1.
add_node
add_nodeadd_node(self, code: clika_runtime._core.graph.OpCode, inputs: object | None, attributes: object | None = None) -> object
add_node(self, code: clika_runtime._core.graph.OpCode, inputs: object | None, attributes: object | None = None) -> object
add_node(code, inputs, attributes=None) -> Node
A new operator of code (an OpCode), built the way its public op builds it, so the op's own checks apply. inputs holds its values, one entry per input port in the op's order: a Value of this graph, or None for an omitted optional operand; trailing entries may be left off, and a constant enters as the Value add_constant() returns. attributes maps the setting names Node.attributes reports to their values: an int also serves a number, an enumerated setting takes its enumerator's name ('Tanh'), a list setting a list of ints, a dtype setting a dtype, and a setting left out takes the op's default. An int past 2**63 - 1 goes in as its 64-bit pattern, which an unsigned setting (a seed) reads back as given. Nothing reads its outputs yet: wire them with set_input(), replace_all_uses_with() or add_output(); finalize() drops a node nothing reads by then, with what only it read. The node is named <OpCode>_<N>, as a trace names it (rename_node() renames it). Raises InvalidArgumentError for a value of another graph or one no longer held, a state buffer, a missing required input or setting, an input or a setting the op does not take, a setting of another kind, the op's own refusal of the arguments, and a code no single public op call builds (an operator with several outputs, one whose public op call takes a setting the operator does not record, or a quantized operator; build those from the public ops that compute them); TypeError for an input that is neither a Value nor None and a setting no op takes (a Tensor, an enumerator object); and OverflowError for an int outside the 64-bit range.
add_output
add_outputadd_output(self, value: clika_runtime._core.graph.Value, name: str) -> None
add_output(self, value: clika_runtime._core.graph.Value, name: str) -> None
add_output(value, name) -> None
Return value as a new graph output named name, last in output_names(); a value the graph returns already may be returned under a second name. Raises InvalidArgumentError for an empty name, a name another output carries, and a constant or a state buffer (a graph output never returns one directly).
all_simple_edge_paths
all_simple_edge_pathsall_simple_edge_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
all_simple_edge_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
all_simple_edge_paths(src, dst, *, cutoff=None, limit=None, avoid=(), edge_filter=None) -> Iterator[list[Edge]]
Every simple path from src to dst, as edges; each parallel edge gives its own path, as networkx's all_simple_edge_paths. src == dst gives one empty path. Depth-first in out_edges() order, with the bounds, the search at the call and the MAX_PATHS_WITHOUT_LIMIT refusal of find_paths_to().
all_simple_paths
all_simple_pathsall_simple_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
all_simple_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
all_simple_paths(src, dst, *, cutoff=None, limit=None, avoid=(), edge_filter=None) -> Iterator[list[Node]]
Every simple path from src to dst, as nodes; parallel edges give one path, as networkx's all_simple_paths over the graph with its parallel edges merged. src == dst gives the one-node path. The order, the bounds, the search at the call and the MAX_PATHS_WITHOUT_LIMIT refusal of find_paths_to().
ancestors
ancestorsancestors(self, node: clika_runtime._core.graph.Node, *, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
ancestors(self, node: clika_runtime._core.graph.Node, *, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
ancestors(node, *, max_depth=None, max_nodes=None, stop_at=None, edge_filter=None, skip_shape_lane=False) -> list[Node]
Every node with a path to node, node left out, nearest first: a backward walk from it, bounded and filtered as walk() takes them.
bench
benchbench(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape], options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport
bench(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape], options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport bench(self, shapes: collections.abc.Sequence[collections.abc.Sequence[int]], options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport bench(self, shapes: dict, options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport
Overloaded function.
bench(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape], options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport
bench(shapes, options=BenchOptions()) -> BenchReport
Time the graph on synthesized inputs of the given shapes: the shapes are validated as validate_shapes() does, one tensor per input is filled per options.fill on the benchmark device, options.warmup untimed runs precede options.iterations timed ones, and the report carries every timed run's milliseconds (each output synchronized before the clock stops), the summary statistics, the process's peak resident set and the device's memory counters. shapes is a list of InputShape, a list of dims in input_names() order, a dict of name to dims, or a dict of name to Tensor (the tensors are fed as they are). InvalidArgumentError on a shape the domains reject; the run's own error when a run fails.
bench(self, shapes: collections.abc.Sequence[collections.abc.Sequence[int]], options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport
bench(shapes, options=BenchOptions()) -> BenchReport
The positional form: one dims sequence per input_names() entry, that order.
bench(self, shapes: dict, options: clika_runtime._core.io.BenchOptions = BenchOptions(warmup=3, iterations=20, fill=FeedFill.Zeros, device=None, reuse_output_buffers=True, batch_axis=None, profile_dir=None)) -> clika_runtime._core.io.BenchReport
bench(shapes, options=BenchOptions()) -> BenchReport
The named form: a dict of input name to dims (synthesized inputs), or of input name to Tensor (the caller's tensors, fed as they are; their shapes are still validated).
between
betweenbetween(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> list
between(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> list
between(src, dst) -> list[Node]
Every node on a path from src to dst, both ends included, in nodes() order; [] when no path runs.
bypass_node
bypass_nodebypass_node(self, node: clika_runtime._core.graph.Node, input_port: int = 0, output_port: int = 0) -> None
bypass_node(self, node: clika_runtime._core.graph.Node, input_port: int = 0, output_port: int = 0) -> None
bypass_node(node, input_port=0, output_port=0) -> None
Every read of node's output output_port reads the value on its input input_port instead, and node is removed once nothing reads any of its outputs. Raises InvalidArgumentError for an Input node, an input port nothing feeds, an output port nothing reads, a type mismatch between the two values, a node that reads a state buffer, and a constant taking a graph output.
constants
constantsconstants(self) -> dict
constants(self) -> dict
constants() -> dict[str, Tensor]
The bound constants (weights, baked values) by value name.
consumer_cone
consumer_coneconsumer_cone(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
consumer_cone(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
consumer_cone(nodes) -> list[Node]
Every node that reads the outputs of nodes, directly or through others, in nodes() order; the cone of a node no other node reads is [].
count_paths
count_pathscount_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> int
count_paths(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> int
count_paths(src, dst, *, cutoff=None, avoid=(), edge_filter=None) -> int
How many paths all_simple_paths() lists, counted without listing them, so MAX_PATHS_WITHOUT_LIMIT does not apply. Raises InvalidArgumentError when the count passes 2**64 - 1.
critical_path
critical_pathcritical_path(self, node_cost: collections.abc.Callable | None = None, edge_cost: collections.abc.Callable | None = None) -> object
critical_path(self, node_cost: collections.abc.Callable | None = None, edge_cost: collections.abc.Callable | None = None) -> object
critical_path(node_cost=None, edge_cost=None) -> WeightedPath
The path of greatest cost: node_cost (a callable taking a Node) summed over its nodes and edge_cost (taking an Edge) over its edges, each finite and of any sign; a cost not given counts 0, so no costs give the path with the most edges. A path may start and end at any node: a prefix whose sum falls below 0 is dropped and the path starts again at the next node, as networkx's dag_longest_path does. Ties go to more edges, then to the path found first. Each cost runs once per node or edge; a NaN or infinite cost raises InvalidArgumentError naming the node or edge.
default_transforms
default_transformsdefault_transforms(self, defaults: clika_runtime._core.io.DefaultsOptions | None = None) -> list[clika_runtime._core.graph.Transform]
default_transforms(self, defaults: clika_runtime._core.io.DefaultsOptions | None = None) -> list[clika_runtime._core.graph.Transform]
default_transforms(defaults=None) -> list[Transform]
The transform list optimize() runs on this graph under defaults (a DefaultsOptions; None takes every default) when it is handed no list, in the order it runs them: a starting point to edit and hand back as optimize(transforms=...). It follows how the graph was built, so it can differ from the graph-free transforms.defaults(defaults).
depths
depthsdepths(self) -> dict
depths(self) -> dict
depths() -> dict[Node, int]
Each node's generation: the most edges on a path that ends at it, so depths()[n] is the index of n's layer in layers(). One entry per node, in nodes() order.
descendants
descendantsdescendants(self, node: clika_runtime._core.graph.Node, *, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
descendants(self, node: clika_runtime._core.graph.Node, *, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
descendants(node, *, max_depth=None, max_nodes=None, stop_at=None, edge_filter=None, skip_shape_lane=False) -> list[Node]
Every node with a path from node, node left out, nearest first: a forward walk from it, bounded and filtered as walk() takes them.
dominators
dominatorsdominators(self) -> dict
dominators(self) -> dict
dominators() -> dict[Node, Node]
Each node's immediate dominator: the last node before it that every path from the graph inputs to it crosses. Paths start at the graph inputs, so a constant or weight operand opens none. A node no other node dominates (an input, or a node where two inputs' paths meet) maps to itself, and a node on no path from an input has no entry. Entries in nodes() order.
edges
edgesedges(self) -> list
edges(self) -> list
edges() -> list[Edge]
Every edge, in (source name, source port, destination name, destination port) order.
edges_between
edges_betweenedges_between(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> list
edges_between(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> list
edges_between(src, dst) -> list[Edge]
The edges from src to dst, in (source port, destination port) order; [] when no edge runs from one to the other, a node of another graph included. A view whose node an edit removed or renamed raises InvalidArgumentError, as its check() does.
export_onnx
export_onnxexport_onnx(self, path: object | None, *, opset_version: int = 0, contrib_ops: bool = True, optimize: bool = True, save_as_external_data: bool | None = None, producer_name: str = '') -> None
export_onnx(self, path: object | None, *, opset_version: int = 0, contrib_ops: bool = True, optimize: bool = True, save_as_external_data: bool | None = None, producer_name: str = '') -> None
export_onnx(path, *, opset_version=0, contrib_ops=True, optimize=True, save_as_external_data=None, producer_name='') -> None
Write the graph to path, a str or an os.PathLike, as a runnable ONNX model. The inputs and outputs keep their names, dtypes and dims, and a dynamic dimension is written under its name, so two inputs that share one still share it when the model is read back. The weights become the model's initializers, read one at a time as the file is written, so the export holds no second copy of them. opset_version is the ai.onnx opset the model imports (0 takes the library's default); contrib_ops lets the model use the com.microsoft operators; optimize simplifies the written model (transposes that undo each other compose, and nodes no output reads go); save_as_external_data puts the weights in a 'producer_name is the producer the model records (empty takes the library's). OnnxModel.from_graph() builds the same model in memory, and OnnxModel.open(path).compile() reads the file back. A refusal writes nothing. Raises UnsupportedError for a graph that rewrites a state buffer in place (one given a KV cache by attach_kv_cache(), or traced over a function that writes its cache in place) and for an operator with no ONNX form at the chosen opset, naming the node; InvalidArgumentError for an opset_version the library does not know, and with the code FAILED_PRECONDITION while optimize(), finalize(), attach_kv_cache(), to() or an edit runs on the graph; and TypeError for a path of another type.
finalize
finalizefinalize(self) -> None
finalize(self) -> None
finalize() -> None
Finalize the graph for serving: place it on the device its compile's weights or to() named (a graph with neither keeps its operators where they are), pack the weights into their kernel layouts, absorb the constants the operators hold, and plan the execution order. A finalized graph runs and refuses optimize(); calling finalize() again changes nothing.
find_cycle
find_cyclefind_cycle(self) -> list
find_cycle(self) -> list
find_cycle() -> list[Edge]
The edges of one cycle, in order: each edge enters the node the next one leaves, and the last enters the node the first one leaves. [] when the graph has none, as every traced or compiled graph, where networkx's find_cycle() raises.
find_nodes
find_nodesfind_nodes(self, op_code: clika_runtime._core.graph.OpCode) -> list
find_nodes(self, op_code: clika_runtime._core.graph.OpCode) -> list find_nodes(self, predicate: collections.abc.Callable) -> list
Overloaded function.
find_nodes(self, op_code: clika_runtime._core.graph.OpCode) -> list
find_nodes(op_code) -> list[Node]
Every node running the operator, in name order.
find_nodes(self, predicate: collections.abc.Callable) -> list
find_nodes(predicate) -> list[Node]
Every node predicate accepts, in name order: a callable taking a Node and returning True to accept it. It runs inside the search; an exception it raises ends the search, and find_nodes raises with its message.
find_nodes_by_name
find_nodes_by_namefind_nodes_by_name(self, pattern: str, match: clika_runtime._core.graph.NameMatch = NameMatch.Whole) -> list
find_nodes_by_name(self, pattern: str, match: clika_runtime._core.graph.NameMatch = NameMatch.Whole) -> list
find_nodes_by_name(pattern, match=NameMatch.Whole) -> list[Node]
Every node whose name the regular expression pattern matches, in name order: the whole name (NameMatch.Whole) or some part of it (NameMatch.Anywhere). The expression syntax is a large PCRE-like subset with no backreferences and no lookaround; a malformed pattern raises InvalidArgumentError with the regex engine's message.
find_paths_to
find_paths_tofind_paths_to(self, start: clika_runtime._core.graph.Node, target: collections.abc.Callable, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
find_paths_to(self, start: clika_runtime._core.graph.Node, target: collections.abc.Callable, *, cutoff: int | None = None, limit: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
find_paths_to(start, target, *, cutoff=None, limit=None, avoid=(), edge_filter=None) -> Iterator[list[Node]]
Every simple path from start that ends at the first node target accepts: a path never passes an accepted node, and an accepted start is the one-node path. Depth-first, each node's next nodes in out_edges() order; parallel edges give one path. cutoff is the most edges a path may have, limit the most paths returned (the first ones), avoid the nodes no path may hold (its two ends included), and only the edges edge_filter accepts are taken. The search runs at the call, so its refusals and a callable's exception surface there: without a limit, a search that finds more than MAX_PATHS_WITHOUT_LIMIT paths raises InvalidArgumentError rather than returning a cut list; pass a limit, or count them with count_paths(). The target and the edge filter each run once per node or edge.
find_pattern
find_patternfind_pattern(self, pattern: clika_runtime._core.graph.Pattern) -> list
find_pattern(self, pattern: clika_runtime._core.graph.Pattern) -> list
find_pattern(pattern) -> list[Match]
Every occurrence of the pattern in this graph, in match order (non-overlapping: a node belongs to at most one occurrence); each Match lists the matched nodes in the pattern's add_node order, None for an absent optional node. A pattern predicate that raises ends the search and the error carries its message.
has_path
has_pathhas_path(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> bool
has_path(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> bool
has_path(src, dst, *, cutoff=None, avoid=(), edge_filter=None) -> bool
True when a path runs from src to dst within the bounds find_paths_to() takes; a node reaches itself.
input_names
input_namesinput_names(self) -> list[str]
input_names(self) -> list[str]
input_names() -> list[str]
Runtime input names, declaration order; the order the positional run() binds.
input_shape_domain
input_shape_domaininput_shape_domain(self, name: str) -> clika_runtime._core.io.ShapeDomain
input_shape_domain(self, name: str) -> clika_runtime._core.io.ShapeDomain
input_shape_domain(name) -> ShapeDomain
The domain of the input named name; NotFoundError when no input carries it.
inputs
inputsinputs(self) -> list
inputs(self) -> list
inputs() -> list[tuple[str, DataType, tuple[int, ...]]]
Input slots as (name, dtype, dims) tuples; a dynamic dim reads as -1.
insert
insertinsert(self, fn: object | None, inputs: object | None) -> list
insert(self, fn: object | None, inputs: object | None) -> list
insert(fn, inputs) -> list[Value]
New operators computed from inputs, a sequence of Values of this graph: the ones fn records when it is traced over one Tensor per input, each with that value's dtype, device and shape (a dynamic dim keeps the graph's own symbol). A constant scalar input goes into fn as the literal it holds, so a value fn reads from it (a range's end, a count) keeps the extent it gives. fn returns a Tensor or a sequence of Tensors, and insert() returns their Values in order, which nothing reads yet: wire them as add_node()'s outputs are wired. A tensor holding data that fn makes or reads becomes a constant of the graph, a value fn returns unchanged comes back as the input it is, and the new nodes take fresh names. fn computes values: it does not write one of its inputs, or a tensor that holds data, in place, and it does not edit this graph or call optimize(). An exception fn raises leaves insert() as that same exception, with the graph as it was. Raises InvalidArgumentError for a value of another graph or one no longer held, a state buffer, a value with no recorded type, such an in-place write, a returned value that holds data, and a read of a tensor without data that is none of its inputs; and TypeError for an fn that cannot be called, an entry that is not a Value, and a return that is not a Tensor or a sequence of Tensors.
is_convex
is_convexis_convex(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> bool
is_convex(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> bool
is_convex(nodes) -> bool
True when nodes is convex: no path leaves the set and comes back into it, so the set can be cut out and replaced as one piece.
is_finalized
is_finalizedis_finalized(self) -> bool
is_finalized(self) -> bool
is_finalized() -> bool
True once finalize() ran. compile() and trace() return a graph that is not finalized yet.
is_topological_order
is_topological_orderis_topological_order(self, order: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> bool
is_topological_order(self, order: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> bool
is_topological_order(order) -> bool
True when order, a sequence of Nodes, is a topological order of this graph: every node exactly once, and every edge running forward. A node of another graph, a repeated or a missing node, or an edge running backward makes it False. A view whose node an edit removed or renamed raises InvalidArgumentError, as its check() does.
kv_cache_info
kv_cache_infokv_cache_info(self) -> list[clika_runtime._core.io.KVCacheLayerInfo]
kv_cache_info(self) -> list[clika_runtime._core.io.KVCacheLayerInfo]
kv_cache_info() -> list[KVCacheLayerInfo]
The attention layers' KV-cache wiring (past inputs, present outputs, heads, mask family), one entry per layer; empty for a graph without attention.
layers
layerslayers(self) -> list
layers(self) -> list
layers() -> list[list[Node]]
The topological generations: the nodes with no in-edge first (in_degree() 0), then each node one layer after its latest producer; every layer in nodes() order.
lowest_common_ancestors
lowest_common_ancestorslowest_common_ancestors(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
lowest_common_ancestors(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
lowest_common_ancestors(nodes) -> list[Node]
The lowest common ancestors of nodes, a sequence of at least one Node: the nodes every one of them descends from (each counting as its own ancestor) that no other such node descends from, in nodes() order. networkx's lowest_common_ancestor returns one of them.
merge
mergemerge(self, second: object | None, io_map: collections.abc.Sequence[tuple[str, str]] = []) -> list[clika_runtime._core.graph.Rename]
merge(self, second: object | None, io_map: collections.abc.Sequence[tuple[str, str]] = []) -> list[clika_runtime._core.graph.Rename]
merge(second, io_map=()) -> list[Rename]
Merge second, a ModelGraph, into this graph. Each io_map entry (this_output, second_input) feeds one of this graph's outputs into one of second's inputs; the connected outputs and inputs leave the lists, and everything else stays. The inputs are this graph's, then second's unconnected ones, and the outputs second's, then this graph's unconnected ones. This graph keeps every name, and a name of second's that this graph already uses takes the first free '
merge_point
merge_pointmerge_point(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> object
merge_point(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> object
merge_point(nodes) -> Node | None
Where the paths from nodes, a sequence of at least one Node, merge: the nearest node every path from them to the graph outputs crosses, each counting for itself. None when their paths meet only at the outputs. A node on no path to an output is not counted.
min_value_cut
min_value_cutmin_value_cut(self, before: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], after: collections.abc.Sequence[clika_runtime._core.graph.Node] = []) -> object
min_value_cut(self, before: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], after: collections.abc.Sequence[clika_runtime._core.graph.Node] = []) -> object
min_value_cut(before=(), after=()) -> ValueCut
The cheapest cut through the graph's values: a split of the nodes in two, every node before the cut with its producers before it, that hands the fewest bytes from the part before to the part after. The graph inputs and the nodes of before run before the cut and the nodes of after after it; a graph output made before the cut is one of the values. A value weighs its tensor's bytes: a view adds nothing to the tensor it re-describes, and a constant or a state buffer is never one of the values. Of the cheapest cuts this is the one nearest the inputs: the least set of nodes before the cut. networkx's minimum_cut returns the one nearest the sink instead; called on the reversed network, from the sink to the source, it returns this one. Raises InvalidArgumentError when no cut exists, naming the node of after that is a graph input, is in before or feeds a node of before, and UnsupportedError when a value has no fixed size in bytes (a dynamic dim), since the cut weighs every value.
node
nodenode(self, name: str) -> object
node(self, name: str) -> object
node(name) -> Node
The node named name; KeyError when absent.
nodes
nodesnodes(self) -> list
nodes(self) -> list
nodes() -> list[Node]
Every node in execution order (graph inputs first, then the operators). compile() and trace() return the graph as the model states it; read it there, before optimize() and finalize() rewrite it.
optimize
optimizeoptimize(self, transforms: collections.abc.Sequence[clika_runtime._core.graph.Transform] | None = None, max_num_iterations: int = 100, *, defaults: clika_runtime._core.io.DefaultsOptions | None = None) -> clika_runtime._core.io.OptimizeReport
optimize(self, transforms: collections.abc.Sequence[clika_runtime._core.graph.Transform] | None = None, max_num_iterations: int = 100, *, defaults: clika_runtime._core.io.DefaultsOptions | None = None) -> clika_runtime._core.io.OptimizeReport
optimize(transforms=None, max_num_iterations=100, *, defaults=None) -> OptimizeReport
Run the graph optimizer: transforms, a list of handles from clika_runtime.graph.transforms run in order each iteration (any of them as often as wanted), iterated until an iteration changes nothing or max_num_iterations (1 to 2147483647) have run. None runs this graph's default list (default_transforms(defaults)); an empty list runs none of them, though the run still drops the nodes nothing reads. defaults is a DefaultsOptions; None takes every default, and the transforms read their settings from it either way. Returns what the run did, one TransformReport per list entry. It runs before finalize(), and raises InvalidArgumentError on a finalized graph, while a run, optimize() or finalize() is in flight on this graph, and before anything runs when the list places a transform ahead of one it must follow or holds a transform that defaults switch off for this graph (each refusal names the list entry and what to change). A transform made from a Python function (Transform) that raises ends the run, and optimize() raises that same exception, with the graph as optimize() found it.
output_names
output_namesoutput_names(self) -> list[str]
output_names(self) -> list[str]
output_names() -> list[str]
Output names, declaration order; the order run() returns.
outputs
outputsoutputs(self) -> list
outputs(self) -> list
outputs() -> list[tuple[str, DataType, tuple[int, ...]]]
Output slots as (name, dtype, dims) tuples.
post_dominators
post_dominatorspost_dominators(self) -> dict
post_dominators(self) -> dict
post_dominators() -> dict[Node, Node]
Each node's immediate post-dominator: the first node after it that every path from it to the graph outputs crosses. A node no other node post-dominates maps to itself, and a node on no path to an output has no entry. Entries in nodes() order.
producer_cone
producer_coneproducer_cone(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
producer_cone(self, nodes: collections.abc.Sequence[clika_runtime._core.graph.Node]) -> list
producer_cone(nodes) -> list[Node]
Every node whose output nodes read, directly or through others, in nodes() order. A node of nodes counts only when another one reads it, so the cone of an input is [].
random_topological_order
random_topological_orderrandom_topological_order(self, seed: int) -> list
random_topological_order(self, seed: int) -> list
random_topological_order(seed) -> list[Node]
A topological order drawn at random from the valid ones: each node once, after every node whose output it reads. One seed (an integer from 0 to 2**64 - 1) draws one order of a given graph, on every platform.
region
regionregion(self, entry: clika_runtime._core.graph.Node, exit: clika_runtime._core.graph.Node) -> list
region(self, entry: clika_runtime._core.graph.Node, exit: clika_runtime._core.graph.Node) -> list
region(entry, exit) -> list[Node]
The single-entry, single-exit region from entry to exit: the nodes entry dominates and exit post-dominates, both ends included, in nodes() order; a node alone is a region. Raises InvalidArgumentError, naming the condition that fails, unless entry dominates exit and exit post-dominates entry.
remove_node
remove_noderemove_node(self, node: clika_runtime._core.graph.Node) -> None
remove_node(self, node: clika_runtime._core.graph.Node) -> None
remove_node(node) -> None
Remove node, an operator nothing reads, with its reads of other values (a constant only it read goes with it). Raises InvalidArgumentError for an Input node and a node that reads a state buffer, and with code_name FAILED_PRECONDITION for a node whose outputs are still read, naming the first reader: rewire or remove that reader first.
remove_output
remove_outputremove_output(self, name: str) -> None
remove_output(self, name: str) -> None
remove_output(name) -> None
Stop returning the graph output name; the node that computes it stays. Raises InvalidArgumentError for a name no output carries, and with code_name FAILED_PRECONDITION for an output a KV cache layer returns its cache as, naming the layer.
rename_input
rename_inputrename_input(self, name: str, new_name: str) -> None
rename_input(self, name: str, new_name: str) -> None
rename_input(name, new_name) -> None
Rename the graph input name, and its Input node, new_name. Views of the old name are gone afterwards. Raises InvalidArgumentError for a name no input carries, an empty name and a name a node carries already, and with code_name FAILED_PRECONDITION for an input a KV cache layer reads its cache from, naming the layer.
rename_node
rename_noderename_node(self, node: clika_runtime._core.graph.Node, name: str) -> None
rename_node(self, node: clika_runtime._core.graph.Node, name: str) -> None
rename_node(node, name) -> None
Name node name; its outputs keep their names. Views of the old name are gone afterwards: find the node again with node(name). Raises InvalidArgumentError for an Input node (rename it with rename_input()), an empty name, and a name another node carries.
rename_output
rename_outputrename_output(self, name: str, new_name: str) -> None
rename_output(self, name: str, new_name: str) -> None
rename_output(name, new_name) -> None
Rename the graph output name new_name. Raises InvalidArgumentError for a name no output carries, an empty name and a name another output carries, and with code_name FAILED_PRECONDITION for an output a KV cache layer returns its cache as, naming the layer.
replace
replacereplace(self, old_outputs: object | None, fn: object | None, inputs: object | None) -> list
replace(self, old_outputs: object | None, fn: object | None, inputs: object | None) -> list
replace(old_outputs, fn, inputs) -> list[Value]
insert(fn, inputs), then every read of old_outputs[i] reads new value i, the graph's returns included (they keep their names), and the operators that computed old_outputs from inputs go, with every producer only they read. An operator an input is computed from stays, since the new values read that input; when it makes an old output (an input read from another of its outputs), that output's reads move all the same. Returns the new Values. An exception fn raises leaves replace() as that same exception, with the graph as it was. Raises what insert() raises, and InvalidArgumentError for no old outputs, one listed twice, or one that is a constant, a state buffer or a graph input's value; an old output that is also one of inputs; an old output not computed from inputs; a value those operators make that another node reads or the graph returns (naming it and its reader); a KV cache layer's attention among them; an input computed from a reader of an old output; a count of new values other than the old outputs'; a new value whose type differs from its old output's; and a constant a graph output would return.
replace_all_uses_with
replace_all_uses_withreplace_all_uses_with(self, old_value: clika_runtime._core.graph.Value, replacement: clika_runtime._core.graph.Value) -> None
replace_all_uses_with(self, old_value: clika_runtime._core.graph.Value, replacement: clika_runtime._core.graph.Value) -> None
replace_all_uses_with(old_value, replacement) -> None
Every read of old_value reads replacement instead: each operator input it feeds, and each graph output it returns (the output keeps its name). Nothing reads old_value afterwards, so its view is gone, unless it is a graph input's value. Raises InvalidArgumentError for replacement being old_value, a type mismatch, a replacement computed from one of old_value's readers (a cycle), a state buffer's reads, a read an operator serves from a weight it holds itself, and a constant taking a graph output.
run
runrun(self, inputs: collections.abc.Sequence[clika_runtime._core.Tensor]) -> list[clika_runtime._core.Tensor]
run(self, inputs: collections.abc.Sequence[clika_runtime._core.Tensor]) -> list[clika_runtime._core.Tensor] run(self, inputs: dict) -> list[clika_runtime._core.Tensor]
Overloaded function.
run(self, inputs: collections.abc.Sequence[clika_runtime._core.Tensor]) -> list[clika_runtime._core.Tensor]
run(inputs) -> list[Tensor]
Run with positional inputs (input_names() order); returns the outputs in output_names() order.
run(self, inputs: dict) -> list[clika_runtime._core.Tensor]
run(inputs) -> list[Tensor]
Run with named inputs (dict[str, Tensor], strict); returns the outputs in output_names() order.
set_constant_input
set_constant_inputset_constant_input(self, node: clika_runtime._core.graph.Node, port: int, tensor: clika_runtime._core.Tensor) -> None
set_constant_input(self, node: clika_runtime._core.graph.Node, port: int, tensor: clika_runtime._core.Tensor) -> None
set_constant_input(node, port, tensor) -> None
node's input port reads a new constant holding tensor's bytes: the graph keeps a handle to them, no copy, and finalize() places them with the graph. The constant replaces the value the port reads, so the port already reads one, of the same type. Raises InvalidArgumentError for an Input node, a port nothing feeds, a state buffer's read, a port the operator serves from a weight it holds itself, a tensor with no data (a traced or a meta tensor), and a type mismatch with the value the port reads.
set_input
set_inputset_input(self, node: clika_runtime._core.graph.Node, port: int, value: clika_runtime._core.graph.Value) -> None
set_input(self, node: clika_runtime._core.graph.Node, port: int, value: clika_runtime._core.graph.Value) -> None
set_input(node, port, value) -> None
node's input port reads value. The edit replaces the value the port reads, so the port already reads one: an input the operator was built without stays empty. Raises InvalidArgumentError for an Input node, a port nothing feeds, a state buffer's read, a port the operator serves from a weight it holds itself, a type mismatch with the value the port reads, and a value computed from node's own outputs (a cycle).
shape_domains
shape_domainsshape_domains(self) -> list[clika_runtime._core.io.ShapeDomain]
shape_domains(self) -> list[clika_runtime._core.io.ShapeDomain]
shape_domains() -> list[ShapeDomain]
The shapes each input admits, input_names() order: a fixed dimension is Fixed, a dynamic one compiled with a shape spec is Range, any other dynamic one is Free.
shortest_path
shortest_pathshortest_path(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, edge_cost: collections.abc.Callable | None = None, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
shortest_path(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node, *, edge_cost: collections.abc.Callable | None = None, cutoff: int | None = None, avoid: collections.abc.Sequence[clika_runtime._core.graph.Node] = [], edge_filter: collections.abc.Callable | None = None) -> object
shortest_path(src, dst, *, edge_cost=None, cutoff=None, avoid=(), edge_filter=None) -> list[Node] | WeightedPath
Without edge_cost, a path from src to dst with the fewest edges, as its nodes: [src] when the two are one node, [] when no path runs, one answer among equally short paths, the same on every call. With edge_cost, a callable taking an Edge and returning its cost, the cheapest path as a WeightedPath: the costs summed over the edges it takes (among parallel edges, the cheapest), ties to fewer edges, and under cutoff the cheapest path of at most that many edges. Each cost must be finite and at least 0, or InvalidArgumentError names the edge; the cost runs at most once per edge. Unlike networkx, which answers the length through a second function (shortest_path_length), the weighted answer carries its cost. cutoff, avoid and edge_filter bound the search as find_paths_to() takes them.
split_points
split_pointssplit_points(self) -> list
split_points(self) -> list
split_points() -> list[Node]
The nodes every path from the graph inputs to the graph outputs crosses, from the inputs to the outputs: where the graph splits into two stages at one node. [] when no node is on every such path.
to
toto(self, where: object) -> None
to(self, where: object) -> None
to(where) -> None
Move the graph to where: a Device, a device string, or a Stream so the graph computes on that stream. Before finalize() it records where finalize() places the graph and moves nothing, and device reports the new device at once. After finalize() it moves the finalized graph: an operator that changes device re-packs its weights there once, and no copy of a moved weight stays behind. A device that cannot serve is refused before anything moves; while a run, optimize(), finalize() or an edit is in flight on this graph it raises InvalidArgumentError, whose code_name is FAILED_PRECONDITION.
to_networkx
to_networkxto_networkx(self) -> object
to_networkx(self) -> object
to_networkx() -> networkx.MultiDiGraph
The graph as a networkx.MultiDiGraph: one node per Node, keyed by the Node view with its op_code and kind as node data, and one edge per Edge, keyed (src_port, dst_port), so the two reads of Mul(x, x) stay two edges. The networkx graph holds this graph alive through its Node keys. networkx is imported at the call; ImportError when it is not installed.
topological_generations
topological_generationstopological_generations(self) -> list
topological_generations(self) -> list
topological_generations() -> list[list[Node]]
layers() under networkx's name: the same generations.
topological_order
topological_ordertopological_order(self, order: clika_runtime._core.graph.TopologicalOrder = TopologicalOrder.Deterministic) -> list
topological_order(self, order: clika_runtime._core.graph.TopologicalOrder = TopologicalOrder.Deterministic) -> list
topological_order(order=TopologicalOrder.Deterministic) -> list[Node]
Every node in the topological order order names: each node once, after every node whose output it reads (see TopologicalOrder for how each kind breaks the ties).
validate_shapes
validate_shapesvalidate_shapes(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape]) -> None
validate_shapes(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape]) -> None validate_shapes(self, shapes: collections.abc.Sequence[collections.abc.Sequence[int]]) -> None validate_shapes(self, shapes: dict) -> None
Overloaded function.
validate_shapes(self, shapes: collections.abc.Sequence[clika_runtime._core.io.InputShape]) -> None
validate_shapes(shapes) -> None
Check shapes against the domains: every input present once, every name an input, every rank the input's, every extent admitted. shapes is a list of InputShape, a list of dims in input_names() order, or a dict of name to dims. InvalidArgumentError names the input and the dimension that failed.
validate_shapes(self, shapes: collections.abc.Sequence[collections.abc.Sequence[int]]) -> None
validate_shapes(shapes) -> None
The positional form: one dims sequence per input_names() entry, that order.
validate_shapes(self, shapes: dict) -> None
validate_shapes(shapes) -> None
The named form: a dict of input name to dims.
visit
visitvisit(self, start: clika_runtime._core.graph.Node, visitor: collections.abc.Callable, *, direction: clika_runtime._core.graph.WalkDirection = WalkDirection.Forward, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> None
visit(self, start: clika_runtime._core.graph.Node, visitor: collections.abc.Callable, *, direction: clika_runtime._core.graph.WalkDirection = WalkDirection.Forward, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> None
visit(start, visitor, *, direction=WalkDirection.Forward, max_depth=None, max_nodes=None, stop_at=None, edge_filter=None, skip_shape_lane=False) -> None
The walk walk() takes, showing visitor each node it reaches, the start included. The visitor answers a VisitAction: Prune does not go past that node, and Stop ends the walk, which then returns. None reads as Continue; any other answer ends the walk and raises TypeError. A visitor or callable that raises ends the walk, and visit raises with its message.
visualize
visualizevisualize(self, path: str) -> None
visualize(self, path: str) -> None
visualize(path) -> None
Write a rendering of the graph's nodes and edges to path (the file suffix picks the format).
walk
walkwalk(self, start: clika_runtime._core.graph.Node, *, direction: clika_runtime._core.graph.WalkDirection = WalkDirection.Forward, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
walk(self, start: clika_runtime._core.graph.Node, *, direction: clika_runtime._core.graph.WalkDirection = WalkDirection.Forward, max_depth: int | None = None, max_nodes: int | None = None, stop_at: collections.abc.Callable | None = None, edge_filter: collections.abc.Callable | None = None, skip_shape_lane: bool = False) -> list
walk(start, *, direction=WalkDirection.Forward, max_depth=None, max_nodes=None, stop_at=None, edge_filter=None, skip_shape_lane=False) -> list[Node]
The nodes a walk from start reaches, in walk order: breadth-first, the start first, each node once at its fewest edges from the start, and a node's neighbors in out_edges() order (in_edges() when direction is Backward). max_depth is the most edges between the start and a node the walk reaches (0 reaches the start alone). max_nodes is the most nodes the walk may reach, the start included: a walk that would reach one more raises InvalidArgumentError naming the budget, never a cut answer. A node stop_at accepts is reached but not gone past (the start included), and the walk crosses only the edges edge_filter accepts. skip_shape_lane crosses no edge that carries shape or index arithmetic (the shape computations the graph optimizer marks; a graph that was not optimized carries no marks). A start of another graph raises InvalidArgumentError; a callable that raises ends the walk, and walk raises with its message.
weakly_connected_components
weakly_connected_componentsweakly_connected_components(self) -> list
weakly_connected_components(self) -> list
weakly_connected_components() -> list[list[Node]]
The groups of nodes joined by edges taken either way, each in name order, the groups ordered by their first node's name.
would_create_cycle
would_create_cyclewould_create_cycle(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> bool
would_create_cycle(self, src: clika_runtime._core.graph.Node, dst: clika_runtime._core.graph.Node) -> bool
would_create_cycle(src, dst) -> bool
True when an edge from src to dst would close a cycle: dst reaches src, or the two are one node.