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 Protobuf Converter

From Leeroopedia


Knowledge Sources
Domains Serialization, Intermediate Representation, Protobuf Conversion
Last Updated 2026-02-10 00:00 GMT

Overview

Implements bidirectional conversion between ONNX Protocol Buffer (protobuf) serialization format and ONNX's internal intermediate representation (IR) graph structures.

Description

The ir_pb_converter.cc file serves as the critical bridge between ONNX's on-disk protobuf format and its in-memory IR representation. The file is logically divided into two halves: Part 1 converts protobuf to IR, and Part 2 converts IR back to protobuf.

Part 1 -- Protobuf to IR: The primary entry point is ImportModelProto(const ModelProto& mp), which validates the IR version (must be >= 2) and delegates to graphProtoToGraph. The graph conversion proceeds in six carefully ordered stages: (1) add all graph input Values owned by the sentinel Param node, (2) add all Nodes and their output Values, (3) initialize inputs of all Nodes by name lookup, (4) initialize inputs of the Return sentinel node, (5) fill in type info for graph outputs, and (6) fill in type info from the value_info list. A value_by_name_of map tracks the correspondence between string names in protobuf and Value pointers in the IR. The function tensorProtoToTensor handles all ONNX data types including newer formats like FLOAT8E4M3FN, FLOAT8E5M2, FLOAT4E2M1, UINT2, and INT2. The function convertAttribute handles all 12 attribute types recursively, including nested graph attributes.

For IR version >= 4, initializers that do not appear in the graph inputs are handled specially via addInitializerAndCreateValue, which creates standalone initializer nodes. Nested subgraphs handle captured values by creating kCaptured dummy nodes for references to outer-scope values.

Part 2 -- IR to Protobuf: The entry point ExportModelProto(ModelProto* p_m, const shared_ptr<Graph>& g) delegates to encodeGraph, which serializes graph inputs, outputs, nodes (skipping kUndefined and kCaptured sentinel nodes), attributes, and initializers. The function encodeTensor handles all data types in the reverse direction. The function encodeValueInfo serializes type and shape information, and addAttribute serializes all 12 attribute kinds back to protobuf format. Value info is selectively saved only when it contains meaningful type/shape data and is not already captured in graph outputs.

The helper function PrepareOutput copies model-level metadata (ir_version, producer_name, producer_version, domain, model_version, doc_string, opset_import, metadata_props) from an input ModelProto to a fresh output, preparing a clean container for graph export.

Usage

This converter is used whenever ONNX models are loaded from or saved to protobuf format. The ImportModelProto function is called during model loading to create the in-memory IR. ExportModelProto is called when saving models after optimization or transformation passes. The version converter also uses PrepareOutput to construct output models while preserving metadata.

Code Reference

Source Location

Signature

namespace ONNX_NAMESPACE {

// Protobuf -> IR
std::unique_ptr<Graph> ImportModelProto(const ModelProto& mp);

// IR -> Protobuf
void ExportModelProto(ModelProto* p_m, const std::shared_ptr<Graph>& g);

// Prepare output model with metadata from input
ModelProto PrepareOutput(const ModelProto& mp_in);

// Assert graph pointer is not null
void assertNonNull(const std::shared_ptr<Graph>& g);

// Internal helpers (static)
static std::unique_ptr<Graph> graphProtoToGraph(
    const GraphProto& gp, bool nested, int ir_version = IR_VERSION);
static Tensor tensorProtoToTensor(const TensorProto& tp);
static void convertAttribute(const AttributeProto& ap, Node* n,
                              int ir_version = IR_VERSION);
static void encodeGraph(GraphProto* p_g, const std::shared_ptr<Graph>& g);
static void encodeTensor(TensorProto* p, const Tensor& tensor);
static void encodeValueInfo(ValueInfoProto* v, Value* n);

} // namespace ONNX_NAMESPACE

Import

#include "onnx/common/ir_pb_converter.h"

I/O Contract

Inputs

Name Type Required Description
mp const ModelProto& Yes (ImportModelProto) Serialized ONNX model in protobuf format
p_m ModelProto* Yes (ExportModelProto) Output model proto to write graph data into
g const shared_ptr<Graph>& Yes (ExportModelProto) In-memory IR graph to serialize
mp_in const ModelProto& Yes (PrepareOutput) Source model for copying metadata

Outputs

Name Type Description
Graph std::unique_ptr<Graph> Complete IR graph with nodes, values, initializers, and opset versions (from ImportModelProto)
ModelProto (mutated) ModelProto* Populated protobuf model with serialized graph (from ExportModelProto)
ModelProto ModelProto New model proto with copied metadata (from PrepareOutput)
nullptr std::unique_ptr<Graph> Returned if ir_version is missing or <= 1

Usage Examples

#include "onnx/common/ir_pb_converter.h"
#include "onnx/onnx_pb.h"

using namespace ONNX_NAMESPACE;

// Load a model from protobuf
ModelProto model_proto;
// ... parse model_proto from file ...

std::unique_ptr<Graph> graph = ImportModelProto(model_proto);
if (!graph) {
    // IR version not supported
    return;
}

// Manipulate the graph
for (Node* node : graph->nodes()) {
    // ... apply optimizations ...
}

// Export back to protobuf
ModelProto output = PrepareOutput(model_proto);
auto graph_ptr = std::shared_ptr<Graph>(std::move(graph));
ExportModelProto(&output, graph_ptr);

// Serialize to file
std::string serialized;
output.SerializeToString(&serialized);

Related Pages

Page Connections

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