[
  {
    "name": "ATen",
    "schema": {
      "description": "Experimental allowing ATen operations to be accessed directly from Caffe2\nto allow for quick prototyping when ONNX is missing standard versions of\nand op",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Arbitrary input",
          "name": "input",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 2147483647,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Arbitrary output",
          "name": "output",
          "option": "variadic",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to bool, int32, int64, float16, float, double tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Abs",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Absolute takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the absolute is, y = abs(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Abs',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.abs(x)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_abs')",
          "summary": "abs"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Abs",
    "schema": {
      "description": "Absolute takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the absolute is, y = abs(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Abs',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.abs(x)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_abs')",
          "summary": "abs"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Add",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Performs element-wise binary addition (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Add',\n    inputs=['x', 'y'],\n    outputs=['sum'],\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nexpect(node, inputs=[x, y], outputs=[x + y],\n       name='test_add')",
          "summary": "add"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Add',\n    inputs=['x', 'y'],\n    outputs=['sum'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nexpect(node, inputs=[x, y], outputs=[x + y],\n       name='test_add_bcast')",
          "summary": "add_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Add",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Performs element-wise binary addition (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Add',\n    inputs=['x', 'y'],\n    outputs=['sum'],\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nexpect(node, inputs=[x, y], outputs=[x + y],\n       name='test_add')",
          "summary": "add"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Add',\n    inputs=['x', 'y'],\n    outputs=['sum'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nexpect(node, inputs=[x, y], outputs=[x + y],\n       name='test_add_bcast')",
          "summary": "add_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Affine",
    "schema": {
      "attributes": [
        {
          "description": "Value of alpha",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Value of beta",
          "name": "beta",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Affine takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the affine function, y = alpha * x + beta,\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "1D input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "1D output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "And",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `and` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n)\n\n# 2d\nx = (np.random.randn(3, 4) > 0).astype(np.bool)\ny = (np.random.randn(3, 4) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and2d')\n\n# 3d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and3d')\n\n# 4d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and4d')",
          "summary": "and"
        },
        {
          "code": "x = (np.random.randn(5, 5, 5, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\n\nnode = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n    broadcast=1,\n    axis=0,\n)\n\nz = np.logical_and(x, y[:, np.newaxis, np.newaxis, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and_axis0')\n\nnode = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n    broadcast=1,\n    axis=1,\n)\n\nz = np.logical_and(x, y[:, np.newaxis, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and_axis1')\n\nnode = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n    broadcast=1,\n    axis=2,\n)\n\nz = np.logical_and(x, y[:, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and_axis2')\n\nnode = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n    broadcast=1,\n    axis=3,\n)\n\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_and_axis3')",
          "summary": "and_axis"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'And',\n    inputs=['x', 'y'],\n    outputs=['and'],\n    broadcast=1,\n)\n\n# 3d vs 1d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast3v1d')\n\n# 3d vs 2d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(4, 5) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast3v2d')\n\n# 4d vs 2d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(5, 6) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast4v2d')\n\n# 4d vs 3d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(4, 5, 6) > 0).astype(np.bool)\nz = np.logical_and(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast4v3d')",
          "summary": "and_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains input to boolean tensor.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "ArgMax",
    "schema": {
      "attributes": [
        {
          "description": "The axis in which to compute the arg indices",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the indices of the max elements of the input tensor's element along the \nprovided axis. The resulted tensor has the same rank as the input if keepdims equal 1.\nIf keepdims equal 0, then the resulted tensor have the reduced dimension pruned. \nThe type of the output tensor is integer.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor with integer data type.",
          "name": "reduced",
          "type": "tensor(int32)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ArgMin",
    "schema": {
      "attributes": [
        {
          "description": "The axis in which to compute the arg indices",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the indices of the min elements of the input tensor's element along the \nprovided axis. The resulted tensor has the same rank as the input if keepdims equal 1.\nIf keepdims equal 0, then the resulted tensor have the reduced dimension pruned. \nThe type of the output tensor is integer.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor with integer data type.",
          "name": "reduced",
          "type": "tensor(int32)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ArrayFeatureExtractor",
    "schema": {
      "description": "Select a subset of the data based on the indices passed.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be selected",
          "name": "X",
          "type": "T1"
        },
        {
          "description": "The index values to select as a tensor of int64s",
          "name": "Y",
          "type": "T2"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Selected output data as an array",
          "name": "Z",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)",
            "tensor(string)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(int64)"
          ],
          "description": " Index value types .",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "AveragePool",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "The size of the kernel along each axis.",
          "name": "kernel_shape",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "Padding for the beginning and ending along each 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 axis.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis. If not present, the stride defaults to 1 along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Pool",
      "description": "AveragePool consumes an input tensor X and applies average pooling across the\n the tensor according to kernel sizes, stride sizes, and pad lengths.\n average pooling consisting of computing the average on all values of a\n subset of the input tensor according to the kernel size and downsampling the\n data into the output tensor Y for further processing. The output spatial shape will be following:\n ```\n output_spatial_shape[i] = floor((input_spatial_shape[i] + pad_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)\n\n * pad_shape[i] is sum of pads along axis i\n ```\n\n `auto_pad` is a DEPRECATED attribute. If you are using them currently, the output spatial shape will be following:\n ```\n VALID: output_spatial_shape[i] = floor((input_spatial_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)\n SAME_UPPER or SAME_LOWER: output_spatial_shape[i] = floor(input_spatial_shape[i] / strides_spatial_shape[i] + 1)\n ```\n And pad shape will be following if `SAME_UPPER` or `SAME_LOWER`:\n ```\n pad_shape[i] = (output_spatial_shape[i] - 1) * strides_spatial_shape[i] + kernel_spatial_shape[i] - input_spatial_shape[i]\n ```\n The output of each pooling window is divided by the number of elements exclude pad.\n ",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32]\noutput_shape: [1, 3, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2],\n)\nx = np.random.randn(1, 3, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = [2]\nstrides = [1]\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, [0], 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_1d_default')",
          "summary": "averagepool_1d_default"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 31, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, (0, 0), 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_default')",
          "summary": "averagepool_2d_default"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 28, 28]\noutput_shape: [1, 3, 30, 30]\npad_shape: [4, 4] -> [2, 2, 2, 2] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    pads=[2, 2, 2, 2]\n)\nx = np.random.randn(1, 3, 28, 28).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (3, 3)\nstrides = (1, 1)\npad_bottom = 2\npad_top = 2\npad_right = 2\npad_left = 2\npad_shape = [pad_top + pad_bottom, pad_left + pad_right]\nout_shape = get_output_shape('VALID', np.add(x_shape[2:], pad_shape), kernel_shape, strides)\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_pads')",
          "summary": "averagepool_2d_pads"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 5, 5]\npad_shape: [4, 4] -> [2, 2, 2, 2] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[5, 5],\n    pads=[2, 2, 2, 2]\n\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[[7, 7.5, 8, 8.5, 9],\n                [9.5, 10, 10.5, 11, 11.5],\n                [12, 12.5, 13, 13.5, 14],\n                [14.5, 15, 15.5, 16, 16.5],\n                [17, 17.5, 18, 18.5, 19]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_precomputed_pads')",
          "summary": "averagepool_2d_precomputed_pads"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 3, 3]\npad_shape: [2, 2] -> [1, 1, 1, 1] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    strides=[2, 2],\n    auto_pad='SAME_UPPER'\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[[4, 5.5, 7],\n                [11.5, 13, 14.5],\n                [19, 20.5, 22]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_precomputed_same_upper')",
          "summary": "averagepool_2d_precomputed_same_upper"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 2, 2]\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    strides=[2, 2]\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[[4, 6],\n                [14, 16]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_precomputed_strides')",
          "summary": "averagepool_2d_precomputed_strides"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 32, 32]\npad_shape: [1, 1] -> [1, 0, 1, 0] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    auto_pad='SAME_LOWER'\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('SAME_LOWER', x_shape[2:], kernel_shape, strides)\npad_shape = get_pad_shape('SAME_LOWER', x_shape[2:], kernel_shape, strides, out_shape)\npad_bottom = pad_shape[0] // 2\npad_top = pad_shape[0] - pad_bottom\npad_right = pad_shape[1] // 2\npad_left = pad_shape[1] - pad_right\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_same_lower')",
          "summary": "averagepool_2d_same_lower"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 32, 32]\npad_shape: [1, 1] -> [0, 1, 0, 1] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    auto_pad='SAME_UPPER'\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('SAME_UPPER', x_shape[2:], kernel_shape, strides)\npad_shape = get_pad_shape('SAME_UPPER', x_shape[2:], kernel_shape, strides, out_shape)\npad_top = pad_shape[0] // 2\npad_bottom = pad_shape[0] - pad_top\npad_left = pad_shape[1] // 2\npad_right = pad_shape[1] - pad_left\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_same_upper')",
          "summary": "averagepool_2d_same_upper"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 10, 10]\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[5, 5],\n    strides=[3, 3]\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (5, 5)\nstrides = (3, 3)\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, (0, 0), 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_2d_strides')",
          "summary": "averagepool_2d_strides"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32, 32]\noutput_shape: [1, 3, 31, 31, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'AveragePool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2, 2],\n)\nx = np.random.randn(1, 3, 32, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = [2, 2, 2]\nstrides = [1, 1, 1]\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, [0, 0, 0], 'AVG')\n\nexpect(node, inputs=[x], outputs=[y], name='test_averagepool_3d_default')",
          "summary": "averagepool_3d_default"
        }
      ],
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from average or max pooling across the input tensor. Dimensions will vary based on various kernel, stride, and pad sizes. Floor value of the dimension is used",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "BatchNormalization",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "The epsilon value to use to avoid division by zero, default is 1e-5f.",
          "name": "epsilon",
          "required": false,
          "type": "float"
        },
        {
          "description": "If set to nonzero, run spatial batch normalization in test mode, default is 0.",
          "name": "is_test",
          "required": false,
          "type": "int"
        },
        {
          "description": "Factor used in computing the running mean and variance.e.g., running_mean = running_mean * momentum + mean * (1 - momentum), default is 0.9f.",
          "name": "momentum",
          "required": false,
          "type": "float"
        },
        {
          "description": "If true, compute the mean and variance across all spatial elements If false, compute the mean and variance across per feature.Default is 1.",
          "name": "spatial",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Normalization",
      "description": "Carries out batch normalization as described in the paper\nhttps://arxiv.org/abs/1502.03167. Depending on the mode it is being run,\nthere are multiple cases for the number of outputs, which we list below:\n\nOutput case #1: Y, mean, var, saved_mean, saved_var (training mode)\nOutput case #2: Y (test mode)\n    ",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input 4-dimensional tensor of shape NCHW.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "The scale as a 1-dimensional tensor of size C to be applied to the output.",
          "name": "scale",
          "type": "T"
        },
        {
          "description": "The bias as a 1-dimensional tensor of size C to be applied to the output.",
          "name": "B",
          "type": "T"
        },
        {
          "description": "The running mean (training) or the estimated mean (testing) as a 1-dimensional tensor of size C.",
          "name": "mean",
          "type": "T"
        },
        {
          "description": "The running variance (training) or the estimated variance (testing) as a 1-dimensional tensor of size C.",
          "name": "var",
          "type": "T"
        }
      ],
      "max_input": 5,
      "max_output": 5,
      "min_input": 5,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output 4-dimensional tensor of the same shape as X.",
          "name": "Y",
          "type": "T"
        },
        {
          "description": "The running mean after the BatchNormalization operator. Must be in-place with the input mean. Should not be used for testing.",
          "name": "mean",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The running variance after the BatchNormalization operator. Must be in-place with the input var. Should not be used for testing.",
          "name": "var",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "Saved mean used during training to speed up gradient computation. Should not be used for testing.",
          "name": "saved_mean",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "Saved variance used during training to speed up gradient computation. Should not be used for testing.",
          "name": "saved_var",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "BatchNormalization",
    "schema": {
      "attributes": [
        {
          "description": "The epsilon value to use to avoid division by zero, default is 1e-5f.",
          "name": "epsilon",
          "required": false,
          "type": "float"
        },
        {
          "description": "If set to nonzero, run spatial batch normalization in test mode, default is 0.",
          "name": "is_test",
          "required": false,
          "type": "int"
        },
        {
          "description": "Factor used in computing the running mean and variance.e.g., running_mean = running_mean * momentum + mean * (1 - momentum), default is 0.9f.",
          "name": "momentum",
          "required": false,
          "type": "float"
        },
        {
          "description": "If true, compute the mean and variance across all spatial elements If false, compute the mean and variance across per feature.Default is 1.",
          "name": "spatial",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Normalization",
      "description": "Carries out batch normalization as described in the paper\nhttps://arxiv.org/abs/1502.03167. Depending on the mode it is being run,\nthere are multiple cases for the number of outputs, which we list below:\n\nOutput case #1: Y, mean, var, saved_mean, saved_var (training mode)\nOutput case #2: Y (test mode)\n    ",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input 4-dimensional tensor of shape NCHW.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "The scale as a 1-dimensional tensor of size C to be applied to the output.",
          "name": "scale",
          "type": "T"
        },
        {
          "description": "The bias as a 1-dimensional tensor of size C to be applied to the output.",
          "name": "B",
          "type": "T"
        },
        {
          "description": "The running mean (training) or the estimated mean (testing) as a 1-dimensional tensor of size C.",
          "name": "mean",
          "type": "T"
        },
        {
          "description": "The running variance (training) or the estimated variance (testing) as a 1-dimensional tensor of size C.",
          "name": "var",
          "type": "T"
        }
      ],
      "max_input": 5,
      "max_output": 5,
      "min_input": 5,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output 4-dimensional tensor of the same shape as X.",
          "name": "Y",
          "type": "T"
        },
        {
          "description": "The running mean after the BatchNormalization operator. Must be in-place with the input mean. Should not be used for testing.",
          "name": "mean",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The running variance after the BatchNormalization operator. Must be in-place with the input var. Should not be used for testing.",
          "name": "var",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "Saved mean used during training to speed up gradient computation. Should not be used for testing.",
          "name": "saved_mean",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "Saved variance used during training to speed up gradient computation. Should not be used for testing.",
          "name": "saved_var",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Binarizer",
    "schema": {
      "attributes": [
        {
          "description": "Values greater than this are set to 1, else set to 0",
          "name": "threshold",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Makes values 1 or 0 based on a single threshold.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be binarized",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Binarized output data",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Cast",
    "schema": {
      "attributes": [
        {
          "description": "The data type to which the elements of the input tensor are cast.Strictly must be one of the types from DataType enum in TensorProto",
          "name": "to",
          "required": true,
          "type": "string"
        }
      ],
      "description": "The operator casts the elements of a given input tensor to a data type\nspecified by the 'to' argument and returns an output tensor of the same size in\nthe converted type. The 'to' argument must be one of the data types specified\nin the 'DataType' enum field in the TensorProto message.\n\nNOTE: Casting to and from strings is not supported yet.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "shape = (3, 4)\ntest_cases = [\n    ('FLOAT', 'FLOAT16'),\n    ('FLOAT', 'DOUBLE'),\n    ('FLOAT16', 'FLOAT'),\n    ('FLOAT16', 'DOUBLE'),\n    ('DOUBLE', 'FLOAT'),\n    ('DOUBLE', 'FLOAT16'),\n]\n\nfor case in test_cases:\n    from_type = case[0]\n    to_type = case[1]\n    input = np.random.random_sample(shape).astype(\n        TENSOR_TYPE_TO_NP_TYPE[getattr(TensorProto, from_type)])\n    node = onnx.helper.make_node(\n        'Cast',\n        inputs=['input'],\n        outputs=['output'],\n        to=to_type\n    )\n    output = input.astype(TENSOR_TYPE_TO_NP_TYPE[getattr(TensorProto, to_type)])\n    expect(node, inputs=[input], outputs=[output],\n           name='test_cast_' + from_type + '_to_' + to_type)",
          "summary": "cast"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor to be cast.",
          "name": "input",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor with the same shape as input with type specified by the 'to' argument",
          "name": "output",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)",
            "tensor(int8)",
            "tensor(int16)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(uint8)",
            "tensor(uint16)",
            "tensor(uint32)",
            "tensor(uint64)",
            "tensor(bool)"
          ],
          "description": "Constrain input types. Casting from strings and complex are not supported.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)",
            "tensor(int8)",
            "tensor(int16)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(uint8)",
            "tensor(uint16)",
            "tensor(uint32)",
            "tensor(uint64)",
            "tensor(bool)"
          ],
          "description": "Constrain output types. Casting to strings and complex are not supported.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "CastMap",
    "schema": {
      "attributes": [
        {
          "description": "what to cast output to, enum 'TO_FLOAT', 'TO_STRING', 'TO_INT64', default is 'TO_FLOAT'",
          "name": "cast_to",
          "required": false,
          "type": "string"
        },
        {
          "description": "whether to only output as many values as are in the input, or position the input based on using the key of the map as the index of the output (sparse), enum 'DENSE', 'SPARSE', default is 'DENSE'",
          "name": "map_form",
          "required": false,
          "type": "string"
        },
        {
          "description": "if map_form packing is SPARSE, what is the total length of each output in N (max index value)",
          "name": "max_map",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Converts a map to a tensor.  Map key must be int64 and the values will be ordered\n    in ascending order based on this key.  Supports dense packing or sparse packing.\n    If using sparse packing, the key cannot exceed the max_map-1 value.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be encoded",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "encoded output data",
          "name": "Y",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "map(int64, string)",
            "map(int64, float)"
          ],
          "description": " allowed input types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(float)",
            "tensor(int64)"
          ],
          "description": " allowed output types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "CategoryMapper",
    "schema": {
      "attributes": [
        {
          "description": "ints part of the input map, must be same size and the strings",
          "name": "cats_int64s",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "strings part of the input map, must be same size and the ints",
          "name": "cats_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "int value to use if the string is not in the map",
          "name": "default_int64",
          "required": false,
          "type": "int"
        },
        {
          "description": "string value to use if the int is not in the map",
          "name": "default_string",
          "required": false,
          "type": "string"
        }
      ],
      "description": "Convert strings to int64s and vice versa.\n    Takes in a map to use for the conversion.\n    The index position in the strings and ints repeated inputs\n     is used to do the mapping.\n    Each instantiated operator converts either ints to strings or strings to ints.\n    This behavior is triggered based on which default value is set.\n    If the string default value is set, it will convert ints to strings.\n    If the int default value is set, it will convert strings to ints.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Input data",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data, if strings are input, then output is int64s, and vice versa.",
          "name": "Y",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "Ceil",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Ceil takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the ceil is, y = ceil(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Ceil',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1.5, 1.2]).astype(np.float32)\ny = np.ceil(x)  # expected output [-1., 2.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_ceil_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.ceil(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_ceil')",
          "summary": "ceil"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Ceil",
    "schema": {
      "description": "Ceil takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the ceil is, y = ceil(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Ceil',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1.5, 1.2]).astype(np.float32)\ny = np.ceil(x)  # expected output [-1., 2.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_ceil_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.ceil(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_ceil')",
          "summary": "ceil"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Clip",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Maximum value, above which element is replaced by max",
          "name": "max",
          "required": false,
          "type": "float"
        },
        {
          "description": "Minimum value, under which element is replaced by min",
          "name": "min",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Clip operator limits the given input within an interval. The interval is\nspecified with arguments 'min' and 'max'. They default to\nnumeric_limits::lowest() and numeric_limits::max() respectively.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    min=-1.0,\n    max=1.0\n)\n\nx = np.array([-2, 0, 2]).astype(np.float32)\ny = np.clip(x, -1, 1)  # expected output [-1., 0., 1.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, -1.0, 1.0)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip')",
          "summary": "clip"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    min=0.0\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0.0, np.inf)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_default_min')\n\nnode = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    max=0.0\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, -np.inf, 0.0)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_default_max')",
          "summary": "clip_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor whose elements to be clipped",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor with clipped input elements",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Clip",
    "schema": {
      "attributes": [
        {
          "description": "Maximum value, above which element is replaced by max",
          "name": "max",
          "required": false,
          "type": "float"
        },
        {
          "description": "Minimum value, under which element is replaced by min",
          "name": "min",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Clip operator limits the given input within an interval. The interval is\nspecified with arguments 'min' and 'max'. They default to\nnumeric_limits::lowest() and numeric_limits::max() respectively.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    min=-1.0,\n    max=1.0\n)\n\nx = np.array([-2, 0, 2]).astype(np.float32)\ny = np.clip(x, -1, 1)  # expected output [-1., 0., 1.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, -1.0, 1.0)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip')",
          "summary": "clip"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    min=0.0\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0.0, np.inf)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_default_min')\n\nnode = onnx.helper.make_node(\n    'Clip',\n    inputs=['x'],\n    outputs=['y'],\n    max=0.0\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, -np.inf, 0.0)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_clip_default_max')",
          "summary": "clip_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor whose elements to be clipped",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor with clipped input elements",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Concat",
    "schema": {
      "attributes": [
        {
          "description": "Which axis to concat on.  Default value is 1.",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Tensor",
      "description": "Concatenate a list of tensors into a single tensor",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "test_cases = {\n    '1d': ([1, 2],\n           [3, 4]),\n    '2d': ([[1, 2], [3, 4]],\n           [[5, 6], [7, 8]]),\n    '3d': ([[[1, 2], [3, 4]], [[5, 6], [7, 8]]],\n           [[[9, 10], [11, 12]], [[13, 14], [15, 16]]])\n}\n\nfor test_case, values in test_cases.items():\n    values = [np.asarray(v) for v in values]\n    for i in range(len(values[0].shape)):\n        in_args = ['value' + str(k) for k in range(len(values))]\n        node = onnx.helper.make_node(\n            'Concat',\n            inputs=[s for s in in_args],\n            outputs=['output'],\n            axis=i\n        )\n        output = np.concatenate(values, i)\n        expect(node, inputs=[v for v in values], outputs=[output],\n               name='test_concat_' + test_case + '_axis_' + str(i))",
          "summary": "concat"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for concatenation",
          "name": "inputs",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Concatenated tensor",
          "name": "concat_result",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Concat",
    "schema": {
      "attributes": [
        {
          "description": "Which axis to concat on",
          "name": "axis",
          "required": true,
          "type": "int"
        }
      ],
      "category": "Tensor",
      "description": "Concatenate a list of tensors into a single tensor",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "test_cases = {\n    '1d': ([1, 2],\n           [3, 4]),\n    '2d': ([[1, 2], [3, 4]],\n           [[5, 6], [7, 8]]),\n    '3d': ([[[1, 2], [3, 4]], [[5, 6], [7, 8]]],\n           [[[9, 10], [11, 12]], [[13, 14], [15, 16]]])\n}\n\nfor test_case, values in test_cases.items():\n    values = [np.asarray(v) for v in values]\n    for i in range(len(values[0].shape)):\n        in_args = ['value' + str(k) for k in range(len(values))]\n        node = onnx.helper.make_node(\n            'Concat',\n            inputs=[s for s in in_args],\n            outputs=['output'],\n            axis=i\n        )\n        output = np.concatenate(values, i)\n        expect(node, inputs=[v for v in values], outputs=[output],\n               name='test_concat_' + test_case + '_axis_' + str(i))",
          "summary": "concat"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for concatenation",
          "name": "inputs",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Concatenated tensor",
          "name": "concat_result",
          "type": "T"
        }
      ],
      "since_version": 4,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Constant",
    "schema": {
      "attributes": [
        {
          "description": "The value for the elements of the output tensor.",
          "name": "value",
          "required": true,
          "type": "tensor"
        }
      ],
      "category": "Constant",
      "description": "A constant tensor.",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "values = np.random.randn(5, 5).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Constant',\n    inputs=[],\n    outputs=['values'],\n    value=onnx.helper.make_tensor(\n        name='const_tensor',\n        data_type=onnx.TensorProto.FLOAT,\n        dims=values.shape,\n        vals=values.flatten().astype(float),\n    ),\n)\n\nexpect(node, inputs=[], outputs=[values],\n       name='test_constant')",
          "summary": "constant"
        }
      ],
      "max_input": 0,
      "max_output": 1,
      "min_input": 0,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor containing the same value of the provided tensor.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ConstantFill",
    "schema": {
      "attributes": [
        {
          "description": "The data type for the elements of the output tensor.Strictly must be one of the types from DataType enum in TensorProto.",
          "name": "dtype",
          "required": false,
          "type": "int"
        },
        {
          "description": "The additional dimensions appended at the end of the shape indicatedby the input blob.Cannot set the extra_shape argument when there is no input blob.",
          "name": "extra_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "1D tensor containing the desired output shape.  First input must be in CPU context.",
          "name": "input_as_shape",
          "required": false,
          "type": "int"
        },
        {
          "description": "The shape of the output tensor.Cannot set the shape argument and pass in an input at the same time.",
          "name": "shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "The value for the elements of the output tensor.",
          "name": "value",
          "required": false,
          "type": "float"
        }
      ],
      "description": "The operator fills the elements of the output tensor with a constant value\nspecified by the 'value' attribute.\n\nThe data type is specified by the 'dtype' attribute. The 'dtype' attribute must\nbe one of the data types specified in the 'DataType' enum field in the\nTensorProto message. If the 'dtype' attribute is not provided, the data type of\n'value' is used.\n\nThe output tensor shape is specified by the 'shape' attribute. If the number of\ninput is 1, the shape will be identical to that of the input at run time with\noptional additional dimensions appended at the end as specified by 'extra_shape'\nattribute. In that case the 'shape' attribute should not be set.\n\nIf input_as_shape is set to true, then the input should be a 1D tensor\ncontaining the desired output shape (the dimensions specified in extra_shape\nwill also be appended)\n\nNOTE: Currently, it supports data type of float, int32, int64, and bool.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor (optional) to provide shape information.",
          "name": "input",
          "option": "optional",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 0,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of constant values specified by 'value'argument and its type is specified by the 'dtype' argument",
          "name": "output",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(bool)"
          ],
          "description": "Constrain input types to float, int32, int64, bool tensors.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(bool)"
          ],
          "description": "Constrain output types to float, int32, int64, bool tensors.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "Conv",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "dilation value along each axis of the filter. If not present, the dilation defaults to 1 along each axis.",
          "name": "dilations",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "number of groups input channels and output channels are divided into, default is 1.",
          "name": "group",
          "required": false,
          "type": "int"
        },
        {
          "description": "The shape of the convolution kernel. If not present, should be inferred from input W.",
          "name": "kernel_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Padding for the beginning and ending along each 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 axis.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis. If not present, the stride defaults to 1 along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Layer",
      "description": "The convolution operator consumes an input tensor and a filter, and\ncomputes the output.",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "\nx = np.array([[[[0., 1., 2., 3., 4.],  # (1, 1, 5, 5) input tensor\n                [5., 6., 7., 8., 9.],\n                [10., 11., 12., 13., 14.],\n                [15., 16., 17., 18., 19.],\n                [20., 21., 22., 23., 24.]]]]).astype(np.float32)\nW = np.array([[[[1., 1., 1.],  # (1, 1, 3, 3) tensor for convolution weights\n                [1., 1., 1.],\n                [1., 1., 1.]]]]).astype(np.float32)\n\n# Convolution with padding\nnode_with_padding = onnx.helper.make_node(\n    'Conv',\n    inputs=['x', 'W'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    # Default values for other attributes: strides=[1, 1], dilations=[1, 1], groups=1\n    pads=[1, 1, 1, 1],\n)\ny_with_padding = np.array([[[[12., 21., 27., 33., 24.],  # (1, 1, 5, 5) output tensor\n                             [33., 54., 63., 72., 51.],\n                             [63., 99., 108., 117., 81.],\n                             [93., 144., 153., 162., 111.],\n                             [72., 111., 117., 123., 84.]]]]).astype(np.float32)\nexpect(node_with_padding, inputs=[x, W], outputs=[y_with_padding],\n       name='test_basic_conv_with_padding')\n\n# Convolution without padding\nnode_without_padding = onnx.helper.make_node(\n    'Conv',\n    inputs=['x', 'W'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    # Default values for other attributes: strides=[1, 1], dilations=[1, 1], groups=1\n    pads=[0, 0, 0, 0],\n)\ny_without_padding = np.array([[[[54., 63., 72.],  # (1, 1, 3, 3) output tensor\n                                [99., 108., 117.],\n                                [144., 153., 162.]]]]).astype(np.float32)\nexpect(node_without_padding, inputs=[x, W], outputs=[y_without_padding],\n       name='test_basic_conv_without_padding')",
          "summary": "conv"
        },
        {
          "code": "\nx = np.array([[[[0., 1., 2., 3., 4.],  # (1, 1, 7, 5) input tensor\n                [5., 6., 7., 8., 9.],\n                [10., 11., 12., 13., 14.],\n                [15., 16., 17., 18., 19.],\n                [20., 21., 22., 23., 24.],\n                [25., 26., 27., 28., 29.],\n                [30., 31., 32., 33., 34.]]]]).astype(np.float32)\nW = np.array([[[[1., 1., 1.],  # (1, 1, 3, 3) tensor for convolution weights\n                [1., 1., 1.],\n                [1., 1., 1.]]]]).astype(np.float32)\n\n# Convolution with strides=2 and padding\nnode_with_padding = onnx.helper.make_node(\n    'Conv',\n    inputs=['x', 'W'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    pads=[1, 1, 1, 1],\n    strides=[2, 2],  # Default values for other attributes: dilations=[1, 1], groups=1\n)\ny_with_padding = np.array([[[[12., 27., 24.],  # (1, 1, 4, 3) output tensor\n                             [63., 108., 81.],\n                             [123., 198., 141.],\n                             [112., 177., 124.]]]]).astype(np.float32)\nexpect(node_with_padding, inputs=[x, W], outputs=[y_with_padding],\n       name='test_conv_with_strides_padding')\n\n# Convolution with strides=2 and no padding\nnode_without_padding = onnx.helper.make_node(\n    'Conv',\n    inputs=['x', 'W'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    pads=[0, 0, 0, 0],\n    strides=[2, 2],  # Default values for other attributes: dilations=[1, 1], groups=1\n)\ny_without_padding = np.array([[[[54., 72.],  # (1, 1, 3, 2) output tensor\n                                [144., 162.],\n                                [234., 252.]]]]).astype(np.float32)\nexpect(node_without_padding, inputs=[x, W], outputs=[y_without_padding],\n       name='test_conv_with_strides_no_padding')\n\n# Convolution with strides=2 and padding only along one dimension (the H dimension in NxCxHxW tensor)\nnode_with_asymmetric_padding = onnx.helper.make_node(\n    'Conv',\n    inputs=['x', 'W'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    pads=[1, 0, 1, 0],\n    strides=[2, 2],  # Default values for other attributes: dilations=[1, 1], groups=1\n)\ny_with_asymmetric_padding = np.array([[[[21., 33.],  # (1, 1, 4, 2) output tensor\n                                        [99., 117.],\n                                        [189., 207.],\n                                        [171., 183.]]]]).astype(np.float32)\nexpect(node_with_asymmetric_padding, inputs=[x, W], outputs=[y_with_asymmetric_padding],\n       name='test_conv_with_strides_and_asymmetric_padding')",
          "summary": "conv_with_strides"
        }
      ],
      "inputs": [
        {
          "description": "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 D1 x D2 ... x Dn)",
          "name": "X",
          "type": "T"
        },
        {
          "description": "The weight tensor that will be used in the convolutions; has size (M x C 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 x k1 x k2 x ... x kn), where is the dimension of the kernel",
          "name": "W",
          "type": "T"
        },
        {
          "description": "Optional 1D bias to be added to the convolution, has size of M.",
          "name": "B",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor that contains the result of the convolution. The output dimensions are functions of the kernel size, stride size, and pad lengths.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ConvTranspose",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "dilation value along each axis of the filter. If not present, the dilation defaults to 1 along each axis.",
          "name": "dilations",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "number of groups input channels and output channels are divided into, default is 1.",
          "name": "group",
          "required": false,
          "type": "int"
        },
        {
          "description": "The shape of the convolution kernel. If not present, should be inferred from input W.",
          "name": "kernel_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "The zero-padding added to one side of the output. This is also called adjs/adjustment in some frameworks. If output_shape is set, this attribute will be ignored.",
          "name": "output_padding",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "The shape of the output. output_shape[i] = stride[i] * (input_size[i] - 1) + output_padding[i] + kernel_shape[i] - pads[start_i] - pads[end_i]",
          "name": "output_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Padding for the beginning and ending along each 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 axis.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis. If not present, the stride defaults to 1 along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Layer",
      "description": "The convolution transpose operator consumes an input tensor and a filter,\nand computes the output.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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 D1 x D2 ... x Dn)",
          "name": "X",
          "type": "T"
        },
        {
          "description": "The weight tensor that will be used in the convolutions; has size (C x M 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 (C x M x k1 x k2 x ... x kn), where is the dimension of the kernel",
          "name": "W",
          "type": "T"
        },
        {
          "description": "Optional 1D bias to be added to the convolution, has size of C.",
          "name": "B",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor that contains the result of the convolution. The output dimensions are functions of the kernel size, stride size, and pad lengths.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Crop",
    "schema": {
      "attributes": [
        {
          "description": "A 1-D values of (leftBorder, topBorder, rightBorder, bottomBorder).",
          "name": "border",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "A 1-D values of (height, width).",
          "name": "scale",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Data",
      "description": "Crop and image to the specified spatial dimensions. If scale is given,\nthen optionally start the crop offset by the left/top border amounts.\nIf scale is not provided, crop the borders as provided.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor of shape [N,C,H,W]",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same type as input, with H and W dimensions reduced.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "DepthToSpace",
    "schema": {
      "attributes": [
        {
          "description": "Blocks of [blocksize, blocksize] are moved.",
          "name": "blocksize",
          "required": false,
          "type": "int"
        }
      ],
      "description": "DepthToSpace rearranges (permutes) data from depth into blocks of spatial data.\nThis is the reverse transformation of SpaceToDepth. More specifically, this op outputs a copy of\nthe input tensor where values from the depth dimension are moved in spatial blocks to the height\nand width dimensions.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "b, c, h, w = shape = (2, 8, 3, 3)\nblocksize = 2\nnode = onnx.helper.make_node(\n    'DepthToSpace',\n    inputs=['x'],\n    outputs=['y'],\n    blocksize=blocksize,\n)\nx = np.random.random_sample(shape).astype(np.float32)\ntmp = np.reshape(x, [b, blocksize, blocksize, c // (blocksize**2), h, w])\ntmp = np.transpose(tmp, [0, 3, 4, 1, 5, 2])\ny = np.reshape(tmp, [b, c // (blocksize**2), h * blocksize, w * blocksize])\nexpect(node, inputs=[x], outputs=[y],\n       name='test_depthtospace')",
          "summary": "depthtospace"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'DepthToSpace',\n    inputs=['x'],\n    outputs=['y'],\n    blocksize=2,\n)\n\n# (1, 4, 2, 3) input tensor\nx = np.array([[[[0, 1, 2],\n                [3, 4, 5]],\n               [[6, 7, 8],\n                [9, 10, 11]],\n               [[12, 13, 14],\n                [15, 16, 17]],\n               [[18, 19, 20],\n                [21, 22, 23]]]]).astype(np.float32)\n\n# (1, 1, 4, 6) output tensor\ny = np.array([[[[0, 6, 1, 7, 2, 8],\n                [12, 18, 13, 19, 14, 20],\n                [3, 9, 4, 10, 5, 11],\n                [15, 21, 16, 22, 17, 23]]]]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_depthtospace_example')",
          "summary": "example"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor of [N,C,H,W], where N is the batch axis, C is the channel or depth, H is the height and W is the width.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of [N, C/(blocksize * blocksize), H * blocksize, W * blocksize].",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "DictVectorizer",
    "schema": {
      "attributes": [
        {
          "description": "The vocabulary vector",
          "name": "int64_vocabulary",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "The vocabulary vector",
          "name": "string_vocabulary",
          "required": false,
          "type": "string[]"
        }
      ],
      "description": "Uses an index mapping to convert a dictionary to an array.\n    The output array will be equal in length to the index mapping vector parameter.\n    All keys in the input dictionary must be present in the index mapping vector.\n    For each item in the input dictionary, insert its value in the output array.\n    The position of the insertion is determined by the position of the item's key\n    in the index mapping. Any keys not present in the input dictionary, will be\n    zero in the output array.  Use either string_vocabulary or int64_vocabulary, not both.\n    For example: if the ``string_vocabulary`` parameter is set to ``[\"a\", \"c\", \"b\", \"z\"]``,\n    then an input of ``{\"a\": 4, \"c\": 8}`` will produce an output of ``[4, 8, 0, 0]``.\n    ",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "The input dictionary",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The tensor",
          "name": "Y",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "map(string, int64)",
            "map(int64, string)",
            "map(int64, float)",
            "map(int64, double)",
            "map(string, float)",
            "map(string, double)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(int64)",
            "tensor(float)",
            "tensor(double)",
            "tensor(string)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "Div",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Performs element-wise binary division (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Div',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([3, 4]).astype(np.float32)\ny = np.array([1, 2]).astype(np.float32)\nz = x / y  # expected output [3., 2.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.rand(3, 4, 5).astype(np.float32) + 1.0\nz = x / y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div')",
          "summary": "div"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Div',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.rand(5).astype(np.float32) + 1.0\nz = x / y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div_bcast')",
          "summary": "div_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Div",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Performs element-wise binary division (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Div',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([3, 4]).astype(np.float32)\ny = np.array([1, 2]).astype(np.float32)\nz = x / y  # expected output [3., 2.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.rand(3, 4, 5).astype(np.float32) + 1.0\nz = x / y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div')",
          "summary": "div"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Div',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.rand(5).astype(np.float32) + 1.0\nz = x / y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_div_bcast')",
          "summary": "div_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Dropout",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "(int, default 0) if nonzero, run dropout in test mode where the output is simply Y = X.",
          "name": "is_test",
          "required": false,
          "type": "int"
        },
        {
          "description": "(float, default 0.5) the ratio of random dropout",
          "name": "ratio",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Dropout",
      "description": "Dropout takes one input data (Tensor<float>) and produces two Tensor outputs,\noutput (Tensor<float>) and mask (Tensor<bool>). Depending on whether it is in\ntest mode or not, the output Y will either be a random dropout, or a simple\ncopy of the input. Note that our implementation of Dropout does scaling in\nthe training phase, so during testing nothing needs to be done.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input data as Tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output.",
          "name": "output",
          "type": "T"
        },
        {
          "description": "The output mask. If is_test is nonzero, this output is not filled.",
          "name": "mask",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Dropout",
    "schema": {
      "attributes": [
        {
          "description": "(int, default 0) if nonzero, run dropout in test mode where the output is simply Y = X.",
          "name": "is_test",
          "required": false,
          "type": "int"
        },
        {
          "description": "(float, default 0.5) the ratio of random dropout",
          "name": "ratio",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Dropout",
      "description": "Dropout takes one input data (Tensor<float>) and produces two Tensor outputs,\noutput (Tensor<float>) and mask (Tensor<bool>). Depending on whether it is in\ntest mode or not, the output Y will either be a random dropout, or a simple\ncopy of the input. Note that our implementation of Dropout does scaling in\nthe training phase, so during testing nothing needs to be done.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input data as Tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output.",
          "name": "output",
          "type": "T"
        },
        {
          "description": "The output mask. If is_test is nonzero, this output is not filled.",
          "name": "mask",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Elu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of ELU default to 1.0.",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "Elu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the function `f(x) = alpha * (exp(x) - 1.) for x <\n0`, `f(x) = x for x >= 0`., is applied to the tensor elementwise.\n\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Elu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=2.0\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-1.2642411, 0., 1.]\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu')",
          "summary": "elu"
        },
        {
          "code": "default_alpha = 1.0\nnode = onnx.helper.make_node(\n    'Elu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * default_alpha\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu_default')",
          "summary": "elu_default"
        }
      ],
      "inputs": [
        {
          "description": "1D input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "1D input tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Elu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of ELU default to 1.0.",
          "name": "alpha",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "Elu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the function `f(x) = alpha * (exp(x) - 1.) for x <\n0`, `f(x) = x for x >= 0`., is applied to the tensor elementwise.\n\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Elu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=2.0\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-1.2642411, 0., 1.]\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu')",
          "summary": "elu"
        },
        {
          "code": "default_alpha = 1.0\nnode = onnx.helper.make_node(\n    'Elu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + (np.exp(np.clip(x, -np.inf, 0)) - 1) * default_alpha\nexpect(node, inputs=[x], outputs=[y],\n       name='test_elu_default')",
          "summary": "elu_default"
        }
      ],
      "inputs": [
        {
          "description": "1D input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "1D input tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Equal",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `equal` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Equal',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = (np.random.randn(3, 4, 5) * 10).astype(np.int32)\ny = (np.random.randn(3, 4, 5) * 10).astype(np.int32)\nz = np.equal(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_equal')",
          "summary": "equal"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Equal',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = (np.random.randn(3, 4, 5) * 10).astype(np.int32)\ny = (np.random.randn(5) * 10).astype(np.int32)\nz = np.equal(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_equal_bcast')",
          "summary": "equal_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)",
            "tensor(int32)",
            "tensor(int64)"
          ],
          "description": "Constrains input to integral tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "Exp",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Calculates the exponential of the given input tensor, element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Exp',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.exp(x)  # expected output [0.36787945, 1., 2.71828175]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_exp_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.exp(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_exp')",
          "summary": "exp"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The exponential of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Exp",
    "schema": {
      "description": "Calculates the exponential of the given input tensor, element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Exp',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.exp(x)  # expected output [0.36787945, 1., 2.71828175]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_exp_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.exp(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_exp')",
          "summary": "exp"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The exponential of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "FC",
    "schema": {
      "attributes": [
        {
          "description": "(int32_t) default to 1; describes the axis of the inputs; defaults to one because the 0th axis most likely describes the batch_size",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "(int32_t) default to 1; describes the axis of the weights; defaults to one because the 0th axis most likely describes the batch_size",
          "name": "axis_w",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Layer",
      "description": "Computes the result of passing an input vector X into a fully\nconnected layer with 2D weight matrix W and 1D bias vector b. That is,\nthe layer computes Y = X * W^T + b, where X has size (M x K),\nW has size (N x K), b has size (N), and Y has size (M x N),\nwhere M is often the batch size.\nNOTE: X does not need to explicitly be a 2D vector; rather, it will be\ncoerced into one. For an arbitrary n-dimensional tensor\nX \\in [a_0, a_1, ...,a_{k-1}, a_k, ..., a_{n-1}] where a_i \\in N+ and k is\nthe axis provided, then X will be coerced into a 2-dimensional tensor with\ndimensions [a_0 * ... * a_{k-1}, a_k * ... * a_{n-1}]. For the default\ncase where axis=1, this means the X tensor will be coerced into a 2D tensor\nof dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.\nIn this situation, we must have a_0 = M and a_1 * ... * a_{n-1} = K.\nLastly, even though b is a 1D vector of size N, it is copied/resized to\nbe size (M x N) implicitly and added to each vector in the batch.\nEach of these dimensions must be matched correctly, or else the operator\nwill throw errors.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "input tensor that's coerced into a 2D matrix of size (MxK) as described above",
          "name": "X",
          "type": "T"
        },
        {
          "description": "2D blob of size (KxN) containing fully connected weight matrix",
          "name": "W",
          "type": "T"
        },
        {
          "description": "1D blob containing bias vector",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "2D output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "FeatureVectorizer",
    "schema": {
      "attributes": [
        {
          "description": "the size of each input in the input list",
          "name": "inputdimensions",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Concatenates input features into one continuous output.\n    Inputlist is a list of input feature names, inputdimensions is the size of each input feature.\n    Inputs will be written to the output in the order of the input arguments.\n    All inputs are tensors of float.  Any feature that is not a tensor of float should\n    be converted using either Cast or CastMap.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "ordered input tensors",
          "name": "X",
          "option": "variadic",
          "type": "T1"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Full output array, in order assigned in the inputlist, as floats",
          "name": "Y",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(int32)",
            "tensor(int64)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": " Allowed input types",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(float)"
          ],
          "description": " Output data type",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "Flatten",
    "schema": {
      "attributes": [
        {
          "description": "(Default to 1) Indicate up to which input dimensions (exclusive) should be flattened to the outer dimension of the output. The value for axis must be in the range [0, R], where R is the rank of the input tensor. When axis = 0, the shape of the output tensor is (1, (d_0 X d_1 ... d_n), where the shape of the input tensor is (d_0, d_1, ... d_n). ",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Shape",
      "description": "Flattens the input tensor into a 2D matrix. If input tensor has shape\n(d_0, d_1, ... d_n) then the output will have shape\n(d_0 X d_1 ... d_(axis-1), d_axis X d_(axis+1) ... X dn).\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "shape = (2, 3, 4, 5)\na = np.random.random_sample(shape).astype(np.float32)\n\nfor i in range(len(shape)):\n    node = onnx.helper.make_node(\n        'Flatten',\n        inputs=['a'],\n        outputs=['b'],\n        axis=i,\n    )\n\n    new_shape = (1, -1) if i == 0 else (np.prod(shape[0:i]).astype(int), -1)\n    b = np.reshape(a, new_shape)\n    expect(node, inputs=[a], outputs=[b],\n           name='test_flatten_axis' + str(i))",
          "summary": "flatten"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Flatten',\n    inputs=['a'],\n    outputs=['b'],  # Default value for axis: axis=1\n)\n\nshape = (5, 4, 3, 2)\na = np.random.random_sample(shape).astype(np.float32)\nnew_shape = (5, 24)\nb = np.reshape(a, new_shape)\nexpect(node, inputs=[a], outputs=[b],\n       name='test_flatten_default_axis')",
          "summary": "flatten_with_default_axis"
        }
      ],
      "inputs": [
        {
          "description": "A tensor of rank >= axis.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "A 2D tensor with the contents of the input tensor, with input dimensions up to axis flattened to the outer dimension of the output and remaining input dimensions flattened into the inner dimension of the output.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Floor",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Floor takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the floor is, y = floor(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Floor',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1.5, 1.2, 2]).astype(np.float32)\ny = np.floor(x)  # expected output [-2., 1., 2.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_floor_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.floor(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_floor')",
          "summary": "floor"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Floor",
    "schema": {
      "description": "Floor takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the floor is, y = floor(x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Floor',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1.5, 1.2, 2]).astype(np.float32)\ny = np.floor(x)  # expected output [-2., 1., 2.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_floor_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.floor(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_floor')",
          "summary": "floor"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GRU",
    "schema": {
      "attributes": [
        {
          "description": "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.",
          "name": "activation_alpha",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activation_beta",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activations",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "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.",
          "name": "clip",
          "required": false,
          "type": "float"
        },
        {
          "description": "Specify if the RNN is forward, reverse, or bidirectional. Must be one of forward (default), reverse, or bidirectional.",
          "name": "direction",
          "required": false,
          "type": "string"
        },
        {
          "description": "Number of neurons in the hidden layer",
          "name": "hidden_size",
          "required": false,
          "type": "int"
        },
        {
          "description": "When computing the output of the hidden gate, apply the linear transformation before multiplying by the output of the reset gate.",
          "name": "linear_before_reset",
          "required": false,
          "type": "int"
        },
        {
          "description": "The sequence output for the hidden is optional if 0. Default 0.",
          "name": "output_sequence",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Layer",
      "description": "Computes an one-layer GRU. This operator is usually supported via some custom\nimplementation such as CuDNN.\n\nNotations:\n\n`X` - input tensor\n\n`z` - update gate\n\n`r` - reset gate\n\n`h` - hidden gate\n\n`t` - time step (t-1 means previous time step)\n\n`W[zrh]` - W parameter weight matrix for update, reset, and hidden gates\n\n`R[zrh]` - R recurrence weight matrix for update, reset, and hidden gates\n\n`Wb[zrh]` - W bias vectors for update, reset, and hidden gates\n\n`Rb[zrh]` - R bias vectors for update, reset, and hidden gates\n\n`WB[zrh]` - W parameter weight matrix for backward update, reset, and hidden gates\n\n`RB[zrh]` - R recurrence weight matrix for backward update, reset, and hidden gates\n\n`WBb[zrh]` - W bias vectors for backward update, reset, and hidden gates\n\n`RBb[zrh]` - R bias vectors for backward update, reset, and hidden gates\n\n`H` - Hidden state\n\n`num_directions` - 2 if direction == bidirectional else 1\n\nActivation functions:\n\n  Relu(x)                - max(0, x)\n\n  Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})\n\n  Sigmoid(x)             - 1/(1 + e^{-x})\n\n  (NOTE: Below are optional)\n\n  Affine(x)              - alpha*x + beta\n\n  LeakyRelu(x)           - x if x >= 0 else alpha * x\n\n  ThresholdedRelu(x)     - x if x >= alpha else 0\n\n  ScaledTanh(x)          - alpha*Tanh(beta*x)\n\n  HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)\n\n  Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)\n\n  Softsign(x)            - x/(1 + |x|)\n\n  Softplus(x)            - log(1 + e^x)\n\nEquations (Default: f=Sigmoid, g=Tanh):\n\n  - zt = f(Xt*(Wz^T) + Ht-1*Rz + Wbz + Rbz)\n\n  - rt = f(Xt*(Wr^T) + Ht-1*Rr + Wbr + Rbr)\n\n  - ht = g(Xt*(Wh^T) + (rt (.) Ht-1)*Rh + Rbh + Wbh) # default, when linear_before_reset = 0\n\n  - ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*Rh + Rbh) + Wbh) # when linear_before_reset != 0\n\n  - Ht = (1 - zt) (.) ht + zt (.) Ht-1\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input sequences packed (and potentially padded) into one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "W",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "R",
          "type": "T"
        },
        {
          "description": "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",
          "name": "B",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "sequence_lens",
          "option": "optional",
          "type": "T1"
        },
        {
          "description": "Optional initial value of the hidden. If not specified - assumed to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "initial_h",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 6,
      "max_output": 2,
      "min_input": 3,
      "min_output": 2,
      "outputs": [
        {
          "description": "A tensor that concats all the intermediate output values of the hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`. It is optional if `output_sequence` is 0.",
          "name": "Y",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The last output value of the hidden. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "Y_h",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int32)"
          ],
          "description": "Constrain seq_lens to integer tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "GRU",
    "schema": {
      "attributes": [
        {
          "description": "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.",
          "name": "activation_alpha",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activation_beta",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activations",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "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.",
          "name": "clip",
          "required": false,
          "type": "float"
        },
        {
          "description": "Specify if the RNN is forward, reverse, or bidirectional. Must be one of forward (default), reverse, or bidirectional.",
          "name": "direction",
          "required": false,
          "type": "string"
        },
        {
          "description": "Number of neurons in the hidden layer",
          "name": "hidden_size",
          "required": false,
          "type": "int"
        },
        {
          "description": "When computing the output of the hidden gate, apply the linear transformation before multiplying by the output of the reset gate.",
          "name": "linear_before_reset",
          "required": false,
          "type": "int"
        },
        {
          "description": "The sequence output for the hidden is optional if 0. Default 0.",
          "name": "output_sequence",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Layer",
      "description": "Computes an one-layer GRU. This operator is usually supported via some custom\nimplementation such as CuDNN.\n\nNotations:\n\n`X` - input tensor\n\n`z` - update gate\n\n`r` - reset gate\n\n`h` - hidden gate\n\n`t` - time step (t-1 means previous time step)\n\n`W[zrh]` - W parameter weight matrix for update, reset, and hidden gates\n\n`R[zrh]` - R recurrence weight matrix for update, reset, and hidden gates\n\n`Wb[zrh]` - W bias vectors for update, reset, and hidden gates\n\n`Rb[zrh]` - R bias vectors for update, reset, and hidden gates\n\n`WB[zrh]` - W parameter weight matrix for backward update, reset, and hidden gates\n\n`RB[zrh]` - R recurrence weight matrix for backward update, reset, and hidden gates\n\n`WBb[zrh]` - W bias vectors for backward update, reset, and hidden gates\n\n`RBb[zrh]` - R bias vectors for backward update, reset, and hidden gates\n\n`H` - Hidden state\n\n`num_directions` - 2 if direction == bidirectional else 1\n\nActivation functions:\n\n  Relu(x)                - max(0, x)\n\n  Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})\n\n  Sigmoid(x)             - 1/(1 + e^{-x})\n\n  (NOTE: Below are optional)\n\n  Affine(x)              - alpha*x + beta\n\n  LeakyRelu(x)           - x if x >= 0 else alpha * x\n\n  ThresholdedRelu(x)     - x if x >= alpha else 0\n\n  ScaledTanh(x)          - alpha*Tanh(beta*x)\n\n  HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)\n\n  Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)\n\n  Softsign(x)            - x/(1 + |x|)\n\n  Softplus(x)            - log(1 + e^x)\n\nEquations (Default: f=Sigmoid, g=Tanh):\n\n  - zt = f(Xt*(Wz^T) + Ht-1*Rz + Wbz + Rbz)\n\n  - rt = f(Xt*(Wr^T) + Ht-1*Rr + Wbr + Rbr)\n\n  - ht = g(Xt*(Wh^T) + (rt (.) Ht-1)*Rh + Rbh + Wbh) # default, when linear_before_reset = 0\n\n  - ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*Rh + Rbh) + Wbh) # when linear_before_reset != 0\n\n  - Ht = (1 - zt) (.) ht + zt (.) Ht-1\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input sequences packed (and potentially padded) into one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "W",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "R",
          "type": "T"
        },
        {
          "description": "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",
          "name": "B",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "sequence_lens",
          "option": "optional",
          "type": "T1"
        },
        {
          "description": "Optional initial value of the hidden. If not specified - assumed to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "initial_h",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 6,
      "max_output": 2,
      "min_input": 3,
      "min_output": 0,
      "outputs": [
        {
          "description": "A tensor that concats all the intermediate output values of the hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`. It is optional if `output_sequence` is 0.",
          "name": "Y",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The last output value of the hidden. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "Y_h",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 3,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int32)"
          ],
          "description": "Constrain seq_lens to integer tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "GRUUnit",
    "schema": {
      "attributes": [
        {
          "description": "Bool to determine if hidden state is zeroes or passed along for timesteps past the given sequence_length.",
          "name": "drop_states",
          "required": false,
          "type": "int"
        }
      ],
      "description": "GRUUnit computes the activations of a standard GRU,\nin a sequence-length aware fashion.\nConcretely, given the (fused) inputs X (TxNxD), the previous hidden\nstate (NxD), and the sequence lengths (N), computes the GRU\nactivations, avoiding computation if the input is invalid (as in, the\nvalue at X[t][n] >= seqLengths[n].\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The previous GRU hidden state.",
          "name": "hidden_prev",
          "type": "T"
        },
        {
          "description": "Unactivated gate outputs from forget, update, and output gates, pre-activation.",
          "name": "gates",
          "type": "T"
        },
        {
          "description": "Array of sequence lengths.  len(seq_lengths) should equal batch size N.",
          "name": "seq_lengths",
          "type": "T"
        },
        {
          "description": "The timestep for this operation.",
          "name": "t",
          "type": "T"
        }
      ],
      "max_input": 4,
      "max_output": 1,
      "min_input": 4,
      "min_output": 1,
      "outputs": [
        {
          "description": "The new GRU hidden state calculated by this op.",
          "name": "hidden",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Gather",
    "schema": {
      "attributes": [
        {
          "description": "Which axis to gather on, defaults to 0. Negative value means counting dimensions from the back. Accepted range in [-r, r-1]",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Given `data` tensor of rank r >= 1, and `indices` tensor of rank q, gather\nentries of the axis dimension of `data` (by default outer-most one as axis=0) indexed by `indices`, and concatenates\nthem in an output tensor of rank q + (r - 1).\n\nExample 1:\n  data = [\n      [1.0, 1.2],\n      [2.3, 3.4],\n      [4.5, 5.7],\n  ]\n  indices = [\n      [0, 1],\n      [1, 2],\n  ]\n  output = [\n      [\n          [1.0, 1.2],\n          [2.3, 3.4],\n      ],\n      [\n          [2.3, 3.4],\n          [4.5, 5.7],\n      ],\n  ]\n\nExample 2:\n  data = [\n      [1.0, 1.2, 1.9],\n      [2.3, 3.4, 3.9],\n      [4.5, 5.7, 5.9],\n  ]\n  indices = [\n      [0, 2],\n  ]\n  axis = 1,\n  output = [\n      [\n          [1.0, 1.9],\n          [2.3, 3.9],\n          [4.5, 5.9],\n      ],\n  ]\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Gather',\n    inputs=['data', 'indices'],\n    outputs=['y'],\n    axis=0,\n)\ndata = np.random.randn(5, 4, 3, 2).astype(np.float32)\nindices = np.array([0, 1, 3])\ny = np.take(data, indices, axis=0)\n\nexpect(node, inputs=[data, indices], outputs=[y],\n       name='test_gather_0')",
          "summary": "gather_0"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Gather',\n    inputs=['data', 'indices'],\n    outputs=['y'],\n    axis=1,\n)\ndata = np.random.randn(5, 4, 3, 2).astype(np.float32)\nindices = np.array([0, 1, 3])\ny = np.take(data, indices, axis=1)\n\nexpect(node, inputs=[data, indices], outputs=[y],\n       name='test_gather_1')",
          "summary": "gather_1"
        }
      ],
      "inputs": [
        {
          "description": "Tensor of rank r >= 1.",
          "name": "data",
          "type": "T"
        },
        {
          "description": "Tensor of int32/int64 indices, of any rank q.",
          "name": "indices",
          "type": "Tind"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Tensor of rank q + (r - 1).",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int32)",
            "tensor(int64)"
          ],
          "description": "Constrain indices to integer types",
          "type_param_str": "Tind"
        }
      ]
    }
  },
  {
    "name": "Gemm",
    "schema": {
      "attributes": [
        {
          "description": "Scalar multiplier for the product of input tensors A * B",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Scalar multiplier for input tensor C",
          "name": "beta",
          "required": false,
          "type": "float"
        },
        {
          "description": "Whether C should be broadcasted",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "Whether A should be transposed",
          "name": "transA",
          "required": false,
          "type": "int"
        },
        {
          "description": "Whether B should be transposed",
          "name": "transB",
          "required": false,
          "type": "int"
        }
      ],
      "description": "General Matrix multiplication:\nhttps://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3\nCompute Y = alpha * A * B + beta * C, where input tensor A has dimension (M X K)\n, input tensor B has dimension (K X N), input tensor C and output tensor Y have\ndimension (M X N).\nIf attribute broadcast is non-zero, input tensor C will be broadcasted to match\nthe dimension requirement. If A can be transposed before doing the computation\nif attribute transA is non-zero, same for B and transB.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor A",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Input tensor B",
          "name": "B",
          "type": "T"
        },
        {
          "description": "Input tensor C, can be inplace.",
          "name": "C",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Gemm",
    "schema": {
      "attributes": [
        {
          "description": "Scalar multiplier for the product of input tensors A * B",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Scalar multiplier for input tensor C",
          "name": "beta",
          "required": false,
          "type": "float"
        },
        {
          "description": "Whether C should be broadcasted",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "Whether A should be transposed",
          "name": "transA",
          "required": false,
          "type": "int"
        },
        {
          "description": "Whether B should be transposed",
          "name": "transB",
          "required": false,
          "type": "int"
        }
      ],
      "description": "General Matrix multiplication:\nhttps://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3\nCompute Y = alpha * A * B + beta * C, where input tensor A has dimension (M X K)\n, input tensor B has dimension (K X N), input tensor C and output tensor Y have\ndimension (M X N).\nIf attribute broadcast is non-zero, input tensor C will be broadcasted to match\nthe dimension requirement. If A can be transposed before doing the computation\nif attribute transA is non-zero, same for B and transB.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor A",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Input tensor B",
          "name": "B",
          "type": "T"
        },
        {
          "description": "Input tensor C, can be inplace.",
          "name": "C",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GivenTensorFill",
    "schema": {
      "attributes": [
        {
          "description": "",
          "name": "extra_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "",
          "name": "input_as_shape",
          "required": false,
          "type": "int"
        },
        {
          "description": "",
          "name": "shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "",
          "name": "values",
          "required": false,
          "type": "float[]"
        }
      ],
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The shape of filled tensor",
          "name": "shape",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 0,
      "min_output": 1,
      "outputs": [
        {
          "description": "The filled tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GlobalAveragePool",
    "schema": {
      "category": "Pool",
      "description": "GlobalAveragePool consumes an input tensor X and applies average pooling across the\n the values in the same channel. This is equivalent to AveragePool with kernel size\n equal to the spatial dimension of input tensor.",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'GlobalAveragePool',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(1, 3, 5, 5).astype(np.float32)\nspatial_shape = np.ndim(x) - 2\ny = np.average(x, axis=tuple(range(spatial_shape, spatial_shape + 2)))\nfor _ in range(spatial_shape):\n    y = np.expand_dims(y, -1)\nexpect(node, inputs=[x], outputs=[y], name='test_globalaveragepool')",
          "summary": "globalaveragepool"
        },
        {
          "code": "\nnode = onnx.helper.make_node(\n    'GlobalAveragePool',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.array([[[\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9],\n]]]).astype(np.float32)\ny = np.array([[[[5]]]]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y], name='test_globalaveragepool_precomputed')",
          "summary": "globalaveragepool_precomputed"
        }
      ],
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from pooling across the input tensor. Dimensions will be N x C x 1 x 1",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GlobalLpPool",
    "schema": {
      "attributes": [
        {
          "description": "p value of the Lp norm used to pool over the input data, default is 2.0.",
          "name": "p",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Pool",
      "description": "GlobalLpPool consumes an input tensor X and applies lp pool pooling across the\n the values in the same channel. This is equivalent to LpPool with kernel size\n equal to the spatial dimension of input tensor.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from pooling across the input tensor. Dimensions will be N x C x 1 x 1",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GlobalLpPool",
    "schema": {
      "attributes": [
        {
          "description": "p value of the Lp norm used to pool over the input data, default is 2.",
          "name": "p",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Pool",
      "description": "GlobalLpPool consumes an input tensor X and applies lp pool pooling across the\n the values in the same channel. This is equivalent to LpPool with kernel size\n equal to the spatial dimension of input tensor.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from pooling across the input tensor. Dimensions will be N x C x 1 x 1",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 2,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "GlobalMaxPool",
    "schema": {
      "category": "Pool",
      "description": "GlobalMaxPool consumes an input tensor X and applies max pooling across the\n the values in the same channel. This is equivalent to MaxPool with kernel size\n equal to the spatial dimension of input tensor.",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "\nnode = onnx.helper.make_node(\n    'GlobalMaxPool',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(1, 3, 5, 5).astype(np.float32)\nspatial_shape = np.ndim(x) - 2\ny = np.max(x, axis=tuple(range(spatial_shape, spatial_shape + 2)))\nfor _ in range(spatial_shape):\n    y = np.expand_dims(y, -1)\nexpect(node, inputs=[x], outputs=[y], name='test_globalmaxpool')",
          "summary": "globalmaxpool"
        },
        {
          "code": "\nnode = onnx.helper.make_node(\n    'GlobalMaxPool',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.array([[[\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9],\n]]]).astype(np.float32)\ny = np.array([[[[9]]]]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y], name='test_globalmaxpool_precomputed')",
          "summary": "globalmaxpool_precomputed"
        }
      ],
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from pooling across the input tensor. Dimensions will be N x C x 1 x 1",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Greater",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `greater` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Greater',\n    inputs=['x', 'y'],\n    outputs=['greater'],\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = np.greater(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_greater')",
          "summary": "greater"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Greater',\n    inputs=['x', 'y'],\n    outputs=['greater'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = np.greater(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_greater_bcast')",
          "summary": "greater_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrains input to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "HardSigmoid",
    "schema": {
      "attributes": [
        {
          "description": "Value of alpha default to 0.2",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Value of beta default to 0.5",
          "name": "beta",
          "required": false,
          "type": "float"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "HardSigmoid takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the HardSigmoid function, y = max(0, min(1, alpha * x + beta)),\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'HardSigmoid',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=0.5,\n    beta=0.6\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.clip(x * 0.5 + 0.6, 0, 1)  # expected output [0.1, 0.6, 1.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x * 0.5 + 0.6, 0, 1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid')",
          "summary": "hardsigmoid"
        },
        {
          "code": "default_alpha = 0.2\ndefault_beta = 0.5\nnode = onnx.helper.make_node(\n    'HardSigmoid',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x * default_alpha + default_beta, 0, 1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid_default')",
          "summary": "hardsigmoid_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "HardSigmoid",
    "schema": {
      "attributes": [
        {
          "description": "Value of alpha default to 0.2",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Value of beta default to 0.5",
          "name": "beta",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "HardSigmoid takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the HardSigmoid function, y = max(0, min(1, alpha * x + beta)),\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'HardSigmoid',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=0.5,\n    beta=0.6\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.clip(x * 0.5 + 0.6, 0, 1)  # expected output [0.1, 0.6, 1.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x * 0.5 + 0.6, 0, 1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid')",
          "summary": "hardsigmoid"
        },
        {
          "code": "default_alpha = 0.2\ndefault_beta = 0.5\nnode = onnx.helper.make_node(\n    'HardSigmoid',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x * default_alpha + default_beta, 0, 1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardsigmoid_default')",
          "summary": "hardsigmoid_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Hardmax",
    "schema": {
      "attributes": [
        {
          "description": "(int) default to 1; describes the axis of the inputs when coerced to 2D; defaults to one because the 0th axis most likely describes the batch_size",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "description": "The operator computes the hardmax (1 for the first maximum value, and 0 for all others) values for each layer in the batch\n of the given input. The input is a 2-D tensor (Tensor<float>) of size\n(batch_size x input_feature_dimensions). The output tensor has the same shape\nand contains the hardmax values of the corresponding input.\n\nX does not need to explicitly be a 2D vector; rather, it will be\ncoerced into one. For an arbitrary n-dimensional tensor\nX \\in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is\nthe axis provided, then X will be coerced into a 2-dimensional tensor with\ndimensions [a_0 * ... * a_{k-1}, a_k * ... * a_{n-1}]. For the default\ncase where axis=1, this means the X tensor will be coerced into a 2D tensor\nof dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.\nIn this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.\nEach of these dimensions must be matched correctly, or else the operator\nwill throw errors.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Hardmax',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([[3, 0, 1, 2], [2, 5, 1, 0], [0, 1, 3, 2], [0, 1, 2, 3]]).astype(np.float32)\ny = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_example')\n\n# For multiple occurrances of the maximal values, the first occurrence is selected for one-hot output\nx = np.array([[3, 3, 3, 1]]).astype(np.float32)\ny = np.array([[1, 0, 0, 0]]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_one_hot')",
          "summary": "hardmax"
        },
        {
          "code": "def hardmax_2d(x):\n    return np.eye(x.shape[1])[np.argmax(x, axis=1)]\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Hardmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=0,\n)\ny = hardmax_2d(x.reshape(1, 60)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_axis_0')\n\nnode = onnx.helper.make_node(\n    'Hardmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=1,\n)\ny = hardmax_2d(x.reshape(3, 20)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_axis_1')\n\n# default axis is 1\nnode = onnx.helper.make_node(\n    'Hardmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_default_axis')\n\nnode = onnx.helper.make_node(\n    'Hardmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=2,\n)\ny = hardmax_2d(x.reshape(12, 5)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_hardmax_axis_2')",
          "summary": "hardmax_axis"
        }
      ],
      "inputs": [
        {
          "description": "The input tensor that's coerced into a 2D matrix of size (NxD) as described above.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output values with the same shape as input tensor.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Identity",
    "schema": {
      "description": "Identity operator",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Tensor to copy input into.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "If",
    "schema": {
      "attributes": [
        {
          "description": "Graph to run if condition is false. Has N outputs: values you wish to be live-out to the enclosing scope. The number of outputs must match the number of outputs in the then_branch.",
          "name": "else_branch",
          "required": true,
          "type": "graph"
        },
        {
          "description": "Graph to run if condition is true. Has N outputs: values you wish to be live-out to the enclosing scope. The number of outputs must match the number of outputs in the else_branch.",
          "name": "then_branch",
          "required": true,
          "type": "graph"
        }
      ],
      "description": "If conditional",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Condition for the if",
          "name": "cond",
          "type": "B"
        }
      ],
      "max_input": 1,
      "max_output": 2147483647,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Values that are live-out to the enclosing scope.",
          "name": "outputs",
          "option": "variadic",
          "type": "V"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(int32)",
            "tensor(string)",
            "tensor(bool)",
            "tensor(uint8)",
            "tensor(int8)",
            "tensor(uint16)",
            "tensor(int16)",
            "tensor(int64)",
            "tensor(float16)",
            "tensor(double)"
          ],
          "description": "All Tensor types",
          "type_param_str": "V"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Only bool",
          "type_param_str": "B"
        }
      ]
    }
  },
  {
    "name": "ImageScaler",
    "schema": {
      "attributes": [
        {
          "description": "Bias applied to each channel, same size as C.",
          "name": "bias",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "(float, default 1.0) the scale to apply.",
          "name": "scale",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Data",
      "description": "Scale and bias the input image. Bias values are stored in\nthe same ordering as the image pixel format.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor of shape [N,C,H,W]",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same shape and type as input",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Imputer",
    "schema": {
      "attributes": [
        {
          "description": "value to change to",
          "name": "imputed_value_floats",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "value to change to",
          "name": "imputed_value_int64s",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "value that needs replacing",
          "name": "replaced_value_float",
          "required": false,
          "type": "float"
        },
        {
          "description": "value that needs replacing",
          "name": "replaced_value_int64",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Replace imputs that equal replaceValue/s  with  imputeValue/s.\n    All other inputs are copied to the output unchanged.\n    This op is used to replace missing values where we know what a missing value looks like.\n    Only one of imputed_value_floats or imputed_value_int64s should be used.\n    The size can be 1 element, which will be reused, or the size of the feature set F in input N,F\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be imputed",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Imputed output data",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "InstanceNormalization",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "The epsilon value to use to avoid division by zero, default is 1e-5f.",
          "name": "epsilon",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Normalization",
      "description": "Carries out instance normalization as described in the paper\nhttps://arxiv.org/abs/1607.08022.\n\ny = scale * (x - mean) / sqrt(variance + epsilon) + B,\nwhere mean and variance are computed per instance per channel.\n\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input 4-dimensional tensor of shape NCHW.",
          "name": "input",
          "type": "T"
        },
        {
          "description": "The input 1-dimensional scale tensor of size C.",
          "name": "scale",
          "type": "T"
        },
        {
          "description": "The input 1-dimensional bias tensor of size C.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output 4-dimensional tensor of the same shape as input.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "InstanceNormalization",
    "schema": {
      "attributes": [
        {
          "description": "The epsilon value to use to avoid division by zero, default is 1e-5f.",
          "name": "epsilon",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Normalization",
      "description": "Carries out instance normalization as described in the paper\nhttps://arxiv.org/abs/1607.08022.\n\ny = scale * (x - mean) / sqrt(variance + epsilon) + B,\nwhere mean and variance are computed per instance per channel.\n\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input 4-dimensional tensor of shape NCHW.",
          "name": "input",
          "type": "T"
        },
        {
          "description": "The input 1-dimensional scale tensor of size C.",
          "name": "scale",
          "type": "T"
        },
        {
          "description": "The input 1-dimensional bias tensor of size C.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output 4-dimensional tensor of the same shape as input.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LRN",
    "schema": {
      "attributes": [
        {
          "description": "Scaling parameter",
          "name": "alpha",
          "required": true,
          "type": "float"
        },
        {
          "description": "The exponent",
          "name": "beta",
          "required": true,
          "type": "float"
        },
        {
          "description": "Default to 1.f",
          "name": "bias",
          "required": false,
          "type": "float"
        },
        {
          "description": "The number of channels to sum over",
          "name": "size",
          "required": true,
          "type": "int"
        }
      ],
      "category": "Normalization",
      "description": "Local Response Normalization. It normalizes over local input regions.\nEach input value is divided by\n(bias+(alpha/size)*sum(xi^2 for every xi in the local region))^beta.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output  types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LSTM",
    "schema": {
      "attributes": [
        {
          "description": "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.",
          "name": "activation_alpha",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activation_beta",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activations",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "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.",
          "name": "clip",
          "required": false,
          "type": "float"
        },
        {
          "description": "Specify if the RNN is forward, reverse, or bidirectional. Must be one of forward (default), reverse, or bidirectional.",
          "name": "direction",
          "required": false,
          "type": "string"
        },
        {
          "description": "Number of neurons in the hidden layer",
          "name": "hidden_size",
          "required": false,
          "type": "int"
        },
        {
          "description": "Couple the input and forget gates if 1, default 0.",
          "name": "input_forget",
          "required": false,
          "type": "int"
        },
        {
          "description": "The sequence output for the hidden is optional if 0. Default 0.",
          "name": "output_sequence",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Layer",
      "description": "Computes an one-layer LSTM. This operator is usually supported via some\ncustom implementation such as CuDNN.\n\nNotations:\n\n`X` - input tensor\n\n`i` - input gate\n\n`o` - output gate\n\n`f` - forget gate\n\n`c` - cell gate\n\n`t` - time step (t-1 means previous time step)\n\n`W[iofc]` - W parameter weight matrix for input, output, forget, and cell gates\n\n`R[iofc]` - R recurrence weight matrix for input, output, forget, and cell gates\n\n`Wb[iofc]` - W bias vectors for input, output, forget, and cell gates\n\n`Rb[iofc]` - R bias vectors for input, output, forget, and cell gates\n\n`P[iof]`  - P peephole weight vector for input, output, and forget gates\n\n`WB[iofc]` - W parameter weight matrix for backward input, output, forget, and cell gates\n\n`RB[iofc]` - R recurrence weight matrix for backward input, output, forget, and cell gates\n\n`WBb[iofc]` - W bias vectors for backward input, output, forget, and cell gates\n\n`RBb[iofc]` - R bias vectors for backward input, output, forget, and cell gates\n\n`PB[iof]`  - P peephole weight vector for backward input, output, and forget gates\n\n`H` - Hidden state\n\n`num_directions` - 2 if direction == bidirectional else 1\n\nActivation functions:\n\n  Relu(x)                - max(0, x)\n\n  Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})\n\n  Sigmoid(x)             - 1/(1 + e^{-x})\n\n  (NOTE: Below are optional)\n\n  Affine(x)              - alpha*x + beta\n\n  LeakyRelu(x)           - x if x >= 0 else alpha * x\n\n  ThresholdedRelu(x)     - x if x >= alpha else 0\n\n  ScaledTanh(x)          - alpha*Tanh(beta*x)\n\n  HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)\n\n  Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)\n\n  Softsign(x)            - x/(1 + |x|)\n\n  Softplus(x)            - log(1 + e^x)\n\nEquations (Default: f=Sigmoid, g=Tanh, h=Tanh):\n\n  - it = f(Xt*(Wi^T) + Ht-1*Ri + Pi (.) Ct-1 + Wbi + Rbi)\n\n  - ft = f(Xt*(Wf^T) + Ht-1*Rf + Pf (.) Ct-1 + Wbf + Rbf)\n\n  - ct = g(Xt*(Wc^T) + Ht-1*Rc + Wbc + Rbc)\n\n  - Ct = ft (.) Ct-1 + it (.) ct\n\n  - ot = f(Xt*(Wo^T) + Ht-1*Ro + Po (.) Ct + Wbo + Rbo)\n\n  - Ht = ot (.) h(Ct)\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input sequences packed (and potentially padded) into one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "W",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "R",
          "type": "T"
        },
        {
          "description": "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.",
          "name": "B",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "sequence_lens",
          "option": "optional",
          "type": "T1"
        },
        {
          "description": "Optional initial value of the hidden. If not specified - assumed to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "initial_h",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "Optional initial value of the cell. If not specified - assumed to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "initial_c",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "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.",
          "name": "P",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 8,
      "max_output": 3,
      "min_input": 3,
      "min_output": 0,
      "outputs": [
        {
          "description": "A tensor that concats all the intermediate output values of the hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`. It is optional if `output_sequence` is 0.",
          "name": "Y",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The last output value of the hidden. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "Y_h",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The last output value of the cell. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "Y_c",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int32)"
          ],
          "description": "Constrain seq_lens to integer tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "LabelEncoder",
    "schema": {
      "attributes": [
        {
          "description": "List of class label strings to be encoded as int64s",
          "name": "classes_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "Default value if not in class list as int64",
          "name": "default_int64",
          "required": false,
          "type": "int"
        },
        {
          "description": "Default value if not in class list as string",
          "name": "default_string",
          "required": false,
          "type": "string"
        }
      ],
      "description": "Convert class label to their integral type and vice versa.\n    In both cases the operator is instantiated with the list of class strings.\n    The integral value of the string is the index position in the list.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be encoded",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Encoded output data",
          "name": "Y",
          "type": "T2"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "LeakyRelu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of leakage default to 0.01.",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "LeakyRelu takes input data (Tensor<T>) and an argument alpha, and produces one\noutput data (Tensor<T>) where the function `f(x) = alpha * x for x < 0`,\n`f(x) = x for x >= 0`, is applied to the data tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'LeakyRelu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=0.1\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-0.1, 0., 1.]\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * 0.1\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * 0.1\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu')",
          "summary": "leakyrelu"
        },
        {
          "code": "default_alpha = 0.01\nnode = onnx.helper.make_node(\n    'LeakyRelu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * default_alpha\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu_default')",
          "summary": "leakyrelu_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LeakyRelu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of leakage default to 0.01.",
          "name": "alpha",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "LeakyRelu takes input data (Tensor<T>) and an argument alpha, and produces one\noutput data (Tensor<T>) where the function `f(x) = alpha * x for x < 0`,\n`f(x) = x for x >= 0`, is applied to the data tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'LeakyRelu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=0.1\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-0.1, 0., 1.]\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * 0.1\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * 0.1\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu')",
          "summary": "leakyrelu"
        },
        {
          "code": "default_alpha = 0.01\nnode = onnx.helper.make_node(\n    'LeakyRelu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * default_alpha\nexpect(node, inputs=[x], outputs=[y],\n       name='test_leakyrelu_default')",
          "summary": "leakyrelu_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Less",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `less` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Less',\n    inputs=['x', 'y'],\n    outputs=['less'],\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = np.less(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_less')",
          "summary": "less"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Less',\n    inputs=['x', 'y'],\n    outputs=['less'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = np.less(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_less_bcast')",
          "summary": "less_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrains input to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "LinearClassifier",
    "schema": {
      "attributes": [
        {
          "description": "class labels if using int labels",
          "name": "classlabels_ints",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "class labels if using string labels",
          "name": "classlabels_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "weights of the model(s)",
          "name": "coefficients",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "weights of the intercepts (if used)",
          "name": "intercepts",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "whether to do OvR or multinomial (0=OvR and is default)",
          "name": "multi_class",
          "required": false,
          "type": "int"
        },
        {
          "description": "enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        }
      ],
      "description": "Linear classifier prediction (choose class)\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be classified",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 2,
      "outputs": [
        {
          "description": "Classification outputs (one class per example",
          "name": "Y",
          "type": "T2"
        },
        {
          "description": "Classification scores (N,E - one score for each class, for each example",
          "name": "Z",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "LinearRegressor",
    "schema": {
      "attributes": [
        {
          "description": "weights of the model(s)",
          "name": "coefficients",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "weights of the intercepts (if used)",
          "name": "intercepts",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        },
        {
          "description": "total number of regression targets (default is 1)",
          "name": "targets",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Generalized linear regression evaluation.\n    If targets is set to 1 (default) then univariate regression is performed.\n    If targets is set to M then M sets of coefficients must be passed in as a sequence\n    and M results will be output for each input n in N.\n    Coefficients are of the same length as an n, and coefficients for each target are contiguous.\n    Intercepts are optional but if provided must match the number of targets.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be regressed",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Regression outputs (one per target, per example",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Log",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Calculates the natural log of the given input tensor, element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Log',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([1, 10]).astype(np.float32)\ny = np.log(x)  # expected output [0., 2.30258512]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_log_example')\n\nx = np.exp(np.random.randn(3, 4, 5).astype(np.float32))\ny = np.log(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_log')",
          "summary": "log"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The natural log of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Log",
    "schema": {
      "description": "Calculates the natural log of the given input tensor, element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Log',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([1, 10]).astype(np.float32)\ny = np.log(x)  # expected output [0., 2.30258512]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_log_example')\n\nx = np.exp(np.random.randn(3, 4, 5).astype(np.float32))\ny = np.log(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_log')",
          "summary": "log"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The natural log of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LogSoftmax",
    "schema": {
      "attributes": [
        {
          "description": "(int) default to 1; describes the axis of the inputs when coerced to 2D; defaults to one because the 0th axis most likely describes the batch_size",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Activation",
      "description": "The operator computes the logsoftmax (log of softmax) values for each layer in the batch\n of the given input. The input is a 2-D tensor (Tensor<float>) of size\n(batch_size x input_feature_dimensions). The output tensor has the same shape\nand contains the logsoftmax values of the corresponding input.\n\nX does not need to explicitly be a 2D vector; rather, it will be\ncoerced into one. For an arbitrary n-dimensional tensor\nX \\in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is\nthe axis provided, then X will be coerced into a 2-dimensional tensor with\ndimensions [a_0 * ... * a_{k-1}, a_k * ... * a_{n-1}]. For the default\ncase where axis=1, this means the X tensor will be coerced into a 2D tensor\nof dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.\nIn this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.\nEach of these dimensions must be matched correctly, or else the operator\nwill throw errors.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.array([[-1, 0, 1]]).astype(np.float32)\n# expected output [[-2.40760589, -1.40760589, -0.40760589]]\ny = x - np.log(np.sum(np.exp(x), axis=1))\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_example_1')",
          "summary": "logsoftmax"
        },
        {
          "code": "def logsoftmax_2d(x):\n    max_x = np.max(x, axis=1).reshape((-1, 1))\n    exp_x = np.exp(x - max_x)\n    return x - max_x - np.log(np.sum(exp_x, axis=1).reshape((-1, 1)))\n\nx = np.array([[0, 1, 2, 3], [10000, 10001, 10002, 10003]]).astype(np.float32)\n# expected output [[-3.4401896, -2.4401896, -1.44018972, -0.44018969],\n#                 [-3.4401896, -2.4401896, -1.44018972, -0.44018969]]\ny = logsoftmax_2d(x)\n\nnode = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_large_number')\n\nx = np.abs(np.random.randn(3, 4, 5).astype(np.float32))\nnode = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=0,\n)\ny = logsoftmax_2d(x.reshape(1, 60)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_axis_0')\n\nnode = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=1,\n)\ny = logsoftmax_2d(x.reshape(3, 20)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_axis_1')\n\n# default axis is 1\nnode = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_default_axis')\n\nnode = onnx.helper.make_node(\n    'LogSoftmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=2,\n)\ny = logsoftmax_2d(x.reshape(12, 5)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_logsoftmax_axis_2')",
          "summary": "logsoftmax_axis"
        }
      ],
      "inputs": [
        {
          "description": "The input tensor that's coerced into a 2D matrix of size (NxD) as described above.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output values with the same shape as input tensor.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Loop",
    "schema": {
      "attributes": [
        {
          "description": "The graph run each iteration. It has 2+N inputs: (iteration_num, condition, loop carried dependencies...). It has 1+N+K outputs: (condition, loop carried dependencies..., scan_outputs...). Each scan_output is created by concatenating the value of the specified output value at the end of each iteration of the loop. It is an error if the dimensions of these values change across loop iterations.",
          "name": "body",
          "required": true,
          "type": "graph"
        }
      ],
      "description": "Generic Looping construct. This loop has multiple termination conditions:\n\n1) Trip count. Iteration count specified at runtime. Set by\n   specifying the input M. Optional. Set to empty string to omit.\n   Note that a static trip count (specified at graph construction time) can be\n   specified by passing in a constant node for input M.\n2) Loop termination condition. This is an input to the op that determines\n   whether to run the first iteration and also a loop-carried dependency for\n   the body graph. The body graph must yield a value for the condition variable,\n   whether this input is provided or not.\n\nThis table summarizes the operating modes of this operator with equivalent\nC-style code:\n\n    Operator inputs defined as (max_trip_count, condition_var).\n\n    input (\"\", \"\"):\n        for (int i=0; ; ++i) {\n          cond = ... // Note this value is ignored, but is required in the body\n        }\n\n    input (\"\", cond) // Note this is analogous to a while loop\n        bool cond = ...;\n        for (int i=0; cond; ++i) {\n          cond = ...;\n        }\n\n    input (\"\", 1) // Note this is analogous to a do-while loop\n        bool cond = true\n        for (int i=0; cond; ++i) {\n          cond = ...;\n        }\n\n    input (trip_count, \"\") // Note this is analogous to a for loop\n        int trip_count = ...\n        for (int i=0; i < trip_count; ++i) {\n          cond = ...; // ignored\n        }\n\n    input (trip_count, cond)\n        int trip_count = ...;\n        bool cond = ...;\n        for (int i=0; i < trip_count && cond; ++i) {\n          cond = ...;\n        }\n\n\n*Sample usage - cond as well as trip count*\n\n    graph predict-net {\n      %a = Constant[value = <Scalar Tensor [3]>]()\n      %b = Constant[value = <Scalar Tensor [6]>]()\n      %keepgoing = Constant[value = <Scalar Tensor [1]>]()\n      %max_trip_count = Constant[value = <Scalar Tensor [10]>]()\n      %keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)\n      return\n    }\n\n    graph body-net (\n      %i[INT32, scalar]\n      %keepgoing[BOOL, scalar]\n      %b[INT32, scalar]\n    ) {\n      %my_local = Add(%a, %b)\n      %b_out = Sub(%a, %b)\n      %keepgoing_out = Greater(%my_local, %b_out)\n      %user_defined_vals = Add(%b, %b)\n      return %keepgoing_out, %b_out, %user_defined_vals\n    }\n\n*Sample equivalent C code*\n\n    {\n      /* User-defined code (enclosing scope) */\n      int a = 3, b = 6;\n      bool keepgoing = true; // Analogous to input cond\n      /* End user-defined code */\n\n      /* Implicitly-defined code */\n      const int max_trip_count = 10; // Analogous to input M\n      int user_defined_vals[]; // Imagine this is resizable\n      /* End implicitly-defined code */\n      for (int i=0; i < max_trip_count && keepgoing; ++i) {\n        /* User-defined code (loop body) */\n        int my_local = a + b; // Reading values in the enclosing scope is fine\n        b = a - b; // writes fine if we specify b as a loop-carried dependency\n        keepgoing = my_local > b; // keepgoing is a loop-carried dependency\n        user_defined_vals[i] = b + b;\n        /* End user-defined code */\n      }\n      // my_local = 123; // Can't do this. my_local was defined in the the body\n\n      // These below values are live-out from the loop and therefore accessible\n      b_out; user_defined_vals; keepgoing_out;\n    }\n\nThere are several things of note in this code snippet:\n\n1) Values from the enclosing scope (i.e. variable a here) are in scope and can\n   be referenced in the inputs of the loop.\n2) Any variables which you wish to make available in the enclosing scope (i.e.\n   the variables b and keepgoing) must be declared as either loop-carried\n   dependencies (both at the op inputs and output and at the body net input and\n   output) or scan_outputs.\n3) Values created in the body cannot be accessed in the enclosing scope.\n\nNote that the semantics of this op support \"diagonal\" or \"wavefront\" execution.\n(See Step 3 here for an example:\nhttps://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/).\nFrontends should emit multi-layer RNNs as a series of While operators (with\ntime being the inner looping dimension), with each successive layer consuming\nthe scan_outputs from the previous layer, possibly going through several\npoint-wise operators (e.g. dropout, residual connections, linear layer).\nConcretely, the (possibly transformed) scan_outputs are referenced by the\nsubsequent layer as a LoopIndexTensor operating on a value in scope, not\nnecessarily a loop-carried dependency. Backends can recognize this pattern and\nare permitted to schedule the execution of the multi-layer network in a\npipelined/\"wavefront\" fashion.\n\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "A maximum trip-count for the loop specified at runtime. Optional. pass empty string to skip.",
          "name": "M",
          "type": "I"
        },
        {
          "description": "A boolean termination condition. Pass empty string to skip.",
          "name": "cond",
          "type": "B"
        },
        {
          "description": "The initial values of any loop-carried dependencies (values that change across loop iterations)",
          "name": "v_initial",
          "option": "variadic",
          "type": "V"
        }
      ],
      "max_input": 2147483647,
      "max_output": 2147483647,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "Final N loop carried dependency values then K scan_outputs",
          "name": "v_final_and_scan_outputs",
          "option": "variadic",
          "type": "V"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(int32)",
            "tensor(string)",
            "tensor(bool)",
            "tensor(uint8)",
            "tensor(int8)",
            "tensor(uint16)",
            "tensor(int16)",
            "tensor(int64)",
            "tensor(float16)",
            "tensor(double)"
          ],
          "description": "All Tensor types",
          "type_param_str": "V"
        },
        {
          "allowed_type_strs": [
            "int64"
          ],
          "description": "Only int64",
          "type_param_str": "I"
        },
        {
          "allowed_type_strs": [
            "bool"
          ],
          "description": "Only bool",
          "type_param_str": "B"
        }
      ]
    }
  },
  {
    "name": "LoopIndexTensor",
    "schema": {
      "attributes": [
        {
          "description": "Axis on which to index",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "description": "This is a special operator only valid inside the loop that supports the common case behavior of accessing the correct element of the input sequence in an RNN. This operator MUST be directly given the passed-in iteration number to the body of a Loop graph. This signals to back-ends that this is a direct indexing operation, with no transforms applied to the index.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Tensor to be indexed (has N dimensions)",
          "name": "T",
          "type": "T"
        },
        {
          "description": "Loop index provided as input to the body graph",
          "name": "loop_idx",
          "type": "I"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Tensor of N - 1 dims that is a sub tensor of T",
          "name": "O",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(int32)",
            "tensor(string)",
            "tensor(bool)",
            "tensor(uint8)",
            "tensor(int8)",
            "tensor(uint16)",
            "tensor(int16)",
            "tensor(int64)",
            "tensor(float16)",
            "tensor(double)"
          ],
          "description": "All Tensor types",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "int32"
          ],
          "description": "Indices",
          "type_param_str": "I"
        }
      ]
    }
  },
  {
    "name": "LpNormalization",
    "schema": {
      "attributes": [
        {
          "description": "(int64, default -1) the axis on which to apply normalization, -1 mean last axis.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "(int64, default 2) the order of the normalization, only 1 or 2 are supported.",
          "name": "p",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Normalization",
      "description": "Given a matrix, apply Lp-normalization along the provided axis.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input matrix",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Matrix after normalization",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LpPool",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "The size of the kernel along each axis.",
          "name": "kernel_shape",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "p value of the Lp norm used to pool over the input data, default is 2.0.",
          "name": "p",
          "required": false,
          "type": "float"
        },
        {
          "description": "Padding for the beginning and ending along each 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.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Pool",
      "description": "LpPool consumes an input tensor X and applies Lp pooling across the\n the tensor according to kernel sizes, stride sizes, and pad lengths.\n Lp pooling consisting of computing the Lp norm on all values of a subset\n of the input tensor according to the kernel size and downsampling the\n data into the output tensor Y for further processing.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from Lp pooling across the input tensor. Dimensions will vary based on various kernel, stride, and pad sizes.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "LpPool",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "The size of the kernel along each axis.",
          "name": "kernel_shape",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "p value of the Lp norm used to pool over the input data, default is 2.",
          "name": "p",
          "required": false,
          "type": "int"
        },
        {
          "description": "Padding for the beginning and ending along each 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 axis.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis. If not present, the stride defaults to 0 along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Pool",
      "description": "LpPool consumes an input tensor X and applies Lp pooling across the\n the tensor according to kernel sizes, stride sizes, and pad lengths.\n Lp pooling consisting of computing the Lp norm on all values of a subset\n of the input tensor according to the kernel size and downsampling the\n data into the output tensor Y for further processing.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from Lp pooling across the input tensor. Dimensions will vary based on various kernel, stride, and pad sizes.",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 2,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "MatMul",
    "schema": {
      "description": "Matrix product that behaves like numpy.matmul: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.matmul.html\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'MatMul',\n    inputs=['a', 'b'],\n    outputs=['c'],\n)\n\n# 2d\na = np.random.randn(3, 4).astype(np.float32)\nb = np.random.randn(4, 3).astype(np.float32)\nc = np.matmul(a, b)\nexpect(node, inputs=[a, b], outputs=[c],\n       name='test_matmul_2d')\n\n# 3d\na = np.random.randn(2, 3, 4).astype(np.float32)\nb = np.random.randn(2, 4, 3).astype(np.float32)\nc = np.matmul(a, b)\nexpect(node, inputs=[a, b], outputs=[c],\n       name='test_matmul_3d')\n\n# 4d\na = np.random.randn(1, 2, 3, 4).astype(np.float32)\nb = np.random.randn(1, 2, 4, 3).astype(np.float32)\nc = np.matmul(a, b)\nexpect(node, inputs=[a, b], outputs=[c],\n       name='test_matmul_4d')",
          "summary": "matmul"
        }
      ],
      "inputs": [
        {
          "description": "N-dimensional matrix A",
          "name": "A",
          "type": "T"
        },
        {
          "description": "N-dimensional matrix B",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Matrix multiply results from A * B",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Max",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Element-wise max of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 2, 1]).astype(np.float32)\ndata_1 = np.array([1, 4, 4]).astype(np.float32)\ndata_2 = np.array([2, 5, 3]).astype(np.float32)\nresult = np.array([3, 5, 4]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_max_example')\n\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_max_one_input')\n\nresult = np.maximum(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_max_two_inputs')",
          "summary": "max"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Max.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "max",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Max",
    "schema": {
      "description": "Element-wise max of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 2, 1]).astype(np.float32)\ndata_1 = np.array([1, 4, 4]).astype(np.float32)\ndata_2 = np.array([2, 5, 3]).astype(np.float32)\nresult = np.array([3, 5, 4]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_max_example')\n\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_max_one_input')\n\nresult = np.maximum(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Max',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_max_two_inputs')",
          "summary": "max"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Max.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "max",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "MaxPool",
    "schema": {
      "attributes": [
        {
          "description": "auto_pad must be either SAME_UPPER, SAME_LOWER or VALID. Where SAME_UPPER or SAME_LOWER mean pad the input so that the output 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. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.",
          "name": "auto_pad",
          "required": false,
          "type": "string"
        },
        {
          "description": "The size of the kernel along each axis.",
          "name": "kernel_shape",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "Padding for the beginning and ending along each 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 axis.",
          "name": "pads",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Stride along each axis. If not present, the stride defaults to 1 along each axis.",
          "name": "strides",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Pool",
      "description": "MaxPool consumes an input tensor X and applies max pooling across the\n the tensor according to kernel sizes, stride sizes, and pad lengths.\n max pooling consisting of computing the max on all values of a\n subset of the input tensor according to the kernel size and downsampling the\n data into the output tensor Y for further processing. The output spatial shape will be following:\n ```\n output_spatial_shape[i] = floor((input_spatial_shape[i] + pad_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)\n\n * pad_shape[i] is sum of pads along axis i\n ```\n\n `auto_pad` is a DEPRECATED attribute. If you are using them currently, the output spatial shape will be following:\n ```\n VALID: output_spatial_shape[i] = floor((input_spatial_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)\n SAME_UPPER or SAME_LOWER: output_spatial_shape[i] = floor(input_spatial_shape[i] / strides_spatial_shape[i] + 1)\n ```\n And pad shape will be following if `SAME_UPPER` or `SAME_LOWER`:\n ```\n pad_shape[i] = (output_spatial_shape[i] - 1) * strides_spatial_shape[i] + kernel_spatial_shape[i] - input_spatial_shape[i]\n ```\n The output of each pooling window is maximum number of elements exclude pad.\n ",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32]\noutput_shape: [1, 3, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2],\n)\nx = np.random.randn(1, 3, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = [2]\nstrides = [1]\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, [0], 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_1d_default')",
          "summary": "maxpool_1d_default"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 31, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, (0, 0), 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_default')",
          "summary": "maxpool_2d_default"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 28, 28]\noutput_shape: [1, 3, 30, 30]\npad_shape: [4, 4] -> [2, 2, 2, 2] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    pads=[2, 2, 2, 2]\n)\nx = np.random.randn(1, 3, 28, 28).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (3, 3)\nstrides = (1, 1)\npad_bottom = 2\npad_top = 2\npad_right = 2\npad_left = 2\npad_shape = [pad_top + pad_bottom, pad_left + pad_right]\nout_shape = get_output_shape('VALID', np.add(x_shape[2:], pad_shape), kernel_shape, strides)\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_pads')",
          "summary": "maxpool_2d_pads"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 5, 5]\npad_shape: [4, 4] -> [2, 2, 2, 2] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[5, 5],\n    pads=[2, 2, 2, 2]\n\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[\n    [13, 14, 15, 15, 15],\n    [18, 19, 20, 20, 20],\n    [23, 24, 25, 25, 25],\n    [23, 24, 25, 25, 25],\n    [23, 24, 25, 25, 25]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_precomputed_pads')",
          "summary": "maxpool_2d_precomputed_pads"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 3, 3]\npad_shape: [2, 2] -> [1, 1, 1, 1] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[3, 3],\n    strides=[2, 2],\n    auto_pad='SAME_UPPER'\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[[7, 9, 10],\n                [17, 19, 20],\n                [22, 24, 25]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_precomputed_same_upper')",
          "summary": "maxpool_2d_precomputed_same_upper"
        },
        {
          "code": "\"\"\"\ninput_shape: [1, 1, 5, 5]\noutput_shape: [1, 1, 2, 2]\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    strides=[2, 2]\n)\nx = np.array([[[\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n]]]).astype(np.float32)\ny = np.array([[[[7, 9],\n                [17, 19]]]]).astype(np.float32)\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_precomputed_strides')",
          "summary": "maxpool_2d_precomputed_strides"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 32, 32]\npad_shape: [1, 1] -> [1, 0, 1, 0] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    auto_pad='SAME_LOWER'\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('SAME_LOWER', x_shape[2:], kernel_shape, strides)\npad_shape = get_pad_shape('SAME_LOWER', x_shape[2:], kernel_shape, strides, out_shape)\npad_bottom = pad_shape[0] // 2\npad_top = pad_shape[0] - pad_bottom\npad_right = pad_shape[1] // 2\npad_left = pad_shape[1] - pad_right\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_same_lower')",
          "summary": "maxpool_2d_same_lower"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 32, 32]\npad_shape: [1, 1] -> [0, 1, 0, 1] by axis\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2],\n    auto_pad='SAME_UPPER'\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (2, 2)\nstrides = (1, 1)\nout_shape = get_output_shape('SAME_UPPER', x_shape[2:], kernel_shape, strides)\npad_shape = get_pad_shape('SAME_UPPER', x_shape[2:], kernel_shape, strides, out_shape)\npad_top = pad_shape[0] // 2\npad_bottom = pad_shape[0] - pad_top\npad_left = pad_shape[1] // 2\npad_right = pad_shape[1] - pad_left\npadded = np.pad(x, ((0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)), mode='constant',\n                constant_values=np.nan)\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, pad_shape, 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_same_upper')",
          "summary": "maxpool_2d_same_upper"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32]\noutput_shape: [1, 3, 10, 10]\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[5, 5],\n    strides=[3, 3]\n)\nx = np.random.randn(1, 3, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = (5, 5)\nstrides = (3, 3)\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, (0, 0), 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_strides')",
          "summary": "maxpool_2d_strides"
        },
        {
          "code": "\"\"\"\niutput_shape: [1, 3, 32, 32, 32]\noutput_shape: [1, 3, 31, 31, 31]\n\"\"\"\nnode = onnx.helper.make_node(\n    'MaxPool',\n    inputs=['x'],\n    outputs=['y'],\n    kernel_shape=[2, 2, 2],\n)\nx = np.random.randn(1, 3, 32, 32, 32).astype(np.float32)\nx_shape = np.shape(x)\nkernel_shape = [2, 2, 2]\nstrides = [1, 1, 1]\nout_shape = get_output_shape('VALID', x_shape[2:], kernel_shape, strides)\npadded = x\ny = pool(padded, x_shape, kernel_shape, strides, out_shape, [0, 0, 0], 'MAX')\n\nexpect(node, inputs=[x], outputs=[y], name='test_maxpool_3d_default')",
          "summary": "maxpool_3d_default"
        }
      ],
      "inputs": [
        {
          "description": "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 dimension are in the form of (N x C x D1 x D2 ... Dn), where N is the batch size.",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data tensor from average or max pooling across the input tensor. Dimensions will vary based on various kernel, stride, and pad sizes. Floor value of the dimension is used",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "MaxRoiPool",
    "schema": {
      "attributes": [
        {
          "description": "ROI pool output shape (height, width).",
          "name": "pooled_shape",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "Multiplicative spatial scale factor to translate ROI coordinates from their input scale to the scale used when pooling, default is 1.0f.",
          "name": "spatial_scale",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Pool",
      "description": "ROI max pool consumes an input tensor X and region of interests (RoIs) to\n apply max pooling across each RoI, to produce output 4-D tensor of shape\n (num_rois, channels, pooled_shape[0], pooled_shape[1]).",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "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.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "RoIs (Regions of Interest) to pool over. Should be a 2-D tensor of shape (num_rois, 5) given as [[batch_id, x1, y1, x2, y2], ...].",
          "name": "rois",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "RoI pooled output 4-D tensor of shape (num_rois, channels, pooled_shape[0], pooled_shape[1]).",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Mean",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Element-wise mean of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 0, 2]).astype(np.float32)\ndata_1 = np.array([1, 3, 4]).astype(np.float32)\ndata_2 = np.array([2, 6, 6]).astype(np.float32)\nresult = np.array([2, 3, 4]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_mean_example')\n\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_mean_one_input')\n\nresult = np.divide(np.add(data_0, data_1), 2.)\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_mean_two_inputs')",
          "summary": "mean"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Mean.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "mean",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Mean",
    "schema": {
      "description": "Element-wise mean of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 0, 2]).astype(np.float32)\ndata_1 = np.array([1, 3, 4]).astype(np.float32)\ndata_2 = np.array([2, 6, 6]).astype(np.float32)\nresult = np.array([2, 3, 4]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_mean_example')\n\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_mean_one_input')\n\nresult = np.divide(np.add(data_0, data_1), 2.)\nnode = onnx.helper.make_node(\n    'Mean',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_mean_two_inputs')",
          "summary": "mean"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Mean.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "mean",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "MeanVarianceNormalization",
    "schema": {
      "attributes": [
        {
          "description": "If 1, mean and variance are computed across channels. Default is 0.",
          "name": "across_channels",
          "required": false,
          "type": "int"
        },
        {
          "description": "If 0, normalize the mean only.  Default is 1.",
          "name": "normalize_variance",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Perform mean variance normalization.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor of shape [N,C,H,W]",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same shape and type as input",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Min",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Element-wise min of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 2, 1]).astype(np.float32)\ndata_1 = np.array([1, 4, 4]).astype(np.float32)\ndata_2 = np.array([2, 5, 0]).astype(np.float32)\nresult = np.array([1, 2, 0]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_min_example')\n\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_min_one_input')\n\nresult = np.minimum(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_min_two_inputs')",
          "summary": "min"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Min",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "min",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Min",
    "schema": {
      "description": "Element-wise min of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 2, 1]).astype(np.float32)\ndata_1 = np.array([1, 4, 4]).astype(np.float32)\ndata_2 = np.array([2, 5, 0]).astype(np.float32)\nresult = np.array([1, 2, 0]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_min_example')\n\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_min_one_input')\n\nresult = np.minimum(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Min',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_min_two_inputs')",
          "summary": "min"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Min",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "min",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Mul",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Performs element-wise binary multiplication (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Mul',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([4, 5, 6]).astype(np.float32)\nz = x * y  # expected output [4., 10., 18.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = x * y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul')",
          "summary": "mul"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Mul',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = x * y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul_bcast')",
          "summary": "mul_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Mul",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Performs element-wise binary multiplication (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Mul',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([4, 5, 6]).astype(np.float32)\nz = x * y  # expected output [4., 10., 18.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = x * y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul')",
          "summary": "mul"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Mul',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = x * y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_mul_bcast')",
          "summary": "mul_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Neg",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Neg takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where each element flipped sign, y = -x, is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Neg',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-4, 2]).astype(np.float32)\ny = np.negative(x)  # expected output [4., -2.],\nexpect(node, inputs=[x], outputs=[y],\n       name='test_neg_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.negative(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_neg')",
          "summary": "neg"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Neg",
    "schema": {
      "description": "Neg takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where each element flipped sign, y = -x, is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Neg',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-4, 2]).astype(np.float32)\ny = np.negative(x)  # expected output [4., -2.],\nexpect(node, inputs=[x], outputs=[y],\n       name='test_neg_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.negative(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_neg')",
          "summary": "neg"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Normalizer",
    "schema": {
      "attributes": [
        {
          "description": "0=Lmax, 1=L1, 2=L2",
          "name": "norm",
          "required": false,
          "type": "string"
        }
      ],
      "description": "Normalize the input.  There are three normalization modes,\n    which have the corresponding formulas:\n    Max .. math::     max(x_i)\n    L1  .. math::  z = ||x||_1 = \\sum_{i=1}^{n} |x_i|\n    L2  .. math::  z = ||x||_2 = \\sqrt{\\sum_{i=1}^{n} x_i^2}\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be encoded",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "encoded output data",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Not",
    "schema": {
      "category": "Logic",
      "description": "Returns the negation of the input tensor element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Not',\n    inputs=['x'],\n    outputs=['not'],\n)\n\n# 2d\nx = (np.random.randn(3, 4) > 0).astype(np.bool)\nexpect(node, inputs=[x], outputs=[np.logical_not(x)],\n       name='test_not_2d')\n\n# 3d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\nexpect(node, inputs=[x], outputs=[np.logical_not(x)],\n       name='test_not_3d')\n\n# 4d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\nexpect(node, inputs=[x], outputs=[np.logical_not(x)],\n       name='test_not_4d')",
          "summary": "not"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains input/output to boolean tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "OneHotEncoder",
    "schema": {
      "attributes": [
        {
          "description": "list of categories, ints",
          "name": "cats_int64s",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "list of categories, strings",
          "name": "cats_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "if true and category is not present, will return all zeros, if false and missing category, operator will return false",
          "name": "zeros",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Replace the inputs with an array of ones and zeros, where the only\n    one is the zero-based category that was passed in.  The total category count\n    will determine the length of the vector. For example if we pass a\n    tensor with a single value of 4, and a category count of 8, the\n    output will be a tensor with 0,0,0,0,1,0,0,0 .\n\n    This operator assumes every input in X is of the same category set\n    (meaning there is only one category count).\n\t\n\tIf the input is a tensor of float, int32, or double, the data will be cast\n    to int64s and the cats_int64s category list will be used for the lookups.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be encoded",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "encoded output data",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)",
            "tensor(int32)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Or",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `or` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n)\n\n# 2d\nx = (np.random.randn(3, 4) > 0).astype(np.bool)\ny = (np.random.randn(3, 4) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or2d')\n\n# 3d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or3d')\n\n# 4d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or4d')",
          "summary": "or"
        },
        {
          "code": "x = (np.random.randn(5, 5, 5, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\n\nnode = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n    broadcast=1,\n    axis=0,\n)\n\nz = np.logical_or(x, y[:, np.newaxis, np.newaxis, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_axis0')\n\nnode = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n    broadcast=1,\n    axis=1,\n)\n\nz = np.logical_or(x, y[:, np.newaxis, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_axis1')\n\nnode = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n    broadcast=1,\n    axis=2,\n)\n\nz = np.logical_or(x, y[:, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_axis2')\n\nnode = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n    broadcast=1,\n    axis=3,\n)\n\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_axis3')",
          "summary": "or_axis"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Or',\n    inputs=['x', 'y'],\n    outputs=['or'],\n    broadcast=1,\n)\n\n# 3d vs 1d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast3v1d')\n\n# 3d vs 2d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(4, 5) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast3v2d')\n\n# 4d vs 2d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(5, 6) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast4v2d')\n\n# 4d vs 3d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(4, 5, 6) > 0).astype(np.bool)\nz = np.logical_or(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_or_bcast4v3d')",
          "summary": "or_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains input to boolean tensor.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "PRelu",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "PRelu takes input data (Tensor<T>) and slope tensor as input, and produces one\noutput data (Tensor<T>) where the function `f(x) = slope * x for x < 0`,\n`f(x) = x for x >= 0`., is applied to the data tensor elementwise.\n\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        },
        {
          "description": "Slope tensor. If `Slope` is of size 1, the value is sharedacross different channels",
          "name": "slope",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "PRelu",
    "schema": {
      "category": "Activation",
      "description": "PRelu takes input data (Tensor<T>) and slope tensor as input, and produces one\noutput data (Tensor<T>) where the function `f(x) = slope * x for x < 0`,\n`f(x) = x for x >= 0`., is applied to the data tensor elementwise.\n\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        },
        {
          "description": "Slope tensor. If `Slope` is of size 1, the value is sharedacross different channels",
          "name": "slope",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Pad",
    "schema": {
      "attributes": [
        {
          "description": "Three modes: constant(default), reflect, edge",
          "name": "mode",
          "required": false,
          "type": "string"
        },
        {
          "description": "List of integers indicate the padding element count at the beginning and end of each axis, for 2D it is the number of pixel. `paddings` rank should be double of the input's rank. `paddings` 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`.",
          "name": "paddings",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "One float, indicates the value to be filled, default is 0",
          "name": "value",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Tensor",
      "description": "Given `data` tensor, paddings, mode, and value.\n\nExample:\n  Insert 0 paddings to the beginning of the second dimension.\n\n  data = [\n      [1.0, 1.2],\n      [2.3, 3.4],\n      [4.5, 5.7],\n  ]\n  paddings = [0, 0, 2, 0]\n\n  output = [\n      [\n          [0.0, 0.0, 1.0, 1.2],\n          [0.0, 0.0, 2.3, 3.4],\n          [0.0, 0.0, 4.5, 5.7],\n      ],\n  ]\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Pad',\n    inputs=['x'],\n    outputs=['y'],\n    mode='constant',\n    value=1.2,\n    pads=[0, 0, 1, 3, 0, 0, 2, 4],\n)\nx = np.random.randn(1, 3, 4, 5).astype(np.float32)\ny = np.pad(\n    x,\n    pad_width=((0, 0), (0, 0), (1, 2), (3, 4)),\n    mode='constant',\n    constant_values=1.2,\n)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_constant_pad')",
          "summary": "constant_pad"
        },
        {
          "code": "for mode in ['edge', 'reflect']:\n    node = onnx.helper.make_node(\n        'Pad',\n        inputs=['x'],\n        outputs=['y'],\n        mode=mode,\n        pads=[0, 0, 1, 1, 0, 0, 1, 1]\n    )\n    x = np.random.randn(1, 3, 4, 5).astype(np.float32)\n    y = np.pad(\n        x,\n        pad_width=((0, 0), (0, 0), (1, 1), (1, 1)),\n        mode=mode,\n    )\n\n    expect(node, inputs=[x], outputs=[y],\n           name='test_{}_pad'.format(mode))",
          "summary": "reflection_and_edge_pad"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Tensor after padding.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Pad",
    "schema": {
      "attributes": [
        {
          "description": "Three modes: constant(default), reflect, edge",
          "name": "mode",
          "required": false,
          "type": "string"
        },
        {
          "description": "List of integers indicate the padding element count at the beginning and end of each axis, for 2D it is the number of pixel. `pads` rank should be double of the input's rank. `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`.",
          "name": "pads",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "One float, indicates the value to be filled, default is 0",
          "name": "value",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Tensor",
      "description": "Given `data` tensor, pads, mode, and value.\n\nExample:\n  Insert 0 pads to the beginning of the second dimension.\n\n  data = [\n      [1.0, 1.2],\n      [2.3, 3.4],\n      [4.5, 5.7],\n  ]\n  pads = [0, 2, 0, 0]\n\n  output = [\n      [\n          [0.0, 0.0, 1.0, 1.2],\n          [0.0, 0.0, 2.3, 3.4],\n          [0.0, 0.0, 4.5, 5.7],\n      ],\n  ]\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Pad',\n    inputs=['x'],\n    outputs=['y'],\n    mode='constant',\n    value=1.2,\n    pads=[0, 0, 1, 3, 0, 0, 2, 4],\n)\nx = np.random.randn(1, 3, 4, 5).astype(np.float32)\ny = np.pad(\n    x,\n    pad_width=((0, 0), (0, 0), (1, 2), (3, 4)),\n    mode='constant',\n    constant_values=1.2,\n)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_constant_pad')",
          "summary": "constant_pad"
        },
        {
          "code": "for mode in ['edge', 'reflect']:\n    node = onnx.helper.make_node(\n        'Pad',\n        inputs=['x'],\n        outputs=['y'],\n        mode=mode,\n        pads=[0, 0, 1, 1, 0, 0, 1, 1]\n    )\n    x = np.random.randn(1, 3, 4, 5).astype(np.float32)\n    y = np.pad(\n        x,\n        pad_width=((0, 0), (0, 0), (1, 1), (1, 1)),\n        mode=mode,\n    )\n\n    expect(node, inputs=[x], outputs=[y],\n           name='test_{}_pad'.format(mode))",
          "summary": "reflection_and_edge_pad"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Tensor after padding.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 2,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ParametricSoftplus",
    "schema": {
      "attributes": [
        {
          "description": "Value of alpha",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Value of beta",
          "name": "beta",
          "required": false,
          "type": "float"
        }
      ],
      "description": "ParametricSoftplus takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the softplus function, y = alpha * ln(exp(beta * x) + 1), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "1D input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "1D input tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Pow",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Pow takes input data (Tensor<T>) and exponent Tensor, and\nproduces one output data (Tensor<T>) where the function `f(x) = x^exponent`,\nis applied to the data tensor elementwise.\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Pow',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([4, 5, 6]).astype(np.float32)\nz = np.power(x, y)  # expected output [1., 32., 729.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_pow_example')\n\nx = np.arange(60).reshape(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = np.power(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_pow')",
          "summary": "pow"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Pow',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([2]).astype(np.float32)\nz = np.power(x, y)  # expected output [1., 4., 9.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_pow_bcast')\n\nnode = onnx.helper.make_node(\n    'Pow',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n    axis=0,\n)\nx = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)\ny = np.array([2, 3]).astype(np.float32)\nz = np.array([[1, 4, 9], [64, 125, 216]]).astype(np.float32)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_pow_bcast_axis0')",
          "summary": "pow_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor of any shape, base of the exponent.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "Input tensor of any shape broadcastable to X shape, the exponent component.",
          "name": "Y",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor (same size as X)",
          "name": "Z",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "RNN",
    "schema": {
      "attributes": [
        {
          "description": "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.",
          "name": "activation_alpha",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activation_beta",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "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.",
          "name": "activations",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "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.",
          "name": "clip",
          "required": false,
          "type": "float"
        },
        {
          "description": "Specify if the RNN is forward, reverse, or bidirectional. Must be one of forward (default), reverse, or bidirectional.",
          "name": "direction",
          "required": false,
          "type": "string"
        },
        {
          "description": "Number of neurons in the hidden layer",
          "name": "hidden_size",
          "required": false,
          "type": "int"
        },
        {
          "description": "The sequence output for the hidden is optional if 0. Default 0.",
          "name": "output_sequence",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Layer",
      "description": "Computes an one-layer simple RNN. This operator is usually supported\nvia some custom implementation such as CuDNN.\n\nNotations:\n\n`X` - input tensor\n\n`i` - input gate\n\n`t` - time step (t-1 means previous time step)\n\n`Wi` - W parameter weight matrix for input gate\n\n`Ri` - R recurrence weight matrix for input gate\n\n`Wbi` - W parameter bias vector for input gate\n\n`Rbi` - R parameter bias vector for input gate\n\n`WBi` - W parameter weight matrix for backward input gate\n\n`RBi` - R recurrence weight matrix for backward input gate\n\n`WBbi` - WR bias vectors for backward input gate\n\n`RBbi` - RR bias vectors for backward input gate\n\n`H` - Hidden state\n\n`num_directions` - 2 if direction == bidirectional else 1\n\nActivation functions:\n\n  Relu(x)                - max(0, x)\n\n  Tanh(x)                - (1 - e^{-2x})/(1 + e^{-2x})\n\n  Sigmoid(x)             - 1/(1 + e^{-x})\n\n  (NOTE: Below are optional)\n\n  Affine(x)              - alpha*x + beta\n\n  LeakyRelu(x)           - x if x >= 0 else alpha * x\n\n  ThresholdedRelu(x)     - x if x >= alpha else 0\n\n  ScaledTanh(x)          - alpha*Tanh(beta*x)\n\n  HardSigmoid(x)         - min(max(alpha*x + beta, 0), 1)\n\n  Elu(x)                 - x if x >= 0 else alpha*(e^x - 1)\n\n  Softsign(x)            - x/(1 + |x|)\n\n  Softplus(x)            - log(1 + e^x)\n\nEquations (Default: f=Tanh):\n\n  - Ht = f(Xt*(Wi^T) + Ht-1*Ri + Wbi + Rbi)\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The input sequences packed (and potentially padded) into one 3-D tensor with the shape of `[seq_length, batch_size, input_size]`.",
          "name": "X",
          "type": "T"
        },
        {
          "description": "The weight tensor for input gate. Concatenation of `Wi` and `WBi` (if bidirectional). The tensor has shape `[num_directions, hidden_size, input_size]`.",
          "name": "W",
          "type": "T"
        },
        {
          "description": "The recurrence weight tensor. Concatenation of `Ri` and `RBi` (if bidirectional). The tensor has shape `[num_directions, hidden_size, hidden_size]`.",
          "name": "R",
          "type": "T"
        },
        {
          "description": "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.",
          "name": "B",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "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]`.",
          "name": "sequence_lens",
          "option": "optional",
          "type": "T1"
        },
        {
          "description": "Optional initial value of the hidden. If not specified - assumed to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "initial_h",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 6,
      "max_output": 2,
      "min_input": 3,
      "min_output": 0,
      "outputs": [
        {
          "description": "A tensor that concats all the intermediate output values of the hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`. It is optional if `output_sequence` is 0.",
          "name": "Y",
          "option": "optional",
          "type": "T"
        },
        {
          "description": "The last output value of the hidden. It has shape `[num_directions, batch_size, hidden_size]`.",
          "name": "Y_h",
          "option": "optional",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int32)"
          ],
          "description": "Constrain seq_lens to integer tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "RandomNormal",
    "schema": {
      "attributes": [
        {
          "description": "The data type for the elements of the output tensor. Default is TensorProto::FLOAT.",
          "name": "dtype",
          "required": false,
          "type": "int"
        },
        {
          "description": "The mean of the normal distribution. If not specified, default is 0.",
          "name": "mean",
          "required": false,
          "type": "float"
        },
        {
          "description": "The standard deviation of the normal distribution. If not specified, default is 1.",
          "name": "scale",
          "required": false,
          "type": "float"
        },
        {
          "description": "(Optional) Seed to the random generator, if not specified we will auto generate one.",
          "name": "seed",
          "required": false,
          "type": "float"
        },
        {
          "description": "The shape of the output tensor.",
          "name": "shape",
          "required": true,
          "type": "int[]"
        }
      ],
      "description": "Generate a tensor with random values drawn from a normal distribution. The shape\nof the tensor is specified by the `shape` argument and the parameter of the normal distribution\nspecified by `mean` and `scale`.\n\nThe data type is specified by the 'dtype' argument. The 'dtype' argument must\nbe one of the data types specified in the 'DataType' enum field in the\nTensorProto message.\n",
      "domain": "ai.onnx",
      "max_input": 0,
      "max_output": 1,
      "min_input": 0,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of random values drawn from normal distribution",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "RandomNormalLike",
    "schema": {
      "attributes": [
        {
          "description": "(Optional) The data type for the elements of the output tensor, if not specified, we will usethe data type of the input tensor.",
          "name": "dtype",
          "required": false,
          "type": "int"
        },
        {
          "description": "The mean of the normal distribution. If not specified, default is 0.",
          "name": "mean",
          "required": false,
          "type": "float"
        },
        {
          "description": "The standard deviation of the normal distribution. If not specified, default is 1.",
          "name": "scale",
          "required": false,
          "type": "float"
        },
        {
          "description": "(Optional) Seed to the random generator, if not specified we will auto generate one.",
          "name": "seed",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Generate a tensor with random values drawn from a normal distribution. The shape\nof the tensor is computed from the input argument and the parameter of the normal distribution\nspecified by `mean` and `scale`.\n\nThe data type is specified by the 'dtype' argument. The 'dtype' argument must\nbe one of the data types specified in the 'DataType' enum field in the\nTensorProto message.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor to provide shape information.",
          "name": "input",
          "type": "tensor(int32)"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of random values drawn from normal distribution",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "RandomUniform",
    "schema": {
      "attributes": [
        {
          "description": "The data type for the elements of the output tensor. If not specified, default is TensorProto::FLOAT.",
          "name": "dtype",
          "required": false,
          "type": "int"
        },
        {
          "description": "Upper boundary of the output values. If not specified, default is 1.",
          "name": "high",
          "required": false,
          "type": "float"
        },
        {
          "description": "Lower boundary of the output values. If not specified, default is 0.",
          "name": "low",
          "required": false,
          "type": "float"
        },
        {
          "description": "(Optional) Seed to the random generator, if not specified we will auto generate one.",
          "name": "seed",
          "required": false,
          "type": "float"
        },
        {
          "description": "The shape of the output tensor.",
          "name": "shape",
          "required": true,
          "type": "int[]"
        }
      ],
      "description": "Generate a tensor with random values drawn from a uniform distribution. The shape\nof the tensor is specified by the `shape` argument and the range by `low` and `high`.\n\nThe data type is specified by the 'dtype' argument. The 'dtype' argument must\nbe one of the data types specified in the 'DataType' enum field in the\nTensorProto message.\n",
      "domain": "ai.onnx",
      "max_input": 0,
      "max_output": 1,
      "min_input": 0,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of random values drawn from uniform distribution",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "RandomUniformLike",
    "schema": {
      "attributes": [
        {
          "description": "(Optional) The data type for the elements of the output tensor, if not specified, we will usethe data type of the input tensor.",
          "name": "dtype",
          "required": false,
          "type": "int"
        },
        {
          "description": "Upper boundary of the output values. If not specified, default is 1.",
          "name": "high",
          "required": false,
          "type": "float"
        },
        {
          "description": "Lower boundary of the output values. If not specified, default is 0.",
          "name": "low",
          "required": false,
          "type": "float"
        },
        {
          "description": "(Optional) Seed to the random generator, if not specified we will auto generate one.",
          "name": "seed",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Generate a tensor with random values drawn from a uniform distribution. The shape\nof the tensor is computed from the input argument and the range by `low` and `high`.\n\nThe data type is specified by the 'dtype' argument. The 'dtype' argument must\nbe one of the data types specified in the 'DataType' enum field in the\nTensorProto message.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor to provide shape information.",
          "name": "input",
          "type": "tensor(int32)"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of random values drawn from uniform distribution",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Reciprocal",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Reciprocal takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the reciprocal is, y = 1/x, is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Reciprocal',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-4, 2]).astype(np.float32)\ny = np.reciprocal(x)  # expected output [-0.25, 0.5],\nexpect(node, inputs=[x], outputs=[y],\n       name='test_reciprocal_example')\n\nx = np.random.rand(3, 4, 5).astype(np.float32) + 0.5\ny = np.reciprocal(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_reciprocal')",
          "summary": "reciprocal"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Reciprocal",
    "schema": {
      "description": "Reciprocal takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the reciprocal is, y = 1/x, is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Reciprocal',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-4, 2]).astype(np.float32)\ny = np.reciprocal(x)  # expected output [-0.25, 0.5],\nexpect(node, inputs=[x], outputs=[y],\n       name='test_reciprocal_example')\n\nx = np.random.rand(3, 4, 5).astype(np.float32) + 0.5\ny = np.reciprocal(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_reciprocal')",
          "summary": "reciprocal"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceL1",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the L1 norm of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceL2",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the L2 norm of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceLogSum",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the log sum of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceLogSumExp",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the log sum exponent of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceMax",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the max of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceMean",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the mean of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceMin",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the min of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceProd",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the product of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceSum",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the sum of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ReduceSumSquare",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers, along which to reduce.",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Keep the reduced dimension or not, default 1 mean keep reduced dimension.",
          "name": "keepdims",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Computes the sum square of the input tensor's element along the provided axes. The resulted\ntensor has the same rank as the input if keepdims equal 1. If keepdims equal 0, then\nthe resulted tensor have the reduced dimension pruned.\n\nThe above behavior is similar to numpy, with the exception that numpy default keepdims to\nFalse instead of True.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reduced output tensor.",
          "name": "reduced",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Relu",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "Relu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the rectified linear function, y = max(0, x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Relu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_relu')",
          "summary": "relu"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Relu",
    "schema": {
      "category": "Activation",
      "description": "Relu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the rectified linear function, y = max(0, x), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Relu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_relu')",
          "summary": "relu"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Reshape",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "New shape",
          "name": "shape",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Shape",
      "description": "Reshape the input tensor similar to numpy.reshape.\nIt takes a tensor as input and an argument `shape`. It outputs the reshaped tensor.\nAt most one dimension of the new shape can be -1. In this case, the value is\ninferred from the size of the tensor and the remaining dimensions. A dimension\ncould also be 0, in which case the actual dimension value is unchanged (i.e. taken\nfrom the input tensor).",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "original_shape = [2, 3, 4]\ntest_cases = {\n    'reordered_dims': np.array([4, 2, 3], dtype=np.int64),\n    'reduced_dims': np.array([3, 8], dtype=np.int64),\n    'extended_dims': np.array([3, 2, 2, 2], dtype=np.int64),\n    'one_dim': np.array([24], dtype=np.int64),\n    'negative_dim': np.array([6, -1, 2], dtype=np.int64),\n}\ndata = np.random.random_sample(original_shape).astype(np.float32)\n\nfor test_name, shape in test_cases.items():\n    node = onnx.helper.make_node(\n        'Reshape',\n        inputs=['data', 'shape'],\n        outputs=['reshaped'],\n    )\n\n    reshaped = np.reshape(data, shape)\n    expect(node, inputs=[data, shape], outputs=[reshaped],\n           name='test_reshape_' + test_name)",
          "summary": "reshape"
        }
      ],
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reshaped data.",
          "name": "reshaped",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Reshape",
    "schema": {
      "category": "Shape",
      "description": "Reshape the input tensor similar to numpy.reshape.\n\nFirst input is the data tensor, second input is a shape tensor which specifies the output shape. It outputs the reshaped tensor.\n\nAt most one dimension of the new shape can be -1. In this case, the value is\ninferred from the size of the tensor and the remaining dimensions. A dimension\ncould also be 0, in which case the actual dimension value is unchanged (i.e. taken\nfrom the input tensor).",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "original_shape = [2, 3, 4]\ntest_cases = {\n    'reordered_dims': np.array([4, 2, 3], dtype=np.int64),\n    'reduced_dims': np.array([3, 8], dtype=np.int64),\n    'extended_dims': np.array([3, 2, 2, 2], dtype=np.int64),\n    'one_dim': np.array([24], dtype=np.int64),\n    'negative_dim': np.array([6, -1, 2], dtype=np.int64),\n}\ndata = np.random.random_sample(original_shape).astype(np.float32)\n\nfor test_name, shape in test_cases.items():\n    node = onnx.helper.make_node(\n        'Reshape',\n        inputs=['data', 'shape'],\n        outputs=['reshaped'],\n    )\n\n    reshaped = np.reshape(data, shape)\n    expect(node, inputs=[data, shape], outputs=[reshaped],\n           name='test_reshape_' + test_name)",
          "summary": "reshape"
        }
      ],
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        },
        {
          "description": "Specified shape for output.",
          "name": "shape",
          "type": "tensor(int64)"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reshaped data.",
          "name": "reshaped",
          "type": "T"
        }
      ],
      "since_version": 5,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "SVMClassifier",
    "schema": {
      "attributes": [
        {
          "description": "class labels if using int labels",
          "name": "classlabels_ints",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "class labels if using string labels",
          "name": "classlabels_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "",
          "name": "coefficients",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "Tensor of 3 elements containing gamma, coef0, degree in that order.  Zero if unused for the kernel.",
          "name": "kernel_params",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "enum LINEAR, POLY, RBF, SIGMOID, defaults to linear",
          "name": "kernel_type",
          "required": false,
          "type": "string"
        },
        {
          "description": "post eval transform for score, enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        },
        {
          "description": "First set of probability coefficients",
          "name": "prob_a",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "Second set of probability coefficients, must be same size as prob_a, if these are provided then output Z are probability estimates.",
          "name": "prob_b",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "",
          "name": "rho",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "",
          "name": "support_vectors",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "",
          "name": "vectors_per_class",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "SVM classifier prediction\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be classified",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 2,
      "outputs": [
        {
          "description": "Classification outputs (one class per example)",
          "name": "Y",
          "type": "T2"
        },
        {
          "description": "Class scores (one per class per example), if prob_a and prob_b are provided they are probabilities for each class otherwise they are raw scores.",
          "name": "Z",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "SVMRegressor",
    "schema": {
      "attributes": [
        {
          "description": "support vector coefficients",
          "name": "coefficients",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "Tensor of 3 elements containing gamma, coef0, degree in that order.  Zero if unused for the kernel.",
          "name": "kernel_params",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "enum LINEAR, POLY, RBF, SIGMOID, defaults to linear",
          "name": "kernel_type",
          "required": false,
          "type": "string"
        },
        {
          "description": "number of support vectors",
          "name": "n_supports",
          "required": false,
          "type": "int"
        },
        {
          "description": "bool whether the regression is a one class svm or not, defaults to false",
          "name": "one_class",
          "required": false,
          "type": "int"
        },
        {
          "description": "post eval transform for score, enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        },
        {
          "description": "",
          "name": "rho",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "chosen support vectors",
          "name": "support_vectors",
          "required": false,
          "type": "float[]"
        }
      ],
      "description": "SVM regression prediction and one-class svm anomaly detection\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be regressed",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Regression outputs (one score per target per example)",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Scale",
    "schema": {
      "attributes": [
        {
          "description": "(float, default 1.0) the scale to apply.",
          "name": "scale",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Scale takes one input data (Tensor<float>) and produces one output data\n(Tensor<float>) whose value is the input data tensor scaled element-wise.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input data to be scaled",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output data after scaling",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ScaledTanh",
    "schema": {
      "attributes": [
        {
          "description": "Scaling value",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Scaling value",
          "name": "beta",
          "required": false,
          "type": "float"
        }
      ],
      "description": "Calculates the scaled hyperbolic tangent of the given input tensor element-wise,\nalpha * tanh(beta * x). This operation can be done in an in-place fashion too,\nby providing the same input and output blobs.\n    ",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "1-D input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The scaled hyperbolic tangent values of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Scaler",
    "schema": {
      "attributes": [
        {
          "description": "first, offset by this, must be same length as scale",
          "name": "offset",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "second, multiply by this, can be length of features or length 1",
          "name": "scale",
          "required": false,
          "type": "float[]"
        }
      ],
      "description": "Rescale input data, for example to standardize features by removing the mean and scaling to unit variance.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Data to be scaled",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Scaled output data",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Selu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of SELU default to 1.6732.",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Coefficient of SELU default to 1.0507.",
          "name": "gamma",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "Selu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the scaled exponential linear unit function,\n`y = gamma * (alpha * e^x - alpha) for x <= 0`, `y = gamma * x for x > 0`,\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Selu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=2.0,\n    gamma=3.0\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-3.79272318, 0., 3.]\ny = np.clip(x, 0, np.inf) * 3.0 + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0 * 3.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) * 3.0 + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0 * 3.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu')",
          "summary": "selu"
        },
        {
          "code": "default_alpha = 1.6732\ndefault_gamma = 1.0507\nnode = onnx.helper.make_node(\n    'Selu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) * default_gamma + \\\n    (np.exp(np.clip(x, -np.inf, 0)) - 1) * default_alpha * default_gamma\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu_default')",
          "summary": "selu_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Selu",
    "schema": {
      "attributes": [
        {
          "description": "Coefficient of SELU default to 1.6732.",
          "name": "alpha",
          "required": false,
          "type": "float"
        },
        {
          "description": "Coefficient of SELU default to 1.0507.",
          "name": "gamma",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "Selu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the scaled exponential linear unit function,\n`y = gamma * (alpha * e^x - alpha) for x <= 0`, `y = gamma * x for x > 0`,\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Selu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=2.0,\n    gamma=3.0\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\n# expected output [-3.79272318, 0., 3.]\ny = np.clip(x, 0, np.inf) * 3.0 + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0 * 3.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) * 3.0 + (np.exp(np.clip(x, -np.inf, 0)) - 1) * 2.0 * 3.0\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu')",
          "summary": "selu"
        },
        {
          "code": "default_alpha = 1.6732\ndefault_gamma = 1.0507\nnode = onnx.helper.make_node(\n    'Selu',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, 0, np.inf) * default_gamma + \\\n    (np.exp(np.clip(x, -np.inf, 0)) - 1) * default_alpha * default_gamma\nexpect(node, inputs=[x], outputs=[y],\n       name='test_selu_default')",
          "summary": "selu_default"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Shape",
    "schema": {
      "description": "Takes a tensor as input and outputs an 1D int64 tensor containing the shape of the input tensor.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Shape',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([\n    [1, 2, 3],\n    [4, 5, 6],\n]).astype(np.float32)\ny = np.array([\n    2, 3,\n]).astype(np.int64)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_shape_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.array(x.shape).astype(np.int64)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_shape')",
          "summary": "shape"
        }
      ],
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Shape of the input tensor",
          "name": "shape",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)",
            "tensor(int8)",
            "tensor(int16)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(uint8)",
            "tensor(uint16)",
            "tensor(bool)"
          ],
          "description": "Input tensor can be of arbitrary type.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int64)"
          ],
          "description": "Constrains output to int64 tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "Sigmoid",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "Sigmoid takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the sigmoid function, y = 1 / (1 + exp(-x)), is applied to the\ntensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sigmoid',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = 1.0 / (1.0 + np.exp(np.negative(x)))  # expected output [0.26894143, 0.5, 0.7310586]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sigmoid_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = 1.0 / (1.0 + np.exp(np.negative(x)))\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sigmoid')",
          "summary": "sigmoid"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sigmoid",
    "schema": {
      "category": "Activation",
      "description": "Sigmoid takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the sigmoid function, y = 1 / (1 + exp(-x)), is applied to the\ntensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sigmoid',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = 1.0 / (1.0 + np.exp(np.negative(x)))  # expected output [0.26894143, 0.5, 0.7310586]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sigmoid_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = 1.0 / (1.0 + np.exp(np.negative(x)))\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sigmoid')",
          "summary": "sigmoid"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Size",
    "schema": {
      "description": "Takes a tensor as input and outputs a int64 scalar that equals to the total number of elements of the input tensor.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Size',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([\n    [1, 2, 3],\n    [4, 5, 6],\n]).astype(np.float32)\ny = np.array(6).astype(np.int64)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_size_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.array(x.size).astype(np.int64)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_size')",
          "summary": "size"
        }
      ],
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Total number of elements of the input tensor",
          "name": "size",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)",
            "tensor(int8)",
            "tensor(int16)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(uint8)",
            "tensor(uint16)",
            "tensor(bool)"
          ],
          "description": "Input tensor can be of arbitrary type.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "int64"
          ],
          "description": "Constrains output to int64 scalar.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "Slice",
    "schema": {
      "attributes": [
        {
          "description": "Axes that `starts` and `ends` apply to. It's optional. If not present, will be treated as [0, 1, ..., len(`starts`) - 1].",
          "name": "axes",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "Ending indices (exclusive) of corresponding axis in axes`",
          "name": "ends",
          "required": true,
          "type": "int[]"
        },
        {
          "description": "Starting indices of corresponding axis in `axes`",
          "name": "starts",
          "required": true,
          "type": "int[]"
        }
      ],
      "category": "Tensor",
      "description": "Produces a slice of the input tensor along multiple axes. Similar to numpy:\nhttps://docs.scipy.org/doc/numpy/reference/arrays.indexing.html\n\nSlices uses `axes`, `starts` and `ends` attributes to specify the start and end\ndimension for each axis in the list of axes, it uses this information to\nslice the input `data` tensor. If a negative value is passed for any of the\nstart or end indices, it represent number of elements before the end of that\ndimension. If the value passed to start or end is larger than the `n` (the\nnumber of elements in this dimension), it represents `n`. For slicing to the\nend of a dimension with unknown size, it is recommended to pass in `INT_MAX`.\nIf `axes` are omitted, they are set to `[0, ..., ndim-1]`.\n\nExample 1:\n\n  data = [\n      [1, 2, 3, 4],\n      [5, 6, 7, 8],\n  ]\n  axes = [0, 1]\n  starts = [1, 0]\n  ends = [2, 3]\n\n  result = [\n      [5, 6, 7],\n  ]\n\n\nExample 2:\n\n  data = [\n      [1, 2, 3, 4],\n      [5, 6, 7, 8],\n  ]\n  starts = [0, 1]\n  ends = [-1, 1000]\n\n  result = [\n      [2, 3, 4],\n  ]\n\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Slice',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[0, 1],\n    starts=[0, 0],\n    ends=[3, 10],\n)\n\nx = np.random.randn(20, 10, 5).astype(np.float32)\ny = x[0:3, 0:10]\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_slice')",
          "summary": "slice"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Slice',\n    inputs=['x'],\n    outputs=['y'],\n    starts=[0, 0, 3],\n    ends=[20, 10, 4],\n)\n\nx = np.random.randn(20, 10, 5).astype(np.float32)\ny = x[:, :, 3:4]\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_slice_default_axes')",
          "summary": "slice_default_axes"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Slice',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[1],\n    starts=[1],\n    ends=[1000],\n)\n\nx = np.random.randn(20, 10, 5).astype(np.float32)\ny = x[:, 1:1000]\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_slice_end_out_of_bounds')",
          "summary": "slice_end_out_of_bounds"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Slice',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[1],\n    starts=[0],\n    ends=[-1],\n)\n\nx = np.random.randn(20, 10, 5).astype(np.float32)\ny = x[:, 0:-1]\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_slice_neg')",
          "summary": "slice_neg"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Slice',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[1],\n    starts=[1000],\n    ends=[1000],\n)\n\nx = np.random.randn(20, 10, 5).astype(np.float32)\ny = x[:, 1000:1000]\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_slice_start_out_of_bounds')",
          "summary": "slice_start_out_of_bounds"
        }
      ],
      "inputs": [
        {
          "description": "Tensor of data to extract slices from.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Sliced data tensor.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Softmax",
    "schema": {
      "attributes": [
        {
          "description": "(int) default to 1; describes the axis of the inputs when coerced to 2D; defaults to one because the 0th axis most likely describes the batch_size",
          "name": "axis",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Activation",
      "description": "The operator computes the softmax (normalized exponential) values for each layer in the batch\n of the given input. The input is a 2-D tensor (Tensor<float>) of size\n(batch_size x input_feature_dimensions). The output tensor has the same shape\nand contains the softmax values of the corresponding input.\n\nX does not need to explicitly be a 2D vector; rather, it will be\ncoerced into one. For an arbitrary n-dimensional tensor\nX \\in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is\nthe axis provided, then X will be coerced into a 2-dimensional tensor with\ndimensions [a_0 * ... * a_{k-1}, a_k * ... * a_{n-1}]. For the default\ncase where axis=1, this means the X tensor will be coerced into a 2D tensor\nof dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.\nIn this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.\nEach of these dimensions must be matched correctly, or else the operator\nwill throw errors.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nx = np.array([[-1, 0, 1]]).astype(np.float32)\n# expected output [[0.09003058, 0.24472848, 0.66524094]]\ny = np.exp(x) / np.sum(np.exp(x), axis=1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_example')",
          "summary": "softmax"
        },
        {
          "code": "def softmax_2d(x):\n    max_x = np.max(x, axis=1).reshape((-1, 1))\n    exp_x = np.exp(x - max_x)\n    return exp_x / np.sum(exp_x, axis=1).reshape((-1, 1))\n\nx = np.array([[0, 1, 2, 3], [10000, 10001, 10002, 10003]]).astype(np.float32)\n# expected output [[0.0320586, 0.08714432, 0.23688284, 0.64391428],\n#                 [0.0320586, 0.08714432, 0.23688284, 0.64391428]]\ny = softmax_2d(x)\n\nnode = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_large_number')\n\nx = np.abs(np.random.randn(3, 4, 5).astype(np.float32))\nnode = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=0,\n)\ny = softmax_2d(x.reshape(1, 60)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_axis_0')\n\nnode = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=1,\n)\ny = softmax_2d(x.reshape(3, 20)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_axis_1')\n\n# default axis is 1\nnode = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_default_axis')\n\nnode = onnx.helper.make_node(\n    'Softmax',\n    inputs=['x'],\n    outputs=['y'],\n    axis=2,\n)\ny = softmax_2d(x.reshape(12, 5)).reshape(3, 4, 5)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softmax_axis_2')",
          "summary": "softmax_axis"
        }
      ],
      "inputs": [
        {
          "description": "The input tensor that's coerced into a 2D matrix of size (NxD) as described above.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output values with the same shape as input tensor.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Softplus",
    "schema": {
      "category": "Activation",
      "description": "Softplus takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the softplus function, y = ln(exp(x) + 1), is applied to\nthe tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Softplus',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.log(np.exp(x) + 1)  # expected output [0.31326166, 0.69314718, 1.31326163]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softplus_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.log(np.exp(x) + 1)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softplus')",
          "summary": "softplus"
        }
      ],
      "inputs": [
        {
          "description": "1D input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "1D input tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Softsign",
    "schema": {
      "category": "Activation",
      "description": "Calculates the softsign (x/(1+|x|)) of the given input tensor element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Softsign',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.array([-0.5, 0, 0.5]).astype(np.float32)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softsign_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = x / (1 + np.abs(x))\nexpect(node, inputs=[x], outputs=[y],\n       name='test_softsign')",
          "summary": "softsign"
        }
      ],
      "inputs": [
        {
          "description": "1-D input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The softsign (x/(1+|x|)) values of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "SpaceToDepth",
    "schema": {
      "attributes": [
        {
          "description": "Blocks of [blocksize, blocksize] are moved.",
          "name": "blocksize",
          "required": false,
          "type": "int"
        }
      ],
      "description": "SpaceToDepth rearranges blocks of spatial data into depth. More specifically,\nthis op outputs a copy of the input tensor where values from the height and width dimensions\nare moved to the depth dimension.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor of [N,C,H,W], where N is the batch axis, C is the channel or depth, H is the height and W is the width.",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of [N, C * blocksize * blocksize, H/blocksize, W/blocksize].",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Split",
    "schema": {
      "attributes": [
        {
          "description": "Which axis to split on",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "length of each output",
          "name": "split",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Tensor",
      "description": "Split a tensor into a list of tensors, along the specified\n'axis'. The lengths of the split can be specified using argument 'axis' or\noptional second input blob to the operator. Otherwise, the tensor is split\nto equal sized parts.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The tensor to split",
          "name": "input",
          "type": "T"
        },
        {
          "description": "Optional list of output lengths (see also arg 'split')",
          "name": "split",
          "option": "optional",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 2147483647,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "One or more outputs forming list of tensors after splitting",
          "name": "outputs...",
          "option": "variadic",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Split",
    "schema": {
      "attributes": [
        {
          "description": "Which axis to split on",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "length of each output",
          "name": "split",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Tensor",
      "description": "Split a tensor into a list of tensors, along the specified\n'axis'. Lengths of the parts can be specified using argument 'split'.\nOtherwise, the tensor is split to equal sized parts.\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "The tensor to split",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 2147483647,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "One or more outputs forming list of tensors after splitting",
          "name": "outputs",
          "option": "variadic",
          "type": "T"
        }
      ],
      "since_version": 2,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sqrt",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Square root takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the square root is, y = x^0.5, is applied to\nthe tensor elementwise. If x is negative, then it will return NaN.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sqrt',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([1, 4, 9]).astype(np.float32)\ny = np.sqrt(x)  # expected output [1., 2., 3.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sqrt_example')\n\nx = np.abs(np.random.randn(3, 4, 5).astype(np.float32))\ny = np.sqrt(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sqrt')",
          "summary": "sqrt"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sqrt",
    "schema": {
      "description": "Square root takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the square root is, y = x^0.5, is applied to\nthe tensor elementwise. If x is negative, then it will return NaN.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sqrt',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([1, 4, 9]).astype(np.float32)\ny = np.sqrt(x)  # expected output [1., 2., 3.]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sqrt_example')\n\nx = np.abs(np.random.randn(3, 4, 5).astype(np.float32))\ny = np.sqrt(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_sqrt')",
          "summary": "sqrt"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Squeeze",
    "schema": {
      "attributes": [
        {
          "description": "List of positive integers, indicate the dimensions to squeeze.",
          "name": "axes",
          "required": true,
          "type": "int[]"
        }
      ],
      "description": "Remove single-dimensional entries from the shape of a tensor.\nTakes a  parameter `axes` with a list of axes to squeeze.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Squeeze',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[0],\n)\nx = np.random.randn(1, 3, 4, 5).astype(np.float32)\ny = np.squeeze(x, axis=0)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_squeeze')",
          "summary": "squeeze"
        }
      ],
      "inputs": [
        {
          "description": "Tensors with at least max(dims) dimensions.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reshaped tensor with same data as input.",
          "name": "squeezed",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sub",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        },
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Performs element-wise binary subtraction (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sub',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([3, 2, 1]).astype(np.float32)\nz = x - y  # expected output [-2., 0., 2.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = x - y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub')",
          "summary": "sub"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Sub',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = x - y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub_bcast')",
          "summary": "sub_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sub",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions. See doc for details.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Pass 1 to enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "description": "Performs element-wise binary subtraction (with limited broadcast support).\n\nIf necessary the right-hand-side argument will be broadcasted to match the\nshape of left-hand-side argument. When broadcasting is specified, the second\ntensor can either be of size 1 (a scalar value), or having its shape as a\ncontiguous subset of the first tensor's shape. The starting of the mutually\nequal shape is specified by the argument \"axis\", and if it is not set, suffix\nmatching is assumed. 1-dim expansion doesn't work yet.\n\nFor example, the following tensor shapes are supported (with broadcast=1):\n\n  shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar\n  shape(A) = (2, 3, 4, 5), shape(B) = (5,)\n  shape(A) = (2, 3, 4, 5), shape(B) = (4, 5)\n  shape(A) = (2, 3, 4, 5), shape(B) = (3, 4), with axis=1\n  shape(A) = (2, 3, 4, 5), shape(B) = (2), with axis=0\n\nAttribute `broadcast=1` needs to be passed to enable broadcasting.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Sub',\n    inputs=['x', 'y'],\n    outputs=['z'],\n)\n\nx = np.array([1, 2, 3]).astype(np.float32)\ny = np.array([3, 2, 1]).astype(np.float32)\nz = x - y  # expected output [-2., 0., 2.]\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(3, 4, 5).astype(np.float32)\nz = x - y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub')",
          "summary": "sub"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Sub',\n    inputs=['x', 'y'],\n    outputs=['z'],\n    broadcast=1,\n)\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.random.randn(5).astype(np.float32)\nz = x - y\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_sub_bcast')",
          "summary": "sub_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "First operand, should share the type with the second operand.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Second operand. With broadcasting can be of smaller size than A. If broadcasting is disabled it should be of the same size.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result, has same dimensions and type as A",
          "name": "C",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sum",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "description": "Element-wise sum of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 0, 2]).astype(np.float32)\ndata_1 = np.array([1, 3, 4]).astype(np.float32)\ndata_2 = np.array([2, 6, 6]).astype(np.float32)\nresult = np.array([6, 9, 12]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_sum_example')\n\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_sum_one_input')\n\nresult = np.add(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_sum_two_inputs')",
          "summary": "sum"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Sum.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "sum",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Sum",
    "schema": {
      "description": "Element-wise sum of each of the input tensors. All inputs and outputs must\nhave the same shape and data type.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "data_0 = np.array([3, 0, 2]).astype(np.float32)\ndata_1 = np.array([1, 3, 4]).astype(np.float32)\ndata_2 = np.array([2, 6, 6]).astype(np.float32)\nresult = np.array([6, 9, 12]).astype(np.float32)\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0', 'data_1', 'data_2'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1, data_2], outputs=[result],\n       name='test_sum_example')\n\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0], outputs=[data_0],\n       name='test_sum_one_input')\n\nresult = np.add(data_0, data_1)\nnode = onnx.helper.make_node(\n    'Sum',\n    inputs=['data_0', 'data_1'],\n    outputs=['result'],\n)\nexpect(node, inputs=[data_0, data_1], outputs=[result],\n       name='test_sum_two_inputs')",
          "summary": "sum"
        }
      ],
      "inputs": [
        {
          "description": "List of tensors for Sum.",
          "name": "data_0",
          "option": "variadic",
          "type": "T"
        }
      ],
      "max_input": 2147483647,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor. Same dimension as inputs.",
          "name": "sum",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Tanh",
    "schema": {
      "attributes": [
        {
          "description": "legacy optimization attribute.",
          "name": "consumed_inputs",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Activation",
      "description": "Calculates the hyperbolic tangent of the given input tensor element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Tanh',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.tanh(x)  # expected output [-0.76159418, 0., 0.76159418]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_tanh_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.tanh(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_tanh')",
          "summary": "tanh"
        }
      ],
      "inputs": [
        {
          "description": "1-D input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The hyperbolic tangent values of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Tanh",
    "schema": {
      "category": "Activation",
      "description": "Calculates the hyperbolic tangent of the given input tensor element-wise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Tanh',\n    inputs=['x'],\n    outputs=['y'],\n)\n\nx = np.array([-1, 0, 1]).astype(np.float32)\ny = np.tanh(x)  # expected output [-0.76159418, 0., 0.76159418]\nexpect(node, inputs=[x], outputs=[y],\n       name='test_tanh_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.tanh(x)\nexpect(node, inputs=[x], outputs=[y],\n       name='test_tanh')",
          "summary": "tanh"
        }
      ],
      "inputs": [
        {
          "description": "1-D input tensor",
          "name": "input",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The hyperbolic tangent values of the input tensor computed element-wise",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 6,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "ThresholdedRelu",
    "schema": {
      "attributes": [
        {
          "description": "Threshold value",
          "name": "alpha",
          "required": false,
          "type": "float"
        }
      ],
      "category": "Activation",
      "description": "ThresholdedRelu takes one input data (Tensor<T>) and produces one output data\n(Tensor<T>) where the rectified linear function, y = x for x > alpha, y = 0 otherwise,\nis applied to the tensor elementwise.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "default_alpha = 1.0\nnode = onnx.helper.make_node(\n    'ThresholdedRelu',\n    inputs=['x'],\n    outputs=['y']\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, default_alpha, np.inf)\ny[y == default_alpha] = 0\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_thresholdedrelu_default')",
          "summary": "default"
        },
        {
          "code": "alpha = 2.0\nnode = onnx.helper.make_node(\n    'ThresholdedRelu',\n    inputs=['x'],\n    outputs=['y'],\n    alpha=alpha\n)\n\nx = np.array([-1.5, 0., 1.2, 2.0, 2.2]).astype(np.float32)\ny = np.clip(x, alpha, np.inf)  # expected output [0., 0., 0., 0., 2.2]\ny[y == alpha] = 0\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_thresholdedrelu_example')\n\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.clip(x, alpha, np.inf)\ny[y == alpha] = 0\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_thresholdedrelu')",
          "summary": "thresholdedrelu"
        }
      ],
      "inputs": [
        {
          "description": "Input tensor",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Tile",
    "schema": {
      "category": "Shape",
      "description": "Repeat the elements of a tensor along an axis.",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "Input tensor of any shape.",
          "name": "input",
          "type": "T"
        },
        {
          "description": "Number of repeated copies to make of the input tensor.",
          "name": "tiles",
          "type": "T"
        },
        {
          "description": "Axis along which to repeat.",
          "name": "axis",
          "type": "T"
        }
      ],
      "max_input": 3,
      "max_output": 1,
      "min_input": 3,
      "min_output": 1,
      "outputs": [
        {
          "description": "Output tensor of same shape and type as input.",
          "name": "output",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "TopK",
    "schema": {
      "attributes": [
        {
          "description": "Dimension on which to do the sort. Default -1, which indicates the last axis",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Number of top elements to retrieve",
          "name": "k",
          "required": true,
          "type": "int"
        }
      ],
      "description": "Retrieve the top-K elements along a specified axis. Given an input tensor of\nshape [a_1, a_2, ..., a_n, r] and integer argument k, return two outputs:\n  -Value tensor of shape [a_1, a_2, ..., a_{axis-1}, k, a_{axis+1}, ... a_n]\n    which contains the values of the top k elements along the specified axis\n  -Index tensor of shape [a_1, a_2, ..., a_{axis-1}, k, a_{axis+1}, ... a_n] which\n   contains the indices of the top k elements (original indices from the input\n   tensor).\n\nGiven two equivalent values, this operator uses the indices along the axis  as\n a tiebreaker. That is, the element with the lower index will appear first.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'TopK',\n    inputs=['x'],\n    outputs=['values', 'indices'],\n    k=3\n)\nX = np.array([\n    [0, 1, 2, 3],\n    [4, 5, 6, 7],\n    [8, 9, 10, 11],\n], dtype=np.float32)\nvalues_ref = np.array([\n    [3, 2, 1],\n    [7, 6, 5],\n    [11, 10, 9],\n])\nindices_ref = np.array([\n    [3, 2, 1],\n    [3, 2, 1],\n    [3, 2, 1],\n], dtype=np.int32)\n\nexpect(node, inputs=[X], outputs=[values_ref, indices_ref],\n       name='test_top_k')",
          "summary": "top_k"
        }
      ],
      "inputs": [
        {
          "description": "Tensor of shape [a_1, a_2, ..., a_n, r]",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 2,
      "outputs": [
        {
          "description": "Tensor of shape [a_1, a_2, ..., a_{axis-1}, k, a_{axis+1}, ... a_n] containing top K values from the input tensor",
          "name": "Values",
          "type": "T"
        },
        {
          "description": "Tensor of shape [a_1, a_2, ..., a_{axis-1}, k, a_{axis+1}, ... a_n] containing the corresponding input tensor indices for the top K values.",
          "name": "Indices",
          "type": "I"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": "Constrain index tensor to integral types",
          "type_param_str": "I"
        }
      ]
    }
  },
  {
    "name": "Transpose",
    "schema": {
      "attributes": [
        {
          "description": "A list of integers. By default, reverse the dimensions, otherwise permute the axes according to the values given.",
          "name": "perm",
          "required": false,
          "type": "int[]"
        }
      ],
      "category": "Shape",
      "description": "Transpose the input tensor similar to numpy.transpose. For example, when\nperm=(1, 0, 2), given an input tensor of shape (1, 2, 3), the output shape\nwill be (2, 1, 3).\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "shape = (2, 3, 4)\ndata = np.random.random_sample(shape).astype(np.float32)\npermutations = list(itertools.permutations(np.arange(len(shape))))\n\nfor i in range(len(permutations)):\n    node = onnx.helper.make_node(\n        'Transpose',\n        inputs=['data'],\n        outputs=['transposed'],\n        perm=permutations[i]\n    )\n    transposed = np.transpose(data, permutations[i])\n    expect(node, inputs=[data], outputs=[transposed],\n           name='test_transpose_all_permutations_' + str(i))",
          "summary": "all_permutations"
        },
        {
          "code": "shape = (2, 3, 4)\ndata = np.random.random_sample(shape).astype(np.float32)\n\nnode = onnx.helper.make_node(\n    'Transpose',\n    inputs=['data'],\n    outputs=['transposed']\n)\n\ntransposed = np.transpose(data)\nexpect(node, inputs=[data], outputs=[transposed],\n       name='test_transpose_default')",
          "summary": "default"
        }
      ],
      "inputs": [
        {
          "description": "An input tensor.",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Transposed output.",
          "name": "transposed",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "TreeEnsembleClassifier",
    "schema": {
      "attributes": [
        {
          "description": "base values for classification, added to final class score, size must be the same as classes or can be left unassigned (assumed 0)",
          "name": "base_values",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "index of the class list that this weight is for",
          "name": "class_ids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "node id that this weight is for",
          "name": "class_nodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "tree that this node is in",
          "name": "class_treeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "the weight for the class in class_id",
          "name": "class_weights",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "class labels if using int labels",
          "name": "classlabels_int64s",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "class labels if using string labels",
          "name": "classlabels_strings",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "child node if expression is false",
          "name": "nodes_falsenodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "feature id for this node",
          "name": "nodes_featureids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "",
          "name": "nodes_hitrates",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "for each node, decide if the value is missing (nan) then use true branch, this field can be left unset and will assume false for all nodes",
          "name": "nodes_missing_value_tracks_true",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "enum of behavior for this node 'BRANCH_LEQ', 'BRANCH_LT', 'BRANCH_GTE', 'BRANCH_GT', 'BRANCH_EQ', 'BRANCH_NEQ', 'LEAF'",
          "name": "nodes_modes",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "node id for this node, node ids may restart at zero for each tree (but not required).",
          "name": "nodes_nodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "tree id for this node",
          "name": "nodes_treeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "child node if expression is true",
          "name": "nodes_truenodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "thresholds to do the splitting on for this node.",
          "name": "nodes_values",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "post eval transform for score, enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        }
      ],
      "description": "Tree Ensemble classifier.  Returns the top class for each input in N.\n    All args with nodes_ are fields of a tuple of tree nodes, and\n    it is assumed they are the same length, and an index i will decode the\n    tuple across these inputs.  Each node id can appear only once\n    for each tree id.\n    All fields prefixed with class_ are tuples of votes at the leaves.\n    A leaf may have multiple votes, where each vote is weighted by\n    the associated class_weights index.\n    It is expected that either classlabels_strings or classlabels_int64s\n    will be passed and the class_ids are an index into this list.\n    Mode enum is BRANCH_LEQ, BRANCH_LT, BRANCH_GTE, BRANCH_GT, BRANCH_EQ, BRANCH_NEQ, LEAF\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Input N,F",
          "name": "X",
          "type": "T1"
        }
      ],
      "max_input": 1,
      "max_output": 2,
      "min_input": 1,
      "min_output": 2,
      "outputs": [
        {
          "description": "N, Top class for each point",
          "name": "Y",
          "type": "T2"
        },
        {
          "description": "N,E the class score for each class, for each point",
          "name": "Z",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T1"
        },
        {
          "allowed_type_strs": [
            "tensor(string)",
            "tensor(int64)"
          ],
          "description": " allowed types.",
          "type_param_str": "T2"
        }
      ]
    }
  },
  {
    "name": "TreeEnsembleRegressor",
    "schema": {
      "attributes": [
        {
          "description": " enum, how to aggregate leaf values within a target, AVERAGE,SUM,MIN,MAX",
          "name": "aggregate_function",
          "required": false,
          "type": "string"
        },
        {
          "description": "base values for regression, added to final score, size must be the same as n_outputs or can be left unassigned (assumed 0)",
          "name": "base_values",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "total number of targets",
          "name": "n_targets",
          "required": false,
          "type": "int"
        },
        {
          "description": "child node if expression is false",
          "name": "nodes_falsenodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "feature id for this node",
          "name": "nodes_featureids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "popularity of the node, used for performance and may be omitted",
          "name": "nodes_hitrates",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "for each node, decide if the value is missing (nan) then use true branch, this field can be left unset and will assume false for all nodes",
          "name": "nodes_missing_value_tracks_true",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "enum of behavior for this node as enum of BRANCH_LEQ, BRANCH_LT, BRANCH_GTE, BRANCH_GT, BRANCH_EQ, BRANCH_NEQ, LEAF",
          "name": "nodes_modes",
          "required": false,
          "type": "string[]"
        },
        {
          "description": "node id for this node, node ids must restart at zero for each tree and increase sequentially.",
          "name": "nodes_nodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "tree id for this node",
          "name": "nodes_treeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "child node if expression is true",
          "name": "nodes_truenodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "thresholds to do the splitting on for this node.",
          "name": "nodes_values",
          "required": false,
          "type": "float[]"
        },
        {
          "description": "post eval transform for score, enum NONE, SOFTMAX, LOGISTIC, SOFTMAX_ZERO, PROBIT",
          "name": "post_transform",
          "required": false,
          "type": "string"
        },
        {
          "description": "index of the class list that this weight is for",
          "name": "target_ids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "node id that this weight is for",
          "name": "target_nodeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "tree that this node is in",
          "name": "target_treeids",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "the weight for the class in target_id",
          "name": "target_weights",
          "required": false,
          "type": "float[]"
        }
      ],
      "description": "Tree Ensemble regressor.  Returns the regressed values for each input in N.\n    All args with nodes_ are fields of a tuple of tree nodes, and\n    it is assumed they are the same length, and an index i will decode the\n    tuple across these inputs.  Each node id can appear only once\n    for each tree id.\n    All fields prefixed with target_ are tuples of votes at the leaves.\n    A leaf may have multiple votes, where each vote is weighted by\n    the associated target_weights index.\n    All trees must have their node ids start at 0 and increment by 1.\n    Mode enum is BRANCH_LEQ, BRANCH_LT, BRANCH_GTE, BRANCH_GT, BRANCH_EQ, BRANCH_NEQ, LEAF\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "Input N,F",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "N classes",
          "name": "Y",
          "type": "tensor(float)"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float)",
            "tensor(double)",
            "tensor(int64)",
            "tensor(int32)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Unsqueeze",
    "schema": {
      "attributes": [
        {
          "description": "List of positive integers, indicate the dimensions to be inserted",
          "name": "axes",
          "required": true,
          "type": "int[]"
        }
      ],
      "description": "Insert single-dimensional entries to the shape of a tensor.\nTakes one required argument `axes`, a list of dimensions that will be inserted.\nDimension indices in `axes` are as seen in the output tensor. For example:\n\n  Given a tensor such that tensor with shape [3, 4, 5], then\n  Unsqueeze(tensor, axes=[0, 4]) has shape [1, 3, 4, 5, 1]\n\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Unsqueeze',\n    inputs=['x'],\n    outputs=['y'],\n    axes=[0],\n)\nx = np.random.randn(3, 4, 5).astype(np.float32)\ny = np.expand_dims(x, axis=0)\n\nexpect(node, inputs=[x], outputs=[y],\n       name='test_unsqueeze')",
          "summary": "squeeze"
        }
      ],
      "inputs": [
        {
          "description": "Original tensor",
          "name": "data",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "Reshaped tensor with same data as input.",
          "name": "expanded",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain input and output types to float tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Upsample",
    "schema": {
      "attributes": [
        {
          "description": "The scale along height dimension. It takes value greater than or equal to 1.",
          "name": "height_scale",
          "required": true,
          "type": "float"
        },
        {
          "description": "Two interpolation modes: nearest(default), bilinear",
          "name": "mode",
          "required": false,
          "type": "string"
        },
        {
          "description": "The scale along width dimension. It takes value greater than or equal to 1.",
          "name": "width_scale",
          "required": true,
          "type": "float"
        }
      ],
      "description": "Upsample the input tensor.\nThe width and height of the output tensor are:\n  output_width = floor(input_width * width_scale),\n  output_height = floor(input_height * height_scale).\n\nExample:\n  Given `data` tensor, width_scale, height_scale, mode,\n  Upsample the input 4-D tensor in nearest mode:\n\n  data = [[[\n      [1, 2],\n      [3, 4]\n  ]]]\n  width_scale = 2\n  height_scale = 2\n  mode = \"nearest\"\n\n  output = [[[\n      [1, 1, 2, 2],\n      [1, 1, 2, 2],\n      [3, 3, 4, 4],\n      [3, 3, 4, 4]\n  ]]]\n",
      "domain": "ai.onnx",
      "inputs": [
        {
          "description": "4-D tensor, [N,C,H,W]",
          "name": "X",
          "type": "T"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "4-D tensor after resizing, [N,C,H,W]",
          "name": "Y",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "experimental",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)",
            "tensor(int32)",
            "tensor(int64)",
            "tensor(float16)",
            "tensor(float)",
            "tensor(double)"
          ],
          "description": "Constrain output types to bool, int32, int64, float16, float, double tensors.",
          "type_param_str": "T"
        }
      ]
    }
  },
  {
    "name": "Xor",
    "schema": {
      "attributes": [
        {
          "description": "If set, defines the broadcast dimensions.",
          "name": "axis",
          "required": false,
          "type": "int"
        },
        {
          "description": "Enable broadcasting",
          "name": "broadcast",
          "required": false,
          "type": "int"
        }
      ],
      "category": "Logic",
      "description": "Returns the tensor resulted from performing the `xor` logical operation\nelementwise on the input tensors `A` and `B`.\n\nIf broadcasting is enabled, the right-hand-side argument will be broadcasted\nto match the shape of left-hand-side argument. See the doc of `Add` for a\ndetailed description of the broadcasting rules.\n",
      "domain": "ai.onnx",
      "examples": [
        {
          "code": "node = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n)\n\n# 2d\nx = (np.random.randn(3, 4) > 0).astype(np.bool)\ny = (np.random.randn(3, 4) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor2d')\n\n# 3d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor3d')\n\n# 4d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor4d')",
          "summary": "xor"
        },
        {
          "code": "x = (np.random.randn(5, 5, 5, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\n\nnode = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n    broadcast=1,\n    axis=0,\n)\n\nz = np.logical_xor(x, y[:, np.newaxis, np.newaxis, np.newaxis])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_axis0')\n\nnode = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n    broadcast=1,\n    axis=1,\n)\n\nz = np.logical_xor(x, y[:, np.newaxis, np.newaxis, ])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_axis1')\n\nnode = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n    broadcast=1,\n    axis=2,\n)\n\nz = np.logical_xor(x, y[:, np.newaxis, ])\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_axis2')\n\nnode = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n    broadcast=1,\n    axis=3,\n)\n\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_axis3')",
          "summary": "xor_axis"
        },
        {
          "code": "node = onnx.helper.make_node(\n    'Xor',\n    inputs=['x', 'y'],\n    outputs=['xor'],\n    broadcast=1,\n)\n\n# 3d vs 1d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(5) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_bcast3v1d')\n\n# 3d vs 2d\nx = (np.random.randn(3, 4, 5) > 0).astype(np.bool)\ny = (np.random.randn(4, 5) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_bcast3v2d')\n\n# 4d vs 2d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(5, 6) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_bcast4v2d')\n\n# 4d vs 3d\nx = (np.random.randn(3, 4, 5, 6) > 0).astype(np.bool)\ny = (np.random.randn(4, 5, 6) > 0).astype(np.bool)\nz = np.logical_xor(x, y)\nexpect(node, inputs=[x, y], outputs=[z],\n       name='test_xor_bcast4v3d')",
          "summary": "xor_broadcast"
        }
      ],
      "inputs": [
        {
          "description": "Left input tensor for the logical operator.",
          "name": "A",
          "type": "T"
        },
        {
          "description": "Right input tensor for the logical operator.",
          "name": "B",
          "type": "T"
        }
      ],
      "max_input": 2,
      "max_output": 1,
      "min_input": 2,
      "min_output": 1,
      "outputs": [
        {
          "description": "Result tensor.",
          "name": "C",
          "type": "T1"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains input to boolean tensor.",
          "type_param_str": "T"
        },
        {
          "allowed_type_strs": [
            "tensor(bool)"
          ],
          "description": "Constrains output to boolean tensor.",
          "type_param_str": "T1"
        }
      ]
    }
  },
  {
    "name": "ZipMap",
    "schema": {
      "attributes": [
        {
          "description": "keys if using int keys",
          "name": "classlabels_int64s",
          "required": false,
          "type": "int[]"
        },
        {
          "description": "keys if using string keys",
          "name": "classlabels_strings",
          "required": false,
          "type": "string[]"
        }
      ],
      "description": "Makes a map from the input and the attributes.\n    Assumes input 0 are the values, and the keys are specified by the attributes.\n    Must provide keys in either classlabels_strings or classlabels_int64s (but not both).\n    Input 0 may have a batch size larger than 1,\n    but each input in the batch must be the size of the keys specified by the attributes.\n    The order of the input and attributes determines the key-value mapping.\n",
      "domain": "ai.onnx.ml",
      "inputs": [
        {
          "description": "The input values",
          "name": "X",
          "type": "tensor(float)"
        }
      ],
      "max_input": 1,
      "max_output": 1,
      "min_input": 1,
      "min_output": 1,
      "outputs": [
        {
          "description": "The output map",
          "name": "Z",
          "type": "T"
        }
      ],
      "since_version": 1,
      "support_level": "common",
      "type_constraints": [
        {
          "allowed_type_strs": [
            "map(string, float)",
            "map(int64, float)"
          ],
          "description": " allowed types.",
          "type_param_str": "T"
        }
      ]
    }
  }
]
