---
title: "ClikaRT::io::OnnxModel"
sidebar_label: "OnnxModel"
description: "An ONNX model, opened from disk or built from scratch. Move-only."
---

<!-- Generated by tools/doxygen2mdx from Doxygen XML. Do not edit. -->

<span class="api-kind api-kind--class">class</span>

**Header:** `ClikaRT/io/onnx_model.h`

An ONNX model, opened from disk or built from scratch. Move-only.

## Static member functions

### open() {#open}

<div class="api-signature">

`static` [`OnnxModel`](./OnnxModel.md) **`open`**(`std::string_view` `path`, [`OnnxModelOptions`](./OnnxModelOptions.md) `options` `=` `{}`)

</div>

Open a `.onnx` file. The graph structure loads into memory (memory-mapped parse); initializer payloads referenced as external data stay on disk beside the model until something consumes them. No compute graph is built and nothing is validated beyond the wire format; [`compile`](./OnnxModel.md#compile) is where operator support is decided.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 103

</div>

### create() {#create}

<div class="api-signature">

`static` [`OnnxModel`](./OnnxModel.md) **`create`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::string_view` `graph_name`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::int64_t` `opset_version` `=` `0`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OnnxModelOptions`](./OnnxModelOptions.md) `options` `=` `{}`<br />
)

</div>

Create an empty model: a named graph at the given `ai.onnx` opset version (and [`OnnxModelOptions::ir_version`](./OnnxModelOptions.md#ir_version)). A version \<= 0 means "solve it": both unset → the library defaults; only the opset given → the minimum IR that supports it; only the IR given → the highest opset it supports. A fully-specified pair is validated against the official ONNX version table; an unsupported combination is an error, so a [`save`](./OnnxModel.md#save)d model is version-valid by construction. Build the graph up with [`add_input`](./OnnxModel.md#add_input) / [`add_initializer`](./OnnxModel.md#add_initializer) / [`add_node`](./OnnxModel.md#add_node) / [`add_output`](./OnnxModel.md#add_output).

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 117

</div>

### from\_graph() {#from_graph}

<div class="api-signature">

`static` [`OnnxModel`](./OnnxModel.md) **`from_graph`**(`const` [`graph::ModelGraph`](../graph/ModelGraph.md)`&` `graph`, `const` [`graph::OnnxExportOptions`](../graph/OnnxExportOptions.md)`&` `options` `=` `{}`)

</div>

Build the ONNX model of [`graph`](../graph/index.md) in memory: the model `graph.export_onnx(path, options)` writes, before it is saved. Inspect, edit, [`optimize`](./OnnxModel.md#optimize), [`save`](./OnnxModel.md#save) or [`compile`](./OnnxModel.md#compile) it like any other model. The model reads the graph's weights only when it is saved or compiled, so it holds no copy of them, and it keeps them alive for as long as it lives. Refused as `ModelGraph::export_onnx` is refused.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 131

</div>

## Member functions

### OnnxModel(OnnxModel) {#OnnxModel}

<div class="api-signature">

**`OnnxModel`**(`OnnxModel&&`) `noexcept`

</div>

Move-only: transfers the model.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 137

</div>

### operator=(OnnxModel) {#operator-assign}

<div class="api-signature">

[`OnnxModel`](./OnnxModel.md)`&` **`operator=`**([`OnnxModel`](./OnnxModel.md)`&&`) `noexcept`

</div>

Move-assign: transfers the model.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 139

</div>

### OnnxModel(OnnxModel) {#OnnxModel-2}

<div class="api-signature">

**`OnnxModel`**(`const OnnxModel&`) `=delete`

</div>

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 140

</div>

### operator=(OnnxModel) {#operator-assign-2}

<div class="api-signature">

[`OnnxModel`](./OnnxModel.md)`&` **`operator=`**(`const` [`OnnxModel`](./OnnxModel.md)`&`) `=delete`

</div>

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 141

</div>

### \~OnnxModel() {#OnnxModel-3}

<div class="api-signature">

**`~OnnxModel`**()

</div>

Releases the parsed model.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 143

</div>

### num\_nodes() {#num_nodes}

<div class="api-signature">

`std::size_t` **`num_nodes`**() `const noexcept`

</div>

graph node count

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 146

</div>

### num\_initializers() {#num_initializers}

<div class="api-signature">

`std::size_t` **`num_initializers`**() `const noexcept`

</div>

initializer (weight) count

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 147

</div>

### opset() {#opset}

<div class="api-signature">

`std::int64_t` **`opset`**() `const noexcept`

</div>

The default (`ai.onnx`) opset version / the model IR version.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 149

</div>

### ir\_version() {#ir_version}

<div class="api-signature">

`std::int64_t` **`ir_version`**() `const noexcept`

</div>

the file's ONNX IR version

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 150

</div>

### inputs() {#inputs}

<div class="api-signature">

`std::vector<`[`spec::TensorSpec`](../spec/TensorSpec.md)`>` **`inputs`**() `const`

</div>

Graph inputs / outputs as (name, dtype, dims) specs, declaration order. A dynamic dimension reads as [`spec::TensorSpec::kDynamicDim`](../spec/TensorSpec.md#kDynamicDim).

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 155

</div>

### outputs() {#outputs}

<div class="api-signature">

`std::vector<`[`spec::TensorSpec`](../spec/TensorSpec.md)`>` **`outputs`**() `const`

</div>

Graph outputs: the same (name, dtype, dims) spec shape as [`inputs()`](./OnnxModel.md#inputs), declaration order.

**Throws**

- `ClikaRT::Error`: when the specs cannot be read.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 159

</div>

### nodes() {#nodes}

<div class="api-signature">

`std::vector<`[`OnnxNodeInfo`](./OnnxNodeInfo.md)`>` **`nodes`**() `const`

</div>

Every node of the graph in graph order (a valid topological order): name, op type, domain, and the tensor names on its input and output slots. The names are what [`add_node`](./OnnxModel.md#add_node) returned and what [`remove_node`](./OnnxModel.md#remove_node) takes, so a node added earlier can be found and removed by name.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 166

</div>

### add\_opset\_domain() {#add_opset_domain}

<div class="api-signature">

`void` **`add_opset_domain`**(`std::string_view` `domain`, `std::int64_t` `version`)

</div>

Declare an additional opset import (e.g. `("com.microsoft", 1)`) for nodes added under a non-standard domain. A model imports a domain once: declaring it again keeps the higher of the two versions, as [`merge`](./OnnxModel.md#merge) does.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 172

</div>

### add\_input(string\_view, DataType, vector\<spec::DimOrInt\>) {#add_input}

<div class="api-signature">

`std::string` **`add_input`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::string_view` `name`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`DataType`](../../index.md#DataType) `dtype`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`const std::vector<`[`spec::DimOrInt`](../spec/DimOrInt.md)`>&` `shape`<br />
)

