Pattern Optimizer

The pattern optimizer is implemented by class GraphBuilderPatternOptimization. It searches for a specific sequence of nodes in the graph and replaces it by another one without changing the inputs or the long_outputs of the graph. The goal of the optimizer is to make the whole computation graph more efficient. The goal of this implementation is to make this optimization as fast as possible. Assuming the nodes in an onnx graph are ordered in a way every input of a node was created by previous nodes, the optimizer must not require any global reordering. The cost should be in O(N P I) in the worst case where N is the number of nodes, P is the number of patterns, I is the number of iterations.

It is difficult to foresee what a pattern needs in order to rewrite a part of the graph. This API tries to give as much freedom as it can without leaving too much to do to the developper which tries to add a new pattern.

Patterns

Patterns must inherit from PatternOptimization. This class defines two methods.

PatternOptimization.match

def match(
    self,
    g: "GraphBuilderPatternOptimization",
    node: NodeProto,
    matched: List[MatchResult],
) -> Optional[MatchResult]:
  • g is a GraphBuilderPatternOptimization, it holds all the existing nodes, is able to return any information about type, shape, the node before, the node after another one.

  • node: the matching must determine if some nodes around this one are part of set of nodes this pattern optimizer can rewrite. From there, the function explores wherever it needs, checking any condition it needs.

  • matched: usually unused, it returns of nodes already matching a pattern

The method must not modify the graph. The method returns None if no match is found or an instance of class MatchResult. It must contain:

  • a list of nodes involved in the rewriting. It does not mean all of them will be removed but all of them are needed to do the rewriting and must not be impacted by other pattern optimizer.

  • A function doing the rewriting (usually method apply of the pattern class).

  • An existing node where the rewritten nodes can be inserted. Knowing it makes it faster to rewriter. If not specified, the optimizer will automatically determine the position of the new nodes.

Debugging: method none

def none(
    self,
    node: Optional[NodeProto] = None,
    lineno: Optional[int] = None,
    msg: str = "",
):

It may be useful which reason made a pattern matching fail. Instead of returning None, method match can return the following expression:

return self.none(node, inspect.currentframe().f_lineno)

By setting the verbosity (see next Section), the user may then know which lines in the code returned None and which condition failed.

PatternOptimization.apply

@classmethod
def apply(
    cls, g: "GraphBuilder", *nodes: Sequence[NodeProto]
) -> List[NodeProto]:

The method does the rewriting. It assumes it can happen. It takes a list of nodes impacted by the rewriting. It assumes no other pattern optimizer modified them or will modify them. It receives the list of nodes returned by method apply. Since it is a list of argument, method match can include None values. The method returns the new nodes. The optimizer considers that any node given to this function is removed from the graph, and any node returned by it are added. If a received node must be kept, it must be added to the list of returned node.

Optimization Algorithm

It is implemented in method optimize

def optimize(
    self, max_iter=-1, remove_identity: bool = True
) -> List[Dict[str, Any]]:

The algorithm runs multiple iteration until the graph is not evolving or max_iter is reached. By default, it is equal to the number of nodes. An iteration is:

matches = []

builds all successors and predecessors

# Step 1: match

for all patterns P:

    for all nodes n:

        r = p.match(n)
        if r:
            if no node already scheduled to be rewritten by another match:
                matches.append(r)

# Step 2: apply

for all matches r:
    apply the match r

# Step 3: clean

remove unused nodes
remove identity nodes

This algorithm may apply more than one rewriting at each iteration but it guarantees the local structure when applying the rewriting was not altered by another one.

Adding a pattern

See #80 about the addition of a new pattern.

Example

Simple API

We consider the following simple model:

<<<

import torch
from experimental_experiment.helpers import pretty_onnx
from experimental_experiment.xbuilder import OptimizationOptions
from experimental_experiment.torch_interpreter import to_onnx


class MLP(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = torch.nn.Sequential(
            torch.nn.Linear(10, 32),
            torch.nn.ReLU(),
            torch.nn.Linear(32, 1),
        )

    def forward(self, x):
        return self.layers(x)


x = torch.rand(3, 10)
onx = to_onnx(
    MLP(), (x,), input_names=["x"], options=OptimizationOptions(patterns=None)
)
with open("temp_doc_mlp.onnx", "wb") as f:
    f.write(onx.SerializeToString())
print(pretty_onnx(onx))

>>>

    opset: domain='' version=18
    doc_string: large_model=False, inline=False, external_threshold=102...
    input: name='x' type=dtype('float32') shape=[3, 10]
    init: name='layers.0.weight' type=float32 shape=(32, 10)              -- DynamoInterpret.placeholder.1/P(layers.0.weight)
    init: name='layers.0.bias' type=float32 shape=(32,)                   -- DynamoInterpret.placeholder.1/P(layers.0.bias)
    init: name='layers.2.weight' type=float32 shape=(1, 32)               -- DynamoInterpret.placeholder.1/P(layers.2.weight)
    init: name='layers.2.bias' type=float32 shape=(1,) -- array([-0.068], dtype=float32)-- DynamoInterpret.placeholder.1/P(layers.2.bias)
    Transpose(layers.0.weight, perm=[1,0]) -> _onx_transpose0
      MatMul(x, _onx_transpose0) -> _onx_matmul0
        Add(_onx_matmul0, layers.0.bias) -> linear
          Relu(linear) -> relu
    Transpose(layers.2.weight, perm=[1,0]) -> _onx_transpose02
      MatMul(relu, _onx_transpose02) -> _onx_matmul02
        Add(_onx_matmul02, layers.2.bias) -> output_0
    output: name='output_0' type=dtype('float32') shape=[3, 1]

Which we can renders as follows:

digraph{
  ranksep=0.25;
  size=7;
  nodesep=0.05;
  orientation=portrait;

  x [shape=box color=red label="x\nTensorProto.FLOAT\nshape=[3, 10]" fontsize=10];

  output_0 [shape=box color=green label="output_0\nTensorProto.FLOAT\nshape=[3, 1]" fontsize=10];

  layers_0_weight [shape=box label="layers_0_weight\nfloat32((32, 10))\n[[-0.094 -0.066  0.125 -0.114  0.125  0.096 -0.202..." fontsize=10];
  layers_0_bias [shape=box label="layers_0_bias\nfloat32((32,))\n[-0.03  -0.157 -0.19   0.231 -0.291 -0.071 -0.049 ..." fontsize=10];
  layers_2_weight [shape=box label="layers_2_weight\nfloat32((1, 32))\n[[ 0.127 -0.09  -0.092 -0.139  0.173 -0.042  0.145..." fontsize=10];
  layers_2_bias [shape=box label="layers_2_bias\nfloat32((1,))\n[-0.068]" fontsize=10];

  _onx_transpose0 [shape=box label="_onx_transpose0" fontsize=10];
  linear [shape=box style="filled,rounded" color=orange label="Transpose\nperm=[1, 0]" fontsize=10];
  layers_0_weight -> linear;
  linear -> _onx_transpose0;

  _onx_matmul0 [shape=box label="_onx_matmul0" fontsize=10];
  Opset [shape=box style="filled,rounded" color=orange label="MatMul" fontsize=10];
  x -> Opset;
  _onx_transpose0 -> Opset;
  Opset -> _onx_matmul0;

  linear [shape=box label="linear" fontsize=10];
  Opset2 [shape=box style="filled,rounded" color=orange label="Add" fontsize=10];
  _onx_matmul0 -> Opset2;
  layers_0_bias -> Opset2;
  Opset2 -> linear;

  relu [shape=box label="relu" fontsize=10];
  relu [shape=box style="filled,rounded" color=orange label="Relu" fontsize=10];
  linear -> relu;
  relu -> relu;

  _onx_transpose02 [shape=box label="_onx_transpose02" fontsize=10];
  linear2 [shape=box style="filled,rounded" color=orange label="Transpose\nperm=[1, 0]" fontsize=10];
  layers_2_weight -> linear2;
  linear2 -> _onx_transpose02;

  _onx_matmul02 [shape=box label="_onx_matmul02" fontsize=10];
  Opset3 [shape=box style="filled,rounded" color=orange label="MatMul" fontsize=10];
  relu -> Opset3;
  _onx_transpose02 -> Opset3;
  Opset3 -> _onx_matmul02;

  Opset4 [shape=box style="filled,rounded" color=orange label="Add" fontsize=10];
  _onx_matmul02 -> Opset4;
  layers_2_bias -> Opset4;
  Opset4 -> output_0;
}

We then apply the optimizations by writing the following code:

<<<

import onnx
from experimental_experiment.helpers import pretty_onnx
from experimental_experiment.xbuilder import GraphBuilder

onx = onnx.load("temp_doc_mlp.onnx")

# The model is placed in a GraphBuilder.
# It creates dictionnaires to store shapes, ranks, types
# to make it easier to the optimizers to find the information
# they need. It still uses NodeProto to store nodes
gr = GraphBuilder(onx, infer_shapes_options=True)

# Let's optimize.
opt_onx = gr.to_onnx(optimize=True)
with open("temp_doc_mlp_opt.onnx", "wb") as f:
    f.write(opt_onx.SerializeToString())
print(pretty_onnx(opt_onx))

>>>

    opset: domain='' version=18
    doc_string: large_model=False, inline=False, external_threshold=102...
    input: name='x' type=dtype('float32') shape=[3, 10]
    init: name='layers.0.weight' type=float32 shape=(32, 10)              -- DynamoInterpret.placeholder.1/P(layers.0.weight)GraphBuilder._update_structures_with_proto.1/from(layers.0.weight)
    init: name='layers.0.bias' type=float32 shape=(32,)                   -- DynamoInterpret.placeholder.1/P(layers.0.bias)GraphBuilder._update_structures_with_proto.1/from(layers.0.bias)
    init: name='layers.2.weight' type=float32 shape=(1, 32)               -- DynamoInterpret.placeholder.1/P(layers.2.weight)GraphBuilder._update_structures_with_proto.1/from(layers.2.weight)
    init: name='layers.2.bias' type=float32 shape=(1,) -- array([-0.068], dtype=float32)-- DynamoInterpret.placeholder.1/P(layers.2.bias)GraphBuilder._update_structures_with_proto.1/from(layers.2.bias)
    init: name='init7_s2_-1_1' type=int64 shape=(2,) -- array([-1,  1])   -- TransposeEqualReshapePattern.apply.new_shape
    init: name='init7_s2_1_-1' type=int64 shape=(2,) -- array([ 1, -1])   -- TransposeEqualReshapePattern.apply.new_shape
    Gemm(x, layers.0.weight, layers.0.bias, transB=1) -> linear
      Relu(linear) -> relu
    Reshape(layers.2.weight, init7_s2_-1_1) -> _onx_transpose02
      Reshape(_onx_transpose02, init7_s2_1_-1) -> GemmTransposePattern--_onx_transpose02
        Gemm(relu, GemmTransposePattern--_onx_transpose02, layers.2.bias, transB=1) -> output_0
    output: name='output_0' type=dtype('float32') shape=[3, 1]

Which renders as follows:

digraph{
  ranksep=0.25;
  size=7;
  nodesep=0.05;
  orientation=portrait;

  x [shape=box color=red label="x\nTensorProto.FLOAT\nshape=[3, 10]" fontsize=10];

  output_0 [shape=box color=green label="output_0\nTensorProto.FLOAT\nshape=[3, 1]" fontsize=10];

  layers_0_weight [shape=box label="layers_0_weight\nfloat32((32, 10))\n[[-0.094 -0.066  0.125 -0.114  0.125  0.096 -0.202..." fontsize=10];
  layers_0_bias [shape=box label="layers_0_bias\nfloat32((32,))\n[-0.03  -0.157 -0.19   0.231 -0.291 -0.071 -0.049 ..." fontsize=10];
  layers_2_weight [shape=box label="layers_2_weight\nfloat32((1, 32))\n[[ 0.127 -0.09  -0.092 -0.139  0.173 -0.042  0.145..." fontsize=10];
  layers_2_bias [shape=box label="layers_2_bias\nfloat32((1,))\n[-0.068]" fontsize=10];
  init7_s2__1_1 [shape=box label="init7_s2__1_1\nint64((2,))\n[-1  1]" fontsize=10];
  init7_s2_1__1 [shape=box label="init7_s2_1__1\nint64((2,))\n[ 1 -1]" fontsize=10];

  linear [shape=box label="linear" fontsize=10];
  GemmTransposePattern__MatMulAddPattern__Opset2 [shape=box style="filled,rounded" color=orange label="Gemm\ntransB=1" fontsize=10];
  x -> GemmTransposePattern__MatMulAddPattern__Opset2;
  layers_0_weight -> GemmTransposePattern__MatMulAddPattern__Opset2;
  layers_0_bias -> GemmTransposePattern__MatMulAddPattern__Opset2;
  GemmTransposePattern__MatMulAddPattern__Opset2 -> linear;

  relu [shape=box label="relu" fontsize=10];
  relu [shape=box style="filled,rounded" color=orange label="Relu" fontsize=10];
  linear -> relu;
  relu -> relu;

  _onx_transpose02 [shape=box label="_onx_transpose02" fontsize=10];
  TransposeEqualReshapePattern__B__linear2 [shape=box style="filled,rounded" color=orange label="Reshape" fontsize=10];
  layers_2_weight -> TransposeEqualReshapePattern__B__linear2;
  init7_s2__1_1 -> TransposeEqualReshapePattern__B__linear2;
  TransposeEqualReshapePattern__B__linear2 -> _onx_transpose02;

  GemmTransposePattern___onx_transpose02 [shape=box label="GemmTransposePattern___onx_transpose02" fontsize=10];
  TransposeEqualReshapePattern__B__GemmTransposePattern__MatMulAddPattern__Opset3 [shape=box style="filled,rounded" color=orange label="Reshape" fontsize=10];
  _onx_transpose02 -> TransposeEqualReshapePattern__B__GemmTransposePattern__MatMulAddPattern__Opset3;
  init7_s2_1__1 -> TransposeEqualReshapePattern__B__GemmTransposePattern__MatMulAddPattern__Opset3;
  TransposeEqualReshapePattern__B__GemmTransposePattern__MatMulAddPattern__Opset3 -> GemmTransposePattern___onx_transpose02;

  GemmTransposePattern__MatMulAddPattern__Opset32 [shape=box style="filled,rounded" color=orange label="Gemm\ntransB=1" fontsize=10];
  relu -> GemmTransposePattern__MatMulAddPattern__Opset32;
  GemmTransposePattern___onx_transpose02 -> GemmTransposePattern__MatMulAddPattern__Opset32;
  layers_2_bias -> GemmTransposePattern__MatMulAddPattern__Opset32;
  GemmTransposePattern__MatMulAddPattern__Opset32 -> output_0;
}

Verbosity

<<<

import onnx
from experimental_experiment.xbuilder import GraphBuilder

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(onx, infer_shapes_options=True, verbose=1)
opt_onx = gr.to_onnx(optimize=True)

>>>

    [GraphBuilder.optimize] start with 7 nodes
    [GraphBuilder.optimize] #patterns=47
    [GraphBuilderPatternOptimization.optimize] start with 7 nodes, 4 initializers, 47 patterns, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] iteration 0: 7 nodes, priority=0
    [GraphBuilderPatternOptimization.optimize] increase priority to 1
    [GraphBuilderPatternOptimization.optimize] iteration 1: 7 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 3 matches, 2*MatMulAddPattern, 1*TransposeEqualReshapePattern - time=0.000 | max_time=IdentityPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 2: 5 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 2*GemmTransposePattern - time=0.000 | max_time=ReshapeReshapeBinaryPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 3: 7 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 1*TransposeEqualReshapePattern, 1*TransposeTransposePattern - time=0.000 | max_time=TransposeMatMulPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 4: 5 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] stops current_priority_index=2, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] done after 5 iterations with 5 nodes in 0.004
    [GraphBuilder.optimize] done with 5 nodes in 0.005
    [GraphBuilder-EOU.to_onnx] make_model 6 inits 0 params
    [GraphBuilder-EOU.time_evaluation_constants_] 0
    [GraphBuilder-EOU._build_initializers] start with 6 initializers, large_model=False, external_threshold=1024
    [GraphBuilder-EOU._build_initializers] switch low/high order
    [GraphBuilder-EOU._build_initializers] done in 6.629998097196221e-07s with 6 initializers, 0 large initializers

