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 FunctionBuilder

From Leeroopedia


Knowledge Sources
Domains Function Definition, Operator Schema
Last Updated 2026-02-10 00:00 GMT

Overview

Concrete tool for programmatically building ONNX function definitions and expanding function nodes, provided by the ONNX library.

Description

This header declares the interface and helper classes for the ONNX function system. It provides three main components:

FunctionExpandHelper is a free function that expands a function node (NodeProto) into its constituent operations within a target graph (GraphProto). It maps the calling node's inputs, outputs, and attributes to the function body's formal parameters.

FunctionBodyHelper is a utility class for defining function bodies using a concise, declarative syntax. It contains the nested NodeDef struct that allows expressing operations like {{"Z"}, "Add", {"X", "Y"}} to represent Z = Add(X, Y). The AttributeProtoWrapper nested struct enables automatic attribute type inference from C++ types. The class provides static methods BuildNodes and BuildFunctionProto for converting these high-level definitions into protobuf objects.

FunctionBuilder offers a fluent (method-chaining) API for constructing functions. The Add methods accept ONNX text-format node descriptions parsed by OnnxParser, with optional attributes. Const and Const1D create constant nodes from scalar values, tensors, or vectors. AddOpset registers opset dependencies. AddInlinedCall inlines an entire graph into the function with proper variable renaming via the inliner::Renamer utility. AddAttributeToNode and AddAttributes allow attaching attributes to the last added node, with variadic template support.

Usage

Use FunctionBodyHelper when defining operator function bodies during schema registration, where the NodeDef syntax provides a compact representation. Use FunctionBuilder when you need more control over function construction, such as parsing text-format nodes, creating constants of specific types, or inlining subgraphs. Use FunctionExpandHelper to expand function calls during graph transformation or optimization.

Code Reference

Source Location

Signature

// Free function for expanding function nodes
void FunctionExpandHelper(
    const NodeProto& node,
    const FunctionProto& func,
    GraphProto& g,
    const std::string& node_prefix = "");

// FunctionBodyHelper class
class FunctionBodyHelper {
public:
    struct AttributeProtoWrapper { ... };
    struct NodeDef {
        NodeDef(std::vector<std::string> outputs,
                std::string op_type,
                std::vector<std::string> inputs,
                std::vector<AttributeProtoWrapper> attributes = {},
                std::string domain = "");
    };
    static std::vector<NodeProto> BuildNodes(const std::vector<NodeDef>& node_defs);
    static void BuildNodes(FunctionProto& functionProto, const std::vector<NodeDef>& node_defs);
    static bool BuildFunctionProto(FunctionProto& functionProto, const OpSchema& schema,
        const std::vector<NodeDef>& node_defs, const std::vector<OperatorSetIdProto>& relied_opsets);
    template <typename T> static NodeDef Const(const std::string& name, const T& value);
    template <typename T> static NodeDef Const(const std::string& name, const std::vector<T>& values);
};

// FunctionBuilder class
class FunctionBuilder {
public:
    explicit FunctionBuilder(FunctionProto& funProto_);
    FunctionBuilder& Add(const char* nodes_txt);
    FunctionBuilder& Add(const char* node_txt, const AttributeProto& attr);
    template <typename T> FunctionBuilder& Add(const char* node_txt, const std::string& attr_name, const T& attr_value);
    FunctionBuilder& Const(const std::string& name, const TensorProto& tensor);
    template <typename T> FunctionBuilder& Const(const std::string& name, T const_value);
    template <typename T> FunctionBuilder& Const1D(const std::string& name, T const_value);
    template <typename T> FunctionBuilder& Const(const std::string& name, const std::vector<T>& values);
    FunctionBuilder& AddOpset(const char* domain, int version);
    FunctionBuilder& AddInlinedCall(std::initializer_list<std::string_view> outputs,
        const GraphProto& graph, std::initializer_list<std::string_view> inputs, std::string_view prefix);
};

Import

#include "onnx/defs/function.h"

I/O Contract

Inputs (FunctionBuilder::Add)

Name Type Required Description
nodes_txt const char* Yes ONNX text-format node description string to parse
attr const AttributeProto& No Optional attribute to attach to the parsed node
attr_name const std::string& No Attribute name (for template overloads)
attr_value T No Attribute value, type inferred from C++ type

Inputs (FunctionBodyHelper::NodeDef)

Name Type Required Description
outputs std::vector<std::string> Yes Output tensor names for the node
op_type std::string Yes The operator type (e.g., "Add", "Relu")
inputs std::vector<std::string> Yes Input tensor names for the node
attributes std::vector<AttributeProtoWrapper> No Attributes with automatic type inference
domain std::string No Operator domain (defaults to standard ONNX domain)

Outputs

Name Type Description
FunctionBuilder& FunctionBuilder& Returns reference to self for method chaining
NodeProto vector std::vector<NodeProto> Built node protobuf objects (from BuildNodes)
bool bool Success status (from BuildFunctionProto)

Usage Examples

// Using FunctionBodyHelper with NodeDef syntax
std::vector<FunctionBodyHelper::NodeDef> node_defs = {
    {{"Z"}, "Add", {"X", "Y"}},                          // Z = Add(X, Y)
    {{"W"}, "Concat", {"X1", "X2"}, {{"axis", 1}}},      // W = Concat(X1, X2, axis=1)
    {{"R"}, "Foo", {"A", "B"}, {}, "customdomain"},       // R = customdomain.Foo(A, B)
};
std::vector<NodeProto> nodes = FunctionBodyHelper::BuildNodes(node_defs);

// Using FunctionBuilder fluent API
FunctionProto func;
FunctionBuilder builder(func);
builder.Add("Y = Relu(X)")
       .Add("Z = Add(Y, X)")
       .Const("one", 1.0f)
       .Const1D("shape", int64_t(3))
       .AddOpset("", 18);

Related Pages

Page Connections

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