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 Proto Visitor

From Leeroopedia


Knowledge Sources
Domains Design Patterns, Graph Traversal
Last Updated 2026-02-10 00:00 GMT

Overview

Concrete tool for traversing ONNX protobuf graph structures using the visitor pattern provided by the ONNX library.

Description

The onnx/common/visitor.h header provides two visitor pattern implementations for traversing ONNX protobuf structures: a read-only Visitor and a mutation-capable MutableVisitor. Both reside in the ONNX_NAMESPACE::internal namespace.

Visitor (read-only) provides virtual methods in two categories:

  • VisitX methods (VisitGraph, VisitFunction, VisitNode, VisitAttribute) that orchestrate traversal. Each VisitX method calls the corresponding ProcessX method and, if it returns true, recursively visits all children.
  • ProcessX methods (ProcessGraph, ProcessFunction, ProcessNode, ProcessAttribute) that serve as callbacks for subclasses to override. They return bool to control whether traversal continues into children. All default to returning true (continue traversal).

The traversal hierarchy is: Graph/Function contains Nodes; Nodes contain Attributes; Attributes may contain sub-Graphs (via attr.g() for single graphs or attr.graphs() for multiple graphs). This enables recursive traversal of nested subgraphs within control flow operators like If and Loop.

MutableVisitor mirrors the same structure but takes pointers instead of const references, allowing modifications to the visited protobuf objects. It uses mutable_node(), mutable_attribute(), mutable_g(), and mutable_graphs() for write access to protobuf fields.

Both classes have virtual destructors for safe polymorphic use.

Usage

Use Visitor when you need to analyze or inspect an ONNX graph without modifying it. Use MutableVisitor when you need to transform graph elements in place. Subclass the appropriate visitor and override the ProcessX methods to implement your specific logic. Return false from a ProcessX method to skip traversal of that element's children.

Code Reference

Source Location

Signature

namespace ONNX_NAMESPACE {
namespace internal {

struct Visitor {
  virtual void VisitGraph(const GraphProto& graph);
  virtual void VisitFunction(const FunctionProto& function);
  virtual void VisitNode(const NodeProto& node);
  virtual void VisitAttribute(const AttributeProto& attr);

  virtual bool ProcessGraph(const GraphProto& graph);
  virtual bool ProcessFunction(const FunctionProto& function);
  virtual bool ProcessNode(const NodeProto& node);
  virtual bool ProcessAttribute(const AttributeProto& attr);

  virtual ~Visitor() = default;
};

struct MutableVisitor {
  virtual void VisitGraph(GraphProto* graph);
  virtual void VisitFunction(FunctionProto* function);
  virtual void VisitNode(NodeProto* node);
  virtual void VisitAttribute(AttributeProto* attr);

  virtual bool ProcessGraph(GraphProto* graph);
  virtual bool ProcessFunction(FunctionProto* function);
  virtual bool ProcessNode(NodeProto* node);
  virtual bool ProcessAttribute(AttributeProto* attr);

  virtual ~MutableVisitor() = default;
};

} // namespace internal
} // namespace ONNX_NAMESPACE

Import

#include "onnx/common/visitor.h"

I/O Contract

Inputs

Name Type Required Description
graph const GraphProto& (Visitor) or GraphProto* (MutableVisitor) Yes The root graph to begin traversal from
function const FunctionProto& or FunctionProto* Yes (alternative) A function to begin traversal from

Outputs

Name Type Description
ProcessX return bool Controls traversal: true continues into children, false skips children
(side effects) varies Subclass-defined behavior via overridden ProcessX methods

Usage Examples

#include "onnx/common/visitor.h"
using namespace ONNX_NAMESPACE;

// Read-only visitor to count nodes
struct NodeCounter : internal::Visitor {
  int count = 0;

  bool ProcessNode(const NodeProto& node) override {
      count++;
      return true;  // continue visiting attributes/subgraphs
  }
};

NodeCounter counter;
counter.VisitGraph(model.graph());
std::cout << "Total nodes: " << counter.count << std::endl;

// Mutable visitor to rename operators
struct OpRenamer : internal::MutableVisitor {
  bool ProcessNode(NodeProto* node) override {
      if (node->op_type() == "OldName") {
          node->set_op_type("NewName");
      }
      return true;  // continue into subgraphs
  }
};

OpRenamer renamer;
renamer.VisitGraph(model.mutable_graph());

// Visitor that skips subgraph traversal
struct TopLevelOnly : internal::Visitor {
  bool ProcessAttribute(const AttributeProto& attr) override {
      return false;  // do not recurse into subgraphs within attributes
  }

  bool ProcessNode(const NodeProto& node) override {
      // only processes top-level nodes
      return true;
  }
};

Related Pages

Page Connections

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