With more verbosity:

<<<

import onnx
from experimental_experiment.xbuilder import GraphBuilder

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(onx, infer_shapes_options=True, verbose=11)
opt_onx = gr.to_onnx(optimize=True)

>>>

    [GraphBuilder._update_structures_with_proto] -- starts with 7 nodes
    [GraphBuilder-TYU.set_shape] layers.0.weight:(32, 10)
    [GraphBuilder-TYU.set_rank] layers.0.weight:2
    [GraphBuilder-TYU.set_type] layers.0.weight:1
    [GraphBuilder-TYU.make_initializer] layers.0.weight[1:(32, 10)]
    [GraphBuilder.update_node_constant] new constant 'layers.0.weight', node=None
    [GraphBuilder-TYU.set_shape] layers.0.bias:(32,)
    [GraphBuilder-TYU.set_rank] layers.0.bias:1
    [GraphBuilder-TYU.set_type] layers.0.bias:1
    [GraphBuilder-TYU.make_initializer] layers.0.bias[1:(32,)]
    [GraphBuilder.update_node_constant] new constant 'layers.0.bias', node=None
    [GraphBuilder-TYU.set_shape] layers.2.weight:(1, 32)
    [GraphBuilder-TYU.set_rank] layers.2.weight:2
    [GraphBuilder-TYU.set_type] layers.2.weight:1
    [GraphBuilder-TYU.make_initializer] layers.2.weight[1:(1, 32)]
    [GraphBuilder.update_node_constant] new constant 'layers.2.weight', node=None
    [GraphBuilder-TYU.set_shape] layers.2.bias:(1,)
    [GraphBuilder-TYU.set_rank] layers.2.bias:1
    [GraphBuilder-TYU.set_type] layers.2.bias:1
    [GraphBuilder-TYU.make_initializer] layers.2.bias[1:(1,)]
    [GraphBuilder.update_node_constant] new constant 'layers.2.bias', node=None
    [GraphBuilder-TYU.set_type] x:1
    [GraphBuilder-TYU.set_shape] x:(3, 10)
    [GraphBuilder-TYU.set_rank] x:2
    [GraphBuilder-TYU.set_type] output_0:1
    [GraphBuilder-TYU.set_shape] output_0:(3, 1)
    [GraphBuilder-TYU.set_rank] output_0:2
    [GraphBuilder.update_node_constant] new constant '_onx_transpose0', node=Transpose
    [GraphBuilder-TYU.set_type] _onx_transpose0:1
    [GraphBuilder-TYU.set_shape] _onx_transpose0:(10, 32)
    [GraphBuilder-TYU.set_rank] _onx_transpose0:2
    [GraphBuilder-TYU.set_type] _onx_transpose0:1
    [GraphBuilder-TYU.set_type] _onx_matmul0:1
    [GraphBuilder-TYU.set_shape] _onx_matmul0:(3, 32)
    [GraphBuilder-TYU.set_rank] _onx_matmul0:2
    [GraphBuilder-TYU.set_type] _onx_matmul0:1
    [GraphBuilder-TYU.set_type] linear:1
    [GraphBuilder-TYU.set_shape] linear:(3, 32)
    [GraphBuilder-TYU.set_rank] linear:2
    [GraphBuilder-TYU.set_type] linear:1
    [GraphBuilder-TYU.set_type] relu:1
    [GraphBuilder-TYU.set_shape] relu:(3, 32)
    [GraphBuilder-TYU.set_rank] relu:2
    [GraphBuilder-TYU.set_type] relu:1
    [GraphBuilder.update_node_constant] new constant '_onx_transpose02', node=Transpose
    [GraphBuilder-TYU.set_type] _onx_transpose02:1
    [GraphBuilder-TYU.set_shape] _onx_transpose02:(32, 1)
    [GraphBuilder-TYU.set_rank] _onx_transpose02:2
    [GraphBuilder-TYU.set_type] _onx_transpose02:1
    [GraphBuilder-TYU.set_type] _onx_matmul02:1
    [GraphBuilder-TYU.set_shape] _onx_matmul02:(3, 1)
    [GraphBuilder-TYU.set_rank] _onx_matmul02:2
    [GraphBuilder-TYU.set_type] _onx_matmul02:1
    [GraphBuilder-TYU.set_type] output_0:1
    [GraphBuilder._update_structures_with_proto] ends with 7 nodes in 0.0004256609972799197
    [GraphBuilder.constant_folding] -- starts with 6 constants and 7 nodes.
    [GraphBuilder.constant_folding] cst:: 1 :: layers.2.weight
    [GraphBuilder.constant_folding] cst:: . :: _onx_matmul0
    [GraphBuilder.constant_folding] cst:: . :: linear
    [GraphBuilder.constant_folding] cst:: . :: _onx_matmul02
    [GraphBuilder.constant_folding] cst:: . :: x
    [GraphBuilder.constant_folding] cst:: 1 :: layers.0.bias
    [GraphBuilder.constant_folding] cst:: 1 :: _onx_transpose0
    [GraphBuilder.constant_folding] cst:: 1 :: layers.2.bias
    [GraphBuilder.constant_folding] cst:: . :: relu
    [GraphBuilder.constant_folding] cst:: 1 :: _onx_transpose02
    [GraphBuilder.constant_folding] cst:: 1 :: layers.0.weight
    [GraphBuilder.constant_folding] cst:: . :: output_0
    [GraphBuilder.constant_folding] initializer: layers.0.weight
    [GraphBuilder.constant_folding] initializer: layers.0.bias
    [GraphBuilder.constant_folding] initializer: layers.2.weight
    [GraphBuilder.constant_folding] initializer: layers.2.bias
    [GraphBuilder.constant_folding] from: Transpose(_onx_transpose0)
    [GraphBuilder.constant_folding] fold_constant:Transpose:_onx_transpose0[torch.float32:torch.Size([10, 32])]:from:layers.0.weight
    [GraphBuilder.constant_folding] from: Transpose(_onx_transpose02)
    [GraphBuilder.constant_folding] fold_constant:Transpose:_onx_transpose02[torch.float32:torch.Size([32, 1])]:from:layers.2.weight
    [GraphBuilder.update_node_constant] new constant '_onx_transpose0', node=Transpose
    [GraphBuilder.update_node_constant] new constant '_onx_transpose02', node=Transpose
    [GraphBuilder.constant_folding] ends with 6 constants and 7 nodes in 0.0001628680038265884 seconds
    [GraphBuilder._update_shape_types_with_proto] -- starts with 7 nodes and 11 shapes.
    [GraphBuilder._update_shape_types_with_proto] infer shapes
    [GraphBuilder._update_shape_types_with_proto] infer shapes done 9.616200986783952e-05 seconds
    [GraphBuilder._update_shape_types_with_proto] _clean_shapes after 0.00012126800720579922 seconds
    [GraphBuilder._update_shape_types_with_proto] walk through 11 shapes.
    [GraphBuilder-TYU.set_type] _onx_matmul0:1
    [GraphBuilder-TYU.set_type] p_layers_0_bias:1
    [GraphBuilder-TYU.set_shape] p_layers_0_bias:(32,)
    [GraphBuilder-TYU.set_rank] p_layers_0_bias:1
    [GraphBuilder-TYU.set_type] linear:1
    [GraphBuilder-TYU.set_type] p_layers_2_weight:1
    [GraphBuilder-TYU.set_shape] p_layers_2_weight:(1, 32)
    [GraphBuilder-TYU.set_rank] p_layers_2_weight:2
    [GraphBuilder-TYU.set_type] _onx_matmul02:1
    [GraphBuilder-TYU.set_type] p_layers_2_bias:1
    [GraphBuilder-TYU.set_shape] p_layers_2_bias:(1,)
    [GraphBuilder-TYU.set_rank] p_layers_2_bias:1
    [GraphBuilder-TYU.set_type] _onx_transpose0:1
    [GraphBuilder-TYU.set_type] linear_1:1
    [GraphBuilder-TYU.set_shape] linear_1:(3, 1)
    [GraphBuilder-TYU.set_rank] linear_1:2
    [GraphBuilder-TYU.set_type] relu:1
    [GraphBuilder-TYU.set_type] _onx_transpose02:1
    [GraphBuilder-TYU.set_type] p_layers_0_weight:1
    [GraphBuilder-TYU.set_shape] p_layers_0_weight:(32, 10)
    [GraphBuilder-TYU.set_rank] p_layers_0_weight:2
    [GraphBuilder._update_shape_types_with_proto] ends in 9.844799933489412e-05 seconds.
    [GraphBuilder.optimize] start with 7 nodes
    [GraphBuilder.optimize] options=OptimizationOptions(remove_unused=True, remove_identity=True,
        constant_folding=False, constant_size=1024, constant_fusing=True,
        verbose=11, max_iter=-1, recursive=False, processor=CPU, order=None,
        patterns=['BatchNormalizationPattern', 'BatchNormalizationTrainingPattern',
        'CastLayerNormalizationCastPattern', 'CastPattern', 'CastCastBinaryPattern',
        'CastOpCastPattern', 'ClipClipPattern', 'ComputationCastOpCastPattern',
        'ConvBiasNullPattern', 'DropoutPattern', 'ExpandPattern',
        'ExpandBroadcastPattern', 'ExpandSwapPattern', 'GeluPattern',
        'IdentityPattern', 'LayerNormalizationPattern',
        'LayerNormalizationScalePattern', 'LeakyReluPattern',
        'MulMulMulScalarPattern', 'ReduceReshapePattern',
        'ReduceSumNormalizePattern', 'ReshapePattern',
        'ReshapeMatMulReshapePattern', 'Reshape2Of3Pattern',
        'ReshapeReshapeBinaryPattern', 'MatMulAddPattern', 'GemmTransposePattern',
        'MatMulReshape2Of3Pattern', 'MulMulMatMulPattern', 'ReshapeReshapePattern',
        'RotaryConcatPartPattern', 'SameChildrenPattern',
        'SequenceConstructAtPattern', 'SliceSlicePattern', 'SlicesSplitPattern',
        'SoftmaxCrossEntropyLossCastPattern', 'SplitConcatPattern',
        'Sub1MulPattern', 'SwitchOrderBinaryPattern',
        'SwitchReshapeActivationPattern', 'TransposeEqualReshapePattern',
        'TransposeMatMulPattern', 'TransposeReshapeMatMulPattern',
        'TransposeReshapeTransposePattern', 'TransposeTransposePattern',
        'UnsqueezeEqualPattern', 'UnsqueezeUnsqueezePattern'])
    [GraphBuilder.remove_identity_nodes] -- starts with 7
    [GraphBuilder.remove_identity_nodes] found 0 replacements
    [GraphBuilder.remove_identity_nodes] kept 7 nodes
    [GraphBuilder.remove_identity_nodes] ends with 7 nodes in 4.3159001506865025e-05 seconds
    [GraphBuilderPatternOptimization.optimize] start with 7 nodes, 4 initializers, 47 patterns, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] use pattern   1/47 - P0 - BatchNormalizationPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   2/47 - P0 - BatchNormalizationTrainingPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   3/47 - P0 - CastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   4/47 - P0 - ConvBiasNullPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   5/47 - P0 - ExpandPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   6/47 - P0 - GeluPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   7/47 - P0 - IdentityPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   8/47 - P0 - LeakyReluPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern   9/47 - P0 - ReshapePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  10/47 - P0 - ReshapeReshapePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  11/47 - P0 - SameChildrenPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  12/47 - P0 - SoftmaxCrossEntropyLossCastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  13/47 - P0 - TransposeReshapeTransposePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  14/47 - P0 - TransposeTransposePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  15/47 - P0 - UnsqueezeUnsqueezePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  16/47 - P1 - CastCastBinaryPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  17/47 - P1 - CastLayerNormalizationCastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  18/47 - P1 - CastOpCastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  19/47 - P1 - ClipClipPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  20/47 - P1 - ComputationCastOpCastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  21/47 - P1 - DropoutPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  22/47 - P1 - ExpandBroadcastPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  23/47 - P1 - ExpandSwapPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  24/47 - P1 - GemmTransposePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  25/47 - P1 - LayerNormalizationPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  26/47 - P1 - LayerNormalizationScalePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  27/47 - P1 - MatMulAddPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  28/47 - P1 - MatMulReshape2Of3Pattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  29/47 - P1 - MulMulMatMulPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  30/47 - P1 - MulMulMulScalarPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  31/47 - P1 - ReduceReshapePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  32/47 - P1 - ReduceSumNormalizePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  33/47 - P1 - Reshape2Of3Pattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  34/47 - P1 - ReshapeMatMulReshapePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  35/47 - P1 - ReshapeReshapeBinaryPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  36/47 - P1 - RotaryConcatPartPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  37/47 - P1 - SequenceConstructAtPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  38/47 - P1 - SliceSlicePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  39/47 - P1 - SlicesSplitPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  40/47 - P1 - SplitConcatPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  41/47 - P1 - Sub1MulPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  42/47 - P1 - SwitchOrderBinaryPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  43/47 - P1 - SwitchReshapeActivationPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  44/47 - P1 - TransposeEqualReshapePattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  45/47 - P1 - TransposeMatMulPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  46/47 - P1 - TransposeReshapeMatMulPattern()
    [GraphBuilderPatternOptimization.optimize] use pattern  47/47 - P1 - UnsqueezeEqualPattern()
    --
    
    opset: : 18
    init: layers.0.weight: ?: ?                                            -- GraphBuilder._update_structures_with_proto.1/from(layers.0.weight)
    init: layers.0.bias: ?: ?                                              -- GraphBuilder._update_structures_with_proto.1/from(layers.0.bias)
    init: layers.2.weight: ?: ?                                            -- GraphBuilder._update_structures_with_proto.1/from(layers.2.weight)
    init: layers.2.bias: ?: ?                                              -- GraphBuilder._update_structures_with_proto.1/from(layers.2.bias)
    input:: x                                                                       |T1: 3 x 10
    Transpose: layers.0.weight -> _onx_transpose0                                   |T1: 10 x 32                  - linear
    MatMul: x, _onx_transpose0 -> _onx_matmul0                                      |T1: 3 x 32                   - Opset
    Add: _onx_matmul0, layers.0.bias -> linear                                      |T1: 3 x 32                   - Opset2
    Relu: linear -> relu                                                            |T1: 3 x 32                   - relu
    Transpose: layers.2.weight -> _onx_transpose02                                  |T1: 32 x 1                   - linear2
    MatMul: relu, _onx_transpose02 -> _onx_matmul02                                 |T1: 3 x 1                    - Opset3
    Add: _onx_matmul02, layers.2.bias -> output_0                                   |T1: 3 x 1                    - Opset4
    output:: output_0                                                               |T1: 3 x 1
    --
    [GraphBuilderPatternOptimization.optimize] iteration 0: 7 nodes, priority=0
    [PatternOptimization.enumerate_matches] start BatchNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationTrainingPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips CastLayerNormalizationCastPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start CastPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips CastCastBinaryPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips CastOpCastPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ClipClipPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ComputationCastOpCastPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start ConvBiasNullPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips DropoutPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start ExpandPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips ExpandBroadcastPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ExpandSwapPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start GeluPattern with main_opset=18 and min_opset=20
    [PatternOptimization.enumerate_matches] start IdentityPattern with main_opset=18 and min_opset=1
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear
    [IdentityPattern.match] NONE - line: 197:experimental_experiment.xoptim.patterns.onnx_any, op_type=Add, name=Opset2
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear2
    [IdentityPattern.match] NONE - line: 210:experimental_experiment.xoptim.patterns.onnx_any, op_type=Add, name=Opset4
    [GraphBuilderPatternOptimization.optimize] skips LayerNormalizationPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips LayerNormalizationScalePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start LeakyReluPattern with main_opset=18 and min_opset=6
    [GraphBuilder-NBK.make_tensor_input] x[0:None] -- marker=_build_pattern1_x
    [GraphBuilder-NBK.set_type] x:-1
    [GraphBuilder-NBK.make_tensor_input] zero[0:None] -- marker=_build_pattern1_zero
    [GraphBuilder-NBK.set_type] zero:-1
    [GraphBuilder-NBK.make_tensor_input] slope[0:None] -- marker=_build_pattern1_slope
    [GraphBuilder-NBK.set_type] slope:-1
    [GraphBuilder-NBK.make_node] [TT:-] Greater: ['x', 'zero']->['_onx_greater0']
    [GraphBuilder-NBK.set_type] _onx_greater0:9
    [GraphBuilder-NBK.make_node] [TT:-] Mul: ['x', 'slope']->['_onx_mul0']
    [GraphBuilder-NBK.set_type] _onx_mul0:-1
    [GraphBuilder-NBK.make_node] [TTT:-] Where: ['_onx_greater0', 'x', '_onx_mul0']->['_onx_where0']
    [GraphBuilder-NBK.set_type] _onx_where0:-1
    [GraphBuilder-NBK.make_tensor_output] _onx_where0[0: None]
    [GraphBuilderPatternOptimization.optimize] skips MulMulMulScalarPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ReduceReshapePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ReduceSumNormalizePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start ReshapePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips ReshapeMatMulReshapePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips Reshape2Of3Pattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips ReshapeReshapeBinaryPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips MatMulAddPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips GemmTransposePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips MatMulReshape2Of3Pattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips MulMulMatMulPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start ReshapeReshapePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips RotaryConcatPartPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start SameChildrenPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] skips SequenceConstructAtPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips SliceSlicePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips SlicesSplitPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start SoftmaxCrossEntropyLossCastPattern with main_opset=18 and min_opset=14
    [GraphBuilder-TEE.make_tensor_input] X[0:None] -- marker=_build_pattern1_X
    [GraphBuilder-TEE.set_type] X:-1
    [GraphBuilder-TEE.make_tensor_input] indices[0:None] -- marker=_build_pattern1_indices
    [GraphBuilder-TEE.set_type] indices:-1
    [GraphBuilder-TEE.make_tensor_input] axis[0:None] -- marker=_build_pattern1_axis
    [GraphBuilder-TEE.set_type] axis:-1
    [GraphBuilder-TEE.make_tensor_input] zerof[0:None] -- marker=_build_pattern1_zerof
    [GraphBuilder-TEE.set_type] zerof:-1
    [GraphBuilder-TEE.make_tensor_input] zeroi[0:None] -- marker=_build_pattern1_zeroi
    [GraphBuilder-TEE.set_type] zeroi:-1
    [GraphBuilder-TEE.make_tensor_input] b[0:None] -- marker=_build_pattern1_b
    [GraphBuilder-TEE.set_type] b:-1
    [GraphBuilder-TEE.make_node] [TT:-] Equal: ['indices', 'b']->['_onx_equal0']
    [GraphBuilder-TEE.set_type] _onx_equal0:9
    [GraphBuilder-TEE.make_node] [T:-] Not: ['_onx_equal0']->['_onx_not0']
    [GraphBuilder-TEE.set_type] _onx_not0:9
    [GraphBuilder-TEE.make_node] [TTT:-] Where: ['_onx_not0', 'indices', 'zeroi']->['_onx_where0']
    [GraphBuilder-TEE.set_type] _onx_where0:-1
    [GraphBuilder-TEE.make_node] [TT:-] Unsqueeze: ['_onx_where0', 'axis']->['_onx_unsqueeze0']
    [GraphBuilder-TEE.set_type] _onx_unsqueeze0:-1
    [GraphBuilder-TEE.make_node] [T:-] LogSoftmax: ['X']->['_onx_logsoftmax0']
    [GraphBuilder-TEE.set_type] _onx_logsoftmax0:-1
    [GraphBuilder-TEE.set_type] _onx_gatherelements0:-1
    [GraphBuilder-TEE.make_node] [TT:T] GatherElements: ['_onx_logsoftmax0', '_onx_unsqueeze0']->['_onx_gatherelements0']
    [GraphBuilder-TEE.set_type] _onx_gatherelements0:-1
    [GraphBuilder-TEE.make_node] [TT:-] Squeeze: ['_onx_gatherelements0', 'axis']->['_onx_squeeze0']
    [GraphBuilder-TEE.set_type] _onx_squeeze0:-1
    [GraphBuilder-TEE.make_node] [T:-] Neg: ['_onx_squeeze0']->['_onx_neg0']
    [GraphBuilder-TEE.set_type] _onx_neg0:-1
    [GraphBuilder-TEE.make_node] [TTT:-] Where: ['_onx_not0', '_onx_neg0', 'zerof']->['_onx_where02']
    [GraphBuilder-TEE.set_type] _onx_where02:-1
    [GraphBuilder-TEE.make_node] [T:-] Cast: ['_onx_not0']->['_onx_cast0']
    [GraphBuilder-TEE.set_type] _onx_cast0:1
    [GraphBuilder-TEE.make_node] [T:-] ReduceSum: ['_onx_cast0']->['_onx_reducesum0']
    [GraphBuilder-TEE.set_type] _onx_reducesum0:1
    [GraphBuilder-TEE.set_shape] _onx_reducesum0:()
    [GraphBuilder-TEE.set_rank] _onx_reducesum0:0
    [GraphBuilder-TEE.make_node] [#:-] Cast: ['_onx_reducesum0']->['_onx_cast02']
    [GraphBuilder-TEE.set_type] _onx_cast02:10
    [GraphBuilder-TEE.set_shape] _onx_cast02:()
    [GraphBuilder-TEE.set_rank] _onx_cast02:0
    [GraphBuilder-TEE.make_node] [T:-] Cast: ['_onx_where02']->['_onx_cast03']
    [GraphBuilder-TEE.set_type] _onx_cast03:1
    [GraphBuilder-TEE.make_node] [T:-] ReduceSum: ['_onx_cast03']->['_onx_reducesum02']
    [GraphBuilder-TEE.set_type] _onx_reducesum02:1
    [GraphBuilder-TEE.set_shape] _onx_reducesum02:()
    [GraphBuilder-TEE.set_rank] _onx_reducesum02:0
    [GraphBuilder-TEE.make_node] [#:-] Cast: ['_onx_reducesum02']->['_onx_cast04']
    [GraphBuilder-TEE.set_type] _onx_cast04:10
    [GraphBuilder-TEE.set_shape] _onx_cast04:()
    [GraphBuilder-TEE.set_rank] _onx_cast04:0
    [GraphBuilder-TEE.make_node] [##:-] Div: ['_onx_cast04', '_onx_cast02']->['_onx_div0']
    [GraphBuilder-TEE.set_type] _onx_div0:10
    [GraphBuilder-TEE.set_shape] _onx_div0:()
    [GraphBuilder-TEE.set_rank] _onx_div0:0
    [GraphBuilder-TEE.make_tensor_output] _onx_div0[0: None]
    [GraphBuilderPatternOptimization.optimize] skips SplitConcatPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips Sub1MulPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips SwitchOrderBinaryPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips SwitchReshapeActivationPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips TransposeEqualReshapePattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips TransposeMatMulPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] skips TransposeReshapeMatMulPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start TransposeReshapeTransposePattern with main_opset=18 and min_opset=1
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear2
    [PatternOptimization.enumerate_matches] start TransposeTransposePattern with main_opset=18 and min_opset=1
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear2
    [GraphBuilderPatternOptimization.optimize] skips UnsqueezeEqualPattern, pattern.priority=1, current_priority_index=0, priorities[current_priority_index]=0 priorities=[0, 1]
    [PatternOptimization.enumerate_matches] start UnsqueezeUnsqueezePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] done all: -0 +0 nodes
    [GraphBuilder.remove_identity_nodes] -- starts with 7
    [GraphBuilder.remove_identity_nodes] found 0 replacements
    [GraphBuilder.remove_identity_nodes] kept 7 nodes
    [GraphBuilder.remove_identity_nodes] ends with 7 nodes in 2.1427011233754456e-05 seconds
    [GraphBuilderPatternOptimization.optimize] increase priority to 1
    [GraphBuilderPatternOptimization.optimize] iteration 1: 7 nodes, priority=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationTrainingPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastLayerNormalizationCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastCastBinaryPattern with main_opset=18 and min_opset=1
    [CastCastBinaryPattern.match] NONE - line: 86:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset2
    [CastCastBinaryPattern.match] NONE - line: 86:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start CastOpCastPattern with main_opset=18 and min_opset=1
    [CastOpCastPattern.match] NONE - line: 162:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset2
    [CastOpCastPattern.match] NONE - line: 159:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start ClipClipPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ComputationCastOpCastPattern with main_opset=18 and min_opset=1
    [ComputationCastOpCastPattern.match] NONE - line: 303:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset2
    [ComputationCastOpCastPattern.match] NONE - line: 303:experimental_experiment.xoptim.patterns.onnx_cast, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start ConvBiasNullPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start DropoutPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandBroadcastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandSwapPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start GeluPattern with main_opset=18 and min_opset=20
    [PatternOptimization.enumerate_matches] start IdentityPattern with main_opset=18 and min_opset=1
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear
    [IdentityPattern.match] NONE - line: 197:experimental_experiment.xoptim.patterns.onnx_any, op_type=Add, name=Opset2
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear2
    [IdentityPattern.match] NONE - line: 210:experimental_experiment.xoptim.patterns.onnx_any, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start LayerNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LayerNormalizationScalePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LeakyReluPattern with main_opset=18 and min_opset=6
    [PatternOptimization.enumerate_matches] start MulMulMulScalarPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceSumNormalizePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeMatMulReshapePattern with main_opset=18 and min_opset=1
    [ReshapeMatMulReshapePattern.match] NONE - line: 765:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset
    [ReshapeMatMulReshapePattern.match] NONE - line: 765:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset3
    [PatternOptimization.enumerate_matches] start Reshape2Of3Pattern with main_opset=18 and min_opset=1
    [Reshape2Of3Pattern.match] NONE - line: 227:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Add, name=Opset2
    [Reshape2Of3Pattern.match] NONE - line: 227:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start ReshapeReshapeBinaryPattern with main_opset=18 and min_opset=1
    [ReshapeReshapeBinaryPattern.match] NONE - line: 389:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Add, name=Opset2
    [ReshapeReshapeBinaryPattern.match] NONE - line: 389:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Add, name=Opset4
    [PatternOptimization.enumerate_matches] start MatMulAddPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']
    [PatternOptimization.enumerate_matches] start GemmTransposePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MatMulReshape2Of3Pattern with main_opset=18 and min_opset=1
    [MatMulReshape2Of3Pattern.match] NONE - line: 390:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset
    [MatMulReshape2Of3Pattern.match] NONE - line: 390:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset3
    [PatternOptimization.enumerate_matches] start MulMulMatMulPattern with main_opset=18 and min_opset=1
    [MulMulMatMulPattern.match] NONE - line: 701:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset
    [MulMulMatMulPattern.match] NONE - line: 704:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset3
    [PatternOptimization.enumerate_matches] start ReshapeReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start RotaryConcatPartPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SameChildrenPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SequenceConstructAtPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SliceSlicePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SlicesSplitPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SoftmaxCrossEntropyLossCastPattern with main_opset=18 and min_opset=14
    [PatternOptimization.enumerate_matches] start SplitConcatPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Sub1MulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchOrderBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchReshapeActivationPattern with main_opset=18 and min_opset=1
    [SwitchReshapeActivationPattern.match] NONE - line: 1163:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Relu, name=relu
    [PatternOptimization.enumerate_matches] start TransposeEqualReshapePattern with main_opset=18 and min_opset=1
    [TransposeEqualReshapePattern.match] NONE - line: 342:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: TransposeEqualReshapePattern replaces ['Transpose']
    [PatternOptimization.enumerate_matches] start TransposeMatMulPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.match] OVERLAP match=MatchResult: TransposeMatMulPattern replaces ['Transpose', 'MatMul'] #marked: 5)
    [GraphBuilderPatternOptimization.match] OVERLAP match=MatchResult: TransposeMatMulPattern replaces ['Transpose', 'MatMul'] #marked: 5)
    [PatternOptimization.enumerate_matches] start TransposeReshapeMatMulPattern with main_opset=18 and min_opset=1
    [TransposeReshapeMatMulPattern.match] NONE - line: 1018:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset
    [TransposeReshapeMatMulPattern.match] NONE - line: 1018:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=MatMul, name=Opset3
    [PatternOptimization.enumerate_matches] start TransposeReshapeTransposePattern with main_opset=18 and min_opset=1
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear2
    [PatternOptimization.enumerate_matches] start TransposeTransposePattern with main_opset=18 and min_opset=1
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear2
    [PatternOptimization.enumerate_matches] start UnsqueezeEqualPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start UnsqueezeUnsqueezePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] applies 3 matches, 2*MatMulAddPattern, 1*TransposeEqualReshapePattern - time=0.001 | max_time=IdentityPattern:0.000
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: MatMulAddPattern replaces ['MatMul', 'Add'], inputs: {'_onx_transpose0', '_onx_matmul0', 'x', 'layers.0.bias'}, outputs: {'_onx_matmul0', 'linear'}
    [GraphBuilderPatternOptimization.apply_match] MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']
      - MatMul: ['x', '_onx_transpose0'] -> ['_onx_matmul0']
      - Add: ['_onx_matmul0', 'layers.0.bias'] -> ['linear']
      + Gemm: ['x', '_onx_transpose0', 'layers.0.bias'] -> ['linear']
    [GraphBuilder-TYU.set_type] linear:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: MatMulAddPattern replaces ['MatMul', 'Add'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Gemm']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']: -2 +1 nodes
    [GraphBuilderPatternOptimization.optimize] removed outputs {'_onx_matmul0'}
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: MatMulAddPattern replaces ['MatMul', 'Add'], inputs: {'_onx_matmul02', 'relu', '_onx_transpose02', 'layers.2.bias'}, outputs: {'output_0', '_onx_matmul02'}
    [GraphBuilderPatternOptimization.apply_match] MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']
      - MatMul: ['relu', '_onx_transpose02'] -> ['_onx_matmul02']
      - Add: ['_onx_matmul02', 'layers.2.bias'] -> ['output_0']
      + Gemm: ['relu', '_onx_transpose02', 'layers.2.bias'] -> ['output_0']
    [GraphBuilder-TYU.set_type] output_0:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: MatMulAddPattern replaces ['MatMul', 'Add'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Gemm']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: MatMulAddPattern replaces ['MatMul', 'Add']: -2 +1 nodes
    [GraphBuilderPatternOptimization.optimize] removed outputs {'_onx_matmul02'}
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: TransposeEqualReshapePattern replaces ['Transpose'], inputs: {'layers.2.weight'}, outputs: {'_onx_transpose02'}
    [GraphBuilder-TYU.set_shape] init7_s2_-1_1:(2,)
    [GraphBuilder-TYU.set_rank] init7_s2_-1_1:1
    [GraphBuilder-TYU.set_type] init7_s2_-1_1:7
    [GraphBuilder-TYU.make_initializer] init7_s2_-1_1[7:(2,)]
    [GraphBuilder.update_node_constant] new constant 'init7_s2_-1_1', node=None
    [GraphBuilder.update_node_constant] new constant '_onx_transpose02', node=Reshape
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeEqualReshapePattern replaces ['Transpose']
      - Transpose: ['layers.2.weight'] -> ['_onx_transpose02']
      + Reshape: ['layers.2.weight', 'init7_s2_-1_1'] -> ['_onx_transpose02']
    [GraphBuilder.update_node_constant] new constant '_onx_transpose02', node=Reshape
    [GraphBuilder-TYU.set_type] _onx_transpose02:1
    [GraphBuilder-TYU.set_type] _onx_transpose02:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeEqualReshapePattern replaces ['Transpose'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Reshape']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: TransposeEqualReshapePattern replaces ['Transpose']: -1 +1 nodes
    [GraphBuilderPatternOptimization.optimize] done all: -5 +3 nodes
    [GraphBuilder.remove_identity_nodes] -- starts with 5
    [GraphBuilder.remove_identity_nodes] found 0 replacements
    [GraphBuilder.remove_identity_nodes] kept 5 nodes
    [GraphBuilder.remove_identity_nodes] ends with 5 nodes in 1.6044999938458204e-05 seconds
    [GraphBuilderPatternOptimization.optimize] iteration 2: 5 nodes, priority=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationTrainingPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastLayerNormalizationCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastCastBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ClipClipPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ComputationCastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ConvBiasNullPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start DropoutPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandBroadcastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandSwapPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start GeluPattern with main_opset=18 and min_opset=20
    [PatternOptimization.enumerate_matches] start IdentityPattern with main_opset=18 and min_opset=1
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear
    [PatternOptimization.enumerate_matches] start LayerNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LayerNormalizationScalePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LeakyReluPattern with main_opset=18 and min_opset=6
    [PatternOptimization.enumerate_matches] start MulMulMulScalarPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceSumNormalizePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapePattern with main_opset=18 and min_opset=1
    [ReshapePattern.match] NONE - line: 38:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [PatternOptimization.enumerate_matches] start ReshapeMatMulReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Reshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapeBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MatMulAddPattern with main_opset=18 and min_opset=1
    [MatMulAddPattern.match] NONE - line: 50:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=MatMulAddPattern--Opset
    [MatMulAddPattern.match] NONE - line: 47:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start GemmTransposePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: GemmTransposePattern replaces ['Gemm']
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: GemmTransposePattern replaces ['Gemm']
    [PatternOptimization.enumerate_matches] start MatMulReshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MulMulMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapePattern with main_opset=18 and min_opset=1
    [ReshapeReshapePattern.match] NONE - line: 167:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [PatternOptimization.enumerate_matches] start RotaryConcatPartPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SameChildrenPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SequenceConstructAtPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SliceSlicePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SlicesSplitPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SoftmaxCrossEntropyLossCastPattern with main_opset=18 and min_opset=14
    [PatternOptimization.enumerate_matches] start SplitConcatPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Sub1MulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchOrderBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchReshapeActivationPattern with main_opset=18 and min_opset=1
    [SwitchReshapeActivationPattern.match] NONE - line: 1163:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Relu, name=relu
    [PatternOptimization.enumerate_matches] start TransposeEqualReshapePattern with main_opset=18 and min_opset=1
    [TransposeEqualReshapePattern.match] NONE - line: 342:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [PatternOptimization.enumerate_matches] start TransposeMatMulPattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.match] OVERLAP match=MatchResult: TransposeMatMulPattern replaces ['Transpose', 'Gemm'] #marked: 2)
    [TransposeMatMulPattern.match] NONE - line: 875:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start TransposeReshapeMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start TransposeReshapeTransposePattern with main_opset=18 and min_opset=1
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [PatternOptimization.enumerate_matches] start TransposeTransposePattern with main_opset=18 and min_opset=1
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [PatternOptimization.enumerate_matches] start UnsqueezeEqualPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start UnsqueezeUnsqueezePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 2*GemmTransposePattern - time=0.000 | max_time=TransposeEqualReshapePattern:0.000
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: GemmTransposePattern replaces ['Gemm'], inputs: {'_onx_transpose0', 'x', 'layers.0.bias'}, outputs: {'linear'}
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose0', node=Transpose
    [GraphBuilderPatternOptimization.apply_match] MatchResult: GemmTransposePattern replaces ['Gemm']
      - Gemm: ['x', '_onx_transpose0', 'layers.0.bias'] -> ['linear']
      + Transpose: ['_onx_transpose0'] -> ['GemmTransposePattern--_onx_transpose0']
      + Gemm: ['x', 'GemmTransposePattern--_onx_transpose0', 'layers.0.bias'] -> ['linear']
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose0', node=Transpose
    [GraphBuilder-TYU.set_type] GemmTransposePattern--_onx_transpose0:1
    [GraphBuilder-TYU.set_shape] GemmTransposePattern--_onx_transpose0:(32, 10)
    [GraphBuilder-TYU.set_rank] GemmTransposePattern--_onx_transpose0:2
    [GraphBuilder-TYU.set_type] linear:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: GemmTransposePattern replaces ['Gemm'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Transpose', 'Gemm']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: GemmTransposePattern replaces ['Gemm']: -1 +2 nodes
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: GemmTransposePattern replaces ['Gemm'], inputs: {'layers.2.bias', 'relu', '_onx_transpose02'}, outputs: {'output_0'}
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose02', node=Transpose
    [GraphBuilderPatternOptimization.apply_match] MatchResult: GemmTransposePattern replaces ['Gemm']
      - Gemm: ['relu', '_onx_transpose02', 'layers.2.bias'] -> ['output_0']
      + Transpose: ['_onx_transpose02'] -> ['GemmTransposePattern--_onx_transpose02']
      + Gemm: ['relu', 'GemmTransposePattern--_onx_transpose02', 'layers.2.bias'] -> ['output_0']
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose02', node=Transpose
    [GraphBuilder-TYU.set_type] GemmTransposePattern--_onx_transpose02:1
    [GraphBuilder-TYU.set_shape] GemmTransposePattern--_onx_transpose02:(1, 32)
    [GraphBuilder-TYU.set_rank] GemmTransposePattern--_onx_transpose02:2
    [GraphBuilder-TYU.set_type] output_0:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: GemmTransposePattern replaces ['Gemm'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Transpose', 'Gemm']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: GemmTransposePattern replaces ['Gemm']: -1 +2 nodes
    [GraphBuilderPatternOptimization.optimize] done all: -2 +4 nodes
    [GraphBuilder.remove_identity_nodes] -- starts with 7
    [GraphBuilder.remove_identity_nodes] found 0 replacements
    [GraphBuilder.remove_identity_nodes] kept 7 nodes
    [GraphBuilder.remove_identity_nodes] ends with 7 nodes in 1.904800592456013e-05 seconds
    [GraphBuilderPatternOptimization.optimize] iteration 3: 7 nodes, priority=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationTrainingPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastLayerNormalizationCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastCastBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ClipClipPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ComputationCastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ConvBiasNullPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start DropoutPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandBroadcastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandSwapPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start GeluPattern with main_opset=18 and min_opset=20
    [PatternOptimization.enumerate_matches] start IdentityPattern with main_opset=18 and min_opset=1
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=linear
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset
    [IdentityPattern.match] NONE - line: 165:experimental_experiment.xoptim.patterns.onnx_any, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start LayerNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LayerNormalizationScalePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LeakyReluPattern with main_opset=18 and min_opset=6
    [PatternOptimization.enumerate_matches] start MulMulMulScalarPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceSumNormalizePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapePattern with main_opset=18 and min_opset=1
    [ReshapePattern.match] NONE - line: 38:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [PatternOptimization.enumerate_matches] start ReshapeMatMulReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Reshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapeBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MatMulAddPattern with main_opset=18 and min_opset=1
    [MatMulAddPattern.match] NONE - line: 50:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [MatMulAddPattern.match] NONE - line: 47:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start GemmTransposePattern with main_opset=18 and min_opset=1
    [GemmTransposePattern.match] NONE - line: 297:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [GemmTransposePattern.match] NONE - line: 297:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start MatMulReshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MulMulMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapePattern with main_opset=18 and min_opset=1
    [ReshapeReshapePattern.match] NONE - line: 167:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [PatternOptimization.enumerate_matches] start RotaryConcatPartPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SameChildrenPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SequenceConstructAtPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SliceSlicePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SlicesSplitPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SoftmaxCrossEntropyLossCastPattern with main_opset=18 and min_opset=14
    [PatternOptimization.enumerate_matches] start SplitConcatPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Sub1MulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchOrderBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchReshapeActivationPattern with main_opset=18 and min_opset=1
    [SwitchReshapeActivationPattern.match] NONE - line: 1163:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Relu, name=relu
    [PatternOptimization.enumerate_matches] start TransposeEqualReshapePattern with main_opset=18 and min_opset=1
    [TransposeEqualReshapePattern.match] NONE - line: 342:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeEqualReshapePattern.match] NONE - line: 342:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: TransposeEqualReshapePattern replaces ['Transpose']
    [PatternOptimization.enumerate_matches] start TransposeMatMulPattern with main_opset=18 and min_opset=1
    [TransposeMatMulPattern.match] NONE - line: 913:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [TransposeMatMulPattern.match] NONE - line: 913:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start TransposeReshapeMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start TransposeReshapeTransposePattern with main_opset=18 and min_opset=1
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=linear
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset
    [TransposeReshapeTransposePattern.match] NONE - line: 140:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start TransposeTransposePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] match=MatchResult: TransposeTransposePattern replaces ['Transpose', 'Transpose']
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset
    [TransposeTransposePattern.match] NONE - line: 51:experimental_experiment.xoptim.patterns.onnx_transpose, op_type=Transpose, name=GemmTransposePattern--MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start UnsqueezeEqualPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start UnsqueezeUnsqueezePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 1*TransposeEqualReshapePattern, 1*TransposeTransposePattern - time=0.000 | max_time=MatMulAddPattern:0.000
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: TransposeEqualReshapePattern replaces ['Transpose'], inputs: {'_onx_transpose02'}, outputs: {'GemmTransposePattern--_onx_transpose02'}
    [GraphBuilder-TYU.set_shape] init7_s2_1_-1:(2,)
    [GraphBuilder-TYU.set_rank] init7_s2_1_-1:1
    [GraphBuilder-TYU.set_type] init7_s2_1_-1:7
    [GraphBuilder-TYU.make_initializer] init7_s2_1_-1[7:(2,)]
    [GraphBuilder.update_node_constant] new constant 'init7_s2_1_-1', node=None
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose02', node=Reshape
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeEqualReshapePattern replaces ['Transpose']
      - Transpose: ['_onx_transpose02'] -> ['GemmTransposePattern--_onx_transpose02']
      + Reshape: ['_onx_transpose02', 'init7_s2_1_-1'] -> ['GemmTransposePattern--_onx_transpose02']
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose02', node=Reshape
    [GraphBuilder-TYU.set_type] GemmTransposePattern--_onx_transpose02:1
    [GraphBuilder-TYU.set_type] GemmTransposePattern--_onx_transpose02:1
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeEqualReshapePattern replaces ['Transpose'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Reshape']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: TransposeEqualReshapePattern replaces ['Transpose']: -1 +1 nodes
    [GraphBuilderPatternOptimization.optimize] apply MatchResult: TransposeTransposePattern replaces ['Transpose', 'Transpose'], inputs: {'_onx_transpose0', 'layers.0.weight'}, outputs: {'_onx_transpose0', 'GemmTransposePattern--_onx_transpose0'}
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose0', node=Identity
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeTransposePattern replaces ['Transpose', 'Transpose']
      - Transpose: ['layers.0.weight'] -> ['_onx_transpose0']
      - Transpose: ['_onx_transpose0'] -> ['GemmTransposePattern--_onx_transpose0']
      + Identity: ['layers.0.weight'] -> ['GemmTransposePattern--_onx_transpose0']
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose0', node=Identity
    [GraphBuilder-TYU.set_type] GemmTransposePattern--_onx_transpose0:1
    [GraphBuilder.update_node_constant] new constant 'GemmTransposePattern--_onx_transpose0', node=Identity
    [GraphBuilderPatternOptimization.apply_match] MatchResult: TransposeTransposePattern replaces ['Transpose', 'Transpose'] applied.
    [GraphBuilderPatternOptimization.optimize] - add ['Identity']
    [GraphBuilderPatternOptimization.optimize] done MatchResult: TransposeTransposePattern replaces ['Transpose', 'Transpose']: -2 +1 nodes
    [GraphBuilderPatternOptimization.optimize] removed outputs {'_onx_transpose0'}
    [GraphBuilderPatternOptimization.optimize] done all: -3 +2 nodes
    [GraphBuilder.remove_identity_nodes] -- starts with 6
    [GraphBuilder.remove_identity_nodes] found 1 replacements
    [GraphBuilder.remove_identity_nodes] kept 5 nodes
    [GraphBuilder.remove_identity_nodes] node Gemm-GemmTransposePattern--MatMulAddPattern--Opset2:['x', 'GemmTransposePattern--_onx_transpose0', 'layers.0.bias']->['x', 'layers.0.weight', 'layers.0.bias']:['linear']->['linear']
    [GraphBuilder.remove_identity_nodes] ends with 5 nodes in 3.821800055447966e-05 seconds
    [GraphBuilderPatternOptimization.optimize] iteration 4: 5 nodes, priority=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start BatchNormalizationTrainingPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastLayerNormalizationCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastCastBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start CastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ClipClipPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ComputationCastOpCastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ConvBiasNullPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start DropoutPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandBroadcastPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ExpandSwapPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start GeluPattern with main_opset=18 and min_opset=20
    [PatternOptimization.enumerate_matches] start IdentityPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LayerNormalizationPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LayerNormalizationScalePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start LeakyReluPattern with main_opset=18 and min_opset=6
    [PatternOptimization.enumerate_matches] start MulMulMulScalarPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReduceSumNormalizePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapePattern with main_opset=18 and min_opset=1
    [ReshapePattern.match] NONE - line: 38:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [ReshapePattern.match] NONE - line: 38:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--GemmTransposePattern--MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start ReshapeMatMulReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Reshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapeBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MatMulAddPattern with main_opset=18 and min_opset=1
    [MatMulAddPattern.match] NONE - line: 50:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [MatMulAddPattern.match] NONE - line: 47:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start GemmTransposePattern with main_opset=18 and min_opset=1
    [GemmTransposePattern.match] NONE - line: 297:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [GemmTransposePattern.match] NONE - line: 297:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start MatMulReshape2Of3Pattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start MulMulMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start ReshapeReshapePattern with main_opset=18 and min_opset=1
    [ReshapeReshapePattern.match] NONE - line: 178:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--linear2
    [ReshapeReshapePattern.match] NONE - line: 167:experimental_experiment.xoptim.patterns.onnx_reshape, op_type=Reshape, name=TransposeEqualReshapePattern--B--GemmTransposePattern--MatMulAddPattern--Opset3
    [PatternOptimization.enumerate_matches] start RotaryConcatPartPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SameChildrenPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SequenceConstructAtPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SliceSlicePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SlicesSplitPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SoftmaxCrossEntropyLossCastPattern with main_opset=18 and min_opset=14
    [PatternOptimization.enumerate_matches] start SplitConcatPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start Sub1MulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchOrderBinaryPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start SwitchReshapeActivationPattern with main_opset=18 and min_opset=1
    [SwitchReshapeActivationPattern.match] NONE - line: 1163:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Relu, name=relu
    [PatternOptimization.enumerate_matches] start TransposeEqualReshapePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start TransposeMatMulPattern with main_opset=18 and min_opset=1
    [TransposeMatMulPattern.match] NONE - line: 875:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset2
    [TransposeMatMulPattern.match] NONE - line: 875:experimental_experiment.xoptim.patterns.onnx_matmul, op_type=Gemm, name=GemmTransposePattern--MatMulAddPattern--Opset32
    [PatternOptimization.enumerate_matches] start TransposeReshapeMatMulPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start TransposeReshapeTransposePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start TransposeTransposePattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start UnsqueezeEqualPattern with main_opset=18 and min_opset=1
    [PatternOptimization.enumerate_matches] start UnsqueezeUnsqueezePattern with main_opset=18 and min_opset=1
    [GraphBuilderPatternOptimization.optimize] done all: -0 +0 nodes
    [GraphBuilderPatternOptimization.optimize] stops current_priority_index=2, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] done after 5 iterations with 5 nodes in 0.005
        STAT apply_GemmTransposePattern +4 -2 #it=1 maxmatch=1 i=2 - time=0.0002470740000717342
        STAT apply_MatMulAddPattern +2 -4 #it=1 maxmatch=1 i=2 - time=0.00015389100008178502
        STAT apply_TransposeEqualReshapePattern +2 -2 #it=2 maxmatch=2 i=2 - time=0.0003896369889844209
        STAT apply_TransposeTransposePattern +1 -2 #it=1 maxmatch=1 i=1 - time=9.900199074763805e-05
        STAT build_graph_for_pattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.00012665498070418835
        STAT check_pattern_00 +0 -0 #it=1 maxmatch=0 i=0 - time=1.544599945191294e-05
        STAT check_pattern_A0 +0 -0 #it=3 maxmatch=0 i=0 - time=9.096502617467195e-05
        STAT check_pattern_B0 +0 -0 #it=4 maxmatch=0 i=0 - time=4.680900019593537e-05
        STAT match_BatchNormalizationPattern +0 -0 #it=5 maxmatch=0 i=0 - time=3.665500844363123e-05
        STAT match_BatchNormalizationTrainingPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.56429921137169e-05
        STAT match_CastCastBinaryPattern +0 -0 #it=4 maxmatch=0 i=0 - time=3.553199348971248e-05
        STAT match_CastLayerNormalizationCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.9147017155773938e-05
        STAT match_CastOpCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=4.7837005695328116e-05
        STAT match_CastPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.1988991647958755e-05
        STAT match_ClipClipPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8637001630850136e-05
        STAT match_ComputationCastOpCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=5.184501060284674e-05
        STAT match_ConvBiasNullPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.4317982024513185e-05
        STAT match_DropoutPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.636501110624522e-05
        STAT match_ExpandBroadcastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.6458987374790013e-05
        STAT match_ExpandPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.121999568771571e-05
        STAT match_ExpandSwapPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.5111974789761007e-05
        STAT match_GeluPattern +0 -0 #it=5 maxmatch=0 i=0 - time=5.092981155030429e-06
        STAT match_GemmTransposePattern +0 -0 #it=4 maxmatch=2 i=2 - time=7.440902118105441e-05
        STAT match_IdentityPattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.00023286200303118676
        STAT match_LayerNormalizationPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8498991266824305e-05
        STAT match_LayerNormalizationScalePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.66529935086146e-05
        STAT match_LeakyReluPattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.000547258008737117
        STAT match_MatMulAddPattern +0 -0 #it=4 maxmatch=2 i=2 - time=0.00010439702600706369
        STAT match_MatMulReshape2Of3Pattern +0 -0 #it=4 maxmatch=2 i=0 - time=3.644400567281991e-05
        STAT match_MulMulMatMulPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.9608025215566158e-05
        STAT match_MulMulMulScalarPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8665014067664742e-05
        STAT match_ReduceReshapePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.849600812420249e-05
        STAT match_ReduceSumNormalizePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8990016542375088e-05
        STAT match_Reshape2Of3Pattern +0 -0 #it=4 maxmatch=0 i=0 - time=3.169100091326982e-05
        STAT match_ReshapeMatMulReshapePattern +0 -0 #it=4 maxmatch=0 i=0 - time=2.7442991267889738e-05
        STAT match_ReshapePattern +0 -0 #it=5 maxmatch=0 i=0 - time=7.896999886725098e-05
        STAT match_ReshapeReshapeBinaryPattern +0 -0 #it=4 maxmatch=0 i=0 - time=2.452198532409966e-05
        STAT match_ReshapeReshapePattern +0 -0 #it=5 maxmatch=2 i=0 - time=5.120801506564021e-05
        STAT match_RotaryConcatPartPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.295500598847866e-05
        STAT match_SameChildrenPattern +0 -0 #it=5 maxmatch=2 i=0 - time=3.8125988794490695e-05
        STAT match_SequenceConstructAtPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7302983906120062e-05
        STAT match_SliceSlicePattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.645401061978191e-05
        STAT match_SlicesSplitPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7802987713366747e-05
        STAT match_SoftmaxCrossEntropyLossCastPattern +0 -0 #it=5 maxmatch=2 i=0 - time=0.0009513160184724256
        STAT match_SplitConcatPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7055004718713462e-05
        STAT match_Sub1MulPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.561200770083815e-05
        STAT match_SwitchOrderBinaryPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.3254004190675914e-05
        STAT match_SwitchReshapeActivationPattern +0 -0 #it=4 maxmatch=2 i=0 - time=4.421600897330791e-05
        STAT match_TransposeEqualReshapePattern +0 -0 #it=4 maxmatch=3 i=2 - time=0.0001368469966109842
        STAT match_TransposeMatMulPattern +0 -0 #it=4 maxmatch=3 i=0 - time=0.00012169702677056193
        STAT match_TransposeReshapeMatMulPattern +0 -0 #it=4 maxmatch=3 i=0 - time=2.9705013730563223e-05
        STAT match_TransposeReshapeTransposePattern +0 -0 #it=5 maxmatch=3 i=0 - time=5.3491981816478074e-05
        STAT match_TransposeTransposePattern +0 -0 #it=5 maxmatch=3 i=1 - time=5.756599421147257e-05
        STAT match_UnsqueezeEqualPattern +0 -0 #it=4 maxmatch=3 i=0 - time=1.64090160978958e-05
        STAT match_UnsqueezeUnsqueezePattern +0 -0 #it=5 maxmatch=3 i=0 - time=2.0929990569129586e-05
        STAT remove_identity_nodes +1 -2 #it=4 maxmatch=0 i=0 - time=0.00014151599316392094
    --MODEL: 5 nodes, 1 inputs, 1 outputs, 6 initializers--
             INPUT:   1 x 1t
         INPUT-SEQ:   1 x Falset
            OUTPUT:   1 x 1t
        OUTPUT-SEQ:   1 x Falset
              INIT:   4 x 1t
              INIT:   2 x 7t
              NODE:   2 x Gemm
              NODE:   1 x Relu
              NODE:   2 x Reshape
    --MODEL: 5 nodes, 1 inputs, 1 outputs, 6 initializers--DETAILED--
         INPUT:   1 x 1t[3x10]
        OUTPUT:   1 x 1t[3x1]
          INIT:   1 x 1t[1]
          INIT:   1 x 1t[1x32]
          INIT:   1 x 1t[32]
          INIT:   1 x 1t[32x10]
          INIT:   2 x 7t[2]
          NODE:   1 x Gemm -SIG- 1t[3x10], 1t[32x10], 1t[32]
          NODE:   1 x Gemm -SIG- 1t[3x32], 1t[1x32], 1t[1]
          NODE:   1 x Relu -SIG- 1t[3x32]
          NODE:   1 x Reshape -SIG- 1t[1x32], 7t[2]
          NODE:   1 x Reshape -SIG- 1t[32x1], 7t[2]
    [GraphBuilder.optimize] done with 5 nodes in 0.006
        STAT apply_GemmTransposePattern +4 -2 #it=1 maxmatch=1 i=2 - time=0.0002470740000717342
        STAT apply_MatMulAddPattern +2 -4 #it=1 maxmatch=1 i=2 - time=0.00015389100008178502
        STAT apply_TransposeEqualReshapePattern +2 -2 #it=2 maxmatch=2 i=2 - time=0.0003896369889844209
        STAT apply_TransposeTransposePattern +1 -2 #it=1 maxmatch=1 i=1 - time=9.900199074763805e-05
        STAT build_graph_for_pattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.00012665498070418835
        STAT check_A +0 -0 #it=0 maxmatch=0 i=0 - time=1.9933999283239245e-05
        STAT check_B +0 -0 #it=0 maxmatch=0 i=0 - time=1.545899431221187e-05
        STAT check_C +0 -0 #it=0 maxmatch=0 i=0 - time=1.2899006833322346e-05
        STAT check_F +0 -0 #it=0 maxmatch=0 i=0 - time=1.9836006686091423e-05
        STAT check_G +0 -0 #it=0 maxmatch=0 i=0 - time=1.597098889760673e-05
        STAT check_pattern_00 +0 -0 #it=1 maxmatch=0 i=0 - time=1.544599945191294e-05
        STAT check_pattern_A0 +0 -0 #it=3 maxmatch=0 i=0 - time=9.096502617467195e-05
        STAT check_pattern_B0 +0 -0 #it=4 maxmatch=0 i=0 - time=4.680900019593537e-05
        STAT match_BatchNormalizationPattern +0 -0 #it=5 maxmatch=0 i=0 - time=3.665500844363123e-05
        STAT match_BatchNormalizationTrainingPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.56429921137169e-05
        STAT match_CastCastBinaryPattern +0 -0 #it=4 maxmatch=0 i=0 - time=3.553199348971248e-05
        STAT match_CastLayerNormalizationCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.9147017155773938e-05
        STAT match_CastOpCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=4.7837005695328116e-05
        STAT match_CastPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.1988991647958755e-05
        STAT match_ClipClipPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8637001630850136e-05
        STAT match_ComputationCastOpCastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=5.184501060284674e-05
        STAT match_ConvBiasNullPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.4317982024513185e-05
        STAT match_DropoutPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.636501110624522e-05
        STAT match_ExpandBroadcastPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.6458987374790013e-05
        STAT match_ExpandPattern +0 -0 #it=5 maxmatch=0 i=0 - time=2.121999568771571e-05
        STAT match_ExpandSwapPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.5111974789761007e-05
        STAT match_GeluPattern +0 -0 #it=5 maxmatch=0 i=0 - time=5.092981155030429e-06
        STAT match_GemmTransposePattern +0 -0 #it=4 maxmatch=2 i=2 - time=7.440902118105441e-05
        STAT match_IdentityPattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.00023286200303118676
        STAT match_LayerNormalizationPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8498991266824305e-05
        STAT match_LayerNormalizationScalePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.66529935086146e-05
        STAT match_LeakyReluPattern +0 -0 #it=5 maxmatch=0 i=0 - time=0.000547258008737117
        STAT match_MatMulAddPattern +0 -0 #it=4 maxmatch=2 i=2 - time=0.00010439702600706369
        STAT match_MatMulReshape2Of3Pattern +0 -0 #it=4 maxmatch=2 i=0 - time=3.644400567281991e-05
        STAT match_MulMulMatMulPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.9608025215566158e-05
        STAT match_MulMulMulScalarPattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8665014067664742e-05
        STAT match_ReduceReshapePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.849600812420249e-05
        STAT match_ReduceSumNormalizePattern +0 -0 #it=4 maxmatch=0 i=0 - time=1.8990016542375088e-05
        STAT match_Reshape2Of3Pattern +0 -0 #it=4 maxmatch=0 i=0 - time=3.169100091326982e-05
        STAT match_ReshapeMatMulReshapePattern +0 -0 #it=4 maxmatch=0 i=0 - time=2.7442991267889738e-05
        STAT match_ReshapePattern +0 -0 #it=5 maxmatch=0 i=0 - time=7.896999886725098e-05
        STAT match_ReshapeReshapeBinaryPattern +0 -0 #it=4 maxmatch=0 i=0 - time=2.452198532409966e-05
        STAT match_ReshapeReshapePattern +0 -0 #it=5 maxmatch=2 i=0 - time=5.120801506564021e-05
        STAT match_RotaryConcatPartPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.295500598847866e-05
        STAT match_SameChildrenPattern +0 -0 #it=5 maxmatch=2 i=0 - time=3.8125988794490695e-05
        STAT match_SequenceConstructAtPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7302983906120062e-05
        STAT match_SliceSlicePattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.645401061978191e-05
        STAT match_SlicesSplitPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7802987713366747e-05
        STAT match_SoftmaxCrossEntropyLossCastPattern +0 -0 #it=5 maxmatch=2 i=0 - time=0.0009513160184724256
        STAT match_SplitConcatPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.7055004718713462e-05
        STAT match_Sub1MulPattern +0 -0 #it=4 maxmatch=2 i=0 - time=1.561200770083815e-05
        STAT match_SwitchOrderBinaryPattern +0 -0 #it=4 maxmatch=2 i=0 - time=2.3254004190675914e-05
        STAT match_SwitchReshapeActivationPattern +0 -0 #it=4 maxmatch=2 i=0 - time=4.421600897330791e-05
        STAT match_TransposeEqualReshapePattern +0 -0 #it=4 maxmatch=3 i=2 - time=0.0001368469966109842
        STAT match_TransposeMatMulPattern +0 -0 #it=4 maxmatch=3 i=0 - time=0.00012169702677056193
        STAT match_TransposeReshapeMatMulPattern +0 -0 #it=4 maxmatch=3 i=0 - time=2.9705013730563223e-05
        STAT match_TransposeReshapeTransposePattern +0 -0 #it=5 maxmatch=3 i=0 - time=5.3491981816478074e-05
        STAT match_TransposeTransposePattern +0 -0 #it=5 maxmatch=3 i=1 - time=5.756599421147257e-05
        STAT match_UnsqueezeEqualPattern +0 -0 #it=4 maxmatch=3 i=0 - time=1.64090160978958e-05
        STAT match_UnsqueezeUnsqueezePattern +0 -0 #it=5 maxmatch=3 i=0 - time=2.0929990569129586e-05
        STAT pattern_optimization +0 -2 #it=0 maxmatch=0 i=0 - time=0.005799550999654457
        STAT remove_identity_nodes +1 -2 #it=4 maxmatch=0 i=0 - time=0.00020096100342925638
        STAT remove_unused +0 -0 #it=0 maxmatch=0 i=0 - time=7.903399819042534e-05
    --MODEL: 5 nodes, 1 inputs, 1 outputs, 6 initializers--
             INPUT:   1 x 1t
         INPUT-SEQ:   1 x Falset
            OUTPUT:   1 x 1t
        OUTPUT-SEQ:   1 x Falset
              INIT:   4 x 1t
              INIT:   2 x 7t
              NODE:   2 x Gemm
              NODE:   1 x Relu
              NODE:   2 x Reshape
    --MODEL: 5 nodes, 1 inputs, 1 outputs, 6 initializers--DETAILED--
         INPUT:   1 x 1t[3x10]
        OUTPUT:   1 x 1t[3x1]
          INIT:   1 x 1t[1]
          INIT:   1 x 1t[1x32]
          INIT:   1 x 1t[32]
          INIT:   1 x 1t[32x10]
          INIT:   2 x 7t[2]
          NODE:   1 x Gemm -SIG- 1t[3x10], 1t[32x10], 1t[32]
          NODE:   1 x Gemm -SIG- 1t[3x32], 1t[1x32], 1t[1]
          NODE:   1 x Relu -SIG- 1t[3x32]
          NODE:   1 x Reshape -SIG- 1t[1x32], 7t[2]
          NODE:   1 x Reshape -SIG- 1t[32x1], 7t[2]
    [GraphBuilder-TYU.to_onnx] make_model 6 inits 0 params
    [GraphBuilder-TYU.time_evaluation_constants_] 0
    [GraphBuilder-TYU._build_initializers] start with 6 initializers, large_model=False, external_threshold=1024
    [GraphBuilder-TYU._build_initializers] switch low/high order
    [GraphBuilder-TYU._build_initializers] TensorProto-layers.0.weight:1[(32, 10)]
    [GraphBuilder-TYU._build_initializers] TensorProto-layers.0.bias:1[(32,)]
    [GraphBuilder-TYU._build_initializers] TensorProto-layers.2.weight:1[(1, 32)]
    [GraphBuilder-TYU._build_initializers] TensorProto-layers.2.bias:1[(1,)]
    [GraphBuilder-TYU._build_initializers] <ndarray>-init7_s2_-1_1:int64[(2,)]
    [GraphBuilder-TYU._build_initializers] <ndarray>-init7_s2_1_-1:int64[(2,)]
    [GraphBuilder-TYU._build_initializers] done in 7.560010999441147e-07s with 6 initializers, 0 large initializers

Select the pattern to use

Class OptimizationOptions is used to enable or disable patterns.

<<<

import onnx
from experimental_experiment.xbuilder import GraphBuilder, OptimizationOptions

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(
    onx,
    infer_shapes_options=True,
    optimization_options=OptimizationOptions(
        patterns="TransposeTranspose,TransposeMatMul", verbose=1
    ),
)
opt_onx = gr.to_onnx(optimize=True)

>>>

    [GraphBuilder.optimize] start with 7 nodes
    [GraphBuilder.optimize] #patterns=2
    [GraphBuilderPatternOptimization.optimize] start with 7 nodes, 4 initializers, 2 patterns, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] iteration 0: 7 nodes, priority=0
    [GraphBuilderPatternOptimization.optimize] increase priority to 1
    [GraphBuilderPatternOptimization.optimize] iteration 1: 7 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 2*TransposeMatMulPattern - time=0.000 | max_time=TransposeMatMulPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 2: 5 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] stops current_priority_index=2, priorities=[0, 1]
    [GraphBuilderPatternOptimization.optimize] done after 3 iterations with 5 nodes in 0.000
    [GraphBuilder.optimize] done with 5 nodes in 0.001

