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,77 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import onnx
|
|
9
|
+
import onnxruntime as ort
|
|
10
|
+
|
|
11
|
+
from onnxscript import ir
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def assert_numerically_equal(
|
|
15
|
+
original_model_proto: onnx.ModelProto | ir.Model,
|
|
16
|
+
rewritten_model_proto: onnx.ModelProto | ir.Model,
|
|
17
|
+
args: tuple[Any, ...],
|
|
18
|
+
rtol: float = 1,
|
|
19
|
+
atol: float = 1e-3,
|
|
20
|
+
):
|
|
21
|
+
"""Assert that the two models are numerically equal.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
original_model_proto: The original model proto or ir.Model.
|
|
25
|
+
rewritten_model_proto: The rewritten by the rules model proto or ir.Model.
|
|
26
|
+
rtol: Relative tolerance.
|
|
27
|
+
atol: Absolute tolerance.
|
|
28
|
+
args: The positional arguments to pass to the model.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
if isinstance(original_model_proto, ir.Model):
|
|
32
|
+
original_model_proto = ir.serde.serialize_model(original_model_proto)
|
|
33
|
+
if isinstance(rewritten_model_proto, ir.Model):
|
|
34
|
+
rewritten_model_proto = ir.serde.serialize_model(rewritten_model_proto)
|
|
35
|
+
|
|
36
|
+
original_proto_ort_inputs = {
|
|
37
|
+
k.name: v for k, v in zip(original_model_proto.graph.input, args)
|
|
38
|
+
}
|
|
39
|
+
original_proto_ort_inference_session = _ort_session_initializer(
|
|
40
|
+
original_model_proto.SerializeToString()
|
|
41
|
+
)
|
|
42
|
+
run_options = ort.RunOptions()
|
|
43
|
+
run_options.log_severity_level = 3 # 3: Error
|
|
44
|
+
original_outputs = original_proto_ort_inference_session.run(
|
|
45
|
+
None, original_proto_ort_inputs, run_options=run_options
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
the_rewritten_proto_ort_inputs = {
|
|
49
|
+
k.name: v for k, v in zip(rewritten_model_proto.graph.input, args)
|
|
50
|
+
}
|
|
51
|
+
the_rewritten_proto_ort_inference_session = _ort_session_initializer(
|
|
52
|
+
rewritten_model_proto.SerializeToString()
|
|
53
|
+
)
|
|
54
|
+
the_rewritten_outputs = the_rewritten_proto_ort_inference_session.run(
|
|
55
|
+
None, the_rewritten_proto_ort_inputs, run_options=run_options
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
np.testing.assert_allclose(
|
|
59
|
+
original_outputs, the_rewritten_outputs, rtol=rtol, atol=atol, equal_nan=True
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _ort_session_initializer(model: str | bytes) -> ort.InferenceSession:
|
|
64
|
+
"""Initialize an ONNX Runtime inference session with the specified model."""
|
|
65
|
+
import onnxruntime as ort
|
|
66
|
+
|
|
67
|
+
session_options = ort.SessionOptions()
|
|
68
|
+
session_options.log_severity_level = 3 # 3: Error
|
|
69
|
+
possible_providers = (
|
|
70
|
+
"CUDAExecutionProvider",
|
|
71
|
+
"CPUExecutionProvider",
|
|
72
|
+
)
|
|
73
|
+
available_providers = set(ort.get_available_providers())
|
|
74
|
+
providers = [
|
|
75
|
+
provider for provider in possible_providers if provider in available_providers
|
|
76
|
+
]
|
|
77
|
+
return ort.InferenceSession(model, providers=providers, sess_options=session_options)
|
onnxscript/sourceinfo.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# -------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
"""Source code information used for diagnostic messages."""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import ast
|
|
11
|
+
from typing import Callable, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SourceInfo:
|
|
15
|
+
"""Information about onnxscript source fragment, used for diagnostic messages."""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
ast_node: ast.AST,
|
|
20
|
+
code: Optional[str] = None,
|
|
21
|
+
function_name: Optional[str] = None,
|
|
22
|
+
):
|
|
23
|
+
self.ast_node = ast_node
|
|
24
|
+
self.code = code
|
|
25
|
+
self.function_name = function_name
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def lineno(self):
|
|
29
|
+
return self.ast_node.lineno
|
|
30
|
+
|
|
31
|
+
def msg(self, error_message: str) -> str:
|
|
32
|
+
lineno = self.lineno
|
|
33
|
+
if self.function_name:
|
|
34
|
+
source_loc = f"Function '{self.function_name}', line {lineno}"
|
|
35
|
+
else:
|
|
36
|
+
source_loc = f"Line {lineno}"
|
|
37
|
+
|
|
38
|
+
if self.code:
|
|
39
|
+
lines = self.code.split("\n")
|
|
40
|
+
line = lines[lineno - 1]
|
|
41
|
+
marker_prefix = " " * (self.ast_node.col_offset)
|
|
42
|
+
source_line = f"{line}\n{marker_prefix}^\n"
|
|
43
|
+
else:
|
|
44
|
+
source_line = ""
|
|
45
|
+
|
|
46
|
+
return f"ERROR: {error_message}\nat: {source_loc}\n{source_line}"
|
|
47
|
+
|
|
48
|
+
def __str__(self) -> str:
|
|
49
|
+
raise ValueError("Cannot happen!")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Formatter = Callable[[ast.AST, str], str]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def formatter(source_code: Optional[str]) -> Formatter:
|
|
56
|
+
def format(node: ast.AST, message: str) -> str:
|
|
57
|
+
return SourceInfo(node, source_code).msg(message)
|
|
58
|
+
|
|
59
|
+
return format
|
onnxscript/tensor.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import onnx.helper
|
|
10
|
+
from onnx import TensorProto
|
|
11
|
+
|
|
12
|
+
from onnxscript import onnx_opset
|
|
13
|
+
from onnxscript._internal import autocast
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Tensor:
|
|
17
|
+
"""An implementation of ONNX Tensors, based on a wrapper around numpy arrays.
|
|
18
|
+
Serves to define overloaded ops with an ONNX/ONNXScript semantics.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, nparray: Optional[np.ndarray], opset=None):
|
|
22
|
+
if nparray is not None and not isinstance(nparray, np.ndarray):
|
|
23
|
+
raise TypeError(
|
|
24
|
+
f"Unexpected type {type(nparray)}. It must be a numpy array or None."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
self._nparray = nparray
|
|
28
|
+
# FIXME(justinhuby): Create a better way to determine the opset version
|
|
29
|
+
self._opset: Any = opset or onnx_opset.opset18
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def value(self) -> np.ndarray:
|
|
33
|
+
if self._nparray is None:
|
|
34
|
+
raise ValueError("Tensor does not have a value.")
|
|
35
|
+
return self._nparray
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def rank(self) -> int:
|
|
39
|
+
return len(self.value.shape)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def is_scalar(self) -> bool:
|
|
43
|
+
return self.rank == 0
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def shape(self) -> tuple[int, ...]:
|
|
47
|
+
return self.value.shape
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def dtype(self) -> np.dtype:
|
|
51
|
+
return self.value.dtype
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def onnx_dtype(self) -> int:
|
|
55
|
+
return onnx.helper.np_dtype_to_tensor_dtype(self.dtype)
|
|
56
|
+
|
|
57
|
+
def __repr__(self) -> str:
|
|
58
|
+
return f"{self.__class__.__name__}({self.value!r})"
|
|
59
|
+
|
|
60
|
+
def __bool__(self) -> bool:
|
|
61
|
+
return bool(self.value)
|
|
62
|
+
|
|
63
|
+
def __int__(self) -> int:
|
|
64
|
+
return int(self.value)
|
|
65
|
+
|
|
66
|
+
def __float__(self) -> float:
|
|
67
|
+
return float(self.value)
|
|
68
|
+
|
|
69
|
+
def __len__(self) -> int:
|
|
70
|
+
return self.shape[0]
|
|
71
|
+
|
|
72
|
+
def __index__(self) -> int:
|
|
73
|
+
return self.value.__index__()
|
|
74
|
+
|
|
75
|
+
def __getitem__(self, index):
|
|
76
|
+
op = self._opset
|
|
77
|
+
if op.version < 13:
|
|
78
|
+
raise RuntimeError("Indexing requires opset 13 or later.")
|
|
79
|
+
if not isinstance(index, tuple):
|
|
80
|
+
# Normalize representation to a tuple.
|
|
81
|
+
# A single index-value is equivalent to a tuple with a single element.
|
|
82
|
+
index = (index,)
|
|
83
|
+
if len(index) > self.rank:
|
|
84
|
+
raise ValueError(
|
|
85
|
+
f"Number of indices {len(index)} is greater than rank {self.rank}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Promote integer indices to tensors of rank 0
|
|
89
|
+
index = [autocast.cast_pyvalue_to_os_tensor(x) for x in index]
|
|
90
|
+
# Process all elements in index
|
|
91
|
+
shape = self.shape
|
|
92
|
+
sliced_indices = []
|
|
93
|
+
scalar_indices = []
|
|
94
|
+
to_squeeze = []
|
|
95
|
+
non_scalar_indices = []
|
|
96
|
+
for axis_, s in enumerate(index):
|
|
97
|
+
if isinstance(s, slice):
|
|
98
|
+
if s.start is None and s.stop is None and s.step is None:
|
|
99
|
+
continue
|
|
100
|
+
if s.step is None or s.step > 0:
|
|
101
|
+
sliced_indices.append(
|
|
102
|
+
[
|
|
103
|
+
s.start or 0,
|
|
104
|
+
s.stop if s.stop is not None else shape[axis_],
|
|
105
|
+
axis_,
|
|
106
|
+
s.step or 1,
|
|
107
|
+
]
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
sliced_indices.append(
|
|
111
|
+
[
|
|
112
|
+
s.start if s.start is not None else (shape[axis_] - 1),
|
|
113
|
+
s.stop if s.stop is not None else -(shape[axis_] + 1),
|
|
114
|
+
axis_,
|
|
115
|
+
s.step,
|
|
116
|
+
]
|
|
117
|
+
)
|
|
118
|
+
elif isinstance(s, Tensor):
|
|
119
|
+
if s.is_scalar:
|
|
120
|
+
scalar_indices.append([s, s + 1, axis_, 1])
|
|
121
|
+
to_squeeze.append(axis_)
|
|
122
|
+
else:
|
|
123
|
+
non_scalar_indices.append((axis_, s))
|
|
124
|
+
else:
|
|
125
|
+
raise TypeError(f"Unexpected type {type(s)}: slice or int expected.")
|
|
126
|
+
|
|
127
|
+
# Non-scalar-indexing requires the use of ONNX Gather operation.
|
|
128
|
+
# Slicing can be implemented efficiently using ONNX's Slice operation.
|
|
129
|
+
# Scalar-indexing can be implemented using either Gather or with the Slice operation.
|
|
130
|
+
# We map scalar-indexing into the Slice operation, except in the special case
|
|
131
|
+
# of a single scalar-index (with no other sliced_index), which we map directly
|
|
132
|
+
# to a Gather.
|
|
133
|
+
|
|
134
|
+
if not (sliced_indices or scalar_indices or non_scalar_indices):
|
|
135
|
+
# Edge case: no index specified. Eg. A[:, :]
|
|
136
|
+
return op.Identity(self)
|
|
137
|
+
if not sliced_indices and len(scalar_indices) == 1:
|
|
138
|
+
# Special case of indexing along a single axis: A[i], A[:, i], A[:, :, i] etc.
|
|
139
|
+
# promote integer input to tensor
|
|
140
|
+
axis = to_squeeze[0]
|
|
141
|
+
index_value = index[axis]
|
|
142
|
+
# use Gather to perform indexing
|
|
143
|
+
result = op.Gather(self, index_value, axis=axis)
|
|
144
|
+
elif sliced_indices or scalar_indices:
|
|
145
|
+
sliced_indices = sliced_indices + scalar_indices
|
|
146
|
+
indices = np.array(sliced_indices, dtype=np.int64).T
|
|
147
|
+
starts = Tensor(indices[0])
|
|
148
|
+
ends = Tensor(indices[1])
|
|
149
|
+
axes = Tensor(indices[2])
|
|
150
|
+
steps = Tensor(indices[3])
|
|
151
|
+
result = op.Slice(self, starts, ends, axes, steps)
|
|
152
|
+
if to_squeeze:
|
|
153
|
+
result = Tensor(np.squeeze(result.value, axis=tuple(to_squeeze)))
|
|
154
|
+
else:
|
|
155
|
+
result = self
|
|
156
|
+
for axis, value in non_scalar_indices:
|
|
157
|
+
result = op.Gather(result, value, axis=axis)
|
|
158
|
+
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
def __mod__(self, other):
|
|
162
|
+
if self.onnx_dtype in {
|
|
163
|
+
TensorProto.FLOAT,
|
|
164
|
+
TensorProto.DOUBLE,
|
|
165
|
+
TensorProto.FLOAT16,
|
|
166
|
+
TensorProto.BFLOAT16,
|
|
167
|
+
}:
|
|
168
|
+
return self._opset.Mod(self, other, fmod=1)
|
|
169
|
+
return self._opset.Mod(self, other)
|
|
170
|
+
|
|
171
|
+
def __ne__(self, other):
|
|
172
|
+
temp = self._opset.Equal(self, other)
|
|
173
|
+
return self._opset.Not(temp)
|
|
174
|
+
|
|
175
|
+
def __neg__(self):
|
|
176
|
+
return self._opset.Neg(self)
|
|
177
|
+
|
|
178
|
+
def __add__(self, other):
|
|
179
|
+
return self._opset.Add(self, other)
|
|
180
|
+
|
|
181
|
+
def __radd__(self, other):
|
|
182
|
+
return self._opset.Add(other, self)
|
|
183
|
+
|
|
184
|
+
def __and__(self, other):
|
|
185
|
+
return self._opset.And(self, other)
|
|
186
|
+
|
|
187
|
+
def __rand__(self, other):
|
|
188
|
+
return self._opset.And(other, self)
|
|
189
|
+
|
|
190
|
+
def __mul__(self, other):
|
|
191
|
+
return self._opset.Mul(self, other)
|
|
192
|
+
|
|
193
|
+
def __rmul__(self, other):
|
|
194
|
+
return self._opset.Mul(other, self)
|
|
195
|
+
|
|
196
|
+
def __matmul__(self, other):
|
|
197
|
+
return self._opset.MatMul(self, other)
|
|
198
|
+
|
|
199
|
+
def __or__(self, other):
|
|
200
|
+
return self._opset.Or(self, other)
|
|
201
|
+
|
|
202
|
+
def __pow__(self, other):
|
|
203
|
+
return self._opset.Pow(self, other)
|
|
204
|
+
|
|
205
|
+
def __sub__(self, other):
|
|
206
|
+
return self._opset.Sub(self, other)
|
|
207
|
+
|
|
208
|
+
def __rsub__(self, other):
|
|
209
|
+
return self._opset.Sub(other, self)
|
|
210
|
+
|
|
211
|
+
def __truediv__(self, other):
|
|
212
|
+
return self._opset.Div(self, other)
|
|
213
|
+
|
|
214
|
+
def __lt__(self, other):
|
|
215
|
+
return self._opset.Less(self, other)
|
|
216
|
+
|
|
217
|
+
def __le__(self, other):
|
|
218
|
+
return self._opset.LessOrEqual(self, other)
|
|
219
|
+
|
|
220
|
+
def __eq__(self, other):
|
|
221
|
+
return self._opset.Equal(self, other)
|
|
222
|
+
|
|
223
|
+
def __ge__(self, other):
|
|
224
|
+
return self._opset.GreaterOrEqual(self, other)
|
|
225
|
+
|
|
226
|
+
def __gt__(self, other):
|
|
227
|
+
return self._opset.Greater(self, other)
|