# --------------------------------------------------------------------------
# ⚠️ WARNING - AUTO-GENERATED CODE - DO NOT EDIT ⚠️
# ⚙️ Generated by 'python -m opgen'
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# --------------------------------------------------------------------------
# pylint: disable=W0221,W0222,R0901,W0237
# mypy: disable-error-code=override
# ruff: noqa: D402
# --------------------------------------------------------------------------

from __future__ import annotations

from typing import Optional, Sequence, Tuple, TypeVar

from onnx.defs import get_schema
from typing_extensions import TypeAlias

from onnxscript.onnx_opset._impl.opset9 import Opset9
from onnxscript.onnx_types import (
    BOOL,
    COMPLEX64,
    COMPLEX128,
    DOUBLE,
    FLOAT,
    FLOAT16,
    INT8,
    INT16,
    INT32,
    INT64,
    STRING,
    UINT8,
    UINT16,
    UINT32,
    UINT64,
)
from onnxscript.values import Op, Opset


class Opset10(Opset9):
    def __new__(cls):
        return Opset.__new__(cls, "", 10)

    T_AveragePool = TypeVar("T_AveragePool", DOUBLE, FLOAT, FLOAT16)

    def AveragePool(
        self,
        X: T_AveragePool,
        *,
        auto_pad: str = "NOTSET",
        ceil_mode: int = 0,
        count_include_pad: int = 0,
        kernel_shape: Sequence[int],
        pads: Optional[Sequence[int]] = None,
        strides: Optional[Sequence[int]] = None,
    ) -> T_AveragePool:
        r"""[🌐 AveragePool(10)](https://onnx.ai/onnx/operators/onnx__AveragePool.html#averagepool-10 "Online Documentation")


         AveragePool consumes an input tensor X and applies average pooling across
         the tensor according to kernel sizes, stride sizes, and pad lengths.
         average pooling consisting of computing the average on all values of a
         subset of the input tensor according to the kernel size and downsampling the
         data into the output tensor Y for further processing. The output spatial shape will be following:
         ```
         output_spatial_shape[i] = floor((input_spatial_shape[i] + pad_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)
         ```
         or
         ```
         output_spatial_shape[i] = ceil((input_spatial_shape[i] + pad_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)
         ```
         if ceil_mode is enabled

         ```
         * pad_shape[i] is sum of pads along axis i
         ```

         `auto_pad` is a DEPRECATED attribute. If you are using them currently, the output spatial shape will be following:
         ```
         VALID: output_spatial_shape[i] = ceil((input_spatial_shape[i] - kernel_spatial_shape[i] + 1) / strides_spatial_shape[i])
         SAME_UPPER or SAME_LOWER: output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides_spatial_shape[i])
         ```
         And pad shape will be following if `SAME_UPPER` or `SAME_LOWER`:
         ```
         pad_shape[i] = (output_spatial_shape[i] - 1) * strides_spatial_shape[i] + kernel_spatial_shape[i] - input_spatial_shape[i]
         ```
         The output of each pooling window is divided by the number of elements (exclude pad when attribute count_include_pad is zero).


        Args:
            X: Input data tensor from the previous operator; dimensions for image case
                are (N x C x H x W), where N is the batch size, C is the number of
                channels, and H and W are the height and the width of the data. For non
                image case, the dimensions are in the form of (N x C x D1 x D2 ... Dn),
                where N is the batch size. Optionally, if dimension denotation is in
                effect, the operation expects the input data tensor to arrive with the
                dimension denotation of [DATA_BATCH, DATA_CHANNEL, DATA_FEATURE,
                DATA_FEATURE ...].

            auto_pad: auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID.
                Where default value is NOTSET, which means explicit padding is used.
                SAME_UPPER or SAME_LOWER mean pad the input so that the output spatial
                size match the input.In case of odd number add the extra padding at the
                end for SAME_UPPER and at the beginning for SAME_LOWER. VALID mean no
                padding.

            ceil_mode: Whether to use ceil or floor (default) to compute the output
                shape.

            count_include_pad: Whether include pad pixels when calculating values for
                the edges. Default is 0, doesn't count include pad.

            kernel_shape: The size of the kernel along each axis.

            pads: Padding for the beginning and ending along each spatial axis, it can
                take any value greater than or equal to 0. The value represent the
                number of pixels added to the beginning and end part of the
                corresponding axis. `pads` format should be as follow [x1_begin,
                x2_begin...x1_end, x2_end,...], where xi_begin the number of pixels
                added at the beginning of axis `i` and xi_end, the number of pixels
                added at the end of axis `i`. This attribute cannot be used
                simultaneously with auto_pad attribute. If not present, the padding
                defaults to 0 along start and end of each spatial axis.

            strides: Stride along each spatial axis.
        """

        schema = get_schema("AveragePool", 10, "")
        op = Op(self, "AveragePool", schema)
        return op(
            *self._prepare_inputs(schema, X),
            auto_pad=auto_pad,
            ceil_mode=ceil_mode,
            count_include_pad=count_include_pad,
            kernel_shape=kernel_shape,
            pads=pads,
            strides=strides,
        )

    T1_ConvInteger = TypeVar("T1_ConvInteger", INT8, UINT8)

    T2_ConvInteger = TypeVar("T2_ConvInteger", INT8, UINT8)

    T3_ConvInteger: TypeAlias = INT32

    def ConvInteger(
        self,
        x: T1_ConvInteger,
        w: T2_ConvInteger,
        x_zero_point: Optional[T1_ConvInteger] = None,
        w_zero_point: Optional[T2_ConvInteger] = None,
        *,
        auto_pad: str = "NOTSET",
        dilations: Optional[Sequence[int]] = None,
        group: int = 1,
        kernel_shape: Optional[Sequence[int]] = None,
        pads: Optional[Sequence[int]] = None,
        strides: Optional[Sequence[int]] = None,
    ) -> T3_ConvInteger:
        r"""[🌐 ConvInteger(10)](https://onnx.ai/onnx/operators/onnx__ConvInteger.html#convinteger-10 "Online Documentation")


        The integer convolution operator consumes an input tensor, its zero-point, a filter, and its zero-point,
        and computes the output. The production MUST never overflow. The accumulation may overflow if and only if in 32 bits.


        Args:
            x: Input data tensor from previous layer; has size (N x C x H x W), where N
                is the batch size, C is the number of channels, and H and W are the
                height and width. Note that this is for the 2D image. Otherwise the size
                is (N x C x D1 x D2 ... x Dn). Optionally, if dimension denotation is in
                effect, the operation expects input data tensor to arrive with the
                dimension denotation of [DATA_BATCH, DATA_CHANNEL, DATA_FEATURE,
                DATA_FEATURE ...].

            w: The weight tensor that will be used in the convolutions; has size (M x
                C/group x kH x kW), where C is the number of channels, and kH and kW are
                the height and width of the kernel, and M is the number of feature maps.
                For more than 2 dimensions, the kernel shape will be (M x C/group x k1 x
                k2 x ... x kn), where (k1 x k2 x ... kn) is the dimension of the kernel.
                Optionally, if dimension denotation is in effect, the operation expects
                the weight tensor to arrive with the dimension denotation of
                [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, FILTER_SPATIAL, FILTER_SPATIAL
                ...]. X.shape[1] == (W.shape[1] * group) == C (assuming zero based
                indices for the shape array). Or in other words FILTER_IN_CHANNEL should
                be equal to DATA_CHANNEL.

            x_zero_point: (optional) Zero point tensor for input 'x'. It's optional and
                default value is 0. It's a scalar, which means a per-tensor/layer
                quantization.

            w_zero_point: (optional) Zero point tensor for input 'w'. It's optional and
                default value is 0.  It could be a scalar or a 1-D tensor, which means a
                per-tensor/layer or per output channel quantization. If it's a 1-D
                tensor, its number of elements should be equal to the number of output
                channels (M)

            auto_pad: auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID.
                Where default value is NOTSET, which means explicit padding is used.
                SAME_UPPER or SAME_LOWER mean pad the input so that `output_shape[i] =
                ceil(input_shape[i] / strides[i])` for each axis `i`. The padding is
                split between the two sides equally or almost equally (depending on
                whether it is even or odd). In case the padding is an odd number, the
                extra padding is added at the end for SAME_UPPER and at the beginning
                for SAME_LOWER.

            dilations: dilation value along each spatial axis of the filter. If not
                present, the dilation defaults to 1 along each axis.

            group: number of groups input channels and output channels are divided into.
                default is 1.

            kernel_shape: The shape of the convolution kernel. If not present, should be
                inferred from input 'w'.

            pads: Padding for the beginning and ending along each spatial axis, it can
                take any value greater than or equal to 0.The value represent the number
                of pixels added to the beginning and end part of the corresponding
                axis.`pads` format should be as follow [x1_begin, x2_begin...x1_end,
                x2_end,...], where xi_begin the number ofpixels added at the beginning
                of axis `i` and xi_end, the number of pixels added at the end of axis
                `i`.This attribute cannot be used simultaneously with auto_pad
                attribute. If not present, the padding defaultsto 0 along start and end
                of each spatial axis.

            strides: Stride along each spatial axis. If not present, the stride defaults
                to 1 along each axis.
        """

        schema = get_schema("ConvInteger", 10, "")
        op = Op(self, "ConvInteger", schema)
        return op(
            *self._prepare_inputs(schema, x, w, x_zero_point, w_zero_point),
            auto_pad=auto_pad,
            dilations=dilations,
            group=group,
            kernel_shape=kernel_shape,
            pads=pads,
            strides=strides,
        )

    T_DequantizeLinear = TypeVar("T_DequantizeLinear", INT32, INT8, UINT8)

    def DequantizeLinear(
        self,
        x: T_DequantizeLinear,
        x_scale: FLOAT,
        x_zero_point: Optional[T_DequantizeLinear] = None,
    ) -> FLOAT:
        r"""[🌐 DequantizeLinear(10)](https://onnx.ai/onnx/operators/onnx__DequantizeLinear.html#dequantizelinear-10 "Online Documentation")


        The linear dequantization operator. It consumes a quantized tensor, a scale, a zero point to compute the full precision tensor.
        The dequantization formula is y = (x - x_zero_point) * x_scale. 'x_scale' and 'x_zero_point' are both scalars.
        'x_zero_point' and 'x' must have same type. 'x' and 'y' must have same shape. In the case of dequantizing int32,
        there's no zero point (zero point is supposed to be 0).


        Args:
            x: N-D quantized input tensor to be de-quantized.

            x_scale: Scale for input 'x'. It's a scalar, which means a per-tensor/layer
                quantization.

            x_zero_point: (optional) Zero point for input 'x'. It's a scalar, which
                means a per-tensor/layer quantization. It's optional. 0 is the default
                value when it's not specified.
        """

        schema = get_schema("DequantizeLinear", 10, "")
        op = Op(self, "DequantizeLinear", schema)
        return op(*self._prepare_inputs(schema, x, x_scale, x_zero_point))

    T_Dropout = TypeVar("T_Dropout", DOUBLE, FLOAT, FLOAT16)

    T1_Dropout: TypeAlias = BOOL

    def Dropout(self, data: T_Dropout, *, ratio: float = 0.5) -> Tuple[T_Dropout, T1_Dropout]:
        r"""[🌐 Dropout(10)](https://onnx.ai/onnx/operators/onnx__Dropout.html#dropout-10 "Online Documentation")


        Dropout takes one input floating tensor and produces two tensor outputs,
        output (floating tensor) and mask (`Tensor<bool>`). Depending on whether it is
        in test mode or not, the output Y will either be a random dropout, or a simple
        copy of the input. Note that our implementation of Dropout does scaling in
        the training phase, so during testing nothing needs to be done.
        This operator has **optional** inputs/outputs. See `ONNX <https://github.com/onnx/onnx/blob/master/docs/IR.md>`_ for more details about the representation of optional arguments. An empty string may be used in the place of an actual argument's name to indicate a missing argument. Trailing optional arguments (those not followed by an argument that is present) may also be simply omitted.


        Args:
            data: The input data as Tensor.

            ratio: The ratio of random dropout
        """

        schema = get_schema("Dropout", 10, "")
        op = Op(self, "Dropout", schema)
        return op(*self._prepare_inputs(schema, data), ratio=ratio)

    T1_IsInf = TypeVar("T1_IsInf", DOUBLE, FLOAT)

    T2_IsInf: TypeAlias = BOOL

    def IsInf(
        self, X: T1_IsInf, *, detect_negative: int = 1, detect_positive: int = 1
    ) -> T2_IsInf:
        r"""[🌐 IsInf(10)](https://onnx.ai/onnx/operators/onnx__IsInf.html#isinf-10 "Online Documentation")

        Map infinity to true and other values to false.

        Args:
            X: (non-differentiable) input

            detect_negative: (Optional) Whether map negative infinity to true. Default
                to 1 so that negative infinity induces true. Set this attribute to 0 if
                negative infinity should be mapped to false.

            detect_positive: (Optional) Whether map positive infinity to true. Default
                to 1 so that positive infinity induces true. Set this attribute to 0 if
                positive infinity should be mapped to false.
        """

        schema = get_schema("IsInf", 10, "")
        op = Op(self, "IsInf", schema)
        return op(
            *self._prepare_inputs(schema, X),
            detect_negative=detect_negative,
            detect_positive=detect_positive,
        )

    T1_MatMulInteger = TypeVar("T1_MatMulInteger", INT8, UINT8)

    T2_MatMulInteger = TypeVar("T2_MatMulInteger", INT8, UINT8)

    T3_MatMulInteger: TypeAlias = INT32

    def MatMulInteger(
        self,
        A: T1_MatMulInteger,
        B: T2_MatMulInteger,
        a_zero_point: Optional[T1_MatMulInteger] = None,
        b_zero_point: Optional[T2_MatMulInteger] = None,
    ) -> T3_MatMulInteger:
        r"""[🌐 MatMulInteger(10)](https://onnx.ai/onnx/operators/onnx__MatMulInteger.html#matmulinteger-10 "Online Documentation")


        Matrix product that behaves like [numpy.matmul](https://numpy.org/doc/stable/reference/generated/numpy.matmul.html).
        The production MUST never overflow. The accumulation may overflow if and only if in 32 bits.


        Args:
            A: (non-differentiable) N-dimensional matrix A

            B: (non-differentiable) N-dimensional matrix B

            a_zero_point: (optional, non-differentiable) Zero point tensor for input
                'A'. It's optional and default value is 0. It could be a scalar or N-D
                tensor. Scalar refers to per tensor quantization whereas N-D refers to
                per row quantization. If the input is 2D of shape [M, K] then zero point
                tensor may be an M element vector [zp_1, zp_2, ..., zp_M]. If the input
                is N-D tensor with shape [D1, D2, M, K] then zero point tensor may have
                shape [D1, D2, M, 1].

            b_zero_point: (optional, non-differentiable) Zero point tensor for input
                'B'. It's optional and default value is 0. It could be a scalar or a N-D
                tensor, Scalar refers to per tensor quantization whereas N-D refers to
                per col quantization. If the input is 2D of shape [K, N] then zero point
                tensor may be an N element vector [zp_1, zp_2, ..., zp_N]. If the input
                is N-D tensor with shape [D1, D2, K, N] then zero point tensor may have
                shape [D1, D2, 1, N].
        """

        schema = get_schema("MatMulInteger", 10, "")
        op = Op(self, "MatMulInteger", schema)
        return op(*self._prepare_inputs(schema, A, B, a_zero_point, b_zero_point))

    T_MaxPool = TypeVar("T_MaxPool", DOUBLE, FLOAT, FLOAT16)

    I_MaxPool: TypeAlias = INT64

    def MaxPool(
        self,
        X: T_MaxPool,
        *,
        auto_pad: str = "NOTSET",
        ceil_mode: int = 0,
        dilations: Optional[Sequence[int]] = None,
        kernel_shape: Sequence[int],
        pads: Optional[Sequence[int]] = None,
        storage_order: int = 0,
        strides: Optional[Sequence[int]] = None,
    ) -> Tuple[T_MaxPool, I_MaxPool]:
        r"""[🌐 MaxPool(10)](https://onnx.ai/onnx/operators/onnx__MaxPool.html#maxpool-10 "Online Documentation")


         MaxPool consumes an input tensor X and applies max pooling across
         the tensor according to kernel sizes, stride sizes, and pad lengths.
         max pooling consisting of computing the max on all values of a
         subset of the input tensor according to the kernel size and downsampling the
         data into the output tensor Y for further processing. The output spatial shape will be following:
         ```
         output_spatial_shape[i] = floor((input_spatial_shape[i] + pad_shape[i] - ((kernel_spatial_shape[i] - 1) * dilations[i] + 1)) / strides_spatial_shape[i] + 1)
         ```
         or
         ```
         output_spatial_shape[i] = ceil((input_spatial_shape[i] + pad_shape[i] - ((kernel_spatial_shape[i] - 1) * dilations[i] + 1)) / strides_spatial_shape[i] + 1)
         ```
         if ceil_mode is enabled

         ```
         * pad_shape[i] is sum of pads along axis i
         ```

         `auto_pad` is a DEPRECATED attribute. If you are using them currently, the output spatial shape will be following:
         ```
         VALID: output_spatial_shape[i] = ceil((input_spatial_shape[i] - ((kernel_spatial_shape[i] - 1) * dilations[i] + 1) + 1) / strides_spatial_shape[i])
         SAME_UPPER or SAME_LOWER: output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides_spatial_shape[i])
         ```
         And pad shape will be following if `SAME_UPPER` or `SAME_LOWER`:
         ```
         pad_shape[i] = (output_spatial_shape[i] - 1) * strides_spatial_shape[i] + ((kernel_spatial_shape[i] - 1) * dilations[i] + 1) - input_spatial_shape[i]
         ```
         The output of each pooling window is maximum number of elements exclude pad.


        Args:
            X: Input data tensor from the previous operator; dimensions for image case
                are (N x C x H x W), where N is the batch size, C is the number of
                channels, and H and W are the height and the width of the data. For non
                image case, the dimensions are in the form of (N x C x D1 x D2 ... Dn),
                where N is the batch size. Optionally, if dimension denotation is in
                effect, the operation expects the input data tensor to arrive with the
                dimension denotation of [DATA_BATCH, DATA_CHANNEL, DATA_FEATURE,
                DATA_FEATURE ...].

            auto_pad: auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID.
                Where default value is NOTSET, which means explicit padding is used.
                SAME_UPPER or SAME_LOWER mean pad the input so that the output spatial
                size match the input.In case of odd number add the extra padding at the
                end for SAME_UPPER and at the beginning for SAME_LOWER. VALID mean no
                padding.

            ceil_mode: Whether to use ceil or floor (default) to compute the output
                shape.

            dilations: Dilation value along each spatial axis of filter.

            kernel_shape: The size of the kernel along each axis.

            pads: Padding for the beginning and ending along each spatial axis, it can
                take any value greater than or equal to 0. The value represent the
                number of pixels added to the beginning and end part of the
                corresponding axis. `pads` format should be as follow [x1_begin,
                x2_begin...x1_end, x2_end,...], where xi_begin the number of pixels
                added at the beginning of axis `i` and xi_end, the number of pixels
                added at the end of axis `i`. This attribute cannot be used
                simultaneously with auto_pad attribute. If not present, the padding
                defaults to 0 along start and end of each spatial axis.

            storage_order: The storage order of the tensor. 0 is row major, and 1 is
                column major.

            strides: Stride along each spatial axis.
        """

        schema = get_schema("MaxPool", 10, "")
        op = Op(self, "MaxPool", schema)
        return op(
            *self._prepare_inputs(schema, X),
            auto_pad=auto_pad,
            ceil_mode=ceil_mode,
            dilations=dilations,
            kernel_shape=kernel_shape,
            pads=pads,
            storage_order=storage_order,
            strides=strides,
        )

    T_Mod = TypeVar(
        "T_Mod",
        DOUBLE,
        FLOAT,
        FLOAT16,
        INT16,
        INT32,
        INT64,
        INT8,
        UINT16,
        UINT32,
        UINT64,
        UINT8,
    )

    def Mod(self, A: T_Mod, B: T_Mod, *, fmod: int = 0) -> T_Mod:
        r"""[🌐 Mod(10)](https://onnx.ai/onnx/operators/onnx__Mod.html#mod-10 "Online Documentation")


          Performs element-wise binary modulus (with Numpy-style broadcasting support).
            The sign of the remainder is the same as that of the Divisor.

            Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
            (in contrast to integer mod). To force a behavior like numpy.fmod() an 'fmod' Attribute is provided.
            This attribute is set to 0 by default causing the behavior to be like integer mod.
            Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().

            If the input type is floating point, then `fmod` attribute must be set to 1.

            In case of dividend being zero, the results will be platform dependent.

          This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check `Broadcasting in ONNX <https://github.com/onnx/onnx/blob/master/docs/Broadcasting.md>`_.


        Args:
            A: Dividend tensor

            B: Divisor tensor

            fmod: Whether the operator should behave like fmod (default=0 meaning it
                will do integer mods); Set this to 1 to force fmod treatment
        """

        schema = get_schema("Mod", 10, "")
        op = Op(self, "Mod", schema)
        return op(*self._prepare_inputs(schema, A, B), fmod=fmod)

    def NonMaxSuppression(
        self,
        boxes: FLOAT,
        scores: FLOAT,
        max_output_boxes_per_class: Optional[INT64] = None,
        iou_threshold: Optional[FLOAT] = None,
        score_threshold: Optional[FLOAT] = None,
        *,
        center_point_box: int = 0,
    ) -> INT64:
        r"""[🌐 NonMaxSuppression(10)](https://onnx.ai/onnx/operators/onnx__NonMaxSuppression.html#nonmaxsuppression-10 "Online Documentation")


        Filter out boxes that have high intersection-over-union (IOU) overlap with previously selected boxes.
        Bounding boxes with score less than score_threshold are removed. Bounding box format is indicated by attribute center_point_box.
        Note that this algorithm is agnostic to where the origin is in the coordinate system and more generally is invariant to
        orthogonal transformations and translations of the coordinate system; thus translating or reflections of the coordinate system
        result in the same boxes being selected by the algorithm.
        The selected_indices output is a set of integers indexing into the input collection of bounding boxes representing the selected boxes.
        The bounding box coordinates corresponding to the selected indices can then be obtained using the Gather or GatherND operation.


        Args:
            boxes: An input tensor with shape [num_batches, spatial_dimension, 4]. The
                single box data format is indicated by center_point_box.

            scores: An input tensor with shape [num_batches, num_classes,
                spatial_dimension]

            max_output_boxes_per_class: (optional) Integer representing the maximum
                number of boxes to be selected per batch per class. It is a scalar.
                Default to 0, which means no output.

            iou_threshold: (optional) Float representing the threshold for deciding
                whether boxes overlap too much with respect to IOU. It is scalar. Value
                range [0, 1]. Default to 0.

            score_threshold: (optional) Float representing the threshold for deciding
                when to remove boxes based on score. It is a scalar.

            center_point_box: Integer indicate the format of the box data. The default
                is 0. 0 - the box data is supplied as [y1, x1, y2, x2] where (y1, x1)
                and (y2, x2) are the coordinates of any diagonal pair of box corners and
                the coordinates can be provided as normalized (i.e., lying in the
                interval [0, 1]) or absolute. Mostly used for TF models. 1 - the box
                data is supplied as [x_center, y_center, width, height]. Mostly used for
                Pytorch models.
        """

        schema = get_schema("NonMaxSuppression", 10, "")
        op = Op(self, "NonMaxSuppression", schema)
        return op(
            *self._prepare_inputs(
                schema,
                boxes,
                scores,
                max_output_boxes_per_class,
                iou_threshold,
                score_threshold,
            ),
            center_point_box=center_point_box,
        )

    T1_QLinearConv = TypeVar("T1_QLinearConv", INT8, UINT8)

    T2_QLinearConv = TypeVar("T2_QLinearConv", INT8, UINT8)

    T3_QLinearConv = TypeVar("T3_QLinearConv", INT8, UINT8)

    T4_QLinearConv: TypeAlias = INT32

    def QLinearConv(
        self,
        x: T1_QLinearConv,
        x_scale: FLOAT,
        x_zero_point: T1_QLinearConv,
        w: T2_QLinearConv,
        w_scale: FLOAT,
        w_zero_point: T2_QLinearConv,
        y_scale: FLOAT,
        y_zero_point: T3_QLinearConv,
        B: Optional[T4_QLinearConv] = None,
        *,
        auto_pad: str = "NOTSET",
        dilations: Optional[Sequence[int]] = None,
        group: int = 1,
        kernel_shape: Optional[Sequence[int]] = None,
        pads: Optional[Sequence[int]] = None,
        strides: Optional[Sequence[int]] = None,
    ) -> T3_QLinearConv:
        r"""[🌐 QLinearConv(10)](https://onnx.ai/onnx/operators/onnx__QLinearConv.html#qlinearconv-10 "Online Documentation")


        The convolution operator consumes a quantized input tensor, its scale and zero point,
        a quantized filter, its scale and zero point, and output's scale and zero point,
        and computes the quantized output. Each scale and zero-point pair must have same shape.
        It means they must be either scalars (per tensor) or 1-D tensors (per output channel).
        Each input or output and its related zero point must have same type.
        When bias is present it must be quantized using scale = input scale * weight scale and
        zero point as 0.


        Args:
            x: Input data tensor from previous layer; has size (N x C x H x W), where N
                is the batch size, C is the number of channels, and H and W are the
                height and width. Note that this is for the 2D image. Otherwise the size
                is (N x C x D1 x D2 ... x Dn). Optionally, if dimension denotation is in
                effect, the operation expects input data tensor to arrive with the
                dimension denotation of [DATA_BATCH, DATA_CHANNEL, DATA_FEATURE,
                DATA_FEATURE ...].

            x_scale: Scale tensor for input 'x'. It's a scalar, which means a
                per-tensor/layer quantization.

            x_zero_point: Zero point tensor for input 'x'. It's a scalar, which means a
                per-tensor/layer quantization.

            w: The weight tensor that will be used in the convolutions; has size (M x
                C/group x kH x kW), where C is the number of channels, and kH and kW are
                the height and width of the kernel, and M is the number of feature maps.
                For more than 2 dimensions, the kernel shape will be (M x C/group x k1 x
                k2 x ... x kn), where (k1 x k2 x ... kn) is the dimension of the kernel.
                Optionally, if dimension denotation is in effect, the operation expects
                the weight tensor to arrive with the dimension denotation of
                [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, FILTER_SPATIAL, FILTER_SPATIAL
                ...]. X.shape[1] == (W.shape[1] * group) == C (assuming zero based
                indices for the shape array). Or in other words FILTER_IN_CHANNEL should
                be equal to DATA_CHANNEL.

            w_scale: Scale tensor for input 'w'. It could be a scalar or a 1-D tensor,
                which means a per-tensor/layer or per output channel quantization. If
                it's a 1-D tensor, its number of elements should be equal to the number
                of output channels (M).

            w_zero_point: Zero point tensor for input 'w'. It could be a scalar or a 1-D
                tensor, which means a per-tensor/layer or per output channel
                quantization. If it's a 1-D tensor, its number of elements should be
                equal to the number of output channels (M).

            y_scale: Scale tensor for output 'y'. It's a scalar, which means a
                per-tensor/layer quantization.

            y_zero_point: Zero point tensor for output 'y'. It's a scalar, which means a
                per-tensor/layer quantization.

            B: (optional) Optional 1D bias to be added to the convolution, has size of
                M. Bias must be quantized using scale = x_scale * w_scale and zero_point
                = 0

            auto_pad: auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID.
                Where default value is NOTSET, which means explicit padding is used.
                SAME_UPPER or SAME_LOWER mean pad the input so that `output_shape[i] =
                ceil(input_shape[i] / strides[i])` for each axis `i`. The padding is
                split between the two sides equally or almost equally (depending on
                whether it is even or odd). In case the padding is an odd number, the
                extra padding is added at the end for SAME_UPPER and at the beginning
                for SAME_LOWER.

            dilations: dilation value along each spatial axis of the filter. If not
                present, the dilation defaults to 1 along each spatial axis.

            group: number of groups input channels and output channels are divided into.
                default is 1.

            kernel_shape: The shape of the convolution kernel. If not present, should be
                inferred from input 'w'.

            pads: Padding for the beginning and ending along each spatial axis, it can
                take any value greater than or equal to 0.The value represent the number
                of pixels added to the beginning and end part of the corresponding
                axis.`pads` format should be as follow [x1_begin, x2_begin...x1_end,
                x2_end,...], where xi_begin the number ofpixels added at the beginning
                of axis `i` and xi_end, the number of pixels added at the end of axis
                `i`.This attribute cannot be used simultaneously with auto_pad
                attribute. If not present, the padding defaultsto 0 along start and end
                of each spatial axis.

            strides: Stride along each spatial axis. If not present, the stride defaults
                to 1 along each spatial axis.
        """

        schema = get_schema("QLinearConv", 10, "")
        op = Op(self, "QLinearConv", schema)
        return op(
            *self._prepare_inputs(
                schema,
                x,
                x_scale,
                x_zero_point,
                w,
                w_scale,
                w_zero_point,
                y_scale,
                y_zero_point,
                B,
            ),
            auto_pad=auto_pad,
            dilations=dilations,
            group=group,
            kernel_shape=kernel_shape,
            pads=pads,
            strides=strides,
        )

    T1_QLinearMatMul = TypeVar("T1_QLinearMatMul", INT8, UINT8)

    T2_QLinearMatMul = TypeVar("T2_QLinearMatMul", INT8, UINT8)

    T3_QLinearMatMul = TypeVar("T3_QLinearMatMul", INT8, UINT8)

    def QLinearMatMul(
        self,
        a: T1_QLinearMatMul,
        a_scale: FLOAT,
        a_zero_point: T1_QLinearMatMul,
        b: T2_QLinearMatMul,
        b_scale: FLOAT,
        b_zero_point: T2_QLinearMatMul,
        y_scale: FLOAT,
        y_zero_point: T3_QLinearMatMul,
    ) -> T3_QLinearMatMul:
        r"""[🌐 QLinearMatMul(10)](https://onnx.ai/onnx/operators/onnx__QLinearMatMul.html#qlinearmatmul-10 "Online Documentation")


        Matrix product that behaves like [numpy.matmul](https://numpy.org/doc/stable/reference/generated/numpy.matmul.html).
        It consumes two quantized input tensors, their scales and zero points, scale and zero point of output,
        and computes the quantized output. The quantization formula is y = saturate((x / y_scale) + y_zero_point).
        For (x / y_scale), it is rounding to nearest ties to even. Refer to https://en.wikipedia.org/wiki/Rounding for details.
        Scale and zero point must have same shape. They must be either scalar (per tensor) or N-D tensor
        (per row for 'a' and per column for 'b'). Scalar refers to per tensor quantization whereas N-D refers to per row
        or per column quantization. If the input is 2D of shape [M, K] then zero point and scale tensor may be
        an M element vector [v_1, v_2, ..., v_M] for per row quantization and K element vector of shape [v_1, v_2, ..., v_K]
        for per column quantization. If the input is N-D tensor with shape [D1, D2, M, K] then zero point and scale tensor may
        have shape [D1, D2, M, 1] for per row quantization and shape [D1, D2, 1, K] for per column quantization.
        Production must never overflow, and accumulation may overflow if and only if in 32 bits.


        Args:
            a: (non-differentiable) N-dimensional quantized matrix a

            a_scale: (non-differentiable) scale of quantized input a

            a_zero_point: (non-differentiable) zero point of quantized input a

            b: (non-differentiable) N-dimensional quantized matrix b

            b_scale: (non-differentiable) scale of quantized input b

            b_zero_point: (non-differentiable) zero point of quantized input b

            y_scale: (non-differentiable) scale of quantized output y

            y_zero_point: (non-differentiable) zero point of quantized output y
        """

        schema = get_schema("QLinearMatMul", 10, "")
        op = Op(self, "QLinearMatMul", schema)
        return op(
            *self._prepare_inputs(
                schema,
                a,
                a_scale,
                a_zero_point,
                b,
                b_scale,
                b_zero_point,
                y_scale,
                y_zero_point,
            )
        )

    T1_QuantizeLinear = TypeVar("T1_QuantizeLinear", FLOAT, INT32)

    T2_QuantizeLinear = TypeVar("T2_QuantizeLinear", INT8, UINT8)

    def QuantizeLinear(
        self,
        x: T1_QuantizeLinear,
        y_scale: FLOAT,
        y_zero_point: Optional[T2_QuantizeLinear] = None,
    ) -> T2_QuantizeLinear:
        r"""[🌐 QuantizeLinear(10)](https://onnx.ai/onnx/operators/onnx__QuantizeLinear.html#quantizelinear-10 "Online Documentation")


        The linear per-tensor/layer quantization operator. It consumes a high precision tensor, a scale, a zero point to compute the low precision / quantized tensor.
        The quantization formula is y = saturate ((x / y_scale) + y_zero_point). For saturation, it saturates to [0, 255] if it's uint8, or [-128, 127] if it's int8.
        For (x / y_scale), it's rounding to the nearest even. Refer to https://en.wikipedia.org/wiki/Rounding for details. 'y_zero_point' and 'y' must have same type.


        Args:
            x: N-D full precision Input tensor to be quantized.

            y_scale: Scale for doing quantization to get 'y'. It's a scalar, which means
                a per-tensor/layer quantization.

            y_zero_point: (optional) Zero point for doing quantization to get 'y'. It's
                a scalar, which means a per-tensor/layer quantization. Default value is
                uint8 typed 0 if it's not specified.
        """

        schema = get_schema("QuantizeLinear", 10, "")
        op = Op(self, "QuantizeLinear", schema)
        return op(*self._prepare_inputs(schema, x, y_scale, y_zero_point))

    T_Resize = TypeVar(
        "T_Resize",
        BOOL,
        COMPLEX128,
        COMPLEX64,
        DOUBLE,
        FLOAT,
        FLOAT16,
        INT16,
        INT32,
        INT64,
        INT8,
        STRING,
        UINT16,
        UINT32,
        UINT64,
        UINT8,
    )

    def Resize(self, X: T_Resize, scales: FLOAT, *, mode: str = "nearest") -> T_Resize:
        r"""[🌐 Resize(10)](https://onnx.ai/onnx/operators/onnx__Resize.html#resize-10 "Online Documentation")


        Resize the input tensor.
        Each dimension value of the output tensor is:
          output_dimension = floor(input_dimension * scale).


        Args:
            X: N-D tensor

            scales: The scale array along each dimension. It takes value greater than 0.
                If it's less than 1, it's sampling down, otherwise, it's upsampling. The
                number of elements of 'scales' should be the same as the rank of input
                'X'.

            mode: Two interpolation modes: nearest (default), and linear (including
                bilinear, trilinear, etc)
        """

        schema = get_schema("Resize", 10, "")
        op = Op(self, "Resize", schema)
        return op(*self._prepare_inputs(schema, X, scales), mode=mode)

    T_ReverseSequence = TypeVar(
        "T_ReverseSequence",
        BOOL,
        COMPLEX128,
        COMPLEX64,
        DOUBLE,
        FLOAT,
        FLOAT16,
        INT16,
        INT32,
        INT64,
        INT8,
        STRING,
        UINT16,
        UINT32,
        UINT64,
        UINT8,
    )

    def ReverseSequence(
        self,
        input: T_ReverseSequence,
        sequence_lens: INT64,
        *,
        batch_axis: int = 1,
        time_axis: int = 0,
    ) -> T_ReverseSequence:
        r"""[🌐 ReverseSequence(10)](https://onnx.ai/onnx/operators/onnx__ReverseSequence.html#reversesequence-10 "Online Documentation")


        Reverse batch of sequences having different lengths specified by `sequence_lens`.

        For each slice i iterating on batch axis, the operator reverses the first sequence_lens[i] elements on time axis,
        and copies elements whose index's beyond sequence_lens[i] to the output. So the output slice i contains reversed
        sequences on the first sequence_lens[i] elements, then have original values copied for the other elements.

        Example 1:
          input = [[0.0, 4.0, 8.0,  12.0],
                   [1.0, 5.0, 9.0,  13.0],
                   [2.0, 6.0, 10.0, 14.0],
                   [3.0, 7.0, 11.0, 15.0]]
          sequence_lens = [4, 3, 2, 1]
          time_axis = 0
          batch_axis = 1

          output = [[3.0, 6.0, 9.0,  12.0],
                    [2.0, 5.0, 8.0,  13.0],
                    [1.0, 4.0, 10.0, 14.0],
                    [0.0, 7.0, 11.0, 15.0]]

        Example 2:
          input = [[0.0,  1.0,  2.0,  3.0 ],
                   [4.0,  5.0,  6.0,  7.0 ],
                   [8.0,  9.0,  10.0, 11.0],
                   [12.0, 13.0, 14.0, 15.0]]
          sequence_lens = [1, 2, 3, 4]
          time_axis = 1
          batch_axis = 0

          output = [[0.0,  1.0,  2.0,  3.0 ],
                    [5.0,  4.0,  6.0,  7.0 ],
                    [10.0, 9.0,  8.0,  11.0],
                    [15.0, 14.0, 13.0, 12.0]]


        Args:
            input: Tensor of rank r >= 2.

            sequence_lens: Tensor specifying lengths of the sequences in a batch. It has
                shape `[batch_size]`.

            batch_axis: (Optional) Specify which axis is batch axis. Must be one of 1
                (default), or 0.

            time_axis: (Optional) Specify which axis is time axis. Must be one of 0
                (default), or 1.
        """

        schema = get_schema("ReverseSequence", 10, "")
        op = Op(self, "ReverseSequence", schema)
        return op(
            *self._prepare_inputs(schema, input, sequence_lens),
            batch_axis=batch_axis,
            time_axis=time_axis,
        )

    T1_RoiAlign = TypeVar("T1_RoiAlign", DOUBLE, FLOAT, FLOAT16)

    T2_RoiAlign: TypeAlias = INT64

    def RoiAlign(
        self,
        X: T1_RoiAlign,
        rois: T1_RoiAlign,
        batch_indices: T2_RoiAlign,
        *,
        mode: str = "avg",
        output_height: int = 1,
        output_width: int = 1,
        sampling_ratio: int = 0,
        spatial_scale: float = 1.0,
    ) -> T1_RoiAlign:
        r"""[🌐 RoiAlign(10)](https://onnx.ai/onnx/operators/onnx__RoiAlign.html#roialign-10 "Online Documentation")


        Region of Interest (RoI) align operation described in the
        [Mask R-CNN paper](https://arxiv.org/abs/1703.06870).
        RoiAlign consumes an input tensor X and region of interests (rois)
        to apply pooling across each RoI; it produces a 4-D tensor of shape
        (num_rois, C, output_height, output_width).

        RoiAlign is proposed to avoid the misalignment by removing
        quantizations while converting from original image into feature
        map and from feature map into RoI feature; in each ROI bin,
        the value of the sampled locations are computed directly
        through bilinear interpolation.


        Args:
            X: Input data tensor from the previous operator; 4-D feature map of shape
                (N, C, H, W), where N is the batch size, C is the number of channels,
                and H and W are the height and the width of the data.

            rois: RoIs (Regions of Interest) to pool over; rois is 2-D input of shape
                (num_rois, 4) given as [[x1, y1, x2, y2], ...]. The RoIs' coordinates
                are in the coordinate system of the input image. Each coordinate set has
                a 1:1 correspondence with the 'batch_indices' input.

            batch_indices: 1-D tensor of shape (num_rois,) with each element denoting
                the index of the corresponding image in the batch.

            mode: The pooling method. Two modes are supported: 'avg' and 'max'. Default
                is 'avg'.

            output_height: default 1; Pooled output Y's height.

            output_width: default 1; Pooled output Y's width.

            sampling_ratio: Number of sampling points in the interpolation grid used to
                compute the output value of each pooled output bin. If > 0, then exactly
                sampling_ratio x sampling_ratio grid points are used. If == 0, then an
                adaptive number of grid points are used (computed as ceil(roi_width /
                output_width), and likewise for height). Default is 0.

            spatial_scale: Multiplicative spatial scale factor to translate ROI
                coordinates from their input spatial scale to the scale used when
                pooling, i.e., spatial scale of the input feature map X relative to the
                input image. E.g.; default is 1.0f.
        """

        schema = get_schema("RoiAlign", 10, "")
        op = Op(self, "RoiAlign", schema)
        return op(
            *self._prepare_inputs(schema, X, rois, batch_indices),
            mode=mode,
            output_height=output_height,
            output_width=output_width,
            sampling_ratio=sampling_ratio,
            spatial_scale=spatial_scale,
        )

    T_Slice = TypeVar(
        "T_Slice",
        BOOL,
        COMPLEX128,
        COMPLEX64,
        DOUBLE,
        FLOAT,
        FLOAT16,
        INT16,
        INT32,
        INT64,
        INT8,
        STRING,
        UINT16,
        UINT32,
        UINT64,
        UINT8,
    )

    Tind_Slice = TypeVar("Tind_Slice", INT32, INT64)

    def Slice(
        self,
        data: T_Slice,
        starts: Tind_Slice,
        ends: Tind_Slice,
        axes: Optional[Tind_Slice] = None,
        steps: Optional[Tind_Slice] = None,
    ) -> T_Slice:
        r"""[🌐 Slice(10)](https://onnx.ai/onnx/operators/onnx__Slice.html#slice-10 "Online Documentation")


        Produces a slice of the input tensor along multiple axes. Similar to numpy:
        https://numpy.org/doc/stable/reference/routines.indexing.html
        Slices uses `starts`, `ends`, `axes` and `steps` inputs to specify the start and end
        dimension and step for each axis in the list of axes, it uses this information to
        slice the input `data` tensor. If a negative value is passed for any of the
        start or end indices, it represent number of elements before the end of that
        dimension. If the value passed to start or end is larger than the `n` (the
        number of elements in this dimension), it represents `n`. For slicing to the
        end of a dimension with unknown size, it is recommended to pass in `INT_MAX`.
        If a negative value is passed for step, it represents slicing backward.
        If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
        If `steps` are omitted, they are set to `[1, ..., 1]` of length `len(starts)`
        Example 1:
          data = [
              [1, 2, 3, 4],
              [5, 6, 7, 8],
          ]
          axes = [0, 1]
          starts = [1, 0]
          ends = [2, 3]
          steps = [1, 2]
          result = [
              [5, 7],
          ]
        Example 2:
          data = [
              [1, 2, 3, 4],
              [5, 6, 7, 8],
          ]
          starts = [0, 1]
          ends = [-1, 1000]
          result = [
              [2, 3, 4],
          ]


        Args:
            data: Tensor of data to extract slices from.

            starts: 1-D tensor of starting indices of corresponding axis in `axes`

            ends: 1-D tensor of ending indices (exclusive) of corresponding axis in
                `axes`

            axes: (optional) 1-D tensor of axes that `starts` and `ends` apply to.

            steps: (optional) 1-D tensor of slice step of corresponding axis in `axes`.
                Default to 1.
        """

        schema = get_schema("Slice", 10, "")
        op = Op(self, "Slice", schema)
        return op(*self._prepare_inputs(schema, data, starts, ends, axes, steps))

    def StringNormalizer(
        self,
        X: STRING,
        *,
        case_change_action: str = "NONE",
        is_case_sensitive: int = 0,
        locale: Optional[str] = None,
        stopwords: Optional[Sequence[str]] = None,
    ) -> STRING:
        r"""[🌐 StringNormalizer(10)](https://onnx.ai/onnx/operators/onnx__StringNormalizer.html#stringnormalizer-10 "Online Documentation")


        StringNormalization performs string operations for basic cleaning.
        This operator has only one input (denoted by X) and only one output
        (denoted by Y). This operator first examines the elements in the X,
        and removes elements specified in "stopwords" attribute.
        After removing stop words, the intermediate result can be further lowercased,
        uppercased, or just returned depending the "case_change_action" attribute.
        This operator only accepts [C]- and [1, C]-tensor.
        If all elements in X are dropped, the output will be the empty value of string tensor with shape [1]
        if input shape is [C] and shape [1, 1] if input shape is [1, C].


        Args:
            X: UTF-8 strings to normalize

            case_change_action: string enum that cases output to be
                lowercased/uppercases/unchanged. Valid values are "LOWER", "UPPER",
                "NONE". Default is "NONE"

            is_case_sensitive: Boolean. Whether the identification of stop words in X is
                case-sensitive. Default is false

            locale: Environment dependent string that denotes the locale according to
                which output strings needs to be upper/lowercased.Default en_US or
                platform specific equivalent as decided by the implementation.

            stopwords: List of stop words. If not set, no word would be removed from X.
        """

        schema = get_schema("StringNormalizer", 10, "")
        op = Op(self, "StringNormalizer", schema)
        return op(
            *self._prepare_inputs(schema, X),
            case_change_action=case_change_action,
            is_case_sensitive=is_case_sensitive,
            locale=locale,
            stopwords=stopwords,
        )

    T_ThresholdedRelu = TypeVar("T_ThresholdedRelu", DOUBLE, FLOAT, FLOAT16)

    def ThresholdedRelu(
        self, X: T_ThresholdedRelu, *, alpha: float = 1.0
    ) -> T_ThresholdedRelu:
        r"""[🌐 ThresholdedRelu(10)](https://onnx.ai/onnx/operators/onnx__ThresholdedRelu.html#thresholdedrelu-10 "Online Documentation")


        ThresholdedRelu takes one input data (Tensor<T>) and produces one output data
        (Tensor<T>) where the rectified linear function, y = x for x > alpha, y = 0 otherwise,
        is applied to the tensor elementwise.


        Args:
            X: (differentiable) Input tensor

            alpha: Threshold value
        """

        schema = get_schema("ThresholdedRelu", 10, "")
        op = Op(self, "ThresholdedRelu", schema)
        return op(*self._prepare_inputs(schema, X), alpha=alpha)

    T_TopK = TypeVar("T_TopK", DOUBLE, FLOAT, FLOAT16)

    I_TopK: TypeAlias = INT64

    def TopK(self, X: T_TopK, K: INT64, *, axis: int = -1) -> Tuple[T_TopK, I_TopK]:
        r"""[🌐 TopK(10)](https://onnx.ai/onnx/operators/onnx__TopK.html#topk-10 "Online Documentation")


        Retrieve the top-K elements along a specified axis. Given an input tensor of
        shape [a_0, a_1, ..., a_{n-1}] and integer argument k, return two outputs:
          -Value tensor of shape [a_0, a_1, ..., a_{axis-1}, k, a_{axis+1}, ... a_{n-1}]
            which contains the values of the top k elements along the specified axis
          -Index tensor of shape [a_0, a_1, ..., a_{axis-1}, k, a_{axis+1}, ... a_{n-1}] which
           contains the indices of the top k elements (original indices from the input
           tensor).

        Given two equivalent values, this operator uses the indices along the axis  as
         a tiebreaker. That is, the element with the lower index will appear first.


        Args:
            X: Tensor of shape [a_0, a_1, ..., a_{n-1}]

            K: A 1-D tensor containing a single positive value corresponding to the
                number of top elements to retrieve

            axis: Dimension on which to do the sort.
        """

        schema = get_schema("TopK", 10, "")
        op = Op(self, "TopK", schema)
        return op(*self._prepare_inputs(schema, X, K), axis=axis)