There exists some predefined lists of patterns:

  • default: includes all patterns using only standard onnx patterns.

  • onnxruntime: patterns specific to onnxruntime, the final model may be executed by onnxruntime and possibly only onnxruntime as it may introduce patterns from Supported Operators and Data Types.

<<<

import onnx
from experimental_experiment.xbuilder import GraphBuilder, OptimizationOptions

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(
    onx,
    infer_shapes_options=True,
    optimization_options=OptimizationOptions(patterns="default+onnxruntime", verbose=1),
)
opt_onx = gr.to_onnx(optimize=True)

>>>

    [GraphBuilder.optimize] start with 7 nodes
    [GraphBuilder.optimize] #patterns=61
    [GraphBuilderPatternOptimization.optimize] start with 7 nodes, 4 initializers, 61 patterns, priorities=[0, 1, 2, 3]
    [GraphBuilderPatternOptimization.optimize] iteration 0: 7 nodes, priority=0
    [GraphBuilderPatternOptimization.optimize] increase priority to 1
    [GraphBuilderPatternOptimization.optimize] iteration 1: 7 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 3 matches, 2*MatMulAddPattern, 1*TransposeEqualReshapePattern - time=0.001 | max_time=IdentityPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 2: 5 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 2*GemmTransposePattern - time=0.000 | max_time=TransposeMatMulPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 3: 7 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] applies 2 matches, 1*TransposeEqualReshapePattern, 1*TransposeTransposePattern - time=0.000 | max_time=TransposeMatMulPattern:0.000
    [GraphBuilderPatternOptimization.optimize] iteration 4: 5 nodes, priority=1
    [GraphBuilderPatternOptimization.optimize] increase priority to 2
    [GraphBuilderPatternOptimization.optimize] iteration 5: 5 nodes, priority=2
    [GraphBuilderPatternOptimization.optimize] increase priority to 3
    [GraphBuilderPatternOptimization.optimize] iteration 6: 5 nodes, priority=3
    [GraphBuilderPatternOptimization.optimize] stops current_priority_index=4, priorities=[0, 1, 2, 3]
    [GraphBuilderPatternOptimization.optimize] done after 7 iterations with 5 nodes in 0.007
    [GraphBuilder.optimize] done with 5 nodes in 0.007

Statistics

This can be used to see when a pattern is applied and how long it takes.

<<<

import pandas
import onnx
from experimental_experiment.xbuilder import GraphBuilder, OptimizationOptions

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(
    onx,
    infer_shapes_options=True,
    optimization_options=OptimizationOptions(patterns="default"),
)
stat = gr.optimize()

print(pandas.DataFrame(stat))

>>>

                         pattern   time_in  removed  added  iteration  instances  match_index
    0                    check_A  0.000018      NaN    NaN        NaN        NaN          NaN
    1      remove_identity_nodes  0.000028      0.0    0.0        NaN        NaN          NaN
    2                    check_B  0.000013      NaN    NaN        NaN        NaN          NaN
    3              remove_unused  0.000031      0.0    NaN        NaN        NaN          NaN
    4                    check_C  0.000012      NaN    NaN        NaN        NaN          NaN
    ..                       ...       ...      ...    ...        ...        ...          ...
    235  build_graph_for_pattern  0.000034      NaN    NaN        4.0        NaN          NaN
    236     pattern_optimization  0.005351      2.0    NaN        NaN        NaN          NaN
    237                  check_F  0.000019      NaN    NaN        NaN        NaN          NaN
    238            remove_unused  0.000043      0.0    NaN        NaN        NaN          NaN
    239                  check_G  0.000017      NaN    NaN        NaN        NaN          NaN
    
    [240 rows x 7 columns]

