Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Onnx Onnx IR Graph Model

From Leeroopedia


Knowledge Sources
Domains Intermediate Representation, Graph Data Structure, Core Infrastructure
Last Updated 2026-02-10 00:00 GMT

Overview

Defines the core intermediate representation (IR) data structures for ONNX graphs, including the Graph, Node, Value, and Attributes types that form the in-memory representation of ONNX models.

Description

The ir.h header is the absolute core of ONNX's C++ implementation. It defines the complete in-memory graph representation used for model construction, analysis, optimization, and transformation. The design centers on three interconnected structures:

Value represents data flowing between nodes in the graph. Each Value carries type metadata (elem_type_), optional shape information (sizes_ as a vector of Dimension objects), a unique name for identification, and a full TypeProto for complex types. Values track their consumer nodes via a use_list (vector of Use structs), enabling efficient graph traversal and transformation operations like replaceAllUsesWith.

Node represents a single computation operation. It inherits from Attributes<Node> using CRTP (Curiously Recurring Template Pattern) to enable method chaining. Each Node stores its kind (operator type as a Symbol), input/output Values, owning Graph pointer, and optional metadata (name, domain, doc_string, overload). Nodes are linked in a doubly-linked list (next_in_graph array) that maintains topological ordering. Key operations include addInput, replaceInput, insertBefore/insertAfter, and destroy.

Graph owns all Nodes and Values, managing their lifetimes via unordered_set containers. It uses sentinel nodes for the input (kParam), output (kReturn), and standalone initializers (initializer_node_). The Graph provides factory methods (create, appendNode), initializer management, graph traversal (forSelfAndEachSubGraph, forEachNode), and unique name generation.

The Attributes template provides a generic attribute storage mechanism supporting 12 attribute kinds: float, floats, int, ints, string, strings, tensor, tensors, graph, graphs, type_proto, type_protos. The CREATE_ACCESSOR macro generates typed getter/setter pairs for each kind. Attributes are stored in a vector for deterministic ordering with O(n) lookup.

Supporting types include Dimension (representing known integer, symbolic parameter, or unknown dimensions), OpSetID (domain + version pair with string serialization), ResourceGuard (RAII scope guard), and AttributeValue hierarchy (ScalarAttributeValue and VectorAttributeValue templates).

Usage

This header is included by virtually every C++ file in the ONNX project that needs to manipulate graph structures. It is essential for model loading (ir_pb_converter.cc), optimization passes, shape inference, validation, version conversion, and Python binding export. The structures are designed for in-place mutation rather than immutable transformation, favoring performance in optimization workloads.

Code Reference

Source Location

Signature

namespace ONNX_NAMESPACE {

struct Dimension final {
  Dimension();
  explicit Dimension(std::string param);
  explicit Dimension(int64_t dim);
  bool is_unknown;
  bool is_int;
  int64_t dim;
  std::string param;
};

enum class AttributeKind : uint8_t { f, fs, i, is, s, ss, t, ts, g, gs, tp, tps };

struct Value final {
  Value* setElemType(int32_t elem_type);
  Value* setSizes(std::vector<Dimension> sizes);
  Value* setUniqueName(const std::string& name, bool update_related_names = true);
  void replaceAllUsesWith(Value* newValue);
  use_list uses() const;
};

struct Node : public Attributes<Node> {
  NodeKind kind() const;
  ArrayRef<Value*> inputs();
  ArrayRef<Value*> outputs();
  Value* addInput(Value* node);
  Value* addOutput();
  Node* insertBefore(Node* n);
  Node* insertAfter(Node* n);
  void destroy();
};

class OpSetID final {
  static OpSetID fromString(const std::string& target);
  std::string toString() const;
  const std::string& domain() const;
  int64_t version() const;
};

struct Graph final {
  Graph();
  ArrayRef<Value*> inputs();
  ArrayRef<Value*> outputs();
  graph_node_list nodes();
  Node* create(NodeKind kind, size_t num_outputs = 1);
  Node* appendNode(Node* n);
  Value* addInput();
  void addInitializer(Tensor& initializer);
  Value* addInitializerAndCreateValue(Tensor& initializer);
  void forEachNode(const std::function<void(Node*)>& fn);
};

} // namespace ONNX_NAMESPACE

Import

#include "onnx/common/ir.h"

I/O Contract

Inputs

Name Type Required Description
kind NodeKind (Symbol) Yes Operator type symbol when creating a Node
num_outputs size_t No Number of output Values for a new Node (default: 1)
inputs ArrayRef<Value*> No Input Values when creating a Node with inputs
initializer Tensor& Yes (for addInitializer) Tensor data for graph initializers
name std::string No Unique name for Values and Graphs

Outputs

Name Type Description
Graph std::unique_ptr<Graph> Complete in-memory graph representation
Node* Node pointer Created node, registered in the graph
Value* Value pointer Data flow value with type/shape metadata
use_list std::vector<Use> List of all consumers of a Value

Usage Examples

#include "onnx/common/ir.h"

using namespace ONNX_NAMESPACE;

// Create a new graph
Graph g;

// Add graph inputs
Value* x = g.addInput();
x->setUniqueName("X");
x->setElemType(TensorProto_DataType_FLOAT);
x->setSizes({Dimension(1), Dimension(3), Dimension(224), Dimension(224)});

// Create a Relu node
Node* relu = g.create(Symbol("Relu"), 1);
relu->addInput(x);
g.appendNode(relu);

// Register the output
g.registerOutput(relu->output());

// Iterate over all nodes
for (Node* n : g.nodes()) {
    std::cout << n->kind().toString() << std::endl;
}

// Add an initializer
Tensor weight;
weight.setName("weight");
g.addInitializerAndInput(weight, "weight");

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment