onnxscript 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- onnxscript/__init__.py +131 -0
- onnxscript/_framework_apis/__init__.py +3 -0
- onnxscript/_framework_apis/torch_2_5.py +117 -0
- onnxscript/_framework_apis/torch_2_6.py +45 -0
- onnxscript/_internal/__init__.py +0 -0
- onnxscript/_internal/analysis.py +229 -0
- onnxscript/_internal/ast_utils.py +64 -0
- onnxscript/_internal/autocast.py +250 -0
- onnxscript/_internal/deprecation.py +78 -0
- onnxscript/_internal/param_manipulation.py +148 -0
- onnxscript/_internal/runtime_typing.py +43 -0
- onnxscript/_internal/utils.py +99 -0
- onnxscript/_internal/version_utils.py +118 -0
- onnxscript/_legacy_ir/__init__.py +341 -0
- onnxscript/_legacy_ir/visitor.py +937 -0
- onnxscript/_thirdparty/asciichartpy.py +313 -0
- onnxscript/backend/__init__.py +2 -0
- onnxscript/backend/onnx_backend.py +303 -0
- onnxscript/backend/onnx_export.py +885 -0
- onnxscript/converter.py +1470 -0
- onnxscript/evaluator.py +619 -0
- onnxscript/function_libs/tools/torch_lib/deduce_type_constraints.py +403 -0
- onnxscript/function_libs/tools/torch_lib/generate_aten_signatures.py +333 -0
- onnxscript/function_libs/tools/torch_lib/generate_prims_signatures.py +331 -0
- onnxscript/function_libs/torch_lib/__init__.py +12 -0
- onnxscript/function_libs/torch_lib/_constants.py +5 -0
- onnxscript/function_libs/torch_lib/_flags.py +58 -0
- onnxscript/function_libs/torch_lib/graph_building/__init__.py +56 -0
- onnxscript/function_libs/torch_lib/graph_building/_graph_building_ir.py +723 -0
- onnxscript/function_libs/torch_lib/graph_building/_graph_building_torch.py +1125 -0
- onnxscript/function_libs/torch_lib/ops/__init__.py +27 -0
- onnxscript/function_libs/torch_lib/ops/common.py +80 -0
- onnxscript/function_libs/torch_lib/ops/core.py +8935 -0
- onnxscript/function_libs/torch_lib/ops/fft.py +385 -0
- onnxscript/function_libs/torch_lib/ops/linalg.py +399 -0
- onnxscript/function_libs/torch_lib/ops/nested.py +25 -0
- onnxscript/function_libs/torch_lib/ops/nn.py +2713 -0
- onnxscript/function_libs/torch_lib/ops/prims.py +850 -0
- onnxscript/function_libs/torch_lib/ops/quantized_decomposed.py +63 -0
- onnxscript/function_libs/torch_lib/ops/sparse.py +23 -0
- onnxscript/function_libs/torch_lib/ops/special.py +387 -0
- onnxscript/function_libs/torch_lib/ops/vision.py +25 -0
- onnxscript/function_libs/torch_lib/registration.py +151 -0
- onnxscript/function_libs/torch_lib/tensor_typing.py +74 -0
- onnxscript/ir/__init__.py +153 -0
- onnxscript/ir/_convenience.py +447 -0
- onnxscript/ir/_core.py +3119 -0
- onnxscript/ir/_display.py +49 -0
- onnxscript/ir/_enums.py +163 -0
- onnxscript/ir/_graph_comparison.py +23 -0
- onnxscript/ir/_io.py +97 -0
- onnxscript/ir/_linked_list.py +276 -0
- onnxscript/ir/_metadata.py +44 -0
- onnxscript/ir/_name_authority.py +72 -0
- onnxscript/ir/_polyfill.py +25 -0
- onnxscript/ir/_protocols.py +598 -0
- onnxscript/ir/_schemas.py +548 -0
- onnxscript/ir/_tape.py +120 -0
- onnxscript/ir/_type_casting.py +106 -0
- onnxscript/ir/convenience.py +32 -0
- onnxscript/ir/external_data.py +396 -0
- onnxscript/ir/passes/__init__.py +33 -0
- onnxscript/ir/passes/_pass_infra.py +172 -0
- onnxscript/ir/serde.py +1620 -0
- onnxscript/ir/tensor_adapters.py +122 -0
- onnxscript/ir/traversal.py +82 -0
- onnxscript/irbuilder.py +542 -0
- onnxscript/main.py +167 -0
- onnxscript/onnx_opset/__init__.py +232 -0
- onnxscript/onnx_opset/_impl/opset1.py +4100 -0
- onnxscript/onnx_opset/_impl/opset10.py +1227 -0
- onnxscript/onnx_opset/_impl/opset11.py +4013 -0
- onnxscript/onnx_opset/_impl/opset12.py +1078 -0
- onnxscript/onnx_opset/_impl/opset13.py +3924 -0
- onnxscript/onnx_opset/_impl/opset14.py +999 -0
- onnxscript/onnx_opset/_impl/opset15.py +604 -0
- onnxscript/onnx_opset/_impl/opset16.py +1255 -0
- onnxscript/onnx_opset/_impl/opset17.py +561 -0
- onnxscript/onnx_opset/_impl/opset18.py +1803 -0
- onnxscript/onnx_opset/_impl/opset19.py +1942 -0
- onnxscript/onnx_opset/_impl/opset2.py +218 -0
- onnxscript/onnx_opset/_impl/opset20.py +675 -0
- onnxscript/onnx_opset/_impl/opset21.py +1976 -0
- onnxscript/onnx_opset/_impl/opset22.py +2588 -0
- onnxscript/onnx_opset/_impl/opset3.py +199 -0
- onnxscript/onnx_opset/_impl/opset4.py +77 -0
- onnxscript/onnx_opset/_impl/opset5.py +84 -0
- onnxscript/onnx_opset/_impl/opset6.py +944 -0
- onnxscript/onnx_opset/_impl/opset7.py +1243 -0
- onnxscript/onnx_opset/_impl/opset8.py +444 -0
- onnxscript/onnx_opset/_impl/opset9.py +1485 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_ml1.py +974 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_ml2.py +112 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_ml3.py +308 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_ml4.py +129 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_ml5.py +158 -0
- onnxscript/onnx_opset/_impl/opset_ai_onnx_preview_training1.py +577 -0
- onnxscript/onnx_types.py +229 -0
- onnxscript/optimizer/__init__.py +39 -0
- onnxscript/optimizer/_constant_folding.py +1083 -0
- onnxscript/optimizer/_inliner.py +312 -0
- onnxscript/optimizer/_legacy/_optimizer.py +98 -0
- onnxscript/optimizer/_legacy/_remove_unused_proto.py +144 -0
- onnxscript/optimizer/_legacy/_simple_function_folding.py +243 -0
- onnxscript/optimizer/_legacy/constant_folding.py +293 -0
- onnxscript/optimizer/_legacy/evaluator.py +439 -0
- onnxscript/optimizer/_optimizer.py +61 -0
- onnxscript/optimizer/_remove_unused.py +106 -0
- onnxscript/optimizer/_remove_unused_function.py +72 -0
- onnxscript/py.typed +1 -0
- onnxscript/rewriter/__init__.py +56 -0
- onnxscript/rewriter/_ir_utils.py +111 -0
- onnxscript/rewriter/broadcast_to_matmul.py +180 -0
- onnxscript/rewriter/cast_constant_of_shape.py +50 -0
- onnxscript/rewriter/collapse_slices.py +141 -0
- onnxscript/rewriter/erfgelu.py +27 -0
- onnxscript/rewriter/function_rule.py +232 -0
- onnxscript/rewriter/gemm_to_matmul_add.py +21 -0
- onnxscript/rewriter/generic_pattern.py +700 -0
- onnxscript/rewriter/llama_rule_sets.py +287 -0
- onnxscript/rewriter/no_op.py +56 -0
- onnxscript/rewriter/onnxruntime/__init__.py +50 -0
- onnxscript/rewriter/onnxruntime/bfloat16_utils/bfloat16_converter.py +99 -0
- onnxscript/rewriter/onnxruntime/fused_matmul_rule_sets.py +177 -0
- onnxscript/rewriter/onnxruntime/group_normalization_merge_silu.py +64 -0
- onnxscript/rewriter/onnxruntime/instance_to_group_normalization.py +155 -0
- onnxscript/rewriter/onnxruntime/softmax.py +63 -0
- onnxscript/rewriter/onnxruntime/transformers/__init__.py +21 -0
- onnxscript/rewriter/onnxruntime/transformers/biassplitgelu.py +31 -0
- onnxscript/rewriter/onnxruntime/transformers/fastgelu.py +29 -0
- onnxscript/rewriter/onnxruntime/transformers/layernorm.py +47 -0
- onnxscript/rewriter/onnxruntime/transformers/multihead_attention.py +715 -0
- onnxscript/rewriter/ort_fusions/__init__.py +9 -0
- onnxscript/rewriter/ort_fusions/_core.py +28 -0
- onnxscript/rewriter/ort_fusions/_smollm_1.py +253 -0
- onnxscript/rewriter/ort_fusions/_smollm_2.py +467 -0
- onnxscript/rewriter/ort_fusions/_test_models.py +122 -0
- onnxscript/rewriter/ort_fusions/_test_utils.py +42 -0
- onnxscript/rewriter/ort_fusions/cos_sin_cache.py +154 -0
- onnxscript/rewriter/ort_fusions/gqa.py +156 -0
- onnxscript/rewriter/ort_fusions/mha.py +198 -0
- onnxscript/rewriter/ort_fusions/rms_normalization.py +95 -0
- onnxscript/rewriter/ort_fusions/rotary_embedding.py +64 -0
- onnxscript/rewriter/ort_fusions/sdpa.py +75 -0
- onnxscript/rewriter/ort_fusions/skip_normalization.py +46 -0
- onnxscript/rewriter/pattern.py +1714 -0
- onnxscript/rewriter/testing.py +77 -0
- onnxscript/sourceinfo.py +59 -0
- onnxscript/tensor.py +227 -0
- onnxscript/testing/__init__.py +482 -0
- onnxscript/tools/__init__.py +4 -0
- onnxscript/tools/benchmark/__init__.py +23 -0
- onnxscript/tools/benchmark/benchmark_helpers.py +783 -0
- onnxscript/tools/benchmark/benchmark_run.py +140 -0
- onnxscript/tools/benchmark/export_model.py +207 -0
- onnxscript/tools/benchmark/export_model_batch.py +146 -0
- onnxscript/tools/memory_peak.py +244 -0
- onnxscript/tools/training_helper.py +50 -0
- onnxscript/tools/transformers_models/__init__.py +190 -0
- onnxscript/tools/transformers_models/llama.py +168 -0
- onnxscript/tools/transformers_models/mistral.py +238 -0
- onnxscript/tools/transformers_models/phi.py +248 -0
- onnxscript/tools/transformers_models/phi3.py +259 -0
- onnxscript/type_annotation.py +281 -0
- onnxscript/utils/__init__.py +0 -0
- onnxscript/utils/evaluation_utils.py +56 -0
- onnxscript/utils/timing_utils.py +33 -0
- onnxscript/utils/utils.py +84 -0
- onnxscript/values.py +790 -0
- onnxscript/version_converter/__init__.py +21 -0
- onnxscript/version_converter/_version_converter.py +314 -0
- onnxscript-0.1.0.dist-info/LICENSE +21 -0
- onnxscript-0.1.0.dist-info/METADATA +370 -0
- onnxscript-0.1.0.dist-info/RECORD +176 -0
- onnxscript-0.1.0.dist-info/WHEEL +5 -0
- onnxscript-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""Version utils for testing."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import warnings
|
|
8
|
+
from typing import Callable, Sequence
|
|
9
|
+
|
|
10
|
+
import packaging.version
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def onnx_older_than(version: str) -> bool:
|
|
14
|
+
"""Returns True if the ONNX version is older than the given version."""
|
|
15
|
+
import onnx # pylint: disable=import-outside-toplevel
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
packaging.version.parse(onnx.__version__).release
|
|
19
|
+
< packaging.version.parse(version).release
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def torch_older_than(version: str) -> bool:
|
|
24
|
+
"""Returns True if the torch version is older than the given version."""
|
|
25
|
+
import torch # pylint: disable=import-outside-toplevel
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
packaging.version.parse(torch.__version__).release
|
|
29
|
+
< packaging.version.parse(version).release
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def transformers_older_than(version: str) -> bool | None:
|
|
34
|
+
"""Returns True if the transformers version is older than the given version."""
|
|
35
|
+
try:
|
|
36
|
+
import transformers # pylint: disable=import-outside-toplevel
|
|
37
|
+
except ImportError:
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
packaging.version.parse(transformers.__version__).release
|
|
42
|
+
< packaging.version.parse(version).release
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def is_onnxruntime_training() -> bool:
|
|
47
|
+
"""Returns True if the onnxruntime is onnxruntime-training."""
|
|
48
|
+
try:
|
|
49
|
+
from onnxruntime import training # pylint: disable=import-outside-toplevel
|
|
50
|
+
|
|
51
|
+
assert training
|
|
52
|
+
except ImportError:
|
|
53
|
+
# onnxruntime not training
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
from onnxruntime.capi.onnxruntime_pybind11_state import ( # pylint: disable=import-outside-toplevel
|
|
58
|
+
OrtValueVector,
|
|
59
|
+
)
|
|
60
|
+
except ImportError:
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
return hasattr(OrtValueVector, "push_back_batch")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def onnxruntime_older_than(version: str) -> bool:
|
|
67
|
+
"""Returns True if the onnxruntime version is older than the given version."""
|
|
68
|
+
import onnxruntime # pylint: disable=import-outside-toplevel
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
packaging.version.parse(onnxruntime.__version__).release
|
|
72
|
+
< packaging.version.parse(version).release
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def numpy_older_than(version: str) -> bool:
|
|
77
|
+
"""Returns True if the numpy version is older than the given version."""
|
|
78
|
+
import numpy # pylint: disable=import-outside-toplevel
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
packaging.version.parse(numpy.__version__).release
|
|
82
|
+
< packaging.version.parse(version).release
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def has_transformers():
|
|
87
|
+
"""Tells if transformers is installed."""
|
|
88
|
+
try:
|
|
89
|
+
import transformers # pylint: disable=import-outside-toplevel
|
|
90
|
+
|
|
91
|
+
assert transformers
|
|
92
|
+
return True # noqa
|
|
93
|
+
except ImportError:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def ignore_warnings(warns: Warning | Sequence[Warning]) -> Callable: # type: ignore[arg-type]
|
|
98
|
+
"""Catches warnings.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
warns: warnings to ignore
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
decorated function
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def wrapper(fct):
|
|
108
|
+
if warns is None:
|
|
109
|
+
raise AssertionError(f"warns cannot be None for '{fct}'.")
|
|
110
|
+
|
|
111
|
+
def call_f(self):
|
|
112
|
+
with warnings.catch_warnings():
|
|
113
|
+
warnings.simplefilter("ignore", warns) # type: ignore[arg-type]
|
|
114
|
+
return fct(self)
|
|
115
|
+
|
|
116
|
+
return call_f
|
|
117
|
+
|
|
118
|
+
return wrapper
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
from collections import deque
|
|
7
|
+
from typing import List, Tuple, Union
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import onnx
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Unknown:
|
|
14
|
+
"""A special value used to indicate that a value is not a statically known constant.
|
|
15
|
+
|
|
16
|
+
We use this instead of None because None is a valid constant value (since ONNX
|
|
17
|
+
supports the Optional type).
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
instance = None
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
if Unknown.instance is not None:
|
|
24
|
+
raise ValueError("Unknown.instance is already set")
|
|
25
|
+
Unknown.instance = self
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Singleton instance of Unknown
|
|
29
|
+
unknown = Unknown()
|
|
30
|
+
NotConstant = unknown
|
|
31
|
+
|
|
32
|
+
# ConcreteValue: This type represents constant values that an ONNX variable can take.
|
|
33
|
+
# TODO: Extend this to a recursive type to handle lists of tensors, etc., support optionals,
|
|
34
|
+
# maps, etc.
|
|
35
|
+
# TODO (rama): The value is sometimes stored as a numpy array, and sometimes as an ONNX TensorProto.
|
|
36
|
+
# A uniform representation would be helpful, but we should avoid unnecessary conversions for
|
|
37
|
+
# large tensors. Should be cleaned up in the new IR.
|
|
38
|
+
ConcreteValue = Union[onnx.TensorProto, np.ndarray, Unknown, None]
|
|
39
|
+
|
|
40
|
+
# SymbolicValue: This information is used to enable partial-evaluation and specialization
|
|
41
|
+
# of sequence operations, as well as elimination of redundant Identity ops.
|
|
42
|
+
# The symbolic value of a variable X can be:
|
|
43
|
+
# - a string with the value "Y", indicating that "X" is a copy of "Y"
|
|
44
|
+
# - a list of strings, indicating that "X" is a list of tensors, with their symbolic values
|
|
45
|
+
# Eg., the symbolic value ["A", "B", "C"] indicates that the value of X is equal to
|
|
46
|
+
# "SequenceConstruct(A, B, C)".
|
|
47
|
+
# TODO: Technically, SymbolicValue should be a recursive type to handle lists of lists of
|
|
48
|
+
# tensors, etc. However, we currently only handle lists of tensors.
|
|
49
|
+
|
|
50
|
+
SymbolicValue = Union[str, List[str]]
|
|
51
|
+
|
|
52
|
+
FunctionId = Tuple[str, str, str]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_function_id(function: onnx.FunctionProto) -> FunctionId:
|
|
56
|
+
return (function.domain, function.name, getattr(function, "overload", ""))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_function_id_from_node(node: onnx.NodeProto) -> FunctionId:
|
|
60
|
+
return (node.domain, node.op_type, getattr(node, "overload", ""))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclasses.dataclass
|
|
64
|
+
class StaticValueInfo:
|
|
65
|
+
name: str
|
|
66
|
+
value: ConcreteValue = NotConstant
|
|
67
|
+
type: onnx.TypeProto | None = None
|
|
68
|
+
symbolic_value: SymbolicValue | None = None
|
|
69
|
+
|
|
70
|
+
def is_copy(self) -> bool:
|
|
71
|
+
return isinstance(self.symbolic_value, str)
|
|
72
|
+
|
|
73
|
+
def tensor_shape_proto(self) -> onnx.TensorShapeProto | None:
|
|
74
|
+
"""Returns the shape of a tensor or None.
|
|
75
|
+
|
|
76
|
+
A return value of None could mean that the type is unknown or that the type is not a tensor
|
|
77
|
+
or that the tensor shape (that is, even the rank) is unknown.
|
|
78
|
+
"""
|
|
79
|
+
type = self.type
|
|
80
|
+
if type and type.HasField("tensor_type") and type.tensor_type.HasField("shape"):
|
|
81
|
+
return type.tensor_type.shape
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def shape(self) -> list[str | int | None] | None:
|
|
86
|
+
"""Returns the shape in a list.
|
|
87
|
+
|
|
88
|
+
Str means that the shape is dynamic.
|
|
89
|
+
"""
|
|
90
|
+
type = self.type
|
|
91
|
+
if type and type.HasField("tensor_type") and type.tensor_type.HasField("shape"):
|
|
92
|
+
dims = []
|
|
93
|
+
for dim in type.tensor_type.shape.dim:
|
|
94
|
+
if dim.HasField("dim_param"):
|
|
95
|
+
dims.append(dim.dim_param)
|
|
96
|
+
elif dim.HasField("dim_value"):
|
|
97
|
+
dims.append(dim.dim_value)
|
|
98
|
+
else:
|
|
99
|
+
dims.append(None)
|
|
100
|
+
return dims
|
|
101
|
+
if self.value_as_np_array is not None:
|
|
102
|
+
return list(self.value_as_np_array.shape)
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def element_type(self) -> int | None:
|
|
107
|
+
"""Returns the element type of a tensor, or None if type is not known or is not a tensor."""
|
|
108
|
+
type = self.type
|
|
109
|
+
if type and type.HasField("tensor_type"):
|
|
110
|
+
return type.tensor_type.elem_type
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
def identity_merge_from(self, other: StaticValueInfo) -> None:
|
|
114
|
+
"""Merge the value of other into self.
|
|
115
|
+
|
|
116
|
+
This models the effect of an identity (copy) operation.
|
|
117
|
+
This will update static-analysis information based on incoming value.
|
|
118
|
+
"""
|
|
119
|
+
if not isinstance(other, StaticValueInfo):
|
|
120
|
+
raise TypeError(f"Cannot merge {other} into {self}.")
|
|
121
|
+
if other.value is not NotConstant:
|
|
122
|
+
self.value = other.value
|
|
123
|
+
# TODO: merge and combine best shape information from both types.
|
|
124
|
+
if other.tensor_shape_proto() is not None and other.element_type is not None:
|
|
125
|
+
self.type = other.type
|
|
126
|
+
# We cannot copy symbolic value across different scopes.
|
|
127
|
+
|
|
128
|
+
# WIP: Extensions towards new IR: Note that the default construction of StaticValueInfo
|
|
129
|
+
# does not fill in the following fields. These fields are filled in by the IRBuilder
|
|
130
|
+
# which constructs the IR from the ONNX model.
|
|
131
|
+
node: Node | None = None
|
|
132
|
+
uses: list[Node] = dataclasses.field(default_factory=list)
|
|
133
|
+
output_index: int | None = None
|
|
134
|
+
is_output: bool = False
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def const_value(self) -> ConcreteValue:
|
|
138
|
+
return self.value
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def value_as_np_array(self) -> np.ndarray | None:
|
|
142
|
+
if isinstance(self.value, np.ndarray):
|
|
143
|
+
return self.value
|
|
144
|
+
if isinstance(self.value, onnx.TensorProto):
|
|
145
|
+
return onnx.numpy_helper.to_array(self.value)
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
def def_node(self) -> Node | None:
|
|
149
|
+
return self.node
|
|
150
|
+
|
|
151
|
+
def def_index(self) -> int:
|
|
152
|
+
return self.output_index # type: ignore[return-value]
|
|
153
|
+
|
|
154
|
+
def is_same_as(self, other: StaticValueInfo) -> bool:
|
|
155
|
+
"""Returns true if this value represents the same IR object as the other value.
|
|
156
|
+
|
|
157
|
+
This is *not* value-equality, but rather object-equality.
|
|
158
|
+
"""
|
|
159
|
+
return self is other
|
|
160
|
+
|
|
161
|
+
def __str__(self) -> str:
|
|
162
|
+
shape = self.shape
|
|
163
|
+
if shape is not None:
|
|
164
|
+
shape = [str(dim) for dim in shape]
|
|
165
|
+
shape_str = f"[{', '.join(shape)}]" # type: ignore[arg-type]
|
|
166
|
+
else:
|
|
167
|
+
shape_str = "None"
|
|
168
|
+
return (
|
|
169
|
+
f"StaticValueInfo({self.name}, shape:{shape_str}, dtype:{self.element_type}, "
|
|
170
|
+
f"{'has const value' if self.value is not unknown else 'no const value'}.)"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
Value = StaticValueInfo
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class Model:
|
|
178
|
+
def __init__(self) -> None:
|
|
179
|
+
self.gen_var_counter: int = 0
|
|
180
|
+
|
|
181
|
+
def set(
|
|
182
|
+
self,
|
|
183
|
+
model_proto: onnx.ModelProto,
|
|
184
|
+
graph: Graph,
|
|
185
|
+
functions: list[Function],
|
|
186
|
+
version_map: dict[str, int],
|
|
187
|
+
) -> None:
|
|
188
|
+
"""TODO. This is a temporary patch."""
|
|
189
|
+
self.original_model_proto = model_proto
|
|
190
|
+
self.graph = graph
|
|
191
|
+
self.functions = functions
|
|
192
|
+
self.version_map = version_map
|
|
193
|
+
|
|
194
|
+
def make_new_name(self):
|
|
195
|
+
# Temporary hack.
|
|
196
|
+
self.gen_var_counter += 1
|
|
197
|
+
return f"_gen_{self.gen_var_counter}"
|
|
198
|
+
|
|
199
|
+
def __str__(self) -> str:
|
|
200
|
+
# TODO: Naive string representation for debugging. Need to improve this.
|
|
201
|
+
return "\n".join(
|
|
202
|
+
[
|
|
203
|
+
f"ModelGraph: {self.graph}",
|
|
204
|
+
f"Functions: {self.functions}",
|
|
205
|
+
f"VersionMap: {self.version_map}",
|
|
206
|
+
]
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class Graph:
|
|
211
|
+
def __init__(self, graph_proto: onnx.GraphProto):
|
|
212
|
+
self.original_graph_proto = graph_proto
|
|
213
|
+
self.nodes: deque[Node] = deque()
|
|
214
|
+
self.values: dict[str, Value] = {}
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def name(self) -> str:
|
|
218
|
+
return self.original_graph_proto.name
|
|
219
|
+
|
|
220
|
+
def __str__(self) -> str:
|
|
221
|
+
return "\n".join(
|
|
222
|
+
[
|
|
223
|
+
"Graph",
|
|
224
|
+
f"Nodes: {[str(n) for n in self.nodes]}",
|
|
225
|
+
f"Values: {[str(v) for v in self.values]}",
|
|
226
|
+
]
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
def input_names(self) -> list[str]:
|
|
231
|
+
return [_.name for _ in self.original_graph_proto.input]
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def output_names(self) -> list[str]:
|
|
235
|
+
return [_.name for _ in self.original_graph_proto.output]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class Function:
|
|
239
|
+
def __init__(self, function_proto: onnx.FunctionProto):
|
|
240
|
+
self.original_function_proto = function_proto
|
|
241
|
+
self.nodes = deque() # type: ignore[var-annotated]
|
|
242
|
+
self.values = {} # type: ignore[var-annotated]
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def id(self) -> FunctionId:
|
|
246
|
+
return (self.domain, self.name, self.overload)
|
|
247
|
+
|
|
248
|
+
@property
|
|
249
|
+
def domain(self) -> str:
|
|
250
|
+
return self.original_function_proto.domain
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def name(self) -> str:
|
|
254
|
+
return self.original_function_proto.name
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def overload(self) -> str:
|
|
258
|
+
return getattr(self.original_function_proto, "overload", "")
|
|
259
|
+
|
|
260
|
+
def __str__(self) -> str:
|
|
261
|
+
return "\n".join(
|
|
262
|
+
[
|
|
263
|
+
"Function",
|
|
264
|
+
f"Nodes: {[str(n) for n in self.nodes]}",
|
|
265
|
+
f"Values: {[str(v) for v in self.values]}",
|
|
266
|
+
]
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class RefAttr:
|
|
271
|
+
def __init__(self, name: str, ref_attr_name: str, type) -> None:
|
|
272
|
+
self.name = name
|
|
273
|
+
self.ref_attr_name = ref_attr_name
|
|
274
|
+
self.type = type
|
|
275
|
+
|
|
276
|
+
def to_proto(self) -> onnx.AttributeProto:
|
|
277
|
+
attr_proto = onnx.AttributeProto()
|
|
278
|
+
attr_proto.name = self.name
|
|
279
|
+
attr_proto.ref_attr_name = self.ref_attr_name
|
|
280
|
+
attr_proto.type = self.type
|
|
281
|
+
return attr_proto
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class Node:
|
|
285
|
+
def __init__(
|
|
286
|
+
self,
|
|
287
|
+
node_proto: onnx.NodeProto,
|
|
288
|
+
populate_io: bool = False,
|
|
289
|
+
) -> None:
|
|
290
|
+
self.original_node_proto = node_proto
|
|
291
|
+
self.domain: str = node_proto.domain
|
|
292
|
+
self.version: int | None = None
|
|
293
|
+
self.op_type: str = node_proto.op_type
|
|
294
|
+
if populate_io:
|
|
295
|
+
self.inputs: list[Value | None] = [Value(i) for i in node_proto.input]
|
|
296
|
+
self.outputs: list[Value | None] = [Value(i) for i in node_proto.output]
|
|
297
|
+
else:
|
|
298
|
+
self.inputs: list[Value | None] = [] # type: ignore[no-redef]
|
|
299
|
+
self.outputs: list[Value | None] = [] # type: ignore[no-redef]
|
|
300
|
+
# TODO: attributes are never populated.
|
|
301
|
+
self.attributes: dict[str, int | float | RefAttr | Graph | list[Graph]] = {}
|
|
302
|
+
|
|
303
|
+
def __repr__(self) -> str:
|
|
304
|
+
return (
|
|
305
|
+
f"{self.op_type}({','.join(self.original_node_proto.input)})"
|
|
306
|
+
f"->{','.join(self.original_node_proto.output)}"
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def name(self) -> str:
|
|
311
|
+
return self.original_node_proto.name
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def input_names(self):
|
|
315
|
+
return self.original_node_proto.input
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def output_names(self):
|
|
319
|
+
return self.original_node_proto.output
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def attribute(self):
|
|
323
|
+
return self.original_node_proto.attribute
|
|
324
|
+
|
|
325
|
+
def set_version_if_custom_op(self, version_map: dict[str, int]) -> None:
|
|
326
|
+
if self.domain != "" and self.domain in version_map:
|
|
327
|
+
self.version = version_map[self.domain]
|
|
328
|
+
|
|
329
|
+
def get_attribute(self, name: str) -> int | float | None:
|
|
330
|
+
return self.attributes.get(name, None) # type: ignore[return-value]
|
|
331
|
+
|
|
332
|
+
def __str__(self) -> str:
|
|
333
|
+
return "\n".join(
|
|
334
|
+
[
|
|
335
|
+
"Node",
|
|
336
|
+
f"OpType: {self.op_type}",
|
|
337
|
+
f"Inputs: {self.inputs}",
|
|
338
|
+
f"Outputs: {self.outputs}",
|
|
339
|
+
f"Attributes: {self.attributes}",
|
|
340
|
+
]
|
|
341
|
+
)
|