graph_graph.h#

Graph index and pattern-rewrite driver over a :cpp:class:core::builder::GraphBuilder.

:cpp:class:core::builder::GraphGraph owns an index over the builder nodes and applies graph-rewrite patterns directly to that builder. It rebuilds its index after every optimization iteration.

Nodes are identified by their address, so the index stores const NodeProto * and maps each to its position in :cpp:func:GraphBuilder::Nodes (this mirrors make_idn / id(node) in Python). The index tracks:

  • the producing node of every value (predecessors);

  • the consuming nodes of every value, deduplicated and in insertion order (successors);

  • the declared graph outputs;

  • the values captured by a nested subgraph from the enclosing scope, so a rewrite never deletes a producer a subgraph still relies on.

On top of the structural index the class also exposes the read-only value queries a pattern needs — shapes, element types and constants — drawing on the builder’s inferred information and constant analysis rather than re-implementing them. Constant-folding results are cached by value name because a name is assigned once and never reused.

namespace onnx_light

Alias that makes onnx-light headers compatible with code that references ONNX_LIGHT_NAMESPACE (the macro used in the standard onnx package).

Set to ONNX_LIGHT_NAMESPACE so both names resolve to the same namespace.

Symbol-visibility attribute for the public onnx-light C++ API.

Maps the upstream compatibility macro to onnx-light’s explicit proto ABI annotation. This keeps declarations from vendored ONNX headers visible when lib_onnx_proto uses hidden visibility by default.

Namespace alias so that ONNX C++ code (and consumers such as onnxruntime) that refers to the literal onnx namespace — rather than the ONNX_NAMESPACE macro — resolves to the onnx-light namespace. The standard onnx package lives in namespace onnx; onnx-light uses onnx_light (via ONNX_LIGHT_NAMESPACE), so this alias keeps onnx-light a true drop-in. It is only introduced when the onnx-light namespace differs from onnx.

namespace core
namespace builder

Functions

GraphProto Replay(const ModelProto &model, const std::vector<LocalRewriting> &rewrites, GraphBuilder::SchemaLookupFn schema_lookup = {})#

Reconstructs an optimized graph by replaying captured rewrites.

Rewrites must be ordered as returned by :cpp:func:GraphGraph::Optimize. Pattern and cleanup records are both applied from that sequence; replay does not rerun matching or cleanup algorithms.

class GraphGraph#
#include <graph_graph.h>

Index and rewrite driver over the nodes of a :cpp:class:GraphBuilder.

The referenced :cpp:class:GraphBuilder must outlive this object. Mutating the builder outside :cpp:func:Optimize invalidates the index.

Public Types

using DoNotRemovePredicate = std::function<bool(const NodeProto&)>#

Predicate that protects matching nodes from removal.

Public Functions

explicit GraphGraph(GraphBuilder &builder)#

Builds the index from builder. The builder must outlive the index.

GraphGraph(GraphBuilder &builder, std::vector<std::unique_ptr<PatternOptimization>> patterns, DoNotRemovePredicate do_not_remove = {})#

Builds the index and uses the supplied patterns in their given order.

GraphGraph(GraphBuilder &builder, std::vector<std::shared_ptr<PatternOptimization>> patterns)#

Builds the index and shares ownership of the supplied patterns.

inline GraphBuilder &Builder() noexcept#

Returns the builder being indexed and optimized.

std::vector<LocalRewriting> Optimize(int max_iter = -1, OptimizationReport *report = nullptr)#

Applies patterns and cleanup passes until convergence.

Patterns are considered in ascending priority order. A negative max_iter selects max(node_count, 10) * priority_count. Replacement nodes whose inputs are all materialized constants are folded into initializers before cleanup.

Returns: Self-contained records of the applied rewrites, in application order.

inline const std::vector<std::shared_ptr<PatternOptimization>> &Patterns() const noexcept#

Returns the patterns shared by this graph optimizer and its rewrites.

const NodeProto *NodeBefore(const std::string &name) const#

Returns the node producing name, or nullptr when name is a graph input, an initializer or otherwise not produced by any node.

const std::vector<const NodeProto*> &NextNodes(const std::string &name) const#

Returns the nodes consuming name (in insertion order, deduplicated). Returns a reference to a shared empty vector when name is unused.

std::vector<const NodeProto*> Predecessors(const NodeProto &node) const#

Returns the nodes producing the inputs of node (its immediate predecessors in the data-flow graph), deduplicated and in input order. Inputs that are graph inputs or initializers contribute no predecessor.