</div>

Register a graph input / output; returns the tensor name. The shape mixes all three dim spellings (see [`spec::DimOrInt`](../spec/DimOrInt.md)): a concrete extent, an anonymous dynamic dim (any value \<= 0, each occurrence its own), and a [`spec::Dim`](../spec/Dim.md) object, named or identity-tied, so the SAME [`spec::Dim`](../spec/Dim.md) passed to several declarations ties those dims (an anonymous [`spec::Dim`](../spec/Dim.md) gets a systematic model-assigned name: "dim\_0", "dim\_1", …). The [`spec::TensorSpec`](../spec/TensorSpec.md) overload takes back exactly what [`inputs()`](./OnnxModel.md#inputs) / [`outputs()`](./OnnxModel.md#outputs) (here and on [`graph::ModelGraph`](../graph/ModelGraph.md)) hand out: one IO-slot vocabulary across the library.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 185

</div>

### add\_input(spec::TensorSpec) {#add_input-2}

<div class="api-signature">

`std::string` **`add_input`**(`const` [`spec::TensorSpec`](../spec/TensorSpec.md)`&` `spec`)

</div>

Register a graph input / output; returns the tensor name. The shape mixes all three dim spellings (see [`spec::DimOrInt`](../spec/DimOrInt.md)): a concrete extent, an anonymous dynamic dim (any value \<= 0, each occurrence its own), and a [`spec::Dim`](../spec/Dim.md) object, named or identity-tied, so the SAME [`spec::Dim`](../spec/Dim.md) passed to several declarations ties those dims (an anonymous [`spec::Dim`](../spec/Dim.md) gets a systematic model-assigned name: "dim\_0", "dim\_1", …). The [`spec::TensorSpec`](../spec/TensorSpec.md) overload takes back exactly what [`inputs()`](./OnnxModel.md#inputs) / [`outputs()`](./OnnxModel.md#outputs) (here and on [`graph::ModelGraph`](../graph/ModelGraph.md)) hand out: one IO-slot vocabulary across the library.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 189

</div>

### add\_output(string\_view, DataType, vector\<spec::DimOrInt\>) {#add_output}

<div class="api-signature">

`std::string` **`add_output`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::string_view` `name`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`DataType`](../../index.md#DataType) `dtype`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`const std::vector<`[`spec::DimOrInt`](../spec/DimOrInt.md)`>&` `shape`<br />
)

</div>

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 194

</div>

### add\_output(spec::TensorSpec) {#add_output-2}

<div class="api-signature">

`std::string` **`add_output`**(`const` [`spec::TensorSpec`](../spec/TensorSpec.md)`&` `spec`)

</div>

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 198

</div>

### add\_initializer() {#add_initializer}

<div class="api-signature">

`std::string` **`add_initializer`**(`const` [`Tensor`](../Tensor.md)`&` `value`)

</div>

Create an initializer (a graph constant) from a materialized tensor's bytes. Returns the generated initializer name.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 205

</div>

### add\_node() {#add_node}

<div class="api-signature">

`std::vector<std::string>` **`add_node`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::string_view` `op_type`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`const std::vector<std::string>&` `inputs`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`int` `num_outputs`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`const std::vector<`[`OnnxAttr`](./OnnxAttr.md)`>&` `attrs` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::string_view` `domain` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`const std::vector<std::string>&` `output_names` `=` `{}`<br />
)

</div>

Append a node of any op type. [`inputs`](./OnnxModel.md#inputs) are tensor names in the op's positional input slots (an empty string is an omitted interior optional); each of the `num_outputs` outputs gets a generated name, returned in node output order, or, with a non-empty `output_names` (one per output), the caller's exact names (an in-use name is an error). `domain` empty = the standard `ai.onnx` domain. Any other domain must be declared first with [`add_opset_domain`](./OnnxModel.md#add_opset_domain); a node under a domain the model does not import is refused with `InvalidArgument`, and the model is left as it was.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 224

</div>

### remove\_node() {#remove_node}

<div class="api-signature">

`void` **`remove_node`**(`std::string_view` `name`)

</div>

Remove the node named `name` (an error if absent).

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 233

</div>

### optimize() {#optimize}

<div class="api-signature">

`int` **`optimize`**()

</div>

Run the ONNX graph-rewrite pipeline to a fixed point: collapse double casts, drop redundant quantize/dequantize pairs, fuse shape movement, fold constants, eliminate dead nodes. Returns the number of pipeline passes executed.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 240

</div>

### merge() {#merge}

<div class="api-signature">

`void` **`merge`**([`OnnxModel`](./OnnxModel.md) `second`, `const std::vector<std::pair<std::string, std::string>>&` `io_map`)

</div>

Combine `second` into this model (consuming it): each `io_map` entry `(this_output, second_input)` connects one of THIS model's outputs to one of `second`'s inputs; the connected outputs stop being graph outputs and the connected inputs stop being graph inputs; everything unconnected remains, so the combined model's inputs are this model's plus `second`'s unconnected ones, and its outputs are `second`'s plus this model's unconnected ones. Name collisions between the two graphs are resolved automatically (the second model's colliding names are renamed); opset imports merge to the max version per domain.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 253

</div>

### save() {#save}

<div class="api-signature">

`void` **`save`**(`std::string_view` `path`) `const`

</div>

Assemble the model and write it to `path`. Initializer payloads ride inline or in a `<stem>_data` sidecar per [`OnnxModelOptions::save_as_external_data`](./OnnxModelOptions.md#save_as_external_data). A model opened with external-data references saves those references verbatim; keep its sidecar beside the saved file.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 265

</div>

### compile() {#compile}

<div class="api-signature">

[`graph::ModelGraph`](../graph/ModelGraph.md) **`compile`**(`const` [`graph::CompileOptions`](../graph/CompileOptions.md)`&` `options` `=` `{}`) `const`

</div>

Build the executable form: parse every node into its runtime operator (an unsupported op fails here, naming it), bind the weights, resolve shapes per `options` (see [`graph::CompileOptions`](../graph/CompileOptions.md)), and return the [`graph::ModelGraph`](../graph/ModelGraph.md) as built: [`optimize()`](./OnnxModel.md#optimize) it when wanted, then `finalize()` it to run. The [`OnnxModel`](./OnnxModel.md) is unchanged and reusable.

<div class="api-declared">

Declared in `ClikaRT/io/onnx_model.h`, line 274

</div>
