# --------------------------------------------------------------------------
# ⚠️ 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, D405
# --------------------------------------------------------------------------

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.opset13 import Opset13
from onnxscript.onnx_types import (
    BFLOAT16,
    BOOL,
    COMPLEX64,
    COMPLEX128,
    DOUBLE,
    FLOAT,
    FLOAT16,
    INT8,
    INT16,
    INT32,
    INT64,
    STRING,
    UINT8,
    UINT16,
    UINT32,
    UINT64,
)
from onnxscript.values import Op, Opset


class Opset14(Opset13):
    def __new__(cls):
        return Opset.__new__(cls, "", 14)

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

    def Add(self, A: T_Add, B: T_Add) -> T_Add:
        r"""[🌐 Add(14)](https://onnx.ai/onnx/operators/onnx__Add.html#add-14 "Online Documentation")


        Performs element-wise binary addition (with Numpy-style broadcasting support).

        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>`_.

        (Opset 14 change): Extend supported types to include uint8, int8, uint16, and int16.


        Args:
            A: (differentiable) First operand.

            B: (differentiable) Second operand.
        """

        schema = get_schema("Add", 14, "")
        op = Op(self, "Add", schema)
        return op(*self._prepare_inputs(schema, A, B))

    T_BatchNormalization = TypeVar("T_BatchNormalization", BFLOAT16, DOUBLE, FLOAT, FLOAT16)

    U_BatchNormalization = TypeVar("U_BatchNormalization", BFLOAT16, DOUBLE, FLOAT, FLOAT16)

    def BatchNormalization(
        self,
        X: T_BatchNormalization,
        scale: T_BatchNormalization,
        B: T_BatchNormalization,
        input_mean: U_BatchNormalization,
        input_var: U_BatchNormalization,
        *,
        epsilon: float = 9.999999747378752e-06,
        momentum: float = 0.8999999761581421,
        training_mode: int = 0,
    ) -> Tuple[T_BatchNormalization, U_BatchNormalization, U_BatchNormalization]:
        r"""[🌐 BatchNormalization(14)](https://onnx.ai/onnx/operators/onnx__BatchNormalization.html#batchnormalization-14 "Online Documentation")


        Carries out batch normalization as described in the paper
        https://arxiv.org/abs/1502.03167. Depending on the mode it is being run,
        There are five required inputs 'X', 'scale', 'B', 'input_mean' and
        'input_var'.
        Note that 'input_mean' and 'input_var' are expected to be the estimated
        statistics in inference mode (training_mode=False, default),
        and the running statistics in training mode (training_mode=True).
        There are multiple cases for the number of outputs, which we list below:

        Output case #1: Y, running_mean, running_var (training_mode=True)
        Output case #2: Y (training_mode=False)

        When training_mode=False, extra outputs are invalid.
        The outputs are updated as follows when training_mode=True:
        ::

            running_mean = input_mean * momentum + current_mean * (1 - momentum)
            running_var = input_var * momentum + current_var * (1 - momentum)

            Y = (X - current_mean) / sqrt(current_var + epsilon) * scale + B

            where:

            current_mean = ReduceMean(X, axis=all_except_channel_index)
            current_var =  ReduceVar(X, axis=all_except_channel_index)

            Notice that ReduceVar refers to the population variance, and it equals to
            sum(sqrd(x_i - x_avg)) / N
            where N is the population size (this formula does not use sample size N - 1).




        When training_mode=False:
        ::

            Y = (X - input_mean) / sqrt(input_var + epsilon) * scale + B



        For previous (depreciated) non-spatial cases, implementors are suggested
        to flatten the input shape to (N x C * D1 * D2 * ... * Dn) before a BatchNormalization Op.
        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:
            X: (differentiable) Input data tensor from the previous operator; dimensions
                are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size,
                C is the number of channels. Statistics are computed for every channel
                of C over N and D1 to Dn dimensions. For image data, input dimensions
                become (N x C x H x W). The op also accepts single dimension input of
                size N in which case C is assumed to be 1

            scale: (differentiable) Scale tensor of shape (C).

            B: (differentiable) Bias tensor of shape (C).

            input_mean: (differentiable) running (training) or estimated (testing) mean
                tensor of shape (C).

            input_var: (differentiable) running (training) or estimated (testing)
                variance tensor of shape (C).

            epsilon: The epsilon value to use to avoid division by zero.

            momentum: Factor used in computing the running mean and variance.e.g.,
                running_mean = running_mean * momentum + mean * (1 - momentum).

            training_mode: If set to true, it indicates BatchNormalization is being used
                for training, and outputs 1, 2, 3, and 4 would be populated.
        """

        schema = get_schema("BatchNormalization", 14, "")
        op = Op(self, "BatchNormalization", schema)
        return op(
            *self._prepare_inputs(schema, X, scale, B, input_mean, input_var),
            epsilon=epsilon,
            momentum=momentum,
            training_mode=training_mode,
        )

    T_CumSum = TypeVar(
        "T_CumSum", BFLOAT16, DOUBLE, FLOAT, FLOAT16, INT32, INT64, UINT32, UINT64
    )

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

    def CumSum(
        self, x: T_CumSum, axis: T2_CumSum, *, exclusive: int = 0, reverse: int = 0
    ) -> T_CumSum:
        r"""[🌐 CumSum(14)](https://onnx.ai/onnx/operators/onnx__CumSum.html#cumsum-14 "Online Documentation")


        Performs cumulative sum of the input elements along the given axis.
        By default, it will do the sum inclusively meaning the first element is copied as is.
        Through an `exclusive` attribute, this behavior can change to exclude the first element.
        It can also perform summation in the opposite direction of the axis. For that, set `reverse` attribute to 1.

        Example:
        ::

            input_x = [1, 2, 3]
            axis=0
            output = [1, 3, 6]
            exclusive=1
            output = [0, 1, 3]
            exclusive=0
            reverse=1
            output = [6, 5, 3]
            exclusive=1
            reverse=1
            output = [5, 3, 0]




        Args:
            x: (differentiable) An input tensor that is to be processed.

            axis: (non-differentiable) A 0-D tensor. Must be in the range [-rank(x),
                rank(x)-1]. Negative value means counting dimensions from the back.

            exclusive: If set to 1 will return exclusive sum in which the top element is
                not included. In other terms, if set to 1, the j-th output element would
                be the sum of the first (j-1) elements. Otherwise, it would be the sum
                of the first j elements.

            reverse: If set to 1 will perform the sums in reverse direction.
        """

        schema = get_schema("CumSum", 14, "")
        op = Op(self, "CumSum", schema)
        return op(*self._prepare_inputs(schema, x, axis), exclusive=exclusive, reverse=reverse)

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

    def Div(self, A: T_Div, B: T_Div) -> T_Div:
        r"""[🌐 Div(14)](https://onnx.ai/onnx/operators/onnx__Div.html#div-14 "Online Documentation")


        Performs element-wise binary division (with Numpy-style broadcasting support).

        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>`_.

        (Opset 14 change): Extend supported types to include uint8, int8, uint16, and int16.


        Args:
            A: (differentiable) First operand.

            B: (differentiable) Second operand.
        """

        schema = get_schema("Div", 14, "")
        op = Op(self, "Div", schema)
        return op(*self._prepare_inputs(schema, A, B))

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

    T1_GRU: TypeAlias = INT32

    def GRU(
        self,
        X: T_GRU,
        W: T_GRU,
        R: T_GRU,
        B: Optional[T_GRU] = None,
        sequence_lens: Optional[T1_GRU] = None,
        initial_h: Optional[T_GRU] = None,
        *,
        activation_alpha: Optional[Sequence[float]] = None,
        activation_beta: Optional[Sequence[float]] = None,
        activations: Optional[Sequence[str]] = None,
        clip: Optional[float] = None,
        direction: str = "forward",
        hidden_size: Optional[int] = None,
        layout: int = 0,
        linear_before_reset: int = 0,
    ) -> Tuple[T_GRU, T_GRU]:
        r"""[🌐 GRU(14)](https://onnx.ai/onnx/operators/onnx__GRU.html#gru-14 "Online Documentation")


        Computes an one-layer GRU. This operator is usually supported via some custom
        implementation such as CuDNN.

        Notations:

        * `X` - input tensor
        * `z` - update gate
        * `r` - reset gate
        * `h` - hidden gate
        * `t` - time step (t-1 means previous time step)
        * `W[zrh]` - W parameter weight matrix for update, reset, and hidden gates
        * `R[zrh]` - R recurrence weight matrix for update, reset, and hidden gates
        * `Wb[zrh]` - W bias vectors for update, reset, and hidden gates
        * `Rb[zrh]` - R bias vectors for update, reset, and hidden gates
        * `WB[zrh]` - W parameter weight matrix for backward update, reset, and hidden gates
        * `RB[zrh]` - R recurrence weight matrix for backward update, reset, and hidden gates
        * `WBb[zrh]` - W bias vectors for backward update, reset, and hidden gates
        * `RBb[zrh]` - R bias vectors for backward update, reset, and hidden gates
        * `H` - Hidden state
        * `num_directions` - 2 if direction == bidirectional else 1

        Activation functions:

        * Relu(x)                - max(0, x)
        * Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})
        * Sigmoid(x)             - 1/(1 + e^{-x})

        NOTE:
          Below are optional

        * Affine(x)              - alpha * x + beta
        * LeakyRelu(x)           - x if x >= 0 else alpha * x
        * ThresholdedRelu(x)     - x if x >= alpha else 0
        * ScaledTanh(x)          - alpha * Tanh(beta * x)
        * HardSigmoid(x)         - min(max(alpha * x + beta, 0), 1)
        * Elu(x)                 - x if x >= 0 else alpha * (e^x - 1)
        * Softsign(x)            - x/(1 + |x|)
        * Softplus(x)            - log(1 + e^x)

        Equations (Default: f=Sigmoid, g=Tanh):

        * zt = f(Xt*(Wz^T) + Ht-1*(Rz^T) + Wbz + Rbz)
        * rt = f(Xt*(Wr^T) + Ht-1*(Rr^T) + Wbr + Rbr)
        * ht = g(Xt*(Wh^T) + (rt (.) Ht-1)*(Rh^T) + Rbh + Wbh) # default, when linear_before_reset = 0
        * ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*(Rh^T) + Rbh)) + Wbh) # when linear_before_reset != 0
        * Ht = (1 - zt) (.) ht + zt (.) Ht-1
        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:
            X: (differentiable) The input sequences packed (and potentially padded) into
                one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.

            W: (differentiable) The weight tensor for the gates. Concatenation of
                `W[zrh]` and `WB[zrh]` (if bidirectional) along dimension 0. This tensor
                has shape `[num_directions, 3*hidden_size, input_size]`.

            R: (differentiable) The recurrence weight tensor. Concatenation of `R[zrh]`
                and `RB[zrh]` (if bidirectional) along dimension 0. This tensor has
                shape `[num_directions, 3*hidden_size, hidden_size]`.

            B: (optional, differentiable) The bias tensor for the gates. Concatenation
                of `[Wb[zrh], Rb[zrh]]` and `[WBb[zrh], RBb[zrh]]` (if bidirectional)
                along dimension 0. This tensor has shape `[num_directions,
                6*hidden_size]`. Optional: If not specified - assumed to be 0

            sequence_lens: (optional, non-differentiable) Optional tensor specifying
                lengths of the sequences in a batch. If not specified - assumed all
                sequences in the batch to have length `seq_length`. It has shape
                `[batch_size]`.

            initial_h: (optional, non-differentiable) Optional initial value of the
                hidden. If not specified - assumed to be 0. It has shape
                `[num_directions, batch_size, hidden_size]`.

            activation_alpha: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.For example with LeakyRelu, the default
                alpha is 0.01.

            activation_beta: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.

            activations: A list of 2 (or 4 if bidirectional) activation functions for
                update, reset, and hidden gates. The activation functions must be one of
                the activation functions specified above. Optional: See the equations
                for default if not specified.

            clip: Cell clip threshold. Clipping bounds the elements of a tensor in the
                range of [-threshold, +threshold] and is applied to the input of
                activations. No clip if not specified.

            direction: Specify if the RNN is forward, reverse, or bidirectional. Must be
                one of forward (default), reverse, or bidirectional.

            hidden_size: Number of neurons in the hidden layer

            layout: The shape format of inputs X, initial_h and outputs Y, Y_h. If 0,
                the following shapes are expected: X.shape = [seq_length, batch_size,
                input_size], Y.shape = [seq_length, num_directions, batch_size,
                hidden_size], initial_h.shape = Y_h.shape = [num_directions, batch_size,
                hidden_size]. If 1, the following shapes are expected: X.shape =
                [batch_size, seq_length, input_size], Y.shape = [batch_size, seq_length,
                num_directions, hidden_size], initial_h.shape = Y_h.shape = [batch_size,
                num_directions, hidden_size].

            linear_before_reset: When computing the output of the hidden gate, apply the
                linear transformation before multiplying by the output of the reset
                gate.
        """

        schema = get_schema("GRU", 14, "")
        op = Op(self, "GRU", schema)
        return op(
            *self._prepare_inputs(schema, X, W, R, B, sequence_lens, initial_h),
            activation_alpha=activation_alpha,
            activation_beta=activation_beta,
            activations=activations,
            clip=clip,
            direction=direction,
            hidden_size=hidden_size,
            layout=layout,
            linear_before_reset=linear_before_reset,
        )

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

    def HardSwish(self, X: T_HardSwish) -> T_HardSwish:
        r"""[🌐 HardSwish(14)](https://onnx.ai/onnx/operators/onnx__HardSwish.html#hardswish-14 "Online Documentation")


        HardSwish takes one input data (Tensor<T>) and produces one output data (Tensor<T>) where
        the HardSwish function, y = x * max(0, min(1, alpha * x + beta)) = x * HardSigmoid<alpha, beta>(x),
        where alpha = 1/6 and beta = 0.5, is applied to the tensor elementwise.


        Args:
            X: (differentiable) Input tensor
        """

        schema = get_schema("HardSwish", 14, "")
        op = Op(self, "HardSwish", schema)
        return op(*self._prepare_inputs(schema, X))

    V_Identity = TypeVar(
        "V_Identity",
        Sequence[BOOL],
        Sequence[COMPLEX128],
        Sequence[COMPLEX64],
        Sequence[DOUBLE],
        Sequence[FLOAT],
        Sequence[FLOAT16],
        Sequence[INT16],
        Sequence[INT32],
        Sequence[INT64],
        Sequence[INT8],
        Sequence[STRING],
        Sequence[UINT16],
        Sequence[UINT32],
        Sequence[UINT64],
        Sequence[UINT8],
        BFLOAT16,
        BOOL,
        COMPLEX128,
        COMPLEX64,
        DOUBLE,
        FLOAT,
        FLOAT16,
        INT16,
        INT32,
        INT64,
        INT8,
        STRING,
        UINT16,
        UINT32,
        UINT64,
        UINT8,
    )

    def Identity(self, input: V_Identity) -> V_Identity:
        r"""[🌐 Identity(14)](https://onnx.ai/onnx/operators/onnx__Identity.html#identity-14 "Online Documentation")

        Identity operator

        Args:
            input: (differentiable) Input tensor
        """

        schema = get_schema("Identity", 14, "")
        op = Op(self, "Identity", schema)
        return op(*self._prepare_inputs(schema, input))

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

    T1_LSTM: TypeAlias = INT32

    def LSTM(
        self,
        X: T_LSTM,
        W: T_LSTM,
        R: T_LSTM,
        B: Optional[T_LSTM] = None,
        sequence_lens: Optional[T1_LSTM] = None,
        initial_h: Optional[T_LSTM] = None,
        initial_c: Optional[T_LSTM] = None,
        P: Optional[T_LSTM] = None,
        *,
        activation_alpha: Optional[Sequence[float]] = None,
        activation_beta: Optional[Sequence[float]] = None,
        activations: Optional[Sequence[str]] = None,
        clip: Optional[float] = None,
        direction: str = "forward",
        hidden_size: Optional[int] = None,
        input_forget: int = 0,
        layout: int = 0,
    ) -> Tuple[T_LSTM, T_LSTM, T_LSTM]:
        r"""[🌐 LSTM(14)](https://onnx.ai/onnx/operators/onnx__LSTM.html#lstm-14 "Online Documentation")


        Computes an one-layer LSTM. This operator is usually supported via some
        custom implementation such as CuDNN.

        Notations:

        * `X` - input tensor
        * `i` - input gate
        * `o` - output gate
        * `f` - forget gate
        * `c` - cell gate
        * `t` - time step (t-1 means previous time step)
        * `W[iofc]` - W parameter weight matrix for input, output, forget, and cell gates
        * `R[iofc]` - R recurrence weight matrix for input, output, forget, and cell gates
        * `Wb[iofc]` - W bias vectors for input, output, forget, and cell gates
        * `Rb[iofc]` - R bias vectors for input, output, forget, and cell gates
        * `P[iof]`  - P peephole weight vector for input, output, and forget gates
        * `WB[iofc]` - W parameter weight matrix for backward input, output, forget, and cell gates
        * `RB[iofc]` - R recurrence weight matrix for backward input, output, forget, and cell gates
        * `WBb[iofc]` - W bias vectors for backward input, output, forget, and cell gates
        * `RBb[iofc]` - R bias vectors for backward input, output, forget, and cell gates
        * `PB[iof]`  - P peephole weight vector for backward input, output, and forget gates
        * `H` - Hidden state
        * `num_directions` - 2 if direction == bidirectional else 1

        Activation functions:

        * Relu(x)                - max(0, x)
        * Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})
        * Sigmoid(x)             - 1/(1 + e^{-x})

        NOTE: Below are optional

        * Affine(x)              - alpha*x + beta
        * LeakyRelu(x)           - x if x >= 0 else alpha * x
        * ThresholdedRelu(x)     - x if x >= alpha else 0
        * ScaledTanh(x)          - alpha*Tanh(beta*x)
        * HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)
        * Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)
        * Softsign(x)            - x/(1 + |x|)
        * Softplus(x)            - log(1 + e^x)

        Equations (Default: f=Sigmoid, g=Tanh, h=Tanh):

        * it = f(Xt*(Wi^T) + Ht-1*(Ri^T) + Pi (.) Ct-1 + Wbi + Rbi)
        * ft = f(Xt*(Wf^T) + Ht-1*(Rf^T) + Pf (.) Ct-1 + Wbf + Rbf)
        * ct = g(Xt*(Wc^T) + Ht-1*(Rc^T) + Wbc + Rbc)
        * Ct = ft (.) Ct-1 + it (.) ct
        * ot = f(Xt*(Wo^T) + Ht-1*(Ro^T) + Po (.) Ct + Wbo + Rbo)
        * Ht = ot (.) h(Ct)
        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:
            X: (differentiable) The input sequences packed (and potentially padded) into
                one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.

            W: (differentiable) The weight tensor for the gates. Concatenation of
                `W[iofc]` and `WB[iofc]` (if bidirectional) along dimension 0. The
                tensor has shape `[num_directions, 4*hidden_size, input_size]`.

            R: (differentiable) The recurrence weight tensor. Concatenation of `R[iofc]`
                and `RB[iofc]` (if bidirectional) along dimension 0. This tensor has
                shape `[num_directions, 4*hidden_size, hidden_size]`.

            B: (optional, differentiable) The bias tensor for input gate. Concatenation
                of `[Wb[iofc], Rb[iofc]]`, and `[WBb[iofc], RBb[iofc]]` (if
                bidirectional) along dimension 0. This tensor has shape
                `[num_directions, 8*hidden_size]`. Optional: If not specified - assumed
                to be 0.

            sequence_lens: (optional, non-differentiable) Optional tensor specifying
                lengths of the sequences in a batch. If not specified - assumed all
                sequences in the batch to have length `seq_length`. It has shape
                `[batch_size]`.

            initial_h: (optional, non-differentiable) Optional initial value of the
                hidden. If not specified - assumed to be 0. It has shape
                `[num_directions, batch_size, hidden_size]`.

            initial_c: (optional, non-differentiable) Optional initial value of the
                cell. If not specified - assumed to be 0. It has shape `[num_directions,
                batch_size, hidden_size]`.

            P: (optional, differentiable) The weight tensor for peepholes. Concatenation
                of `P[iof]` and `PB[iof]` (if bidirectional) along dimension 0. It has
                shape `[num_directions, 3*hidde_size]`. Optional: If not specified -
                assumed to be 0.

            activation_alpha: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.For example with LeakyRelu, the default
                alpha is 0.01.

            activation_beta: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.

            activations: A list of 3 (or 6 if bidirectional) activation functions for
                input, output, forget, cell, and hidden. The activation functions must
                be one of the activation functions specified above. Optional: See the
                equations for default if not specified.

            clip: Cell clip threshold. Clipping bounds the elements of a tensor in the
                range of [-threshold, +threshold] and is applied to the input of
                activations. No clip if not specified.

            direction: Specify if the RNN is forward, reverse, or bidirectional. Must be
                one of forward (default), reverse, or bidirectional.

            hidden_size: Number of neurons in the hidden layer

            input_forget: Couple the input and forget gates if 1.

            layout: The shape format of inputs X, initial_h, initial_c and outputs Y,
                Y_h, Y_c. If 0, the following shapes are expected: X.shape =
                [seq_length, batch_size, input_size], Y.shape = [seq_length,
                num_directions, batch_size, hidden_size], initial_h.shape = Y_h.shape =
                initial_c.shape = Y_c.shape = [num_directions, batch_size, hidden_size].
                If 1, the following shapes are expected: X.shape = [batch_size,
                seq_length, input_size], Y.shape = [batch_size, seq_length,
                num_directions, hidden_size], initial_h.shape = Y_h.shape =
                initial_c.shape = Y_c.shape = [batch_size, num_directions, hidden_size].
        """

        schema = get_schema("LSTM", 14, "")
        op = Op(self, "LSTM", schema)
        return op(
            *self._prepare_inputs(schema, X, W, R, B, sequence_lens, initial_h, initial_c, P),
            activation_alpha=activation_alpha,
            activation_beta=activation_beta,
            activations=activations,
            clip=clip,
            direction=direction,
            hidden_size=hidden_size,
            input_forget=input_forget,
            layout=layout,
        )

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

    def Mul(self, A: T_Mul, B: T_Mul) -> T_Mul:
        r"""[🌐 Mul(14)](https://onnx.ai/onnx/operators/onnx__Mul.html#mul-14 "Online Documentation")


        Performs element-wise binary multiplication (with Numpy-style broadcasting support).

        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>`_.

        (Opset 14 change): Extend supported types to include uint8, int8, uint16, and int16.


        Args:
            A: (differentiable) First operand.

            B: (differentiable) Second operand.
        """

        schema = get_schema("Mul", 14, "")
        op = Op(self, "Mul", schema)
        return op(*self._prepare_inputs(schema, A, B))

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

    T1_RNN: TypeAlias = INT32

    def RNN(
        self,
        X: T_RNN,
        W: T_RNN,
        R: T_RNN,
        B: Optional[T_RNN] = None,
        sequence_lens: Optional[T1_RNN] = None,
        initial_h: Optional[T_RNN] = None,
        *,
        activation_alpha: Optional[Sequence[float]] = None,
        activation_beta: Optional[Sequence[float]] = None,
        activations: Sequence[str] = ("Tanh", "Tanh"),
        clip: Optional[float] = None,
        direction: str = "forward",
        hidden_size: Optional[int] = None,
        layout: int = 0,
    ) -> Tuple[T_RNN, T_RNN]:
        r"""[🌐 RNN(14)](https://onnx.ai/onnx/operators/onnx__RNN.html#rnn-14 "Online Documentation")


        Computes an one-layer simple RNN. This operator is usually supported
        via some custom implementation such as CuDNN.

        Notations:

        * `X` - input tensor
        * `i` - input gate
        * `t` - time step (t-1 means previous time step)
        * `Wi` - W parameter weight matrix for input gate
        * `Ri` - R recurrence weight matrix for input gate
        * `Wbi` - W parameter bias vector for input gate
        * `Rbi` - R parameter bias vector for input gate
        * `WBi` - W parameter weight matrix for backward input gate
        * `RBi` - R recurrence weight matrix for backward input gate
        * `WBbi` - WR bias vectors for backward input gate
        * `RBbi` - RR bias vectors for backward input gate
        * `H` - Hidden state
        * `num_directions` - 2 if direction == bidirectional else 1

        Activation functions:

        * Relu(x)                - max(0, x)
        * Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})
        * Sigmoid(x)             - 1/(1 + e^{-x})

        NOTE: Below are optional

        * Affine(x)              - alpha*x + beta
        * LeakyRelu(x)           - x if x >= 0 else alpha * x
        * ThresholdedRelu(x)     - x if x >= alpha else 0
        * ScaledTanh(x)          - alpha*Tanh(beta*x)
        * HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)
        * Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)
        * Softsign(x)            - x/(1 + |x|)
        * Softplus(x)            - log(1 + e^x)

        Equations (Default: f=Tanh):

        * Ht = f(Xt*(Wi^T) + Ht-1*(Ri^T) + Wbi + Rbi)
        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:
            X: (differentiable) The input sequences packed (and potentially padded) into
                one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.

            W: (differentiable) The weight tensor for input gate. Concatenation of `Wi`
                and `WBi` (if bidirectional). The tensor has shape `[num_directions,
                hidden_size, input_size]`.

            R: (differentiable) The recurrence weight tensor. Concatenation of `Ri` and
                `RBi` (if bidirectional). The tensor has shape `[num_directions,
                hidden_size, hidden_size]`.

            B: (optional, differentiable) The bias tensor for input gate. Concatenation
                of `[Wbi, Rbi]` and `[WBbi, RBbi]` (if bidirectional). The tensor has
                shape `[num_directions, 2*hidden_size]`. Optional: If not specified -
                assumed to be 0.

            sequence_lens: (optional, non-differentiable) Optional tensor specifying
                lengths of the sequences in a batch. If not specified - assumed all
                sequences in the batch to have length `seq_length`. It has shape
                `[batch_size]`.

            initial_h: (optional, non-differentiable) Optional initial value of the
                hidden. If not specified - assumed to be 0. It has shape
                `[num_directions, batch_size, hidden_size]`.

            activation_alpha: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.For example with LeakyRelu, the default
                alpha is 0.01.

            activation_beta: Optional scaling values used by some activation functions.
                The values are consumed in the order of activation functions, for
                example (f, g, h) in LSTM. Default values are the same as of
                corresponding ONNX operators.

            activations: One (or two if bidirectional) activation function for input
                gate. The activation function must be one of the activation functions
                specified above. Optional: Default `Tanh` if not specified.

            clip: Cell clip threshold. Clipping bounds the elements of a tensor in the
                range of [-threshold, +threshold] and is applied to the input of
                activations. No clip if not specified.

            direction: Specify if the RNN is forward, reverse, or bidirectional. Must be
                one of forward (default), reverse, or bidirectional.

            hidden_size: Number of neurons in the hidden layer

            layout: The shape format of inputs X, initial_h and outputs Y, Y_h. If 0,
                the following shapes are expected: X.shape = [seq_length, batch_size,
                input_size], Y.shape = [seq_length, num_directions, batch_size,
                hidden_size], initial_h.shape = Y_h.shape = [num_directions, batch_size,
                hidden_size]. If 1, the following shapes are expected: X.shape =
                [batch_size, seq_length, input_size], Y.shape = [batch_size, seq_length,
                num_directions, hidden_size], initial_h.shape = Y_h.shape = [batch_size,
                num_directions, hidden_size].
        """

        schema = get_schema("RNN", 14, "")
        op = Op(self, "RNN", schema)
        return op(
            *self._prepare_inputs(schema, X, W, R, B, sequence_lens, initial_h),
            activation_alpha=activation_alpha,
            activation_beta=activation_beta,
            activations=activations,
            clip=clip,
            direction=direction,
            hidden_size=hidden_size,
            layout=layout,
        )

    T_Relu = TypeVar("T_Relu", BFLOAT16, DOUBLE, FLOAT, FLOAT16, INT16, INT32, INT64, INT8)

    def Relu(self, X: T_Relu) -> T_Relu:
        r"""[🌐 Relu(14)](https://onnx.ai/onnx/operators/onnx__Relu.html#relu-14 "Online Documentation")


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


        Args:
            X: (differentiable) Input tensor
        """

        schema = get_schema("Relu", 14, "")
        op = Op(self, "Relu", schema)
        return op(*self._prepare_inputs(schema, X))

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

    def Reshape(self, data: T_Reshape, shape: INT64, *, allowzero: int = 0) -> T_Reshape:
        r"""[🌐 Reshape(14)](https://onnx.ai/onnx/operators/onnx__Reshape.html#reshape-14 "Online Documentation")


        Reshape the input tensor similar to numpy.reshape.
        First input is the data tensor, second input is a shape tensor which specifies the output shape. It outputs the reshaped tensor.
        At most one dimension of the new shape can be -1. In this case, the value is
        inferred from the size of the tensor and the remaining dimensions. A dimension
        could also be 0, in which case the actual dimension value is unchanged (i.e. taken
        from the input tensor). If 'allowzero' is set, and the new shape includes 0, the
        dimension will be set explicitly to zero (i.e. not taken from input tensor).
        Shape (second input) could be an empty shape, which means converting to a scalar.
        The input tensor's shape and the output tensor's shape are required to have the same number of elements.

        If the attribute 'allowzero' is set, it is invalid for the specified shape to
        contain both a zero value and -1, as the value of the dimension corresponding
        to -1 cannot be determined uniquely.


        Args:
            data: (differentiable) An input tensor.

            shape: (non-differentiable) Specified shape for output.

            allowzero: (Optional) By default, when any value in the 'shape' input is
                equal to zero the corresponding dimension value is copied from the input
                tensor dynamically. allowzero=1 indicates that if any value in the
                'shape' input is set to zero, the zero value is honored, similar to
                NumPy.
        """

        schema = get_schema("Reshape", 14, "")
        op = Op(self, "Reshape", schema)
        return op(*self._prepare_inputs(schema, data, shape), allowzero=allowzero)

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

    def Sub(self, A: T_Sub, B: T_Sub) -> T_Sub:
        r"""[🌐 Sub(14)](https://onnx.ai/onnx/operators/onnx__Sub.html#sub-14 "Online Documentation")


        Performs element-wise binary subtraction (with Numpy-style broadcasting support).

        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>`_.

        (Opset 14 change): Extend supported types to include uint8, int8, uint16, and int16.


        Args:
            A: (differentiable) First operand.

            B: (differentiable) Second operand.
        """

        schema = get_schema("Sub", 14, "")
        op = Op(self, "Sub", schema)
        return op(*self._prepare_inputs(schema, A, B))

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

    def Trilu(self, input: T_Trilu, k: Optional[INT64] = None, *, upper: int = 1) -> T_Trilu:
        r"""[🌐 Trilu(14)](https://onnx.ai/onnx/operators/onnx__Trilu.html#trilu-14 "Online Documentation")


        Given a 2-D matrix or batches of 2-D matrices, returns the upper or lower triangular part of the tensor(s).
        The attribute "upper" determines whether the upper or lower part is retained. If set to true,
        the upper triangular matrix is retained. Lower triangular matrix is retained otherwise.
        Default value for the "upper" attribute is true.
        Trilu takes one input tensor of shape [*, N, M], where * is zero or more batch dimensions. The upper triangular part consists
        of the elements on and above the given diagonal (k). The lower triangular part consists of elements on and below the diagonal.
        All other elements in the matrix are set to zero.
        If k = 0, the triangular part on and above/below the main diagonal is retained.
        If upper is set to true, a positive k retains the upper triangular matrix excluding the main diagonal and (k-1) diagonals above it.
        A negative k value retains the main diagonal and |k| diagonals below it.
        If upper is set to false, a positive k retains the lower triangular matrix including the main diagonal and k diagonals above it.
        A negative k value excludes the main diagonal and (|k|-1) diagonals below it.


        Args:
            input: (differentiable) Input tensor of rank 2 or higher.

            k: (optional, non-differentiable) A 0-D tensor containing a single value
                corresponding to the number diagonals above or below the main diagonal
                to exclude or include. Default value is 0 if it's not specified.

            upper: Boolean. Indicates whether upper or lower part of matrix is retained.
                Default is true.
        """

        schema = get_schema("Trilu", 14, "")
        op = Op(self, "Trilu", schema)
        return op(*self._prepare_inputs(schema, input, k), upper=upper)