It can be aggregated:

<<<

import pandas
import onnx
from experimental_experiment.xbuilder import GraphBuilder, OptimizationOptions

onx = onnx.load("temp_doc_mlp.onnx")

gr = GraphBuilder(
    onx,
    infer_shapes_options=True,
    optimization_options=OptimizationOptions(patterns="default"),
)
stat = gr.optimize()

df = pandas.DataFrame(stat)
for c in df.columns:
    if "time" not in c and "pattern" not in c:
        df[c] = df[c].fillna(0).astype(int)
aggs = {
    "time_in": "sum",
    "added": "sum",
    "removed": "sum",
    "iteration": "max",
    "match_index": "max",
    "instances": "sum",
}
print(df.groupby("pattern").agg(aggs))

>>>

                                         time_in  added  removed  iteration  match_index  instances
    pattern                                                                                        
    apply_GemmTransposePattern          0.000218      4        2          2            1          2
    apply_MatMulAddPattern              0.000121      2        4          1            1          2
    apply_TransposeEqualReshapePattern  0.000364      2        2          3            2          2
    apply_TransposeTransposePattern     0.000102      1        2          3            1          1
    build_graph_for_pattern             0.000152      0        0          4            0          0
    ...                                      ...    ...      ...        ...          ...        ...
    match_UnsqueezeEqualPattern         0.000018      0        0          4            3          0
    match_UnsqueezeUnsqueezePattern     0.000020      0        0          4            3          0
    pattern_optimization                0.004546      0        2          0            0          0
    remove_identity_nodes               0.000192      1        2          3            0          0
    remove_unused                       0.000078      0        0          0            0          0
    
    [63 rows x 6 columns]

Shape inference

The optimizers require to know the shapes to ensure they can rewrite some nodes and avoid producing a model which does not return the same results. If it is missing, some patterns cannot match for sure and they will not match.

This information can be built by running shape inference on the onnx models. That’s what is done is the previous examples. However, the best case is when this information comes from torch.

Function to_onnx converts a torch model into ONNX. While doing so, it stores the shape information coming from torch. There is no need to run shape inference on the onnx model it generates before optimizing it.

Available Patterns and API

All patterns may be found at .xoptim.patterns and .xoptim.patterns_ort.

When writing a pattern, walking along the graph or checking the shape is very common. Class GraphBuilderPatternOptimization provides the following methods.

Opsets

Patterns must rewrite using the nodes of the opset defined in the model.

Shapes, Types

Constants

  • is_constant: tells if a node is a constant (it may be a constant, an initializer or any value built on other constants)

  • is_constant_scalar: checks a constant is a scalar and compares its value to a number

  • get_computed_constant: returns the constant, computes it is a constant built from other constants

  • get_attribute: returns an attribute of a node

Graph

Nodes

  • make_node: creates a node without adding it to the graph

  • make_node_check_opset: creates a node without adding it to the graph, deals with some constraints related to opset version