std::vector<const NodeProto*> Successors(const NodeProto &node) const#

Returns the nodes consuming the outputs of node (its immediate successors in the data-flow graph), deduplicated and in output order.

bool IsOutput(const std::string &name) const#

Returns true when name is a declared graph output.

bool IsUsed(const std::string &name) const#

Returns true when name is consumed by a node, captured by a nested subgraph, or declared as a graph output.

bool IsUsedMoreThanOnce(const std::string &name) const#

Returns true when name is consumed by more than one node, captured by a nested subgraph, or declared as a graph output.

bool IsUsedBySubgraph(const std::string &name) const#

Returns true when name is captured by a nested subgraph from the enclosing scope.

std::size_t Position(const NodeProto &node) const#

Returns the position of node in :cpp:func:GraphBuilder::Nodes. Throws :cpp:class:BuilderError when node is not part of the index.

bool HasShape(const std::string &name) const#

Returns true when the shape of name has been inferred.

const SymTensor &GetShape(const std::string &name) const#

Returns the inferred descriptor of name. Throws when it is unknown.

bool HasType(const std::string &name) const#

Returns true when the element type of name is known.

TensorType GetType(const std::string &name) const#

Returns the element type of name. Throws when it is unknown.

bool IsConstant(const std::string &name) const#

Returns true when name is a constant value (an initializer, a Constant output, or the output of a deterministic node whose inputs are all constant), as tracked by the builder’s constant analysis.

bool IsConstantScalar(const std::string &name, bool broadcast = false) const#

Returns true when name is a constant scalar.

A value is scalar when its shape is () or (1,). When broadcast is true a shape whose every dimension is 1 (e.g. (1, 1)) also qualifies. This overload does not compare the stored value.

bool IsConstantScalar(const std::string &name, double value, bool broadcast) const#

Returns true when name is a constant scalar equal to value.

The scalar-shape rules of the other overload apply; in addition the stored value must be readable and compare equal to value.

const TensorProto *GetComputedConstant(const std::string &name) const#

Returns the tensor value of the constant name, or nullptr when the value is not materialised as a :cpp:class:TensorProto (for example a Constant node using value_int / value_float, or a constant that has not been folded). Registered computed constants take precedence over the builder’s initializers and Constant node attributes.

void SetComputedConstant(const std::string &name, TensorProto value)#

Records a folded constant value for name so later queries can read it through :cpp:func:GetComputedConstant. A name is assigned once and never reused, so the cached value stays valid for the lifetime of the index.

Private Functions

void Rebuild()#
void RebuildSuccessors()#
std::size_t Cleanup(std::vector<LocalRewriting> &rewrites, std::size_t &rewrite_batch)#
void ApplyRewritingBatch(const std::vector<LocalRewriting> &rewrites, std::size_t begin, std::size_t end)#
bool ConstantShape(const std::string &name, std::vector<int64_t> &dims) const#
bool ConstantScalarValue(const std::string &name, double &out) const#
bool IsVisibleBefore(const std::string &name, std::size_t position_limit) const#
GraphGraph(GraphBuilder &builder, const std::vector<std::shared_ptr<PatternOptimization>> &patterns, DoNotRemovePredicate do_not_remove, const GraphGraph *parent_graph, std::size_t parent_position_limit)#
std::vector<LocalRewriting> OptimizeImpl(int max_iterations, OptimizationReport *report, const std::vector<std::string> &graph_path)#

Private Members

GraphBuilder &builder_#
std::vector<std::shared_ptr<PatternOptimization>> patterns_#
DoNotRemovePredicate do_not_remove_#
const GraphGraph *parent_graph_ = nullptr#
std::size_t parent_position_limit_ = 0#
std::unordered_map<std::string, const NodeProto*> predecessors_#
std::unordered_map<std::string, std::vector<const NodeProto*>> successors_#
std::unordered_map<const NodeProto*, std::size_t> positions_#
std::unordered_set<std::string> output_names_#
std::unordered_set<std::string> subgraph_captured_#
std::unordered_map<std::string, const TensorProto*> initializers_#
std::unordered_map<std::string, TensorProto> computed_constants_#

Friends

friend GraphProto Replay(const ModelProto &model, const std::vector<LocalRewriting> &rewrites, GraphBuilder::SchemaLookupFn schema_lookup)#

Reconstructs an optimized graph by replaying captured rewrites.

Rewrites must be ordered as returned by :cpp:func:GraphGraph::Optimize. Pattern and cleanup records are both applied from that sequence; replay does not rerun matching or cleanup algorithms.