Build and optimize a graph with GraphBuilder#

onnx_light.onnx_core.graph_builder.GraphBuilder incrementally builds ONNX graphs while resolving operator schemas, inferring shapes, and assigning unique value names. This walkthrough uses its compact authoring API and then optimizes a second graph with the standard pattern library.

Create and export a model#

Select every opset before adding its nodes. The empty domain is the standard ONNX domain; a custom operator requires an explicit non-empty domain and an imported version. It does not require a schema registered on the local machine.

The example includes:

  • Add as a standard operator;

  • Clip with an omitted optional min input;

  • variadic Sum inputs;

  • both outputs of TopK;

  • a schema-less com.example::CustomNormalize operator.

    opsets: {'com.example': 7, 'ai.onnx': 18}
    custom node: com.example::CustomNormalize
    TopK outputs: values, indices
    model validated and round-tripped

g.inp declares and returns an input name, g.init adds a NumPy initializer, g.op.<Operator> adds a node, and g.out declares an output. Operator inputs can be value names, NumPy arrays, or None for an omitted optional input. The outputs option accepts one name, a sequence of names, or a positive output count.

The compact helpers delegate to the explicit make_input(), make_initializer(), make_node(), and make_output() methods. Those make_* methods are the complete low-level contract for generated code and advanced authoring.

Optimize and replay a rewrite#

The following model contains a redundant Cast from float to float. Selecting only the standard Cast pattern makes the result deterministic: one LocalRewriting replaces it with Identity.

    Cast: 1 match(es) over 1 attempt(s)
    LocalRewriting(pattern=Cast, graph_path=<root>, matched_nodes=1, added_nodes=1)
    replay reproduced the optimized graph

report aggregates attempts, matches, rejections, and timings by pattern. Each returned LocalRewriting is also a replayable record of the matched and added nodes, their positions, initializer changes, and value renames.