{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
module TensorFlow.GenOps.Core where

import Data.ByteString (ByteString)
import Data.Complex (Complex)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word8, Word16)
import Lens.Family2 ((.~), (&))
import TensorFlow.Build
import TensorFlow.BuildOp
import TensorFlow.Output (ResourceHandle)
import TensorFlow.Tensor
import TensorFlow.Types

-- | Receives the named tensor from send_device on recv_device.
--
-- _HostRecv requires its input on host memory whereas _Recv requires its
-- input on device memory.
_HostRecv :: forall tensor_type . (TensorType tensor_type) =>
             Data.Int.Int64 -- ^ __send_device_incarnation__: The current incarnation of send_device.
             -> Build (Tensor Value tensor_type) -- ^ __tensor__: The tensor to receive.
_HostRecv send_device_incarnation | eqLengthGuard [] =
    buildOp (opDef "_HostRecv"
             & opAttr "tensor_type" .~ tensorType (undefined :: tensor_type)
             & opAttr "send_device_incarnation" .~ send_device_incarnation)
        
{-
attr { name: "tensor_type" type: "type" }
attr {
  description: "The name of the tensor to receive."
  name: "tensor_name"
  type: "string"
}
attr {
  description: "The name of the device sending the tensor."
  name: "send_device"
  type: "string"
}
attr {
  description: "The current incarnation of send_device."
  name: "send_device_incarnation"
  type: "int"
}
attr {
  description: "The name of the device receiving the tensor."
  name: "recv_device"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If set to true, this indicates that the node was added\nto the graph as a result of a client-side feed or fetch of Tensor data,\nin which case the corresponding send or recv is expected to be managed\nlocally by the caller."
  name: "client_terminated"
  type: "bool"
}
output_arg {
  description: "The tensor to receive."
  name: "tensor"
  type_attr: "tensor_type"
}
-}

-- | Sends the named tensor from send_device to recv_device.
--
-- _HostSend requires its input on host memory whereas _Send requires its
-- input on device memory.
_HostSend :: forall v1 t . (TensorType t) =>
             Data.Int.Int64 -- ^ __send_device_incarnation__: The current incarnation of send_device.
             -> Tensor v1 t -- ^ __tensor__: The tensor to send.
             -> Build (ControlNode)
_HostSend send_device_incarnation tensor | eqLengthGuard [] =
    buildOp (opDef "_HostSend"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "send_device_incarnation" .~ send_device_incarnation)
        tensor
{-
attr { name: "T" type: "type" }
attr {
  description: "The name of the tensor to send."
  name: "tensor_name"
  type: "string"
}
attr {
  description: "The name of the device sending the tensor."
  name: "send_device"
  type: "string"
}
attr {
  description: "The current incarnation of send_device."
  name: "send_device_incarnation"
  type: "int"
}
attr {
  description: "The name of the device receiving the tensor."
  name: "recv_device"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If set to true, this indicates that the node was added\nto the graph as a result of a client-side feed or fetch of Tensor data,\nin which case the corresponding send or recv is expected to be managed\nlocally by the caller."
  name: "client_terminated"
  type: "bool"
}
input_arg {
  description: "The tensor to send." name: "tensor" type_attr: "T"
}
-}

-- | Receives the named tensor from send_device on recv_device.

_Recv :: forall tensor_type . (TensorType tensor_type) =>
         Data.Int.Int64 -- ^ __send_device_incarnation__: The current incarnation of send_device.
         -> Build (Tensor Value tensor_type) -- ^ __tensor__: The tensor to receive.
_Recv send_device_incarnation | eqLengthGuard [] =
    buildOp (opDef "_Recv"
             & opAttr "tensor_type" .~ tensorType (undefined :: tensor_type)
             & opAttr "send_device_incarnation" .~ send_device_incarnation)
        
{-
attr { name: "tensor_type" type: "type" }
attr {
  description: "The name of the tensor to receive."
  name: "tensor_name"
  type: "string"
}
attr {
  description: "The name of the device sending the tensor."
  name: "send_device"
  type: "string"
}
attr {
  description: "The current incarnation of send_device."
  name: "send_device_incarnation"
  type: "int"
}
attr {
  description: "The name of the device receiving the tensor."
  name: "recv_device"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If set to true, this indicates that the node was added\nto the graph as a result of a client-side feed or fetch of Tensor data,\nin which case the corresponding send or recv is expected to be managed\nlocally by the caller."
  name: "client_terminated"
  type: "bool"
}
output_arg {
  description: "The tensor to receive."
  name: "tensor"
  type_attr: "tensor_type"
}
-}

-- | Sends the named tensor from send_device to recv_device.

_Send :: forall v1 t . (TensorType t) =>
         Data.Int.Int64 -- ^ __send_device_incarnation__: The current incarnation of send_device.
         -> Tensor v1 t -- ^ __tensor__: The tensor to send.
         -> Build (ControlNode)
_Send send_device_incarnation tensor | eqLengthGuard [] =
    buildOp (opDef "_Send"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "send_device_incarnation" .~ send_device_incarnation)
        tensor
{-
attr { name: "T" type: "type" }
attr {
  description: "The name of the tensor to send."
  name: "tensor_name"
  type: "string"
}
attr {
  description: "The name of the device sending the tensor."
  name: "send_device"
  type: "string"
}
attr {
  description: "The current incarnation of send_device."
  name: "send_device_incarnation"
  type: "int"
}
attr {
  description: "The name of the device receiving the tensor."
  name: "recv_device"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If set to true, this indicates that the node was added\nto the graph as a result of a client-side feed or fetch of Tensor data,\nin which case the corresponding send or recv is expected to be managed\nlocally by the caller."
  name: "client_terminated"
  type: "bool"
}
input_arg {
  description: "The tensor to send." name: "tensor" type_attr: "T"
}
-}

-- | Does nothing. Only useful as a placeholder for control edges.

noOp :: ControlNode
noOp  | eqLengthGuard [] =
    buildOp (opDef "NoOp")
        
{-

-}

-- | A graph node which represents a return value of a function.

_Retval :: forall v1 t . (TensorType t) =>
           Data.Int.Int64 -- ^ __index__: This return value is the index-th return value of the function.
           -> Tensor v1 t -- ^ __input__: The return value.
           -> Build (ControlNode)
_Retval index input | eqLengthGuard [] =
    buildOp (opDef "_Retval"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "index" .~ index)
        input
{-
attr { name: "T" type: "type" }
attr {
  description: "This return value is the index-th return value of the function."
  has_minimum: true
  name: "index"
  type: "int"
}
input_arg {
  description: "The return value." name: "input" type_attr: "T"
}
-}

-- | A graph node which represents an argument to a function.

_Arg :: forall t . (TensorType t) =>
        Data.Int.Int64 -- ^ __index__: This argument is the index-th argument of the function.
        -> Build (Tensor Value t) -- ^ __output__: The argument.
_Arg index | eqLengthGuard [] =
    buildOp (opDef "_Arg"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "index" .~ index)
        
{-
attr { name: "T" type: "type" }
attr {
  description: "This argument is the index-th argument of the function."
  has_minimum: true
  name: "index"
  type: "int"
}
output_arg {
  description: "The argument." name: "output" type_attr: "T"
}
-}

-- | Quantized Batch normalization.
--
-- This op is deprecated and will be removed in the future. Prefer
-- `tf.nn.batch_normalization`.
quantizedBatchNormWithGlobalNormalization :: forall v1 v2 v3 v4 v5 v6 v7 v8 v9
                                             v10 v11 v12 v13 v14 v15 tinput
                                             out_type . (TensorType tinput,
                                                         OneOf '[Data.Int.Int16,
                                                                 Data.Int.Int32,
                                                                 Data.Word.Word16,
                                                                 Data.Word.Word8] tinput,
                                                         TensorType out_type,
                                                         OneOf '[Data.Int.Int16,
                                                                 Data.Int.Int32,
                                                                 Data.Word.Word16,
                                                                 Data.Word.Word8] out_type) =>
                                             Bool -- ^ __scale_after_normalization__: A bool indicating whether the resulted tensor
                                                  -- needs to be multiplied with gamma.
                                             -> Float -- ^ __variance_epsilon__: A small float number to avoid dividing by 0.
                                             -> Tensor v1 tinput -- ^ __t__: A 4D input Tensor.
                                             -> Tensor v2 Float -- ^ __t_min__: The value represented by the lowest quantized input.
                                             -> Tensor v3 Float -- ^ __t_max__: The value represented by the highest quantized input.
                                             -> Tensor v4 tinput -- ^ __m__: A 1D mean Tensor with size matching the last dimension of t.
                                                                 -- This is the first output from tf.nn.moments,
                                                                 -- or a saved moving average thereof.
                                             -> Tensor v5 Float -- ^ __m_min__: The value represented by the lowest quantized mean.
                                             -> Tensor v6 Float -- ^ __m_max__: The value represented by the highest quantized mean.
                                             -> Tensor v7 tinput -- ^ __v__: A 1D variance Tensor with size matching the last dimension of t.
                                                                 -- This is the second output from tf.nn.moments,
                                                                 -- or a saved moving average thereof.
                                             -> Tensor v8 Float -- ^ __v_min__: The value represented by the lowest quantized variance.
                                             -> Tensor v9 Float -- ^ __v_max__: The value represented by the highest quantized variance.
                                             -> Tensor v10 tinput -- ^ __beta__: A 1D beta Tensor with size matching the last dimension of t.
                                                                  -- An offset to be added to the normalized tensor.
                                             -> Tensor v11 Float -- ^ __beta_min__: The value represented by the lowest quantized offset.
                                             -> Tensor v12 Float -- ^ __beta_max__: The value represented by the highest quantized offset.
                                             -> Tensor v13 tinput -- ^ __gamma__: A 1D gamma Tensor with size matching the last dimension of t.
                                                                  -- If "scale_after_normalization" is true, this tensor will be multiplied
                                                                  -- with the normalized tensor.
                                             -> Tensor v14 Float -- ^ __gamma_min__: The value represented by the lowest quantized gamma.
                                             -> Tensor v15 Float -- ^ __gamma_max__: The value represented by the highest quantized gamma.
                                             -> (Tensor Value out_type,
                                                 Tensor Value Float,
                                                 Tensor Value Float)
                                             -- ^ (__result__, __result_min__, __result_max__)
                                             --
                                             -- * __result__
                                             --
                                             -- * __result_min__
                                             --
                                             -- * __result_max__
quantizedBatchNormWithGlobalNormalization scale_after_normalization
                                          variance_epsilon t t_min t_max m m_min
                                          m_max v v_min v_max beta beta_min
                                          beta_max gamma gamma_min
                                          gamma_max | eqLengthGuard [] =
    buildOp (opDef "QuantizedBatchNormWithGlobalNormalization"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type)
             & opAttr "scale_after_normalization" .~ scale_after_normalization
             & opAttr "variance_epsilon" .~ variance_epsilon)
        t t_min t_max m m_min m_max v v_min v_max beta beta_min beta_max gamma
        gamma_min gamma_max
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "out_type"
  type: "type"
}
attr {
  description: "A small float number to avoid dividing by 0."
  name: "variance_epsilon"
  type: "float"
}
attr {
  description: "A bool indicating whether the resulted tensor\nneeds to be multiplied with gamma."
  name: "scale_after_normalization"
  type: "bool"
}
input_arg {
  description: "A 4D input Tensor." name: "t" type_attr: "Tinput"
}
input_arg {
  description: "The value represented by the lowest quantized input."
  name: "t_min"
  type: DT_FLOAT
}
input_arg {
  description: "The value represented by the highest quantized input."
  name: "t_max"
  type: DT_FLOAT
}
input_arg {
  description: "A 1D mean Tensor with size matching the last dimension of t.\nThis is the first output from tf.nn.moments,\nor a saved moving average thereof."
  name: "m"
  type_attr: "Tinput"
}
input_arg {
  description: "The value represented by the lowest quantized mean."
  name: "m_min"
  type: DT_FLOAT
}
input_arg {
  description: "The value represented by the highest quantized mean."
  name: "m_max"
  type: DT_FLOAT
}
input_arg {
  description: "A 1D variance Tensor with size matching the last dimension of t.\nThis is the second output from tf.nn.moments,\nor a saved moving average thereof."
  name: "v"
  type_attr: "Tinput"
}
input_arg {
  description: "The value represented by the lowest quantized variance."
  name: "v_min"
  type: DT_FLOAT
}
input_arg {
  description: "The value represented by the highest quantized variance."
  name: "v_max"
  type: DT_FLOAT
}
input_arg {
  description: "A 1D beta Tensor with size matching the last dimension of t.\nAn offset to be added to the normalized tensor."
  name: "beta"
  type_attr: "Tinput"
}
input_arg {
  description: "The value represented by the lowest quantized offset."
  name: "beta_min"
  type: DT_FLOAT
}
input_arg {
  description: "The value represented by the highest quantized offset."
  name: "beta_max"
  type: DT_FLOAT
}
input_arg {
  description: "A 1D gamma Tensor with size matching the last dimension of t.\nIf \"scale_after_normalization\" is true, this tensor will be multiplied\nwith the normalized tensor."
  name: "gamma"
  type_attr: "Tinput"
}
input_arg {
  description: "The value represented by the lowest quantized gamma."
  name: "gamma_min"
  type: DT_FLOAT
}
input_arg {
  description: "The value represented by the highest quantized gamma."
  name: "gamma_max"
  type: DT_FLOAT
}
output_arg { name: "result" type_attr: "out_type" }
output_arg { name: "result_min" type: DT_FLOAT }
output_arg { name: "result_max" type: DT_FLOAT }
-}

-- | Computes Quantized Rectified Linear 6: `min(max(features, 0), 6)`

quantizedRelu6 :: forall v1 v2 v3 tinput out_type . (TensorType tinput,
                                                     OneOf '[Data.Int.Int16,
                                                             Data.Int.Int32,
                                                             Data.Word.Word16,
                                                             Data.Word.Word8] tinput,
                                                     TensorType out_type,
                                                     OneOf '[Data.Int.Int16,
                                                             Data.Int.Int32,
                                                             Data.Word.Word16,
                                                             Data.Word.Word8] out_type) =>
                  Tensor v1 tinput -- ^ __features__
                  -> Tensor v2 Float -- ^ __min_features__: The float value that the lowest quantized value represents.
                  -> Tensor v3 Float -- ^ __max_features__: The float value that the highest quantized value represents.
                  -> (Tensor Value out_type, Tensor Value Float,
                      Tensor Value Float)
                  -- ^ (__activations__, __min_activations__, __max_activations__)
                  --
                  -- * __activations__: Has the same output shape as "features".
                  --
                  -- * __min_activations__: The float value that the lowest quantized value represents.
                  --
                  -- * __max_activations__: The float value that the highest quantized value represents.
quantizedRelu6 features min_features max_features | eqLengthGuard [] =
    buildOp (opDef "QuantizedRelu6"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        features min_features max_features
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  default_value { type: DT_QUINT8 }
  name: "out_type"
  type: "type"
}
input_arg { name: "features" type_attr: "Tinput" }
input_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_features"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_features"
  type: DT_FLOAT
}
output_arg {
  description: "Has the same output shape as \"features\"."
  name: "activations"
  type_attr: "out_type"
}
output_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_activations"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_activations"
  type: DT_FLOAT
}
-}

-- | Adds Tensor 'bias' to Tensor 'input' for Quantized types.
--
-- Broadcasts the values of bias on dimensions 0..N-2 of 'input'.
quantizedBiasAdd :: forall v1 v2 v3 v4 v5 v6 t1 t2 out_type . (TensorType t1,
                                                               OneOf '[Data.Int.Int16,
                                                                       Data.Int.Int32,
                                                                       Data.Word.Word16,
                                                                       Data.Word.Word8] t1,
                                                               TensorType t2,
                                                               OneOf '[Data.Int.Int16,
                                                                       Data.Int.Int32,
                                                                       Data.Word.Word16,
                                                                       Data.Word.Word8] t2,
                                                               TensorType out_type,
                                                               OneOf '[Data.Int.Int16,
                                                                       Data.Int.Int32,
                                                                       Data.Word.Word16,
                                                                       Data.Word.Word8] out_type) =>
                    Tensor v1 t1 -- ^ __input__
                    -> Tensor v2 t2 -- ^ __bias__: A 1D bias Tensor with size matching the last dimension of 'input'.
                    -> Tensor v3 Float -- ^ __min_input__: The float value that the lowest quantized input value represents.
                    -> Tensor v4 Float -- ^ __max_input__: The float value that the highest quantized input value represents.
                    -> Tensor v5 Float -- ^ __min_bias__: The float value that the lowest quantized bias value represents.
                    -> Tensor v6 Float -- ^ __max_bias__: The float value that the highest quantized bias value represents.
                    -> (Tensor Value out_type, Tensor Value Float,
                        Tensor Value Float)
                    -- ^ (__output__, __min_out__, __max_out__)
                    --
                    -- * __output__
                    --
                    -- * __min_out__: The float value that the lowest quantized output value represents.
                    --
                    -- * __max_out__: The float value that the highest quantized output value represents.
quantizedBiasAdd input bias min_input max_input min_bias
                 max_bias | eqLengthGuard [] =
    buildOp (opDef "QuantizedBiasAdd"
             & opAttr "T1" .~ tensorType (undefined :: t1)
             & opAttr "T2" .~ tensorType (undefined :: t2)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input bias min_input max_input min_bias max_bias
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T1"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T2"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "out_type"
  type: "type"
}
input_arg { name: "input" type_attr: "T1" }
input_arg {
  description: "A 1D bias Tensor with size matching the last dimension of \'input\'."
  name: "bias"
  type_attr: "T2"
}
input_arg {
  description: "The float value that the lowest quantized input value represents."
  name: "min_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized input value represents."
  name: "max_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the lowest quantized bias value represents."
  name: "min_bias"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized bias value represents."
  name: "max_bias"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "out_type" }
output_arg {
  description: "The float value that the lowest quantized output value represents."
  name: "min_out"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized output value represents."
  name: "max_out"
  type: DT_FLOAT
}
-}

-- | Computes gradient of the FractionalAvgPool function.
--
-- Unlike FractionalMaxPoolGrad, we don't need to find arg_max for
-- FractionalAvgPoolGrad, we just need to evenly back-propagate each element of
-- out_backprop to those indices that form the same pooling cell. Therefore, we
-- just need to know the shape of original input tensor, instead of the whole
-- tensor.
fractionalAvgPoolGrad :: forall v1 v2 v3 v4 t . (TensorType t,
                                                 OneOf '[Data.Int.Int32,
                                                         Data.Int.Int64, Double,
                                                         Float] t) =>
                         Tensor v1 Data.Int.Int64 -- ^ __orig_input_tensor_shape__: Original input tensor shape for `fractional_avg_pool`
                         -> Tensor v2 t -- ^ __out_backprop__: 4-D with shape `[batch, height, width, channels]`.  Gradients
                                        -- w.r.t. the output of `fractional_avg_pool`.
                         -> Tensor v3 Data.Int.Int64 -- ^ __row_pooling_sequence__: row pooling sequence, form pooling region with
                                                     -- col_pooling_sequence.
                         -> Tensor v4 Data.Int.Int64 -- ^ __col_pooling_sequence__: column pooling sequence, form pooling region with
                                                     -- row_pooling sequence.
                         -> Tensor Value t -- ^ __output__: 4-D.  Gradients w.r.t. the input of `fractional_avg_pool`.
fractionalAvgPoolGrad orig_input_tensor_shape out_backprop row_pooling_sequence
                      col_pooling_sequence | eqLengthGuard [] =
    buildOp (opDef "FractionalAvgPoolGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input_tensor_shape out_backprop row_pooling_sequence
        col_pooling_sequence
{-
attr {
  default_value { b: false }
  description: "When set to True, it means when pooling, the values at the boundary\nof adjacent pooling cells are used by both cells. For example:\n\n`index  0  1  2  3  4`\n\n`value  20 5  16 3  7`\n\nIf the pooling sequence is [0, 2, 4], then 16, at index 2 will be used twice.\nThe result would be [41/3, 26/3] for fractional avg pooling."
  name: "overlapping"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT type: DT_DOUBLE type: DT_INT32 type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Original input tensor shape for `fractional_avg_pool`"
  name: "orig_input_tensor_shape"
  type: DT_INT64
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`.  Gradients\nw.r.t. the output of `fractional_avg_pool`."
  name: "out_backprop"
  type_attr: "T"
}
input_arg {
  description: "row pooling sequence, form pooling region with\ncol_pooling_sequence."
  name: "row_pooling_sequence"
  type: DT_INT64
}
input_arg {
  description: "column pooling sequence, form pooling region with\nrow_pooling sequence."
  name: "col_pooling_sequence"
  type: DT_INT64
}
output_arg {
  description: "4-D.  Gradients w.r.t. the input of `fractional_avg_pool`."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes gradient of the FractionalMaxPool function.

fractionalMaxPoolGrad :: forall v1 v2 v3 v4 v5 t . (TensorType t,
                                                    OneOf '[Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Double, Float] t) =>
                         Tensor v1 t -- ^ __orig_input__: Original input for `fractional_max_pool`
                         -> Tensor v2 t -- ^ __orig_output__: Original output for `fractional_max_pool`
                         -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, height, width, channels]`.  Gradients
                                        -- w.r.t. the output of `fractional_max_pool`.
                         -> Tensor v4 Data.Int.Int64 -- ^ __row_pooling_sequence__: row pooling sequence, form pooling region with
                                                     -- col_pooling_sequence.
                         -> Tensor v5 Data.Int.Int64 -- ^ __col_pooling_sequence__: column pooling sequence, form pooling region with
                                                     -- row_pooling sequence.
                         -> Tensor Value t -- ^ __output__: 4-D.  Gradients w.r.t. the input of `fractional_max_pool`.
fractionalMaxPoolGrad orig_input orig_output out_backprop row_pooling_sequence
                      col_pooling_sequence | eqLengthGuard [] =
    buildOp (opDef "FractionalMaxPoolGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input orig_output out_backprop row_pooling_sequence
        col_pooling_sequence
{-
attr {
  default_value { b: false }
  description: "When set to True, it means when pooling, the values at the boundary\nof adjacent pooling cells are used by both cells. For example:\n\n`index  0  1  2  3  4`\n\n`value  20 5  16 3  7`\n\nIf the pooling sequence is [0, 2, 4], then 16, at index 2 will be used twice.\nThe result would be [20, 16] for fractional max pooling."
  name: "overlapping"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT type: DT_DOUBLE type: DT_INT32 type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Original input for `fractional_max_pool`"
  name: "orig_input"
  type_attr: "T"
}
input_arg {
  description: "Original output for `fractional_max_pool`"
  name: "orig_output"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`.  Gradients\nw.r.t. the output of `fractional_max_pool`."
  name: "out_backprop"
  type_attr: "T"
}
input_arg {
  description: "row pooling sequence, form pooling region with\ncol_pooling_sequence."
  name: "row_pooling_sequence"
  type: DT_INT64
}
input_arg {
  description: "column pooling sequence, form pooling region with\nrow_pooling sequence."
  name: "col_pooling_sequence"
  type: DT_INT64
}
output_arg {
  description: "4-D.  Gradients w.r.t. the input of `fractional_max_pool`."
  name: "output"
  type_attr: "T"
}
-}

-- | Performs fractional max pooling on the input.
--
-- Fractional max pooling is slightly different than regular max pooling.  In
-- regular max pooling, you downsize an input set by taking the maximum value of
-- smaller N x N subsections of the set (often 2x2), and try to reduce the set by
-- a factor of N, where N is an integer.  Fractional max pooling, as you might
-- expect from the word "fractional", means that the overall reduction ratio N
-- does not have to be an integer.
-- 
-- The sizes of the pooling regions are generated randomly but are fairly uniform.
-- For example, let's look at the height dimension, and the constraints on the
-- list of rows that will be pool boundaries.
-- 
-- First we define the following:
-- 
-- 1.  input_row_length : the number of rows from the input set
-- 2.  output_row_length : which will be smaller than the input
-- 3.  alpha = input_row_length / output_row_length : our reduction ratio
-- 4.  K = floor(alpha)
-- 5.  row_pooling_sequence : this is the result list of pool boundary rows
-- 
-- Then, row_pooling_sequence should satisfy:
-- 
-- 1.  a[0] = 0 : the first value of the sequence is 0
-- 2.  a[end] = input_row_length : the last value of the sequence is the size
-- 3.  K <= (a[i+1] - a[i]) <= K+1 : all intervals are K or K+1 size
-- 4.  length(row_pooling_sequence) = output_row_length+1
-- 
-- For more details on fractional max pooling, see this paper:
-- [Benjamin Graham, Fractional Max-Pooling](http://arxiv.org/abs/1412.6071)
fractionalMaxPool :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Double, Float] t) =>
                     Tensor v1 t -- ^ __value__: 4-D with shape `[batch, height, width, channels]`.
                     -> (Tensor Value t, Tensor Value Data.Int.Int64,
                         Tensor Value Data.Int.Int64)
                     -- ^ (__output__, __row_pooling_sequence__, __col_pooling_sequence__)
                     --
                     -- * __output__: output tensor after fractional max pooling.
                     --
                     -- * __row_pooling_sequence__: row pooling sequence, needed to calculate gradient.
                     --
                     -- * __col_pooling_sequence__: column pooling sequence, needed to calculate gradient.
fractionalMaxPool value | eqLengthGuard [] =
    buildOp (opDef "FractionalMaxPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        value
{-
attr {
  description: "Pooling ratio for each dimension of `value`, currently only\nsupports row and col dimension and should be >= 1.0. For example, a valid\npooling ratio looks like [1.0, 1.44, 1.73, 1.0]. The first and last elements\nmust be 1.0 because we don\'t allow pooling on batch and channels\ndimensions. 1.44 and 1.73 are pooling ratio on height and width dimensions\nrespectively."
  has_minimum: true
  minimum: 4
  name: "pooling_ratio"
  type: "list(float)"
}
attr {
  default_value { b: false }
  description: "When set to True, generates the pooling sequence in a\npseudorandom fashion, otherwise, in a random fashion. Check paper [Benjamin\nGraham, Fractional Max-Pooling](http://arxiv.org/abs/1412.6071) for\ndifference between pseudorandom and random."
  name: "pseudo_random"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "When set to True, it means when pooling, the values at the boundary\nof adjacent pooling cells are used by both cells. For example:\n\n`index  0  1  2  3  4`\n\n`value  20 5  16 3  7`\n\nIf the pooling sequence is [0, 2, 4], then 16, at index 2 will be used twice.\nThe result would be [20, 16] for fractional max pooling."
  name: "overlapping"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "When set to True, a fixed pooling region will be used when\niterating over a FractionalMaxPool node in the computation graph. Mainly used\nin unit test to make FractionalMaxPool deterministic."
  name: "deterministic"
  type: "bool"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT type: DT_DOUBLE type: DT_INT32 type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "output tensor after fractional max pooling."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "row pooling sequence, needed to calculate gradient."
  name: "row_pooling_sequence"
  type: DT_INT64
}
output_arg {
  description: "column pooling sequence, needed to calculate gradient."
  name: "col_pooling_sequence"
  type: DT_INT64
}
-}

-- | Finds values and indices of the `k` largest elements for the last dimension.
--
-- If the input is a vector (rank-1), finds the `k` largest entries in the vector
-- and outputs their values and indices as vectors.  Thus `values[j]` is the
-- `j`-th largest entry in `input`, and its index is `indices[j]`.
-- 
-- For matrices (resp. higher rank input), computes the top `k` entries in each
-- row (resp. vector along the last dimension).  Thus,
-- 
--     values.shape = indices.shape = input.shape[:-1] + [k]
-- 
-- If two elements are equal, the lower-index element appears first.
-- 
-- If `k` varies dynamically, use `TopKV2` below.
topK :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                             Data.Int.Int64, Data.Int.Int8,
                                             Data.Word.Word16, Data.Word.Word8,
                                             Double, Float] t) =>
        Data.Int.Int64 -- ^ __k__: Number of top elements to look for along the last dimension (along each
                       -- row for matrices).
        -> Tensor v1 t -- ^ __input__: 1-D or higher with last dimension at least `k`.
        -> (Tensor Value t, Tensor Value Data.Int.Int32)
        -- ^ (__values__, __indices__)
        --
        -- * __values__: The `k` largest elements along each last dimensional slice.
        --
        -- * __indices__: The indices of `values` within the last dimension of `input`.
topK k input | eqLengthGuard [] =
    buildOp (opDef "TopK"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "k" .~ k)
        input
{-
attr {
  description: "Number of top elements to look for along the last dimension (along each\nrow for matrices)."
  has_minimum: true
  name: "k"
  type: "int"
}
attr {
  default_value { b: true }
  description: "If true the resulting `k` elements will be sorted by the values in\ndescending order."
  name: "sorted"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D or higher with last dimension at least `k`."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The `k` largest elements along each last dimensional slice."
  name: "values"
  type_attr: "T"
}
output_arg {
  description: "The indices of `values` within the last dimension of `input`."
  name: "indices"
  type: DT_INT32
}
-}

-- | Says whether the targets are in the top `K` predictions.
--
-- This outputs a `batch_size` bool array, an entry `out[i]` is `true` if the
-- prediction for the target class is among the top `k` predictions among
-- all predictions for example `i`. Note that the behavior of `InTopK` differs
-- from the `TopK` op in its handling of ties; if multiple classes have the
-- same prediction value and straddle the top-`k` boundary, all of those
-- classes are considered to be in the top `k`.
-- 
-- More formally, let
-- 
--   \\(predictions_i\\) be the predictions for all classes for example `i`,
--   \\(targets_i\\) be the target class for example `i`,
--   \\(out_i\\) be the output for example `i`,
-- 
-- $$out_i = predictions_{i, targets_i} \in TopKIncludingTies(predictions_i)$$
inTopK :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                  Data.Int.Int64] t) =>
          Data.Int.Int64 -- ^ __k__: Number of top elements to look at for computing precision.
          -> Tensor v1 Float -- ^ __predictions__: A `batch_size` x `classes` tensor.
          -> Tensor v2 t -- ^ __targets__: A `batch_size` vector of class ids.
          -> Tensor Value Bool -- ^ __precision__: Computed Precision at `k` as a `bool Tensor`.
inTopK k predictions targets | eqLengthGuard [] =
    buildOp (opDef "InTopK"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "k" .~ k)
        predictions targets
{-
attr {
  description: "Number of top elements to look at for computing precision."
  name: "k"
  type: "int"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "T"
  type: "type"
}
input_arg {
  description: "A `batch_size` x `classes` tensor."
  name: "predictions"
  type: DT_FLOAT
}
input_arg {
  description: "A `batch_size` vector of class ids."
  name: "targets"
  type_attr: "T"
}
output_arg {
  description: "Computed Precision at `k` as a `bool Tensor`."
  name: "precision"
  type: DT_BOOL
}
-}

-- | Computes softmax cross entropy cost and gradients to backpropagate.
--
-- Unlike `SoftmaxCrossEntropyWithLogits`, this operation does not accept
-- a matrix of label probabilities, but rather a single label per row
-- of features.  This label is considered to have probability 1.0 for the
-- given row.
-- 
-- Inputs are the logits, not probabilities.
sparseSoftmaxCrossEntropyWithLogits :: forall v1 v2 t tlabels . (TensorType t,
                                                                 OneOf '[Data.Word.Word16,
                                                                         Double,
                                                                         Float] t,
                                                                 TensorType tlabels,
                                                                 OneOf '[Data.Int.Int32,
                                                                         Data.Int.Int64] tlabels) =>
                                       Tensor v1 t -- ^ __features__: batch_size x num_classes matrix
                                       -> Tensor v2 tlabels -- ^ __labels__: batch_size vector with values in [0, num_classes).
                                                            -- This is the label for the given minibatch entry.
                                       -> (Tensor Value t, Tensor Value t)
                                       -- ^ (__loss__, __backprop__)
                                       --
                                       -- * __loss__: Per example loss (batch_size vector).
                                       --
                                       -- * __backprop__: backpropagated gradients (batch_size x num_classes matrix).
sparseSoftmaxCrossEntropyWithLogits features labels | eqLengthGuard [] =
    buildOp (opDef "SparseSoftmaxCrossEntropyWithLogits"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tlabels" .~ tensorType (undefined :: tlabels))
        features labels
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT64 }
  name: "Tlabels"
  type: "type"
}
input_arg {
  description: "batch_size x num_classes matrix"
  name: "features"
  type_attr: "T"
}
input_arg {
  description: "batch_size vector with values in [0, num_classes).\nThis is the label for the given minibatch entry."
  name: "labels"
  type_attr: "Tlabels"
}
output_arg {
  description: "Per example loss (batch_size vector)."
  name: "loss"
  type_attr: "T"
}
output_arg {
  description: "backpropagated gradients (batch_size x num_classes matrix)."
  name: "backprop"
  type_attr: "T"
}
-}

-- | Computes softmax cross entropy cost and gradients to backpropagate.
--
-- Inputs are the logits, not probabilities.
softmaxCrossEntropyWithLogits :: forall v1 v2 t . (TensorType t,
                                                   OneOf '[Data.Word.Word16,
                                                           Double, Float] t) =>
                                 Tensor v1 t -- ^ __features__: batch_size x num_classes matrix
                                 -> Tensor v2 t -- ^ __labels__: batch_size x num_classes matrix
                                                -- The caller must ensure that each batch of labels represents a valid
                                                -- probability distribution.
                                 -> (Tensor Value t, Tensor Value t)
                                 -- ^ (__loss__, __backprop__)
                                 --
                                 -- * __loss__: Per example loss (batch_size vector).
                                 --
                                 -- * __backprop__: backpropagated gradients (batch_size x num_classes matrix).
softmaxCrossEntropyWithLogits features labels | eqLengthGuard [] =
    buildOp (opDef "SoftmaxCrossEntropyWithLogits"
             & opAttr "T" .~ tensorType (undefined :: t))
        features labels
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "batch_size x num_classes matrix"
  name: "features"
  type_attr: "T"
}
input_arg {
  description: "batch_size x num_classes matrix\nThe caller must ensure that each batch of labels represents a valid\nprobability distribution."
  name: "labels"
  type_attr: "T"
}
output_arg {
  description: "Per example loss (batch_size vector)."
  name: "loss"
  type_attr: "T"
}
output_arg {
  description: "backpropagated gradients (batch_size x num_classes matrix)."
  name: "backprop"
  type_attr: "T"
}
-}

-- | Computes log softmax activations.
--
-- For each batch `i` and class `j` we have
-- 
--     logsoftmax[i, j] = logits[i, j] - log(sum(exp(logits[i])))
logSoftmax :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                   Float] t) =>
              Tensor v1 t -- ^ __logits__: 2-D with shape `[batch_size, num_classes]`.
              -> Tensor Value t -- ^ __logsoftmax__: Same shape as `logits`.
logSoftmax logits | eqLengthGuard [] =
    buildOp (opDef "LogSoftmax"
             & opAttr "T" .~ tensorType (undefined :: t))
        logits
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D with shape `[batch_size, num_classes]`."
  name: "logits"
  type_attr: "T"
}
output_arg {
  description: "Same shape as `logits`."
  name: "logsoftmax"
  type_attr: "T"
}
-}

-- | Computes softsign gradients for a softsign operation.

softsignGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word16,
                                                        Data.Word.Word8, Double,
                                                        Float] t) =>
                Tensor v1 t -- ^ __gradients__: The backpropagated gradients to the corresponding softsign operation.
                -> Tensor v2 t -- ^ __features__: The features passed as input to the corresponding softsign operation.
                -> Tensor Value t -- ^ __backprops__: The gradients: `gradients / (1 + abs(-features)) ** 2`.
softsignGrad gradients features | eqLengthGuard [] =
    buildOp (opDef "SoftsignGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        gradients features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The backpropagated gradients to the corresponding softsign operation."
  name: "gradients"
  type_attr: "T"
}
input_arg {
  description: "The features passed as input to the corresponding softsign operation."
  name: "features"
  type_attr: "T"
}
output_arg {
  description: "The gradients: `gradients / (1 + abs(-features)) ** 2`."
  name: "backprops"
  type_attr: "T"
}
-}

-- | Computes softplus: `log(exp(features) + 1)`.

softplus :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
            Tensor v1 t -- ^ __features__
            -> Tensor Value t -- ^ __activations__
softplus features | eqLengthGuard [] =
    buildOp (opDef "Softplus"
             & opAttr "T" .~ tensorType (undefined :: t))
        features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "features" type_attr: "T" }
output_arg { name: "activations" type_attr: "T" }
-}

-- | Computes gradients for the exponential linear (Elu) operation.

eluGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t) =>
           Tensor v1 t -- ^ __gradients__: The backpropagated gradients to the corresponding Elu operation.
           -> Tensor v2 t -- ^ __outputs__: The outputs of the corresponding Elu operation.
           -> Tensor Value t -- ^ __backprops__: The gradients: `gradients * (outputs + 1)` if outputs < 0,
           -- `gradients` otherwise.
eluGrad gradients outputs | eqLengthGuard [] =
    buildOp (opDef "EluGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        gradients outputs
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The backpropagated gradients to the corresponding Elu operation."
  name: "gradients"
  type_attr: "T"
}
input_arg {
  description: "The outputs of the corresponding Elu operation."
  name: "outputs"
  type_attr: "T"
}
output_arg {
  description: "The gradients: `gradients * (outputs + 1)` if outputs < 0,\n`gradients` otherwise."
  name: "backprops"
  type_attr: "T"
}
-}

-- | Computes exponential linear: `exp(features) - 1` if < 0, `features` otherwise.
--
-- See [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)
-- ](http://arxiv.org/abs/1511.07289)
elu :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                            Data.Int.Int64, Data.Int.Int8,
                                            Data.Word.Word16, Data.Word.Word8,
                                            Double, Float] t) =>
       Tensor v1 t -- ^ __features__
       -> Tensor Value t -- ^ __activations__
elu features | eqLengthGuard [] =
    buildOp (opDef "Elu"
             & opAttr "T" .~ tensorType (undefined :: t))
        features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "features" type_attr: "T" }
output_arg { name: "activations" type_attr: "T" }
-}

-- | Computes rectified linear 6: `min(max(features, 0), 6)`.

relu6 :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                              Data.Int.Int64, Data.Int.Int8,
                                              Data.Word.Word16, Data.Word.Word8,
                                              Double, Float] t) =>
         Tensor v1 t -- ^ __features__
         -> Tensor Value t -- ^ __activations__
relu6 features | eqLengthGuard [] =
    buildOp (opDef "Relu6"
             & opAttr "T" .~ tensorType (undefined :: t))
        features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "features" type_attr: "T" }
output_arg { name: "activations" type_attr: "T" }
-}

-- | Computes rectified linear gradients for a Relu operation.

reluGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                    Data.Int.Int32,
                                                    Data.Int.Int64,
                                                    Data.Int.Int8,
                                                    Data.Word.Word16,
                                                    Data.Word.Word8, Double,
                                                    Float] t) =>
            Tensor v1 t -- ^ __gradients__: The backpropagated gradients to the corresponding Relu operation.
            -> Tensor v2 t -- ^ __features__: The features passed as input to the corresponding Relu operation, OR
                           -- the outputs of that operation (both work equivalently).
            -> Tensor Value t -- ^ __backprops__: `gradients * (features > 0)`.
reluGrad gradients features | eqLengthGuard [] =
    buildOp (opDef "ReluGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        gradients features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The backpropagated gradients to the corresponding Relu operation."
  name: "gradients"
  type_attr: "T"
}
input_arg {
  description: "The features passed as input to the corresponding Relu operation, OR\nthe outputs of that operation (both work equivalently)."
  name: "features"
  type_attr: "T"
}
output_arg {
  description: "`gradients * (features > 0)`."
  name: "backprops"
  type_attr: "T"
}
-}

-- | Computes the gradient of morphological 2-D dilation with respect to the input.

dilation2DBackpropInput :: forall v1 v2 v3 t . (TensorType t,
                                                OneOf '[Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word16,
                                                        Data.Word.Word8, Double,
                                                        Float] t) =>
                           Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, depth]`.
                           -> Tensor v2 t -- ^ __filter__: 3-D with shape `[filter_height, filter_width, depth]`.
                           -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, depth]`.
                           -> Tensor Value t -- ^ __in_backprop__: 4-D with shape `[batch, in_height, in_width, depth]`.
dilation2DBackpropInput input filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Dilation2DBackpropInput"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D of length 4. The stride of the sliding window for each dimension of\nthe input tensor. Must be: `[1, stride_height, stride_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  description: "1-D of length 4. The input stride for atrous morphological dilation.\nMust be: `[1, rate_height, rate_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "rates"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, depth]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "3-D with shape `[filter_height, filter_width, depth]`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, depth]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape `[batch, in_height, in_width, depth]`."
  name: "in_backprop"
  type_attr: "T"
}
-}

-- | Computes gradients of the maxpooling function.

maxPoolGrad :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                          Float] t) =>
               Tensor v1 t -- ^ __orig_input__: The original input tensor.
               -> Tensor v2 t -- ^ __orig_output__: The original output tensor.
               -> Tensor v3 t -- ^ __grad__: 4-D.  Gradients w.r.t. the output of `max_pool`.
               -> Tensor Value t -- ^ __output__: Gradients w.r.t. the input to `max_pool`.
maxPoolGrad orig_input orig_output grad | eqLengthGuard [] =
    buildOp (opDef "MaxPoolGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input orig_output grad
{-
attr {
  description: "The size of the window for each dimension of the input tensor."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the\ninput tensor."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "The original input tensor."
  name: "orig_input"
  type_attr: "T"
}
input_arg {
  description: "The original output tensor."
  name: "orig_output"
  type_attr: "T"
}
input_arg {
  description: "4-D.  Gradients w.r.t. the output of `max_pool`."
  name: "grad"
  type_attr: "T"
}
output_arg {
  description: "Gradients w.r.t. the input to `max_pool`."
  name: "output"
  type_attr: "T"
}
-}

-- | Gradients for Local Response Normalization.

lRNGrad :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                      Float] t) =>
           Tensor v1 t -- ^ __input_grads__: 4-D with shape `[batch, height, width, channels]`.
           -> Tensor v2 t -- ^ __input_image__: 4-D with shape `[batch, height, width, channels]`.
           -> Tensor v3 t -- ^ __output_image__: 4-D with shape `[batch, height, width, channels]`.
           -> Tensor Value t -- ^ __output__: The gradients for LRN.
lRNGrad input_grads input_image output_image | eqLengthGuard [] =
    buildOp (opDef "LRNGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_grads input_image output_image
{-
attr {
  default_value { i: 5 }
  description: "A depth radius."
  name: "depth_radius"
  type: "int"
}
attr {
  default_value { f: 1.0 }
  description: "An offset (usually > 0 to avoid dividing by 0)."
  name: "bias"
  type: "float"
}
attr {
  default_value { f: 1.0 }
  description: "A scale factor, usually positive."
  name: "alpha"
  type: "float"
}
attr {
  default_value { f: 0.5 }
  description: "An exponent."
  name: "beta"
  type: "float"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "input_grads"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "input_image"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "output_image"
  type_attr: "T"
}
output_arg {
  description: "The gradients for LRN." name: "output" type_attr: "T"
}
-}

-- | Computes gradients of max pooling function.

maxPool3DGrad :: forall v1 v2 v3 t . (TensorType t,
                                      OneOf '[(Data.Complex.Complex Double),
                                              (Data.Complex.Complex Float),
                                              Data.Int.Int16, Data.Int.Int32,
                                              Data.Int.Int64, Data.Int.Int8,
                                              Data.Word.Word16, Data.Word.Word8,
                                              Double, Float] t) =>
                 Tensor v1 Float -- ^ __orig_input__: The original input tensor.
                 -> Tensor v2 Float -- ^ __orig_output__: The original output tensor.
                 -> Tensor v3 t -- ^ __grad__: Output backprop of shape `[batch, depth, rows, cols, channels]`.
                 -> Tensor Value t -- ^ __output__
maxPool3DGrad orig_input orig_output grad | eqLengthGuard [] =
    buildOp (opDef "MaxPool3DGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input orig_output grad
{-
attr {
  description: "1-D tensor of length 5. The size of the window for each dimension of\nthe input tensor. Must have `ksize[0] = ksize[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The original input tensor."
  name: "orig_input"
  type: DT_FLOAT
}
input_arg {
  description: "The original output tensor."
  name: "orig_output"
  type: DT_FLOAT
}
input_arg {
  description: "Output backprop of shape `[batch, depth, rows, cols, channels]`."
  name: "grad"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the gradients of 3-D convolution with respect to the filter.

conv3DBackpropFilterV2 :: forall v1 v2 v3 t . (TensorType t,
                                               OneOf '[(Data.Complex.Complex Double),
                                                       (Data.Complex.Complex Float),
                                                       Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
                          Tensor v1 t -- ^ __input__: Shape `[batch, depth, rows, cols, in_channels]`.
                          -> Tensor v2 Data.Int.Int32 -- ^ __filter_sizes__: An integer vector representing the tensor shape of `filter`,
                                                      -- where `filter` is a 5-D
                                                      -- `[filter_depth, filter_height, filter_width, in_channels, out_channels]`
                                                      -- tensor.
                          -> Tensor v3 t -- ^ __out_backprop__: Backprop signal of shape `[batch, out_depth, out_rows, out_cols,
                                         -- out_channels]`.
                          -> Tensor Value t -- ^ __output__
conv3DBackpropFilterV2 input filter_sizes out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv3DBackpropFilterV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter_sizes out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "Shape `[batch, depth, rows, cols, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "An integer vector representing the tensor shape of `filter`,\nwhere `filter` is a 5-D\n`[filter_depth, filter_height, filter_width, in_channels, out_channels]`\ntensor."
  name: "filter_sizes"
  type: DT_INT32
}
input_arg {
  description: "Backprop signal of shape `[batch, out_depth, out_rows, out_cols,\nout_channels]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the gradients of 3-D convolution with respect to the filter.

conv3DBackpropFilter :: forall v1 v2 v3 t . (TensorType t,
                                             OneOf '[(Data.Complex.Complex Double),
                                                     (Data.Complex.Complex Float),
                                                     Data.Int.Int16,
                                                     Data.Int.Int32,
                                                     Data.Int.Int64,
                                                     Data.Int.Int8,
                                                     Data.Word.Word16,
                                                     Data.Word.Word8, Double,
                                                     Float] t) =>
                        Tensor v1 t -- ^ __input__: Shape `[batch, depth, rows, cols, in_channels]`.
                        -> Tensor v2 t -- ^ __filter__: Shape `[depth, rows, cols, in_channels, out_channels]`.
                                       -- `in_channels` must match between `input` and `filter`.
                        -> Tensor v3 t -- ^ __out_backprop__: Backprop signal of shape `[batch, out_depth, out_rows, out_cols,
                                       -- out_channels]`.
                        -> Tensor Value t -- ^ __output__
conv3DBackpropFilter input filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv3DBackpropFilter"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "Shape `[batch, depth, rows, cols, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "Shape `[depth, rows, cols, in_channels, out_channels]`.\n`in_channels` must match between `input` and `filter`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "Backprop signal of shape `[batch, out_depth, out_rows, out_cols,\nout_channels]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes a 3-D convolution given 5-D `input` and `filter` tensors.
--
-- In signal processing, cross-correlation is a measure of similarity of
-- two waveforms as a function of a time-lag applied to one of them. This
-- is also known as a sliding dot product or sliding inner-product.
-- 
-- Our Conv3D implements a form of cross-correlation.
conv3D :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
          Tensor v1 t -- ^ __input__: Shape `[batch, in_depth, in_height, in_width, in_channels]`.
          -> Tensor v2 t -- ^ __filter__: Shape `[filter_depth, filter_height, filter_width, in_channels,
                         -- out_channels]`. `in_channels` must match between `input` and `filter`.
          -> Tensor Value t -- ^ __output__
conv3D input filter | eqLengthGuard [] =
    buildOp (opDef "Conv3D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "Shape `[batch, in_depth, in_height, in_width, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "Shape `[filter_depth, filter_height, filter_width, in_channels,\nout_channels]`. `in_channels` must match between `input` and `filter`."
  name: "filter"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the gradients of depthwise convolution with respect to the filter.

depthwiseConv2dNativeBackpropFilter :: forall v1 v2 v3 t . (TensorType t,
                                                            OneOf '[Double,
                                                                    Float] t) =>
                                       Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, in_channels]`.
                                       -> Tensor v2 Data.Int.Int32 -- ^ __filter_sizes__: An integer vector representing the tensor shape of `filter`,
                                                                   -- where `filter` is a 4-D
                                                                   -- `[filter_height, filter_width, in_channels, depthwise_multiplier]` tensor.
                                       -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, out_channels]`.
                                                      -- Gradients w.r.t. the output of the convolution.
                                       -> Tensor Value t -- ^ __output__: 4-D with shape
                                       -- `[filter_height, filter_width, in_channels, out_channels]`.  Gradient w.r.t.
                                       -- the `filter` input of the convolution.
depthwiseConv2dNativeBackpropFilter input filter_sizes
                                    out_backprop | eqLengthGuard [] =
    buildOp (opDef "DepthwiseConv2dNativeBackpropFilter"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter_sizes out_backprop
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\nof the convolution."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "An integer vector representing the tensor shape of `filter`,\nwhere `filter` is a 4-D\n`[filter_height, filter_width, in_channels, depthwise_multiplier]` tensor."
  name: "filter_sizes"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, out_channels]`.\nGradients w.r.t. the output of the convolution."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, out_channels]`.  Gradient w.r.t.\nthe `filter` input of the convolution."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the gradients of convolution with respect to the filter.

conv2DBackpropFilter :: forall v1 v2 v3 t . (TensorType t,
                                             OneOf '[Data.Word.Word16, Double,
                                                     Float] t) =>
                        Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, in_channels]`.
                        -> Tensor v2 Data.Int.Int32 -- ^ __filter_sizes__: An integer vector representing the tensor shape of `filter`,
                                                    -- where `filter` is a 4-D
                                                    -- `[filter_height, filter_width, in_channels, out_channels]` tensor.
                        -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, out_channels]`.
                                       -- Gradients w.r.t. the output of the convolution.
                        -> Tensor Value t -- ^ __output__: 4-D with shape
                        -- `[filter_height, filter_width, in_channels, out_channels]`.  Gradient w.r.t.
                        -- the `filter` input of the convolution.
conv2DBackpropFilter input filter_sizes out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv2DBackpropFilter"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter_sizes out_backprop
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\nof the convolution. Must be in the same order as the dimension specified with\nformat."
  name: "strides"
  type: "list(int)"
}
attr {
  default_value { b: true } name: "use_cudnn_on_gpu" type: "bool"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "An integer vector representing the tensor shape of `filter`,\nwhere `filter` is a 4-D\n`[filter_height, filter_width, in_channels, out_channels]` tensor."
  name: "filter_sizes"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, out_channels]`.\nGradients w.r.t. the output of the convolution."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, out_channels]`.  Gradient w.r.t.\nthe `filter` input of the convolution."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the gradients of convolution with respect to the input.

conv2DBackpropInput :: forall v1 v2 v3 t . (TensorType t,
                                            OneOf '[Data.Word.Word16, Double,
                                                    Float] t) =>
                       Tensor v1 Data.Int.Int32 -- ^ __input_sizes__: An integer vector representing the shape of `input`,
                                                -- where `input` is a 4-D `[batch, height, width, channels]` tensor.
                       -> Tensor v2 t -- ^ __filter__: 4-D with shape
                                      -- `[filter_height, filter_width, in_channels, out_channels]`.
                       -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, out_channels]`.
                                      -- Gradients w.r.t. the output of the convolution.
                       -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, in_height, in_width, in_channels]`.  Gradient
                       -- w.r.t. the input of the convolution.
conv2DBackpropInput input_sizes filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv2DBackpropInput"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_sizes filter out_backprop
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\nof the convolution. Must be in the same order as the dimension specified with\nformat."
  name: "strides"
  type: "list(int)"
}
attr {
  default_value { b: true } name: "use_cudnn_on_gpu" type: "bool"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
input_arg {
  description: "An integer vector representing the shape of `input`,\nwhere `input` is a 4-D `[batch, height, width, channels]` tensor."
  name: "input_sizes"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, out_channels]`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, out_channels]`.\nGradients w.r.t. the output of the convolution."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`.  Gradient\nw.r.t. the input of the convolution."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes a 2-D convolution given 4-D `input` and `filter` tensors.
--
-- Given an input tensor of shape `[batch, in_height, in_width, in_channels]`
-- and a filter / kernel tensor of shape
-- `[filter_height, filter_width, in_channels, out_channels]`, this op
-- performs the following:
-- 
-- 1. Flattens the filter to a 2-D matrix with shape
--    `[filter_height * filter_width * in_channels, output_channels]`.
-- 2. Extracts image patches from the input tensor to form a *virtual*
--    tensor of shape `[batch, out_height, out_width,
--    filter_height * filter_width * in_channels]`.
-- 3. For each patch, right-multiplies the filter matrix and the image patch
--    vector.
-- 
-- In detail, with the default NHWC format,
-- 
--     output[b, i, j, k] =
--         sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
--                         filter[di, dj, q, k]
-- 
-- Must have `strides[0] = strides[3] = 1`.  For the most common case of the same
-- horizontal and vertices strides, `strides = [1, stride, stride, 1]`.
conv2D :: forall v1 v2 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                  Float] t) =>
          Tensor v1 t -- ^ __input__
          -> Tensor v2 t -- ^ __filter__
          -> Tensor Value t -- ^ __output__
conv2D input filter | eqLengthGuard [] =
    buildOp (opDef "Conv2D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D of length 4.  The stride of the sliding window for each dimension\nof `input`. Must be in the same order as the dimension specified with format."
  name: "strides"
  type: "list(int)"
}
attr {
  default_value { b: true } name: "use_cudnn_on_gpu" type: "bool"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
input_arg { name: "input" type_attr: "T" }
input_arg { name: "filter" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Adds `bias` to `value`.
--
-- This is a special case of `tf.add` where `bias` is restricted to be 1-D.
-- Broadcasting is supported, so `value` may have any number of dimensions.
biasAdd :: forall v1 v2 t . (TensorType t,
                             OneOf '[(Data.Complex.Complex Double),
                                     (Data.Complex.Complex Float),
                                     Data.Int.Int16, Data.Int.Int32,
                                     Data.Int.Int64, Data.Int.Int8,
                                     Data.Word.Word16, Data.Word.Word8, Double,
                                     Float] t) =>
           Tensor v1 t -- ^ __value__: Any number of dimensions.
           -> Tensor v2 t -- ^ __bias__: 1-D with size the last dimension of `value`.
           -> Tensor Value t -- ^ __output__: Broadcasted sum of `value` and `bias`.
biasAdd value bias | eqLengthGuard [] =
    buildOp (opDef "BiasAdd"
             & opAttr "T" .~ tensorType (undefined :: t))
        value bias
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the bias tensor will be added to the last dimension\nof the value tensor.\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width].\nThe tensor will be added to \"in_channels\", the third-to-the-last\n    dimension."
  name: "data_format"
  type: "string"
}
input_arg {
  description: "Any number of dimensions."
  name: "value"
  type_attr: "T"
}
input_arg {
  description: "1-D with size the last dimension of `value`."
  name: "bias"
  type_attr: "T"
}
output_arg {
  description: "Broadcasted sum of `value` and `bias`."
  name: "output"
  type_attr: "T"
}
-}

-- | Batch normalization.
--
-- Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW".
-- The size of 1D Tensors matches the dimension C of the 4D Tensors.
fusedBatchNorm :: forall v1 v2 v3 v4 v5 t . (TensorType t,
                                             OneOf '[(Data.Complex.Complex Double),
                                                     (Data.Complex.Complex Float),
                                                     Data.Int.Int16,
                                                     Data.Int.Int32,
                                                     Data.Int.Int64,
                                                     Data.Int.Int8,
                                                     Data.Word.Word16,
                                                     Data.Word.Word8, Double,
                                                     Float] t) =>
                  Tensor v1 t -- ^ __x__: A 4D Tensor for input data.
                  -> Tensor v2 t -- ^ __scale__: A 1D Tensor for scaling factor, to scale the normalized x.
                  -> Tensor v3 t -- ^ __offset__: A 1D Tensor for offset, to shift to the normalized x.
                  -> Tensor v4 t -- ^ __mean__: A 1D Tensor for population mean. Used for inference only;
                                 -- must be empty for training.
                  -> Tensor v5 t -- ^ __variance__: A 1D Tensor for population variance. Used for inference only;
                                 -- must be empty for training.
                  -> (Tensor Value t, Tensor Value t, Tensor Value t,
                      Tensor Value t, Tensor Value t)
                  -- ^ (__y__, __batch_mean__, __batch_variance__, __reserve_space_1__, __reserve_space_2__)
                  --
                  -- * __y__: A 4D Tensor for output data.
                  --
                  -- * __batch_mean__: A 1D Tensor for the computed batch mean, to be used by TensorFlow
                  -- to compute the running mean.
                  --
                  -- * __batch_variance__: A 1D Tensor for the computed batch variance, to be used by
                  -- TensorFlow to compute the running variance.
                  --
                  -- * __reserve_space_1__: A 1D Tensor for the computed batch mean, to be reused
                  -- in the gradient computation.
                  --
                  -- * __reserve_space_2__: A 1D Tensor for the computed batch variance (inverted variance
                  -- in the cuDNN case), to be used in the gradient computation.
fusedBatchNorm x scale offset mean variance | eqLengthGuard [] =
    buildOp (opDef "FusedBatchNorm"
             & opAttr "T" .~ tensorType (undefined :: t))
        x scale offset mean variance
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type for the elements of input and output Tensors."
  name: "T"
  type: "type"
}
attr {
  default_value { f: 1.0e-4 }
  description: "A small float number added to the variance of x."
  name: "epsilon"
  type: "float"
}
attr {
  default_value { s: "NHWC" }
  description: "The data format for x and y. Either \"NHWC\" (default) or \"NCHW\"."
  name: "data_format"
  type: "string"
}
attr {
  default_value { b: true }
  description: "A bool value to indicate the operation is for training (default)\nor inference."
  name: "is_training"
  type: "bool"
}
input_arg {
  description: "A 4D Tensor for input data." name: "x" type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for scaling factor, to scale the normalized x."
  name: "scale"
  type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for offset, to shift to the normalized x."
  name: "offset"
  type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for population mean. Used for inference only;\nmust be empty for training."
  name: "mean"
  type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for population variance. Used for inference only;\nmust be empty for training."
  name: "variance"
  type_attr: "T"
}
output_arg {
  description: "A 4D Tensor for output data."
  name: "y"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the computed batch mean, to be used by TensorFlow\nto compute the running mean."
  name: "batch_mean"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the computed batch variance, to be used by\nTensorFlow to compute the running variance."
  name: "batch_variance"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the computed batch mean, to be reused\nin the gradient computation."
  name: "reserve_space_1"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the computed batch variance (inverted variance\nin the cuDNN case), to be used in the gradient computation."
  name: "reserve_space_2"
  type_attr: "T"
}
-}

-- | Gradients for batch normalization.
--
-- This op is deprecated. See `tf.nn.batch_normalization`.
batchNormWithGlobalNormalizationGrad :: forall v1 v2 v3 v4 v5 t . (TensorType t,
                                                                   OneOf '[(Data.Complex.Complex Double),
                                                                           (Data.Complex.Complex Float),
                                                                           Data.Int.Int16,
                                                                           Data.Int.Int32,
                                                                           Data.Int.Int64,
                                                                           Data.Int.Int8,
                                                                           Data.Word.Word16,
                                                                           Data.Word.Word8,
                                                                           Double,
                                                                           Float] t) =>
                                        Bool -- ^ __scale_after_normalization__: A bool indicating whether the resulted tensor
                                             -- needs to be multiplied with gamma.
                                        -> Float -- ^ __variance_epsilon__: A small float number to avoid dividing by 0.
                                        -> Tensor v1 t -- ^ __t__: A 4D input Tensor.
                                        -> Tensor v2 t -- ^ __m__: A 1D mean Tensor with size matching the last dimension of t.
                                                       -- This is the first output from tf.nn.moments,
                                                       -- or a saved moving average thereof.
                                        -> Tensor v3 t -- ^ __v__: A 1D variance Tensor with size matching the last dimension of t.
                                                       -- This is the second output from tf.nn.moments,
                                                       -- or a saved moving average thereof.
                                        -> Tensor v4 t -- ^ __gamma__: A 1D gamma Tensor with size matching the last dimension of t.
                                                       -- If "scale_after_normalization" is true, this Tensor will be multiplied
                                                       -- with the normalized Tensor.
                                        -> Tensor v5 t -- ^ __backprop__: 4D backprop Tensor.
                                        -> (Tensor Value t, Tensor Value t,
                                            Tensor Value t, Tensor Value t,
                                            Tensor Value t)
                                        -- ^ (__dx__, __dm__, __dv__, __db__, __dg__)
                                        --
                                        -- * __dx__: 4D backprop tensor for input.
                                        --
                                        -- * __dm__: 1D backprop tensor for mean.
                                        --
                                        -- * __dv__: 1D backprop tensor for variance.
                                        --
                                        -- * __db__: 1D backprop tensor for beta.
                                        --
                                        -- * __dg__: 1D backprop tensor for gamma.
batchNormWithGlobalNormalizationGrad scale_after_normalization variance_epsilon
                                     t m v gamma backprop | eqLengthGuard [] =
    buildOp (opDef "BatchNormWithGlobalNormalizationGrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "scale_after_normalization" .~ scale_after_normalization
             & opAttr "variance_epsilon" .~ variance_epsilon)
        t m v gamma backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "A small float number to avoid dividing by 0."
  name: "variance_epsilon"
  type: "float"
}
attr {
  description: "A bool indicating whether the resulted tensor\nneeds to be multiplied with gamma."
  name: "scale_after_normalization"
  type: "bool"
}
input_arg {
  description: "A 4D input Tensor." name: "t" type_attr: "T"
}
input_arg {
  description: "A 1D mean Tensor with size matching the last dimension of t.\nThis is the first output from tf.nn.moments,\nor a saved moving average thereof."
  name: "m"
  type_attr: "T"
}
input_arg {
  description: "A 1D variance Tensor with size matching the last dimension of t.\nThis is the second output from tf.nn.moments,\nor a saved moving average thereof."
  name: "v"
  type_attr: "T"
}
input_arg {
  description: "A 1D gamma Tensor with size matching the last dimension of t.\nIf \"scale_after_normalization\" is true, this Tensor will be multiplied\nwith the normalized Tensor."
  name: "gamma"
  type_attr: "T"
}
input_arg {
  description: "4D backprop Tensor." name: "backprop" type_attr: "T"
}
output_arg {
  description: "4D backprop tensor for input."
  name: "dx"
  type_attr: "T"
}
output_arg {
  description: "1D backprop tensor for mean."
  name: "dm"
  type_attr: "T"
}
output_arg {
  description: "1D backprop tensor for variance."
  name: "dv"
  type_attr: "T"
}
output_arg {
  description: "1D backprop tensor for beta."
  name: "db"
  type_attr: "T"
}
output_arg {
  description: "1D backprop tensor for gamma."
  name: "dg"
  type_attr: "T"
}
-}

-- | 

batchFFT3D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
              -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchFFT3D input | eqLengthGuard [] =
    buildOp (opDef "BatchFFT3D")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | 

batchIFFT2D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
               -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchIFFT2D input | eqLengthGuard [] =
    buildOp (opDef "BatchIFFT2D")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | Performs average pooling on the input.
--
-- Each entry in `output` is the mean of the corresponding size `ksize`
-- window in `value`.
avgPool :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                Float] t) =>
           Tensor v1 t -- ^ __value__: 4-D with shape `[batch, height, width, channels]`.
           -> Tensor Value t -- ^ __output__: The average pooled output tensor.
avgPool value | eqLengthGuard [] =
    buildOp (opDef "AvgPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        value
{-
attr {
  description: "The size of the sliding window for each dimension of `value`."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of `value`."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
attr {
  allowed_values {
    list { type: DT_FLOAT type: DT_HALF type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "The average pooled output tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | 

batchFFT2D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
              -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchFFT2D input | eqLengthGuard [] =
    buildOp (opDef "BatchFFT2D")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | 

batchFFT :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
            -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchFFT input | eqLengthGuard [] =
    buildOp (opDef "BatchFFT")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | Given a quantized tensor described by (input, input_min, input_max), outputs a
--
-- range that covers the actual values present in that tensor.  This op is
-- typically used to produce the requested_output_min and requested_output_max for
-- Requantize.
requantizationRange :: forall v1 v2 v3 tinput . (TensorType tinput,
                                                 OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8] tinput) =>
                       Tensor v1 tinput -- ^ __input__
                       -> Tensor v2 Float -- ^ __input_min__: The float value that the minimum quantized input value represents.
                       -> Tensor v3 Float -- ^ __input_max__: The float value that the maximum quantized input value represents.
                       -> (Tensor Value Float, Tensor Value Float)
                       -- ^ (__output_min__, __output_max__)
                       --
                       -- * __output_min__: The computed min output.
                       --
                       -- * __output_max__: the computed max output.
requantizationRange input input_min input_max | eqLengthGuard [] =
    buildOp (opDef "RequantizationRange"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput))
        input input_min input_max
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  description: "The type of the input."
  name: "Tinput"
  type: "type"
}
input_arg { name: "input" type_attr: "Tinput" }
input_arg {
  description: "The float value that the minimum quantized input value represents."
  name: "input_min"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the maximum quantized input value represents."
  name: "input_max"
  type: DT_FLOAT
}
output_arg {
  description: "The computed min output."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "the computed max output."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Convert the quantized 'input' tensor into a lower-precision 'output', using the
--
-- output range specified with 'requested_output_min' and 'requested_output_max'.
-- 
-- [input_min, input_max] are scalar floats that specify the range for the float
-- interpretation of the 'input' data. For example, if input_min is -1.0f and
-- input_max is 1.0f, and we are dealing with quint16 quantized data, then a 0
-- value in the 16-bit data should be interpreted as -1.0f, and a 65535 means 1.0f.
requantize :: forall v1 v2 v3 v4 v5 tinput out_type . (TensorType tinput,
                                                       OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8] tinput,
                                                       TensorType out_type,
                                                       OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8] out_type) =>
              Tensor v1 tinput -- ^ __input__
              -> Tensor v2 Float -- ^ __input_min__: The float value that the minimum quantized input value represents.
              -> Tensor v3 Float -- ^ __input_max__: The float value that the maximum quantized input value represents.
              -> Tensor v4 Float -- ^ __requested_output_min__: The float value that the minimum quantized output value represents.
              -> Tensor v5 Float -- ^ __requested_output_max__: The float value that the maximum quantized output value represents.
              -> (Tensor Value out_type, Tensor Value Float, Tensor Value Float)
              -- ^ (__output__, __output_min__, __output_max__)
              --
              -- * __output__
              --
              -- * __output_min__: The requested_output_min value is copied into this output.
              --
              -- * __output_max__: The requested_output_max value is copied into this output.
requantize input input_min input_max requested_output_min
           requested_output_max | eqLengthGuard [] =
    buildOp (opDef "Requantize"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input input_min input_max requested_output_min requested_output_max
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  description: "The type of the input."
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  description: "The type of the output. Should be a lower bit depth than Tinput."
  name: "out_type"
  type: "type"
}
input_arg { name: "input" type_attr: "Tinput" }
input_arg {
  description: "The float value that the minimum quantized input value represents."
  name: "input_min"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the maximum quantized input value represents."
  name: "input_max"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the minimum quantized output value represents."
  name: "requested_output_min"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the maximum quantized output value represents."
  name: "requested_output_max"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "out_type" }
output_arg {
  description: "The requested_output_min value is copied into this output."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "The requested_output_max value is copied into this output."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Convert the quantized 'input' tensor into a lower-precision 'output', using the
--
-- actual distribution of the values to maximize the usage of the lower bit depth
-- and adjusting the output min and max ranges accordingly.
-- 
-- [input_min, input_max] are scalar floats that specify the range for the float
-- interpretation of the 'input' data. For example, if input_min is -1.0f and
-- input_max is 1.0f, and we are dealing with quint16 quantized data, then a 0
-- value in the 16-bit data should be interpreted as -1.0f, and a 65535 means 1.0f.
-- 
-- This operator tries to squeeze as much precision as possible into an output with
-- a lower bit depth by calculating the actual min and max values found in the
-- data. For example, maybe that quint16 input has no values lower than 16,384 and
-- none higher than 49,152. That means only half the range is actually needed, all
-- the float interpretations are between -0.5f and 0.5f, so if we want to compress
-- the data into a quint8 output, we can use that range rather than the theoretical
-- -1.0f to 1.0f that is suggested by the input min and max.
-- 
-- In practice, this is most useful for taking output from operations like
-- QuantizedMatMul that can produce higher bit-depth outputs than their inputs and
-- may have large potential output ranges, but in practice have a distribution of
-- input values that only uses a small fraction of the possible range. By feeding
-- that output into this operator, we can reduce it from 32 bits down to 8 with
-- minimal loss of accuracy.
quantizeDownAndShrinkRange :: forall v1 v2 v3 tinput
                              out_type . (TensorType tinput,
                                          OneOf '[Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8] tinput,
                                          TensorType out_type,
                                          OneOf '[Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8] out_type) =>
                              Tensor v1 tinput -- ^ __input__
                              -> Tensor v2 Float -- ^ __input_min__: The float value that the minimum quantized input value represents.
                              -> Tensor v3 Float -- ^ __input_max__: The float value that the maximum quantized input value represents.
                              -> (Tensor Value out_type, Tensor Value Float,
                                  Tensor Value Float)
                              -- ^ (__output__, __output_min__, __output_max__)
                              --
                              -- * __output__
                              --
                              -- * __output_min__: The float value that the minimum quantized output value represents.
                              --
                              -- * __output_max__: The float value that the maximum quantized output value represents.
quantizeDownAndShrinkRange input input_min input_max | eqLengthGuard [] =
    buildOp (opDef "QuantizeDownAndShrinkRange"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input input_min input_max
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  description: "The type of the input."
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  description: "The type of the output. Should be a lower bit depth than Tinput."
  name: "out_type"
  type: "type"
}
input_arg { name: "input" type_attr: "Tinput" }
input_arg {
  description: "The float value that the minimum quantized input value represents."
  name: "input_min"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the maximum quantized input value represents."
  name: "input_max"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "out_type" }
output_arg {
  description: "The float value that the minimum quantized output value represents."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the maximum quantized output value represents."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Perform a quantized matrix multiplication of  `a` by the matrix `b`.
--
-- The inputs must be two-dimensional matrices and the inner dimension of
-- `a` (after being transposed if `transpose_a` is non-zero) must match the
-- outer dimension of `b` (after being transposed if `transposed_b` is
-- non-zero).
quantizedMatMul :: forall v1 v2 v3 v4 v5 v6 t1 t2 toutput . (TensorType t1,
                                                             OneOf '[Data.Int.Int16,
                                                                     Data.Int.Int32,
                                                                     Data.Word.Word16,
                                                                     Data.Word.Word8] t1,
                                                             TensorType t2,
                                                             OneOf '[Data.Int.Int16,
                                                                     Data.Int.Int32,
                                                                     Data.Word.Word16,
                                                                     Data.Word.Word8] t2,
                                                             TensorType toutput,
                                                             OneOf '[Data.Int.Int16,
                                                                     Data.Int.Int32,
                                                                     Data.Word.Word16,
                                                                     Data.Word.Word8] toutput) =>
                   Tensor v1 t1 -- ^ __a__: Must be a two-dimensional tensor.
                   -> Tensor v2 t2 -- ^ __b__: Must be a two-dimensional tensor.
                   -> Tensor v3 Float -- ^ __min_a__: The float value that the lowest quantized `a` value represents.
                   -> Tensor v4 Float -- ^ __max_a__: The float value that the highest quantized `a` value represents.
                   -> Tensor v5 Float -- ^ __min_b__: The float value that the lowest quantized `b` value represents.
                   -> Tensor v6 Float -- ^ __max_b__: The float value that the highest quantized `b` value represents.
                   -> (Tensor Value toutput, Tensor Value Float,
                       Tensor Value Float)
                   -- ^ (__out__, __min_out__, __max_out__)
                   --
                   -- * __out__
                   --
                   -- * __min_out__: The float value that the lowest quantized output value represents.
                   --
                   -- * __max_out__: The float value that the highest quantized output value represents.
quantizedMatMul a b min_a max_a min_b max_b | eqLengthGuard [] =
    buildOp (opDef "QuantizedMatMul"
             & opAttr "T1" .~ tensorType (undefined :: t1)
             & opAttr "T2" .~ tensorType (undefined :: t2)
             & opAttr "Toutput" .~ tensorType (undefined :: toutput))
        a b min_a max_a min_b max_b
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T1"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T2"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  default_value { type: DT_QINT32 }
  name: "Toutput"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, `a` is transposed before multiplication."
  name: "transpose_a"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If true, `b` is transposed before multiplication."
  name: "transpose_b"
  type: "bool"
}
input_arg {
  description: "Must be a two-dimensional tensor."
  name: "a"
  type_attr: "T1"
}
input_arg {
  description: "Must be a two-dimensional tensor."
  name: "b"
  type_attr: "T2"
}
input_arg {
  description: "The float value that the lowest quantized `a` value represents."
  name: "min_a"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized `a` value represents."
  name: "max_a"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the lowest quantized `b` value represents."
  name: "min_b"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized `b` value represents."
  name: "max_b"
  type: DT_FLOAT
}
output_arg { name: "out" type_attr: "Toutput" }
output_arg {
  description: "The float value that the lowest quantized output value represents."
  name: "min_out"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized output value represents."
  name: "max_out"
  type: DT_FLOAT
}
-}

-- | Compute the cumulative product of the tensor `x` along `axis`.
--
-- By default, this op performs an inclusive cumprod, which means that the first
-- element of the input is identical to the first element of the output:
-- ```prettyprint
-- tf.cumprod([a, b, c]) ==> [a, a * b, a * b * c]
-- ```
-- 
-- By setting the `exclusive` kwarg to `True`, an exclusive cumprod is
-- performed instead:
-- ```prettyprint
-- tf.cumprod([a, b, c], exclusive=True) ==> [0, a, a * b]
-- ```
-- 
-- By setting the `reverse` kwarg to `True`, the cumprod is performed in the
-- opposite direction:
-- ```prettyprint
-- tf.cumprod([a, b, c], reverse=True) ==> [a * b * c, b * c, c]
-- ```
-- This is more efficient than using separate `tf.reverse` ops.
-- 
-- The `reverse` and `exclusive` kwargs can also be combined:
-- ```prettyprint
-- tf.cumprod([a, b, c], exclusive=True, reverse=True) ==> [b * c, c, 0]
-- ```
cumprod :: forall v1 v2 t tidx . (TensorType t,
                                  OneOf '[(Data.Complex.Complex Double),
                                          (Data.Complex.Complex Float),
                                          Data.Int.Int16, Data.Int.Int32,
                                          Data.Int.Int64, Data.Int.Int8,
                                          Data.Word.Word16, Data.Word.Word8,
                                          Double, Float] t, TensorType tidx,
                                  OneOf '[Data.Int.Int32,
                                          Data.Int.Int64] tidx) =>
           Tensor v1 t -- ^ __x__
           -> Tensor v2 tidx -- ^ __axis__
           -> Tensor Value t -- ^ __out__
cumprod x axis | eqLengthGuard [] =
    buildOp (opDef "Cumprod"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        x axis
{-
attr { default_value { b: false } name: "exclusive" type: "bool" }
attr { default_value { b: false } name: "reverse" type: "bool" }
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "axis" type_attr: "Tidx" }
output_arg { name: "out" type_attr: "T" }
-}

-- | Compute the cumulative sum of the tensor `x` along `axis`.
--
-- By default, this op performs an inclusive cumsum, which means that the first
-- element of the input is identical to the first element of the output:
-- ```prettyprint
-- tf.cumsum([a, b, c]) ==> [a, a + b, a + b + c]
-- ```
-- 
-- By setting the `exclusive` kwarg to `True`, an exclusive cumsum is
-- performed instead:
-- ```prettyprint
-- tf.cumsum([a, b, c], exclusive=True) ==> [0, a, a + b]
-- ```
-- 
-- By setting the `reverse` kwarg to `True`, the cumsum is performed in the
-- opposite direction:
-- ```prettyprint
-- tf.cumsum([a, b, c], reverse=True) ==> [a + b + c, b + c, c]
-- ```
-- This is more efficient than using separate `tf.reverse` ops.
-- 
-- The `reverse` and `exclusive` kwargs can also be combined:
-- ```prettyprint
-- tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0]
-- ```
cumsum :: forall v1 v2 t tidx . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Int.Int16, Data.Int.Int32,
                                         Data.Int.Int64, Data.Int.Int8,
                                         Data.Word.Word16, Data.Word.Word8,
                                         Double, Float] t, TensorType tidx,
                                 OneOf '[Data.Int.Int32,
                                         Data.Int.Int64] tidx) =>
          Tensor v1 t -- ^ __x__
          -> Tensor v2 tidx -- ^ __axis__
          -> Tensor Value t -- ^ __out__
cumsum x axis | eqLengthGuard [] =
    buildOp (opDef "Cumsum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        x axis
{-
attr { default_value { b: false } name: "exclusive" type: "bool" }
attr { default_value { b: false } name: "reverse" type: "bool" }
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "axis" type_attr: "Tidx" }
output_arg { name: "out" type_attr: "T" }
-}

-- | Compute the pairwise cross product.
--
-- `a` and `b` must be the same shape; they can either be simple 3-element vectors,
-- or any shape where the innermost dimension is 3. In the latter case, each pair
-- of corresponding 3-element vectors is cross-multiplied independently.
cross :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
         Tensor v1 t -- ^ __a__: A tensor containing 3-element vectors.
         -> Tensor v2 t -- ^ __b__: Another tensor, of same type and shape as `a`.
         -> Tensor Value t -- ^ __product__: Pairwise cross product of the vectors in `a` and `b`.
cross a b | eqLengthGuard [] =
    buildOp (opDef "Cross"
             & opAttr "T" .~ tensorType (undefined :: t))
        a b
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "A tensor containing 3-element vectors."
  name: "a"
  type_attr: "T"
}
input_arg {
  description: "Another tensor, of same type and shape as `a`."
  name: "b"
  type_attr: "T"
}
output_arg {
  description: "Pairwise cross product of the vectors in `a` and `b`."
  name: "product"
  type_attr: "T"
}
-}

-- | Compute the inverse 3-dimensional discrete Fourier Transform over the inner-most
--
-- 3 dimensions of `input`.
iFFT3D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
          -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most 3
          --   dimensions of `input` are replaced with their inverse 3D Fourier Transform.
          -- 
          -- @compatibility(numpy)
          -- Equivalent to np.fft3
          -- @end_compatibility
iFFT3D input | eqLengthGuard [] =
    buildOp (opDef "IFFT3D")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most 3\n  dimensions of `input` are replaced with their inverse 3D Fourier Transform.\n\n@compatibility(numpy)\nEquivalent to np.fft3\n@end_compatibility"
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Compute the 3-dimensional discrete Fourier Transform over the inner-most 3
--
-- dimensions of `input`.
fFT3D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
         -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most 3
         --   dimensions of `input` are replaced with their 3D Fourier Transform.
         -- 
         -- @compatibility(numpy)
         -- Equivalent to np.fft3
         -- @end_compatibility
fFT3D input | eqLengthGuard [] =
    buildOp (opDef "FFT3D")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most 3\n  dimensions of `input` are replaced with their 3D Fourier Transform.\n\n@compatibility(numpy)\nEquivalent to np.fft3\n@end_compatibility"
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Computes gradients of the maxpooling function.

maxPoolGradWithArgmax :: forall v1 v2 v3 targmax t . (TensorType targmax,
                                                      OneOf '[Data.Int.Int32,
                                                              Data.Int.Int64] targmax,
                                                      TensorType t,
                                                      OneOf '[Data.Word.Word16,
                                                              Float] t) =>
                         Tensor v1 t -- ^ __input__: The original input.
                         -> Tensor v2 t -- ^ __grad__: 4-D with shape `[batch, height, width, channels]`.  Gradients w.r.t. the
                                        -- output of `max_pool`.
                         -> Tensor v3 targmax -- ^ __argmax__: The indices of the maximum values chosen for each output of `max_pool`.
                         -> Tensor Value t -- ^ __output__: Gradients w.r.t. the input of `max_pool`.
maxPoolGradWithArgmax input grad argmax | eqLengthGuard [] =
    buildOp (opDef "MaxPoolGradWithArgmax"
             & opAttr "Targmax" .~ tensorType (undefined :: targmax)
             & opAttr "T" .~ tensorType (undefined :: t))
        input grad argmax
{-
attr {
  description: "The size of the window for each dimension of the input tensor."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the\ninput tensor."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Targmax"
  type: "type"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "The original input." name: "input" type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`.  Gradients w.r.t. the\noutput of `max_pool`."
  name: "grad"
  type_attr: "T"
}
input_arg {
  description: "The indices of the maximum values chosen for each output of `max_pool`."
  name: "argmax"
  type_attr: "Targmax"
}
output_arg {
  description: "Gradients w.r.t. the input of `max_pool`."
  name: "output"
  type_attr: "T"
}
-}

-- | Compute the 2-dimensional discrete Fourier Transform over the inner-most
--
-- 2 dimensions of `input`.
fFT2D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
         -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most 2
         --   dimensions of `input` are replaced with their 2D Fourier Transform.
         -- 
         -- @compatibility(numpy)
         -- Equivalent to np.fft2
         -- @end_compatibility
fFT2D input | eqLengthGuard [] =
    buildOp (opDef "FFT2D")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most 2\n  dimensions of `input` are replaced with their 2D Fourier Transform.\n\n@compatibility(numpy)\nEquivalent to np.fft2\n@end_compatibility"
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Compute the inverse 1-dimensional discrete Fourier Transform over the inner-most
--
-- dimension of `input`.
iFFT :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
        -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most
        -- dimension of `input` is replaced with its inverse 1D Fourier Transform.
iFFT input | eqLengthGuard [] =
    buildOp (opDef "IFFT")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most\ndimension of `input` is replaced with its inverse 1D Fourier Transform."
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Compute the 1-dimensional discrete Fourier Transform over the inner-most
--
-- dimension of `input`.
fFT :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
       -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most
       -- dimension of `input` is replaced with its 1D Fourier Transform.
fFT input | eqLengthGuard [] =
    buildOp (opDef "FFT")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most\ndimension of `input` is replaced with its 1D Fourier Transform."
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Returns the complex conjugate of a complex number.
--
-- Given a tensor `input` of complex numbers, this operation returns a tensor of
-- complex numbers that are the complex conjugate of each element in `input`. The
-- complex numbers in `input` must be of the form \\(a + bj\\), where *a* is the
-- real part and *b* is the imaginary part.
-- 
-- The complex conjugate returned by this operation is of the form \\(a - bj\\).
-- 
-- For example:
-- 
-- ```
-- # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j]
-- tf.conj(input) ==> [-2.25 - 4.75j, 3.25 - 5.75j]
-- ```
conj :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float)] t) =>
        Tensor v1 t -- ^ __input__
        -> Tensor Value t -- ^ __output__
conj input | eqLengthGuard [] =
    buildOp (opDef "Conj"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_COMPLEX64 type: DT_COMPLEX128 } }
  default_value { type: DT_COMPLEX64 }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns the real part of a complex number.
--
-- Given a tensor `input` of complex numbers, this operation returns a tensor of
-- type `float` that is the real part of each element in `input`. All elements in
-- `input` must be complex numbers of the form \\(a + bj\\), where *a* is the real
--  part returned by this operation and *b* is the imaginary part.
-- 
-- For example:
-- 
-- ```
-- # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j]
-- tf.real(input) ==> [-2.25, 3.25]
-- ```
real :: forall v1 t tout . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float)] t,
                            TensorType tout, OneOf '[Double, Float] tout) =>
        Tensor v1 t -- ^ __input__
        -> Tensor Value tout -- ^ __output__
real input | eqLengthGuard [] =
    buildOp (opDef "Real"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        input
{-
attr {
  allowed_values { list { type: DT_COMPLEX64 type: DT_COMPLEX128 } }
  default_value { type: DT_COMPLEX64 }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "Tout"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "Tout" }
-}

-- | Converts two real numbers to a complex number.
--
-- Given a tensor `real` representing the real part of a complex number, and a
-- tensor `imag` representing the imaginary part of a complex number, this
-- operation returns complex numbers elementwise of the form \\(a + bj\\), where
-- *a* represents the `real` part and *b* represents the `imag` part.
-- 
-- The input tensors `real` and `imag` must have the same shape.
-- 
-- For example:
-- 
-- ```
-- # tensor 'real' is [2.25, 3.25]
-- # tensor `imag` is [4.75, 5.75]
-- tf.complex(real, imag) ==> [[2.25 + 4.75j], [3.25 + 5.75j]]
-- ```
complex :: forall v1 v2 t tout . (TensorType t, OneOf '[Double, Float] t,
                                  TensorType tout,
                                  OneOf '[(Data.Complex.Complex Double),
                                          (Data.Complex.Complex Float)] tout) =>
           Tensor v1 t -- ^ __real__
           -> Tensor v2 t -- ^ __imag__
           -> Tensor Value tout -- ^ __out__
complex real imag | eqLengthGuard [] =
    buildOp (opDef "Complex"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        real imag
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_COMPLEX64 type: DT_COMPLEX128 } }
  default_value { type: DT_COMPLEX64 }
  name: "Tout"
  type: "type"
}
input_arg { name: "real" type_attr: "T" }
input_arg { name: "imag" type_attr: "T" }
output_arg { name: "out" type_attr: "Tout" }
-}

-- | Creates a sequence of numbers.
--
-- This operation creates a sequence of numbers that begins at `start` and
-- extends by increments of `delta` up to but not including `limit`.
-- 
-- For example:
-- 
-- ```
-- # 'start' is 3
-- # 'limit' is 18
-- # 'delta' is 3
-- tf.range(start, limit, delta) ==> [3, 6, 9, 12, 15]
-- ```
range :: forall v1 v2 v3 tidx . (TensorType tidx, OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Double,
                                                          Float] tidx) =>
         Tensor v1 tidx -- ^ __start__: 0-D (scalar). First entry in the sequence.
         -> Tensor v2 tidx -- ^ __limit__: 0-D (scalar). Upper limit of sequence, exclusive.
         -> Tensor v3 tidx -- ^ __delta__: 0-D (scalar). Optional. Default is 1. Number that increments `start`.
         -> Tensor Value tidx -- ^ __output__: 1-D.
range start limit delta | eqLengthGuard [] =
    buildOp (opDef "Range"
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        start limit delta
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT type: DT_DOUBLE type: DT_INT32 type: DT_INT64
    }
  }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "0-D (scalar). First entry in the sequence."
  name: "start"
  type_attr: "Tidx"
}
input_arg {
  description: "0-D (scalar). Upper limit of sequence, exclusive."
  name: "limit"
  type_attr: "Tidx"
}
input_arg {
  description: "0-D (scalar). Optional. Default is 1. Number that increments `start`."
  name: "delta"
  type_attr: "Tidx"
}
output_arg { description: "1-D." name: "output" type_attr: "Tidx" }
-}

-- | Computes the "logical or" of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
any :: forall v1 v2 tidx . (TensorType tidx, OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] tidx) =>
       Tensor v1 Bool -- ^ __input__: The tensor to reduce.
       -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
       -> Tensor Value Bool -- ^ __output__: The reduced tensor.
any input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Any"
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type: DT_BOOL
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type: DT_BOOL
}
-}

-- | Computes the mean along sparse segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Like `SegmentMean`, but `segment_ids` can have rank less than `data`'s first
-- dimension, selecting a subset of dimension 0, specified by `indices`.
sparseSegmentMean :: forall v1 v2 v3 t tidx . (TensorType t, OneOf '[Double,
                                                                     Float] t,
                                               TensorType tidx,
                                               OneOf '[Data.Int.Int32,
                                                       Data.Int.Int64] tidx) =>
                     Tensor v1 t -- ^ __data__
                     -> Tensor v2 tidx -- ^ __indices__: A 1-D tensor. Has same rank as `segment_ids`.
                     -> Tensor v3 Data.Int.Int32 -- ^ __segment_ids__: A 1-D tensor. Values should be sorted and can be repeated.
                     -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
                     -- has size `k`, the number of segments.
sparseSegmentMean data' indices segment_ids | eqLengthGuard [] =
    buildOp (opDef "SparseSegmentMean"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        data' indices segment_ids
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor. Has same rank as `segment_ids`."
  name: "indices"
  type_attr: "Tidx"
}
input_arg {
  description: "A 1-D tensor. Values should be sorted and can be repeated."
  name: "segment_ids"
  type: DT_INT32
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the sum along sparse segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Like `SegmentSum`, but `segment_ids` can have rank less than `data`'s first
-- dimension, selecting a subset of dimension 0, specified by `indices`.
-- 
-- For example:
-- 
-- ```prettyprint
-- c = tf.constant([[1,2,3,4], [-1,-2,-3,-4], [5,6,7,8]])
-- 
-- # Select two rows, one segment.
-- tf.sparse_segment_sum(c, tf.constant([0, 1]), tf.constant([0, 0]))
--   ==> [[0 0 0 0]]
-- 
-- # Select two rows, two segment.
-- tf.sparse_segment_sum(c, tf.constant([0, 1]), tf.constant([0, 1]))
--   ==> [[ 1  2  3  4]
--        [-1 -2 -3 -4]]
-- 
-- # Select all rows, two segments.
-- tf.sparse_segment_sum(c, tf.constant([0, 1, 2]), tf.constant([0, 0, 1]))
--   ==> [[0 0 0 0]
--        [5 6 7 8]]
-- 
-- # Which is equivalent to:
-- tf.segment_sum(c, tf.constant([0, 0, 1]))
-- ```
sparseSegmentSum :: forall v1 v2 v3 t tidx . (TensorType t,
                                              OneOf '[Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word16,
                                                      Data.Word.Word8, Double,
                                                      Float] t, TensorType tidx,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] tidx) =>
                    Tensor v1 t -- ^ __data__
                    -> Tensor v2 tidx -- ^ __indices__: A 1-D tensor. Has same rank as `segment_ids`.
                    -> Tensor v3 Data.Int.Int32 -- ^ __segment_ids__: A 1-D tensor. Values should be sorted and can be repeated.
                    -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
                    -- has size `k`, the number of segments.
sparseSegmentSum data' indices segment_ids | eqLengthGuard [] =
    buildOp (opDef "SparseSegmentSum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        data' indices segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor. Has same rank as `segment_ids`."
  name: "indices"
  type_attr: "Tidx"
}
input_arg {
  description: "A 1-D tensor. Values should be sorted and can be repeated."
  name: "segment_ids"
  type: DT_INT32
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the sum along segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Computes a tensor such that
-- `(output[i] = sum_{j...} data[j...]` where the sum is over tuples `j...` such
-- that `segment_ids[j...] == i`.  Unlike `SegmentSum`, `segment_ids`
-- need not be sorted and need not cover all values in the full
-- range of valid values.
-- 
-- If the sum is empty for a given segment ID `i`, `output[i] = 0`.
-- 
-- `num_segments` should equal the number of distinct segment IDs.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/UnsortedSegmentSum.png" alt>
-- </div>
unsortedSegmentSum :: forall v1 v2 v3 t tindices . (TensorType t,
                                                    OneOf '[(Data.Complex.Complex Double),
                                                            (Data.Complex.Complex Float),
                                                            Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double, Float] t,
                                                    TensorType tindices,
                                                    OneOf '[Data.Int.Int32,
                                                            Data.Int.Int64] tindices) =>
                      Tensor v1 t -- ^ __data__
                      -> Tensor v2 tindices -- ^ __segment_ids__: A tensor whose shape is a prefix of `data.shape`.
                      -> Tensor v3 Data.Int.Int32 -- ^ __num_segments__
                      -> Tensor Value t -- ^ __output__: Has same shape as data, except for the first `segment_ids.rank`
                      -- dimensions, which are replaced with a single dimension which has size
                      -- `num_segments`.
unsortedSegmentSum data' segment_ids num_segments | eqLengthGuard [] =
    buildOp (opDef "UnsortedSegmentSum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids num_segments
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A tensor whose shape is a prefix of `data.shape`."
  name: "segment_ids"
  type_attr: "Tindices"
}
input_arg { name: "num_segments" type: DT_INT32 }
output_arg {
  description: "Has same shape as data, except for the first `segment_ids.rank`\ndimensions, which are replaced with a single dimension which has size\n`num_segments`."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the minimum along segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Computes a tensor such that
-- \\(output_i = \min_j(data_j)\\) where `min` is over `j` such
-- that `segment_ids[j] == i`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/SegmentMin.png" alt>
-- </div>
segmentMin :: forall v1 v2 t tindices . (TensorType t, OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Int.Int64,
                                                               Data.Int.Int8,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8,
                                                               Double, Float] t,
                                         TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor v1 t -- ^ __data__
              -> Tensor v2 tindices -- ^ __segment_ids__: A 1-D tensor whose rank is equal to the rank of `data`'s
                                    -- first dimension.  Values should be sorted and can be repeated.
              -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
              -- has size `k`, the number of segments.
segmentMin data' segment_ids | eqLengthGuard [] =
    buildOp (opDef "SegmentMin"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension.  Values should be sorted and can be repeated."
  name: "segment_ids"
  type_attr: "Tindices"
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the product along segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Computes a tensor such that
-- \\(output_i = \prod_j data_j\\) where the product is over `j` such
-- that `segment_ids[j] == i`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/SegmentProd.png" alt>
-- </div>
segmentProd :: forall v1 v2 t tindices . (TensorType t,
                                          OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t, TensorType tindices,
                                          OneOf '[Data.Int.Int32,
                                                  Data.Int.Int64] tindices) =>
               Tensor v1 t -- ^ __data__
               -> Tensor v2 tindices -- ^ __segment_ids__: A 1-D tensor whose rank is equal to the rank of `data`'s
                                     -- first dimension.  Values should be sorted and can be repeated.
               -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
               -- has size `k`, the number of segments.
segmentProd data' segment_ids | eqLengthGuard [] =
    buildOp (opDef "SegmentProd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension.  Values should be sorted and can be repeated."
  name: "segment_ids"
  type_attr: "Tindices"
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the mean along segments of a tensor.
--
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
-- 
-- Computes a tensor such that
-- \\(output_i = \frac{\sum_j data_j}{N}\\) where `mean` is
-- over `j` such that `segment_ids[j] == i` and `N` is the total number of
-- values summed.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/SegmentMean.png" alt>
-- </div>
segmentMean :: forall v1 v2 t tindices . (TensorType t, OneOf '[Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Int.Int64,
                                                                Data.Int.Int8,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8,
                                                                Double,
                                                                Float] t,
                                          TensorType tindices,
                                          OneOf '[Data.Int.Int32,
                                                  Data.Int.Int64] tindices) =>
               Tensor v1 t -- ^ __data__
               -> Tensor v2 tindices -- ^ __segment_ids__: A 1-D tensor whose rank is equal to the rank of `data`'s
                                     -- first dimension.  Values should be sorted and can be repeated.
               -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
               -- has size `k`, the number of segments.
segmentMean data' segment_ids | eqLengthGuard [] =
    buildOp (opDef "SegmentMean"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension.  Values should be sorted and can be repeated."
  name: "segment_ids"
  type_attr: "Tindices"
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the sum along segments of a tensor.
--
-- Read [the section on Segmentation](../../api_docs/python/math_ops.md#segmentation)
-- for an explanation of segments.
-- 
-- Computes a tensor such that
-- \\(output_i = \sum_j data_j\\) where sum is over `j` such
-- that `segment_ids[j] == i`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/SegmentSum.png" alt>
-- </div>
segmentSum :: forall v1 v2 t tindices . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t, TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor v1 t -- ^ __data__
              -> Tensor v2 tindices -- ^ __segment_ids__: A 1-D tensor whose rank is equal to the rank of `data`'s
                                    -- first dimension.  Values should be sorted and can be repeated.
              -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
              -- has size `k`, the number of segments.
segmentSum data' segment_ids | eqLengthGuard [] =
    buildOp (opDef "SegmentSum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension.  Values should be sorted and can be repeated."
  name: "segment_ids"
  type_attr: "Tindices"
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns the index with the smallest value across dimensions of a tensor.

argMin :: forall v1 v2 t tidx . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Int.Int16, Data.Int.Int32,
                                         Data.Int.Int64, Data.Int.Int8,
                                         Data.Word.Word16, Data.Word.Word8,
                                         Double, Float] t, TensorType tidx,
                                 OneOf '[Data.Int.Int32,
                                         Data.Int.Int64] tidx) =>
          Tensor v1 t -- ^ __input__
          -> Tensor v2 tidx -- ^ __dimension__: int32, 0 <= dimension < rank(input).  Describes which dimension
                            -- of the input Tensor to reduce across. For vectors, use dimension = 0.
          -> Tensor Value Data.Int.Int64 -- ^ __output__
argMin input dimension | eqLengthGuard [] =
    buildOp (opDef "ArgMin"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input dimension
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "int32, 0 <= dimension < rank(input).  Describes which dimension\nof the input Tensor to reduce across. For vectors, use dimension = 0."
  name: "dimension"
  type_attr: "Tidx"
}
output_arg { name: "output" type: DT_INT64 }
-}

-- | Computes the maximum of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
max :: forall v1 v2 t tidx . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t, TensorType tidx,
                              OneOf '[Data.Int.Int32, Data.Int.Int64] tidx) =>
       Tensor v1 t -- ^ __input__: The tensor to reduce.
       -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
       -> Tensor Value t -- ^ __output__: The reduced tensor.
max input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Max"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type_attr: "T"
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type_attr: "T"
}
-}

-- | Computes the minimum of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
min :: forall v1 v2 t tidx . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t, TensorType tidx,
                              OneOf '[Data.Int.Int32, Data.Int.Int64] tidx) =>
       Tensor v1 t -- ^ __input__: The tensor to reduce.
       -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
       -> Tensor Value t -- ^ __output__: The reduced tensor.
min input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Min"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type_attr: "T"
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type_attr: "T"
}
-}

-- | Computes the product of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
prod :: forall v1 v2 t tidx . (TensorType t,
                               OneOf '[(Data.Complex.Complex Double),
                                       (Data.Complex.Complex Float),
                                       Data.Int.Int16, Data.Int.Int32,
                                       Data.Int.Int64, Data.Int.Int8,
                                       Data.Word.Word16, Data.Word.Word8,
                                       Double, Float] t, TensorType tidx,
                               OneOf '[Data.Int.Int32, Data.Int.Int64] tidx) =>
        Tensor v1 t -- ^ __input__: The tensor to reduce.
        -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
        -> Tensor Value t -- ^ __output__: The reduced tensor.
prod input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Prod"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type_attr: "T"
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type_attr: "T"
}
-}

-- | Computes the sum of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
sum :: forall v1 v2 t tidx . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t, TensorType tidx,
                              OneOf '[Data.Int.Int32, Data.Int.Int64] tidx) =>
       Tensor v1 t -- ^ __input__: The tensor to reduce.
       -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
       -> Tensor Value t -- ^ __output__: The reduced tensor.
sum input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Sum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type_attr: "T"
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type_attr: "T"
}
-}

-- | Multiply matrix "a" by matrix "b".
--
-- The inputs must be two-dimensional matrices and the inner dimension of "a" must
-- match the outer dimension of "b". This op is optimized for the case where at
-- least one of "a" or "b" is sparse. The breakeven for using this versus a dense
-- matrix multiply on one platform was 30% zero values in the sparse matrix.
sparseMatMul :: forall v1 v2 ta tb . (TensorType ta, OneOf '[Data.Word.Word16,
                                                             Float] ta,
                                      TensorType tb, OneOf '[Data.Word.Word16,
                                                             Float] tb) =>
                Tensor v1 ta -- ^ __a__
                -> Tensor v2 tb -- ^ __b__
                -> Tensor Value Float -- ^ __product__
sparseMatMul a b | eqLengthGuard [] =
    buildOp (opDef "SparseMatMul"
             & opAttr "Ta" .~ tensorType (undefined :: ta)
             & opAttr "Tb" .~ tensorType (undefined :: tb))
        a b
{-
attr {
  default_value { b: false } name: "transpose_a" type: "bool"
}
attr {
  default_value { b: false } name: "transpose_b" type: "bool"
}
attr {
  default_value { b: false } name: "a_is_sparse" type: "bool"
}
attr {
  default_value { b: false } name: "b_is_sparse" type: "bool"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_BFLOAT16 } }
  default_value { type: DT_FLOAT }
  name: "Ta"
  type: "type"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_BFLOAT16 } }
  default_value { type: DT_FLOAT }
  name: "Tb"
  type: "type"
}
input_arg { name: "a" type_attr: "Ta" }
input_arg { name: "b" type_attr: "Tb" }
output_arg { name: "product" type: DT_FLOAT }
-}

-- | Multiply the matrix "a" by the matrix "b".
--
-- The inputs must be two-dimensional matrices and the inner dimension of
-- "a" (after being transposed if transpose_a is true) must match the
-- outer dimension of "b" (after being transposed if transposed_b is
-- true).
-- 
-- *Note*: The default kernel implementation for MatMul on GPUs uses
-- cublas.
matMul :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int32,
                                                  Data.Word.Word16, Double,
                                                  Float] t) =>
          Tensor v1 t -- ^ __a__
          -> Tensor v2 t -- ^ __b__
          -> Tensor Value t -- ^ __product__
matMul a b | eqLengthGuard [] =
    buildOp (opDef "MatMul"
             & opAttr "T" .~ tensorType (undefined :: t))
        a b
{-
attr {
  default_value { b: false }
  description: "If true, \"a\" is transposed before multiplication."
  name: "transpose_a"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If true, \"b\" is transposed before multiplication."
  name: "transpose_b"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "a" type_attr: "T" }
input_arg { name: "b" type_attr: "T" }
output_arg { name: "product" type_attr: "T" }
-}

-- | Returns the truth value of x AND y element-wise.
--
-- *NOTE*: `LogicalAnd` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
logicalAnd :: Tensor v1 Bool -- ^ __x__
              -> Tensor v2 Bool -- ^ __y__
              -> Tensor Value Bool -- ^ __z__
logicalAnd x y | eqLengthGuard [] =
    buildOp (opDef "LogicalAnd")
        x y
{-
input_arg { name: "x" type: DT_BOOL }
input_arg { name: "y" type: DT_BOOL }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Returns the truth value of (x == y) element-wise.
--
-- *NOTE*: `Equal` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
equal :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Bool,
                                                 Data.ByteString.ByteString,
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor v2 t -- ^ __y__
         -> Tensor Value Bool -- ^ __z__
equal x y | eqLengthGuard [] =
    buildOp (opDef "Equal"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_QUINT8
      type: DT_QINT8
      type: DT_QINT32
      type: DT_STRING
      type: DT_BOOL
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Returns the truth value of (x >= y) element-wise.
--
-- *NOTE*: `GreaterEqual` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
greaterEqual :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word16,
                                                        Data.Word.Word8, Double,
                                                        Float] t) =>
                Tensor v1 t -- ^ __x__
                -> Tensor v2 t -- ^ __y__
                -> Tensor Value Bool -- ^ __z__
greaterEqual x y | eqLengthGuard [] =
    buildOp (opDef "GreaterEqual"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Returns the truth value of (x <= y) element-wise.
--
-- *NOTE*: `LessEqual` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
lessEqual :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                     Data.Int.Int32,
                                                     Data.Int.Int64,
                                                     Data.Int.Int8,
                                                     Data.Word.Word16,
                                                     Data.Word.Word8, Double,
                                                     Float] t) =>
             Tensor v1 t -- ^ __x__
             -> Tensor v2 t -- ^ __y__
             -> Tensor Value Bool -- ^ __z__
lessEqual x y | eqLengthGuard [] =
    buildOp (opDef "LessEqual"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Returns the truth value of (x < y) element-wise.
--
-- *NOTE*: `Less` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
less :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                                Data.Int.Int64, Data.Int.Int8,
                                                Data.Word.Word16,
                                                Data.Word.Word8, Double,
                                                Float] t) =>
        Tensor v1 t -- ^ __x__
        -> Tensor v2 t -- ^ __y__
        -> Tensor Value Bool -- ^ __z__
less x y | eqLengthGuard [] =
    buildOp (opDef "Less"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Compute the polygamma function \\(\psi^{(n)}(x)\\).
--
-- The polygamma function is defined as:
-- 
-- ```
-- \psi^{(n)}(x) = \frac{d^n}{dx^n} \psi(x)
-- ```
-- where \\(\psi(x)\\) is the digamma function.
polygamma :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
             Tensor v1 t -- ^ __a__
             -> Tensor v2 t -- ^ __x__
             -> Tensor Value t -- ^ __z__
polygamma a x | eqLengthGuard [] =
    buildOp (opDef "Polygamma"
             & opAttr "T" .~ tensorType (undefined :: t))
        a x
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "a" type_attr: "T" }
input_arg { name: "x" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Compute the lower regularized incomplete Gamma function `Q(a, x)`.
--
-- The lower regularized incomplete Gamma function is defined as:
-- 
-- ```
-- P(a, x) = gamma(a, x) / Gamma(a) = 1 - Q(a, x)
-- ```
-- where
-- ```
-- gamma(a, x) = int_{0}^{x} t^{a-1} exp(-t) dt
-- ```
-- is the lower incomplete Gamma function.
-- 
-- Note, above `Q(a, x)` (`Igammac`) is the upper regularized complete
-- Gamma function.
igamma :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
          Tensor v1 t -- ^ __a__
          -> Tensor v2 t -- ^ __x__
          -> Tensor Value t -- ^ __z__
igamma a x | eqLengthGuard [] =
    buildOp (opDef "Igamma"
             & opAttr "T" .~ tensorType (undefined :: t))
        a x
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "a" type_attr: "T" }
input_arg { name: "x" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Compute the upper regularized incomplete Gamma function `Q(a, x)`.
--
-- The upper regularized incomplete Gamma function is defined as:
-- 
-- ```
-- Q(a, x) = Gamma(a, x) / Gamma(a) = 1 - P(a, x)
-- ```
-- where
-- ```
-- Gamma(a, x) = int_{x}^{\infty} t^{a-1} exp(-t) dt
-- ```
-- is the upper incomplete Gama function.
-- 
-- Note, above `P(a, x)` (`Igamma`) is the lower regularized complete
-- Gamma function.
igammac :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
           Tensor v1 t -- ^ __a__
           -> Tensor v2 t -- ^ __x__
           -> Tensor Value t -- ^ __z__
igammac a x | eqLengthGuard [] =
    buildOp (opDef "Igammac"
             & opAttr "T" .~ tensorType (undefined :: t))
        a x
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "a" type_attr: "T" }
input_arg { name: "x" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns element-wise remainder of division.
--
-- *NOTE*: `Mod` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
mod :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32, Data.Int.Int64,
                                               Double, Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
mod x y | eqLengthGuard [] =
    buildOp (opDef "Mod"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_INT32 type: DT_INT64 type: DT_FLOAT type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns the min of x and y (i.e. x < y ? x : y) element-wise.
--
-- *NOTE*: `Minimum` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
minimum :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Word.Word16, Double,
                                                   Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor v2 t -- ^ __y__
           -> Tensor Value t -- ^ __z__
minimum x y | eqLengthGuard [] =
    buildOp (opDef "Minimum"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns the max of x and y (i.e. x > y ? x : y) element-wise.
--
-- *NOTE*: `Maximum` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
maximum :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Word.Word16, Double,
                                                   Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor v2 t -- ^ __y__
           -> Tensor Value t -- ^ __z__
maximum x y | eqLengthGuard [] =
    buildOp (opDef "Maximum"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns (x - y)(x - y) element-wise.
--
-- *NOTE*: `SquaredDifference` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
squaredDifference :: forall v1 v2 t . (TensorType t,
                                       OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int32, Data.Int.Int64,
                                               Data.Word.Word16, Double,
                                               Float] t) =>
                     Tensor v1 t -- ^ __x__
                     -> Tensor v2 t -- ^ __y__
                     -> Tensor Value t -- ^ __z__
squaredDifference x y | eqLengthGuard [] =
    buildOp (opDef "SquaredDifference"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes softplus gradients for a softplus operation.

softplusGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word16,
                                                        Data.Word.Word8, Double,
                                                        Float] t) =>
                Tensor v1 t -- ^ __gradients__: The backpropagated gradients to the corresponding softplus operation.
                -> Tensor v2 t -- ^ __features__: The features passed as input to the corresponding softplus operation.
                -> Tensor Value t -- ^ __backprops__: The gradients: `gradients / (1 + exp(-features))`.
softplusGrad gradients features | eqLengthGuard [] =
    buildOp (opDef "SoftplusGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        gradients features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The backpropagated gradients to the corresponding softplus operation."
  name: "gradients"
  type_attr: "T"
}
input_arg {
  description: "The features passed as input to the corresponding softplus operation."
  name: "features"
  type_attr: "T"
}
output_arg {
  description: "The gradients: `gradients / (1 + exp(-features))`."
  name: "backprops"
  type_attr: "T"
}
-}

-- | BatchToSpace for 4-D tensors of type T.
--
-- This is a legacy version of the more general BatchToSpaceND.
-- 
-- Rearranges (permutes) data from batch into blocks of spatial data, followed by
-- cropping. This is the reverse transformation of SpaceToBatch. More specifically,
-- this op outputs a copy of the input tensor where values from the `batch`
-- dimension are moved in spatial blocks to the `height` and `width` dimensions,
-- followed by cropping along the `height` and `width` dimensions.
batchToSpace :: forall v1 v2 t tidx . (TensorType t, TensorType tidx,
                                       OneOf '[Data.Int.Int32,
                                               Data.Int.Int64] tidx) =>
                Data.Int.Int64 -- ^ __block_size__
                -> Tensor v1 t -- ^ __input__: 4-D tensor with shape
                               -- `[batch*block_size*block_size, height_pad/block_size, width_pad/block_size,
                               --   depth]`. Note that the batch size of the input tensor must be divisible by
                               -- `block_size * block_size`.
                -> Tensor v2 tidx -- ^ __crops__: 2-D tensor of non-negative integers with shape `[2, 2]`. It specifies
                                  -- how many elements to crop from the intermediate result across the spatial
                                  -- dimensions as follows:
                                  -- 
                                  --     crops = [[crop_top, crop_bottom], [crop_left, crop_right]]
                -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, height, width, depth]`, where:
                -- 
                --       height = height_pad - crop_top - crop_bottom
                --       width = width_pad - crop_left - crop_right
                -- 
                -- The attr `block_size` must be greater than one. It indicates the block size.
                -- 
                -- Some examples:
                -- 
                -- (1) For the following input of shape `[4, 1, 1, 1]` and block_size of 2:
                -- 
                -- ```prettyprint
                -- [[[[1]]], [[[2]]], [[[3]]], [[[4]]]]
                -- ```
                -- 
                -- The output tensor has shape `[1, 2, 2, 1]` and value:
                -- 
                -- ```prettyprint
                -- x = [[[[1], [2]], [[3], [4]]]]
                -- ```
                -- 
                -- (2) For the following input of shape `[4, 1, 1, 3]` and block_size of 2:
                -- 
                -- ```prettyprint
                -- [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]
                -- ```
                -- 
                -- The output tensor has shape `[1, 2, 2, 3]` and value:
                -- 
                -- ```prettyprint
                -- x = [[[[1, 2, 3], [4, 5, 6]],
                --       [[7, 8, 9], [10, 11, 12]]]]
                -- ```
                -- 
                -- (3) For the following input of shape `[4, 2, 2, 1]` and block_size of 2:
                -- 
                -- ```prettyprint
                -- x = [[[[1], [3]], [[5], [7]]],
                --      [[[2], [4]], [[10], [12]]],
                --      [[[5], [7]], [[13], [15]]],
                --      [[[6], [8]], [[14], [16]]]]
                -- ```
                -- 
                -- The output tensor has shape `[1, 4, 4, 1]` and value:
                -- 
                -- ```prettyprint
                -- x = [[[1],   [2],  [3],  [4]],
                --      [[5],   [6],  [7],  [8]],
                --      [[9],  [10], [11],  [12]],
                --      [[13], [14], [15],  [16]]]
                -- ```
                -- 
                -- (4) For the following input of shape `[8, 1, 2, 1]` and block_size of 2:
                -- 
                -- ```prettyprint
                -- x = [[[[1], [3]]], [[[9], [11]]], [[[2], [4]]], [[[10], [12]]],
                --      [[[5], [7]]], [[[13], [15]]], [[[6], [8]]], [[[14], [16]]]]
                -- ```
                -- 
                -- The output tensor has shape `[2, 2, 4, 1]` and value:
                -- 
                -- ```prettyprint
                -- x = [[[[1], [3]], [[5], [7]]],
                --      [[[2], [4]], [[10], [12]]],
                --      [[[5], [7]], [[13], [15]]],
                --      [[[6], [8]], [[14], [16]]]]
                -- ```
batchToSpace block_size input crops | eqLengthGuard [] =
    buildOp (opDef "BatchToSpace"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx)
             & opAttr "block_size" .~ block_size)
        input crops
{-
attr { name: "T" type: "type" }
attr {
  has_minimum: true minimum: 2 name: "block_size" type: "int"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "4-D tensor with shape\n`[batch*block_size*block_size, height_pad/block_size, width_pad/block_size,\n  depth]`. Note that the batch size of the input tensor must be divisible by\n`block_size * block_size`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "2-D tensor of non-negative integers with shape `[2, 2]`. It specifies\nhow many elements to crop from the intermediate result across the spatial\ndimensions as follows:\n\n    crops = [[crop_top, crop_bottom], [crop_left, crop_right]]"
  name: "crops"
  type_attr: "Tidx"
}
output_arg {
  description: "4-D with shape `[batch, height, width, depth]`, where:\n\n      height = height_pad - crop_top - crop_bottom\n      width = width_pad - crop_left - crop_right\n\nThe attr `block_size` must be greater than one. It indicates the block size.\n\nSome examples:\n\n(1) For the following input of shape `[4, 1, 1, 1]` and block_size of 2:\n\n```prettyprint\n[[[[1]]], [[[2]]], [[[3]]], [[[4]]]]\n```\n\nThe output tensor has shape `[1, 2, 2, 1]` and value:\n\n```prettyprint\nx = [[[[1], [2]], [[3], [4]]]]\n```\n\n(2) For the following input of shape `[4, 1, 1, 3]` and block_size of 2:\n\n```prettyprint\n[[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]\n```\n\nThe output tensor has shape `[1, 2, 2, 3]` and value:\n\n```prettyprint\nx = [[[[1, 2, 3], [4, 5, 6]],\n      [[7, 8, 9], [10, 11, 12]]]]\n```\n\n(3) For the following input of shape `[4, 2, 2, 1]` and block_size of 2:\n\n```prettyprint\nx = [[[[1], [3]], [[5], [7]]],\n     [[[2], [4]], [[10], [12]]],\n     [[[5], [7]], [[13], [15]]],\n     [[[6], [8]], [[14], [16]]]]\n```\n\nThe output tensor has shape `[1, 4, 4, 1]` and value:\n\n```prettyprint\nx = [[[1],   [2],  [3],  [4]],\n     [[5],   [6],  [7],  [8]],\n     [[9],  [10], [11],  [12]],\n     [[13], [14], [15],  [16]]]\n```\n\n(4) For the following input of shape `[8, 1, 2, 1]` and block_size of 2:\n\n```prettyprint\nx = [[[[1], [3]]], [[[9], [11]]], [[[2], [4]]], [[[10], [12]]],\n     [[[5], [7]]], [[[13], [15]]], [[[6], [8]]], [[[14], [16]]]]\n```\n\nThe output tensor has shape `[2, 2, 4, 1]` and value:\n\n```prettyprint\nx = [[[[1], [3]], [[5], [7]]],\n     [[[2], [4]], [[10], [12]]],\n     [[[5], [7]], [[13], [15]]],\n     [[[6], [8]], [[14], [16]]]]\n```"
  name: "output"
  type_attr: "T"
}
-}

-- | Returns x * y element-wise.
--
-- *NOTE*: `Mul` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
mul :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int16, Data.Int.Int32,
                                               Data.Int.Int64, Data.Int.Int8,
                                               Data.Word.Word16,
                                               Data.Word.Word8, Double,
                                               Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
mul x y | eqLengthGuard [] =
    buildOp (opDef "Mul"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns element-wise integer closest to x.
--
-- If the result is midway between two representable values,
-- the even representable is chosen.
-- For example:
-- 
-- ```
-- rint(-1.5) ==> -2.0
-- rint(0.5000001) ==> 1.0
-- rint([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) ==> [-2., -2., -0., 0., 2., 2., 2.]
-- ```
rint :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
        Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
rint x | eqLengthGuard [] =
    buildOp (opDef "Rint"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Returns element-wise smallest integer in not less than x.

ceil :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
ceil x | eqLengthGuard [] =
    buildOp (opDef "Ceil"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Returns element-wise largest integer not greater than x.

floor :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value t -- ^ __y__
floor x | eqLengthGuard [] =
    buildOp (opDef "Floor"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Performs 3D max pooling on the input.

maxPool3D :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
             Tensor v1 t -- ^ __input__: Shape `[batch, depth, rows, cols, channels]` tensor to pool over.
             -> Tensor Value t -- ^ __output__: The max pooled output tensor.
maxPool3D input | eqLengthGuard [] =
    buildOp (opDef "MaxPool3D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  description: "1-D tensor of length 5. The size of the window for each dimension of\nthe input tensor. Must have `ksize[0] = ksize[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape `[batch, depth, rows, cols, channels]` tensor to pool over."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The max pooled output tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns which elements of x are Inf.
--
-- @compatibility(numpy)
-- Equivalent to np.isinf
-- @end_compatibility
isInf :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value Bool -- ^ __y__
isInf x | eqLengthGuard [] =
    buildOp (opDef "IsInf"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type: DT_BOOL }
-}

-- | Computes the gradients of depthwise convolution with respect to the input.

depthwiseConv2dNativeBackpropInput :: forall v1 v2 v3 t . (TensorType t,
                                                           OneOf '[Double,
                                                                   Float] t) =>
                                      Tensor v1 Data.Int.Int32 -- ^ __input_sizes__: An integer vector representing the shape of `input`,
                                                               -- where `input` is a 4-D `[batch, height, width, channels]` tensor.
                                      -> Tensor v2 t -- ^ __filter__: 4-D with shape
                                                     -- `[filter_height, filter_width, in_channels, depthwise_multiplier]`.
                                      -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, out_channels]`.
                                                     -- Gradients w.r.t. the output of the convolution.
                                      -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, in_height, in_width, in_channels]`.  Gradient
                                      -- w.r.t. the input of the convolution.
depthwiseConv2dNativeBackpropInput input_sizes filter
                                   out_backprop | eqLengthGuard [] =
    buildOp (opDef "DepthwiseConv2dNativeBackpropInput"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_sizes filter out_backprop
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\nof the convolution."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "An integer vector representing the shape of `input`,\nwhere `input` is a 4-D `[batch, height, width, channels]` tensor."
  name: "input_sizes"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, depthwise_multiplier]`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, out_channels]`.\nGradients w.r.t. the output of the convolution."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`.  Gradient\nw.r.t. the input of the convolution."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns which elements of x are NaN.
--
-- @compatibility(numpy)
-- Equivalent to np.isnan
-- @end_compatibility
isNan :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value Bool -- ^ __y__
isNan x | eqLengthGuard [] =
    buildOp (opDef "IsNan"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type: DT_BOOL }
-}

-- | Computes natural logarithm of (1 + x) element-wise.
--
-- I.e., \\(y = \log_e (1 + x)\\).
log1p :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                              (Data.Complex.Complex Float),
                                              Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value t -- ^ __y__
log1p x | eqLengthGuard [] =
    buildOp (opDef "Log1p"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes asin of x element-wise.

asin :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int32, Data.Int.Int64,
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
asin x | eqLengthGuard [] =
    buildOp (opDef "Asin"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Finds values and indices of the `k` largest elements for the last dimension.
--
-- If the input is a vector (rank-1), finds the `k` largest entries in the vector
-- and outputs their values and indices as vectors.  Thus `values[j]` is the
-- `j`-th largest entry in `input`, and its index is `indices[j]`.
-- 
-- For matrices (resp. higher rank input), computes the top `k` entries in each
-- row (resp. vector along the last dimension).  Thus,
-- 
--     values.shape = indices.shape = input.shape[:-1] + [k]
-- 
-- If two elements are equal, the lower-index element appears first.
-- 
-- This is the same as `TopK`, but takes `k` as in input rather than an attr.
topKV2 :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
          Tensor v1 t -- ^ __input__: 1-D or higher with last dimension at least `k`.
          -> Tensor v2 Data.Int.Int32 -- ^ __k__: 0-D.  Number of top elements to look for along the last dimension (along each
                                      -- row for matrices).
          -> (Tensor Value t, Tensor Value Data.Int.Int32)
          -- ^ (__values__, __indices__)
          --
          -- * __values__: The `k` largest elements along each last dimensional slice.
          --
          -- * __indices__: The indices of `values` within the last dimension of `input`.
topKV2 input k | eqLengthGuard [] =
    buildOp (opDef "TopKV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input k
{-
attr {
  default_value { b: true }
  description: "If true the resulting `k` elements will be sorted by the values in\ndescending order."
  name: "sorted"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D or higher with last dimension at least `k`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "0-D.  Number of top elements to look for along the last dimension (along each\nrow for matrices)."
  name: "k"
  type: DT_INT32
}
output_arg {
  description: "The `k` largest elements along each last dimensional slice."
  name: "values"
  type_attr: "T"
}
output_arg {
  description: "The indices of `values` within the last dimension of `input`."
  name: "indices"
  type: DT_INT32
}
-}

-- | Computes cos of x element-wise.

cos :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
cos x | eqLengthGuard [] =
    buildOp (opDef "Cos"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes sin of x element-wise.

sin :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
sin x | eqLengthGuard [] =
    buildOp (opDef "Sin"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Outputs random integers from a uniform distribution.
--
-- The generated values are uniform integers in the range `[minval, maxval)`.
-- The lower bound `minval` is included in the range, while the upper bound
-- `maxval` is excluded.
-- 
-- The random integers are slightly biased unless `maxval - minval` is an exact
-- power of two.  The bias is small for values of `maxval - minval` significantly
-- smaller than the range of the output (either `2^32` or `2^64`).
randomUniformInt :: forall v1 v2 v3 tout t . (TensorType tout,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] tout,
                                              TensorType t,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] t) =>
                    Tensor v1 t -- ^ __shape__: The shape of the output tensor.
                    -> Tensor v2 tout -- ^ __minval__: 0-D.  Inclusive lower bound on the generated integers.
                    -> Tensor v3 tout -- ^ __maxval__: 0-D.  Exclusive upper bound on the generated integers.
                    -> Build (Tensor Value tout) -- ^ __output__: A tensor of the specified shape filled with uniform random integers.
randomUniformInt shape minval maxval | eqLengthGuard [] =
    buildOp (opDef "RandomUniformInt"
             & opAttr "Tout" .~ tensorType (undefined :: tout)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape minval maxval
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tout"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "The shape of the output tensor."
  name: "shape"
  type_attr: "T"
}
input_arg {
  description: "0-D.  Inclusive lower bound on the generated integers."
  name: "minval"
  type_attr: "Tout"
}
input_arg {
  description: "0-D.  Exclusive upper bound on the generated integers."
  name: "maxval"
  type_attr: "Tout"
}
output_arg {
  description: "A tensor of the specified shape filled with uniform random integers."
  name: "output"
  type_attr: "Tout"
}
-}

-- | Computes the complementary error function of `x` element-wise.

erfc :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
erfc x | eqLengthGuard [] =
    buildOp (opDef "Erfc"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes Psi, the derivative of Lgamma (the log of the absolute value of
--
-- `Gamma(x)`), element-wise.
digamma :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor Value t -- ^ __y__
digamma x | eqLengthGuard [] =
    buildOp (opDef "Digamma"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Performs a resize and padding as a preprocess during a convolution.
--
-- It's often possible to do spatial transformations more efficiently as part of
-- the packing stage of a convolution, so this op allows for an optimized
-- implementation where these stages are fused together. This prevents the need to
-- write out the intermediate results as whole tensors, reducing memory pressure,
-- and we can get some latency gains by merging the transformation calculations.
-- The data_format attribute for Conv2D isn't supported by this op, and defaults to
-- 'NHWC' order.
-- Internally this op uses a single per-graph scratch buffer, which means that it
-- will block if multiple versions are being run in parallel. This is because this
-- operator is primarily an optimization to minimize memory usage.
fusedResizeAndPadConv2D :: forall v1 v2 v3 v4 t . (TensorType t,
                                                   OneOf '[Data.Word.Word16,
                                                           Double, Float] t) =>
                           Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, in_channels]`.
                           -> Tensor v2 Data.Int.Int32 -- ^ __size__: A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The
                                                       -- new size for the images.
                           -> Tensor v3 Data.Int.Int32 -- ^ __paddings__: A two-column matrix specifying the padding sizes. The number of
                                                       -- rows must be the same as the rank of `input`.
                           -> Tensor v4 t -- ^ __filter__: 4-D with shape
                                          -- `[filter_height, filter_width, in_channels, out_channels]`.
                           -> Tensor Value t -- ^ __output__
fusedResizeAndPadConv2D input size paddings filter | eqLengthGuard [] =
    buildOp (opDef "FusedResizeAndPadConv2D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input size paddings filter
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale input by (new_height - 1) / (height - 1),\nwhich exactly aligns the 4 corners of images and resized images. If false, rescale\nby new_height / height. Treat similarly the width dimension."
  name: "resize_align_corners"
  type: "bool"
}
attr {
  allowed_values { list { s: "REFLECT" s: "SYMMETRIC" } }
  name: "mode"
  type: "string"
}
attr {
  description: "1-D of length 4.  The stride of the sliding window for each dimension\nof `input`. Must be in the same order as the dimension specified with format."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The\nnew size for the images."
  name: "size"
  type: DT_INT32
}
input_arg {
  description: "A two-column matrix specifying the padding sizes. The number of\nrows must be the same as the rank of `input`."
  name: "paddings"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, out_channels]`."
  name: "filter"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns x - y element-wise.
--
-- *NOTE*: `Sub` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
sub :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int32, Data.Int.Int64,
                                               Data.Word.Word16, Double,
                                               Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
sub x y | eqLengthGuard [] =
    buildOp (opDef "Sub"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns an element-wise indication of the sign of a number.
--
-- `y = sign(x) = -1` if `x < 0`; 0 if `x == 0`; 1 if `x > 0`.
-- 
-- For complex numbers, `y = sign(x) = x / |x|` if `x != 0`, otherwise `y = 0`.
sign :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int32, Data.Int.Int64,
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
sign x | eqLengthGuard [] =
    buildOp (opDef "Sign"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes the log of the absolute value of `Gamma(x)` element-wise.

lgamma :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                               Float] t) =>
          Tensor v1 t -- ^ __x__
          -> Tensor Value t -- ^ __y__
lgamma x | eqLengthGuard [] =
    buildOp (opDef "Lgamma"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes natural logarithm of x element-wise.
--
-- I.e., \\(y = \log_e x\\).
log :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
log x | eqLengthGuard [] =
    buildOp (opDef "Log"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes exponential of x element-wise.  \\(y = e^x\\).

exp :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
exp x | eqLengthGuard [] =
    buildOp (opDef "Exp"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes the grayscale dilation of 4-D `input` and 3-D `filter` tensors.
--
-- The `input` tensor has shape `[batch, in_height, in_width, depth]` and the
-- `filter` tensor has shape `[filter_height, filter_width, depth]`, i.e., each
-- input channel is processed independently of the others with its own structuring
-- function. The `output` tensor has shape
-- `[batch, out_height, out_width, depth]`. The spatial dimensions of the output
-- tensor depend on the `padding` algorithm. We currently only support the default
-- "NHWC" `data_format`.
-- 
-- In detail, the grayscale morphological 2-D dilation is the max-sum correlation
-- (for consistency with `conv2d`, we use unmirrored filters):
-- 
--     output[b, y, x, c] =
--        max_{dy, dx} input[b,
--                           strides[1] * y + rates[1] * dy,
--                           strides[2] * x + rates[2] * dx,
--                           c] +
--                     filter[dy, dx, c]
-- 
-- Max-pooling is a special case when the filter has size equal to the pooling
-- kernel size and contains all zeros.
-- 
-- Note on duality: The dilation of `input` by the `filter` is equal to the
-- negation of the erosion of `-input` by the reflected `filter`.
dilation2D :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word16,
                                                      Data.Word.Word8, Double,
                                                      Float] t) =>
              Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, depth]`.
              -> Tensor v2 t -- ^ __filter__: 3-D with shape `[filter_height, filter_width, depth]`.
              -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, out_height, out_width, depth]`.
dilation2D input filter | eqLengthGuard [] =
    buildOp (opDef "Dilation2D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\ntensor. Must be: `[1, stride_height, stride_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  description: "The input stride for atrous morphological dilation. Must be:\n`[1, rate_height, rate_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "rates"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, depth]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "3-D with shape `[filter_height, filter_width, depth]`."
  name: "filter"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape `[batch, out_height, out_width, depth]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the gradient for the rsqrt of `x` wrt its input.
--
-- Specifically, `grad = dy * -0.5 * y^3`, where `y = rsqrt(x)`, and `dy`
-- is the corresponding input gradient.
rsqrtGrad :: forall v1 v2 t . (TensorType t,
                               OneOf '[(Data.Complex.Complex Double),
                                       (Data.Complex.Complex Float),
                                       Data.Word.Word16, Double, Float] t) =>
             Tensor v1 t -- ^ __x__
             -> Tensor v2 t -- ^ __y__
             -> Tensor Value t -- ^ __z__
rsqrtGrad x y | eqLengthGuard [] =
    buildOp (opDef "RsqrtGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes reciprocal of square root of x element-wise.
--
-- I.e., \\(y = 1 / \sqrt{x}\\).
rsqrt :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                              (Data.Complex.Complex Float),
                                              Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value t -- ^ __y__
rsqrt x | eqLengthGuard [] =
    buildOp (opDef "Rsqrt"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Produces the max pool of the input tensor for quantized types.

quantizedMaxPool :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8] t) =>
                    Tensor v1 t -- ^ __input__: The 4D (batch x rows x cols x depth) Tensor to MaxReduce over.
                    -> Tensor v2 Float -- ^ __min_input__: The float value that the lowest quantized input value represents.
                    -> Tensor v3 Float -- ^ __max_input__: The float value that the highest quantized input value represents.
                    -> (Tensor Value t, Tensor Value Float, Tensor Value Float)
                    -- ^ (__output__, __min_output__, __max_output__)
                    --
                    -- * __output__
                    --
                    -- * __min_output__: The float value that the lowest quantized output value represents.
                    --
                    -- * __max_output__: The float value that the highest quantized output value represents.
quantizedMaxPool input min_input max_input | eqLengthGuard [] =
    buildOp (opDef "QuantizedMaxPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        input min_input max_input
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "The size of the window for each dimension of the input tensor.\nThe length must be 4 to match the number of dimensions of the input."
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\ntensor. The length must be 4 to match the number of dimensions of the input."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "The 4D (batch x rows x cols x depth) Tensor to MaxReduce over."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "The float value that the lowest quantized input value represents."
  name: "min_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized input value represents."
  name: "max_input"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "T" }
output_arg {
  description: "The float value that the lowest quantized output value represents."
  name: "min_output"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized output value represents."
  name: "max_output"
  type: DT_FLOAT
}
-}

-- | Computes square root of x element-wise.
--
-- I.e., \\(y = \sqrt{x} = x^{1/2}\\).
sqrt :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
sqrt x | eqLengthGuard [] =
    buildOp (opDef "Sqrt"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | A Reader that outputs the queued work as both the key and value.
--
-- To use, enqueue strings in a Queue.  ReaderRead will take the front
-- work string and output (work, work).
identityReader :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __reader_handle__: The handle to reference the Reader.
identityReader  | eqLengthGuard [] =
    buildOp (opDef "IdentityReader")
        
{-
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to reference the Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Computes square of x element-wise.
--
-- I.e., \\(y = x * x = x^2\\).
square :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int32, Data.Int.Int64,
                                               Data.Word.Word16, Double,
                                               Float] t) =>
          Tensor v1 t -- ^ __x__
          -> Tensor Value t -- ^ __y__
square x | eqLengthGuard [] =
    buildOp (opDef "Square"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Reshapes a quantized tensor as per the Reshape op.
--
-- ```
quantizedReshape :: forall v1 v2 v3 v4 t tshape . (TensorType t,
                                                   TensorType tshape,
                                                   OneOf '[Data.Int.Int32,
                                                           Data.Int.Int64] tshape) =>
                    Tensor v1 t -- ^ __tensor__
                    -> Tensor v2 tshape -- ^ __shape__: Defines the shape of the output tensor.
                    -> Tensor v3 Float -- ^ __input_min__: The minimum value of the input.
                    -> Tensor v4 Float -- ^ __input_max__: The maximum value of the input.
                    -> (Tensor Value t, Tensor Value Float, Tensor Value Float)
                    -- ^ (__output__, __output_min__, __output_max__)
                    --
                    -- * __output__
                    --
                    -- * __output_min__: This value is copied from input_min.
                    --
                    -- * __output_max__: This value is copied from input_max.
quantizedReshape tensor shape input_min input_max | eqLengthGuard [] =
    buildOp (opDef "QuantizedReshape"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tshape" .~ tensorType (undefined :: tshape))
        tensor shape input_min input_max
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tshape"
  type: "type"
}
input_arg { name: "tensor" type_attr: "T" }
input_arg {
  description: "Defines the shape of the output tensor."
  name: "shape"
  type_attr: "Tshape"
}
input_arg {
  description: "The minimum value of the input."
  name: "input_min"
  type: DT_FLOAT
}
input_arg {
  description: "The maximum value of the input."
  name: "input_max"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "T" }
output_arg {
  description: "This value is copied from input_min."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "This value is copied from input_max."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Computes the gradient for the inverse of `x` wrt its input.
--
-- Specifically, `grad = -dy * y*y`, where `y = 1/x`, and `dy`
-- is the corresponding input gradient.
reciprocalGrad :: forall v1 v2 t . (TensorType t,
                                    OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
                  -> Tensor v2 t -- ^ __y__
                  -> Tensor Value t -- ^ __z__
reciprocalGrad x y | eqLengthGuard [] =
    buildOp (opDef "ReciprocalGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes the gradient for the inverse of `x` wrt its input.
--
-- Specifically, `grad = -dy * y*y`, where `y = 1/x`, and `dy`
-- is the corresponding input gradient.
invGrad :: forall v1 v2 t . (TensorType t,
                             OneOf '[(Data.Complex.Complex Double),
                                     (Data.Complex.Complex Float),
                                     Data.Word.Word16, Double, Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor v2 t -- ^ __y__
           -> Tensor Value t -- ^ __z__
invGrad x y | eqLengthGuard [] =
    buildOp (opDef "InvGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes the reciprocal of x element-wise.
--
-- I.e., \\(y = 1 / x\\).
inv :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Int.Int32, Data.Int.Int64,
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
inv x | eqLengthGuard [] =
    buildOp (opDef "Inv"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Concat the elements from the TensorArray into value `value`.
--
-- Takes `T` elements of shapes
-- 
--   ```
--   (n0 x d0 x d1 x ...), (n1 x d0 x d1 x ...), ..., (n(T-1) x d0 x d1 x ...)
--   ```
-- 
-- and concatenates them into a Tensor of shape:
-- 
--   ```(n0 + n1 + ... + n(T-1) x d0 x d1 x ...)```
-- 
-- All elements must have the same shape (excepting the first dimension).
tensorArrayConcatV2 :: forall v1 v2 dtype . (TensorType dtype) =>
                       Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                       -> Tensor v2 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                       -> (Tensor Value dtype, Tensor Value Data.Int.Int64)
                       -- ^ (__value__, __lengths__)
                       --
                       -- * __value__: All of the elements in the TensorArray, concatenated along the first
                       -- axis.
                       --
                       -- * __lengths__: A vector of the row sizes of the original T elements in the
                       -- value output.  In the example above, this would be the values:
                       -- `(n1, n2, ..., n(T-1))`.
tensorArrayConcatV2 handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayConcatV2"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle flow_in
{-
attr {
  description: "The type of the elem that is returned."
  name: "dtype"
  type: "type"
}
attr {
  default_value { shape { unknown_rank: true } }
  description: "The expected shape of an element, if known,\nexcluding the first dimension. Used to validate the shapes of\nTensorArray elements. If this shape is not fully specified, concatenating\nzero-size TensorArrays is an error."
  name: "element_shape_except0"
  type: "shape"
}
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "All of the elements in the TensorArray, concatenated along the first\naxis."
  name: "value"
  type_attr: "dtype"
}
output_arg {
  description: "A vector of the row sizes of the original T elements in the\nvalue output.  In the example above, this would be the values:\n`(n1, n2, ..., n(T-1))`."
  name: "lengths"
  type: DT_INT64
}
-}

-- | Computes the complex absolute value of a tensor.
--
-- Given a tensor `x` of complex numbers, this operation returns a tensor of type
-- `float` or `double` that is the absolute value of each element in `x`. All
-- elements in `x` must be complex numbers of the form \\(a + bj\\). The absolute
-- value is computed as \\( \sqrt{a^2 + b^2}\\).
-- 
-- For example:
-- 
-- ```
-- # tensor 'x' is [[-2.25 + 4.75j], [-3.25 + 5.75j]]
-- tf.complex_abs(x) ==> [5.25594902, 6.60492229]
-- ```
complexAbs :: forall v1 t tout . (TensorType t,
                                  OneOf '[(Data.Complex.Complex Double),
                                          (Data.Complex.Complex Float)] t,
                                  TensorType tout, OneOf '[Double,
                                                           Float] tout) =>
              Tensor v1 t -- ^ __x__
              -> Tensor Value tout -- ^ __y__
complexAbs x | eqLengthGuard [] =
    buildOp (opDef "ComplexAbs"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        x
{-
attr {
  allowed_values { list { type: DT_COMPLEX64 type: DT_COMPLEX128 } }
  default_value { type: DT_COMPLEX64 }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "Tout"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "Tout" }
-}

-- | Cast x of type SrcT to y of DstT.
--
-- _HostCast requires its input and produces its output in host memory.
_HostCast :: forall v1 srcT dstT . (TensorType srcT, TensorType dstT) =>
             Tensor v1 srcT -- ^ __x__
             -> Tensor Value dstT -- ^ __y__
_HostCast x | eqLengthGuard [] =
    buildOp (opDef "_HostCast"
             & opAttr "SrcT" .~ tensorType (undefined :: srcT)
             & opAttr "DstT" .~ tensorType (undefined :: dstT))
        x
{-
attr { name: "SrcT" type: "type" }
attr { name: "DstT" type: "type" }
input_arg { name: "x" type_attr: "SrcT" }
output_arg { name: "y" type_attr: "DstT" }
-}

-- | Resize `images` to `size` using nearest neighbor interpolation.

resizeNearestNeighbor :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                                 Data.Int.Int32,
                                                                 Data.Int.Int64,
                                                                 Data.Int.Int8,
                                                                 Data.Word.Word16,
                                                                 Data.Word.Word8,
                                                                 Double,
                                                                 Float] t) =>
                         Tensor v1 t -- ^ __images__: 4-D with shape `[batch, height, width, channels]`.
                         -> Tensor v2 Data.Int.Int32 -- ^ __size__: = A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The
                                                     -- new size for the images.
                         -> Tensor Value t -- ^ __resized_images__: 4-D with shape
                         -- `[batch, new_height, new_width, channels]`.
resizeNearestNeighbor images size | eqLengthGuard [] =
    buildOp (opDef "ResizeNearestNeighbor"
             & opAttr "T" .~ tensorType (undefined :: t))
        images size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale input by (new_height - 1) / (height - 1), which\nexactly aligns the 4 corners of images and resized images. If false, rescale\nby new_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "images"
  type_attr: "T"
}
input_arg {
  description: "= A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The\nnew size for the images."
  name: "size"
  type: DT_INT32
}
output_arg {
  description: "4-D with shape\n`[batch, new_height, new_width, channels]`."
  name: "resized_images"
  type_attr: "T"
}
-}

-- | Deprecated. Disallowed in GraphDef version >= 2.

adjustContrast :: forall v1 v2 v3 v4 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Int.Int64,
                                                                Data.Int.Int8,
                                                                Data.Word.Word8,
                                                                Double,
                                                                Float] t) =>
                  Tensor v1 t -- ^ __images__
                  -> Tensor v2 Float -- ^ __contrast_factor__
                  -> Tensor v3 Float -- ^ __min_value__
                  -> Tensor v4 Float -- ^ __max_value__
                  -> Tensor Value Float -- ^ __output__
adjustContrast images contrast_factor min_value max_value | eqLengthGuard [] =
    buildOp (opDef "AdjustContrast"
             & opAttr "T" .~ tensorType (undefined :: t))
        images contrast_factor min_value max_value
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "images" type_attr: "T" }
input_arg { name: "contrast_factor" type: DT_FLOAT }
input_arg { name: "min_value" type: DT_FLOAT }
input_arg { name: "max_value" type: DT_FLOAT }
output_arg { name: "output" type: DT_FLOAT }
-}

-- | 

batchMatrixDiagPart :: forall v1 t . (TensorType t) =>
                       Tensor v1 t -- ^ __input__
                       -> Tensor Value t -- ^ __diagonal__
batchMatrixDiagPart input | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixDiagPart"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
output_arg { name: "diagonal" type_attr: "T" }
-}

-- | 

batchMatrixSetDiag :: forall v1 v2 t . (TensorType t) =>
                      Tensor v1 t -- ^ __input__
                      -> Tensor v2 t -- ^ __diagonal__
                      -> Tensor Value t -- ^ __output__
batchMatrixSetDiag input diagonal | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixSetDiag"
             & opAttr "T" .~ tensorType (undefined :: t))
        input diagonal
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
input_arg { name: "diagonal" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | 

batchMatrixDiag :: forall v1 t . (TensorType t) => Tensor v1 t -- ^ __diagonal__
                   -> Tensor Value t -- ^ __output__
batchMatrixDiag diagonal | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixDiag"
             & opAttr "T" .~ tensorType (undefined :: t))
        diagonal
{-
attr { name: "T" type: "type" }
input_arg { name: "diagonal" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Compute gradients for a FakeQuantWithMinMaxVarsPerChannel operation.

fakeQuantWithMinMaxVarsPerChannelGradient :: Tensor v1 Float -- ^ __gradients__: Backpropagated gradients above the FakeQuantWithMinMaxVars operation,
                                                             -- shape one of: `[d]`, `[b, d]`,  `[b, h, w, d]`.
                                             -> Tensor v2 Float -- ^ __inputs__: Values passed as inputs to the FakeQuantWithMinMaxVars operation, shape
                                                                --   same as `gradients`.
                                                                -- min, max: Quantization interval, floats of shape `[d]`.
                                             -> Tensor v3 Float -- ^ __min__
                                             -> Tensor v4 Float -- ^ __max__
                                             -> (Tensor Value Float,
                                                 Tensor Value Float,
                                                 Tensor Value Float)
                                             -- ^ (__backprops_wrt_input__, __backprop_wrt_min__, __backprop_wrt_max__)
                                             --
                                             -- * __backprops_wrt_input__: Backpropagated gradients w.r.t. inputs, shape same as
                                             -- `inputs`:
                                             --   `gradients * (inputs >= min && inputs <= max)`.
                                             --
                                             -- * __backprop_wrt_min__: Backpropagated gradients w.r.t. min parameter, shape `[d]`:
                                             -- `sum_per_d(gradients * (inputs < min))`.
                                             --
                                             -- * __backprop_wrt_max__: Backpropagated gradients w.r.t. max parameter, shape `[d]`:
                                             -- `sum_per_d(gradients * (inputs > max))`.
fakeQuantWithMinMaxVarsPerChannelGradient gradients inputs min
                                          max | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxVarsPerChannelGradient")
        gradients inputs min max
{-
input_arg {
  description: "Backpropagated gradients above the FakeQuantWithMinMaxVars operation,\nshape one of: `[d]`, `[b, d]`,  `[b, h, w, d]`."
  name: "gradients"
  type: DT_FLOAT
}
input_arg {
  description: "Values passed as inputs to the FakeQuantWithMinMaxVars operation, shape\n  same as `gradients`.\nmin, max: Quantization interval, floats of shape `[d]`."
  name: "inputs"
  type: DT_FLOAT
}
input_arg { name: "min" type: DT_FLOAT }
input_arg { name: "max" type: DT_FLOAT }
output_arg {
  description: "Backpropagated gradients w.r.t. inputs, shape same as\n`inputs`:\n  `gradients * (inputs >= min && inputs <= max)`."
  name: "backprops_wrt_input"
  type: DT_FLOAT
}
output_arg {
  description: "Backpropagated gradients w.r.t. min parameter, shape `[d]`:\n`sum_per_d(gradients * (inputs < min))`."
  name: "backprop_wrt_min"
  type: DT_FLOAT
}
output_arg {
  description: "Backpropagated gradients w.r.t. max parameter, shape `[d]`:\n`sum_per_d(gradients * (inputs > max))`."
  name: "backprop_wrt_max"
  type: DT_FLOAT
}
-}

-- | Computes gradients for SparseSegmentSqrtN.
--
-- Returns tensor "output" with same shape as grad, except for dimension 0 whose
-- value is output_dim0.
sparseSegmentSqrtNGrad :: forall v1 v2 v3 v4 t tidx . (TensorType t,
                                                       OneOf '[Double, Float] t,
                                                       TensorType tidx,
                                                       OneOf '[Data.Int.Int32,
                                                               Data.Int.Int64] tidx) =>
                          Tensor v1 t -- ^ __grad__: gradient propagated to the SparseSegmentSqrtN op.
                          -> Tensor v2 tidx -- ^ __indices__: indices passed to the corresponding SparseSegmentSqrtN op.
                          -> Tensor v3 Data.Int.Int32 -- ^ __segment_ids__: segment_ids passed to the corresponding SparseSegmentSqrtN op.
                          -> Tensor v4 Data.Int.Int32 -- ^ __output_dim0__: dimension 0 of "data" passed to SparseSegmentSqrtN op.
                          -> Tensor Value t -- ^ __output__
sparseSegmentSqrtNGrad grad indices segment_ids output_dim0 | eqLengthGuard [] =
    buildOp (opDef "SparseSegmentSqrtNGrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        grad indices segment_ids output_dim0
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "gradient propagated to the SparseSegmentSqrtN op."
  name: "grad"
  type_attr: "T"
}
input_arg {
  description: "indices passed to the corresponding SparseSegmentSqrtN op."
  name: "indices"
  type_attr: "Tidx"
}
input_arg {
  description: "segment_ids passed to the corresponding SparseSegmentSqrtN op."
  name: "segment_ids"
  type: DT_INT32
}
input_arg {
  description: "dimension 0 of \"data\" passed to SparseSegmentSqrtN op."
  name: "output_dim0"
  type: DT_INT32
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Fake-quantize the 'inputs' tensor of type float and one of the shapes: `[d]`,
--
-- `[b, d]` `[b, h, w, d]` via per-channel floats `min` and `max` of shape `[d]`
-- to 'outputs' tensor of same shape as `inputs`.
-- 
-- [min; max] is the clamping range for the 'inputs' data in the corresponding
-- depth channel.  Op divides this range into 255 steps (total of 256 values), then
-- replaces each 'inputs' value with the closest of the quantized step values.
-- 
-- This operation has a gradient and thus allows for training `min` and `max` values.
fakeQuantWithMinMaxVarsPerChannel :: Tensor v1 Float -- ^ __inputs__
                                     -> Tensor v2 Float -- ^ __min__
                                     -> Tensor v3 Float -- ^ __max__
                                     -> Tensor Value Float -- ^ __outputs__
fakeQuantWithMinMaxVarsPerChannel inputs min max | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxVarsPerChannel")
        inputs min max
{-
input_arg { name: "inputs" type: DT_FLOAT }
input_arg { name: "min" type: DT_FLOAT }
input_arg { name: "max" type: DT_FLOAT }
output_arg { name: "outputs" type: DT_FLOAT }
-}

-- | Outputs a `Summary` protocol buffer with scalar values.
--
-- The input `tags` and `values` must have the same shape.  The generated summary
-- has a summary value for each tag-value pair in `tags` and `values`.
scalarSummary :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Int.Int64,
                                                         Data.Int.Int8,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8,
                                                         Double, Float] t) =>
                 Tensor v1 Data.ByteString.ByteString -- ^ __tags__: Tags for the summary.
                 -> Tensor v2 t -- ^ __values__: Same shape as `tags.  Values for the summary.
                 -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar.  Serialized `Summary` protocol buffer.
scalarSummary tags values | eqLengthGuard [] =
    buildOp (opDef "ScalarSummary"
             & opAttr "T" .~ tensorType (undefined :: t))
        tags values
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Tags for the summary." name: "tags" type: DT_STRING
}
input_arg {
  description: "Same shape as `tags.  Values for the summary."
  name: "values"
  type_attr: "T"
}
output_arg {
  description: "Scalar.  Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Computes numerical negative value element-wise.
--
-- I.e., \\(y = -x\\).
neg :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Int.Int32, Data.Int.Int64,
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
neg x | eqLengthGuard [] =
    buildOp (opDef "Neg"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Compute gradients for a FakeQuantWithMinMaxArgs operation.

fakeQuantWithMinMaxArgsGradient :: Tensor v1 Float -- ^ __gradients__: Backpropagated gradients above the FakeQuantWithMinMaxArgs operation.
                                   -> Tensor v2 Float -- ^ __inputs__: Values passed as inputs to the FakeQuantWithMinMaxArgs operation.
                                   -> Tensor Value Float -- ^ __backprops__: Backpropagated gradients below the FakeQuantWithMinMaxArgs operation:
                                   -- `gradients * (inputs >= min && inputs <= max)`.
fakeQuantWithMinMaxArgsGradient gradients inputs | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxArgsGradient")
        gradients inputs
{-
attr { default_value { f: -6.0 } name: "min" type: "float" }
attr { default_value { f: 6.0 } name: "max" type: "float" }
input_arg {
  description: "Backpropagated gradients above the FakeQuantWithMinMaxArgs operation."
  name: "gradients"
  type: DT_FLOAT
}
input_arg {
  description: "Values passed as inputs to the FakeQuantWithMinMaxArgs operation."
  name: "inputs"
  type: DT_FLOAT
}
output_arg {
  description: "Backpropagated gradients below the FakeQuantWithMinMaxArgs operation:\n`gradients * (inputs >= min && inputs <= max)`."
  name: "backprops"
  type: DT_FLOAT
}
-}

-- | Debug NaN Value Counter Op
--
-- Counts number of NaNs in the input tensor, for debugging.
debugNanCount :: forall v1 t . (TensorType t) =>
                 Tensor v1 t -- ^ __input__: Input tensor, non-Reference type.
                 -> Tensor Value Data.Int.Int64 -- ^ __output__: An integer output tensor that is the number of NaNs in the input.
debugNanCount input | eqLengthGuard [] =
    buildOp (opDef "DebugNanCount"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "Name of the input tensor."
  name: "tensor_name"
  type: "string"
}
attr {
  default_value { list { } }
  description: "List of URLs to debug targets, e.g.,\nfile:///foo/tfdbg_dump, grpc:://localhost:11011"
  name: "debug_urls"
  type: "list(string)"
}
input_arg {
  description: "Input tensor, non-Reference type."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "An integer output tensor that is the number of NaNs in the input."
  name: "output"
  type: DT_INT64
}
-}

-- | Debug Identity Op.
--
-- Provides an identity mapping of the non-Ref type input tensor for debugging.
debugIdentity :: forall v1 t . (TensorType t) =>
                 Tensor v1 t -- ^ __input__: Input tensor, non-Reference type.
                 -> Tensor Value t -- ^ __output__: Output tensor that equals the input tensor.
debugIdentity input | eqLengthGuard [] =
    buildOp (opDef "DebugIdentity"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "Name of the input tensor."
  name: "tensor_name"
  type: "string"
}
attr {
  default_value { list { } }
  description: "List of URLs to debug targets, e.g.,\nfile:///foo/tfdbg_dump, grpc:://localhost:11011"
  name: "debug_urls"
  type: "list(string)"
}
input_arg {
  description: "Input tensor, non-Reference type."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "Output tensor that equals the input tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | Bitcasts a tensor from one type to another without copying data.
--
-- Given a tensor `input`, this operation returns a tensor that has the same buffer
-- data as `input` with datatype `type`.
-- 
-- If the input datatype `T` is larger than the output datatype `type` then the
-- shape changes from [...] to [..., sizeof(`T`)/sizeof(`type`)].
-- 
-- If `T` is smaller than `type`, the operator requires that the rightmost
-- dimension be equal to sizeof(`type`)/sizeof(`T`). The shape then goes from
-- [..., sizeof(`type`)/sizeof(`T`)] to [...].
-- 
-- *NOTE*: Bitcast is implemented as a low-level cast, so machines with different
-- endian orderings will give different results.
bitcast :: forall v1 t type' . (TensorType t,
                                OneOf '[(Data.Complex.Complex Double),
                                        (Data.Complex.Complex Float),
                                        Data.Int.Int16, Data.Int.Int32,
                                        Data.Int.Int64, Data.Int.Int8,
                                        Data.Word.Word16, Data.Word.Word8,
                                        Double, Float] t, TensorType type',
                                OneOf '[(Data.Complex.Complex Double),
                                        (Data.Complex.Complex Float),
                                        Data.Int.Int16, Data.Int.Int32,
                                        Data.Int.Int64, Data.Int.Int8,
                                        Data.Word.Word16, Data.Word.Word8,
                                        Double, Float] type') =>
           Tensor v1 t -- ^ __input__
           -> Tensor Value type' -- ^ __output__
bitcast input | eqLengthGuard [] =
    buildOp (opDef "Bitcast"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "type" .~ tensorType (undefined :: type'))
        input
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "type"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "type" }
-}

-- | Computes sigmoid of `x` element-wise.
--
-- Specifically, `y = 1 / (1 + exp(-x))`.
sigmoid :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                (Data.Complex.Complex Float),
                                                Data.Word.Word16, Double,
                                                Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor Value t -- ^ __y__
sigmoid x | eqLengthGuard [] =
    buildOp (opDef "Sigmoid"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Copy Op.
--
-- Performs CPU-to-CPU or GPU-to-GPU deep-copying of tensor, depending on the
-- device on which the tensor is allocated.
-- 
-- Unlike the CopyHost Op, this op does not have HostMemory constraint on its
-- input or output.
copy :: forall v1 t . (TensorType t) =>
        Tensor v1 t -- ^ __input__: Input tensor.
        -> Tensor Value t -- ^ __output__: Output tensor, deep-copied from input.
copy input | eqLengthGuard [] =
    buildOp (opDef "Copy"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "The name of the input tensor."
  name: "tensor_name"
  type: "string"
}
input_arg {
  description: "Input tensor." name: "input" type_attr: "T"
}
output_arg {
  description: "Output tensor, deep-copied from input."
  name: "output"
  type_attr: "T"
}
-}

-- | Generates labels for candidate sampling with a learned unigram distribution.
--
-- A unigram sampler could use a fixed unigram distribution read from a
-- file or passed in as an in-memory array instead of building up the distribution
-- from data on the fly. There is also an option to skew the distribution by
-- applying a distortion power to the weights.
-- 
-- The vocabulary file should be in CSV-like format, with the last field
-- being the weight associated with the word.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
fixedUnigramCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to randomly sample per batch.
                                -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                                -> Data.Int.Int64 -- ^ __range_max__: The sampler will sample integers from the interval [0, range_max).
                                -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                                        -- candidates in a batch are unique. This requires some approximation to
                                        -- estimate the post-rejection sampling probabilities.
                                -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                            -- IDs of the num_true target_classes in the corresponding original label.
                                -> (Tensor Value Data.Int.Int64,
                                    Tensor Value Float, Tensor Value Float)
                                -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                                --
                                -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                                -- the ID of a sampled candidate.
                                --
                                -- * __true_expected_count__: A batch_size * num_true matrix, representing
                                -- the number of times each candidate is expected to occur in a batch
                                -- of sampled candidates. If unique=true, then this is a probability.
                                --
                                -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                                -- candidate representing the number of times the candidate is expected
                                -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                                -- probability.
fixedUnigramCandidateSampler num_sampled num_true range_max unique
                             true_classes | eqLengthGuard [] =
    buildOp (opDef "FixedUnigramCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "range_max" .~ range_max
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to randomly sample per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  description: "The sampler will sample integers from the interval [0, range_max)."
  has_minimum: true
  minimum: 1
  name: "range_max"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "Each valid line in this file (which should have a CSV-like format)\ncorresponds to a valid word ID. IDs are in sequential order, starting from\nnum_reserved_ids. The last entry in each line is expected to be a value\ncorresponding to the count or relative probability. Exactly one of vocab_file\nand unigrams needs to be passed to this op."
  name: "vocab_file"
  type: "string"
}
attr {
  default_value { f: 1.0 }
  description: "The distortion is used to skew the unigram probability distribution.\nEach weight is first raised to the distortion\'s power before adding to the\ninternal unigram distribution. As a result, distortion = 1.0 gives regular\nunigram sampling (as defined by the vocab file), and distortion = 0.0 gives\na uniform distribution."
  name: "distortion"
  type: "float"
}
attr {
  default_value { i: 0 }
  description: "Optionally some reserved IDs can be added in the range [0,\n..., num_reserved_ids) by the users. One use case is that a special unknown\nword token is used as ID 0. These IDs will have a sampling probability of 0."
  name: "num_reserved_ids"
  type: "int"
}
attr {
  default_value { i: 1 }
  description: "A sampler can be used to sample from a subset of the original range\nin order to speed up the whole computation through parallelism. This parameter\n(together with \'shard\') indicates the number of partitions that are being\nused in the overall computation."
  has_minimum: true
  minimum: 1
  name: "num_shards"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A sampler can be used to sample from a subset of the original range\nin order to speed up the whole computation through parallelism. This parameter\n(together with \'num_shards\') indicates the particular partition number of a\nsampler op, when partitioning is being used."
  has_minimum: true
  name: "shard"
  type: "int"
}
attr {
  default_value { list { } }
  description: "A list of unigram counts or probabilities, one per ID in sequential\norder. Exactly one of vocab_file and unigrams should be passed to this op."
  name: "unigrams"
  type: "list(float)"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Computes the difference between two lists of numbers or strings.
--
-- Given a list `x` and a list `y`, this operation returns a list `out` that
-- represents all values that are in `x` but not in `y`. The returned list `out`
-- is sorted in the same order that the numbers appear in `x` (duplicates are
-- preserved). This operation also returns a list `idx` that represents the
-- position of each `out` element in `x`. In other words:
-- 
-- `out[i] = x[idx[i]] for i in [0, 1, ..., len(out) - 1]`
-- 
-- For example, given this input:
-- 
-- ```prettyprint
-- x = [1, 2, 3, 4, 5, 6]
-- y = [1, 3, 5]
-- ```
-- 
-- This operation would return:
-- 
-- ```prettyprint
-- out ==> [2, 4, 6]
-- idx ==> [1, 3, 5]
-- ```
listDiff :: forall v1 v2 t out_idx . (TensorType t, TensorType out_idx,
                                      OneOf '[Data.Int.Int32,
                                              Data.Int.Int64] out_idx) =>
            Tensor v1 t -- ^ __x__: 1-D. Values to keep.
            -> Tensor v2 t -- ^ __y__: 1-D. Values to remove.
            -> (Tensor Value t, Tensor Value out_idx) -- ^ (__out__, __idx__)
            --
            -- * __out__: 1-D. Values present in `x` but not in `y`.
            --
            -- * __idx__: 1-D. Positions of `x` values preserved in `out`.
listDiff x y | eqLengthGuard [] =
    buildOp (opDef "ListDiff"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "out_idx" .~ tensorType (undefined :: out_idx))
        x y
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_idx"
  type: "type"
}
input_arg {
  description: "1-D. Values to keep." name: "x" type_attr: "T"
}
input_arg {
  description: "1-D. Values to remove." name: "y" type_attr: "T"
}
output_arg {
  description: "1-D. Values present in `x` but not in `y`."
  name: "out"
  type_attr: "T"
}
output_arg {
  description: "1-D. Positions of `x` values preserved in `out`."
  name: "idx"
  type_attr: "out_idx"
}
-}

-- | Extract `patches` from `images` and put them in the "depth" output dimension.

extractImagePatches :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double, Float] t) =>
                       Tensor v1 t -- ^ __images__: 4-D Tensor with shape `[batch, in_rows, in_cols, depth]`.
                       -> Tensor Value t -- ^ __patches__: 4-D Tensor with shape `[batch, out_rows, out_cols, ksize_rows *
                       -- ksize_cols * depth]` containing image patches with size
                       -- `ksize_rows x ksize_cols x depth` vectorized in the "depth" dimension.
extractImagePatches images | eqLengthGuard [] =
    buildOp (opDef "ExtractImagePatches"
             & opAttr "T" .~ tensorType (undefined :: t))
        images
{-
attr {
  description: "The size of the sliding window for each dimension of `images`."
  has_minimum: true
  minimum: 4
  name: "ksizes"
  type: "list(int)"
}
attr {
  description: "1-D of length 4. How far the centers of two consecutive patches are in\nthe images. Must be: `[1, stride_rows, stride_cols, 1]`."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  description: "1-D of length 4. Must be: `[1, rate_rows, rate_cols, 1]`. This is the\ninput stride, specifying how far two consecutive patch samples are in the\ninput. Equivalent to extracting patches with\n`patch_sizes_eff = patch_sizes + (patch_sizes - 1) * (rates - 1)`, followed by\nsubsampling them spatially by a factor of `rates`."
  has_minimum: true
  minimum: 4
  name: "rates"
  type: "list(int)"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use.\n\nWe specify the size-related attributes as:\n\n```python\n      ksizes = [1, ksize_rows, ksize_cols, 1]\n      strides = [1, strides_rows, strides_cols, 1]\n      rates = [1, rates_rows, rates_cols, 1]\n```"
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D Tensor with shape `[batch, in_rows, in_cols, depth]`."
  name: "images"
  type_attr: "T"
}
output_arg {
  description: "4-D Tensor with shape `[batch, out_rows, out_cols, ksize_rows *\nksize_cols * depth]` containing image patches with size\n`ksize_rows x ksize_cols x depth` vectorized in the \"depth\" dimension."
  name: "patches"
  type_attr: "T"
}
-}

-- | SpaceToDepth for tensors of type T.
--
-- Rearranges blocks of spatial data, into depth. More specifically,
-- this op outputs a copy of the input tensor where values from the `height`
-- and `width` dimensions are moved to the `depth` dimension.
-- The attr `block_size` indicates the input block size and how the data is moved.
-- 
--   * Non-overlapping blocks of size `block_size x block size` are rearranged
--     into depth at each location.
--   * The depth of the output tensor is `input_depth * block_size * block_size`.
--   * The input tensor's height and width must be divisible by block_size.
-- 
-- That is, assuming the input is in the shape:
-- `[batch, height, width, depth]`,
-- the shape of the output will be:
-- `[batch, height/block_size, width/block_size, depth*block_size*block_size]`
-- 
-- This operation requires that the input tensor be of rank 4, and that
-- `block_size` be >=1 and a divisor of both the input `height` and `width`.
-- 
-- This operation is useful for resizing the activations between convolutions
-- (but keeping all data), e.g. instead of pooling. It is also useful for training
-- purely convolutional models.
-- 
-- For example, given this input of shape `[1, 2, 2, 1]`, and block_size of 2:
-- 
-- ```prettyprint
-- x = [[[[1], [2]],
--       [[3], [4]]]]
-- ```
-- 
-- This operation will output a tensor of shape `[1, 1, 1, 4]`:
-- 
-- ```prettyprint
-- [[[[1, 2, 3, 4]]]]
-- ```
-- 
-- Here, the input has a batch of 1 and each batch element has shape `[2, 2, 1]`,
-- the corresponding output will have a single element (i.e. width and height are
-- both 1) and will have a depth of 4 channels (1 * block_size * block_size).
-- The output element shape is `[1, 1, 4]`.
-- 
-- For an input tensor with larger depth, here of shape `[1, 2, 2, 3]`, e.g.
-- 
-- ```prettyprint
-- x = [[[[1, 2, 3], [4, 5, 6]],
--       [[7, 8, 9], [10, 11, 12]]]]
-- ```
-- 
-- This operation, for block_size of 2, will return the following tensor of shape
-- `[1, 1, 1, 12]`
-- 
-- ```prettyprint
-- [[[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]]]
-- ```
-- 
-- Similarly, for the following input of shape `[1 4 4 1]`, and a block size of 2:
-- 
-- ```prettyprint
-- x = [[[[1],   [2],  [5],  [6]],
--       [[3],   [4],  [7],  [8]],
--       [[9],  [10], [13],  [14]],
--       [[11], [12], [15],  [16]]]]
-- ```
-- 
-- the operator will return the following tensor of shape `[1 2 2 4]`:
-- 
-- ```prettyprint
-- x = [[[[1, 2, 3, 4],
--        [5, 6, 7, 8]],
--       [[9, 10, 11, 12],
--        [13, 14, 15, 16]]]]
-- ```
spaceToDepth :: forall v1 t . (TensorType t) =>
                Data.Int.Int64 -- ^ __block_size__: The size of the spatial block.
                -> Tensor v1 t -- ^ __input__
                -> Tensor Value t -- ^ __output__
spaceToDepth block_size input | eqLengthGuard [] =
    buildOp (opDef "SpaceToDepth"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "block_size" .~ block_size)
        input
{-
attr { name: "T" type: "type" }
attr {
  description: "The size of the spatial block."
  has_minimum: true
  minimum: 2
  name: "block_size"
  type: "int"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the gradient of the crop_and_resize op wrt the input boxes tensor.

cropAndResizeGradBoxes :: forall v1 v2 v3 v4 t . (TensorType t,
                                                  OneOf '[Data.Int.Int16,
                                                          Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Data.Int.Int8,
                                                          Data.Word.Word16,
                                                          Data.Word.Word8,
                                                          Double, Float] t) =>
                          Tensor v1 Float -- ^ __grads__: A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`.
                          -> Tensor v2 t -- ^ __image__: A 4-D tensor of shape `[batch, image_height, image_width, depth]`.
                                         -- Both `image_height` and `image_width` need to be positive.
                          -> Tensor v3 Float -- ^ __boxes__: A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor
                                             -- specifies the coordinates of a box in the `box_ind[i]` image and is specified
                                             -- in normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of
                                             -- `y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the
                                             -- `[0, 1]` interval of normalized image height is mapped to
                                             -- `[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in
                                             -- which case the sampled crop is an up-down flipped version of the original
                                             -- image. The width dimension is treated similarly. Normalized coordinates
                                             -- outside the `[0, 1]` range are allowed, in which case we use
                                             -- `extrapolation_value` to extrapolate the input image values.
                          -> Tensor v4 Data.Int.Int32 -- ^ __box_ind__: A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.
                                                      -- The value of `box_ind[i]` specifies the image that the `i`-th box refers to.
                          -> Tensor Value Float -- ^ __output__: A 2-D tensor of shape `[num_boxes, 4]`.
cropAndResizeGradBoxes grads image boxes box_ind | eqLengthGuard [] =
    buildOp (opDef "CropAndResizeGradBoxes"
             & opAttr "T" .~ tensorType (undefined :: t))
        grads image boxes box_ind
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "bilinear" } }
  default_value { s: "bilinear" }
  description: "A string specifying the interpolation method. Only \'bilinear\' is\nsupported for now."
  name: "method"
  type: "string"
}
input_arg {
  description: "A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`."
  name: "grads"
  type: DT_FLOAT
}
input_arg {
  description: "A 4-D tensor of shape `[batch, image_height, image_width, depth]`.\nBoth `image_height` and `image_width` need to be positive."
  name: "image"
  type_attr: "T"
}
input_arg {
  description: "A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor\nspecifies the coordinates of a box in the `box_ind[i]` image and is specified\nin normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of\n`y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the\n`[0, 1]` interval of normalized image height is mapped to\n`[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in\nwhich case the sampled crop is an up-down flipped version of the original\nimage. The width dimension is treated similarly. Normalized coordinates\noutside the `[0, 1]` range are allowed, in which case we use\n`extrapolation_value` to extrapolate the input image values."
  name: "boxes"
  type: DT_FLOAT
}
input_arg {
  description: "A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.\nThe value of `box_ind[i]` specifies the image that the `i`-th box refers to."
  name: "box_ind"
  type: DT_INT32
}
output_arg {
  description: "A 2-D tensor of shape `[num_boxes, 4]`."
  name: "output"
  type: DT_FLOAT
}
-}

-- | BatchToSpace for N-D tensors of type T.
--
-- This operation reshapes the "batch" dimension 0 into `M + 1` dimensions of shape
-- `block_shape + [batch]`, interleaves these blocks back into the grid defined by
-- the spatial dimensions `[1, ..., M]`, to obtain a result with the same rank as
-- the input.  The spatial dimensions of this intermediate result are then
-- optionally cropped according to `crops` to produce the output.  This is the
-- reverse of SpaceToBatch.  See below for a precise description.
batchToSpaceND :: forall v1 v2 v3 t tblock_shape tcrops . (TensorType t,
                                                           TensorType tblock_shape,
                                                           OneOf '[Data.Int.Int32,
                                                                   Data.Int.Int64] tblock_shape,
                                                           TensorType tcrops,
                                                           OneOf '[Data.Int.Int32,
                                                                   Data.Int.Int64] tcrops) =>
                  Tensor v1 t -- ^ __input__: N-D with shape `input_shape = [batch] + spatial_shape + remaining_shape`,
                              -- where spatial_shape has M dimensions.
                  -> Tensor v2 tblock_shape -- ^ __block_shape__: 1-D with shape `[M]`, all values must be >= 1.
                  -> Tensor v3 tcrops -- ^ __crops__: 2-D with shape `[M, 2]`, all values must be >= 0.
                                      --   `crops[i] = [crop_start, crop_end]` specifies the amount to crop from input
                                      --   dimension `i + 1`, which corresponds to spatial dimension `i`.  It is
                                      --   required that
                                      --   `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i + 1]`.
                                      -- 
                                      -- This operation is equivalent to the following steps:
                                      -- 
                                      -- 1. Reshape `input` to `reshaped` of shape:
                                      --      [block_shape[0], ..., block_shape[M-1],
                                      --       batch / prod(block_shape),
                                      --       input_shape[1], ..., input_shape[N-1]]
                                      -- 
                                      -- 2. Permute dimensions of `reshaped` to produce `permuted` of shape
                                      --      [batch / prod(block_shape),
                                      -- 
                                      --       input_shape[1], block_shape[0],
                                      --       ...,
                                      --       input_shape[M], block_shape[M-1],
                                      -- 
                                      --       input_shape[M+1], ..., input_shape[N-1]]
                                      -- 
                                      -- 3. Reshape `permuted` to produce `reshaped_permuted` of shape
                                      --      [batch / prod(block_shape),
                                      -- 
                                      --       input_shape[1] * block_shape[0],
                                      --       ...,
                                      --       input_shape[M] * block_shape[M-1],
                                      -- 
                                      --       input_shape[M+1],
                                      --       ...,
                                      --       input_shape[N-1]]
                                      -- 
                                      -- 4. Crop the start and end of dimensions `[1, ..., M]` of
                                      --    `reshaped_permuted` according to `crops` to produce the output of shape:
                                      --      [batch / prod(block_shape),
                                      -- 
                                      --       input_shape[1] * block_shape[0] - crops[0,0] - crops[0,1],
                                      --       ...,
                                      --       input_shape[M] * block_shape[M-1] - crops[M-1,0] - crops[M-1,1],
                                      -- 
                                      --       input_shape[M+1], ..., input_shape[N-1]]
                                      -- 
                                      -- Some examples:
                                      -- 
                                      -- (1) For the following input of shape `[4, 1, 1, 1]`, `block_shape = [2, 2]`, and
                                      --     `crops = [[0, 0], [0, 0]]`:
                                      -- 
                                      -- ```prettyprint
                                      -- [[[[1]]], [[[2]]], [[[3]]], [[[4]]]]
                                      -- ```
                                      -- 
                                      -- The output tensor has shape `[1, 2, 2, 1]` and value:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[[1], [2]], [[3], [4]]]]
                                      -- ```
                                      -- 
                                      -- (2) For the following input of shape `[4, 1, 1, 3]`, `block_shape = [2, 2]`, and
                                      --     `crops = [[0, 0], [0, 0]]`:
                                      -- 
                                      -- ```prettyprint
                                      -- [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]
                                      -- ```
                                      -- 
                                      -- The output tensor has shape `[1, 2, 2, 3]` and value:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[[1, 2, 3], [4, 5, 6]],
                                      --       [[7, 8, 9], [10, 11, 12]]]]
                                      -- ```
                                      -- 
                                      -- (3) For the following input of shape `[4, 2, 2, 1]`, `block_shape = [2, 2]`, and
                                      --     `crops = [[0, 0], [0, 0]]`:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[[1], [3]], [[5], [7]]],
                                      --      [[[2], [4]], [[10], [12]]],
                                      --      [[[5], [7]], [[13], [15]]],
                                      --      [[[6], [8]], [[14], [16]]]]
                                      -- ```
                                      -- 
                                      -- The output tensor has shape `[1, 4, 4, 1]` and value:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[1],   [2],  [3],  [4]],
                                      --      [[5],   [6],  [7],  [8]],
                                      --      [[9],  [10], [11],  [12]],
                                      --      [[13], [14], [15],  [16]]]
                                      -- ```
                                      -- 
                                      -- (4) For the following input of shape `[8, 1, 3, 1]`, `block_shape = [2, 2]`, and
                                      --     `crops = [[0, 0], [2, 0]]`:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[[0], [1], [3]]], [[[0], [9], [11]]],
                                      --      [[[0], [2], [4]]], [[[0], [10], [12]]],
                                      --      [[[0], [5], [7]]], [[[0], [13], [15]]],
                                      --      [[[0], [6], [8]]], [[[0], [14], [16]]]]
                                      -- ```
                                      -- 
                                      -- The output tensor has shape `[2, 2, 4, 1]` and value:
                                      -- 
                                      -- ```prettyprint
                                      -- x = [[[[1],   [2],  [3],  [4]],
                                      --       [[5],   [6],  [7],  [8]]],
                                      --      [[[9],  [10], [11],  [12]],
                                      --       [[13], [14], [15],  [16]]]]
                                      -- ```
                  -> Tensor Value t -- ^ __output__
batchToSpaceND input block_shape crops | eqLengthGuard [] =
    buildOp (opDef "BatchToSpaceND"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tblock_shape" .~ tensorType (undefined :: tblock_shape)
             & opAttr "Tcrops" .~ tensorType (undefined :: tcrops))
        input block_shape crops
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tblock_shape"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tcrops"
  type: "type"
}
input_arg {
  description: "N-D with shape `input_shape = [batch] + spatial_shape + remaining_shape`,\nwhere spatial_shape has M dimensions."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "1-D with shape `[M]`, all values must be >= 1."
  name: "block_shape"
  type_attr: "Tblock_shape"
}
input_arg {
  description: "2-D with shape `[M, 2]`, all values must be >= 0.\n  `crops[i] = [crop_start, crop_end]` specifies the amount to crop from input\n  dimension `i + 1`, which corresponds to spatial dimension `i`.  It is\n  required that\n  `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i + 1]`.\n\nThis operation is equivalent to the following steps:\n\n1. Reshape `input` to `reshaped` of shape:\n     [block_shape[0], ..., block_shape[M-1],\n      batch / prod(block_shape),\n      input_shape[1], ..., input_shape[N-1]]\n\n2. Permute dimensions of `reshaped` to produce `permuted` of shape\n     [batch / prod(block_shape),\n\n      input_shape[1], block_shape[0],\n      ...,\n      input_shape[M], block_shape[M-1],\n\n      input_shape[M+1], ..., input_shape[N-1]]\n\n3. Reshape `permuted` to produce `reshaped_permuted` of shape\n     [batch / prod(block_shape),\n\n      input_shape[1] * block_shape[0],\n      ...,\n      input_shape[M] * block_shape[M-1],\n\n      input_shape[M+1],\n      ...,\n      input_shape[N-1]]\n\n4. Crop the start and end of dimensions `[1, ..., M]` of\n   `reshaped_permuted` according to `crops` to produce the output of shape:\n     [batch / prod(block_shape),\n\n      input_shape[1] * block_shape[0] - crops[0,0] - crops[0,1],\n      ...,\n      input_shape[M] * block_shape[M-1] - crops[M-1,0] - crops[M-1,1],\n\n      input_shape[M+1], ..., input_shape[N-1]]\n\nSome examples:\n\n(1) For the following input of shape `[4, 1, 1, 1]`, `block_shape = [2, 2]`, and\n    `crops = [[0, 0], [0, 0]]`:\n\n```prettyprint\n[[[[1]]], [[[2]]], [[[3]]], [[[4]]]]\n```\n\nThe output tensor has shape `[1, 2, 2, 1]` and value:\n\n```prettyprint\nx = [[[[1], [2]], [[3], [4]]]]\n```\n\n(2) For the following input of shape `[4, 1, 1, 3]`, `block_shape = [2, 2]`, and\n    `crops = [[0, 0], [0, 0]]`:\n\n```prettyprint\n[[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]\n```\n\nThe output tensor has shape `[1, 2, 2, 3]` and value:\n\n```prettyprint\nx = [[[[1, 2, 3], [4, 5, 6]],\n      [[7, 8, 9], [10, 11, 12]]]]\n```\n\n(3) For the following input of shape `[4, 2, 2, 1]`, `block_shape = [2, 2]`, and\n    `crops = [[0, 0], [0, 0]]`:\n\n```prettyprint\nx = [[[[1], [3]], [[5], [7]]],\n     [[[2], [4]], [[10], [12]]],\n     [[[5], [7]], [[13], [15]]],\n     [[[6], [8]], [[14], [16]]]]\n```\n\nThe output tensor has shape `[1, 4, 4, 1]` and value:\n\n```prettyprint\nx = [[[1],   [2],  [3],  [4]],\n     [[5],   [6],  [7],  [8]],\n     [[9],  [10], [11],  [12]],\n     [[13], [14], [15],  [16]]]\n```\n\n(4) For the following input of shape `[8, 1, 3, 1]`, `block_shape = [2, 2]`, and\n    `crops = [[0, 0], [2, 0]]`:\n\n```prettyprint\nx = [[[[0], [1], [3]]], [[[0], [9], [11]]],\n     [[[0], [2], [4]]], [[[0], [10], [12]]],\n     [[[0], [5], [7]]], [[[0], [13], [15]]],\n     [[[0], [6], [8]]], [[[0], [14], [16]]]]\n```\n\nThe output tensor has shape `[2, 2, 4, 1]` and value:\n\n```prettyprint\nx = [[[[1],   [2],  [3],  [4]],\n      [[5],   [6],  [7],  [8]]],\n     [[[9],  [10], [11],  [12]],\n      [[13], [14], [15],  [16]]]]\n```"
  name: "crops"
  type_attr: "Tcrops"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | SpaceToBatch for 4-D tensors of type T.
--
-- This is a legacy version of the more general SpaceToBatchND.
-- 
-- Zero-pads and then rearranges (permutes) blocks of spatial data into batch.
-- More specifically, this op outputs a copy of the input tensor where values from
-- the `height` and `width` dimensions are moved to the `batch` dimension. After
-- the zero-padding, both `height` and `width` of the input must be divisible by the
-- block size.
spaceToBatch :: forall v1 v2 t tpaddings . (TensorType t, TensorType tpaddings,
                                            OneOf '[Data.Int.Int32,
                                                    Data.Int.Int64] tpaddings) =>
                Data.Int.Int64 -- ^ __block_size__
                -> Tensor v1 t -- ^ __input__: 4-D with shape `[batch, height, width, depth]`.
                -> Tensor v2 tpaddings -- ^ __paddings__: 2-D tensor of non-negative integers with shape `[2, 2]`. It specifies
                                       --   the padding of the input with zeros across the spatial dimensions as follows:
                                       -- 
                                       --       paddings = [[pad_top, pad_bottom], [pad_left, pad_right]]
                                       -- 
                                       --   The effective spatial dimensions of the zero-padded input tensor will be:
                                       -- 
                                       --       height_pad = pad_top + height + pad_bottom
                                       --       width_pad = pad_left + width + pad_right
                                       -- 
                                       -- The attr `block_size` must be greater than one. It indicates the block size.
                                       -- 
                                       --   * Non-overlapping blocks of size `block_size x block size` in the height and
                                       --     width dimensions are rearranged into the batch dimension at each location.
                                       --   * The batch of the output tensor is `batch * block_size * block_size`.
                                       --   * Both height_pad and width_pad must be divisible by block_size.
                                       -- 
                                       -- The shape of the output will be:
                                       -- 
                                       --     [batch*block_size*block_size, height_pad/block_size, width_pad/block_size,
                                       --      depth]
                                       -- 
                                       -- Some examples:
                                       -- 
                                       -- (1) For the following input of shape `[1, 2, 2, 1]` and block_size of 2:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1], [2]], [[3], [4]]]]
                                       -- ```
                                       -- 
                                       -- The output tensor has shape `[4, 1, 1, 1]` and value:
                                       -- 
                                       -- ```prettyprint
                                       -- [[[[1]]], [[[2]]], [[[3]]], [[[4]]]]
                                       -- ```
                                       -- 
                                       -- (2) For the following input of shape `[1, 2, 2, 3]` and block_size of 2:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1, 2, 3], [4, 5, 6]],
                                       --       [[7, 8, 9], [10, 11, 12]]]]
                                       -- ```
                                       -- 
                                       -- The output tensor has shape `[4, 1, 1, 3]` and value:
                                       -- 
                                       -- ```prettyprint
                                       -- [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]
                                       -- ```
                                       -- 
                                       -- (3) For the following input of shape `[1, 4, 4, 1]` and block_size of 2:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1],   [2],  [3],  [4]],
                                       --       [[5],   [6],  [7],  [8]],
                                       --       [[9],  [10], [11],  [12]],
                                       --       [[13], [14], [15],  [16]]]]
                                       -- ```
                                       -- 
                                       -- The output tensor has shape `[4, 2, 2, 1]` and value:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1], [3]], [[5], [7]]],
                                       --      [[[2], [4]], [[10], [12]]],
                                       --      [[[5], [7]], [[13], [15]]],
                                       --      [[[6], [8]], [[14], [16]]]]
                                       -- ```
                                       -- 
                                       -- (4) For the following input of shape `[2, 2, 4, 1]` and block_size of 2:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1],   [2],  [3],  [4]],
                                       --       [[5],   [6],  [7],  [8]]],
                                       --      [[[9],  [10], [11],  [12]],
                                       --       [[13], [14], [15],  [16]]]]
                                       -- ```
                                       -- 
                                       -- The output tensor has shape `[8, 1, 2, 1]` and value:
                                       -- 
                                       -- ```prettyprint
                                       -- x = [[[[1], [3]]], [[[9], [11]]], [[[2], [4]]], [[[10], [12]]],
                                       --      [[[5], [7]]], [[[13], [15]]], [[[6], [8]]], [[[14], [16]]]]
                                       -- ```
                                       -- 
                                       -- Among others, this operation is useful for reducing atrous convolution into
                                       -- regular convolution.
                -> Tensor Value t -- ^ __output__
spaceToBatch block_size input paddings | eqLengthGuard [] =
    buildOp (opDef "SpaceToBatch"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tpaddings" .~ tensorType (undefined :: tpaddings)
             & opAttr "block_size" .~ block_size)
        input paddings
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tpaddings"
  type: "type"
}
attr {
  has_minimum: true minimum: 2 name: "block_size" type: "int"
}
input_arg {
  description: "4-D with shape `[batch, height, width, depth]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "2-D tensor of non-negative integers with shape `[2, 2]`. It specifies\n  the padding of the input with zeros across the spatial dimensions as follows:\n\n      paddings = [[pad_top, pad_bottom], [pad_left, pad_right]]\n\n  The effective spatial dimensions of the zero-padded input tensor will be:\n\n      height_pad = pad_top + height + pad_bottom\n      width_pad = pad_left + width + pad_right\n\nThe attr `block_size` must be greater than one. It indicates the block size.\n\n  * Non-overlapping blocks of size `block_size x block size` in the height and\n    width dimensions are rearranged into the batch dimension at each location.\n  * The batch of the output tensor is `batch * block_size * block_size`.\n  * Both height_pad and width_pad must be divisible by block_size.\n\nThe shape of the output will be:\n\n    [batch*block_size*block_size, height_pad/block_size, width_pad/block_size,\n     depth]\n\nSome examples:\n\n(1) For the following input of shape `[1, 2, 2, 1]` and block_size of 2:\n\n```prettyprint\nx = [[[[1], [2]], [[3], [4]]]]\n```\n\nThe output tensor has shape `[4, 1, 1, 1]` and value:\n\n```prettyprint\n[[[[1]]], [[[2]]], [[[3]]], [[[4]]]]\n```\n\n(2) For the following input of shape `[1, 2, 2, 3]` and block_size of 2:\n\n```prettyprint\nx = [[[[1, 2, 3], [4, 5, 6]],\n      [[7, 8, 9], [10, 11, 12]]]]\n```\n\nThe output tensor has shape `[4, 1, 1, 3]` and value:\n\n```prettyprint\n[[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]\n```\n\n(3) For the following input of shape `[1, 4, 4, 1]` and block_size of 2:\n\n```prettyprint\nx = [[[[1],   [2],  [3],  [4]],\n      [[5],   [6],  [7],  [8]],\n      [[9],  [10], [11],  [12]],\n      [[13], [14], [15],  [16]]]]\n```\n\nThe output tensor has shape `[4, 2, 2, 1]` and value:\n\n```prettyprint\nx = [[[[1], [3]], [[5], [7]]],\n     [[[2], [4]], [[10], [12]]],\n     [[[5], [7]], [[13], [15]]],\n     [[[6], [8]], [[14], [16]]]]\n```\n\n(4) For the following input of shape `[2, 2, 4, 1]` and block_size of 2:\n\n```prettyprint\nx = [[[[1],   [2],  [3],  [4]],\n      [[5],   [6],  [7],  [8]]],\n     [[[9],  [10], [11],  [12]],\n      [[13], [14], [15],  [16]]]]\n```\n\nThe output tensor has shape `[8, 1, 2, 1]` and value:\n\n```prettyprint\nx = [[[[1], [3]]], [[[9], [11]]], [[[2], [4]]], [[[10], [12]]],\n     [[[5], [7]]], [[[13], [15]]], [[[6], [8]]], [[[14], [16]]]]\n```\n\nAmong others, this operation is useful for reducing atrous convolution into\nregular convolution."
  name: "paddings"
  type_attr: "Tpaddings"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Adjust the hue of one or more images.
--
-- `images` is a tensor of at least 3 dimensions.  The last dimension is
-- interpretted as channels, and must be three.
-- 
-- The input image is considered in the RGB colorspace. Conceptually, the RGB
-- colors are first mapped into HSV. A delta is then applied all the hue values,
-- and then remapped back to RGB colorspace.
adjustHue :: Tensor v1 Float -- ^ __images__: Images to adjust.  At least 3-D.
             -> Tensor v2 Float -- ^ __delta__: A float delta to add to the hue.
             -> Tensor Value Float -- ^ __output__: The hue-adjusted image or images.
adjustHue images delta | eqLengthGuard [] =
    buildOp (opDef "AdjustHue")
        images delta
{-
input_arg {
  description: "Images to adjust.  At least 3-D."
  name: "images"
  type: DT_FLOAT
}
input_arg {
  description: "A float delta to add to the hue."
  name: "delta"
  type: DT_FLOAT
}
output_arg {
  description: "The hue-adjusted image or images."
  name: "output"
  type: DT_FLOAT
}
-}

-- | SpaceToBatch for N-D tensors of type T.
--
-- This operation divides "spatial" dimensions `[1, ..., M]` of the input into a
-- grid of blocks of shape `block_shape`, and interleaves these blocks with the
-- "batch" dimension (0) such that in the output, the spatial dimensions
-- `[1, ..., M]` correspond to the position within the grid, and the batch
-- dimension combines both the position within a spatial block and the original
-- batch position.  Prior to division into blocks, the spatial dimensions of the
-- input are optionally zero padded according to `paddings`.  See below for a
-- precise description.
spaceToBatchND :: forall v1 v2 v3 t tblock_shape tpaddings . (TensorType t,
                                                              TensorType tblock_shape,
                                                              OneOf '[Data.Int.Int32,
                                                                      Data.Int.Int64] tblock_shape,
                                                              TensorType tpaddings,
                                                              OneOf '[Data.Int.Int32,
                                                                      Data.Int.Int64] tpaddings) =>
                  Tensor v1 t -- ^ __input__: N-D with shape `input_shape = [batch] + spatial_shape + remaining_shape`,
                              -- where spatial_shape has `M` dimensions.
                  -> Tensor v2 tblock_shape -- ^ __block_shape__: 1-D with shape `[M]`, all values must be >= 1.
                  -> Tensor v3 tpaddings -- ^ __paddings__: 2-D with shape `[M, 2]`, all values must be >= 0.
                                         --   `paddings[i] = [pad_start, pad_end]` specifies the padding for input dimension
                                         --   `i + 1`, which corresponds to spatial dimension `i`.  It is required that
                                         --   `block_shape[i]` divides `input_shape[i + 1] + pad_start + pad_end`.
                                         -- 
                                         -- This operation is equivalent to the following steps:
                                         -- 
                                         -- 1. Zero-pad the start and end of dimensions `[1, ..., M]` of the
                                         --    input according to `paddings` to produce `padded` of shape `padded_shape`.
                                         -- 
                                         -- 2. Reshape `padded` to `reshaped_padded` of shape:
                                         -- 
                                         --      [batch] +
                                         --      [padded_shape[1] / block_shape[0],
                                         --        block_shape[0],
                                         --       ...,
                                         --       padded_shape[M] / block_shape[M-1],
                                         --       block_shape[M-1]] +
                                         --      remaining_shape
                                         -- 
                                         -- 3. Permute dimensions of `reshaped_padded` to produce
                                         --    `permuted_reshaped_padded` of shape:
                                         -- 
                                         --      block_shape +
                                         --      [batch] +
                                         --      [padded_shape[1] / block_shape[0],
                                         --       ...,
                                         --       padded_shape[M] / block_shape[M-1]] +
                                         --      remaining_shape
                                         -- 
                                         -- 4. Reshape `permuted_reshaped_padded` to flatten `block_shape` into the batch
                                         --    dimension, producing an output tensor of shape:
                                         -- 
                                         --      [batch * prod(block_shape)] +
                                         --      [padded_shape[1] / block_shape[0],
                                         --       ...,
                                         --       padded_shape[M] / block_shape[M-1]] +
                                         --      remaining_shape
                                         -- 
                                         -- Some examples:
                                         -- 
                                         -- (1) For the following input of shape `[1, 2, 2, 1]`, `block_shape = [2, 2]`, and
                                         --     `paddings = [[0, 0], [0, 0]]`:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[1], [2]], [[3], [4]]]]
                                         -- ```
                                         -- 
                                         -- The output tensor has shape `[4, 1, 1, 1]` and value:
                                         -- 
                                         -- ```prettyprint
                                         -- [[[[1]]], [[[2]]], [[[3]]], [[[4]]]]
                                         -- ```
                                         -- 
                                         -- (2) For the following input of shape `[1, 2, 2, 3]`, `block_shape = [2, 2]`, and
                                         --     `paddings = [[0, 0], [0, 0]]`:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[1, 2, 3], [4, 5, 6]],
                                         --       [[7, 8, 9], [10, 11, 12]]]]
                                         -- ```
                                         -- 
                                         -- The output tensor has shape `[4, 1, 1, 3]` and value:
                                         -- 
                                         -- ```prettyprint
                                         -- [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]
                                         -- ```
                                         -- 
                                         -- (3) For the following input of shape `[1, 4, 4, 1]`, `block_shape = [2, 2]`, and
                                         --     `paddings = [[0, 0], [0, 0]]`:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[1],   [2],  [3],  [4]],
                                         --       [[5],   [6],  [7],  [8]],
                                         --       [[9],  [10], [11],  [12]],
                                         --       [[13], [14], [15],  [16]]]]
                                         -- ```
                                         -- 
                                         -- The output tensor has shape `[4, 2, 2, 1]` and value:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[1], [3]], [[5], [7]]],
                                         --      [[[2], [4]], [[10], [12]]],
                                         --      [[[5], [7]], [[13], [15]]],
                                         --      [[[6], [8]], [[14], [16]]]]
                                         -- ```
                                         -- 
                                         -- (4) For the following input of shape `[2, 2, 4, 1]`, block_shape = `[2, 2]`, and
                                         --     paddings = `[[0, 0], [2, 0]]`:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[1],   [2],  [3],  [4]],
                                         --       [[5],   [6],  [7],  [8]]],
                                         --      [[[9],  [10], [11],  [12]],
                                         --       [[13], [14], [15],  [16]]]]
                                         -- ```
                                         -- 
                                         -- The output tensor has shape `[8, 1, 3, 1]` and value:
                                         -- 
                                         -- ```prettyprint
                                         -- x = [[[[0], [1], [3]]], [[[0], [9], [11]]],
                                         --      [[[0], [2], [4]]], [[[0], [10], [12]]],
                                         --      [[[0], [5], [7]]], [[[0], [13], [15]]],
                                         --      [[[0], [6], [8]]], [[[0], [14], [16]]]]
                                         -- ```
                                         -- 
                                         -- Among others, this operation is useful for reducing atrous convolution into
                                         -- regular convolution.
                  -> Tensor Value t -- ^ __output__
spaceToBatchND input block_shape paddings | eqLengthGuard [] =
    buildOp (opDef "SpaceToBatchND"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tblock_shape" .~ tensorType (undefined :: tblock_shape)
             & opAttr "Tpaddings" .~ tensorType (undefined :: tpaddings))
        input block_shape paddings
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tblock_shape"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tpaddings"
  type: "type"
}
input_arg {
  description: "N-D with shape `input_shape = [batch] + spatial_shape + remaining_shape`,\nwhere spatial_shape has `M` dimensions."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "1-D with shape `[M]`, all values must be >= 1."
  name: "block_shape"
  type_attr: "Tblock_shape"
}
input_arg {
  description: "2-D with shape `[M, 2]`, all values must be >= 0.\n  `paddings[i] = [pad_start, pad_end]` specifies the padding for input dimension\n  `i + 1`, which corresponds to spatial dimension `i`.  It is required that\n  `block_shape[i]` divides `input_shape[i + 1] + pad_start + pad_end`.\n\nThis operation is equivalent to the following steps:\n\n1. Zero-pad the start and end of dimensions `[1, ..., M]` of the\n   input according to `paddings` to produce `padded` of shape `padded_shape`.\n\n2. Reshape `padded` to `reshaped_padded` of shape:\n\n     [batch] +\n     [padded_shape[1] / block_shape[0],\n       block_shape[0],\n      ...,\n      padded_shape[M] / block_shape[M-1],\n      block_shape[M-1]] +\n     remaining_shape\n\n3. Permute dimensions of `reshaped_padded` to produce\n   `permuted_reshaped_padded` of shape:\n\n     block_shape +\n     [batch] +\n     [padded_shape[1] / block_shape[0],\n      ...,\n      padded_shape[M] / block_shape[M-1]] +\n     remaining_shape\n\n4. Reshape `permuted_reshaped_padded` to flatten `block_shape` into the batch\n   dimension, producing an output tensor of shape:\n\n     [batch * prod(block_shape)] +\n     [padded_shape[1] / block_shape[0],\n      ...,\n      padded_shape[M] / block_shape[M-1]] +\n     remaining_shape\n\nSome examples:\n\n(1) For the following input of shape `[1, 2, 2, 1]`, `block_shape = [2, 2]`, and\n    `paddings = [[0, 0], [0, 0]]`:\n\n```prettyprint\nx = [[[[1], [2]], [[3], [4]]]]\n```\n\nThe output tensor has shape `[4, 1, 1, 1]` and value:\n\n```prettyprint\n[[[[1]]], [[[2]]], [[[3]]], [[[4]]]]\n```\n\n(2) For the following input of shape `[1, 2, 2, 3]`, `block_shape = [2, 2]`, and\n    `paddings = [[0, 0], [0, 0]]`:\n\n```prettyprint\nx = [[[[1, 2, 3], [4, 5, 6]],\n      [[7, 8, 9], [10, 11, 12]]]]\n```\n\nThe output tensor has shape `[4, 1, 1, 3]` and value:\n\n```prettyprint\n[[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]\n```\n\n(3) For the following input of shape `[1, 4, 4, 1]`, `block_shape = [2, 2]`, and\n    `paddings = [[0, 0], [0, 0]]`:\n\n```prettyprint\nx = [[[[1],   [2],  [3],  [4]],\n      [[5],   [6],  [7],  [8]],\n      [[9],  [10], [11],  [12]],\n      [[13], [14], [15],  [16]]]]\n```\n\nThe output tensor has shape `[4, 2, 2, 1]` and value:\n\n```prettyprint\nx = [[[[1], [3]], [[5], [7]]],\n     [[[2], [4]], [[10], [12]]],\n     [[[5], [7]], [[13], [15]]],\n     [[[6], [8]], [[14], [16]]]]\n```\n\n(4) For the following input of shape `[2, 2, 4, 1]`, block_shape = `[2, 2]`, and\n    paddings = `[[0, 0], [2, 0]]`:\n\n```prettyprint\nx = [[[[1],   [2],  [3],  [4]],\n      [[5],   [6],  [7],  [8]]],\n     [[[9],  [10], [11],  [12]],\n      [[13], [14], [15],  [16]]]]\n```\n\nThe output tensor has shape `[8, 1, 3, 1]` and value:\n\n```prettyprint\nx = [[[[0], [1], [3]]], [[[0], [9], [11]]],\n     [[[0], [2], [4]]], [[[0], [10], [12]]],\n     [[[0], [5], [7]]], [[[0], [13], [15]]],\n     [[[0], [6], [8]]], [[[0], [14], [16]]]]\n```\n\nAmong others, this operation is useful for reducing atrous convolution into\nregular convolution."
  name: "paddings"
  type_attr: "Tpaddings"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns the diagonal part of the tensor.
--
-- This operation returns a tensor with the `diagonal` part
-- of the `input`. The `diagonal` part is computed as follows:
-- 
-- Assume `input` has dimensions `[D1,..., Dk, D1,..., Dk]`, then the output is a
-- tensor of rank `k` with dimensions `[D1,..., Dk]` where:
-- 
-- `diagonal[i1,..., ik] = input[i1, ..., ik, i1,..., ik]`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'input' is [[1, 0, 0, 0]
--               [0, 2, 0, 0]
--               [0, 0, 3, 0]
--               [0, 0, 0, 4]]
-- 
-- tf.diag_part(input) ==> [1, 2, 3, 4]
-- ```
diagPart :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int32, Data.Int.Int64,
                                                 Double, Float] t) =>
            Tensor v1 t -- ^ __input__: Rank k tensor where k is 2, 4, or 6.
            -> Tensor Value t -- ^ __diagonal__: The extracted diagonal.
diagPart input | eqLengthGuard [] =
    buildOp (opDef "DiagPart"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Rank k tensor where k is 2, 4, or 6."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The extracted diagonal."
  name: "diagonal"
  type_attr: "T"
}
-}

-- | A placeholder op for a value that will be fed into the computation.
--
-- N.B. This operation will fail with an error if it is executed. It is
-- intended as a way to represent a value that will always be fed, and to
-- provide attrs that enable the fed value to be checked at runtime.
placeholderV2 :: forall dtype . (TensorType dtype) =>
                 Shape -- ^ __shape__: The shape of the tensor. The shape can be any partially-specified
                       -- shape.  To be unconstrained, pass in a shape with unknown rank.
                 -> Tensor Value dtype -- ^ __output__: A placeholder tensor that must be replaced using the feed mechanism.
placeholderV2 shape | eqLengthGuard [] =
    buildOp (opDef "PlaceholderV2"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        
{-
attr {
  description: "The type of elements in the tensor."
  name: "dtype"
  type: "type"
}
attr {
  description: "The shape of the tensor. The shape can be any partially-specified\nshape.  To be unconstrained, pass in a shape with unknown rank."
  name: "shape"
  type: "shape"
}
output_arg {
  description: "A placeholder tensor that must be replaced using the feed mechanism."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Computes acos of x element-wise.

acos :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int32, Data.Int.Int64,
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
acos x | eqLengthGuard [] =
    buildOp (opDef "Acos"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | A placeholder op for a value that will be fed into the computation.
--
-- N.B. This operation will fail with an error if it is executed. It is
-- intended as a way to represent a value that will always be fed, and to
-- provide attrs that enable the fed value to be checked at runtime.
placeholder :: forall dtype . (TensorType dtype) =>
               Tensor Value dtype -- ^ __output__: A placeholder tensor that must be replaced using the feed mechanism.
placeholder  | eqLengthGuard [] =
    buildOp (opDef "Placeholder"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        
{-
attr {
  description: "The type of elements in the tensor."
  name: "dtype"
  type: "type"
}
attr {
  default_value { shape { } }
  description: "(Optional) The shape of the tensor. If the shape has 0 dimensions, the\nshape is unconstrained."
  name: "shape"
  type: "shape"
}
output_arg {
  description: "A placeholder tensor that must be replaced using the feed mechanism."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Does nothing. Serves as a control trigger for scheduling.
--
-- Only useful as a placeholder for control edges.
controlTrigger :: ControlNode
controlTrigger  | eqLengthGuard [] =
    buildOp (opDef "ControlTrigger")
        
{-

-}

-- | Computes atan of x element-wise.

atan :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int32, Data.Int.Int64,
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
atan x | eqLengthGuard [] =
    buildOp (opDef "Atan"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Pads a tensor with mirrored values.
--
-- This operation pads a `input` with mirrored values according to the `paddings`
-- you specify. `paddings` is an integer tensor with shape `[n, 2]`, where n is
-- the rank of `input`. For each dimension D of `input`, `paddings[D, 0]` indicates
-- how many values to add before the contents of `input` in that dimension, and
-- `paddings[D, 1]` indicates how many values to add after the contents of `input`
-- in that dimension. Both `paddings[D, 0]` and `paddings[D, 1]` must be no greater
-- than `input.dim_size(D)` (or `input.dim_size(D) - 1`) if `copy_border` is true
-- (if false, respectively).
-- 
-- The padded size of each dimension D of the output is:
-- 
-- `paddings(D, 0) + input.dim_size(D) + paddings(D, 1)`
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[1, 2, 3], [4, 5, 6]].
-- # 'paddings' is [[1, 1]], [2, 2]].
-- # 'mode' is SYMMETRIC.
-- # rank of 't' is 2.
-- pad(t, paddings) ==> [[2, 1, 1, 2, 3, 3, 2]
--                       [2, 1, 1, 2, 3, 3, 2]
--                       [5, 4, 4, 5, 6, 6, 5]
--                       [5, 4, 4, 5, 6, 6, 5]]
-- ```
mirrorPad :: forall v1 v2 t tpaddings . (TensorType t, TensorType tpaddings,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tpaddings) =>
             Tensor v1 t -- ^ __input__: The input tensor to be padded.
             -> Tensor v2 tpaddings -- ^ __paddings__: A two-column matrix specifying the padding sizes. The number of
                                    -- rows must be the same as the rank of `input`.
             -> Tensor Value t -- ^ __output__: The padded tensor.
mirrorPad input paddings | eqLengthGuard [] =
    buildOp (opDef "MirrorPad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tpaddings" .~ tensorType (undefined :: tpaddings))
        input paddings
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tpaddings"
  type: "type"
}
attr {
  allowed_values { list { s: "REFLECT" s: "SYMMETRIC" } }
  description: "Either `REFLECT` or `SYMMETRIC`. In reflect mode the padded regions\ndo not include the borders, while in symmetric mode the padded regions\ndo include the borders. For example, if `input` is `[1, 2, 3]` and `paddings`\nis `[0, 2]`, then the output is `[1, 2, 3, 2, 1]` in reflect mode, and\nit is `[1, 2, 3, 3, 2]` in symmetric mode."
  name: "mode"
  type: "string"
}
input_arg {
  description: "The input tensor to be padded."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "A two-column matrix specifying the padding sizes. The number of\nrows must be the same as the rank of `input`."
  name: "paddings"
  type_attr: "Tpaddings"
}
output_arg {
  description: "The padded tensor." name: "output" type_attr: "T"
}
-}

-- | Returns locations of true values in a boolean tensor.
--
-- This operation returns the coordinates of true elements in `input`. The
-- coordinates are returned in a 2-D tensor where the first dimension (rows)
-- represents the number of true elements, and the second dimension (columns)
-- represents the coordinates of the true elements. Keep in mind, the shape of
-- the output tensor can vary depending on how many true values there are in
-- `input`. Indices are output in row-major order.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'input' tensor is [[True, False]
-- #                    [True, False]]
-- # 'input' has two true values, so output has two coordinates.
-- # 'input' has rank of 2, so coordinates have two indices.
-- where(input) ==> [[0, 0],
--                   [1, 0]]
-- 
-- # `input` tensor is [[[True, False]
-- #                     [True, False]]
-- #                    [[False, True]
-- #                     [False, True]]
-- #                    [[False, False]
-- #                     [False, True]]]
-- # 'input' has 5 true values, so output has 5 coordinates.
-- # 'input' has rank of 3, so coordinates have three indices.
-- where(input) ==> [[0, 0, 0],
--                   [0, 1, 0],
--                   [1, 0, 1],
--                   [1, 1, 1],
--                   [2, 1, 1]]
-- ```
where' :: Tensor v1 Bool -- ^ __input__
          -> Tensor Value Data.Int.Int64 -- ^ __index__
where' input | eqLengthGuard [] =
    buildOp (opDef "Where")
        input
{-
input_arg { name: "input" type: DT_BOOL }
output_arg { name: "index" type: DT_INT64 }
-}

-- | Computes gradients of average pooling function.

avgPool3DGrad :: forall v1 v2 t . (TensorType t,
                                   OneOf '[(Data.Complex.Complex Double),
                                           (Data.Complex.Complex Float),
                                           Data.Int.Int16, Data.Int.Int32,
                                           Data.Int.Int64, Data.Int.Int8,
                                           Data.Word.Word16, Data.Word.Word8,
                                           Double, Float] t) =>
                 Tensor v1 Data.Int.Int32 -- ^ __orig_input_shape__: The original input dimensions.
                 -> Tensor v2 t -- ^ __grad__: Output backprop of shape `[batch, depth, rows, cols, channels]`.
                 -> Tensor Value t -- ^ __output__: The backprop for input.
avgPool3DGrad orig_input_shape grad | eqLengthGuard [] =
    buildOp (opDef "AvgPool3DGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input_shape grad
{-
attr {
  description: "1-D tensor of length 5. The size of the window for each dimension of\nthe input tensor. Must have `ksize[0] = ksize[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The original input dimensions."
  name: "orig_input_shape"
  type: DT_INT32
}
input_arg {
  description: "Output backprop of shape `[batch, depth, rows, cols, channels]`."
  name: "grad"
  type_attr: "T"
}
output_arg {
  description: "The backprop for input."
  name: "output"
  type_attr: "T"
}
-}

-- | Restore a Reader to its initial clean state.

readerReset :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
               -> Build (ControlNode)
readerReset reader_handle | eqLengthGuard [] =
    buildOp (opDef "ReaderReset")
        reader_handle
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Returns the gradient of `Tile`.
--
-- Since `Tile` takes an input and repeats the input `multiples` times
-- along each dimension, `TileGrad` takes in `multiples` and aggregates
-- each repeated tile of `input` into `output`.
tileGrad :: forall v1 v2 t . (TensorType t) => Tensor v1 t -- ^ __input__
            -> Tensor v2 Data.Int.Int32 -- ^ __multiples__
            -> Tensor Value t -- ^ __output__
tileGrad input multiples | eqLengthGuard [] =
    buildOp (opDef "TileGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        input multiples
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
input_arg { name: "multiples" type: DT_INT32 }
output_arg { name: "output" type_attr: "T" }
-}

-- | Inserts a dimension of 1 into a tensor's shape.
--
-- Given a tensor `input`, this operation inserts a dimension of 1 at the
-- dimension index `dim` of `input`'s shape. The dimension index `dim` starts at
-- zero; if you specify a negative number for `dim` it is counted backward from
-- the end.
-- 
-- This operation is useful if you want to add a batch dimension to a single
-- element. For example, if you have a single image of shape `[height, width,
-- channels]`, you can make it a batch of 1 image with `expand_dims(image, 0)`,
-- which will make the shape `[1, height, width, channels]`.
-- 
-- Other examples:
-- 
-- ```prettyprint
-- # 't' is a tensor of shape [2]
-- shape(expand_dims(t, 0)) ==> [1, 2]
-- shape(expand_dims(t, 1)) ==> [2, 1]
-- shape(expand_dims(t, -1)) ==> [2, 1]
-- 
-- # 't2' is a tensor of shape [2, 3, 5]
-- shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]
-- shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]
-- shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]
-- ```
-- 
-- This operation requires that:
-- 
-- `-1-input.dims() <= dim <= input.dims()`
-- 
-- This operation is related to `squeeze()`, which removes dimensions of
-- size 1.
expandDims :: forall v1 v2 t tdim . (TensorType t, TensorType tdim,
                                     OneOf '[Data.Int.Int32,
                                             Data.Int.Int64] tdim) =>
              Tensor v1 t -- ^ __input__
              -> Tensor v2 tdim -- ^ __dim__: 0-D (scalar). Specifies the dimension index at which to
                                -- expand the shape of `input`.
              -> Tensor Value t -- ^ __output__: Contains the same data as `input`, but its shape has an additional
              -- dimension of size 1 added.
expandDims input dim | eqLengthGuard [] =
    buildOp (opDef "ExpandDims"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tdim" .~ tensorType (undefined :: tdim))
        input dim
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tdim"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "0-D (scalar). Specifies the dimension index at which to\nexpand the shape of `input`."
  name: "dim"
  type_attr: "Tdim"
}
output_arg {
  description: "Contains the same data as `input`, but its shape has an additional\ndimension of size 1 added."
  name: "output"
  type_attr: "T"
}
-}

-- | Outputs a `Summary` protocol buffer with a tensor.

tensorSummary :: forall v1 t . (TensorType t) =>
                 Tensor v1 t -- ^ __tensor__: A tensor to serialize.
                 -> Tensor Value Data.ByteString.ByteString -- ^ __summary__
tensorSummary tensor | eqLengthGuard [] =
    buildOp (opDef "TensorSummary"
             & opAttr "T" .~ tensorType (undefined :: t))
        tensor
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "A json-encoded SummaryDescription proto."
  name: "description"
  type: "string"
}
attr {
  default_value { list { } }
  description: "An unused list of strings."
  name: "labels"
  type: "list(string)"
}
attr {
  default_value { s: "" }
  description: "An unused string."
  name: "display_name"
  type: "string"
}
input_arg {
  description: "A tensor to serialize." name: "tensor" type_attr: "T"
}
output_arg { name: "summary" type: DT_STRING }
-}

-- | Constructs a tensor by tiling a given tensor.
--
-- This operation creates a new tensor by replicating `input` `multiples` times.
-- The output tensor's i'th dimension has `input.dims(i) * multiples[i]` elements,
-- and the values of `input` are replicated `multiples[i]` times along the 'i'th
-- dimension. For example, tiling `[a b c d]` by `[2]` produces
-- `[a b c d a b c d]`.
tile :: forall v1 v2 t tmultiples . (TensorType t, TensorType tmultiples,
                                     OneOf '[Data.Int.Int32,
                                             Data.Int.Int64] tmultiples) =>
        Tensor v1 t -- ^ __input__: 1-D or higher.
        -> Tensor v2 tmultiples -- ^ __multiples__: 1-D. Length must be the same as the number of dimensions in `input`
        -> Tensor Value t -- ^ __output__
tile input multiples | eqLengthGuard [] =
    buildOp (opDef "Tile"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tmultiples" .~ tensorType (undefined :: tmultiples))
        input multiples
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tmultiples"
  type: "type"
}
input_arg {
  description: "1-D or higher." name: "input" type_attr: "T"
}
input_arg {
  description: "1-D. Length must be the same as the number of dimensions in `input`"
  name: "multiples"
  type_attr: "Tmultiples"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Return a strided slice from `input`.
--
-- Note, most python users will want to use the Python `Tensor.__getitem__`
-- or `Variable.__getitem__` rather than this op directly.
-- 
-- The goal of this op is to produce a new tensor with a subset of
-- the elements from the `n` dimensional `input` tensor. The subset is chosen using
-- a sequence of `m` sparse range specifications encoded into the arguments
-- of this function. Note, in some cases
-- `m` could be equal to `n`, but this need not be the case. Each
-- range specification entry can be one of the following:
-- 
-- - An ellipsis (...). Ellipses are used to imply zero or more
--   dimensions of full-dimension selection and are produced using
--   `ellipsis_mask`. For example, `foo[...]` is the identity slice.
-- 
-- - A new axis. This is used to insert a new shape=1 dimension and is
--   produced using `new_axis_mask`. For example, `foo[:, ...]` where
--   `foo` is shape `(3, 4)` produces a `(1, 3, 4)` tensor.
-- 
-- 
-- - A range `begin:end:stride`. This is used to specify how much to choose from
--   a given dimension. `stride` can be any integer but 0.  `begin` is an integer
--   which represents the index of the first value to select while `end` represents
--   the index of the last value to select. The number of values selected in each
--   dimension is `end - begin` if `stride > 0` and `begin - end` if `stride < 0`.
--   `begin` and `end` can be negative where `-1` is the last element, `-2` is
--   the second to last. `begin_mask` controls whether to replace the explicitly
--   given `begin` with an implicit effective value of `0` if `stride > 0` and
--   `-1` if `stride < 0`. `end_mask` is analogous but produces the number
--   required to create the largest open interval. For example, given a shape
--   `(3,)` tensor `foo[:]`, the effective `begin` and `end` are `0` and `3`. Do
--   not assume this is equivalent to `foo[0:-1]` which has an effective `begin`
--   and `end` of `0` and `2`. Another example is `foo[-2::-1]` which reverses the
--   first dimension of a tensor while dropping the last two (in the original
--   order elements). For example `foo = [1,2,3,4]; foo[-2::-1]` is `[4,3]`.
-- 
-- - A single index. This is used to keep only elements that have a given
--   index. For example (`foo[2, :]` on a shape `(5,6)` tensor produces a
--   shape `(6,)` tensor. This is encoded in `begin` and `end` and
--   `shrink_axis_mask`.
-- 
-- Each conceptual range specification is encoded in the op's argument. This
-- encoding is best understand by considering a non-trivial example. In
-- particular,
-- `foo[1, 2:4, None, ..., :-3:-1, :]` will be encoded as
-- 
-- ```prettyprint
-- begin = [1, 2, x, x, 0, x] # x denotes don't care (usually 0)
-- end = [2, 4, x, x, -3, x]
-- strides = [1, 1, x, x, -1, 1]
-- begin_mask = 1<<4 | 1 << 5 = 48
-- end_mask = 1<<5 = 32
-- ellipsis_mask = 1<<3 = 8
-- new_axis_mask = 1<<2 4
-- shrink_axis_mask = 1<<0
-- ```
-- 
-- In this case if `foo.shape` is (5, 5, 5, 5, 5, 5) the final shape of
-- the slice becomes (2, 1, 5, 5, 2, 5).
-- Let us walk step by step through each argument specification.
-- 
-- 1.  The first argument in the example slice is turned into `begin = 1` and
-- `end = begin + 1 = 2`. To disambiguate from the original spec `2:4` we
-- also set the appropriate bit in `shrink_axis_mask`.
-- 
-- 2. `2:4` is contributes 2, 4, 1 to begin, end, and stride. All masks have
-- zero bits contributed.
-- 
-- 3. None is a synonym for `tf.newaxis`. This means insert a dimension of size 1
-- dimension in the final shape. Dummy values are contributed to begin,
-- end and stride, while the new_axis_mask bit is set.
-- 
-- 4. `...` grab the full ranges from as many dimensions as needed to
-- fully specify a slice for every dimension of the input shape.
-- 
-- 5. `:-3:-1` shows the use of negative indices. A negative index `i` associated
-- with a dimension that has shape `s` is converted to a positive index
-- `s + i`. So `-1` becomes `s-1` (i.e. the last element). This conversion
-- is done internally so begin, end and strides receive x, -3, and -1.
-- The appropriate begin_mask bit is set to indicate the start range is the
-- full range (ignoring the x).
-- 
-- 6. `:` indicates that the entire contents of the corresponding dimension
-- is selected. This is equivalent to `::` or `0::1`. begin, end, and strides
-- receive 0, 0, and 1, respectively. The appropriate bits in `begin_mask` and
-- `end_mask` are also set.
-- 
-- *Requirements*:
--   `0 != strides[i] for i in [0, m)`
--   `ellipsis_mask must be a power of two (only one ellipsis)`
stridedSlice :: forall v1 v2 v3 v4 t index . (TensorType t, TensorType index,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] index) =>
                Tensor v1 t -- ^ __input__
                -> Tensor v2 index -- ^ __begin__: `begin[k]` specifies the offset into the `k`th range specification.
                                   -- The exact dimension this corresponds to will be determined by context.
                                   -- Out-of-bounds values will be silently clamped. If the `k`th bit of
                                   -- `begin_mask` then `begin[k]` is ignored and the full range of the
                                   -- appropriate dimension is used instead. Negative values causes indexing
                                   -- to start from the highest element e.g. If `foo==[1,2,3]` then `foo[-1]==3`.
                -> Tensor v3 index -- ^ __end__: `end[i]` is like `begin` with the exception that `end_mask` is
                                   -- used to determine full ranges.
                -> Tensor v4 index -- ^ __strides__: `strides[i]` specifies the increment in the `i`th specification
                                   -- after extracting a given element. Negative indices will reverse
                                   -- the original order. Out or range values are
                                   -- clamped to `[0,dim[i]) if slice[i]>0` or `[-1,dim[i]-1] if slice[i] < 0`
                -> Tensor Value t -- ^ __output__
stridedSlice input begin end strides | eqLengthGuard [] =
    buildOp (opDef "StridedSlice"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Index" .~ tensorType (undefined :: index))
        input begin end strides
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Index"
  type: "type"
}
attr {
  default_value { i: 0 }
  description: "a bitmask where a bit i being 1 means to ignore the begin\nvalue and instead use the largest interval possible. At runtime\nbegin[i] will be replaced with `[0, n-1) if `stride[i] > 0` or\n`[-1, n-1]` if `stride[i] < 0`"
  name: "begin_mask"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "analogous to `begin_mask`"
  name: "end_mask"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "a bitmask where bit `i` being 1 means the `i`th\nposition is actually an ellipsis. One bit at most can be 1.\nIf `ellipsis_mask == 0`, then an implicit ellipsis mask of `1 << (m+1)`\nis provided. This means that `foo[3:5] == foo[3:5, ...]`. An ellipsis\nimplicitly creates as many range specifications as necessary to fully\nspecify the sliced range for every dimension. For example for a 4-dimensional\ntensor `foo` the slice `foo[2, ..., 5:8]` implies `foo[2, :, :, 5:8]`."
  name: "ellipsis_mask"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "a bitmask where bit `i` being 1 means the `i`th\nspecification creates a new shape 1 dimension. For example\n`foo[:4, tf.newaxis, :2]` would produce a shape `(4, 1, 2)` tensor."
  name: "new_axis_mask"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "a bitmask where bit `i` implies that the `i`th\nspecification should shrink the dimensionality. begin and end\nmust imply a slice of size 1 in the dimension. For example in\npython one might do `foo[:, 3, :]` which would result in\n`shrink_axis_mask` being 2."
  name: "shrink_axis_mask"
  type: "int"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "`begin[k]` specifies the offset into the `k`th range specification.\nThe exact dimension this corresponds to will be determined by context.\nOut-of-bounds values will be silently clamped. If the `k`th bit of\n`begin_mask` then `begin[k]` is ignored and the full range of the\nappropriate dimension is used instead. Negative values causes indexing\nto start from the highest element e.g. If `foo==[1,2,3]` then `foo[-1]==3`."
  name: "begin"
  type_attr: "Index"
}
input_arg {
  description: "`end[i]` is like `begin` with the exception that `end_mask` is\nused to determine full ranges."
  name: "end"
  type_attr: "Index"
}
input_arg {
  description: "`strides[i]` specifies the increment in the `i`th specification\nafter extracting a given element. Negative indices will reverse\nthe original order. Out or range values are\nclamped to `[0,dim[i]) if slice[i]>0` or `[-1,dim[i]-1] if slice[i] < 0`"
  name: "strides"
  type_attr: "Index"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Return a slice from 'input'.
--
-- The output tensor is a tensor with dimensions described by 'size'
-- whose values are extracted from 'input' starting at the offsets in
-- 'begin'.
-- 
-- *Requirements*:
--   0 <= begin[i] <= begin[i] + size[i] <= Di  for i in [0, n)
slice :: forall v1 v2 v3 t index . (TensorType t, TensorType index,
                                    OneOf '[Data.Int.Int32,
                                            Data.Int.Int64] index) =>
         Tensor v1 t -- ^ __input__
         -> Tensor v2 index -- ^ __begin__: begin[i] specifies the offset into the 'i'th dimension of
                            -- 'input' to slice from.
         -> Tensor v3 index -- ^ __size__: size[i] specifies the number of elements of the 'i'th dimension
                            -- of 'input' to slice. If size[i] is -1, all remaining elements in dimension
                            -- i are included in the slice (i.e. this is equivalent to setting
                            -- size[i] = input.dim_size(i) - begin[i]).
         -> Tensor Value t -- ^ __output__
slice input begin size | eqLengthGuard [] =
    buildOp (opDef "Slice"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Index" .~ tensorType (undefined :: index))
        input begin size
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Index"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "begin[i] specifies the offset into the \'i\'th dimension of\n\'input\' to slice from."
  name: "begin"
  type_attr: "Index"
}
input_arg {
  description: "size[i] specifies the number of elements of the \'i\'th dimension\nof \'input\' to slice. If size[i] is -1, all remaining elements in dimension\ni are included in the slice (i.e. this is equivalent to setting\nsize[i] = input.dim_size(i) - begin[i])."
  name: "size"
  type_attr: "Index"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes a 2D convolution given quantized 4D input and filter tensors.
--
-- The inputs are quantized tensors where the lowest value represents the real
-- number of the associated minimum, and the highest represents the maximum.
-- This means that you can only interpret the quantized output in the same way, by
-- taking the returned minimum and maximum values into account.
quantizedConv2D :: forall v1 v2 v3 v4 v5 v6 tinput tfilter
                   out_type . (TensorType tinput, OneOf '[Data.Int.Int16,
                                                          Data.Int.Int32,
                                                          Data.Word.Word16,
                                                          Data.Word.Word8] tinput,
                               TensorType tfilter, OneOf '[Data.Int.Int16,
                                                           Data.Int.Int32,
                                                           Data.Word.Word16,
                                                           Data.Word.Word8] tfilter,
                               TensorType out_type, OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8] out_type) =>
                   Tensor v1 tinput -- ^ __input__
                   -> Tensor v2 tfilter -- ^ __filter__: filter's input_depth dimension must match input's depth dimensions.
                   -> Tensor v3 Float -- ^ __min_input__: The float value that the lowest quantized input value represents.
                   -> Tensor v4 Float -- ^ __max_input__: The float value that the highest quantized input value represents.
                   -> Tensor v5 Float -- ^ __min_filter__: The float value that the lowest quantized filter value represents.
                   -> Tensor v6 Float -- ^ __max_filter__: The float value that the highest quantized filter value represents.
                   -> (Tensor Value out_type, Tensor Value Float,
                       Tensor Value Float)
                   -- ^ (__output__, __min_output__, __max_output__)
                   --
                   -- * __output__
                   --
                   -- * __min_output__: The float value that the lowest quantized output value represents.
                   --
                   -- * __max_output__: The float value that the highest quantized output value represents.
quantizedConv2D input filter min_input max_input min_filter
                max_filter | eqLengthGuard [] =
    buildOp (opDef "QuantizedConv2D"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "Tfilter" .~ tensorType (undefined :: tfilter)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input filter min_input max_input min_filter max_filter
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tfilter"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  default_value { type: DT_QINT32 }
  name: "out_type"
  type: "type"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\ntensor."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg { name: "input" type_attr: "Tinput" }
input_arg {
  description: "filter\'s input_depth dimension must match input\'s depth dimensions."
  name: "filter"
  type_attr: "Tfilter"
}
input_arg {
  description: "The float value that the lowest quantized input value represents."
  name: "min_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized input value represents."
  name: "max_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the lowest quantized filter value represents."
  name: "min_filter"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized filter value represents."
  name: "max_filter"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "out_type" }
output_arg {
  description: "The float value that the lowest quantized output value represents."
  name: "min_output"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized output value represents."
  name: "max_output"
  type: DT_FLOAT
}
-}

-- | Computes rectified linear 6 gradients for a Relu6 operation.

relu6Grad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                     Data.Int.Int32,
                                                     Data.Int.Int64,
                                                     Data.Int.Int8,
                                                     Data.Word.Word16,
                                                     Data.Word.Word8, Double,
                                                     Float] t) =>
             Tensor v1 t -- ^ __gradients__: The backpropagated gradients to the corresponding Relu6 operation.
             -> Tensor v2 t -- ^ __features__: The features passed as input to the corresponding Relu6 operation.
             -> Tensor Value t -- ^ __backprops__: The gradients:
             -- `gradients * (features > 0) * (features < 6)`.
relu6Grad gradients features | eqLengthGuard [] =
    buildOp (opDef "Relu6Grad"
             & opAttr "T" .~ tensorType (undefined :: t))
        gradients features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "The backpropagated gradients to the corresponding Relu6 operation."
  name: "gradients"
  type_attr: "T"
}
input_arg {
  description: "The features passed as input to the corresponding Relu6 operation."
  name: "features"
  type_attr: "T"
}
output_arg {
  description: "The gradients:\n`gradients * (features > 0) * (features < 6)`."
  name: "backprops"
  type_attr: "T"
}
-}

-- | Computes gradients of the average pooling function.

avgPoolGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                       Float] t) =>
               Tensor v1 Data.Int.Int32 -- ^ __orig_input_shape__: 1-D.  Shape of the original input to `avg_pool`.
               -> Tensor v2 t -- ^ __grad__: 4-D with shape `[batch, height, width, channels]`.  Gradients w.r.t.
                              -- the output of `avg_pool`.
               -> Tensor Value t -- ^ __output__: 4-D.  Gradients w.r.t. the input of `avg_pool`.
avgPoolGrad orig_input_shape grad | eqLengthGuard [] =
    buildOp (opDef "AvgPoolGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        orig_input_shape grad
{-
attr {
  description: "The size of the sliding window for each dimension of the input."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the input."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
attr {
  allowed_values {
    list { type: DT_FLOAT type: DT_HALF type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D.  Shape of the original input to `avg_pool`."
  name: "orig_input_shape"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`.  Gradients w.r.t.\nthe output of `avg_pool`."
  name: "grad"
  type_attr: "T"
}
output_arg {
  description: "4-D.  Gradients w.r.t. the input of `avg_pool`."
  name: "output"
  type_attr: "T"
}
-}

-- | Split elements of `input` based on `delimiter` into a `SparseTensor`.
--
-- Let N be the size of source (typically N will be the batch size). Split each
-- element of `input` based on `delimiter` and return a `SparseTensor`
-- containing the splitted tokens. Empty tokens are ignored.
-- 
-- `delimiter` can be empty or a single-byte character. If `delimiter` is an empty
--  string, each element of `input` is split into individual single-byte character
--  strings, including splitting of UTF-8 multibyte sequences.
-- 
-- For example:
--   N = 2, input[0] is 'hello world' and input[1] is 'a b c', then the output
--   will be
-- 
--   indices = [0, 0;
--              0, 1;
--              1, 0;
--              1, 1;
--              1, 2]
--   shape = [2, 3]
--   values = ['hello', 'world', 'a', 'b', 'c']
stringSplit :: Tensor v1 Data.ByteString.ByteString -- ^ __input__: 1-D. Strings to split.
               -> Tensor v2 Data.ByteString.ByteString -- ^ __delimiter__: 0-D. Delimiter character, or empty string.
               -> (Tensor Value Data.Int.Int64,
                   Tensor Value Data.ByteString.ByteString,
                   Tensor Value Data.Int.Int64)
               -- ^ (__indices__, __values__, __shape__)
               --
               -- * __indices__: A dense matrix of int64 representing the indices of the sparse tensor.
               --
               -- * __values__: A vector of strings corresponding to the splited values.
               --
               -- * __shape__: a length-2 vector of int64 representing the shape of the sparse
               -- tensor, where the first value is N and the second value is the maximum number
               -- of tokens in a single input entry.
stringSplit input delimiter | eqLengthGuard [] =
    buildOp (opDef "StringSplit")
        input delimiter
{-
input_arg {
  description: "1-D. Strings to split." name: "input" type: DT_STRING
}
input_arg {
  description: "0-D. Delimiter character, or empty string."
  name: "delimiter"
  type: DT_STRING
}
output_arg {
  description: "A dense matrix of int64 representing the indices of the sparse tensor."
  name: "indices"
  type: DT_INT64
}
output_arg {
  description: "A vector of strings corresponding to the splited values."
  name: "values"
  type: DT_STRING
}
output_arg {
  description: "a length-2 vector of int64 representing the shape of the sparse\ntensor, where the first value is N and the second value is the maximum number\nof tokens in a single input entry."
  name: "shape"
  type: DT_INT64
}
-}

-- | Returns the rank of a tensor.
--
-- This operation returns an integer representing the rank of `input`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]
-- # shape of tensor 't' is [2, 2, 3]
-- rank(t) ==> 3
-- ```
-- 
-- **Note**: The rank of a tensor is not the same as the rank of a matrix. The rank
-- of a tensor is the number of indices required to uniquely select each element
-- of the tensor. Rank is also known as "order", "degree", or "ndims."
rank :: forall v1 t . (TensorType t) => Tensor v1 t -- ^ __input__
        -> Tensor Value Data.Int.Int32 -- ^ __output__
rank input | eqLengthGuard [] =
    buildOp (opDef "Rank"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type: DT_INT32 }
-}

-- | Computes the reciprocal of x element-wise.
--
-- I.e., \\(y = 1 / x\\).
reciprocal :: forall v1 t . (TensorType t,
                             OneOf '[(Data.Complex.Complex Double),
                                     (Data.Complex.Complex Float),
                                     Data.Int.Int32, Data.Int.Int64,
                                     Data.Word.Word16, Double, Float] t) =>
              Tensor v1 t -- ^ __x__
              -> Tensor Value t -- ^ __y__
reciprocal x | eqLengthGuard [] =
    buildOp (opDef "Reciprocal"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Reverses variable length slices.
--
-- This op first slices `input` along the dimension `batch_dim`, and for each
-- slice `i`, reverses the first `seq_lengths[i]` elements along
-- the dimension `seq_dim`.
-- 
-- The elements of `seq_lengths` must obey `seq_lengths[i] < input.dims[seq_dim]`,
-- and `seq_lengths` must be a vector of length `input.dims[batch_dim]`.
-- 
-- The output slice `i` along dimension `batch_dim` is then given by input
-- slice `i`, with the first `seq_lengths[i]` slices along dimension
-- `seq_dim` reversed.
-- 
-- For example:
-- 
-- ```prettyprint
-- # Given this:
-- batch_dim = 0
-- seq_dim = 1
-- input.dims = (4, 8, ...)
-- seq_lengths = [7, 2, 3, 5]
-- 
-- # then slices of input are reversed on seq_dim, but only up to seq_lengths:
-- output[0, 0:7, :, ...] = input[0, 7:0:-1, :, ...]
-- output[1, 0:2, :, ...] = input[1, 2:0:-1, :, ...]
-- output[2, 0:3, :, ...] = input[2, 3:0:-1, :, ...]
-- output[3, 0:5, :, ...] = input[3, 5:0:-1, :, ...]
-- 
-- # while entries past seq_lens are copied through:
-- output[0, 7:, :, ...] = input[0, 7:, :, ...]
-- output[1, 2:, :, ...] = input[1, 2:, :, ...]
-- output[2, 3:, :, ...] = input[2, 3:, :, ...]
-- output[3, 2:, :, ...] = input[3, 2:, :, ...]
-- ```
-- 
-- In contrast, if:
-- 
-- ```prettyprint
-- # Given this:
-- batch_dim = 2
-- seq_dim = 0
-- input.dims = (8, ?, 4, ...)
-- seq_lengths = [7, 2, 3, 5]
-- 
-- # then slices of input are reversed on seq_dim, but only up to seq_lengths:
-- output[0:7, :, 0, :, ...] = input[7:0:-1, :, 0, :, ...]
-- output[0:2, :, 1, :, ...] = input[2:0:-1, :, 1, :, ...]
-- output[0:3, :, 2, :, ...] = input[3:0:-1, :, 2, :, ...]
-- output[0:5, :, 3, :, ...] = input[5:0:-1, :, 3, :, ...]
-- 
-- # while entries past seq_lens are copied through:
-- output[7:, :, 0, :, ...] = input[7:, :, 0, :, ...]
-- output[2:, :, 1, :, ...] = input[2:, :, 1, :, ...]
-- output[3:, :, 2, :, ...] = input[3:, :, 2, :, ...]
-- output[2:, :, 3, :, ...] = input[2:, :, 3, :, ...]
-- ```
reverseSequence :: forall v1 v2 t tlen . (TensorType t, TensorType tlen,
                                          OneOf '[Data.Int.Int32,
                                                  Data.Int.Int64] tlen) =>
                   Data.Int.Int64 -- ^ __seq_dim__: The dimension which is partially reversed.
                   -> Tensor v1 t -- ^ __input__: The input to reverse.
                   -> Tensor v2 tlen -- ^ __seq_lengths__: 1-D with length `input.dims(batch_dim)` and
                                     -- `max(seq_lengths) < input.dims(seq_dim)`
                   -> Tensor Value t -- ^ __output__: The partially reversed input. It has the same shape as `input`.
reverseSequence seq_dim input seq_lengths | eqLengthGuard [] =
    buildOp (opDef "ReverseSequence"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tlen" .~ tensorType (undefined :: tlen)
             & opAttr "seq_dim" .~ seq_dim)
        input seq_lengths
{-
attr {
  description: "The dimension which is partially reversed."
  name: "seq_dim"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "The dimension along which reversal is performed."
  name: "batch_dim"
  type: "int"
}
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT64 }
  name: "Tlen"
  type: "type"
}
input_arg {
  description: "The input to reverse." name: "input" type_attr: "T"
}
input_arg {
  description: "1-D with length `input.dims(batch_dim)` and\n`max(seq_lengths) < input.dims(seq_dim)`"
  name: "seq_lengths"
  type_attr: "Tlen"
}
output_arg {
  description: "The partially reversed input. It has the same shape as `input`."
  name: "output"
  type_attr: "T"
}
-}

-- | The backward operation for "BiasAdd" on the "bias" tensor.
--
-- It accumulates all the values from out_backprop into the feature dimension.
-- For NHWC data format, the feature dimension is the last. For NCHW data format,
-- the feature dimension is the third-to-last.
biasAddGrad :: forall v1 t . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t) =>
               Tensor v1 t -- ^ __out_backprop__: Any number of dimensions.
               -> Tensor Value t -- ^ __output__: 1-D with size the feature dimension of `out_backprop`.
biasAddGrad out_backprop | eqLengthGuard [] =
    buildOp (opDef "BiasAddGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the bias tensor will be added to the last dimension\nof the value tensor.\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width].\nThe tensor will be added to \"in_channels\", the third-to-the-last\n    dimension."
  name: "data_format"
  type: "string"
}
input_arg {
  description: "Any number of dimensions."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "1-D with size the feature dimension of `out_backprop`."
  name: "output"
  type_attr: "T"
}
-}

-- | Add a `SparseTensor` to a `SparseTensorsMap` return its handle.
--
-- A `SparseTensor` is represented by three tensors: `sparse_indices`,
-- `sparse_values`, and `sparse_shape`.
-- 
-- This operator takes the given `SparseTensor` and adds it to a container
-- object (a `SparseTensorsMap`).  A unique key within this container is generated
-- in the form of an `int64`, and this is the value that is returned.
-- 
-- The `SparseTensor` can then be read out as part of a minibatch by passing
-- the key as a vector element to `TakeManySparseFromTensorsMap`.  To ensure
-- the correct `SparseTensorsMap` is accessed, ensure that the same
-- `container` and `shared_name` are passed to that Op.  If no `shared_name`
-- is provided here, instead use the *name* of the Operation created by calling
-- `AddSparseToTensorsMap` as the `shared_name` passed to
-- `TakeManySparseFromTensorsMap`.  Ensure the Operations are colocated.
addSparseToTensorsMap :: forall v1 v2 v3 t . (TensorType t) =>
                         Tensor v1 Data.Int.Int64 -- ^ __sparse_indices__: 2-D.  The `indices` of the `SparseTensor`.
                         -> Tensor v2 t -- ^ __sparse_values__: 1-D.  The `values` of the `SparseTensor`.
                         -> Tensor v3 Data.Int.Int64 -- ^ __sparse_shape__: 1-D.  The `shape` of the `SparseTensor`.
                         -> Build (Tensor Value Data.Int.Int64) -- ^ __sparse_handle__: 0-D.  The handle of the `SparseTensor` now stored in the
                         -- `SparseTensorsMap`.
addSparseToTensorsMap sparse_indices sparse_values
                      sparse_shape | eqLengthGuard [] =
    buildOp (opDef "AddSparseToTensorsMap"
             & opAttr "T" .~ tensorType (undefined :: t))
        sparse_indices sparse_values sparse_shape
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "The container name for the `SparseTensorsMap` created by this op."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "The shared name for the `SparseTensorsMap` created by this op.\nIf blank, the new Operation\'s unique name is used."
  name: "shared_name"
  type: "string"
}
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor`."
  name: "sparse_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the `SparseTensor`."
  name: "sparse_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the `SparseTensor`."
  name: "sparse_shape"
  type: DT_INT64
}
output_arg {
  description: "0-D.  The handle of the `SparseTensor` now stored in the\n`SparseTensorsMap`."
  name: "sparse_handle"
  type: DT_INT64
}
-}

-- | Computes tan of x element-wise.

tan :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Data.Int.Int32, Data.Int.Int64,
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
tan x | eqLengthGuard [] =
    buildOp (opDef "Tan"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes the sum of elements across dimensions of a SparseTensor.
--
-- This Op takes a SparseTensor and is the sparse counterpart to
-- `tf.reduce_sum()`.  In contrast to SparseReduceSum, this Op returns a
-- SparseTensor.
-- 
-- Reduces `sp_input` along the dimensions given in `reduction_axes`.  Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_axes`. If `keep_dims` is true, the reduced dimensions are retained
-- with length 1.
-- 
-- If `reduction_axes` has no entries, all dimensions are reduced, and a tensor
-- with a single element is returned.  Additionally, the axes can be negative,
-- which are interpreted according to the indexing rules in Python.
sparseReduceSumSparse :: forall v1 v2 v3 v4 t . (TensorType t,
                                                 OneOf '[(Data.Complex.Complex Double),
                                                         (Data.Complex.Complex Float),
                                                         Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Int.Int64,
                                                         Data.Int.Int8,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8,
                                                         Double, Float] t) =>
                         Tensor v1 Data.Int.Int64 -- ^ __input_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                  -- SparseTensor, possibly not in canonical ordering.
                         -> Tensor v2 t -- ^ __input_values__: 1-D.  `N` non-empty values corresponding to `input_indices`.
                         -> Tensor v3 Data.Int.Int64 -- ^ __input_shape__: 1-D.  Shape of the input SparseTensor.
                         -> Tensor v4 Data.Int.Int32 -- ^ __reduction_axes__: 1-D.  Length-`K` vector containing the reduction axes.
                         -> (Tensor Value Data.Int.Int64, Tensor Value t,
                             Tensor Value Data.Int.Int64)
                         -- ^ (__output_indices__, __output_values__, __output_shape__)
                         --
                         -- * __output_indices__
                         --
                         -- * __output_values__
                         --
                         -- * __output_shape__
sparseReduceSumSparse input_indices input_values input_shape
                      reduction_axes | eqLengthGuard [] =
    buildOp (opDef "SparseReduceSumSparse"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_indices input_values input_shape reduction_axes
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "input_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `input_indices`."
  name: "input_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "input_shape"
  type: DT_INT64
}
input_arg {
  description: "1-D.  Length-`K` vector containing the reduction axes."
  name: "reduction_axes"
  type: DT_INT32
}
output_arg { name: "output_indices" type: DT_INT64 }
output_arg { name: "output_values" type_attr: "T" }
output_arg { name: "output_shape" type: DT_INT64 }
-}

-- | Returns shape of tensors.
--
-- This operation returns N 1-D integer tensors representing shape of `input[i]s`.
shapeN :: forall v1 t out_type . (TensorType t, TensorType out_type,
                                  OneOf '[Data.Int.Int32,
                                          Data.Int.Int64] out_type) =>
          [Tensor v1 t] -- ^ __input__
          -> [Tensor Value out_type] -- ^ __output__
shapeN input | eqLengthGuard [("N", [("input", length input)])] =
    buildListOp [n] (opDef "ShapeN"
                     & opAttr "T" .~ tensorType (undefined :: t)
                     & opAttr "out_type" .~ tensorType (undefined :: out_type)
                     & opAttr "N" .~ n)
        input
  where
    n = fromIntegral (length input) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_type"
  type: "type"
}
input_arg { name: "input" number_attr: "N" type_attr: "T" }
output_arg {
  name: "output" number_attr: "N" type_attr: "out_type"
}
-}

-- | Returns the shape of a tensor.
--
-- This operation returns a 1-D integer tensor representing the shape of `input`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]
-- shape(t) ==> [2, 2, 3]
-- ```
shape :: forall v1 t out_type . (TensorType t, TensorType out_type,
                                 OneOf '[Data.Int.Int32,
                                         Data.Int.Int64] out_type) =>
         Tensor v1 t -- ^ __input__
         -> Tensor Value out_type -- ^ __output__
shape input | eqLengthGuard [] =
    buildOp (opDef "Shape"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_type"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "out_type" }
-}

-- | Finds unique elements in a 1-D tensor.
--
-- This operation returns a tensor `y` containing all of the unique elements of `x`
-- sorted in the same order that they occur in `x`. This operation also returns a
-- tensor `idx` the same size as `x` that contains the index of each value of `x`
-- in the unique output `y`. In other words:
-- 
-- `y[idx[i]] = x[i] for i in [0, 1,...,rank(x) - 1]`
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor 'x' is [1, 1, 2, 4, 4, 4, 7, 8, 8]
-- y, idx = unique(x)
-- y ==> [1, 2, 4, 7, 8]
-- idx ==> [0, 0, 1, 2, 2, 2, 3, 4, 4]
-- ```
unique :: forall v1 t out_idx . (TensorType t, TensorType out_idx,
                                 OneOf '[Data.Int.Int32,
                                         Data.Int.Int64] out_idx) =>
          Tensor v1 t -- ^ __x__: 1-D.
          -> (Tensor Value t, Tensor Value out_idx) -- ^ (__y__, __idx__)
          --
          -- * __y__: 1-D.
          --
          -- * __idx__: 1-D.
unique x | eqLengthGuard [] =
    buildOp (opDef "Unique"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "out_idx" .~ tensorType (undefined :: out_idx))
        x
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_idx"
  type: "type"
}
input_arg { description: "1-D." name: "x" type_attr: "T" }
output_arg { description: "1-D." name: "y" type_attr: "T" }
output_arg { description: "1-D." name: "idx" type_attr: "out_idx" }
-}

-- | Outputs random values from a truncated normal distribution.
--
-- The generated values follow a normal distribution with mean 0 and standard
-- deviation 1, except that values whose magnitude is more than 2 standard
-- deviations from the mean are dropped and re-picked.
truncatedNormal :: forall v1 dtype t . (TensorType dtype,
                                        OneOf '[Data.Word.Word16, Double,
                                                Float] dtype, TensorType t,
                                        OneOf '[Data.Int.Int32,
                                                Data.Int.Int64] t) =>
                   Tensor v1 t -- ^ __shape__: The shape of the output tensor.
                   -> Build (Tensor Value dtype) -- ^ __output__: A tensor of the specified shape filled with random truncated normal
                   -- values.
truncatedNormal shape | eqLengthGuard [] =
    buildOp (opDef "TruncatedNormal"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  description: "The type of the output."
  name: "dtype"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "The shape of the output tensor."
  name: "shape"
  type_attr: "T"
}
output_arg {
  description: "A tensor of the specified shape filled with random truncated normal\nvalues."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Computes the inverse permutation of a tensor.
--
-- This operation computes the inverse of an index permutation. It takes a 1-D
-- integer tensor `x`, which represents the indices of a zero-based array, and
-- swaps each value with its index position. In other words, for an output tensor
-- `y` and an input tensor `x`, this operation computes the following:
-- 
-- `y[x[i]] = i for i in [0, 1, ..., len(x) - 1]`
-- 
-- The values must include 0. There can be no duplicate values or negative values.
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor `x` is [3, 4, 0, 2, 1]
-- invert_permutation(x) ==> [2, 4, 3, 0, 1]
-- ```
invertPermutation :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64] t) =>
                     Tensor v1 t -- ^ __x__: 1-D.
                     -> Tensor Value t -- ^ __y__: 1-D.
invertPermutation x | eqLengthGuard [] =
    buildOp (opDef "InvertPermutation"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "T"
  type: "type"
}
input_arg { description: "1-D." name: "x" type_attr: "T" }
output_arg { description: "1-D." name: "y" type_attr: "T" }
-}

-- | Checks a tensor for NaN and Inf values.
--
-- When run, reports an `InvalidArgument` error if `tensor` has any values
-- that are not a number (NaN) or infinity (Inf). Otherwise, passes `tensor` as-is.
checkNumerics :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                      Float] t) =>
                 Tensor v1 t -- ^ __tensor__
                 -> Tensor Value t -- ^ __output__
checkNumerics tensor | eqLengthGuard [] =
    buildOp (opDef "CheckNumerics"
             & opAttr "T" .~ tensorType (undefined :: t))
        tensor
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  description: "Prefix of the error message."
  name: "message"
  type: "string"
}
input_arg { name: "tensor" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Generates labels for candidate sampling with a uniform distribution.
--
-- See explanations of candidate sampling and the data formats at
-- go/candidate-sampling.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
uniformCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to randomly sample per batch.
                           -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                           -> Data.Int.Int64 -- ^ __range_max__: The sampler will sample integers from the interval [0, range_max).
                           -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                                   -- candidates in a batch are unique. This requires some approximation to
                                   -- estimate the post-rejection sampling probabilities.
                           -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                       -- IDs of the num_true target_classes in the corresponding original label.
                           -> (Tensor Value Data.Int.Int64, Tensor Value Float,
                               Tensor Value Float)
                           -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                           --
                           -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                           -- the ID of a sampled candidate.
                           --
                           -- * __true_expected_count__: A batch_size * num_true matrix, representing
                           -- the number of times each candidate is expected to occur in a batch
                           -- of sampled candidates. If unique=true, then this is a probability.
                           --
                           -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                           -- candidate representing the number of times the candidate is expected
                           -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                           -- probability.
uniformCandidateSampler num_sampled num_true range_max unique
                        true_classes | eqLengthGuard [] =
    buildOp (opDef "UniformCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "range_max" .~ range_max
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to randomly sample per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  description: "The sampler will sample integers from the interval [0, range_max)."
  has_minimum: true
  minimum: 1
  name: "range_max"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Gather slices from `params` according to `indices`.
--
-- `indices` must be an integer tensor of any dimension (usually 0-D or 1-D).
-- Produces an output tensor with shape `indices.shape + params.shape[1:]` where:
-- 
-- ```python
--     # Scalar indices
--     output[:, ..., :] = params[indices, :, ... :]
-- 
--     # Vector indices
--     output[i, :, ..., :] = params[indices[i], :, ... :]
-- 
--     # Higher rank indices
--     output[i, ..., j, :, ... :] = params[indices[i, ..., j], :, ..., :]
-- ```
-- 
-- If `indices` is a permutation and `len(indices) == params.shape[0]` then
-- this operation will permute `params` accordingly.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/Gather.png" alt>
-- </div>
gather :: forall v1 v2 tparams tindices . (TensorType tparams,
                                           TensorType tindices,
                                           OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64] tindices) =>
          Tensor v1 tparams -- ^ __params__
          -> Tensor v2 tindices -- ^ __indices__
          -> Tensor Value tparams -- ^ __output__
gather params indices | eqLengthGuard [] =
    buildOp (opDef "Gather"
             & opAttr "Tparams" .~ tensorType (undefined :: tparams)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        params indices
{-
attr {
  default_value { b: true } name: "validate_indices" type: "bool"
}
attr { name: "Tparams" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "params" type_attr: "Tparams" }
input_arg { name: "indices" type_attr: "Tindices" }
output_arg { name: "output" type_attr: "Tparams" }
-}

-- | Returns a constant tensor.

const :: forall dtype . (TensorType dtype) => Tensor Value dtype -- ^ __output__
const  | eqLengthGuard [] =
    buildOp (opDef "Const"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        
{-
attr {
  description: "Attr `value` is the tensor to return."
  name: "value"
  type: "tensor"
}
attr { name: "dtype" type: "type" }
output_arg { name: "output" type_attr: "dtype" }
-}

-- | Creates a tensor filled with a scalar value.
--
-- This operation creates a tensor of shape `dims` and fills it with `value`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # Output tensor has shape [2, 3].
-- fill([2, 3], 9) ==> [[9, 9, 9]
--                      [9, 9, 9]]
-- ```
fill :: forall v1 v2 t . (TensorType t) =>
        Tensor v1 Data.Int.Int32 -- ^ __dims__: 1-D. Represents the shape of the output tensor.
        -> Tensor v2 t -- ^ __value__: 0-D (scalar). Value to fill the returned tensor.
                       -- 
                       -- @compatibility(numpy)
                       -- Equivalent to np.full
                       -- @end_compatibility
        -> Tensor Value t -- ^ __output__
fill dims value | eqLengthGuard [] =
    buildOp (opDef "Fill"
             & opAttr "T" .~ tensorType (undefined :: t))
        dims value
{-
attr { name: "T" type: "type" }
input_arg {
  description: "1-D. Represents the shape of the output tensor."
  name: "dims"
  type: DT_INT32
}
input_arg {
  description: "0-D (scalar). Value to fill the returned tensor.\n\n@compatibility(numpy)\nEquivalent to np.full\n@end_compatibility"
  name: "value"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the (possibly normalized) Levenshtein Edit Distance.
--
-- The inputs are variable-length sequences provided by SparseTensors
--   (hypothesis_indices, hypothesis_values, hypothesis_shape)
-- and
--   (truth_indices, truth_values, truth_shape).
-- 
-- The inputs are:
editDistance :: forall v1 v2 v3 v4 v5 v6 t . (TensorType t) =>
                Tensor v1 Data.Int.Int64 -- ^ __hypothesis_indices__: The indices of the hypothesis list SparseTensor.
                                         -- This is an N x R int64 matrix.
                -> Tensor v2 t -- ^ __hypothesis_values__: The values of the hypothesis list SparseTensor.
                               -- This is an N-length vector.
                -> Tensor v3 Data.Int.Int64 -- ^ __hypothesis_shape__: The shape of the hypothesis list SparseTensor.
                                            -- This is an R-length vector.
                -> Tensor v4 Data.Int.Int64 -- ^ __truth_indices__: The indices of the truth list SparseTensor.
                                            -- This is an M x R int64 matrix.
                -> Tensor v5 t -- ^ __truth_values__: The values of the truth list SparseTensor.
                               -- This is an M-length vector.
                -> Tensor v6 Data.Int.Int64 -- ^ __truth_shape__: truth indices, vector.
                -> Tensor Value Float -- ^ __output__: A dense float tensor with rank R - 1.
                -- 
                -- For the example input:
                -- 
                --     // hypothesis represents a 2x1 matrix with variable-length values:
                --     //   (0,0) = ["a"]
                --     //   (1,0) = ["b"]
                --     hypothesis_indices = [[0, 0, 0],
                --                           [1, 0, 0]]
                --     hypothesis_values = ["a", "b"]
                --     hypothesis_shape = [2, 1, 1]
                -- 
                --     // truth represents a 2x2 matrix with variable-length values:
                --     //   (0,0) = []
                --     //   (0,1) = ["a"]
                --     //   (1,0) = ["b", "c"]
                --     //   (1,1) = ["a"]
                --     truth_indices = [[0, 1, 0],
                --                      [1, 0, 0],
                --                      [1, 0, 1],
                --                      [1, 1, 0]]
                --     truth_values = ["a", "b", "c", "a"]
                --     truth_shape = [2, 2, 2]
                --     normalize = true
                -- 
                -- The output will be:
                -- 
                --     // output is a 2x2 matrix with edit distances normalized by truth lengths.
                --     output = [[inf, 1.0],  // (0,0): no truth, (0,1): no hypothesis
                --               [0.5, 1.0]]  // (1,0): addition, (1,1): no hypothesis
editDistance hypothesis_indices hypothesis_values hypothesis_shape truth_indices
             truth_values truth_shape | eqLengthGuard [] =
    buildOp (opDef "EditDistance"
             & opAttr "T" .~ tensorType (undefined :: t))
        hypothesis_indices hypothesis_values hypothesis_shape truth_indices
        truth_values truth_shape
{-
attr {
  default_value { b: true }
  description: "boolean (if true, edit distances are normalized by length of truth).\n\nThe output is:"
  name: "normalize"
  type: "bool"
}
attr { name: "T" type: "type" }
input_arg {
  description: "The indices of the hypothesis list SparseTensor.\nThis is an N x R int64 matrix."
  name: "hypothesis_indices"
  type: DT_INT64
}
input_arg {
  description: "The values of the hypothesis list SparseTensor.\nThis is an N-length vector."
  name: "hypothesis_values"
  type_attr: "T"
}
input_arg {
  description: "The shape of the hypothesis list SparseTensor.\nThis is an R-length vector."
  name: "hypothesis_shape"
  type: DT_INT64
}
input_arg {
  description: "The indices of the truth list SparseTensor.\nThis is an M x R int64 matrix."
  name: "truth_indices"
  type: DT_INT64
}
input_arg {
  description: "The values of the truth list SparseTensor.\nThis is an M-length vector."
  name: "truth_values"
  type_attr: "T"
}
input_arg {
  description: "truth indices, vector."
  name: "truth_shape"
  type: DT_INT64
}
output_arg {
  description: "A dense float tensor with rank R - 1.\n\nFor the example input:\n\n    // hypothesis represents a 2x1 matrix with variable-length values:\n    //   (0,0) = [\"a\"]\n    //   (1,0) = [\"b\"]\n    hypothesis_indices = [[0, 0, 0],\n                          [1, 0, 0]]\n    hypothesis_values = [\"a\", \"b\"]\n    hypothesis_shape = [2, 1, 1]\n\n    // truth represents a 2x2 matrix with variable-length values:\n    //   (0,0) = []\n    //   (0,1) = [\"a\"]\n    //   (1,0) = [\"b\", \"c\"]\n    //   (1,1) = [\"a\"]\n    truth_indices = [[0, 1, 0],\n                     [1, 0, 0],\n                     [1, 0, 1],\n                     [1, 1, 0]]\n    truth_values = [\"a\", \"b\", \"c\", \"a\"]\n    truth_shape = [2, 2, 2]\n    normalize = true\n\nThe output will be:\n\n    // output is a 2x2 matrix with edit distances normalized by truth lengths.\n    output = [[inf, 1.0],  // (0,0): no truth, (0,1): no hypothesis\n              [0.5, 1.0]]  // (1,0): addition, (1,1): no hypothesis"
  name: "output"
  type: DT_FLOAT
}
-}

-- | Reverses specific dimensions of a tensor.
--
-- Given a `tensor`, and a `bool` tensor `dims` representing the dimensions
-- of `tensor`, this operation reverses each dimension i of `tensor` where
-- `dims[i]` is `True`.
-- 
-- `tensor` can have up to 8 dimensions. The number of dimensions
-- of `tensor` must equal the number of elements in `dims`. In other words:
-- 
-- `rank(tensor) = size(dims)`
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor 't' is [[[[ 0,  1,  2,  3],
-- #                  [ 4,  5,  6,  7],
-- #                  [ 8,  9, 10, 11]],
-- #                 [[12, 13, 14, 15],
-- #                  [16, 17, 18, 19],
-- #                  [20, 21, 22, 23]]]]
-- # tensor 't' shape is [1, 2, 3, 4]
-- 
-- # 'dims' is [False, False, False, True]
-- reverse(t, dims) ==> [[[[ 3,  2,  1,  0],
--                         [ 7,  6,  5,  4],
--                         [ 11, 10, 9, 8]],
--                        [[15, 14, 13, 12],
--                         [19, 18, 17, 16],
--                         [23, 22, 21, 20]]]]
-- 
-- # 'dims' is [False, True, False, False]
-- reverse(t, dims) ==> [[[[12, 13, 14, 15],
--                         [16, 17, 18, 19],
--                         [20, 21, 22, 23]
--                        [[ 0,  1,  2,  3],
--                         [ 4,  5,  6,  7],
--                         [ 8,  9, 10, 11]]]]
-- 
-- # 'dims' is [False, False, True, False]
-- reverse(t, dims) ==> [[[[8, 9, 10, 11],
--                         [4, 5, 6, 7],
--                         [0, 1, 2, 3]]
--                        [[20, 21, 22, 23],
--                         [16, 17, 18, 19],
--                         [12, 13, 14, 15]]]]
-- ```
reverse :: forall v1 v2 t . (TensorType t,
                             OneOf '[(Data.Complex.Complex Double),
                                     (Data.Complex.Complex Float), Bool,
                                     Data.Int.Int32, Data.Int.Int64,
                                     Data.Int.Int8, Data.Word.Word16,
                                     Data.Word.Word8, Double, Float] t) =>
           Tensor v1 t -- ^ __tensor__: Up to 8-D.
           -> Tensor v2 Bool -- ^ __dims__: 1-D. The dimensions to reverse.
           -> Tensor Value t -- ^ __output__: The same shape as `tensor`.
reverse tensor dims | eqLengthGuard [] =
    buildOp (opDef "Reverse"
             & opAttr "T" .~ tensorType (undefined :: t))
        tensor dims
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT32
      type: DT_INT64
      type: DT_BOOL
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Up to 8-D." name: "tensor" type_attr: "T"
}
input_arg {
  description: "1-D. The dimensions to reverse."
  name: "dims"
  type: DT_BOOL
}
output_arg {
  description: "The same shape as `tensor`."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns a batched matrix tensor with new batched diagonal values.
--
-- Given `input` and `diagonal`, this operation returns a tensor with the
-- same shape and values as `input`, except for the main diagonal of the
-- innermost matrices.  These will be overwritten by the values in `diagonal`.
-- 
-- The output is computed as follows:
-- 
-- Assume `input` has `k+1` dimensions `[I, J, K, ..., M, N]` and `diagonal` has
-- `k` dimensions `[I, J, K, ..., min(M, N)]`.  Then the output is a
-- tensor of rank `k+1` with dimensions `[I, J, K, ..., M, N]` where:
-- 
--   * `output[i, j, k, ..., m, n] = diagonal[i, j, k, ..., n]` for `m == n`.
--   * `output[i, j, k, ..., m, n] = input[i, j, k, ..., m, n]` for `m != n`.
matrixSetDiag :: forall v1 v2 t . (TensorType t) =>
                 Tensor v1 t -- ^ __input__: Rank `k+1`, where `k >= 1`.
                 -> Tensor v2 t -- ^ __diagonal__: Rank `k`, where `k >= 1`.
                 -> Tensor Value t -- ^ __output__: Rank `k+1`, with `output.shape = input.shape`.
matrixSetDiag input diagonal | eqLengthGuard [] =
    buildOp (opDef "MatrixSetDiag"
             & opAttr "T" .~ tensorType (undefined :: t))
        input diagonal
{-
attr { name: "T" type: "type" }
input_arg {
  description: "Rank `k+1`, where `k >= 1`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "Rank `k`, where `k >= 1`."
  name: "diagonal"
  type_attr: "T"
}
output_arg {
  description: "Rank `k+1`, with `output.shape = input.shape`."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns a batched diagonal tensor with a given batched diagonal values.
--
-- Given a `diagonal`, this operation returns a tensor with the `diagonal` and
-- everything else padded with zeros. The diagonal is computed as follows:
-- 
-- Assume `diagonal` has `k` dimensions `[I, J, K, ..., N]`, then the output is a
-- tensor of rank `k+1` with dimensions [I, J, K, ..., N, N]` where:
-- 
-- `output[i, j, k, ..., m, n] = 1{m=n} * diagonal[i, j, k, ..., n]`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'diagonal' is [[1, 2, 3, 4], [5, 6, 7, 8]]
-- 
-- and diagonal.shape = (2, 4)
-- 
-- tf.matrix_diag(diagonal) ==> [[[1, 0, 0, 0]
--                                      [0, 2, 0, 0]
--                                      [0, 0, 3, 0]
--                                      [0, 0, 0, 4]],
--                                     [[5, 0, 0, 0]
--                                      [0, 6, 0, 0]
--                                      [0, 0, 7, 0]
--                                      [0, 0, 0, 8]]]
-- 
-- which has shape (2, 4, 4)
-- ```
matrixDiag :: forall v1 t . (TensorType t) =>
              Tensor v1 t -- ^ __diagonal__: Rank `k`, where `k >= 1`.
              -> Tensor Value t -- ^ __output__: Rank `k+1`, with `output.shape = diagonal.shape + [diagonal.shape[-1]]`.
matrixDiag diagonal | eqLengthGuard [] =
    buildOp (opDef "MatrixDiag"
             & opAttr "T" .~ tensorType (undefined :: t))
        diagonal
{-
attr { name: "T" type: "type" }
input_arg {
  description: "Rank `k`, where `k >= 1`."
  name: "diagonal"
  type_attr: "T"
}
output_arg {
  description: "Rank `k+1`, with `output.shape = diagonal.shape + [diagonal.shape[-1]]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns a diagonal tensor with a given diagonal values.
--
-- Given a `diagonal`, this operation returns a tensor with the `diagonal` and
-- everything else padded with zeros. The diagonal is computed as follows:
-- 
-- Assume `diagonal` has dimensions [D1,..., Dk], then the output is a tensor of
-- rank 2k with dimensions [D1,..., Dk, D1,..., Dk] where:
-- 
-- `output[i1,..., ik, i1,..., ik] = diagonal[i1, ..., ik]` and 0 everywhere else.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'diagonal' is [1, 2, 3, 4]
-- tf.diag(diagonal) ==> [[1, 0, 0, 0]
--                        [0, 2, 0, 0]
--                        [0, 0, 3, 0]
--                        [0, 0, 0, 4]]
-- ```
diag :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int32, Data.Int.Int64,
                                             Double, Float] t) =>
        Tensor v1 t -- ^ __diagonal__: Rank k tensor where k is at most 3.
        -> Tensor Value t -- ^ __output__
diag diagonal | eqLengthGuard [] =
    buildOp (opDef "Diag"
             & opAttr "T" .~ tensorType (undefined :: t))
        diagonal
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Rank k tensor where k is at most 3."
  name: "diagonal"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns immutable tensor from memory region.
--
-- The current implementation memmaps the tensor from a file.
immutableConst :: forall dtype . (TensorType dtype) =>
                  Shape -- ^ __shape__: Shape of the returned tensor.
                  -> Tensor Value dtype -- ^ __tensor__
immutableConst shape | eqLengthGuard [] =
    buildOp (opDef "ImmutableConst"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        
{-
attr {
  description: "Type of the returned tensor."
  name: "dtype"
  type: "type"
}
attr {
  description: "Shape of the returned tensor."
  name: "shape"
  type: "shape"
}
attr {
  description: "Name of readonly memory region used by the tensor, see\nNewReadOnlyMemoryRegionFromFile in tensorflow::Env."
  name: "memory_region_name"
  type: "string"
}
output_arg { name: "tensor" type_attr: "dtype" }
-}

-- | Concatenates tensors along one dimension.

concat :: forall v1 v2 t . (TensorType t) =>
          Tensor v1 Data.Int.Int32 -- ^ __concat_dim__: 0-D.  The dimension along which to concatenate.  Must be in the
                                   -- range [0, rank(values)).
          -> [Tensor v2 t] -- ^ __values__: The `N` Tensors to concatenate. Their ranks and types must match,
                           -- and their sizes must match in all dimensions except `concat_dim`.
          -> Tensor Value t -- ^ __output__: A `Tensor` with the concatenation of values stacked along the
          -- `concat_dim` dimension.  This tensor's shape matches that of `values` except
          -- in `concat_dim` where it has the sum of the sizes.
concat concat_dim values | eqLengthGuard [("N", [("values", length values)])] =
    buildOp (opDef "Concat"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        concat_dim values
  where
    n = fromIntegral (length values) :: Int64
{-
attr { has_minimum: true minimum: 2 name: "N" type: "int" }
attr { name: "T" type: "type" }
input_arg {
  description: "0-D.  The dimension along which to concatenate.  Must be in the\nrange [0, rank(values))."
  name: "concat_dim"
  type: DT_INT32
}
input_arg {
  description: "The `N` Tensors to concatenate. Their ranks and types must match,\nand their sizes must match in all dimensions except `concat_dim`."
  name: "values"
  number_attr: "N"
  type_attr: "T"
}
output_arg {
  description: "A `Tensor` with the concatenation of values stacked along the\n`concat_dim` dimension.  This tensor\'s shape matches that of `values` except\nin `concat_dim` where it has the sum of the sizes."
  name: "output"
  type_attr: "T"
}
-}

-- | Unpacks a given dimension of a rank-`R` tensor into `num` rank-`(R-1)` tensors.
--
-- Unpacks `num` tensors from `value` by chipping it along the `axis` dimension.
-- For example, given a tensor of shape `(A, B, C, D)`;
-- 
-- If `axis == 0` then the i'th tensor in `output` is the slice `value[i, :, :, :]`
--   and each tensor in `output` will have shape `(B, C, D)`. (Note that the
--   dimension unpacked along is gone, unlike `split`).
-- 
-- If `axis == 1` then the i'th tensor in `output` is the slice `value[:, i, :, :]`
--   and each tensor in `output` will have shape `(A, C, D)`.
-- Etc.
-- 
-- This is the opposite of `pack`.
unpack :: forall v1 t . (TensorType t) => Data.Int.Int64 -- ^ __num__
          -> Tensor v1 t -- ^ __value__: 1-D or higher, with `axis` dimension size equal to `num`.
          -> [Tensor Value t] -- ^ __output__: The list of tensors unpacked from `value`.
unpack num value | eqLengthGuard [] =
    buildListOp [num] (opDef "Unpack"
                       & opAttr "T" .~ tensorType (undefined :: t)
                       & opAttr "num" .~ num)
        value
{-
attr { has_minimum: true name: "num" type: "int" }
attr { name: "T" type: "type" }
attr {
  default_value { i: 0 }
  description: "Dimension along which to unpack.  Negative values wrap around, so the\nvalid range is `[-R, R)`."
  name: "axis"
  type: "int"
}
input_arg {
  description: "1-D or higher, with `axis` dimension size equal to `num`."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "The list of tensors unpacked from `value`."
  name: "output"
  number_attr: "num"
  type_attr: "T"
}
-}

-- | Output a fact about factorials.

fact :: Tensor Value Data.ByteString.ByteString -- ^ __fact__
fact  | eqLengthGuard [] =
    buildOp (opDef "Fact")
        
{-
output_arg { name: "fact" type: DT_STRING }
-}

-- | Computes the absolute value of a tensor.
--
-- Given a tensor `x`, this operation returns a tensor containing the absolute
-- value of each element in `x`. For example, if x is an input element and y is
-- an output element, this operation computes \\(y = |x|\\).
abs :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int32, Data.Int.Int64,
                                            Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
abs x | eqLengthGuard [] =
    buildOp (opDef "Abs"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Computes softmax activations.
--
-- For each batch `i` and class `j` we have
-- 
--     softmax[i, j] = exp(logits[i, j]) / sum_j(exp(logits[i, j]))
softmax :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                Float] t) =>
           Tensor v1 t -- ^ __logits__: 2-D with shape `[batch_size, num_classes]`.
           -> Tensor Value t -- ^ __softmax__: Same shape as `logits`.
softmax logits | eqLengthGuard [] =
    buildOp (opDef "Softmax"
             & opAttr "T" .~ tensorType (undefined :: t))
        logits
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D with shape `[batch_size, num_classes]`."
  name: "logits"
  type_attr: "T"
}
output_arg {
  description: "Same shape as `logits`."
  name: "softmax"
  type_attr: "T"
}
-}

-- | Reverses specific dimensions of a tensor.
--
-- Given a `tensor`, and a `int32` tensor `axis` representing the set of
-- dimensions of `tensor` to reverse. This operation reverses each dimension
-- `i` for which there exists `j` s.t. `axis[j] == i`.
-- 
-- `tensor` can have up to 8 dimensions. The number of dimensions specified
-- in `axis` may be 0 or more entries. If an index is specified more than
-- once, a InvalidArgument error is raised.
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor 't' is [[[[ 0,  1,  2,  3],
-- #                  [ 4,  5,  6,  7],
-- #                  [ 8,  9, 10, 11]],
-- #                 [[12, 13, 14, 15],
-- #                  [16, 17, 18, 19],
-- #                  [20, 21, 22, 23]]]]
-- # tensor 't' shape is [1, 2, 3, 4]
-- 
-- # 'dims' is [3] or 'dims' is -1
-- reverse(t, dims) ==> [[[[ 3,  2,  1,  0],
--                         [ 7,  6,  5,  4],
--                         [ 11, 10, 9, 8]],
--                        [[15, 14, 13, 12],
--                         [19, 18, 17, 16],
--                         [23, 22, 21, 20]]]]
-- 
-- # 'dims' is '[1]' (or 'dims' is '[-3]')
-- reverse(t, dims) ==> [[[[12, 13, 14, 15],
--                         [16, 17, 18, 19],
--                         [20, 21, 22, 23]
--                        [[ 0,  1,  2,  3],
--                         [ 4,  5,  6,  7],
--                         [ 8,  9, 10, 11]]]]
-- 
-- # 'dims' is '[2]' (or 'dims' is '[-2]')
-- reverse(t, dims) ==> [[[[8, 9, 10, 11],
--                         [4, 5, 6, 7],
--                         [0, 1, 2, 3]]
--                        [[20, 21, 22, 23],
--                         [16, 17, 18, 19],
--                         [12, 13, 14, 15]]]]
-- ```
reverseV2 :: forall v1 v2 tidx t . (TensorType tidx, OneOf '[Data.Int.Int32,
                                                             Data.Int.Int64] tidx,
                                    TensorType t,
                                    OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float), Bool,
                                            Data.Int.Int32, Data.Int.Int64,
                                            Data.Int.Int8, Data.Word.Word16,
                                            Data.Word.Word8, Double,
                                            Float] t) =>
             Tensor v1 t -- ^ __tensor__: Up to 8-D.
             -> Tensor v2 tidx -- ^ __axis__: 1-D. The indices of the dimensions to reverse.
             -> Tensor Value t -- ^ __output__: The same shape as `tensor`.
reverseV2 tensor axis | eqLengthGuard [] =
    buildOp (opDef "ReverseV2"
             & opAttr "Tidx" .~ tensorType (undefined :: tidx)
             & opAttr "T" .~ tensorType (undefined :: t))
        tensor axis
{-
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT32
      type: DT_INT64
      type: DT_BOOL
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Up to 8-D." name: "tensor" type_attr: "T"
}
input_arg {
  description: "1-D. The indices of the dimensions to reverse."
  name: "axis"
  type_attr: "Tidx"
}
output_arg {
  description: "The same shape as `tensor`."
  name: "output"
  type_attr: "T"
}
-}

-- | Return a tensor with the same shape and contents as the input tensor or value.

identity :: forall v1 t . (TensorType t) => Tensor v1 t -- ^ __input__
            -> Tensor Value t -- ^ __output__
identity input | eqLengthGuard [] =
    buildOp (opDef "Identity"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Adds two `SparseTensor` objects to produce another `SparseTensor`.
--
-- The input `SparseTensor` objects' indices are assumed ordered in standard
-- lexicographic order.  If this is not the case, before this step run
-- `SparseReorder` to restore index ordering.
-- 
-- By default, if two values sum to zero at some index, the output `SparseTensor`
-- would still include that particular location in its index, storing a zero in the
-- corresponding value slot.  To override this, callers can specify `thresh`,
-- indicating that if the sum has a magnitude strictly smaller than `thresh`, its
-- corresponding value and index would then not be included.  In particular,
-- `thresh == 0` (default) means everything is kept and actual thresholding happens
-- only for a positive value.
-- 
-- In the following shapes, `nnz` is the count after taking `thresh` into account.
sparseAdd :: forall v1 v2 v3 v4 v5 v6 v7 t treal . (TensorType t,
                                                    OneOf '[(Data.Complex.Complex Double),
                                                            (Data.Complex.Complex Float),
                                                            Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double, Float] t,
                                                    TensorType treal,
                                                    OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double,
                                                            Float] treal) =>
             Tensor v1 Data.Int.Int64 -- ^ __a_indices__: 2-D.  The `indices` of the first `SparseTensor`, size `[nnz, ndims]` Matrix.
             -> Tensor v2 t -- ^ __a_values__: 1-D.  The `values` of the first `SparseTensor`, size `[nnz]` Vector.
             -> Tensor v3 Data.Int.Int64 -- ^ __a_shape__: 1-D.  The `shape` of the first `SparseTensor`, size `[ndims]` Vector.
             -> Tensor v4 Data.Int.Int64 -- ^ __b_indices__: 2-D.  The `indices` of the second `SparseTensor`, size `[nnz, ndims]` Matrix.
             -> Tensor v5 t -- ^ __b_values__: 1-D.  The `values` of the second `SparseTensor`, size `[nnz]` Vector.
             -> Tensor v6 Data.Int.Int64 -- ^ __b_shape__: 1-D.  The `shape` of the second `SparseTensor`, size `[ndims]` Vector.
             -> Tensor v7 treal -- ^ __thresh__: 0-D.  The magnitude threshold that determines if an output value/index
                                -- pair takes space.
             -> (Tensor Value Data.Int.Int64, Tensor Value t,
                 Tensor Value Data.Int.Int64)
             -- ^ (__sum_indices__, __sum_values__, __sum_shape__)
             --
             -- * __sum_indices__
             --
             -- * __sum_values__
             --
             -- * __sum_shape__
sparseAdd a_indices a_values a_shape b_indices b_values b_shape
          thresh | eqLengthGuard [] =
    buildOp (opDef "SparseAdd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Treal" .~ tensorType (undefined :: treal))
        a_indices a_values a_shape b_indices b_values b_shape thresh
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "Treal"
  type: "type"
}
input_arg {
  description: "2-D.  The `indices` of the first `SparseTensor`, size `[nnz, ndims]` Matrix."
  name: "a_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the first `SparseTensor`, size `[nnz]` Vector."
  name: "a_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the first `SparseTensor`, size `[ndims]` Vector."
  name: "a_shape"
  type: DT_INT64
}
input_arg {
  description: "2-D.  The `indices` of the second `SparseTensor`, size `[nnz, ndims]` Matrix."
  name: "b_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the second `SparseTensor`, size `[nnz]` Vector."
  name: "b_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the second `SparseTensor`, size `[ndims]` Vector."
  name: "b_shape"
  type: DT_INT64
}
input_arg {
  description: "0-D.  The magnitude threshold that determines if an output value/index\npair takes space."
  name: "thresh"
  type_attr: "Treal"
}
output_arg { name: "sum_indices" type: DT_INT64 }
output_arg { name: "sum_values" type_attr: "T" }
output_arg { name: "sum_shape" type: DT_INT64 }
-}

-- | Update '*var' according to the centered RMSProp algorithm.
--
-- The centered RMSProp algorithm uses an estimate of the centered second moment
-- (i.e., the variance) for normalization, as opposed to regular RMSProp, which
-- uses the (uncentered) second moment. This often helps with training, but is
-- slightly more expensive in terms of computation and memory.
-- 
-- Note that in dense implementation of this algorithm, mg, ms, and mom will
-- update even if the grad is zero, but in this sparse implementation, mg, ms,
-- and mom will not update in iterations during which the grad is zero.
-- 
-- mean_square = decay * mean_square + (1-decay) * gradient ** 2
-- mean_grad = decay * mean_grad + (1-decay) * gradient
-- Delta = learning_rate * gradient / sqrt(mean_square + epsilon - mean_grad ** 2)
-- 
-- ms <- rho * ms_{t-1} + (1-rho) * grad * grad
-- mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)
-- var <- var - mom
sparseApplyCenteredRMSProp :: forall v5 v6 v7 v8 v9 v10 t
                              tindices . (TensorType t,
                                          OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t, TensorType tindices,
                                          OneOf '[Data.Int.Int32,
                                                  Data.Int.Int64] tindices) =>
                              Tensor Ref t -- ^ __var__: Should be from a Variable().
                              -> Tensor Ref t -- ^ __mg__: Should be from a Variable().
                              -> Tensor Ref t -- ^ __ms__: Should be from a Variable().
                              -> Tensor Ref t -- ^ __mom__: Should be from a Variable().
                              -> Tensor v5 t -- ^ __lr__: Scaling factor. Must be a scalar.
                              -> Tensor v6 t -- ^ __rho__: Decay rate. Must be a scalar.
                              -> Tensor v7 t -- ^ __momentum__
                              -> Tensor v8 t -- ^ __epsilon__: Ridge term. Must be a scalar.
                              -> Tensor v9 t -- ^ __grad__: The gradient.
                              -> Tensor v10 tindices -- ^ __indices__: A vector of indices into the first dimension of var, ms and mom.
                              -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyCenteredRMSProp var mg ms mom lr rho momentum epsilon grad
                           indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyCenteredRMSProp"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var mg ms mom lr rho momentum epsilon grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var, mg, ms, and mom tensors is\nprotected by a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mg"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "ms"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mom"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay rate. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg { name: "momentum" type_attr: "T" }
input_arg {
  description: "Ridge term. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var, ms and mom."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Add all input tensors element wise.

addN :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Int.Int16, Data.Int.Int32,
                                             Data.Int.Int64, Data.Int.Int8,
                                             Data.Word.Word16, Data.Word.Word8,
                                             Double, Float] t) =>
        [Tensor v1 t] -- ^ __inputs__: Must all be the same size and shape.
        -> Tensor Value t -- ^ __sum__
addN inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "AddN"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Must all be the same size and shape."
  name: "inputs"
  number_attr: "N"
  type_attr: "T"
}
output_arg { name: "sum" type_attr: "T" }
-}

-- | Computes offsets of concat inputs within its output.
--
-- For example:
-- 
-- ```prettyprint
-- # 'x' is [2, 2, 7]
-- # 'y' is [2, 3, 7]
-- # 'z' is [2, 5, 7]
-- concat_offset(2, [x, y, z]) => [0, 0, 0], [0, 2, 0], [0, 5, 0]
-- ```
concatOffset :: Tensor v1 Data.Int.Int32 -- ^ __concat_dim__: The dimension along which to concatenate.
                -> [Tensor v2 Data.Int.Int32] -- ^ __shape__: The `N` int32 vectors representing shape of tensors being concatenated.
                -> [Tensor Value Data.Int.Int32] -- ^ __offset__: The `N` int32 vectors representing the starting offset
                --         of input tensors within the concatenated output.
                -- 
                -- This is typically used by gradient computations for a concat operation.
concatOffset concat_dim
             shape | eqLengthGuard [("N", [("shape", length shape)])] =
    buildListOp [n] (opDef "ConcatOffset"
                     & opAttr "N" .~ n)
        concat_dim shape
  where
    n = fromIntegral (length shape) :: Int64
{-
attr { has_minimum: true minimum: 2 name: "N" type: "int" }
input_arg {
  description: "The dimension along which to concatenate."
  name: "concat_dim"
  type: DT_INT32
}
input_arg {
  description: "The `N` int32 vectors representing shape of tensors being concatenated."
  name: "shape"
  number_attr: "N"
  type: DT_INT32
}
output_arg {
  description: "The `N` int32 vectors representing the starting offset\n        of input tensors within the concatenated output.\n\nThis is typically used by gradient computations for a concat operation."
  name: "offset"
  number_attr: "N"
  type: DT_INT32
}
-}

-- | Concatenates tensors along one dimension.

concatV2 :: forall v1 v2 t tidx . (TensorType t, TensorType tidx,
                                   OneOf '[Data.Int.Int32,
                                           Data.Int.Int64] tidx) =>
            [Tensor v1 t] -- ^ __values__: List of `N` Tensors to concatenate. Their ranks and types must match,
                          -- and their sizes must match in all dimensions except `concat_dim`.
            -> Tensor v2 tidx -- ^ __axis__: 0-D.  The dimension along which to concatenate.  Must be in the
                              -- range [0, rank(values)).
            -> Tensor Value t -- ^ __output__: A `Tensor` with the concatenation of values stacked along the
            -- `concat_dim` dimension.  This tensor's shape matches that of `values` except
            -- in `concat_dim` where it has the sum of the sizes.
concatV2 values axis | eqLengthGuard [("N", [("values", length values)])] =
    buildOp (opDef "ConcatV2"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx)
             & opAttr "N" .~ n)
        values axis
  where
    n = fromIntegral (length values) :: Int64
{-
attr { has_minimum: true minimum: 2 name: "N" type: "int" }
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "List of `N` Tensors to concatenate. Their ranks and types must match,\nand their sizes must match in all dimensions except `concat_dim`."
  name: "values"
  number_attr: "N"
  type_attr: "T"
}
input_arg {
  description: "0-D.  The dimension along which to concatenate.  Must be in the\nrange [0, rank(values))."
  name: "axis"
  type_attr: "Tidx"
}
output_arg {
  description: "A `Tensor` with the concatenation of values stacked along the\n`concat_dim` dimension.  This tensor\'s shape matches that of `values` except\nin `concat_dim` where it has the sum of the sizes."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns a tensor of zeros with the same shape and type as x.

zerosLike :: forall v1 t . (TensorType t) =>
             Tensor v1 t -- ^ __x__: a tensor of type T.
             -> Tensor Value t -- ^ __y__: a tensor of the same shape and type as x but filled with zeros.
zerosLike x | eqLengthGuard [] =
    buildOp (opDef "ZerosLike"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr { name: "T" type: "type" }
input_arg {
  description: "a tensor of type T." name: "x" type_attr: "T"
}
output_arg {
  description: "a tensor of the same shape and type as x but filled with zeros."
  name: "y"
  type_attr: "T"
}
-}

-- | Update '*var' according to the centered RMSProp algorithm.
--
-- The centered RMSProp algorithm uses an estimate of the centered second moment
-- (i.e., the variance) for normalization, as opposed to regular RMSProp, which
-- uses the (uncentered) second moment. This often helps with training, but is
-- slightly more expensive in terms of computation and memory.
-- 
-- Note that in dense implementation of this algorithm, mg, ms, and mom will
-- update even if the grad is zero, but in this sparse implementation, mg, ms,
-- and mom will not update in iterations during which the grad is zero.
-- 
-- mean_square = decay * mean_square + (1-decay) * gradient ** 2
-- mean_grad = decay * mean_grad + (1-decay) * gradient
-- 
-- Delta = learning_rate * gradient / sqrt(mean_square + epsilon - mean_grad ** 2)
-- 
-- mg <- rho * mg_{t-1} + (1-rho) * grad
-- ms <- rho * ms_{t-1} + (1-rho) * grad * grad
-- mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms - mg * mg + epsilon)
-- var <- var - mom
applyCenteredRMSProp :: forall v5 v6 v7 v8 v9 t . (TensorType t,
                                                   OneOf '[(Data.Complex.Complex Double),
                                                           (Data.Complex.Complex Float),
                                                           Data.Int.Int16,
                                                           Data.Int.Int32,
                                                           Data.Int.Int64,
                                                           Data.Int.Int8,
                                                           Data.Word.Word16,
                                                           Data.Word.Word8,
                                                           Double, Float] t) =>
                        Tensor Ref t -- ^ __var__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __mg__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __ms__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __mom__: Should be from a Variable().
                        -> Tensor v5 t -- ^ __lr__: Scaling factor. Must be a scalar.
                        -> Tensor v6 t -- ^ __rho__: Decay rate. Must be a scalar.
                        -> Tensor v7 t -- ^ __momentum__
                        -> Tensor v8 t -- ^ __epsilon__: Ridge term. Must be a scalar.
                        -> Tensor v9 t -- ^ __grad__: The gradient.
                        -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyCenteredRMSProp var mg ms mom lr rho momentum epsilon
                     grad | eqLengthGuard [] =
    buildOp (opDef "ApplyCenteredRMSProp"
             & opAttr "T" .~ tensorType (undefined :: t))
        var mg ms mom lr rho momentum epsilon grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var, mg, ms, and mom tensors is\nprotected by a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mg"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "ms"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mom"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay rate. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg { name: "momentum" type_attr: "T" }
input_arg {
  description: "Ridge term. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update '*var' according to the RMSProp algorithm.
--
-- Note that in dense implementation of this algorithm, ms and mom will
-- update even if the grad is zero, but in this sparse implementation, ms
-- and mom will not update in iterations during which the grad is zero.
-- 
-- mean_square = decay * mean_square + (1-decay) * gradient ** 2
-- Delta = learning_rate * gradient / sqrt(mean_square + epsilon)
-- 
-- ms <- rho * ms_{t-1} + (1-rho) * grad * grad
-- mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)
-- var <- var - mom
applyRMSProp :: forall v4 v5 v6 v7 v8 t . (TensorType t,
                                           OneOf '[(Data.Complex.Complex Double),
                                                   (Data.Complex.Complex Float),
                                                   Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t) =>
                Tensor Ref t -- ^ __var__: Should be from a Variable().
                -> Tensor Ref t -- ^ __ms__: Should be from a Variable().
                -> Tensor Ref t -- ^ __mom__: Should be from a Variable().
                -> Tensor v4 t -- ^ __lr__: Scaling factor. Must be a scalar.
                -> Tensor v5 t -- ^ __rho__: Decay rate. Must be a scalar.
                -> Tensor v6 t -- ^ __momentum__
                -> Tensor v7 t -- ^ __epsilon__: Ridge term. Must be a scalar.
                -> Tensor v8 t -- ^ __grad__: The gradient.
                -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyRMSProp var ms mom lr rho momentum epsilon grad | eqLengthGuard [] =
    buildOp (opDef "ApplyRMSProp"
             & opAttr "T" .~ tensorType (undefined :: t))
        var ms mom lr rho momentum epsilon grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var, ms, and mom tensors is protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "ms"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mom"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay rate. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg { name: "momentum" type_attr: "T" }
input_arg {
  description: "Ridge term. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Adds a value to the current value of a variable.
--
-- Any ReadVariableOp which depends directly or indirectly on this assign is
-- guaranteed to see the incremented value or a subsequent newer one.
-- 
-- Outputs the incremented value, which can be used to totally order the
-- increments to this variable.
assignAddVariableOp :: forall v2 dtype . (TensorType dtype) =>
                       ResourceHandle dtype -- ^ __resource__: handle to the resource in which to store the variable.
                       -> Tensor v2 dtype -- ^ __value__: the value by which the variable will be incremented.
                       -> Build (ControlNode)
assignAddVariableOp resource value | eqLengthGuard [] =
    buildOp (opDef "AssignAddVariableOp"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        resource value
{-
attr {
  description: "the dtype of the value." name: "dtype" type: "type"
}
input_arg {
  description: "handle to the resource in which to store the variable."
  name: "resource"
  type: DT_RESOURCE
}
input_arg {
  description: "the value by which the variable will be incremented."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Update '*var' according to the Adam algorithm.
--
-- lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)
-- m_t <- beta1 * m_{t-1} + (1 - beta1) * g_t
-- v_t <- beta2 * v_{t-1} + (1 - beta2) * g_t * g_t
-- variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)
applyAdam :: forall v4 v5 v6 v7 v8 v9 v10 t . (TensorType t,
                                               OneOf '[(Data.Complex.Complex Double),
                                                       (Data.Complex.Complex Float),
                                                       Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
             Tensor Ref t -- ^ __var__: Should be from a Variable().
             -> Tensor Ref t -- ^ __m__: Should be from a Variable().
             -> Tensor Ref t -- ^ __v__: Should be from a Variable().
             -> Tensor v4 t -- ^ __beta1_power__: Must be a scalar.
             -> Tensor v5 t -- ^ __beta2_power__: Must be a scalar.
             -> Tensor v6 t -- ^ __lr__: Scaling factor. Must be a scalar.
             -> Tensor v7 t -- ^ __beta1__: Momentum factor. Must be a scalar.
             -> Tensor v8 t -- ^ __beta2__: Momentum factor. Must be a scalar.
             -> Tensor v9 t -- ^ __epsilon__: Ridge term. Must be a scalar.
             -> Tensor v10 t -- ^ __grad__: The gradient.
             -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyAdam var m v beta1_power beta2_power lr beta1 beta2 epsilon
          grad | eqLengthGuard [] =
    buildOp (opDef "ApplyAdam"
             & opAttr "T" .~ tensorType (undefined :: t))
        var m v beta1_power beta2_power lr beta1 beta2 epsilon grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var, m, and v tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "m"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "v"
  type_attr: "T"
}
input_arg {
  description: "Must be a scalar." name: "beta1_power" type_attr: "T"
}
input_arg {
  description: "Must be a scalar." name: "beta2_power" type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Momentum factor. Must be a scalar."
  name: "beta1"
  type_attr: "T"
}
input_arg {
  description: "Momentum factor. Must be a scalar."
  name: "beta2"
  type_attr: "T"
}
input_arg {
  description: "Ridge term. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Extracts a glimpse from the input tensor.
--
-- Returns a set of windows called glimpses extracted at location
-- `offsets` from the input tensor. If the windows only partially
-- overlaps the inputs, the non overlapping areas will be filled with
-- random noise.
-- 
-- The result is a 4-D tensor of shape `[batch_size, glimpse_height,
-- glimpse_width, channels]`. The channels and batch dimensions are the
-- same as that of the input tensor. The height and width of the output
-- windows are specified in the `size` parameter.
-- 
-- The argument `normalized` and `centered` controls how the windows are built:
-- 
-- * If the coordinates are normalized but not centered, 0.0 and 1.0
--   correspond to the minimum and maximum of each height and width
--   dimension.
-- * If the coordinates are both normalized and centered, they range from
--   -1.0 to 1.0. The coordinates (-1.0, -1.0) correspond to the upper
--   left corner, the lower right corner is located at (1.0, 1.0) and the
--   center is at (0, 0).
-- * If the coordinates are not normalized they are interpreted as
--   numbers of pixels.
extractGlimpse :: Tensor v1 Float -- ^ __input__: A 4-D float tensor of shape `[batch_size, height, width, channels]`.
                  -> Tensor v2 Data.Int.Int32 -- ^ __size__: A 1-D tensor of 2 elements containing the size of the glimpses
                                              -- to extract.  The glimpse height must be specified first, following
                                              -- by the glimpse width.
                  -> Tensor v3 Float -- ^ __offsets__: A 2-D integer tensor of shape `[batch_size, 2]` containing
                                     -- the x, y locations of the center of each window.
                  -> Tensor Value Float -- ^ __glimpse__: A tensor representing the glimpses `[batch_size,
                  -- glimpse_height, glimpse_width, channels]`.
extractGlimpse input size offsets | eqLengthGuard [] =
    buildOp (opDef "ExtractGlimpse")
        input size offsets
{-
attr {
  default_value { b: true }
  description: "indicates if the offset coordinates are centered relative to\nthe image, in which case the (0, 0) offset is relative to the center\nof the input images. If false, the (0,0) offset corresponds to the\nupper left corner of the input images."
  name: "centered"
  type: "bool"
}
attr {
  default_value { b: true }
  description: "indicates if the offset coordinates are normalized."
  name: "normalized"
  type: "bool"
}
attr {
  default_value { b: true }
  description: "indicates if the noise should be generated using a\nuniform distribution or a Gaussian distribution."
  name: "uniform_noise"
  type: "bool"
}
input_arg {
  description: "A 4-D float tensor of shape `[batch_size, height, width, channels]`."
  name: "input"
  type: DT_FLOAT
}
input_arg {
  description: "A 1-D tensor of 2 elements containing the size of the glimpses\nto extract.  The glimpse height must be specified first, following\nby the glimpse width."
  name: "size"
  type: DT_INT32
}
input_arg {
  description: "A 2-D integer tensor of shape `[batch_size, 2]` containing\nthe x, y locations of the center of each window."
  name: "offsets"
  type: DT_FLOAT
}
output_arg {
  description: "A tensor representing the glimpses `[batch_size,\nglimpse_height, glimpse_width, channels]`."
  name: "glimpse"
  type: DT_FLOAT
}
-}

-- | Update relevant entries in '*var' and '*accum' according to the momentum scheme.
--
-- Set use_nesterov = True if you want to use Nesterov momentum.
-- 
-- That is for rows we have grad for, we update var and accum as follows:
-- 
-- accum = accum * momentum + grad
-- var -= lr * accum
sparseApplyMomentum :: forall v3 v4 v5 v6 t tindices . (TensorType t,
                                                        OneOf '[(Data.Complex.Complex Double),
                                                                (Data.Complex.Complex Float),
                                                                Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Int.Int64,
                                                                Data.Int.Int8,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8,
                                                                Double,
                                                                Float] t,
                                                        TensorType tindices,
                                                        OneOf '[Data.Int.Int32,
                                                                Data.Int.Int64] tindices) =>
                       Tensor Ref t -- ^ __var__: Should be from a Variable().
                       -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                       -> Tensor v3 t -- ^ __lr__: Learning rate. Must be a scalar.
                       -> Tensor v4 t -- ^ __grad__: The gradient.
                       -> Tensor v5 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                       -> Tensor v6 t -- ^ __momentum__: Momentum. Must be a scalar.
                       -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyMomentum var accum lr grad indices momentum | eqLengthGuard [] =
    buildOp (opDef "SparseApplyMomentum"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var accum lr grad indices momentum
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If `True`, the tensor passed to compute grad will be\nvar - lr * momentum * accum, so in the end, the var you get is actually\nvar - lr * momentum * accum."
  name: "use_nesterov"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Learning rate. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "Momentum. Must be a scalar."
  name: "momentum"
  type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update '*var' according to the momentum scheme. Set use_nesterov = True if you
--
-- want to use Nesterov momentum.
-- 
-- accum = accum * momentum + grad
-- var -= lr * accum
applyMomentum :: forall v3 v4 v5 t . (TensorType t,
                                      OneOf '[(Data.Complex.Complex Double),
                                              (Data.Complex.Complex Float),
                                              Data.Int.Int16, Data.Int.Int32,
                                              Data.Int.Int64, Data.Int.Int8,
                                              Data.Word.Word16, Data.Word.Word8,
                                              Double, Float] t) =>
                 Tensor Ref t -- ^ __var__: Should be from a Variable().
                 -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                 -> Tensor v3 t -- ^ __lr__: Scaling factor. Must be a scalar.
                 -> Tensor v4 t -- ^ __grad__: The gradient.
                 -> Tensor v5 t -- ^ __momentum__: Momentum. Must be a scalar.
                 -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyMomentum var accum lr grad momentum | eqLengthGuard [] =
    buildOp (opDef "ApplyMomentum"
             & opAttr "T" .~ tensorType (undefined :: t))
        var accum lr grad momentum
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If `True`, the tensor passed to compute grad will be\nvar - lr * momentum * accum, so in the end, the var you get is actually\nvar - lr * momentum * accum."
  name: "use_nesterov"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "Momentum. Must be a scalar."
  name: "momentum"
  type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | A queue that produces elements in first-in first-out order.

fIFOQueue :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __handle__: The handle to the queue.
fIFOQueue  | eqLengthGuard [] =
    buildOp (opDef "FIFOQueue")
        
{-
attr {
  description: "The type of each component in a value."
  has_minimum: true
  minimum: 1
  name: "component_types"
  type: "list(type)"
}
attr {
  default_value { list { } }
  description: "The shape of each component in a value. The length of this attr must\nbe either 0 or the same as the length of component_types. If the length of\nthis attr is 0, the shapes of queue elements are not constrained, and\nonly one element may be dequeued at a time."
  has_minimum: true
  name: "shapes"
  type: "list(shape)"
}
attr {
  default_value { i: -1 }
  description: "The upper bound on the number of elements in this queue.\nNegative numbers mean no limit."
  name: "capacity"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue will be shared under the given name\nacross multiple sessions."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to the queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Update relevant entries in '*var' according to the Ftrl-proximal scheme.
--
-- That is for rows we have grad for, we update var, accum and linear as follows:
-- accum_new = accum + grad * grad
-- linear += grad + (accum_new^(-lr_power) - accum^(-lr_power)) / lr * var
-- quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2
-- var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0
-- accum = accum_new
sparseApplyFtrl :: forall v4 v5 v6 v7 v8 v9 t tindices . (TensorType t,
                                                          OneOf '[(Data.Complex.Complex Double),
                                                                  (Data.Complex.Complex Float),
                                                                  Data.Int.Int16,
                                                                  Data.Int.Int32,
                                                                  Data.Int.Int64,
                                                                  Data.Int.Int8,
                                                                  Data.Word.Word16,
                                                                  Data.Word.Word8,
                                                                  Double,
                                                                  Float] t,
                                                          TensorType tindices,
                                                          OneOf '[Data.Int.Int32,
                                                                  Data.Int.Int64] tindices) =>
                   Tensor Ref t -- ^ __var__: Should be from a Variable().
                   -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                   -> Tensor Ref t -- ^ __linear__: Should be from a Variable().
                   -> Tensor v4 t -- ^ __grad__: The gradient.
                   -> Tensor v5 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                   -> Tensor v6 t -- ^ __lr__: Scaling factor. Must be a scalar.
                   -> Tensor v7 t -- ^ __l1__: L1 regularization. Must be a scalar.
                   -> Tensor v8 t -- ^ __l2__: L2 regularization. Must be a scalar.
                   -> Tensor v9 t -- ^ __lr_power__: Scaling factor. Must be a scalar.
                   -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyFtrl var accum linear grad indices lr l1 l2
                lr_power | eqLengthGuard [] =
    buildOp (opDef "SparseApplyFtrl"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var accum linear grad indices lr l1 l2 lr_power
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "linear"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr_power"
  type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update entries in '*var' and '*accum' according to the proximal adagrad scheme.

sparseApplyAdagradDA :: forall v4 v5 v6 v7 v8 v9 t tindices . (TensorType t,
                                                               OneOf '[(Data.Complex.Complex Double),
                                                                       (Data.Complex.Complex Float),
                                                                       Data.Int.Int16,
                                                                       Data.Int.Int32,
                                                                       Data.Int.Int64,
                                                                       Data.Int.Int8,
                                                                       Data.Word.Word16,
                                                                       Data.Word.Word8,
                                                                       Double,
                                                                       Float] t,
                                                               TensorType tindices,
                                                               OneOf '[Data.Int.Int32,
                                                                       Data.Int.Int64] tindices) =>
                        Tensor Ref t -- ^ __var__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __gradient_accumulator__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __gradient_squared_accumulator__: Should be from a Variable().
                        -> Tensor v4 t -- ^ __grad__: The gradient.
                        -> Tensor v5 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                        -> Tensor v6 t -- ^ __lr__: Learning rate. Must be a scalar.
                        -> Tensor v7 t -- ^ __l1__: L1 regularization. Must be a scalar.
                        -> Tensor v8 t -- ^ __l2__: L2 regularization. Must be a scalar.
                        -> Tensor v9 Data.Int.Int64 -- ^ __global_step__: Training step number. Must be a scalar.
                        -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyAdagradDA var gradient_accumulator gradient_squared_accumulator grad
                     indices lr l1 l2 global_step | eqLengthGuard [] =
    buildOp (opDef "SparseApplyAdagradDA"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var gradient_accumulator gradient_squared_accumulator grad indices lr l1
        l2 global_step
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var and accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "gradient_accumulator"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "gradient_squared_accumulator"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "Learning rate. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "Training step number. Must be a scalar."
  name: "global_step"
  type: DT_INT64
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Returns x // y element-wise.
--
-- *NOTE*: `FloorDiv` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
floorDiv :: forall v1 v2 t . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t) => Tensor v1 t -- ^ __x__
            -> Tensor v2 t -- ^ __y__
            -> Tensor Value t -- ^ __z__
floorDiv x y | eqLengthGuard [] =
    buildOp (opDef "FloorDiv"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Update '*var' according to the proximal adagrad scheme.

applyAdagradDA :: forall v4 v5 v6 v7 v8 t . (TensorType t,
                                             OneOf '[(Data.Complex.Complex Double),
                                                     (Data.Complex.Complex Float),
                                                     Data.Int.Int16,
                                                     Data.Int.Int32,
                                                     Data.Int.Int64,
                                                     Data.Int.Int8,
                                                     Data.Word.Word16,
                                                     Data.Word.Word8, Double,
                                                     Float] t) =>
                  Tensor Ref t -- ^ __var__: Should be from a Variable().
                  -> Tensor Ref t -- ^ __gradient_accumulator__: Should be from a Variable().
                  -> Tensor Ref t -- ^ __gradient_squared_accumulator__: Should be from a Variable().
                  -> Tensor v4 t -- ^ __grad__: The gradient.
                  -> Tensor v5 t -- ^ __lr__: Scaling factor. Must be a scalar.
                  -> Tensor v6 t -- ^ __l1__: L1 regularization. Must be a scalar.
                  -> Tensor v7 t -- ^ __l2__: L2 regularization. Must be a scalar.
                  -> Tensor v8 Data.Int.Int64 -- ^ __global_step__: Training step number. Must be a scalar.
                  -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyAdagradDA var gradient_accumulator gradient_squared_accumulator grad lr l1
               l2 global_step | eqLengthGuard [] =
    buildOp (opDef "ApplyAdagradDA"
             & opAttr "T" .~ tensorType (undefined :: t))
        var gradient_accumulator gradient_squared_accumulator grad lr l1 l2
        global_step
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var and accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "gradient_accumulator"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "gradient_squared_accumulator"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "Training step number. Must be a scalar."
  name: "global_step"
  type: DT_INT64
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update '*var' according to the adagrad scheme.
--
-- accum += grad * grad
-- var -= lr * grad * (1 / sqrt(accum))
applyAdagrad :: forall v3 v4 t . (TensorType t,
                                  OneOf '[(Data.Complex.Complex Double),
                                          (Data.Complex.Complex Float),
                                          Data.Int.Int16, Data.Int.Int32,
                                          Data.Int.Int64, Data.Int.Int8,
                                          Data.Word.Word16, Data.Word.Word8,
                                          Double, Float] t) =>
                Tensor Ref t -- ^ __var__: Should be from a Variable().
                -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                -> Tensor v3 t -- ^ __lr__: Scaling factor. Must be a scalar.
                -> Tensor v4 t -- ^ __grad__: The gradient.
                -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyAdagrad var accum lr grad | eqLengthGuard [] =
    buildOp (opDef "ApplyAdagrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        var accum lr grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Computes the gradient of the sigmoid of `x` wrt its input.
--
-- Specifically, `grad = dy * y * (1 - y)`, where `y = sigmoid(x)`, and
-- `dy` is the corresponding input gradient.
sigmoidGrad :: forall v1 v2 t . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Word.Word16, Double, Float] t) =>
               Tensor v1 t -- ^ __x__
               -> Tensor v2 t -- ^ __y__
               -> Tensor Value t -- ^ __z__
sigmoidGrad x y | eqLengthGuard [] =
    buildOp (opDef "SigmoidGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Update '*var' according to the adadelta scheme.
--
-- accum = rho() * accum + (1 - rho()) * grad.square();
-- update = (update_accum + epsilon).sqrt() * (accum + epsilon()).rsqrt() * grad;
-- update_accum = rho() * update_accum + (1 - rho()) * update.square();
-- var -= update;
applyAdadelta :: forall v4 v5 v6 v7 t . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
                 Tensor Ref t -- ^ __var__: Should be from a Variable().
                 -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                 -> Tensor Ref t -- ^ __accum_update__: Should be from a Variable().
                 -> Tensor v4 t -- ^ __lr__: Scaling factor. Must be a scalar.
                 -> Tensor v5 t -- ^ __rho__: Decay factor. Must be a scalar.
                 -> Tensor v6 t -- ^ __epsilon__: Constant factor. Must be a scalar.
                 -> Tensor v7 t -- ^ __grad__: The gradient.
                 -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyAdadelta var accum accum_update lr rho epsilon grad | eqLengthGuard [] =
    buildOp (opDef "ApplyAdadelta"
             & opAttr "T" .~ tensorType (undefined :: t))
        var accum accum_update lr rho epsilon grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var, accum and update_accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum_update"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay factor. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg {
  description: "Constant factor. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Sparse update '*var' as FOBOS algorithm with fixed learning rate.
--
-- That is for rows we have grad for, we update var as follows:
-- prox_v = var - alpha * grad
-- var = sign(prox_v)/(1+alpha*l2) * max{|prox_v|-alpha*l1,0}
sparseApplyProximalGradientDescent :: forall v2 v3 v4 v5 v6 t
                                      tindices . (TensorType t,
                                                  OneOf '[(Data.Complex.Complex Double),
                                                          (Data.Complex.Complex Float),
                                                          Data.Int.Int16,
                                                          Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Data.Int.Int8,
                                                          Data.Word.Word16,
                                                          Data.Word.Word8,
                                                          Double, Float] t,
                                                  TensorType tindices,
                                                  OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64] tindices) =>
                                      Tensor Ref t -- ^ __var__: Should be from a Variable().
                                      -> Tensor v2 t -- ^ __alpha__: Scaling factor. Must be a scalar.
                                      -> Tensor v3 t -- ^ __l1__: L1 regularization. Must be a scalar.
                                      -> Tensor v4 t -- ^ __l2__: L2 regularization. Must be a scalar.
                                      -> Tensor v5 t -- ^ __grad__: The gradient.
                                      -> Tensor v6 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                                      -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyProximalGradientDescent var alpha l1 l2 grad
                                   indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyProximalGradientDescent"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var alpha l1 l2 grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the subtraction will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "alpha"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update '*var' as FOBOS algorithm with fixed learning rate.
--
-- prox_v = var - alpha * delta
-- var = sign(prox_v)/(1+alpha*l2) * max{|prox_v|-alpha*l1,0}
applyProximalGradientDescent :: forall v2 v3 v4 v5 t . (TensorType t,
                                                        OneOf '[(Data.Complex.Complex Double),
                                                                (Data.Complex.Complex Float),
                                                                Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Int.Int64,
                                                                Data.Int.Int8,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8,
                                                                Double,
                                                                Float] t) =>
                                Tensor Ref t -- ^ __var__: Should be from a Variable().
                                -> Tensor v2 t -- ^ __alpha__: Scaling factor. Must be a scalar.
                                -> Tensor v3 t -- ^ __l1__: L1 regularization. Must be a scalar.
                                -> Tensor v4 t -- ^ __l2__: L2 regularization. Must be a scalar.
                                -> Tensor v5 t -- ^ __delta__: The change.
                                -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyProximalGradientDescent var alpha l1 l2 delta | eqLengthGuard [] =
    buildOp (opDef "ApplyProximalGradientDescent"
             & opAttr "T" .~ tensorType (undefined :: t))
        var alpha l1 l2 delta
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the subtraction will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "alpha"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "The change." name: "delta" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Solves systems of linear equations.
--
-- `Matrix` is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-- form square matrices. `Rhs` is a tensor of shape `[..., M, K]`. The `output` is
-- a tensor shape `[..., M, K]`.  If `adjoint` is `False` then each output matrix
-- satisfies `matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]`.
-- If `adjoint` is `True` then each output matrix satisfies
-- `adjoint(matrix[..., :, :]) * output[..., :, :] = rhs[..., :, :]`.
matrixSolve :: forall v1 v2 t . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float), Double,
                                         Float] t) =>
               Tensor v1 t -- ^ __matrix__: Shape is `[..., M, M]`.
               -> Tensor v2 t -- ^ __rhs__: Shape is `[..., M, K]`.
               -> Tensor Value t -- ^ __output__: Shape is `[..., M, K]`.
matrixSolve matrix rhs | eqLengthGuard [] =
    buildOp (opDef "MatrixSolve"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs
{-
attr {
  default_value { b: false }
  description: "Boolean indicating whether to solve with `matrix` or its (block-wise)\nadjoint."
  name: "adjoint"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_DOUBLE
      type: DT_FLOAT
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`."
  name: "matrix"
  type_attr: "T"
}
input_arg {
  description: "Shape is `[..., M, K]`." name: "rhs" type_attr: "T"
}
output_arg {
  description: "Shape is `[..., M, K]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Sparse update entries in '*var' and '*accum' according to FOBOS algorithm.
--
-- That is for rows we have grad for, we update var and accum as follows:
-- accum += grad * grad
-- prox_v = var
-- prox_v -= lr * grad * (1 / sqrt(accum))
-- var = sign(prox_v)/(1+lr*l2) * max{|prox_v|-lr*l1,0}
sparseApplyProximalAdagrad :: forall v3 v4 v5 v6 v7 t tindices . (TensorType t,
                                                                  OneOf '[(Data.Complex.Complex Double),
                                                                          (Data.Complex.Complex Float),
                                                                          Data.Int.Int16,
                                                                          Data.Int.Int32,
                                                                          Data.Int.Int64,
                                                                          Data.Int.Int8,
                                                                          Data.Word.Word16,
                                                                          Data.Word.Word8,
                                                                          Double,
                                                                          Float] t,
                                                                  TensorType tindices,
                                                                  OneOf '[Data.Int.Int32,
                                                                          Data.Int.Int64] tindices) =>
                              Tensor Ref t -- ^ __var__: Should be from a Variable().
                              -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                              -> Tensor v3 t -- ^ __lr__: Learning rate. Must be a scalar.
                              -> Tensor v4 t -- ^ __l1__: L1 regularization. Must be a scalar.
                              -> Tensor v5 t -- ^ __l2__: L2 regularization. Must be a scalar.
                              -> Tensor v6 t -- ^ __grad__: The gradient.
                              -> Tensor v7 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                              -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyProximalAdagrad var accum lr l1 l2 grad indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyProximalAdagrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var accum lr l1 l2 grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var and accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Learning rate. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Update '*var' by subtracting 'alpha' * 'delta' from it.

applyGradientDescent :: forall v2 v3 t . (TensorType t,
                                          OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
                        Tensor Ref t -- ^ __var__: Should be from a Variable().
                        -> Tensor v2 t -- ^ __alpha__: Scaling factor. Must be a scalar.
                        -> Tensor v3 t -- ^ __delta__: The change.
                        -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyGradientDescent var alpha delta | eqLengthGuard [] =
    buildOp (opDef "ApplyGradientDescent"
             & opAttr "T" .~ tensorType (undefined :: t))
        var alpha delta
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, the subtraction will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "alpha"
  type_attr: "T"
}
input_arg {
  description: "The change." name: "delta" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Batch normalization.
--
-- This op is deprecated. Prefer `tf.nn.batch_normalization`.
batchNormWithGlobalNormalization :: forall v1 v2 v3 v4 v5 t . (TensorType t,
                                                               OneOf '[(Data.Complex.Complex Double),
                                                                       (Data.Complex.Complex Float),
                                                                       Data.Int.Int16,
                                                                       Data.Int.Int32,
                                                                       Data.Int.Int64,
                                                                       Data.Int.Int8,
                                                                       Data.Word.Word16,
                                                                       Data.Word.Word8,
                                                                       Double,
                                                                       Float] t) =>
                                    Bool -- ^ __scale_after_normalization__: A bool indicating whether the resulted tensor
                                         -- needs to be multiplied with gamma.
                                    -> Float -- ^ __variance_epsilon__: A small float number to avoid dividing by 0.
                                    -> Tensor v1 t -- ^ __t__: A 4D input Tensor.
                                    -> Tensor v2 t -- ^ __m__: A 1D mean Tensor with size matching the last dimension of t.
                                                   -- This is the first output from tf.nn.moments,
                                                   -- or a saved moving average thereof.
                                    -> Tensor v3 t -- ^ __v__: A 1D variance Tensor with size matching the last dimension of t.
                                                   -- This is the second output from tf.nn.moments,
                                                   -- or a saved moving average thereof.
                                    -> Tensor v4 t -- ^ __beta__: A 1D beta Tensor with size matching the last dimension of t.
                                                   -- An offset to be added to the normalized tensor.
                                    -> Tensor v5 t -- ^ __gamma__: A 1D gamma Tensor with size matching the last dimension of t.
                                                   -- If "scale_after_normalization" is true, this tensor will be multiplied
                                                   -- with the normalized tensor.
                                    -> Tensor Value t -- ^ __result__
batchNormWithGlobalNormalization scale_after_normalization variance_epsilon t m
                                 v beta gamma | eqLengthGuard [] =
    buildOp (opDef "BatchNormWithGlobalNormalization"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "scale_after_normalization" .~ scale_after_normalization
             & opAttr "variance_epsilon" .~ variance_epsilon)
        t m v beta gamma
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "A small float number to avoid dividing by 0."
  name: "variance_epsilon"
  type: "float"
}
attr {
  description: "A bool indicating whether the resulted tensor\nneeds to be multiplied with gamma."
  name: "scale_after_normalization"
  type: "bool"
}
input_arg {
  description: "A 4D input Tensor." name: "t" type_attr: "T"
}
input_arg {
  description: "A 1D mean Tensor with size matching the last dimension of t.\nThis is the first output from tf.nn.moments,\nor a saved moving average thereof."
  name: "m"
  type_attr: "T"
}
input_arg {
  description: "A 1D variance Tensor with size matching the last dimension of t.\nThis is the second output from tf.nn.moments,\nor a saved moving average thereof."
  name: "v"
  type_attr: "T"
}
input_arg {
  description: "A 1D beta Tensor with size matching the last dimension of t.\nAn offset to be added to the normalized tensor."
  name: "beta"
  type_attr: "T"
}
input_arg {
  description: "A 1D gamma Tensor with size matching the last dimension of t.\nIf \"scale_after_normalization\" is true, this tensor will be multiplied\nwith the normalized tensor."
  name: "gamma"
  type_attr: "T"
}
output_arg { name: "result" type_attr: "T" }
-}

-- | Encode strings into web-safe base64 format.
--
-- Refer to the following article for more information on base64 format:
-- en.wikipedia.org/wiki/Base64. Base64 strings may have padding with '=' at the
-- end so that the encoded has length multiple of 4. See Padding section of the
-- link above.
-- 
-- Web-safe means that the encoder uses - and _ instead of + and /.
encodeBase64 :: Tensor v1 Data.ByteString.ByteString -- ^ __input__: Strings to be encoded.
                -> Tensor Value Data.ByteString.ByteString -- ^ __output__: Input strings encoded in base64.
encodeBase64 input | eqLengthGuard [] =
    buildOp (opDef "EncodeBase64")
        input
{-
attr {
  default_value { b: false }
  description: "Bool whether padding is applied at the ends."
  name: "pad"
  type: "bool"
}
input_arg {
  description: "Strings to be encoded." name: "input" type: DT_STRING
}
output_arg {
  description: "Input strings encoded in base64."
  name: "output"
  type: DT_STRING
}
-}

-- | Joins the strings in the given list of string tensors into one tensor;
--
-- with the given separator (default is an empty separator).
stringJoin :: [Tensor v1 Data.ByteString.ByteString] -- ^ __inputs__: A list of string tensors.  The tensors must all have the same shape,
                                                     -- or be scalars.  Scalars may be mixed in; these will be broadcast to the shape
                                                     -- of non-scalar inputs.
              -> Tensor Value Data.ByteString.ByteString -- ^ __output__
stringJoin inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "StringJoin"
             & opAttr "N" .~ n)
        inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
attr {
  default_value { s: "" }
  description: "string, an optional join separator."
  name: "separator"
  type: "string"
}
input_arg {
  description: "A list of string tensors.  The tensors must all have the same shape,\nor be scalars.  Scalars may be mixed in; these will be broadcast to the shape\nof non-scalar inputs."
  name: "inputs"
  number_attr: "N"
  type: DT_STRING
}
output_arg { name: "output" type: DT_STRING }
-}

-- | Computes the gradient of the crop_and_resize op wrt the input image tensor.

cropAndResizeGradImage :: forall v1 v2 v3 v4 t . (TensorType t,
                                                  OneOf '[Data.Word.Word16,
                                                          Double, Float] t) =>
                          Tensor v1 Float -- ^ __grads__: A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`.
                          -> Tensor v2 Float -- ^ __boxes__: A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor
                                             -- specifies the coordinates of a box in the `box_ind[i]` image and is specified
                                             -- in normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of
                                             -- `y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the
                                             -- `[0, 1]` interval of normalized image height is mapped to
                                             -- `[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in
                                             -- which case the sampled crop is an up-down flipped version of the original
                                             -- image. The width dimension is treated similarly. Normalized coordinates
                                             -- outside the `[0, 1]` range are allowed, in which case we use
                                             -- `extrapolation_value` to extrapolate the input image values.
                          -> Tensor v3 Data.Int.Int32 -- ^ __box_ind__: A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.
                                                      -- The value of `box_ind[i]` specifies the image that the `i`-th box refers to.
                          -> Tensor v4 Data.Int.Int32 -- ^ __image_size__: A 1-D tensor with value `[batch, image_height, image_width, depth]`
                                                      -- containing the original image size. Both `image_height` and `image_width` need
                                                      -- to be positive.
                          -> Tensor Value t -- ^ __output__: A 4-D tensor of shape `[batch, image_height, image_width, depth]`.
cropAndResizeGradImage grads boxes box_ind image_size | eqLengthGuard [] =
    buildOp (opDef "CropAndResizeGradImage"
             & opAttr "T" .~ tensorType (undefined :: t))
        grads boxes box_ind image_size
{-
attr {
  allowed_values {
    list { type: DT_FLOAT type: DT_HALF type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "bilinear" } }
  default_value { s: "bilinear" }
  description: "A string specifying the interpolation method. Only \'bilinear\' is\nsupported for now."
  name: "method"
  type: "string"
}
input_arg {
  description: "A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`."
  name: "grads"
  type: DT_FLOAT
}
input_arg {
  description: "A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor\nspecifies the coordinates of a box in the `box_ind[i]` image and is specified\nin normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of\n`y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the\n`[0, 1]` interval of normalized image height is mapped to\n`[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in\nwhich case the sampled crop is an up-down flipped version of the original\nimage. The width dimension is treated similarly. Normalized coordinates\noutside the `[0, 1]` range are allowed, in which case we use\n`extrapolation_value` to extrapolate the input image values."
  name: "boxes"
  type: DT_FLOAT
}
input_arg {
  description: "A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.\nThe value of `box_ind[i]` specifies the image that the `i`-th box refers to."
  name: "box_ind"
  type: DT_INT32
}
input_arg {
  description: "A 1-D tensor with value `[batch, image_height, image_width, depth]`\ncontaining the original image size. Both `image_height` and `image_width` need\nto be positive."
  name: "image_size"
  type: DT_INT32
}
output_arg {
  description: "A 4-D tensor of shape `[batch, image_height, image_width, depth]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes hyperbolic tangent of `x` element-wise.

tanh :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                             (Data.Complex.Complex Float),
                                             Data.Word.Word16, Double,
                                             Float] t) => Tensor v1 t -- ^ __x__
        -> Tensor Value t -- ^ __y__
tanh x | eqLengthGuard [] =
    buildOp (opDef "Tanh"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Converts each entry in the given tensor to strings.  Supports many numeric
--
-- types and boolean.
asString :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Float),
                                                 Bool, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Double, Float] t) =>
            Tensor v1 t -- ^ __input__
            -> Tensor Value Data.ByteString.ByteString -- ^ __output__
asString input | eqLengthGuard [] =
    buildOp (opDef "AsString"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values {
    list {
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_BOOL
      type: DT_INT8
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { i: -1 }
  description: "The post-decimal precision to use for floating point numbers.\nOnly used if precision > -1."
  name: "precision"
  type: "int"
}
attr {
  default_value { b: false }
  description: "Use scientific notation for floating point numbers."
  name: "scientific"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "Use shortest representation (either scientific or standard) for\nfloating point numbers."
  name: "shortest"
  type: "bool"
}
attr {
  default_value { i: -1 }
  description: "Pad pre-decimal numbers to this width.\nApplies to both floating point and integer numbers.\nOnly used if width > -1."
  name: "width"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "The value to pad if width > -1.  If empty, pads with spaces.\nAnother typical value is \'0\'.  String cannot be longer than 1 character."
  name: "fill"
  type: "string"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type: DT_STRING }
-}

-- | Compute the inverse 2-dimensional discrete Fourier Transform over the inner-most
--
-- 2 dimensions of `input`.
iFFT2D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__: A complex64 tensor.
          -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__: A complex64 tensor of the same shape as `input`. The inner-most 2
          --   dimensions of `input` are replaced with their inverse 2D Fourier Transform.
          -- 
          -- @compatibility(numpy)
          -- Equivalent to np.ifft2
          -- @end_compatibility
iFFT2D input | eqLengthGuard [] =
    buildOp (opDef "IFFT2D")
        input
{-
input_arg {
  description: "A complex64 tensor." name: "input" type: DT_COMPLEX64
}
output_arg {
  description: "A complex64 tensor of the same shape as `input`. The inner-most 2\n  dimensions of `input` are replaced with their inverse 2D Fourier Transform.\n\n@compatibility(numpy)\nEquivalent to np.ifft2\n@end_compatibility"
  name: "output"
  type: DT_COMPLEX64
}
-}

-- | Concatenates a list of `SparseTensor` along the specified dimension.
--
-- Concatenation is with respect to the dense versions of these sparse tensors.
-- It is assumed that each input is a `SparseTensor` whose elements are ordered
-- along increasing dimension number.
-- 
-- All inputs' shapes must match, except for the concat dimension.  The
-- `indices`, `values`, and `shapes` lists must have the same length.
-- 
-- The output shape is identical to the inputs', except along the concat
-- dimension, where it is the sum of the inputs' sizes along that dimension.
-- 
-- The output elements will be resorted to preserve the sort order along
-- increasing dimension number.
-- 
-- This op runs in `O(M log M)` time, where `M` is the total number of non-empty
-- values across all inputs. This is due to the need for an internal sort in
-- order to concatenate efficiently across an arbitrary dimension.
-- 
-- For example, if `concat_dim = 1` and the inputs are
-- 
--     sp_inputs[0]: shape = [2, 3]
--     [0, 2]: "a"
--     [1, 0]: "b"
--     [1, 1]: "c"
-- 
--     sp_inputs[1]: shape = [2, 4]
--     [0, 1]: "d"
--     [0, 2]: "e"
-- 
-- then the output will be
-- 
--     shape = [2, 7]
--     [0, 2]: "a"
--     [0, 4]: "d"
--     [0, 5]: "e"
--     [1, 0]: "b"
--     [1, 1]: "c"
-- 
-- Graphically this is equivalent to doing
-- 
--     [    a] concat [  d e  ] = [    a   d e  ]
--     [b c  ]        [       ]   [b c          ]
sparseConcat :: forall v1 v2 v3 t . (TensorType t) =>
                Data.Int.Int64 -- ^ __concat_dim__: Dimension to concatenate along. Must be in range [-rank, rank),
                               -- where rank is the number of dimensions in each input `SparseTensor`.
                -> [Tensor v1 Data.Int.Int64] -- ^ __indices__: 2-D.  Indices of each input `SparseTensor`.
                -> [Tensor v2 t] -- ^ __values__: 1-D.  Non-empty values of each `SparseTensor`.
                -> [Tensor v3 Data.Int.Int64] -- ^ __shapes__: 1-D.  Shapes of each `SparseTensor`.
                -> (Tensor Value Data.Int.Int64, Tensor Value t,
                    Tensor Value Data.Int.Int64)
                -- ^ (__output_indices__, __output_values__, __output_shape__)
                --
                -- * __output_indices__: 2-D.  Indices of the concatenated `SparseTensor`.
                --
                -- * __output_values__: 1-D.  Non-empty values of the concatenated `SparseTensor`.
                --
                -- * __output_shape__: 1-D.  Shape of the concatenated `SparseTensor`.
sparseConcat concat_dim indices values
             shapes | eqLengthGuard [("N", [("indices", length indices),
                                            ("values", length values),
                                            ("shapes", length shapes)])] =
    buildOp (opDef "SparseConcat"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "concat_dim" .~ concat_dim
             & opAttr "N" .~ n)
        indices values shapes
  where
    n = fromIntegral (length indices) :: Int64
{-
attr {
  description: "Dimension to concatenate along. Must be in range [-rank, rank),\nwhere rank is the number of dimensions in each input `SparseTensor`."
  name: "concat_dim"
  type: "int"
}
attr { has_minimum: true minimum: 2 name: "N" type: "int" }
attr { name: "T" type: "type" }
input_arg {
  description: "2-D.  Indices of each input `SparseTensor`."
  name: "indices"
  number_attr: "N"
  type: DT_INT64
}
input_arg {
  description: "1-D.  Non-empty values of each `SparseTensor`."
  name: "values"
  number_attr: "N"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shapes of each `SparseTensor`."
  name: "shapes"
  number_attr: "N"
  type: DT_INT64
}
output_arg {
  description: "2-D.  Indices of the concatenated `SparseTensor`."
  name: "output_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  Non-empty values of the concatenated `SparseTensor`."
  name: "output_values"
  type_attr: "T"
}
output_arg {
  description: "1-D.  Shape of the concatenated `SparseTensor`."
  name: "output_shape"
  type: DT_INT64
}
-}

-- | Generate a glob pattern matching all sharded file names.

shardedFilespec :: Tensor v1 Data.ByteString.ByteString -- ^ __basename__
                   -> Tensor v2 Data.Int.Int32 -- ^ __num_shards__
                   -> Tensor Value Data.ByteString.ByteString -- ^ __filename__
shardedFilespec basename num_shards | eqLengthGuard [] =
    buildOp (opDef "ShardedFilespec")
        basename num_shards
{-
input_arg { name: "basename" type: DT_STRING }
input_arg { name: "num_shards" type: DT_INT32 }
output_arg { name: "filename" type: DT_STRING }
-}

-- | Shuffle dimensions of x according to a permutation.
--
-- The output `y` has the same rank as `x`. The shapes of `x` and `y` satisfy:
--   `y.shape[i] == x.shape[perm[i]] for i in [0, 1, ..., rank(x) - 1]`
transpose :: forall v1 v2 t tperm . (TensorType t, TensorType tperm,
                                     OneOf '[Data.Int.Int32,
                                             Data.Int.Int64] tperm) =>
             Tensor v1 t -- ^ __x__
             -> Tensor v2 tperm -- ^ __perm__
             -> Tensor Value t -- ^ __y__
transpose x perm | eqLengthGuard [] =
    buildOp (opDef "Transpose"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tperm" .~ tensorType (undefined :: tperm))
        x perm
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tperm"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "perm" type_attr: "Tperm" }
output_arg { name: "y" type_attr: "T" }
-}

-- | Joins a string Tensor across the given dimensions.
--
-- Computes the string join across dimensions in the given string Tensor of shape
-- `[d_0, d_1, ..., d_n-1]`.  Returns a new Tensor created by joining the input
-- strings with the given separator (default: empty string).  Negative indices are
-- counted backwards from the end, with `-1` being equivalent to `n - 1`.  Passing
-- an empty `reduction_indices` joins all strings in linear index order and outputs
-- a scalar string.
-- 
-- 
-- For example:
-- 
-- ```
-- # tensor `a` is [["a", "b"], ["c", "d"]]
-- tf.reduce_join(a, 0) ==> ["ac", "bd"]
-- tf.reduce_join(a, 1) ==> ["ab", "cd"]
-- tf.reduce_join(a, -2) = tf.reduce_join(a, 0) ==> ["ac", "bd"]
-- tf.reduce_join(a, -1) = tf.reduce_join(a, 1) ==> ["ab", "cd"]
-- tf.reduce_join(a, 0, keep_dims=True) ==> [["ac", "bd"]]
-- tf.reduce_join(a, 1, keep_dims=True) ==> [["ab"], ["cd"]]
-- tf.reduce_join(a, 0, separator=".") ==> ["a.c", "b.d"]
-- tf.reduce_join(a, [0, 1]) ==> ["acbd"]
-- tf.reduce_join(a, [1, 0]) ==> ["abcd"]
-- tf.reduce_join(a, []) ==> ["abcd"]
-- ```
reduceJoin :: Tensor v1 Data.ByteString.ByteString -- ^ __inputs__: The input to be joined.  All reduced indices must have non-zero size.
              -> Tensor v2 Data.Int.Int32 -- ^ __reduction_indices__: The dimensions to reduce over.  Dimensions are reduced in the
                                          -- order specified.  Omitting `reduction_indices` is equivalent to passing
                                          -- `[n-1, n-2, ..., 0]`.  Negative indices from `-n` to `-1` are supported.
              -> Tensor Value Data.ByteString.ByteString -- ^ __output__: Has shape equal to that of the input with reduced dimensions removed or
              -- set to `1` depending on `keep_dims`.
reduceJoin inputs reduction_indices | eqLengthGuard [] =
    buildOp (opDef "ReduceJoin")
        inputs reduction_indices
{-
attr {
  default_value { b: false }
  description: "If `True`, retain reduced dimensions with length `1`."
  name: "keep_dims"
  type: "bool"
}
attr {
  default_value { s: "" }
  description: "The separator to use when joining."
  name: "separator"
  type: "string"
}
input_arg {
  description: "The input to be joined.  All reduced indices must have non-zero size."
  name: "inputs"
  type: DT_STRING
}
input_arg {
  description: "The dimensions to reduce over.  Dimensions are reduced in the\norder specified.  Omitting `reduction_indices` is equivalent to passing\n`[n-1, n-2, ..., 0]`.  Negative indices from `-n` to `-1` are supported."
  name: "reduction_indices"
  type: DT_INT32
}
output_arg {
  description: "Has shape equal to that of the input with reduced dimensions removed or\nset to `1` depending on `keep_dims`."
  name: "output"
  type: DT_STRING
}
-}

-- | Converts each string in the input Tensor to its hash mod by a number of buckets.
--
-- The hash function is deterministic on the content of the string within the
-- process.
-- 
-- Note that the hash function may change from time to time.
-- This functionality will be deprecated and it's recommended to use
-- `tf.string_to_hash_bucket_fast()` or `tf.string_to_hash_bucket_strong()`.
stringToHashBucket :: Data.Int.Int64 -- ^ __num_buckets__: The number of buckets.
                      -> Tensor v1 Data.ByteString.ByteString -- ^ __string_tensor__
                      -> Tensor Value Data.Int.Int64 -- ^ __output__: A Tensor of the same shape as the input `string_tensor`.
stringToHashBucket num_buckets string_tensor | eqLengthGuard [] =
    buildOp (opDef "StringToHashBucket"
             & opAttr "num_buckets" .~ num_buckets)
        string_tensor
{-
attr {
  description: "The number of buckets."
  has_minimum: true
  minimum: 1
  name: "num_buckets"
  type: "int"
}
input_arg { name: "string_tensor" type: DT_STRING }
output_arg {
  description: "A Tensor of the same shape as the input `string_tensor`."
  name: "output"
  type: DT_INT64
}
-}

-- | Draws samples from a multinomial distribution.

multinomial :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
               Tensor v1 t -- ^ __logits__: 2-D Tensor with shape `[batch_size, num_classes]`.  Each slice `[i, :]`
                           -- represents the unnormalized log probabilities for all classes.
               -> Tensor v2 Data.Int.Int32 -- ^ __num_samples__: 0-D.  Number of independent samples to draw for each row slice.
               -> Build (Tensor Value Data.Int.Int64) -- ^ __output__: 2-D Tensor with shape `[batch_size, num_samples]`.  Each slice `[i, :]`
               -- contains the drawn class labels with range `[0, num_classes)`.
multinomial logits num_samples | eqLengthGuard [] =
    buildOp (opDef "Multinomial"
             & opAttr "T" .~ tensorType (undefined :: t))
        logits num_samples
{-
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 is set to be non-zero, the internal random number\ngenerator is seeded by the given seed.  Otherwise, a random seed is used."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D Tensor with shape `[batch_size, num_classes]`.  Each slice `[i, :]`\nrepresents the unnormalized log probabilities for all classes."
  name: "logits"
  type_attr: "T"
}
input_arg {
  description: "0-D.  Number of independent samples to draw for each row slice."
  name: "num_samples"
  type: DT_INT32
}
output_arg {
  description: "2-D Tensor with shape `[batch_size, num_samples]`.  Each slice `[i, :]`\ncontains the drawn class labels with range `[0, num_classes)`."
  name: "output"
  type: DT_INT64
}
-}

-- | Converts each string in the input Tensor to its hash mod by a number of buckets.
--
-- The hash function is deterministic on the content of the string within the
-- process. The hash function is a keyed hash function, where attribute `key`
-- defines the key of the hash function. `key` is an array of 2 elements.
-- 
-- A strong hash is important when inputs may be malicious, e.g. URLs with
-- additional components. Adversaries could try to make their inputs hash to the
-- same bucket for a denial-of-service attack or to skew the results. A strong
-- hash prevents this by making it dificult, if not infeasible, to compute inputs
-- that hash to the same bucket. This comes at a cost of roughly 4x higher compute
-- time than `tf.string_to_hash_bucket_fast`.
stringToHashBucketStrong :: Data.Int.Int64 -- ^ __num_buckets__: The number of buckets.
                            -> Tensor v1 Data.ByteString.ByteString -- ^ __input__: The strings to assign a hash bucket.
                            -> Tensor Value Data.Int.Int64 -- ^ __output__: A Tensor of the same shape as the input `string_tensor`.
stringToHashBucketStrong num_buckets input | eqLengthGuard [] =
    buildOp (opDef "StringToHashBucketStrong"
             & opAttr "num_buckets" .~ num_buckets)
        input
{-
attr {
  description: "The number of buckets."
  has_minimum: true
  minimum: 1
  name: "num_buckets"
  type: "int"
}
attr {
  description: "The key for the keyed hash function passed as a list of two uint64\nelements."
  name: "key"
  type: "list(int)"
}
input_arg {
  description: "The strings to assign a hash bucket."
  name: "input"
  type: DT_STRING
}
output_arg {
  description: "A Tensor of the same shape as the input `string_tensor`."
  name: "output"
  type: DT_INT64
}
-}

-- | Applies sparse `updates` to individual values or slices within a given
--
-- variable according to `indices`.
-- 
-- `ref` is a `Tensor` with rank `P` and `indices` is a `Tensor` of rank `Q`.
-- 
-- `indices` must be integer tensor, containing indices into `ref`.
-- It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
-- 
-- The innermost dimension of `indices` (with length `K`) corresponds to
-- indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
-- dimension of `ref`.
-- 
-- `updates` is `Tensor` of rank `Q-1+P-K` with shape:
-- 
-- ```
-- [d_0, ..., d_{Q-2}, ref.shape[K], ..., ref.shape[P-1]].
-- ```
-- 
-- For example, say we want to update 4 scattered elements to a rank-1 tensor to
-- 8 elements. In Python, that update would look like this:
-- 
--     ref = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8])
--     indices = tf.constant([[4], [3], [1] ,[7]])
--     updates = tf.constant([9, 10, 11, 12])
--     update = tf.scatter_nd_update(ref, indices, updates)
--     with tf.Session() as sess:
--       print sess.run(update)
-- 
-- The resulting update to ref would look like this:
-- 
--     [1, 11, 3, 10, 9, 6, 7, 12]
-- 
-- See [tf.scatter_nd](#scatter_nd) for more details about how to make updates to
-- slices.
scatterNdUpdate :: forall v2 v3 t tindices . (TensorType t, TensorType tindices,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] tindices) =>
                   Tensor Ref t -- ^ __ref__: A mutable Tensor. Should be from a Variable node.
                   -> Tensor v2 tindices -- ^ __indices__: A Tensor. Must be one of the following types: int32, int64.
                                         -- A tensor of indices into ref.
                   -> Tensor v3 t -- ^ __updates__: A Tensor. Must have the same type as ref. A tensor of updated
                                  -- values to add to ref.
                   -> Build (Tensor Ref t) -- ^ __output_ref__: Same as ref. Returned as a convenience for operations that want to
                   -- use the updated values after the update is done.
scatterNdUpdate ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterNdUpdate"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: true }
  description: "An optional bool. Defaults to True. If True, the assignment will\nbe protected by a lock; otherwise the behavior is undefined,\nbut may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "A mutable Tensor. Should be from a Variable node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A Tensor. Must be one of the following types: int32, int64.\nA tensor of indices into ref."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A Tensor. Must have the same type as ref. A tensor of updated\nvalues to add to ref."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "Same as ref. Returned as a convenience for operations that want to\nuse the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Compute gradients for a FakeQuantWithMinMaxVars operation.

fakeQuantWithMinMaxVarsGradient :: Tensor v1 Float -- ^ __gradients__: Backpropagated gradients above the FakeQuantWithMinMaxVars operation.
                                   -> Tensor v2 Float -- ^ __inputs__: Values passed as inputs to the FakeQuantWithMinMaxVars operation.
                                                      -- min, max: Quantization interval, scalar floats.
                                   -> Tensor v3 Float -- ^ __min__
                                   -> Tensor v4 Float -- ^ __max__
                                   -> (Tensor Value Float, Tensor Value Float,
                                       Tensor Value Float)
                                   -- ^ (__backprops_wrt_input__, __backprop_wrt_min__, __backprop_wrt_max__)
                                   --
                                   -- * __backprops_wrt_input__: Backpropagated gradients w.r.t. inputs:
                                   -- `gradients * (inputs >= min && inputs <= max)`.
                                   --
                                   -- * __backprop_wrt_min__: Backpropagated gradients w.r.t. min parameter:
                                   -- `sum(gradients * (inputs < min))`.
                                   --
                                   -- * __backprop_wrt_max__: Backpropagated gradients w.r.t. max parameter:
                                   -- `sum(gradients * (inputs > max))`.
fakeQuantWithMinMaxVarsGradient gradients inputs min max | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxVarsGradient")
        gradients inputs min max
{-
input_arg {
  description: "Backpropagated gradients above the FakeQuantWithMinMaxVars operation."
  name: "gradients"
  type: DT_FLOAT
}
input_arg {
  description: "Values passed as inputs to the FakeQuantWithMinMaxVars operation.\nmin, max: Quantization interval, scalar floats."
  name: "inputs"
  type: DT_FLOAT
}
input_arg { name: "min" type: DT_FLOAT }
input_arg { name: "max" type: DT_FLOAT }
output_arg {
  description: "Backpropagated gradients w.r.t. inputs:\n`gradients * (inputs >= min && inputs <= max)`."
  name: "backprops_wrt_input"
  type: DT_FLOAT
}
output_arg {
  description: "Backpropagated gradients w.r.t. min parameter:\n`sum(gradients * (inputs < min))`."
  name: "backprop_wrt_min"
  type: DT_FLOAT
}
output_arg {
  description: "Backpropagated gradients w.r.t. max parameter:\n`sum(gradients * (inputs > max))`."
  name: "backprop_wrt_max"
  type: DT_FLOAT
}
-}

-- | Returns the size of a tensor.
--
-- This operation returns an integer representing the number of elements in
-- `input`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[[1, 1,, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]]
-- size(t) ==> 12
-- ```
size :: forall v1 t out_type . (TensorType t, TensorType out_type,
                                OneOf '[Data.Int.Int32,
                                        Data.Int.Int64] out_type) =>
        Tensor v1 t -- ^ __input__
        -> Tensor Value out_type -- ^ __output__
size input | eqLengthGuard [] =
    buildOp (opDef "Size"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        input
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_type"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "out_type" }
-}

-- | Divides a variable reference by sparse updates.
--
-- This operation computes
-- 
--     # Scalar indices
--     ref[indices, ...] /= updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] /= updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] /= updates[i, ..., j, ...]
-- 
-- This operation outputs `ref` after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
-- 
-- Duplicate entries are handled correctly: if multiple `indices` reference
-- the same location, their contributions divide.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
scatterDiv :: forall v2 v3 t tindices . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t, TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
              -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
              -> Tensor v3 t -- ^ __updates__: A tensor of values that `ref` is divided by.
              -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as `ref`.  Returned as a convenience for operations that want
              -- to use the updated values after the update is done.
scatterDiv ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterDiv"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the operation will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of values that `ref` is divided by."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "= Same as `ref`.  Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Multiplies sparse updates into a variable reference.
--
-- This operation computes
-- 
--     # Scalar indices
--     ref[indices, ...] *= updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] *= updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] *= updates[i, ..., j, ...]
-- 
-- This operation outputs `ref` after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
-- 
-- Duplicate entries are handled correctly: if multiple `indices` reference
-- the same location, their contributions multiply.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
scatterMul :: forall v2 v3 t tindices . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t, TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
              -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
              -> Tensor v3 t -- ^ __updates__: A tensor of updated values to multiply to `ref`.
              -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as `ref`.  Returned as a convenience for operations that want
              -- to use the updated values after the update is done.
scatterMul ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterMul"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the operation will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of updated values to multiply to `ref`."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "= Same as `ref`.  Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Copy Host Op.
--
-- Performs CPU-to-CPU deep-copying of tensor.
-- 
-- Unlike the Copy Op, this op has HostMemory constraint on its input or output.
copyHost :: forall v1 t . (TensorType t) =>
            Tensor v1 t -- ^ __input__: Input tensor.
            -> Tensor Value t -- ^ __output__: Output tensor, deep-copied from input.
copyHost input | eqLengthGuard [] =
    buildOp (opDef "CopyHost"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "The name of the input tensor."
  name: "tensor_name"
  type: "string"
}
input_arg {
  description: "Input tensor." name: "input" type_attr: "T"
}
output_arg {
  description: "Output tensor, deep-copied from input."
  name: "output"
  type_attr: "T"
}
-}

-- | A Reader that outputs the entire contents of a file as a value.
--
-- To use, enqueue filenames in a Queue.  The output of ReaderRead will
-- be a filename (key) and the contents of that file (value).
wholeFileReader :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __reader_handle__: The handle to reference the Reader.
wholeFileReader  | eqLengthGuard [] =
    buildOp (opDef "WholeFileReader")
        
{-
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to reference the Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Read `SparseTensors` from a `SparseTensorsMap` and concatenate them.
--
-- The input `sparse_handles` must be an `int64` matrix of shape `[N, 1]` where
-- `N` is the minibatch size and the rows correspond to the output handles of
-- `AddSparseToTensorsMap` or `AddManySparseToTensorsMap`.  The ranks of the
-- original `SparseTensor` objects that went into the given input ops must all
-- match.  When the final `SparseTensor` is created, it has rank one
-- higher than the ranks of the incoming `SparseTensor` objects
-- (they have been concatenated along a new row dimension on the left).
-- 
-- The output `SparseTensor` object's shape values for all dimensions but the
-- first are the max across the input `SparseTensor` objects' shape values
-- for the corresponding dimensions.  Its first shape value is `N`, the minibatch
-- size.
-- 
-- The input `SparseTensor` objects' indices are assumed ordered in
-- standard lexicographic order.  If this is not the case, after this
-- step run `SparseReorder` to restore index ordering.
-- 
-- For example, if the handles represent an input, which is a `[2, 3]` matrix
-- representing two original `SparseTensor` objects:
-- 
-- ```
--     index = [ 0]
--             [10]
--             [20]
--     values = [1, 2, 3]
--     shape = [50]
-- ```
-- 
-- and
-- 
-- ```
--     index = [ 2]
--             [10]
--     values = [4, 5]
--     shape = [30]
-- ```
-- 
-- then the final `SparseTensor` will be:
-- 
-- ```
--     index = [0  0]
--             [0 10]
--             [0 20]
--             [1  2]
--             [1 10]
--     values = [1, 2, 3, 4, 5]
--     shape = [2 50]
-- ```
takeManySparseFromTensorsMap :: forall v1 dtype . (TensorType dtype) =>
                                Tensor v1 Data.Int.Int64 -- ^ __sparse_handles__: 1-D, The `N` serialized `SparseTensor` objects.
                                                         -- Shape: `[N]`.
                                -> Build ((Tensor Value Data.Int.Int64,
                                           Tensor Value dtype,
                                           Tensor Value Data.Int.Int64))
                                -- ^ (__sparse_indices__, __sparse_values__, __sparse_shape__)
                                --
                                -- * __sparse_indices__: 2-D.  The `indices` of the minibatch `SparseTensor`.
                                --
                                -- * __sparse_values__: 1-D.  The `values` of the minibatch `SparseTensor`.
                                --
                                -- * __sparse_shape__: 1-D.  The `shape` of the minibatch `SparseTensor`.
takeManySparseFromTensorsMap sparse_handles | eqLengthGuard [] =
    buildOp (opDef "TakeManySparseFromTensorsMap"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        sparse_handles
{-
attr {
  description: "The `dtype` of the `SparseTensor` objects stored in the\n`SparseTensorsMap`."
  name: "dtype"
  type: "type"
}
attr {
  default_value { s: "" }
  description: "The container name for the `SparseTensorsMap` read by this op."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "The shared name for the `SparseTensorsMap` read by this op.\nIt should not be blank; rather the `shared_name` or unique Operation name\nof the Op that created the original `SparseTensorsMap` should be used."
  name: "shared_name"
  type: "string"
}
input_arg {
  description: "1-D, The `N` serialized `SparseTensor` objects.\nShape: `[N]`."
  name: "sparse_handles"
  type: DT_INT64
}
output_arg {
  description: "2-D.  The `indices` of the minibatch `SparseTensor`."
  name: "sparse_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  The `values` of the minibatch `SparseTensor`."
  name: "sparse_values"
  type_attr: "dtype"
}
output_arg {
  description: "1-D.  The `shape` of the minibatch `SparseTensor`."
  name: "sparse_shape"
  type: DT_INT64
}
-}

-- | Destroys the temporary variable and returns its final value.
--
-- Sets output to the value of the Tensor pointed to by 'ref', then destroys
-- the temporary variable called 'var_name'.
-- All other uses of 'ref' *must* have executed before this op.
-- This is typically achieved by chaining the ref through each assign op, or by
-- using control dependencies.
-- 
-- Outputs the final value of the tensor pointed to by 'ref'.
destroyTemporaryVariable :: forall t . (TensorType t) =>
                            Tensor Ref t -- ^ __ref__: A reference to the temporary variable tensor.
                            -> Build (Tensor Value t) -- ^ __value__
destroyTemporaryVariable ref | eqLengthGuard [] =
    buildOp (opDef "DestroyTemporaryVariable"
             & opAttr "T" .~ tensorType (undefined :: t))
        ref
{-
attr { name: "T" type: "type" }
attr {
  description: "Name of the temporary variable, usually the name of the matching\n\'TemporaryVariable\' op."
  name: "var_name"
  type: "string"
}
input_arg {
  description: "A reference to the temporary variable tensor."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
output_arg { name: "value" type_attr: "T" }
-}

-- | Update 'ref' by subtracting 'value' from it.
--
-- This operation outputs "ref" after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
assignSub :: forall v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
             Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
             -> Tensor v2 t -- ^ __value__: The value to be subtracted to the variable.
             -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as "ref".  Returned as a convenience for operations that want
             -- to use the new value after the variable has been updated.
assignSub ref value | eqLengthGuard [] =
    buildOp (opDef "AssignSub"
             & opAttr "T" .~ tensorType (undefined :: t))
        ref value
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the subtraction will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "The value to be subtracted to the variable."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "= Same as \"ref\".  Returned as a convenience for operations that want\nto use the new value after the variable has been updated."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | JPEG-encode an image.
--
-- `image` is a 3-D uint8 Tensor of shape `[height, width, channels]`.
-- 
-- The attr `format` can be used to override the color format of the encoded
-- output.  Values can be:
-- 
-- *   `''`: Use a default format based on the number of channels in the image.
-- *   `grayscale`: Output a grayscale JPEG image.  The `channels` dimension
--     of `image` must be 1.
-- *   `rgb`: Output an RGB JPEG image. The `channels` dimension
--     of `image` must be 3.
-- 
-- If `format` is not specified or is the empty string, a default format is picked
-- in function of the number of channels in `image`:
-- 
-- *   1: Output a grayscale image.
-- *   3: Output an RGB image.
encodeJpeg :: Tensor v1 Data.Word.Word8 -- ^ __image__: 3-D with shape `[height, width, channels]`.
              -> Tensor Value Data.ByteString.ByteString -- ^ __contents__: 0-D. JPEG-encoded image.
encodeJpeg image | eqLengthGuard [] =
    buildOp (opDef "EncodeJpeg")
        image
{-
attr {
  allowed_values { list { s: "" s: "grayscale" s: "rgb" } }
  default_value { s: "" }
  description: "Per pixel image format."
  name: "format"
  type: "string"
}
attr {
  default_value { i: 95 }
  description: "Quality of the compression from 0 to 100 (higher is better and slower)."
  name: "quality"
  type: "int"
}
attr {
  default_value { b: false }
  description: "If True, create a JPEG that loads progressively (coarse to fine)."
  name: "progressive"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If True, spend CPU/RAM to reduce size with no quality change."
  name: "optimize_size"
  type: "bool"
}
attr {
  default_value { b: true }
  description: "See http://en.wikipedia.org/wiki/Chroma_subsampling."
  name: "chroma_downsampling"
  type: "bool"
}
attr {
  allowed_values { list { s: "in" s: "cm" } }
  default_value { s: "in" }
  description: "Unit used to specify `x_density` and `y_density`:\npixels per inch (`\'in\'`) or centimeter (`\'cm\'`)."
  name: "density_unit"
  type: "string"
}
attr {
  default_value { i: 300 }
  description: "Horizontal pixels per density unit."
  name: "x_density"
  type: "int"
}
attr {
  default_value { i: 300 }
  description: "Vertical pixels per density unit."
  name: "y_density"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If not empty, embed this XMP metadata in the image header."
  name: "xmp_metadata"
  type: "string"
}
input_arg {
  description: "3-D with shape `[height, width, channels]`."
  name: "image"
  type: DT_UINT8
}
output_arg {
  description: "0-D. JPEG-encoded image."
  name: "contents"
  type: DT_STRING
}
-}

-- | Returns a tensor that may be mutated, but only persists within a single step.
--
-- This is an experimental op for internal use only and it is possible to use this
-- op in unsafe ways.  DO NOT USE unless you fully understand the risks.
-- 
-- It is the caller's responsibility to ensure that 'ref' is eventually passed to a
-- matching 'DestroyTemporaryVariable' op after all other uses have completed.
-- 
-- Outputs a ref to the tensor state so it may be read or modified.
-- 
--   E.g.
--       var = state_ops._temporary_variable([1, 2], types.float_)
--       var_name = var.op.name
--       var = state_ops.assign(var, [[4.0, 5.0]])
--       var = state_ops.assign_add(var, [[6.0, 7.0]])
--       final = state_ops._destroy_temporary_variable(var, var_name=var_name)
temporaryVariable :: forall dtype . (TensorType dtype) =>
                     Shape -- ^ __shape__: The shape of the variable tensor.
                     -> Build (Tensor Ref dtype) -- ^ __ref__: A reference to the variable tensor.
temporaryVariable shape | eqLengthGuard [] =
    buildOp (opDef "TemporaryVariable"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        
{-
attr {
  description: "The shape of the variable tensor."
  name: "shape"
  type: "shape"
}
attr {
  description: "The type of elements in the variable tensor."
  name: "dtype"
  type: "type"
}
attr {
  default_value { s: "" }
  description: "Overrides the name used for the temporary variable resource. Default\nvalue is the name of the \'TemporaryVariable\' op (which is guaranteed unique)."
  name: "var_name"
  type: "string"
}
output_arg {
  description: "A reference to the variable tensor."
  is_ref: true
  name: "ref"
  type_attr: "dtype"
}
-}

-- | Checks whether a tensor has been initialized.
--
-- Outputs boolean scalar indicating whether the tensor has been initialized.
isVariableInitialized :: forall dtype . (TensorType dtype) =>
                         Tensor Ref dtype -- ^ __ref__: Should be from a `Variable` node. May be uninitialized.
                         -> Build (Tensor Value Bool) -- ^ __is_initialized__
isVariableInitialized ref | eqLengthGuard [] =
    buildOp (opDef "IsVariableInitialized"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        ref
{-
attr {
  description: "The type of elements in the variable tensor."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "Should be from a `Variable` node. May be uninitialized."
  is_ref: true
  name: "ref"
  type_attr: "dtype"
}
output_arg { name: "is_initialized" type: DT_BOOL }
-}

-- | Holds state in the form of a tensor that persists across steps.
--
-- Outputs a ref to the tensor state so it may be read or modified.
-- TODO(zhifengc/mrry): Adds a pointer to a more detail document
-- about sharing states in tensorflow.
variable :: forall dtype . (TensorType dtype) =>
            Shape -- ^ __shape__: The shape of the variable tensor.
            -> Build (Tensor Ref dtype) -- ^ __ref__: A reference to the variable tensor.
variable shape | eqLengthGuard [] =
    buildOp (opDef "Variable"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        
{-
attr {
  description: "The shape of the variable tensor."
  name: "shape"
  type: "shape"
}
attr {
  description: "The type of elements in the variable tensor."
  name: "dtype"
  type: "type"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this variable is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this variable is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "A reference to the variable tensor."
  is_ref: true
  name: "ref"
  type_attr: "dtype"
}
-}

-- | Returns the element-wise min of two SparseTensors.
--
-- Assumes the two SparseTensors have the same shape, i.e., no broadcasting.
sparseSparseMinimum :: forall v1 v2 v3 v4 v5 v6 t . (TensorType t,
                                                     OneOf '[(Data.Complex.Complex Double),
                                                             (Data.Complex.Complex Float),
                                                             Data.Int.Int16,
                                                             Data.Int.Int32,
                                                             Data.Int.Int64,
                                                             Data.Int.Int8,
                                                             Data.Word.Word16,
                                                             Data.Word.Word8,
                                                             Double,
                                                             Float] t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __a_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                -- SparseTensor, in the canonical lexicographic ordering.
                       -> Tensor v2 t -- ^ __a_values__: 1-D.  `N` non-empty values corresponding to `a_indices`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __a_shape__: 1-D.  Shape of the input SparseTensor.
                       -> Tensor v4 Data.Int.Int64 -- ^ __b_indices__: counterpart to `a_indices` for the other operand.
                       -> Tensor v5 t -- ^ __b_values__: counterpart to `a_values` for the other operand; must be of the same dtype.
                       -> Tensor v6 Data.Int.Int64 -- ^ __b_shape__: counterpart to `a_shape` for the other operand; the two shapes must be equal.
                       -> (Tensor Value Data.Int.Int64, Tensor Value t)
                       -- ^ (__output_indices__, __output_values__)
                       --
                       -- * __output_indices__: 2-D.  The indices of the output SparseTensor.
                       --
                       -- * __output_values__: 1-D.  The values of the output SparseTensor.
sparseSparseMinimum a_indices a_values a_shape b_indices b_values
                    b_shape | eqLengthGuard [] =
    buildOp (opDef "SparseSparseMinimum"
             & opAttr "T" .~ tensorType (undefined :: t))
        a_indices a_values a_shape b_indices b_values b_shape
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, in the canonical lexicographic ordering."
  name: "a_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `a_indices`."
  name: "a_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "a_shape"
  type: DT_INT64
}
input_arg {
  description: "counterpart to `a_indices` for the other operand."
  name: "b_indices"
  type: DT_INT64
}
input_arg {
  description: "counterpart to `a_values` for the other operand; must be of the same dtype."
  name: "b_values"
  type_attr: "T"
}
input_arg {
  description: "counterpart to `a_shape` for the other operand; the two shapes must be equal."
  name: "b_shape"
  type: DT_INT64
}
output_arg {
  description: "2-D.  The indices of the output SparseTensor."
  name: "output_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  The values of the output SparseTensor."
  name: "output_values"
  type_attr: "T"
}
-}

-- | Compute the regularized incomplete beta integral \\(I_x(a, b)\\).
--
-- The regularized incomplete beta integral is defined as:
-- 
-- ```
-- I_x(a, b) = \frac{B(x; a, b)}{B(a, b)}
-- ```
-- where
-- 
-- ```
-- B(x; a, b) = \int_0^x t^{a-1} (1 - t)^{b-1} dt
-- ```
-- 
-- is the incomplete beta function and \\(B(a, b)\\) is the *complete*
-- beta function.
betainc :: forall v1 v2 v3 t . (TensorType t, OneOf '[Double, Float] t) =>
           Tensor v1 t -- ^ __a__
           -> Tensor v2 t -- ^ __b__
           -> Tensor v3 t -- ^ __x__
           -> Tensor Value t -- ^ __z__
betainc a b x | eqLengthGuard [] =
    buildOp (opDef "Betainc"
             & opAttr "T" .~ tensorType (undefined :: t))
        a b x
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "a" type_attr: "T" }
input_arg { name: "b" type_attr: "T" }
input_arg { name: "x" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Update 'ref' by assigning 'value' to it.
--
-- This operation outputs "ref" after the assignment is done.
-- This makes it easier to chain operations that need to use the reset value.
assign :: forall v2 t . (TensorType t) =>
          Tensor Ref t -- ^ __ref__: Should be from a `Variable` node. May be uninitialized.
          -> Tensor v2 t -- ^ __value__: The value to be assigned to the variable.
          -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as "ref".  Returned as a convenience for operations that want
          -- to use the new value after the variable has been reset.
assign ref value | eqLengthGuard [] =
    buildOp (opDef "Assign"
             & opAttr "T" .~ tensorType (undefined :: t))
        ref value
{-
attr { name: "T" type: "type" }
attr {
  default_value { b: true }
  description: "If true, the operation will validate that the shape\nof \'value\' matches the shape of the Tensor being assigned to.  If false,\n\'ref\' will take on the shape of \'value\'."
  name: "validate_shape"
  type: "bool"
}
attr {
  default_value { b: true }
  description: "If True, the assignment will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node. May be uninitialized."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "The value to be assigned to the variable."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "= Same as \"ref\".  Returned as a convenience for operations that want\nto use the new value after the variable has been reset."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Applies softmax to a batched N-D `SparseTensor`.
--
-- The inputs represent an N-D SparseTensor  with logical shape `[..., B, C]`
-- (where `N >= 2`), and with indices sorted in the canonical lexicographic order.
-- 
-- This op is equivalent to applying the normal `tf.nn.softmax()` to each innermost
-- logical submatrix with shape `[B, C]`, but with the catch that *the implicitly
-- zero elements do not participate*.  Specifically, the algorithm is equivalent
-- to the following:
-- 
--   (1) Applies `tf.nn.softmax()` to a densified view of each innermost submatrix
--       with shape `[B, C]`, along the size-C dimension;
--   (2) Masks out the original implicitly-zero locations;
--   (3) Renormalizes the remaining elements.
-- 
-- Hence, the `SparseTensor` result has exactly the same non-zero indices and
-- shape.
sparseSoftmax :: forall v1 v2 v3 t . (TensorType t, OneOf '[Double, Float] t) =>
                 Tensor v1 Data.Int.Int64 -- ^ __sp_indices__: 2-D.  `NNZ x R` matrix with the indices of non-empty values in a
                                          -- SparseTensor, in canonical ordering.
                 -> Tensor v2 t -- ^ __sp_values__: 1-D.  `NNZ` non-empty values corresponding to `sp_indices`.
                 -> Tensor v3 Data.Int.Int64 -- ^ __sp_shape__: 1-D.  Shape of the input SparseTensor.
                 -> Tensor Value t -- ^ __output__: 1-D.  The `NNZ` values for the result `SparseTensor`.
sparseSoftmax sp_indices sp_values sp_shape | eqLengthGuard [] =
    buildOp (opDef "SparseSoftmax"
             & opAttr "T" .~ tensorType (undefined :: t))
        sp_indices sp_values sp_shape
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `NNZ x R` matrix with the indices of non-empty values in a\nSparseTensor, in canonical ordering."
  name: "sp_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `NNZ` non-empty values corresponding to `sp_indices`."
  name: "sp_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "sp_shape"
  type: DT_INT64
}
output_arg {
  description: "1-D.  The `NNZ` values for the result `SparseTensor`."
  name: "output"
  type_attr: "T"
}
-}

-- | Adds up a SparseTensor and a dense Tensor, using these special rules:
--
-- (1) Broadcasts the dense side to have the same shape as the sparse side, if
--     eligible;
-- (2) Then, only the dense values pointed to by the indices of the SparseTensor
--     participate in the cwise addition.
-- 
-- By these rules, the result is a logical SparseTensor with exactly the same
-- indices and shape, but possibly with different non-zero values.  The output of
-- this Op is the resultant non-zero values.
sparseDenseCwiseAdd :: forall v1 v2 v3 v4 t . (TensorType t,
                                               OneOf '[(Data.Complex.Complex Double),
                                                       (Data.Complex.Complex Float),
                                                       Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __sp_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                -- SparseTensor, possibly not in canonical ordering.
                       -> Tensor v2 t -- ^ __sp_values__: 1-D.  `N` non-empty values corresponding to `sp_indices`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __sp_shape__: 1-D.  Shape of the input SparseTensor.
                       -> Tensor v4 t -- ^ __dense__: `R`-D.  The dense Tensor operand.
                       -> Tensor Value t -- ^ __output__: 1-D.  The `N` values that are operated on.
sparseDenseCwiseAdd sp_indices sp_values sp_shape dense | eqLengthGuard [] =
    buildOp (opDef "SparseDenseCwiseAdd"
             & opAttr "T" .~ tensorType (undefined :: t))
        sp_indices sp_values sp_shape dense
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "sp_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `sp_indices`."
  name: "sp_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "sp_shape"
  type: DT_INT64
}
input_arg {
  description: "`R`-D.  The dense Tensor operand."
  name: "dense"
  type_attr: "T"
}
output_arg {
  description: "1-D.  The `N` values that are operated on."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns the truth value of NOT x element-wise.

logicalNot :: Tensor v1 Bool -- ^ __x__
              -> Tensor Value Bool -- ^ __y__
logicalNot x | eqLengthGuard [] =
    buildOp (opDef "LogicalNot")
        x
{-
input_arg { name: "x" type: DT_BOOL }
output_arg { name: "y" type: DT_BOOL }
-}

-- | Computes the number of elements in the given queue.

queueSize :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a queue.
             -> Build (Tensor Value Data.Int.Int32) -- ^ __size__: The number of elements in the given queue.
queueSize handle | eqLengthGuard [] =
    buildOp (opDef "QueueSize")
        handle
{-
input_arg {
  description: "The handle to a queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The number of elements in the given queue."
  name: "size"
  type: DT_INT32
}
-}

-- | Update relevant entries in '*var' and '*accum' according to the adagrad scheme.
--
-- That is for rows we have grad for, we update var and accum as follows:
-- accum += grad * grad
-- var -= lr * grad * (1 / sqrt(accum))
sparseApplyAdagrad :: forall v3 v4 v5 t tindices . (TensorType t,
                                                    OneOf '[(Data.Complex.Complex Double),
                                                            (Data.Complex.Complex Float),
                                                            Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double, Float] t,
                                                    TensorType tindices,
                                                    OneOf '[Data.Int.Int32,
                                                            Data.Int.Int64] tindices) =>
                      Tensor Ref t -- ^ __var__: Should be from a Variable().
                      -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                      -> Tensor v3 t -- ^ __lr__: Learning rate. Must be a scalar.
                      -> Tensor v4 t -- ^ __grad__: The gradient.
                      -> Tensor v5 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                      -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyAdagrad var accum lr grad indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyAdagrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var accum lr grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Learning rate. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Store the input tensor in the state of the current session.

getSessionHandle :: forall v1 t . (TensorType t) =>
                    Tensor v1 t -- ^ __value__: The tensor to be stored.
                    -> Tensor Value Data.ByteString.ByteString -- ^ __handle__: The handle for the tensor stored in the session state.
getSessionHandle value | eqLengthGuard [] =
    buildOp (opDef "GetSessionHandle"
             & opAttr "T" .~ tensorType (undefined :: t))
        value
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be stored."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "The handle for the tensor stored in the session state."
  name: "handle"
  type: DT_STRING
}
-}

-- | Component-wise multiplies a SparseTensor by a dense Tensor.
--
-- The output locations corresponding to the implicitly zero elements in the sparse
-- tensor will be zero (i.e., will not take up storage space), regardless of the
-- contents of the dense tensor (even if it's +/-INF and that INF*0 == NaN).
-- 
-- *Limitation*: this Op only broadcasts the dense side to the sparse side, but not
-- the other direction.
sparseDenseCwiseMul :: forall v1 v2 v3 v4 t . (TensorType t,
                                               OneOf '[(Data.Complex.Complex Double),
                                                       (Data.Complex.Complex Float),
                                                       Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __sp_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                -- SparseTensor, possibly not in canonical ordering.
                       -> Tensor v2 t -- ^ __sp_values__: 1-D.  `N` non-empty values corresponding to `sp_indices`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __sp_shape__: 1-D.  Shape of the input SparseTensor.
                       -> Tensor v4 t -- ^ __dense__: `R`-D.  The dense Tensor operand.
                       -> Tensor Value t -- ^ __output__: 1-D.  The `N` values that are operated on.
sparseDenseCwiseMul sp_indices sp_values sp_shape dense | eqLengthGuard [] =
    buildOp (opDef "SparseDenseCwiseMul"
             & opAttr "T" .~ tensorType (undefined :: t))
        sp_indices sp_values sp_shape dense
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "sp_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `sp_indices`."
  name: "sp_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "sp_shape"
  type: DT_INT64
}
input_arg {
  description: "`R`-D.  The dense Tensor operand."
  name: "dense"
  type_attr: "T"
}
output_arg {
  description: "1-D.  The `N` values that are operated on."
  name: "output"
  type_attr: "T"
}
-}

-- | Adds up a `SparseTensor` and a dense `Tensor`, producing a dense `Tensor`.
--
-- This Op does not require `a_indices` be sorted in standard lexicographic order.
sparseTensorDenseAdd :: forall v1 v2 v3 v4 t tindices . (TensorType t,
                                                         OneOf '[(Data.Complex.Complex Double),
                                                                 (Data.Complex.Complex Float),
                                                                 Data.Int.Int16,
                                                                 Data.Int.Int32,
                                                                 Data.Int.Int64,
                                                                 Data.Int.Int8,
                                                                 Data.Word.Word16,
                                                                 Data.Word.Word8,
                                                                 Double,
                                                                 Float] t,
                                                         TensorType tindices,
                                                         OneOf '[Data.Int.Int32,
                                                                 Data.Int.Int64] tindices) =>
                        Tensor v1 tindices -- ^ __a_indices__: 2-D.  The `indices` of the `SparseTensor`, with shape `[nnz, ndims]`.
                        -> Tensor v2 t -- ^ __a_values__: 1-D.  The `values` of the `SparseTensor`, with shape `[nnz]`.
                        -> Tensor v3 tindices -- ^ __a_shape__: 1-D.  The `shape` of the `SparseTensor`, with shape `[ndims]`.
                        -> Tensor v4 t -- ^ __b__: `ndims`-D Tensor.  With shape `a_shape`.
                        -> Tensor Value t -- ^ __output__
sparseTensorDenseAdd a_indices a_values a_shape b | eqLengthGuard [] =
    buildOp (opDef "SparseTensorDenseAdd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        a_indices a_values a_shape b
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor`, with shape `[nnz, ndims]`."
  name: "a_indices"
  type_attr: "Tindices"
}
input_arg {
  description: "1-D.  The `values` of the `SparseTensor`, with shape `[nnz]`."
  name: "a_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the `SparseTensor`, with shape `[ndims]`."
  name: "a_shape"
  type_attr: "Tindices"
}
input_arg {
  description: "`ndims`-D Tensor.  With shape `a_shape`."
  name: "b"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Get the value of the tensor specified by its handle.

getSessionTensor :: forall v1 dtype . (TensorType dtype) =>
                    Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle for a tensor stored in the session state.
                    -> Tensor Value dtype -- ^ __value__: The tensor for the given handle.
getSessionTensor handle | eqLengthGuard [] =
    buildOp (opDef "GetSessionTensor"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle
{-
attr {
  description: "The type of the output value."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "The handle for a tensor stored in the session state."
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The tensor for the given handle."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Reorders a SparseTensor into the canonical, row-major ordering.
--
-- Note that by convention, all sparse ops preserve the canonical ordering along
-- increasing dimension number. The only time ordering can be violated is during
-- manual manipulation of the indices and values vectors to add entries.
-- 
-- Reordering does not affect the shape of the SparseTensor.
-- 
-- If the tensor has rank `R` and `N` non-empty values, `input_indices` has
-- shape `[N, R]`, input_values has length `N`, and input_shape has length `R`.
sparseReorder :: forall v1 v2 v3 t . (TensorType t) =>
                 Tensor v1 Data.Int.Int64 -- ^ __input_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                          -- SparseTensor, possibly not in canonical ordering.
                 -> Tensor v2 t -- ^ __input_values__: 1-D.  `N` non-empty values corresponding to `input_indices`.
                 -> Tensor v3 Data.Int.Int64 -- ^ __input_shape__: 1-D.  Shape of the input SparseTensor.
                 -> (Tensor Value Data.Int.Int64, Tensor Value t)
                 -- ^ (__output_indices__, __output_values__)
                 --
                 -- * __output_indices__: 2-D.  `N x R` matrix with the same indices as input_indices, but
                 -- in canonical row-major ordering.
                 --
                 -- * __output_values__: 1-D.  `N` non-empty values corresponding to `output_indices`.
sparseReorder input_indices input_values input_shape | eqLengthGuard [] =
    buildOp (opDef "SparseReorder"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_indices input_values input_shape
{-
attr { name: "T" type: "type" }
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "input_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `input_indices`."
  name: "input_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "input_shape"
  type: DT_INT64
}
output_arg {
  description: "2-D.  `N x R` matrix with the same indices as input_indices, but\nin canonical row-major ordering."
  name: "output_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  `N` non-empty values corresponding to `output_indices`."
  name: "output_values"
  type_attr: "T"
}
-}

-- | Split a `SparseTensor` into `num_split` tensors along one dimension.
--
-- If the `shape[split_dim]` is not an integer multiple of `num_split`. Slices
-- `[0 : shape[split_dim] % num_split]` gets one extra dimension.
-- For example, if `split_dim = 1` and `num_split = 2` and the input is
-- 
--     input_tensor = shape = [2, 7]
--     [    a   d e  ]
--     [b c          ]
-- 
-- Graphically the output tensors are:
-- 
--     output_tensor[0] = shape = [2, 4]
--     [    a  ]
--     [b c    ]
-- 
--     output_tensor[1] = shape = [2, 3]
--     [ d e  ]
--     [      ]
sparseSplit :: forall v1 v2 v3 v4 t . (TensorType t) =>
               Data.Int.Int64 -- ^ __num_split__: The number of ways to split.
               -> Tensor v1 Data.Int.Int64 -- ^ __split_dim__: 0-D.  The dimension along which to split.  Must be in the range
                                           -- `[0, rank(shape))`.
               -> Tensor v2 Data.Int.Int64 -- ^ __indices__: 2-D tensor represents the indices of the sparse tensor.
               -> Tensor v3 t -- ^ __values__: 1-D tensor represents the values of the sparse tensor.
               -> Tensor v4 Data.Int.Int64 -- ^ __shape__: 1-D. tensor represents the shape of the sparse tensor.
                                           -- output indices: A list of 1-D tensors represents the indices of the output
                                           -- sparse tensors.
               -> ([Tensor Value Data.Int.Int64], [Tensor Value t],
                   [Tensor Value Data.Int.Int64])
               -- ^ (__output_indices__, __output_values__, __output_shape__)
               --
               -- * __output_indices__
               --
               -- * __output_values__: A list of 1-D tensors represents the values of the output sparse
               -- tensors.
               --
               -- * __output_shape__: A list of 1-D tensors represents the shape of the output sparse
               -- tensors.
sparseSplit num_split split_dim indices values shape | eqLengthGuard [] =
    buildListOp [num_split, num_split, num_split] (opDef "SparseSplit"
                                                   & opAttr "T" .~ tensorType (undefined :: t)
                                                   & opAttr "num_split" .~ num_split)
        split_dim indices values shape
{-
attr {
  description: "The number of ways to split."
  has_minimum: true
  minimum: 1
  name: "num_split"
  type: "int"
}
attr { name: "T" type: "type" }
input_arg {
  description: "0-D.  The dimension along which to split.  Must be in the range\n`[0, rank(shape))`."
  name: "split_dim"
  type: DT_INT64
}
input_arg {
  description: "2-D tensor represents the indices of the sparse tensor."
  name: "indices"
  type: DT_INT64
}
input_arg {
  description: "1-D tensor represents the values of the sparse tensor."
  name: "values"
  type_attr: "T"
}
input_arg {
  description: "1-D. tensor represents the shape of the sparse tensor.\noutput indices: A list of 1-D tensors represents the indices of the output\nsparse tensors."
  name: "shape"
  type: DT_INT64
}
output_arg {
  name: "output_indices" number_attr: "num_split" type: DT_INT64
}
output_arg {
  description: "A list of 1-D tensors represents the values of the output sparse\ntensors."
  name: "output_values"
  number_attr: "num_split"
  type_attr: "T"
}
output_arg {
  description: "A list of 1-D tensors represents the shape of the output sparse\ntensors."
  name: "output_shape"
  number_attr: "num_split"
  type: DT_INT64
}
-}

-- | Pads a tensor with zeros.
--
-- This operation pads a `input` with zeros according to the `paddings` you
-- specify. `paddings` is an integer tensor with shape `[Dn, 2]`, where n is the
-- rank of `input`. For each dimension D of `input`, `paddings[D, 0]` indicates
-- how many zeros to add before the contents of `input` in that dimension, and
-- `paddings[D, 1]` indicates how many zeros to add after the contents of `input`
-- in that dimension.
-- 
-- The padded size of each dimension D of the output is:
-- 
-- `paddings(D, 0) + input.dim_size(D) + paddings(D, 1)`
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[1, 1], [2, 2]]
-- # 'paddings' is [[1, 1], [2, 2]]
-- # rank of 't' is 2
-- pad(t, paddings) ==> [[0, 0, 0, 0, 0, 0]
--                       [0, 0, 1, 1, 0, 0]
--                       [0, 0, 2, 2, 0, 0]
--                       [0, 0, 0, 0, 0, 0]]
-- ```
pad :: forall v1 v2 t tpaddings . (TensorType t, TensorType tpaddings,
                                   OneOf '[Data.Int.Int32,
                                           Data.Int.Int64] tpaddings) =>
       Tensor v1 t -- ^ __input__
       -> Tensor v2 tpaddings -- ^ __paddings__
       -> Tensor Value t -- ^ __output__
pad input paddings | eqLengthGuard [] =
    buildOp (opDef "Pad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tpaddings" .~ tensorType (undefined :: tpaddings))
        input paddings
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tpaddings"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
input_arg { name: "paddings" type_attr: "Tpaddings" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Converts a sparse representation into a dense tensor.
--
-- Builds an array `dense` with shape `output_shape` such that
-- 
-- ```prettyprint
-- # If sparse_indices is scalar
-- dense[i] = (i == sparse_indices ? sparse_values : default_value)
-- 
-- # If sparse_indices is a vector, then for each i
-- dense[sparse_indices[i]] = sparse_values[i]
-- 
-- # If sparse_indices is an n by d matrix, then for each i in [0, n)
-- dense[sparse_indices[i][0], ..., sparse_indices[i][d-1]] = sparse_values[i]
-- ```
-- 
-- All other values in `dense` are set to `default_value`.  If `sparse_values` is a
-- scalar, all sparse indices are set to this single value.
-- 
-- Indices should be sorted in lexicographic order, and indices must not
-- contain any repeats. If `validate_indices` is true, these properties
-- are checked during execution.
sparseToDense :: forall v1 v2 v3 v4 t tindices . (TensorType t,
                                                  TensorType tindices,
                                                  OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64] tindices) =>
                 Tensor v1 tindices -- ^ __sparse_indices__: 0-D, 1-D, or 2-D.  `sparse_indices[i]` contains the complete
                                    -- index where `sparse_values[i]` will be placed.
                 -> Tensor v2 tindices -- ^ __output_shape__: 1-D.  Shape of the dense output tensor.
                 -> Tensor v3 t -- ^ __sparse_values__: 1-D.  Values corresponding to each row of `sparse_indices`,
                                -- or a scalar value to be used for all sparse indices.
                 -> Tensor v4 t -- ^ __default_value__: Scalar value to set for indices not specified in
                                -- `sparse_indices`.
                 -> Tensor Value t -- ^ __dense__: Dense output tensor of shape `output_shape`.
sparseToDense sparse_indices output_shape sparse_values
              default_value | eqLengthGuard [] =
    buildOp (opDef "SparseToDense"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        sparse_indices output_shape sparse_values default_value
{-
attr {
  default_value { b: true }
  description: "If true, indices are checked to make sure they are sorted in\nlexicographic order and that there are no repeats."
  name: "validate_indices"
  type: "bool"
}
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg {
  description: "0-D, 1-D, or 2-D.  `sparse_indices[i]` contains the complete\nindex where `sparse_values[i]` will be placed."
  name: "sparse_indices"
  type_attr: "Tindices"
}
input_arg {
  description: "1-D.  Shape of the dense output tensor."
  name: "output_shape"
  type_attr: "Tindices"
}
input_arg {
  description: "1-D.  Values corresponding to each row of `sparse_indices`,\nor a scalar value to be used for all sparse indices."
  name: "sparse_values"
  type_attr: "T"
}
input_arg {
  description: "Scalar value to set for indices not specified in\n`sparse_indices`."
  name: "default_value"
  type_attr: "T"
}
output_arg {
  description: "Dense output tensor of shape `output_shape`."
  name: "dense"
  type_attr: "T"
}
-}

-- | Multiply SparseTensor (of rank 2) "A" by dense matrix "B".
--
-- No validity checking is performed on the indices of A.  However, the following
-- input format is recommended for optimal behavior:
-- 
-- if adjoint_a == false:
--   A should be sorted in lexicographically increasing order.  Use SparseReorder
--   if you're not sure.
-- if adjoint_a == true:
--   A should be sorted in order of increasing dimension 1 (i.e., "column major"
--   order instead of "row major" order).
sparseTensorDenseMatMul :: forall v1 v2 v3 v4 t . (TensorType t) =>
                           Tensor v1 Data.Int.Int64 -- ^ __a_indices__: 2-D.  The `indices` of the `SparseTensor`, size `[nnz, 2]` Matrix.
                           -> Tensor v2 t -- ^ __a_values__: 1-D.  The `values` of the `SparseTensor`, size `[nnz]` Vector.
                           -> Tensor v3 Data.Int.Int64 -- ^ __a_shape__: 1-D.  The `shape` of the `SparseTensor`, size `[2]` Vector.
                           -> Tensor v4 t -- ^ __b__: 2-D.  A dense Matrix.
                           -> Tensor Value t -- ^ __product__
sparseTensorDenseMatMul a_indices a_values a_shape b | eqLengthGuard [] =
    buildOp (opDef "SparseTensorDenseMatMul"
             & opAttr "T" .~ tensorType (undefined :: t))
        a_indices a_values a_shape b
{-
attr { name: "T" type: "type" }
attr {
  default_value { b: false }
  description: "Use the adjoint of A in the matrix multiply.  If A is complex, this\nis transpose(conj(A)).  Otherwise it\'s transpose(A)."
  name: "adjoint_a"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "Use the adjoint of B in the matrix multiply.  If B is complex, this\nis transpose(conj(B)).  Otherwise it\'s transpose(B)."
  name: "adjoint_b"
  type: "bool"
}
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor`, size `[nnz, 2]` Matrix."
  name: "a_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the `SparseTensor`, size `[nnz]` Vector."
  name: "a_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the `SparseTensor`, size `[2]` Vector."
  name: "a_shape"
  type: DT_INT64
}
input_arg {
  description: "2-D.  A dense Matrix." name: "b" type_attr: "T"
}
output_arg { name: "product" type_attr: "T" }
-}

-- | Gradient op for `MirrorPad` op. This op folds a mirror-padded tensor.
--
-- This operation folds the padded areas of `input` by `MirrorPad` according to the
-- `paddings` you specify. `paddings` must be the same as `paddings` argument
-- given to the corresponding `MirrorPad` op.
-- 
-- The folded size of each dimension D of the output is:
-- 
-- `input.dim_size(D) - paddings(D, 0) - paddings(D, 1)`
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is [[1, 2, 3], [4, 5, 6], [7, 8, 9]].
-- # 'paddings' is [[0, 1]], [0, 1]].
-- # 'mode' is SYMMETRIC.
-- # rank of 't' is 2.
-- pad(t, paddings) ==> [[ 1,  5]
--                       [11, 28]]
-- ```
mirrorPadGrad :: forall v1 v2 t tpaddings . (TensorType t, TensorType tpaddings,
                                             OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] tpaddings) =>
                 Tensor v1 t -- ^ __input__: The input tensor to be folded.
                 -> Tensor v2 tpaddings -- ^ __paddings__: A two-column matrix specifying the padding sizes. The number of
                                        -- rows must be the same as the rank of `input`.
                 -> Tensor Value t -- ^ __output__: The folded tensor.
mirrorPadGrad input paddings | eqLengthGuard [] =
    buildOp (opDef "MirrorPadGrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tpaddings" .~ tensorType (undefined :: tpaddings))
        input paddings
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tpaddings"
  type: "type"
}
attr {
  allowed_values { list { s: "REFLECT" s: "SYMMETRIC" } }
  description: "The mode used in the `MirrorPad` op."
  name: "mode"
  type: "string"
}
input_arg {
  description: "The input tensor to be folded."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "A two-column matrix specifying the padding sizes. The number of\nrows must be the same as the rank of `input`."
  name: "paddings"
  type_attr: "Tpaddings"
}
output_arg {
  description: "The folded tensor." name: "output" type_attr: "T"
}
-}

-- | Randomly shuffles a tensor along its first dimension.
--
--   The tensor is shuffled along dimension 0, such that each `value[j]` is mapped
--   to one and only one `output[i]`. For example, a mapping that might occur for a
--   3x2 tensor is:
-- 
-- ```prettyprint
-- [[1, 2],       [[5, 6],
--  [3, 4],  ==>   [1, 2],
--  [5, 6]]        [3, 4]]
-- ```
randomShuffle :: forall v1 t . (TensorType t) =>
                 Tensor v1 t -- ^ __value__: The tensor to be shuffled.
                 -> Build (Tensor Value t) -- ^ __output__: A tensor of same shape and type as `value`, shuffled along its first
                 -- dimension.
randomShuffle value | eqLengthGuard [] =
    buildOp (opDef "RandomShuffle"
             & opAttr "T" .~ tensorType (undefined :: t))
        value
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be shuffled."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "A tensor of same shape and type as `value`, shuffled along its first\ndimension."
  name: "output"
  type_attr: "T"
}
-}

-- | Selects elements from `t` or `e`, depending on `condition`.
--
-- The `t`, and `e` tensors must all have the same shape, and the
-- output will also have that shape.
-- 
-- The `condition` tensor must be a scalar if `t` and `e` are scalars.
-- If `t` and `e` are vectors or higher rank, then `condition` must be either a
-- scalar, a vector with size matching the first dimension of `t`, or must have
-- the same shape as `t`.
-- 
-- The `condition` tensor acts as a mask that chooses, based on the value at each
-- element, whether the corresponding element / row in the output should be
-- taken from `t` (if true) or `e` (if false).
-- 
-- If `condition` is a vector and `t` and `e` are higher rank matrices, then
-- it chooses which row (outer dimension) to copy from `t` and `e`.
-- If `condition` has the same shape as `t` and `e`, then it chooses which
-- element to copy from `t` and `e`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'condition' tensor is [[True,  False]
-- #                        [False, True]]
-- # 't' is [[1, 2],
-- #         [3, 4]]
-- # 'e' is [[5, 6],
-- #         [7, 8]]
-- select(condition, t, e) ==> [[1, 6],
--                              [7, 4]]
-- 
-- 
-- # 'condition' tensor is [True, False]
-- # 't' is [[1, 2],
-- #         [3, 4]]
-- # 'e' is [[5, 6],
-- #         [7, 8]]
-- select(condition, t, e) ==> [[1, 2],
--                              [7, 8]]
-- 
-- ```
select :: forall v1 v2 v3 t . (TensorType t) =>
          Tensor v1 Bool -- ^ __condition__
          -> Tensor v2 t -- ^ __t__: = A `Tensor` which may have the same shape as `condition`.
                         -- If `condition` is rank 1, `t` may have higher rank,
                         -- but its first dimension must match the size of `condition`.
          -> Tensor v3 t -- ^ __e__: = A `Tensor` with the same type and shape as `t`.
          -> Tensor Value t -- ^ __output__: = A `Tensor` with the same type and shape as `t` and `e`.
select condition t e | eqLengthGuard [] =
    buildOp (opDef "Select"
             & opAttr "T" .~ tensorType (undefined :: t))
        condition t e
{-
attr { name: "T" type: "type" }
input_arg { name: "condition" type: DT_BOOL }
input_arg {
  description: "= A `Tensor` which may have the same shape as `condition`.\nIf `condition` is rank 1, `t` may have higher rank,\nbut its first dimension must match the size of `condition`."
  name: "t"
  type_attr: "T"
}
input_arg {
  description: "= A `Tensor` with the same type and shape as `t`."
  name: "e"
  type_attr: "T"
}
output_arg {
  description: "= A `Tensor` with the same type and shape as `t` and `e`."
  name: "output"
  type_attr: "T"
}
-}

-- | The gradient operator for the SparseAdd op.
--
-- The SparseAdd op calculates A + B, where A, B, and the sum are all represented
-- as `SparseTensor` objects.  This op takes in the upstream gradient w.r.t.
-- non-empty values of the sum, and outputs the gradients w.r.t. the non-empty
-- values of A and B.
sparseAddGrad :: forall v1 v2 v3 v4 t . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
                 Tensor v1 t -- ^ __backprop_val_grad__: 1-D with shape `[nnz(sum)]`.  The gradient with respect to
                             -- the non-empty values of the sum.
                 -> Tensor v2 Data.Int.Int64 -- ^ __a_indices__: 2-D.  The `indices` of the `SparseTensor` A, size `[nnz(A), ndims]`.
                 -> Tensor v3 Data.Int.Int64 -- ^ __b_indices__: 2-D.  The `indices` of the `SparseTensor` B, size `[nnz(B), ndims]`.
                 -> Tensor v4 Data.Int.Int64 -- ^ __sum_indices__: 2-D.  The `indices` of the sum `SparseTensor`, size
                                             -- `[nnz(sum), ndims]`.
                 -> (Tensor Value t, Tensor Value t)
                 -- ^ (__a_val_grad__, __b_val_grad__)
                 --
                 -- * __a_val_grad__: 1-D with shape `[nnz(A)]`. The gradient with respect to the
                 -- non-empty values of A.
                 --
                 -- * __b_val_grad__: 1-D with shape `[nnz(B)]`. The gradient with respect to the
                 -- non-empty values of B.
sparseAddGrad backprop_val_grad a_indices b_indices
              sum_indices | eqLengthGuard [] =
    buildOp (opDef "SparseAddGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        backprop_val_grad a_indices b_indices sum_indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D with shape `[nnz(sum)]`.  The gradient with respect to\nthe non-empty values of the sum."
  name: "backprop_val_grad"
  type_attr: "T"
}
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor` A, size `[nnz(A), ndims]`."
  name: "a_indices"
  type: DT_INT64
}
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor` B, size `[nnz(B), ndims]`."
  name: "b_indices"
  type: DT_INT64
}
input_arg {
  description: "2-D.  The `indices` of the sum `SparseTensor`, size\n`[nnz(sum), ndims]`."
  name: "sum_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D with shape `[nnz(A)]`. The gradient with respect to the\nnon-empty values of A."
  name: "a_val_grad"
  type_attr: "T"
}
output_arg {
  description: "1-D with shape `[nnz(B)]`. The gradient with respect to the\nnon-empty values of B."
  name: "b_val_grad"
  type_attr: "T"
}
-}

-- | Computes fingerprints of the input strings.

sdcaFprint :: Tensor v1 Data.ByteString.ByteString -- ^ __input__: vector of strings to compute fingerprints on.
              -> Tensor Value Data.Int.Int64 -- ^ __output__: a (N,2) shaped matrix where N is the number of elements in the input
              -- vector. Each row contains the low and high parts of the fingerprint.
sdcaFprint input | eqLengthGuard [] =
    buildOp (opDef "SdcaFprint")
        input
{-
input_arg {
  description: "vector of strings to compute fingerprints on."
  name: "input"
  type: DT_STRING
}
output_arg {
  description: "a (N,2) shaped matrix where N is the number of elements in the input\nvector. Each row contains the low and high parts of the fingerprint."
  name: "output"
  type: DT_INT64
}
-}

-- | 

tensorArrayUnpack :: forall v2 v3 t . (TensorType t) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                     -> Tensor v2 t -- ^ __value__
                     -> Tensor v3 Float -- ^ __flow_in__
                     -> Build (Tensor Value Float) -- ^ __flow_out__
tensorArrayUnpack handle value flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayUnpack"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle value flow_in
{-
attr { name: "T" type: "type" }
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "value" type_attr: "T" }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "flow_out" type: DT_FLOAT }
-}

-- | Produces the average pool of the input tensor for quantized types.

quantizedAvgPool :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8] t) =>
                    Tensor v1 t -- ^ __input__: 4-D with shape `[batch, height, width, channels]`.
                    -> Tensor v2 Float -- ^ __min_input__: The float value that the lowest quantized input value represents.
                    -> Tensor v3 Float -- ^ __max_input__: The float value that the highest quantized input value represents.
                    -> (Tensor Value t, Tensor Value Float, Tensor Value Float)
                    -- ^ (__output__, __min_output__, __max_output__)
                    --
                    -- * __output__
                    --
                    -- * __min_output__: The float value that the lowest quantized output value represents.
                    --
                    -- * __max_output__: The float value that the highest quantized output value represents.
quantizedAvgPool input min_input max_input | eqLengthGuard [] =
    buildOp (opDef "QuantizedAvgPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        input min_input max_input
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "The size of the window for each dimension of the input tensor.\nThe length must be 4 to match the number of dimensions of the input."
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the input\ntensor.  The length must be 4 to match the number of dimensions of the input."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "The float value that the lowest quantized input value represents."
  name: "min_input"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized input value represents."
  name: "max_input"
  type: DT_FLOAT
}
output_arg { name: "output" type_attr: "T" }
output_arg {
  description: "The float value that the lowest quantized output value represents."
  name: "min_output"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized output value represents."
  name: "max_output"
  type: DT_FLOAT
}
-}

-- | Adjust the contrast of one or more images.
--
-- `images` is a tensor of at least 3 dimensions.  The last 3 dimensions are
-- interpreted as `[height, width, channels]`.  The other dimensions only
-- represent a collection of images, such as `[batch, height, width, channels].`
-- 
-- Contrast is adjusted independently for each channel of each image.
-- 
-- For each channel, the Op first computes the mean of the image pixels in the
-- channel and then adjusts each component of each pixel to
-- `(x - mean) * contrast_factor + mean`.
adjustContrastv2 :: Tensor v1 Float -- ^ __images__: Images to adjust.  At least 3-D.
                    -> Tensor v2 Float -- ^ __contrast_factor__: A float multiplier for adjusting contrast.
                    -> Tensor Value Float -- ^ __output__: The contrast-adjusted image or images.
adjustContrastv2 images contrast_factor | eqLengthGuard [] =
    buildOp (opDef "AdjustContrastv2")
        images contrast_factor
{-
input_arg {
  description: "Images to adjust.  At least 3-D."
  name: "images"
  type: DT_FLOAT
}
input_arg {
  description: "A float multiplier for adjusting contrast."
  name: "contrast_factor"
  type: DT_FLOAT
}
output_arg {
  description: "The contrast-adjusted image or images."
  name: "output"
  type: DT_FLOAT
}
-}

-- | Gather slices from the variable pointed to by `resource` according to `indices`.
--
-- `indices` must be an integer tensor of any dimension (usually 0-D or 1-D).
-- Produces an output tensor with shape `indices.shape + params.shape[1:]` where:
-- 
-- ```python
--     # Scalar indices
--     output[:, ..., :] = params[indices, :, ... :]
-- 
--     # Vector indices
--     output[i, :, ..., :] = params[indices[i], :, ... :]
-- 
--     # Higher rank indices
--     output[i, ..., j, :, ... :] = params[indices[i, ..., j], :, ..., :]
-- ```
resourceGather :: forall v2 dtype tindices . (TensorType dtype,
                                              TensorType tindices,
                                              OneOf '[Data.Int.Int32,
                                                      Data.Int.Int64] tindices) =>
                  ResourceHandle dtype -- ^ __resource__
                  -> Tensor v2 tindices -- ^ __indices__
                  -> Build (Tensor Value dtype) -- ^ __output__
resourceGather resource indices | eqLengthGuard [] =
    buildOp (opDef "ResourceGather"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        resource indices
{-
attr {
  default_value { b: true } name: "validate_indices" type: "bool"
}
attr { name: "dtype" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "resource" type: DT_RESOURCE }
input_arg { name: "indices" type_attr: "Tindices" }
output_arg { name: "output" type_attr: "dtype" }
-}

-- | Merges summaries.
--
-- This op creates a
-- [`Summary`](https://www.tensorflow.org/code/tensorflow/core/framework/summary.proto)
-- protocol buffer that contains the union of all the values in the input
-- summaries.
-- 
-- When the Op is run, it reports an `InvalidArgument` error if multiple values
-- in the summaries to merge use the same tag.
mergeSummary :: [Tensor v1 Data.ByteString.ByteString] -- ^ __inputs__: Can be of any shape.  Each must contain serialized `Summary` protocol
                                                       -- buffers.
                -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar. Serialized `Summary` protocol buffer.
mergeSummary inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "MergeSummary"
             & opAttr "N" .~ n)
        inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
input_arg {
  description: "Can be of any shape.  Each must contain serialized `Summary` protocol\nbuffers."
  name: "inputs"
  number_attr: "N"
  type: DT_STRING
}
output_arg {
  description: "Scalar. Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Serialize a `SparseTensor` into a string 3-vector (1-D `Tensor`) object.

serializeSparse :: forall v1 v2 v3 t . (TensorType t) =>
                   Tensor v1 Data.Int.Int64 -- ^ __sparse_indices__: 2-D.  The `indices` of the `SparseTensor`.
                   -> Tensor v2 t -- ^ __sparse_values__: 1-D.  The `values` of the `SparseTensor`.
                   -> Tensor v3 Data.Int.Int64 -- ^ __sparse_shape__: 1-D.  The `shape` of the `SparseTensor`.
                   -> Tensor Value Data.ByteString.ByteString -- ^ __serialized_sparse__
serializeSparse sparse_indices sparse_values sparse_shape | eqLengthGuard [] =
    buildOp (opDef "SerializeSparse"
             & opAttr "T" .~ tensorType (undefined :: t))
        sparse_indices sparse_values sparse_shape
{-
attr { name: "T" type: "type" }
input_arg {
  description: "2-D.  The `indices` of the `SparseTensor`."
  name: "sparse_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the `SparseTensor`."
  name: "sparse_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the `SparseTensor`."
  name: "sparse_shape"
  type: DT_INT64
}
output_arg { name: "serialized_sparse" type: DT_STRING }
-}

-- | Training via negative sampling.

negTrain :: Data.Int.Int64 -- ^ __num_negative_samples__: Number of negative samples per example.
            -> Tensor Ref Float -- ^ __w_in__: input word embedding.
            -> Tensor Ref Float -- ^ __w_out__: output word embedding.
            -> Tensor v3 Data.Int.Int32 -- ^ __examples__: A vector of word ids.
            -> Tensor v4 Data.Int.Int32 -- ^ __labels__: A vector of word ids.
            -> Tensor v5 Float -- ^ __lr__
            -> Build (ControlNode)
negTrain num_negative_samples w_in w_out examples labels lr | eqLengthGuard [] =
    buildOp (opDef "NegTrain"
             & opAttr "num_negative_samples" .~ num_negative_samples)
        w_in w_out examples labels lr
{-
attr {
  description: "Count of words in the vocabulary."
  name: "vocab_count"
  type: "list(int)"
}
attr {
  description: "Number of negative samples per example."
  name: "num_negative_samples"
  type: "int"
}
input_arg {
  description: "input word embedding."
  is_ref: true
  name: "w_in"
  type: DT_FLOAT
}
input_arg {
  description: "output word embedding."
  is_ref: true
  name: "w_out"
  type: DT_FLOAT
}
input_arg {
  description: "A vector of word ids."
  name: "examples"
  type: DT_INT32
}
input_arg {
  description: "A vector of word ids." name: "labels" type: DT_INT32
}
input_arg { name: "lr" type: DT_FLOAT }
-}

-- | Delete the TensorArray from its resource container.  This enables
--
-- the user to close and release the resource in the middle of a step/run.
tensorArrayCloseV2 :: Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray (output of TensorArray or TensorArrayGrad).
                      -> ControlNode
tensorArrayCloseV2 handle | eqLengthGuard [] =
    buildOp (opDef "TensorArrayCloseV2")
        handle
{-
input_arg {
  description: "The handle to a TensorArray (output of TensorArray or TensorArrayGrad)."
  name: "handle"
  type: DT_STRING
}
-}

-- | Generates labels for candidate sampling with a learned unigram distribution.
--
-- See explanations of candidate sampling and the data formats at
-- go/candidate-sampling.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
threadUnsafeUnigramCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to randomly sample per batch.
                                       -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                                       -> Data.Int.Int64 -- ^ __range_max__: The sampler will sample integers from the interval [0, range_max).
                                       -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                                               -- candidates in a batch are unique. This requires some approximation to
                                               -- estimate the post-rejection sampling probabilities.
                                       -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                                   -- IDs of the num_true target_classes in the corresponding original label.
                                       -> (Tensor Value Data.Int.Int64,
                                           Tensor Value Float,
                                           Tensor Value Float)
                                       -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                                       --
                                       -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                                       -- the ID of a sampled candidate.
                                       --
                                       -- * __true_expected_count__: A batch_size * num_true matrix, representing
                                       -- the number of times each candidate is expected to occur in a batch
                                       -- of sampled candidates. If unique=true, then this is a probability.
                                       --
                                       -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                                       -- candidate representing the number of times the candidate is expected
                                       -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                                       -- probability.
threadUnsafeUnigramCandidateSampler num_sampled num_true range_max unique
                                    true_classes | eqLengthGuard [] =
    buildOp (opDef "ThreadUnsafeUnigramCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "range_max" .~ range_max
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to randomly sample per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  description: "The sampler will sample integers from the interval [0, range_max)."
  has_minimum: true
  minimum: 1
  name: "range_max"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Converts each string in the input Tensor to the specified numeric type.
--
-- (Note that int32 overflow results in an error while float overflow
-- results in a rounded value.)
stringToNumber :: forall v1 out_type . (TensorType out_type,
                                        OneOf '[Data.Int.Int32,
                                                Float] out_type) =>
                  Tensor v1 Data.ByteString.ByteString -- ^ __string_tensor__
                  -> Tensor Value out_type -- ^ __output__: A Tensor of the same shape as the input `string_tensor`.
stringToNumber string_tensor | eqLengthGuard [] =
    buildOp (opDef "StringToNumber"
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        string_tensor
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_INT32 } }
  default_value { type: DT_FLOAT }
  description: "The numeric type to interpret each string in `string_tensor` as."
  name: "out_type"
  type: "type"
}
input_arg { name: "string_tensor" type: DT_STRING }
output_arg {
  description: "A Tensor of the same shape as the input `string_tensor`."
  name: "output"
  type_attr: "out_type"
}
-}

-- | Performs beam search decoding on the logits given in input.
--
-- A note about the attribute merge_repeated: For the beam search decoder,
-- this means that if consecutive entries in a beam are the same, only
-- the first of these is emitted.  That is, when the top path is "A B B B B",
-- "A B" is returned if merge_repeated = True but "A B B B B" is
-- returned if merge_repeated = False.
cTCBeamSearchDecoder :: Data.Int.Int64 -- ^ __beam_width__: A scalar >= 0 (beam search beam width).
                        -> Data.Int.Int64 -- ^ __top_paths__: A scalar >= 0, <= beam_width (controls output size).
                        -> Tensor v1 Float -- ^ __inputs__: 3-D, shape: `(max_time x batch_size x num_classes)`, the logits.
                        -> Tensor v2 Data.Int.Int32 -- ^ __sequence_length__: A vector containing sequence lengths, size `(batch)`.
                        -> ([Tensor Value Data.Int.Int64],
                            [Tensor Value Data.Int.Int64],
                            [Tensor Value Data.Int.Int64], Tensor Value Float)
                        -- ^ (__decoded_indices__, __decoded_values__, __decoded_shape__, __log_probability__)
                        --
                        -- * __decoded_indices__: A list (length: top_paths) of indices matrices.  Matrix j,
                        -- size `(total_decoded_outputs[j] x 2)`, has indices of a
                        -- `SparseTensor<int64, 2>`.  The rows store: [batch, time].
                        --
                        -- * __decoded_values__: A list (length: top_paths) of values vectors.  Vector j,
                        -- size `(length total_decoded_outputs[j])`, has the values of a
                        -- `SparseTensor<int64, 2>`.  The vector stores the decoded classes for beam j.
                        --
                        -- * __decoded_shape__: A list (length: top_paths) of shape vector.  Vector j,
                        -- size `(2)`, stores the shape of the decoded `SparseTensor[j]`.
                        -- Its values are: `[batch_size, max_decoded_length[j]]`.
                        --
                        -- * __log_probability__: A matrix, shaped: `(batch_size x top_paths)`.  The
                        -- sequence log-probabilities.
cTCBeamSearchDecoder beam_width top_paths inputs
                     sequence_length | eqLengthGuard [] =
    buildListOp [top_paths, top_paths, top_paths] (opDef "CTCBeamSearchDecoder"
                                                   & opAttr "beam_width" .~ beam_width
                                                   & opAttr "top_paths" .~ top_paths)
        inputs sequence_length
{-
attr {
  description: "A scalar >= 0 (beam search beam width)."
  has_minimum: true
  minimum: 1
  name: "beam_width"
  type: "int"
}
attr {
  description: "A scalar >= 0, <= beam_width (controls output size)."
  has_minimum: true
  minimum: 1
  name: "top_paths"
  type: "int"
}
attr {
  default_value { b: true }
  description: "If true, merge repeated classes in output."
  name: "merge_repeated"
  type: "bool"
}
input_arg {
  description: "3-D, shape: `(max_time x batch_size x num_classes)`, the logits."
  name: "inputs"
  type: DT_FLOAT
}
input_arg {
  description: "A vector containing sequence lengths, size `(batch)`."
  name: "sequence_length"
  type: DT_INT32
}
output_arg {
  description: "A list (length: top_paths) of indices matrices.  Matrix j,\nsize `(total_decoded_outputs[j] x 2)`, has indices of a\n`SparseTensor<int64, 2>`.  The rows store: [batch, time]."
  name: "decoded_indices"
  number_attr: "top_paths"
  type: DT_INT64
}
output_arg {
  description: "A list (length: top_paths) of values vectors.  Vector j,\nsize `(length total_decoded_outputs[j])`, has the values of a\n`SparseTensor<int64, 2>`.  The vector stores the decoded classes for beam j."
  name: "decoded_values"
  number_attr: "top_paths"
  type: DT_INT64
}
output_arg {
  description: "A list (length: top_paths) of shape vector.  Vector j,\nsize `(2)`, stores the shape of the decoded `SparseTensor[j]`.\nIts values are: `[batch_size, max_decoded_length[j]]`."
  name: "decoded_shape"
  number_attr: "top_paths"
  type: DT_INT64
}
output_arg {
  description: "A matrix, shaped: `(batch_size x top_paths)`.  The\nsequence log-probabilities."
  name: "log_probability"
  type: DT_FLOAT
}
-}

-- | Transforms a serialized tensorflow.TensorProto proto into a Tensor.

parseTensor :: forall v1 out_type . (TensorType out_type) =>
               Tensor v1 Data.ByteString.ByteString -- ^ __serialized__: A scalar string containing a serialized TensorProto proto.
               -> Tensor Value out_type -- ^ __output__: A Tensor of type `out_type`.
parseTensor serialized | eqLengthGuard [] =
    buildOp (opDef "ParseTensor"
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        serialized
{-
attr {
  description: "The type of the serialized tensor.  The provided type must match the\ntype of the serialized tensor and no implicit conversion will take place."
  name: "out_type"
  type: "type"
}
input_arg {
  description: "A scalar string containing a serialized TensorProto proto."
  name: "serialized"
  type: DT_STRING
}
output_arg {
  description: "A Tensor of type `out_type`."
  name: "output"
  type_attr: "out_type"
}
-}

-- | Outputs a `Summary` protocol buffer with images.
--
-- The summary has up to `max_images` summary values containing images. The
-- images are built from `tensor` which must be 4-D with shape `[batch_size,
-- height, width, channels]` and where `channels` can be:
-- 
-- *  1: `tensor` is interpreted as Grayscale.
-- *  3: `tensor` is interpreted as RGB.
-- *  4: `tensor` is interpreted as RGBA.
-- 
-- The images have the same number of channels as the input tensor. For float
-- input, the values are normalized one image at a time to fit in the range
-- `[0, 255]`.  `uint8` values are unchanged.  The op uses two different
-- normalization algorithms:
-- 
-- *  If the input values are all positive, they are rescaled so the largest one
--    is 255.
-- 
-- *  If any input value is negative, the values are shifted so input value 0.0
--    is at 127.  They are then rescaled so that either the smallest value is 0,
--    or the largest one is 255.
-- 
-- The `tag` argument is a scalar `Tensor` of type `string`.  It is used to
-- build the `tag` of the summary values:
-- 
-- *  If `max_images` is 1, the summary value tag is '*tag*/image'.
-- *  If `max_images` is greater than 1, the summary value tags are
--    generated sequentially as '*tag*/image/0', '*tag*/image/1', etc.
-- 
-- The `bad_color` argument is the color to use in the generated images for
-- non-finite input values.  It is a `unit8` 1-D tensor of length `channels`.
-- Each element must be in the range `[0, 255]` (It represents the value of a
-- pixel in the output image).  Non-finite values in the input tensor are
-- replaced by this tensor in the output image.  The default value is the color
-- red.
imageSummary :: forall v1 v2 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                        Data.Word.Word8,
                                                        Float] t) =>
                Tensor v1 Data.ByteString.ByteString -- ^ __tag__: Scalar. Used to build the `tag` attribute of the summary values.
                -> Tensor v2 t -- ^ __tensor__: 4-D of shape `[batch_size, height, width, channels]` where
                               -- `channels` is 1, 3, or 4.
                -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar. Serialized `Summary` protocol buffer.
imageSummary tag tensor | eqLengthGuard [] =
    buildOp (opDef "ImageSummary"
             & opAttr "T" .~ tensorType (undefined :: t))
        tag tensor
{-
attr {
  default_value { i: 3 }
  description: "Max number of batch elements to generate images for."
  has_minimum: true
  minimum: 1
  name: "max_images"
  type: "int"
}
attr {
  allowed_values {
    list { type: DT_UINT8 type: DT_FLOAT type: DT_HALF }
  }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
attr {
  default_value {
    tensor {
      dtype: DT_UINT8
      int_val: 255
      int_val: 0
      int_val: 0
      int_val: 255
      tensor_shape { dim { size: 4 } }
    }
  }
  description: "Color to use for pixels with non-finite values."
  name: "bad_color"
  type: "tensor"
}
input_arg {
  description: "Scalar. Used to build the `tag` attribute of the summary values."
  name: "tag"
  type: DT_STRING
}
input_arg {
  description: "4-D of shape `[batch_size, height, width, channels]` where\n`channels` is 1, 3, or 4."
  name: "tensor"
  type_attr: "T"
}
output_arg {
  description: "Scalar. Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Returns x / y element-wise for integer types.
--
-- Truncation designates that negative numbers will round fractional quantities
-- toward zero. I.e. -7 / 5 = 1. This matches C semantics but it is different
-- than Python semantics. See `FloorDiv` for a division function that matches
-- Python Semantics.
-- 
-- *NOTE*: `TruncateDiv` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
truncateDiv :: forall v1 v2 t . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Int.Int16, Data.Int.Int32,
                                         Data.Int.Int64, Data.Int.Int8,
                                         Data.Word.Word16, Data.Word.Word8,
                                         Double, Float] t) =>
               Tensor v1 t -- ^ __x__
               -> Tensor v2 t -- ^ __y__
               -> Tensor Value t -- ^ __z__
truncateDiv x y | eqLengthGuard [] =
    buildOp (opDef "TruncateDiv"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes the Cholesky decomposition of one or more square matrices.
--
-- The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-- form square matrices, with the same constraints as the single matrix Cholesky
-- decomposition above. The output is a tensor of the same shape as the input
-- containing the Cholesky decompositions for all input submatrices `[..., :, :]`.
cholesky :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
            Tensor v1 t -- ^ __input__: Shape is `[..., M, M]`.
            -> Tensor Value t -- ^ __output__: Shape is `[..., M, M]`.
cholesky input | eqLengthGuard [] =
    buildOp (opDef "Cholesky"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`." name: "input" type_attr: "T"
}
output_arg {
  description: "Shape is `[..., M, M]`."
  name: "output"
  type_attr: "T"
}
-}

-- | 

batchMatrixSolveLs :: forall v1 v2 v3 t . (TensorType t, OneOf '[Double,
                                                                 Float] t) =>
                      Tensor v1 t -- ^ __matrix__
                      -> Tensor v2 t -- ^ __rhs__
                      -> Tensor v3 Double -- ^ __l2_regularizer__
                      -> Tensor Value t -- ^ __output__
batchMatrixSolveLs matrix rhs l2_regularizer | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixSolveLs"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs l2_regularizer
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
attr { default_value { b: true } name: "fast" type: "bool" }
input_arg { name: "matrix" type_attr: "T" }
input_arg { name: "rhs" type_attr: "T" }
input_arg { name: "l2_regularizer" type: DT_DOUBLE }
output_arg { name: "output" type_attr: "T" }
-}

-- | Outputs all keys and values in the table.

lookupTableExport :: forall tkeys tvalues . (TensorType tkeys,
                                             TensorType tvalues) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to the table.
                     -> Build ((Tensor Value tkeys, Tensor Value tvalues))
                     -- ^ (__keys__, __values__)
                     --
                     -- * __keys__: Vector of all keys present in the table.
                     --
                     -- * __values__: Tensor of all values in the table. Indexed in parallel with `keys`.
lookupTableExport table_handle | eqLengthGuard [] =
    buildOp (opDef "LookupTableExport"
             & opAttr "Tkeys" .~ tensorType (undefined :: tkeys)
             & opAttr "Tvalues" .~ tensorType (undefined :: tvalues))
        table_handle
{-
attr { name: "Tkeys" type: "type" }
attr { name: "Tvalues" type: "type" }
input_arg {
  description: "Handle to the table."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
output_arg {
  description: "Vector of all keys present in the table."
  name: "keys"
  type_attr: "Tkeys"
}
output_arg {
  description: "Tensor of all values in the table. Indexed in parallel with `keys`."
  name: "values"
  type_attr: "Tvalues"
}
-}

-- | 

batchSvd :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Double, Float] t) =>
            Tensor v1 t -- ^ __input__
            -> (Tensor Value t, Tensor Value t, Tensor Value t)
            -- ^ (__s__, __u__, __v__)
            --
            -- * __s__
            --
            -- * __u__
            --
            -- * __v__
batchSvd input | eqLengthGuard [] =
    buildOp (opDef "BatchSvd"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { default_value { b: true } name: "compute_uv" type: "bool" }
attr {
  default_value { b: false } name: "full_matrices" type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_DOUBLE
      type: DT_FLOAT
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "s" type_attr: "T" }
output_arg { name: "u" type_attr: "T" }
output_arg { name: "v" type_attr: "T" }
-}

-- | Resize `images` to `size` using bicubic interpolation.
--
-- Input images can be of different types but output images are always float.
resizeBicubic :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Int.Int64,
                                                         Data.Int.Int8,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8,
                                                         Double, Float] t) =>
                 Tensor v1 t -- ^ __images__: 4-D with shape `[batch, height, width, channels]`.
                 -> Tensor v2 Data.Int.Int32 -- ^ __size__: = A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The
                                             -- new size for the images.
                 -> Tensor Value Float -- ^ __resized_images__: 4-D with shape
                 -- `[batch, new_height, new_width, channels]`.
resizeBicubic images size | eqLengthGuard [] =
    buildOp (opDef "ResizeBicubic"
             & opAttr "T" .~ tensorType (undefined :: t))
        images size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale input by (new_height - 1) / (height - 1), which\nexactly aligns the 4 corners of images and resized images. If false, rescale\nby new_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "images"
  type_attr: "T"
}
input_arg {
  description: "= A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The\nnew size for the images."
  name: "size"
  type: DT_INT32
}
output_arg {
  description: "4-D with shape\n`[batch, new_height, new_width, channels]`."
  name: "resized_images"
  type: DT_FLOAT
}
-}

-- | Convert one or more images from HSV to RGB.
--
-- Outputs a tensor of the same shape as the `images` tensor, containing the RGB
-- value of the pixels. The output is only well defined if the value in `images`
-- are in `[0,1]`.
-- 
-- See `rgb_to_hsv` for a description of the HSV encoding.
hSVToRGB :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
            Tensor v1 t -- ^ __images__: 1-D or higher rank. HSV data to convert. Last dimension must be size 3.
            -> Tensor Value t -- ^ __output__: `images` converted to RGB.
hSVToRGB images | eqLengthGuard [] =
    buildOp (opDef "HSVToRGB"
             & opAttr "T" .~ tensorType (undefined :: t))
        images
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D or higher rank. HSV data to convert. Last dimension must be size 3."
  name: "images"
  type_attr: "T"
}
output_arg {
  description: "`images` converted to RGB."
  name: "output"
  type_attr: "T"
}
-}

-- | Performs 3D average pooling on the input.

avgPool3D :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
             Tensor v1 t -- ^ __input__: Shape `[batch, depth, rows, cols, channels]` tensor to pool over.
             -> Tensor Value t -- ^ __output__: The average pooled output tensor.
avgPool3D input | eqLengthGuard [] =
    buildOp (opDef "AvgPool3D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  description: "1-D tensor of length 5. The size of the window for each dimension of\nthe input tensor. Must have `ksize[0] = ksize[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape `[batch, depth, rows, cols, channels]` tensor to pool over."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The average pooled output tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | Delete the stack from its resource container.

stackClose :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a stack.
              -> Build (ControlNode)
stackClose handle | eqLengthGuard [] =
    buildOp (opDef "StackClose")
        handle
{-
input_arg {
  description: "The handle to a stack."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Assigns a new value to a variable.
--
-- Any ReadVariableOp with a control dependency on this op is guaranteed to return
-- this value or a subsequent newer value of the variable.
assignVariableOp :: forall v2 dtype . (TensorType dtype) =>
                    ResourceHandle dtype -- ^ __resource__: handle to the resource in which to store the variable.
                    -> Tensor v2 dtype -- ^ __value__: the value to set the new tensor to use.
                    -> Build (ControlNode)
assignVariableOp resource value | eqLengthGuard [] =
    buildOp (opDef "AssignVariableOp"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        resource value
{-
attr {
  description: "the dtype of the value." name: "dtype" type: "type"
}
input_arg {
  description: "handle to the resource in which to store the variable."
  name: "resource"
  type: DT_RESOURCE
}
input_arg {
  description: "the value to set the new tensor to use."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Local Response Normalization.
--
-- The 4-D `input` tensor is treated as a 3-D array of 1-D vectors (along the last
-- dimension), and each vector is normalized independently.  Within a given vector,
-- each component is divided by the weighted, squared sum of inputs within
-- `depth_radius`.  In detail,
-- 
--     sqr_sum[a, b, c, d] =
--         sum(input[a, b, c, d - depth_radius : d + depth_radius + 1] ** 2)
--     output = input / (bias + alpha * sqr_sum) ** beta
-- 
-- For details, see [Krizhevsky et al., ImageNet classification with deep
-- convolutional neural networks (NIPS 2012)](http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks).
lRN :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Float] t) =>
       Tensor v1 t -- ^ __input__: 4-D.
       -> Tensor Value t -- ^ __output__
lRN input | eqLengthGuard [] =
    buildOp (opDef "LRN"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  default_value { i: 5 }
  description: "0-D.  Half-width of the 1-D normalization window."
  name: "depth_radius"
  type: "int"
}
attr {
  default_value { f: 1.0 }
  description: "An offset (usually positive to avoid dividing by 0)."
  name: "bias"
  type: "float"
}
attr {
  default_value { f: 1.0 }
  description: "A scale factor, usually positive."
  name: "alpha"
  type: "float"
}
attr {
  default_value { f: 0.5 }
  description: "An exponent."
  name: "beta"
  type: "float"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg { description: "4-D." name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Compute the Hurwitz zeta function \\(\zeta(x, q)\\).
--
-- The Hurwitz zeta function is defined as:
-- 
-- ```
-- \zeta(x, q) = \sum_{n=0}^{\infty} (q + n)^{-x}
-- ```
zeta :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
        Tensor v1 t -- ^ __x__
        -> Tensor v2 t -- ^ __q__
        -> Tensor Value t -- ^ __z__
zeta x q | eqLengthGuard [] =
    buildOp (opDef "Zeta"
             & opAttr "T" .~ tensorType (undefined :: t))
        x q
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "q" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Creates a TensorArray for storing the gradients of values in the given handle.
--
-- If the given TensorArray gradient already exists, returns a reference to it.
-- 
-- Locks the size of the original TensorArray by disabling its dynamic size flag.
-- 
-- **A note about the input flow_in:**
-- 
-- The handle flow_in forces the execution of the gradient lookup to occur
-- only after certain other operations have occurred.  For example, when
-- the forward TensorArray is dynamically sized, writes to this TensorArray
-- may resize the object.  The gradient TensorArray is statically sized based
-- on the size of the forward TensorArray when this operation executes.
-- Furthermore, the size of the forward TensorArray is frozen by this call.
-- As a result, the flow is used to ensure that the call to generate the gradient
-- TensorArray only happens after all writes are executed.
-- 
-- In the case of dynamically sized TensorArrays, gradient computation should
-- only be performed on read operations that have themselves been chained via
-- flow to occur only after all writes have executed. That way the final size
-- of the forward TensorArray is known when this operation is called.
-- 
-- **A note about the source attribute:**
-- 
-- TensorArray gradient calls use an accumulator TensorArray object.  If
-- multiple gradients are calculated and run in the same session, the multiple
-- gradient nodes may accidentally flow throuth the same accumulator TensorArray.
-- This double counts and generally breaks the TensorArray gradient flow.
-- 
-- The solution is to identify which gradient call this particular
-- TensorArray gradient is being called in.  This is performed by identifying
-- a unique string (e.g. "gradients", "gradients_1", ...) from the input
-- gradient Tensor's name.  This string is used as a suffix when creating
-- the TensorArray gradient object here (the attribute `source`).
-- 
-- The attribute `source` is added as a suffix to the forward TensorArray's
-- name when performing the creation / lookup, so that each separate gradient
-- calculation gets its own TensorArray accumulator.
tensorArrayGradV2 :: Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to the forward TensorArray.
                     -> Tensor v2 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                     -> Build (Tensor Value Data.ByteString.ByteString) -- ^ __grad_handle__
tensorArrayGradV2 handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayGradV2")
        handle flow_in
{-
attr {
  description: "The gradient source string, used to decide which gradient TensorArray\nto return."
  name: "source"
  type: "string"
}
input_arg {
  description: "The handle to the forward TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg { name: "grad_handle" type: DT_STRING }
-}

-- | Cast x of type SrcT to y of DstT.

cast :: forall v1 srcT dstT . (TensorType srcT, TensorType dstT) =>
        Tensor v1 srcT -- ^ __x__
        -> Tensor Value dstT -- ^ __y__
cast x | eqLengthGuard [] =
    buildOp (opDef "Cast"
             & opAttr "SrcT" .~ tensorType (undefined :: srcT)
             & opAttr "DstT" .~ tensorType (undefined :: dstT))
        x
{-
attr { name: "SrcT" type: "type" }
attr { name: "DstT" type: "type" }
input_arg { name: "x" type_attr: "SrcT" }
output_arg { name: "y" type_attr: "DstT" }
-}

-- | Computes the Gauss error function of `x` element-wise.

erf :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                            Float] t) => Tensor v1 t -- ^ __x__
       -> Tensor Value t -- ^ __y__
erf x | eqLengthGuard [] =
    buildOp (opDef "Erf"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | 

batchMatrixTriangularSolve :: forall v1 v2 t . (TensorType t, OneOf '[Double,
                                                                      Float] t) =>
                              Tensor v1 t -- ^ __matrix__
                              -> Tensor v2 t -- ^ __rhs__
                              -> Tensor Value t -- ^ __output__
batchMatrixTriangularSolve matrix rhs | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixTriangularSolve"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs
{-
attr { default_value { b: true } name: "lower" type: "bool" }
attr { default_value { b: false } name: "adjoint" type: "bool" }
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "matrix" type_attr: "T" }
input_arg { name: "rhs" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Adds sparse updates to the variable referenced by `resource`.
--
-- This operation computes
-- 
--     # Scalar indices
--     ref[indices, ...] += updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] += updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] += updates[i, ..., j, ...]
-- 
-- Duplicate entries are handled correctly: if multiple `indices` reference
-- the same location, their contributions add.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterAdd.png" alt>
-- </div>
resourceScatterAdd :: forall v2 v3 dtype tindices . (TensorType dtype,
                                                     OneOf '[(Data.Complex.Complex Double),
                                                             (Data.Complex.Complex Float),
                                                             Data.Int.Int16,
                                                             Data.Int.Int32,
                                                             Data.Int.Int64,
                                                             Data.Int.Int8,
                                                             Data.Word.Word16,
                                                             Data.Word.Word8,
                                                             Double,
                                                             Float] dtype,
                                                     TensorType tindices,
                                                     OneOf '[Data.Int.Int32,
                                                             Data.Int.Int64] tindices) =>
                      ResourceHandle dtype -- ^ __resource__: Should be from a `Variable` node.
                      -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
                      -> Tensor v3 dtype -- ^ __updates__: A tensor of updated values to add to `ref`.
                      -> Build (ControlNode)
resourceScatterAdd resource indices updates | eqLengthGuard [] =
    buildOp (opDef "ResourceScatterAdd"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        resource indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "dtype"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg {
  description: "Should be from a `Variable` node."
  name: "resource"
  type: DT_RESOURCE
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of updated values to add to `ref`."
  name: "updates"
  type_attr: "dtype"
}
-}

-- | 

batchCholeskyGrad :: forall v1 v2 t . (TensorType t, OneOf '[Double,
                                                             Float] t) =>
                     Tensor v1 t -- ^ __l__
                     -> Tensor v2 t -- ^ __grad__
                     -> Tensor Value t -- ^ __output__
batchCholeskyGrad l grad | eqLengthGuard [] =
    buildOp (opDef "BatchCholeskyGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        l grad
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "l" type_attr: "T" }
input_arg { name: "grad" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | 

batchMatrixInverse :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                      Tensor v1 t -- ^ __input__
                      -> Tensor Value t -- ^ __output__
batchMatrixInverse input | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixInverse"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { default_value { b: false } name: "adjoint" type: "bool" }
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Return the same ref tensor as the input ref tensor.

refIdentity :: forall t . (TensorType t) => Tensor Ref t -- ^ __input__
               -> Build (Tensor Ref t) -- ^ __output__
refIdentity input | eqLengthGuard [] =
    buildOp (opDef "RefIdentity"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg { is_ref: true name: "input" type_attr: "T" }
output_arg { is_ref: true name: "output" type_attr: "T" }
-}

-- | Computes the singular value decompositions of one or more matrices.
--
-- Computes the SVD of each inner matrix in `input` such that
-- `input[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, :])`
-- 
-- ```prettyprint
-- # a is a tensor containing a batch of matrices.
-- # s is a tensor of singular values for each matrix.
-- # u is the tensor containing of left singular vectors for each matrix.
-- # v is the tensor containing of right singular vectors for each matrix.
-- s, u, v = svd(a)
-- s, _, _ = svd(a, compute_uv=False)
-- ```
svd :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                            (Data.Complex.Complex Float),
                                            Double, Float] t) =>
       Tensor v1 t -- ^ __input__: A tensor of shape `[..., M, N]` whose inner-most 2 dimensions
                   -- form matrices of size `[M, N]`. Let `P` be the minimum of `M` and `N`.
       -> (Tensor Value t, Tensor Value t, Tensor Value t)
       -- ^ (__s__, __u__, __v__)
       --
       -- * __s__: Singular values. Shape is `[..., P]`.
       --
       -- * __u__: Left singular vectors. If `full_matrices` is `False` then shape is
       -- `[..., M, M]`; if `full_matrices` is `True` then shape is
       -- `[..., M, P]`. Undefined if `compute_uv` is `False`.
       --
       -- * __v__: Left singular vectors. If `full_matrices` is `False` then shape is
       -- `[..., N, N]`. If `full_matrices` is `True` then shape is `[..., N, P]`.
       -- Undefined if `compute_uv` is false.
svd input | eqLengthGuard [] =
    buildOp (opDef "Svd"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  default_value { b: true }
  description: "If true, left and right singular vectors will be\ncomputed and returned in `u` and `v`, respectively.\nIf false, `u` and `v` are not set and should never referenced."
  name: "compute_uv"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If true, compute full-sized `u` and `v`. If false\n(the default), compute only the leading `P` singular vectors.\nIgnored if `compute_uv` is `False`."
  name: "full_matrices"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_DOUBLE
      type: DT_FLOAT
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "A tensor of shape `[..., M, N]` whose inner-most 2 dimensions\nform matrices of size `[M, N]`. Let `P` be the minimum of `M` and `N`."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "Singular values. Shape is `[..., P]`."
  name: "s"
  type_attr: "T"
}
output_arg {
  description: "Left singular vectors. If `full_matrices` is `False` then shape is\n`[..., M, M]`; if `full_matrices` is `True` then shape is\n`[..., M, P]`. Undefined if `compute_uv` is `False`."
  name: "u"
  type_attr: "T"
}
output_arg {
  description: "Left singular vectors. If `full_matrices` is `False` then shape is\n`[..., N, N]`. If `full_matrices` is `True` then shape is `[..., N, P]`.\nUndefined if `compute_uv` is false."
  name: "v"
  type_attr: "T"
}
-}

-- | Solves one or more linear least-squares problems.
--
-- `matrix` is a tensor of shape `[..., M, N]` whose inner-most 2 dimensions
-- form matrices of size `[M, N]`. Rhs is a tensor of shape `[..., M, K]`.
-- The output is a tensor shape `[..., N, K]` where each output matrix solves
-- each of the equations matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]
-- in the least squares sense.
-- 
-- matrix and right-hand sides in the batch:
-- 
-- `matrix`=\\(A \in \Re^{m \times n}\\),
-- `rhs`=\\(B  \in \Re^{m \times k}\\),
-- `output`=\\(X  \in \Re^{n \times k}\\),
-- `l2_regularizer`=\\(\lambda\\).
-- 
-- If `fast` is `True`, then the solution is computed by solving the normal
-- equations using Cholesky decomposition. Specifically, if \\(m \ge n\\) then
-- \\(X = (A^T A + \lambda I)^{-1} A^T B\\), which solves the least-squares
-- problem \\(X = \mathrm{argmin}_{Z \in \Re^{n \times k}} ||A Z - B||_F^2 +
-- \lambda ||Z||_F^2\\). If \\(m \lt n\\) then `output` is computed as
-- \\(X = A^T (A A^T + \lambda I)^{-1} B\\), which (for \\(\lambda = 0\\)) is the
-- minimum-norm solution to the under-determined linear system, i.e.
-- \\(X = \mathrm{argmin}_{Z \in \Re^{n \times k}} ||Z||_F^2 \\), subject to
-- \\(A Z = B\\). Notice that the fast path is only numerically stable when
-- \\(A\\) is numerically full rank and has a condition number
-- \\(\mathrm{cond}(A) \lt \frac{1}{\sqrt{\epsilon_{mach}}}\\) or\\(\lambda\\) is
-- sufficiently large.
-- 
-- If `fast` is `False` an algorithm based on the numerically robust complete
-- orthogonal decomposition is used. This computes the minimum-norm
-- least-squares solution, even when \\(A\\) is rank deficient. This path is
-- typically 6-7 times slower than the fast path. If `fast` is `False` then
-- `l2_regularizer` is ignored.
matrixSolveLs :: forall v1 v2 v3 t . (TensorType t, OneOf '[Double, Float] t) =>
                 Tensor v1 t -- ^ __matrix__: Shape is `[..., M, N]`.
                 -> Tensor v2 t -- ^ __rhs__: Shape is `[..., M, K]`.
                 -> Tensor v3 Double -- ^ __l2_regularizer__: Scalar tensor.
                                     -- 
                                     -- @compatibility(numpy)
                                     -- Equivalent to np.linalg.lstsq
                                     -- @end_compatibility
                 -> Tensor Value t -- ^ __output__: Shape is `[..., N, K]`.
matrixSolveLs matrix rhs l2_regularizer | eqLengthGuard [] =
    buildOp (opDef "MatrixSolveLs"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs l2_regularizer
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
attr { default_value { b: true } name: "fast" type: "bool" }
input_arg {
  description: "Shape is `[..., M, N]`."
  name: "matrix"
  type_attr: "T"
}
input_arg {
  description: "Shape is `[..., M, K]`." name: "rhs" type_attr: "T"
}
input_arg {
  description: "Scalar tensor.\n\n@compatibility(numpy)\nEquivalent to np.linalg.lstsq\n@end_compatibility"
  name: "l2_regularizer"
  type: DT_DOUBLE
}
output_arg {
  description: "Shape is `[..., N, K]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Packs a list of `N` rank-`R` tensors into one rank-`(R+1)` tensor.
--
-- Packs the `N` tensors in `values` into a tensor with rank one higher than each
-- tensor in `values`, by packing them along the `axis` dimension.
-- Given a list of tensors of shape `(A, B, C)`;
-- 
-- if `axis == 0` then the `output` tensor will have the shape `(N, A, B, C)`.
-- if `axis == 1` then the `output` tensor will have the shape `(A, N, B, C)`.
-- Etc.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'x' is [1, 4]
-- # 'y' is [2, 5]
-- # 'z' is [3, 6]
-- pack([x, y, z]) => [[1, 4], [2, 5], [3, 6]]  # Pack along first dim.
-- pack([x, y, z], axis=1) => [[1, 2, 3], [4, 5, 6]]
-- ```
-- 
-- This is the opposite of `unpack`.
pack :: forall v1 t . (TensorType t) =>
        [Tensor v1 t] -- ^ __values__: Must be of same shape and type.
        -> Tensor Value t -- ^ __output__: The packed tensor.
pack values | eqLengthGuard [("N", [("values", length values)])] =
    buildOp (opDef "Pack"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        values
  where
    n = fromIntegral (length values) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
attr { name: "T" type: "type" }
attr {
  default_value { i: 0 }
  description: "Dimension along which to pack.  Negative values wrap around, so the\nvalid range is `[-(R+1), R+1)`."
  name: "axis"
  type: "int"
}
input_arg {
  description: "Must be of same shape and type."
  name: "values"
  number_attr: "N"
  type_attr: "T"
}
output_arg {
  description: "The packed tensor." name: "output" type_attr: "T"
}
-}

-- | Closes the given barrier.
--
-- This operation signals that no more new elements will be inserted in the
-- given barrier. Subsequent InsertMany that try to introduce a new key will fail.
-- Subsequent InsertMany operations that just add missing components to already
-- existing elements will continue to succeed. Subsequent TakeMany operations will
-- continue to succeed if sufficient completed elements remain in the barrier.
-- Subsequent TakeMany operations that would block will fail immediately.
barrierClose :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a barrier.
                -> Build (ControlNode)
barrierClose handle | eqLengthGuard [] =
    buildOp (opDef "BarrierClose")
        handle
{-
attr {
  default_value { b: false }
  description: "If true, all pending enqueue requests that are\nblocked on the barrier\'s queue will be cancelled. InsertMany will fail, even\nif no new key is introduced."
  name: "cancel_pending_enqueues"
  type: "bool"
}
input_arg {
  description: "The handle to a barrier."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Computes the eigen decomposition of one or more square self-adjoint matrices.
--
-- Computes the eigenvalues and (optionally) eigenvectors of each inner matrix in
-- `input` such that `input[..., :, :] = v[..., :, :] * diag(e[..., :])`.
-- 
-- ```prettyprint
-- # a is a tensor.
-- # e is a tensor of eigenvalues.
-- # v is a tensor of eigenvectors.
-- e, v = self_adjoint_eig(a)
-- e = self_adjoint_eig(a, compute_v=False)
-- ```
selfAdjointEigV2 :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                    Tensor v1 t -- ^ __input__: `Tensor` input of shape `[N, N]`.
                    -> (Tensor Value t, Tensor Value t) -- ^ (__e__, __v__)
                    --
                    -- * __e__: Eigenvalues. Shape is `[N]`.
                    --
                    -- * __v__: Eigenvectors. Shape is `[N, N]`.
selfAdjointEigV2 input | eqLengthGuard [] =
    buildOp (opDef "SelfAdjointEigV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  default_value { b: true }
  description: "If `True` then eigenvectors will be computed and returned in `v`.\nOtherwise, only the eigenvalues will be computed."
  name: "compute_v"
  type: "bool"
}
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg {
  description: "`Tensor` input of shape `[N, N]`."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "Eigenvalues. Shape is `[N]`."
  name: "e"
  type_attr: "T"
}
output_arg {
  description: "Eigenvectors. Shape is `[N, N]`."
  name: "v"
  type_attr: "T"
}
-}

-- | Subtracts sparse updates to a variable reference.
--
--     # Scalar indices
--     ref[indices, ...] -= updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] -= updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] -= updates[i, ..., j, ...]
-- 
-- This operation outputs `ref` after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
-- 
-- Duplicate entries are handled correctly: if multiple `indices` reference
-- the same location, their (negated) contributions add.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterSub.png" alt>
-- </div>
scatterSub :: forall v2 v3 t tindices . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t, TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
              -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
              -> Tensor v3 t -- ^ __updates__: A tensor of updated values to subtract from `ref`.
              -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as `ref`.  Returned as a convenience for operations that want
              -- to use the updated values after the update is done.
scatterSub ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterSub"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the subtraction will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of updated values to subtract from `ref`."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "= Same as `ref`.  Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Computes the Eigen Decomposition of a batch of square self-adjoint matrices.
--
-- The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-- form square matrices, with the same constraints as the single matrix
-- SelfAdjointEig.
-- 
-- The result is a [..., M+1, M] matrix with [..., 0,:] containing the
-- eigenvalues, and subsequent [...,1:, :] containing the eigenvectors.
selfAdjointEig :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                  Tensor v1 t -- ^ __input__: Shape is `[..., M, M]`.
                  -> Tensor Value t -- ^ __output__: Shape is `[..., M+1, M]`.
selfAdjointEig input | eqLengthGuard [] =
    buildOp (opDef "SelfAdjointEig"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`." name: "input" type_attr: "T"
}
output_arg {
  description: "Shape is `[..., M+1, M]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Stops gradient computation.
--
-- When executed in a graph, this op outputs its input tensor as-is.
-- 
-- When building ops to compute gradients, this op prevents the contribution of
-- its inputs to be taken into account.  Normally, the gradient generator adds ops
-- to a graph to compute the derivatives of a specified 'loss' by recursively
-- finding out inputs that contributed to its computation.  If you insert this op
-- in the graph it inputs are masked from the gradient generator.  They are not
-- taken into account for computing gradients.
-- 
-- This is useful any time you want to compute a value with TensorFlow but need
-- to pretend that the value was a constant. Some examples include:
-- 
-- *  The *EM* algorithm where the *M-step* should not involve backpropagation
--    through the output of the *E-step*.
-- *  Contrastive divergence training of Boltzmann machines where, when
--    differentiating the energy function, the training must not backpropagate
--    through the graph that generated the samples from the model.
-- *  Adversarial training, where no backprop should happen through the adversarial
--    example generation process.
stopGradient :: forall v1 t . (TensorType t) => Tensor v1 t -- ^ __input__
                -> Tensor Value t -- ^ __output__
stopGradient input | eqLengthGuard [] =
    buildOp (opDef "StopGradient"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns the index with the largest value across dimensions of a tensor.

argMax :: forall v1 v2 t tidx . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Int.Int16, Data.Int.Int32,
                                         Data.Int.Int64, Data.Int.Int8,
                                         Data.Word.Word16, Data.Word.Word8,
                                         Double, Float] t, TensorType tidx,
                                 OneOf '[Data.Int.Int32,
                                         Data.Int.Int64] tidx) =>
          Tensor v1 t -- ^ __input__
          -> Tensor v2 tidx -- ^ __dimension__: int32, 0 <= dimension < rank(input).  Describes which dimension
                            -- of the input Tensor to reduce across. For vectors, use dimension = 0.
          -> Tensor Value Data.Int.Int64 -- ^ __output__
argMax input dimension | eqLengthGuard [] =
    buildOp (opDef "ArgMax"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input dimension
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "int32, 0 <= dimension < rank(input).  Describes which dimension\nof the input Tensor to reduce across. For vectors, use dimension = 0."
  name: "dimension"
  type_attr: "Tidx"
}
output_arg { name: "output" type: DT_INT64 }
-}

-- | Computes the reverse mode backpropagated gradient of the Cholesky algorithm.
--
-- For an explanation see "Differentiation of the Cholesky algorithm" by
-- Iain Murray http://arxiv.org/abs/1602.07527.
choleskyGrad :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
                Tensor v1 t -- ^ __l__: Output of batch Cholesky algorithm l = cholesky(A). Shape is `[..., M, M]`.
                            -- Algorithm depends only on lower triangular part of the innermost matrices of
                            -- this tensor.
                -> Tensor v2 t -- ^ __grad__: df/dl where f is some scalar function. Shape is `[..., M, M]`.
                               -- Algorithm depends only on lower triangular part of the innermost matrices of
                               -- this tensor.
                -> Tensor Value t -- ^ __output__: Symmetrized version of df/dA . Shape is `[..., M, M]`
choleskyGrad l grad | eqLengthGuard [] =
    buildOp (opDef "CholeskyGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        l grad
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Output of batch Cholesky algorithm l = cholesky(A). Shape is `[..., M, M]`.\nAlgorithm depends only on lower triangular part of the innermost matrices of\nthis tensor."
  name: "l"
  type_attr: "T"
}
input_arg {
  description: "df/dl where f is some scalar function. Shape is `[..., M, M]`.\nAlgorithm depends only on lower triangular part of the innermost matrices of\nthis tensor."
  name: "grad"
  type_attr: "T"
}
output_arg {
  description: "Symmetrized version of df/dA . Shape is `[..., M, M]`"
  name: "output"
  type_attr: "T"
}
-}

-- | Reshapes a SparseTensor to represent values in a new dense shape.
--
-- This operation has the same semantics as reshape on the represented dense
-- tensor.  The `input_indices` are recomputed based on the requested `new_shape`.
-- 
-- If one component of `new_shape` is the special value -1, the size of that
-- dimension is computed so that the total dense size remains constant.  At
-- most one component of `new_shape` can be -1.  The number of dense elements
-- implied by `new_shape` must be the same as the number of dense elements
-- originally implied by `input_shape`.
-- 
-- Reshaping does not affect the order of values in the SparseTensor.
-- 
-- If the input tensor has rank `R_in` and `N` non-empty values, and `new_shape`
-- has length `R_out`, then `input_indices` has shape `[N, R_in]`,
-- `input_shape` has length `R_in`, `output_indices` has shape `[N, R_out]`, and
-- `output_shape` has length `R_out`.
sparseReshape :: Tensor v1 Data.Int.Int64 -- ^ __input_indices__: 2-D.  `N x R_in` matrix with the indices of non-empty values in a
                                          -- SparseTensor.
                 -> Tensor v2 Data.Int.Int64 -- ^ __input_shape__: 1-D.  `R_in` vector with the input SparseTensor's dense shape.
                 -> Tensor v3 Data.Int.Int64 -- ^ __new_shape__: 1-D.  `R_out` vector with the requested new dense shape.
                 -> (Tensor Value Data.Int.Int64, Tensor Value Data.Int.Int64)
                 -- ^ (__output_indices__, __output_shape__)
                 --
                 -- * __output_indices__: 2-D.  `N x R_out` matrix with the updated indices of non-empty
                 -- values in the output SparseTensor.
                 --
                 -- * __output_shape__: 1-D.  `R_out` vector with the full dense shape of the output
                 -- SparseTensor.  This is the same as `new_shape` but with any -1 dimensions
                 -- filled in.
sparseReshape input_indices input_shape new_shape | eqLengthGuard [] =
    buildOp (opDef "SparseReshape")
        input_indices input_shape new_shape
{-
input_arg {
  description: "2-D.  `N x R_in` matrix with the indices of non-empty values in a\nSparseTensor."
  name: "input_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `R_in` vector with the input SparseTensor\'s dense shape."
  name: "input_shape"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `R_out` vector with the requested new dense shape."
  name: "new_shape"
  type: DT_INT64
}
output_arg {
  description: "2-D.  `N x R_out` matrix with the updated indices of non-empty\nvalues in the output SparseTensor."
  name: "output_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  `R_out` vector with the full dense shape of the output\nSparseTensor.  This is the same as `new_shape` but with any -1 dimensions\nfilled in."
  name: "output_shape"
  type: DT_INT64
}
-}

-- | var: Should be from a Variable().

sparseApplyAdadelta :: forall v4 v5 v6 v7 v8 t tindices . (TensorType t,
                                                           OneOf '[(Data.Complex.Complex Double),
                                                                   (Data.Complex.Complex Float),
                                                                   Data.Int.Int16,
                                                                   Data.Int.Int32,
                                                                   Data.Int.Int64,
                                                                   Data.Int.Int8,
                                                                   Data.Word.Word16,
                                                                   Data.Word.Word8,
                                                                   Double,
                                                                   Float] t,
                                                           TensorType tindices,
                                                           OneOf '[Data.Int.Int32,
                                                                   Data.Int.Int64] tindices) =>
                       Tensor Ref t -- ^ __var__
                       -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                       -> Tensor Ref t -- ^ __accum_update__: : Should be from a Variable().
                       -> Tensor v4 t -- ^ __lr__: Learning rate. Must be a scalar.
                       -> Tensor v5 t -- ^ __rho__: Decay factor. Must be a scalar.
                       -> Tensor v6 t -- ^ __epsilon__: Constant factor. Must be a scalar.
                       -> Tensor v7 t -- ^ __grad__: The gradient.
                       -> Tensor v8 tindices -- ^ __indices__: A vector of indices into the first dimension of var and accum.
                       -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyAdadelta var accum accum_update lr rho epsilon grad
                    indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyAdadelta"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var accum accum_update lr rho epsilon grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var and accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg { is_ref: true name: "var" type_attr: "T" }
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: ": Should be from a Variable()."
  is_ref: true
  name: "accum_update"
  type_attr: "T"
}
input_arg {
  description: "Learning rate. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay factor. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg {
  description: "Constant factor. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var and accum."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Computes the gradient of morphological 2-D dilation with respect to the filter.

dilation2DBackpropFilter :: forall v1 v2 v3 t . (TensorType t,
                                                 OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Int.Int64,
                                                         Data.Int.Int8,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8,
                                                         Double, Float] t) =>
                            Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, depth]`.
                            -> Tensor v2 t -- ^ __filter__: 3-D with shape `[filter_height, filter_width, depth]`.
                            -> Tensor v3 t -- ^ __out_backprop__: 4-D with shape `[batch, out_height, out_width, depth]`.
                            -> Tensor Value t -- ^ __filter_backprop__: 3-D with shape `[filter_height, filter_width, depth]`.
dilation2DBackpropFilter input filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Dilation2DBackpropFilter"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D of length 4. The stride of the sliding window for each dimension of\nthe input tensor. Must be: `[1, stride_height, stride_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  description: "1-D of length 4. The input stride for atrous morphological dilation.\nMust be: `[1, rate_height, rate_width, 1]`."
  has_minimum: true
  minimum: 4
  name: "rates"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, depth]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "3-D with shape `[filter_height, filter_width, depth]`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "4-D with shape `[batch, out_height, out_width, depth]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg {
  description: "3-D with shape `[filter_height, filter_width, depth]`."
  name: "filter_backprop"
  type_attr: "T"
}
-}

-- | 

batchSelfAdjointEigV2 :: forall v1 t . (TensorType t, OneOf '[Double,
                                                              Float] t) =>
                         Tensor v1 t -- ^ __input__
                         -> (Tensor Value t, Tensor Value t) -- ^ (__e__, __v__)
                         --
                         -- * __e__
                         --
                         -- * __v__
batchSelfAdjointEigV2 input | eqLengthGuard [] =
    buildOp (opDef "BatchSelfAdjointEigV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { default_value { b: true } name: "compute_v" type: "bool" }
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "e" type_attr: "T" }
output_arg { name: "v" type_attr: "T" }
-}

-- | Computes the number of incomplete elements in the given barrier.

barrierIncompleteSize :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a barrier.
                         -> Build (Tensor Value Data.Int.Int32) -- ^ __size__: The number of incomplete elements (i.e. those with some of their value
                         -- components not set) in the barrier.
barrierIncompleteSize handle | eqLengthGuard [] =
    buildOp (opDef "BarrierIncompleteSize")
        handle
{-
input_arg {
  description: "The handle to a barrier."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The number of incomplete elements (i.e. those with some of their value\ncomponents not set) in the barrier."
  name: "size"
  type: DT_INT32
}
-}

-- | Fake-quantize the 'inputs' tensor of type float and shape `[b, h, w, d]` via
--
-- global float scalars `min` and `max` to 'outputs' tensor of same shape as
-- `inputs`.
-- 
-- [min; max] is the clamping range for the 'inputs' data.  Op divides this range
-- into 255 steps (total of 256 values), then replaces each 'inputs' value with the
-- closest of the quantized step values.
-- 
-- This operation has a gradient and thus allows for training `min` and `max` values.
fakeQuantWithMinMaxVars :: Tensor v1 Float -- ^ __inputs__
                           -> Tensor v2 Float -- ^ __min__
                           -> Tensor v3 Float -- ^ __max__
                           -> Tensor Value Float -- ^ __outputs__
fakeQuantWithMinMaxVars inputs min max | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxVars")
        inputs min max
{-
input_arg { name: "inputs" type: DT_FLOAT }
input_arg { name: "min" type: DT_FLOAT }
input_arg { name: "max" type: DT_FLOAT }
output_arg { name: "outputs" type: DT_FLOAT }
-}

-- | Reads the value of a variable.
--
-- The tensor returned by this operation is immutable.
-- 
-- The value returned by this operation is guaranteed to be influenced by all the
-- writes on which this operation depends directly or indirectly, and to not be
-- influenced by any of the writes which depend directly or indirectly on this
-- operation.
readVariableOp :: forall dtype . (TensorType dtype) =>
                  ResourceHandle dtype -- ^ __resource__: handle to the resource in which to store the variable.
                  -> Build (Tensor Value dtype) -- ^ __value__
readVariableOp resource | eqLengthGuard [] =
    buildOp (opDef "ReadVariableOp"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        resource
{-
attr {
  description: "the dtype of the value." name: "dtype" type: "type"
}
input_arg {
  description: "handle to the resource in which to store the variable."
  name: "resource"
  type: DT_RESOURCE
}
output_arg { name: "value" type_attr: "dtype" }
-}

-- | Gradient for batch normalization.
--
-- Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW".
-- The size of 1D Tensors matches the dimension C of the 4D Tensors.
fusedBatchNormGrad :: forall v1 v2 v3 v4 v5 t . (TensorType t,
                                                 OneOf '[(Data.Complex.Complex Double),
                                                         (Data.Complex.Complex Float),
                                                         Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Int.Int64,
                                                         Data.Int.Int8,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8,
                                                         Double, Float] t) =>
                      Tensor v1 t -- ^ __y_backprop__: A 4D Tensor for the gradient with respect to y.
                      -> Tensor v2 t -- ^ __x__: A 4D Tensor for input data.
                      -> Tensor v3 t -- ^ __scale__: A 1D Tensor for scaling factor, to scale the normalized x.
                      -> Tensor v4 t -- ^ __reserve_space_1__: A 1D Tensor for the computed batch mean, to be reused
                                     -- in the gradient computation.
                      -> Tensor v5 t -- ^ __reserve_space_2__: A 1D Tensor for the computed batch variance (inverted variance
                                     -- in the cuDNN case), to be used in the gradient computation.
                      -> (Tensor Value t, Tensor Value t, Tensor Value t,
                          Tensor Value t, Tensor Value t)
                      -- ^ (__x_backprop__, __scale_backprop__, __offset_backprop__, __reserve_space_3__, __reserve_space_4__)
                      --
                      -- * __x_backprop__: A 4D Tensor for the gradient with respect to x.
                      --
                      -- * __scale_backprop__: A 1D Tensor for the gradient with respect to scale.
                      --
                      -- * __offset_backprop__: A 1D Tensor for the gradient with respect to offset.
                      --
                      -- * __reserve_space_3__: Unused placeholder to match the mean input in FusedBatchNorm.
                      --
                      -- * __reserve_space_4__: Unused placeholder to match the variance input
                      -- in FusedBatchNorm.
fusedBatchNormGrad y_backprop x scale reserve_space_1
                   reserve_space_2 | eqLengthGuard [] =
    buildOp (opDef "FusedBatchNormGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        y_backprop x scale reserve_space_1 reserve_space_2
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type for the elements of input and output Tensors."
  name: "T"
  type: "type"
}
attr {
  default_value { f: 1.0e-4 }
  description: "A small float number added to the variance of x."
  name: "epsilon"
  type: "float"
}
attr {
  default_value { s: "NHWC" }
  description: "The data format for y_backprop, x, x_backprop.\nEither \"NHWC\" (default) or \"NCHW\"."
  name: "data_format"
  type: "string"
}
attr {
  default_value { b: true }
  description: "A bool value to indicate the operation is for training (default)\nor inference."
  name: "is_training"
  type: "bool"
}
input_arg {
  description: "A 4D Tensor for the gradient with respect to y."
  name: "y_backprop"
  type_attr: "T"
}
input_arg {
  description: "A 4D Tensor for input data." name: "x" type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for scaling factor, to scale the normalized x."
  name: "scale"
  type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for the computed batch mean, to be reused\nin the gradient computation."
  name: "reserve_space_1"
  type_attr: "T"
}
input_arg {
  description: "A 1D Tensor for the computed batch variance (inverted variance\nin the cuDNN case), to be used in the gradient computation."
  name: "reserve_space_2"
  type_attr: "T"
}
output_arg {
  description: "A 4D Tensor for the gradient with respect to x."
  name: "x_backprop"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the gradient with respect to scale."
  name: "scale_backprop"
  type_attr: "T"
}
output_arg {
  description: "A 1D Tensor for the gradient with respect to offset."
  name: "offset_backprop"
  type_attr: "T"
}
output_arg {
  description: "Unused placeholder to match the mean input in FusedBatchNorm."
  name: "reserve_space_3"
  type_attr: "T"
}
output_arg {
  description: "Unused placeholder to match the variance input\nin FusedBatchNorm."
  name: "reserve_space_4"
  type_attr: "T"
}
-}

-- | A queue that produces elements in first-in first-out order.
--
-- Variable-size shapes are allowed by setting the corresponding shape dimensions
-- to 0 in the shape attr.  In this case DequeueMany will pad up to the maximum
-- size of any given element in the minibatch.  See below for details.
paddingFIFOQueue :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __handle__: The handle to the queue.
paddingFIFOQueue  | eqLengthGuard [] =
    buildOp (opDef "PaddingFIFOQueue")
        
{-
attr {
  description: "The type of each component in a value."
  has_minimum: true
  minimum: 1
  name: "component_types"
  type: "list(type)"
}
attr {
  default_value { list { } }
  description: "The shape of each component in a value. The length of this attr must\nbe either 0 or the same as the length of component_types.\nShapes of fixed rank but variable size are allowed by setting\nany shape dimension to -1.  In this case, the inputs\' shape may vary along\nthe given dimension, and DequeueMany will pad the given dimension with\nzeros up to the maximum shape of all elements in the given batch.\nIf the length of this attr is 0, different queue elements may have\ndifferent ranks and shapes, but only one element may be dequeued at a time."
  has_minimum: true
  name: "shapes"
  type: "list(shape)"
}
attr {
  default_value { i: -1 }
  description: "The upper bound on the number of elements in this queue.\nNegative numbers mean no limit."
  name: "capacity"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue will be shared under the given name\nacross multiple sessions."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to the queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Computes the inverse of one or more square invertible matrices or their
--
-- adjoints (conjugate transposes).
-- 
-- The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-- form square matrices. The output is a tensor of the same shape as the input
-- containing the inverse for all input submatrices `[..., :, :]`.
-- 
-- The op uses LU decomposition with partial pivoting to compute the inverses.
-- 
-- If a matrix is not invertible there is no guarantee what the op does. It
-- may detect the condition and raise an exception or it may simply return a
-- garbage result.
matrixInverse :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                 Tensor v1 t -- ^ __input__: Shape is `[..., M, M]`.
                 -> Tensor Value t -- ^ __output__: Shape is `[..., M, M]`.
                 -- 
                 -- @compatibility(numpy)
                 -- Equivalent to np.linalg.inv
                 -- @end_compatibility
matrixInverse input | eqLengthGuard [] =
    buildOp (opDef "MatrixInverse"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { default_value { b: false } name: "adjoint" type: "bool" }
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`." name: "input" type_attr: "T"
}
output_arg {
  description: "Shape is `[..., M, M]`.\n\n@compatibility(numpy)\nEquivalent to np.linalg.inv\n@end_compatibility"
  name: "output"
  type_attr: "T"
}
-}

-- | Outputs a `Summary` protocol buffer with audio.
--
-- The summary has up to `max_outputs` summary values containing audio. The
-- audio is built from `tensor` which must be 3-D with shape `[batch_size,
-- frames, channels]` or 2-D with shape `[batch_size, frames]`. The values are
-- assumed to be in the range of `[-1.0, 1.0]` with a sample rate of `sample_rate`.
-- 
-- The `tag` argument is a scalar `Tensor` of type `string`.  It is used to
-- build the `tag` of the summary values:
-- 
-- *  If `max_outputs` is 1, the summary value tag is '*tag*/audio'.
-- *  If `max_outputs` is greater than 1, the summary value tags are
--    generated sequentially as '*tag*/audio/0', '*tag*/audio/1', etc.
audioSummaryV2 :: Tensor v1 Data.ByteString.ByteString -- ^ __tag__: Scalar. Used to build the `tag` attribute of the summary values.
                  -> Tensor v2 Float -- ^ __tensor__: 2-D of shape `[batch_size, frames]`.
                  -> Tensor v3 Float -- ^ __sample_rate__: The sample rate of the signal in hertz.
                  -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar. Serialized `Summary` protocol buffer.
audioSummaryV2 tag tensor sample_rate | eqLengthGuard [] =
    buildOp (opDef "AudioSummaryV2")
        tag tensor sample_rate
{-
attr {
  default_value { i: 3 }
  description: "Max number of batch elements to generate audio for."
  has_minimum: true
  minimum: 1
  name: "max_outputs"
  type: "int"
}
input_arg {
  description: "Scalar. Used to build the `tag` attribute of the summary values."
  name: "tag"
  type: DT_STRING
}
input_arg {
  description: "2-D of shape `[batch_size, frames]`."
  name: "tensor"
  type: DT_FLOAT
}
input_arg {
  description: "The sample rate of the signal in hertz."
  name: "sample_rate"
  type: DT_FLOAT
}
output_arg {
  description: "Scalar. Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Computes the determinant of one ore more square matrices.
--
-- The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-- form square matrices. The output is a tensor containing the determinants
-- for all input submatrices `[..., :, :]`.
matrixDeterminant :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                     Tensor v1 t -- ^ __input__: Shape is `[..., M, M]`.
                     -> Tensor Value t -- ^ __output__: Shape is `[...]`.
matrixDeterminant input | eqLengthGuard [] =
    buildOp (opDef "MatrixDeterminant"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`." name: "input" type_attr: "T"
}
output_arg {
  description: "Shape is `[...]`." name: "output" type_attr: "T"
}
-}

-- | Writes contents to the file at input filename. Creates file if not existing.

writeFile :: Tensor v1 Data.ByteString.ByteString -- ^ __filename__: scalar. The name of the file to which we write the contents.
             -> Tensor v2 Data.ByteString.ByteString -- ^ __contents__: scalar. The content to be written to the output file.
             -> ControlNode
writeFile filename contents | eqLengthGuard [] =
    buildOp (opDef "WriteFile")
        filename contents
{-
input_arg {
  description: "scalar. The name of the file to which we write the contents."
  name: "filename"
  type: DT_STRING
}
input_arg {
  description: "scalar. The content to be written to the output file."
  name: "contents"
  type: DT_STRING
}
-}

-- | Concatenates quantized tensors along one dimension.

quantizedConcat :: forall v1 v2 v3 v4 t . (TensorType t) =>
                   Tensor v1 Data.Int.Int32 -- ^ __concat_dim__: 0-D.  The dimension along which to concatenate.  Must be in the
                                            -- range [0, rank(values)).
                   -> [Tensor v2 t] -- ^ __values__: The `N` Tensors to concatenate. Their ranks and types must match,
                                    -- and their sizes must match in all dimensions except `concat_dim`.
                   -> [Tensor v3 Float] -- ^ __input_mins__: The minimum scalar values for each of the input tensors.
                   -> [Tensor v4 Float] -- ^ __input_maxes__: The maximum scalar values for each of the input tensors.
                   -> (Tensor Value t, Tensor Value Float, Tensor Value Float)
                   -- ^ (__output__, __output_min__, __output_max__)
                   --
                   -- * __output__: A `Tensor` with the concatenation of values stacked along the
                   -- `concat_dim` dimension.  This tensor's shape matches that of `values` except
                   -- in `concat_dim` where it has the sum of the sizes.
                   --
                   -- * __output_min__: The float value that the minimum quantized output value represents.
                   --
                   -- * __output_max__: The float value that the maximum quantized output value represents.
quantizedConcat concat_dim values input_mins
                input_maxes | eqLengthGuard [("N", [("values", length values),
                                                    ("input_mins", length input_mins),
                                                    ("input_maxes", length input_maxes)])] =
    buildOp (opDef "QuantizedConcat"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        concat_dim values input_mins input_maxes
  where
    n = fromIntegral (length values) :: Int64
{-
attr { has_minimum: true minimum: 2 name: "N" type: "int" }
attr { name: "T" type: "type" }
input_arg {
  description: "0-D.  The dimension along which to concatenate.  Must be in the\nrange [0, rank(values))."
  name: "concat_dim"
  type: DT_INT32
}
input_arg {
  description: "The `N` Tensors to concatenate. Their ranks and types must match,\nand their sizes must match in all dimensions except `concat_dim`."
  name: "values"
  number_attr: "N"
  type_attr: "T"
}
input_arg {
  description: "The minimum scalar values for each of the input tensors."
  name: "input_mins"
  number_attr: "N"
  type: DT_FLOAT
}
input_arg {
  description: "The maximum scalar values for each of the input tensors."
  name: "input_maxes"
  number_attr: "N"
  type: DT_FLOAT
}
output_arg {
  description: "A `Tensor` with the concatenation of values stacked along the\n`concat_dim` dimension.  This tensor\'s shape matches that of `values` except\nin `concat_dim` where it has the sum of the sizes."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "The float value that the minimum quantized output value represents."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the maximum quantized output value represents."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Creates a handle to a Variable resource.

varHandleOp :: forall dtype . (TensorType dtype) =>
               Shape -- ^ __shape__: The (possibly partially specified) shape of this variable.
               -> Build (ResourceHandle dtype) -- ^ __resource__
varHandleOp shape | eqLengthGuard [] =
    buildOp (opDef "VarHandleOp"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        
{-
attr {
  default_value { s: "" }
  description: "the container this variable is placed in."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "the name by which this variable is referred to."
  name: "shared_name"
  type: "string"
}
attr {
  description: "the type of this variable. Must agree with the dtypes\nof all ops using this variable."
  name: "dtype"
  type: "type"
}
attr {
  description: "The (possibly partially specified) shape of this variable."
  name: "shape"
  type: "shape"
}
output_arg { name: "resource" type: DT_RESOURCE }
-}

-- | Assign `value` to the sliced l-value reference of `ref`.
--
-- The values of `value` are assigned to the positions in the variable
-- `ref` that are selected by the slice parameters. The slice parameters
-- `begin, `end`, `strides`, etc. work exactly as in `StridedSlice`.
-- 
-- NOTE this op currently does not support broadcasting and so `value`'s
-- shape must be exactly the shape produced by the slice of `ref`.
stridedSliceAssign :: forall v2 v3 v4 v5 t index . (TensorType t,
                                                    TensorType index,
                                                    OneOf '[Data.Int.Int32,
                                                            Data.Int.Int64] index) =>
                      Tensor Ref t -- ^ __ref__
                      -> Tensor v2 index -- ^ __begin__
                      -> Tensor v3 index -- ^ __end__
                      -> Tensor v4 index -- ^ __strides__
                      -> Tensor v5 t -- ^ __value__
                      -> Build (Tensor Ref t) -- ^ __output_ref__
stridedSliceAssign ref begin end strides value | eqLengthGuard [] =
    buildOp (opDef "StridedSliceAssign"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Index" .~ tensorType (undefined :: index))
        ref begin end strides value
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Index"
  type: "type"
}
attr { default_value { i: 0 } name: "begin_mask" type: "int" }
attr { default_value { i: 0 } name: "end_mask" type: "int" }
attr { default_value { i: 0 } name: "ellipsis_mask" type: "int" }
attr { default_value { i: 0 } name: "new_axis_mask" type: "int" }
attr {
  default_value { i: 0 } name: "shrink_axis_mask" type: "int"
}
input_arg { is_ref: true name: "ref" type_attr: "T" }
input_arg { name: "begin" type_attr: "Index" }
input_arg { name: "end" type_attr: "Index" }
input_arg { name: "strides" type_attr: "Index" }
input_arg { name: "value" type_attr: "T" }
output_arg { is_ref: true name: "output_ref" type_attr: "T" }
-}

-- | Checks whether a resource handle-based variable has been initialized.

varIsInitializedOp :: ResourceHandle dtype -- ^ __resource__: the input resource handle.
                      -> Build (Tensor Value Bool) -- ^ __is_initialized__: a scalar boolean which is true if the variable has been
                      -- initialized.
varIsInitializedOp resource | eqLengthGuard [] =
    buildOp (opDef "VarIsInitializedOp")
        resource
{-
input_arg {
  description: "the input resource handle."
  name: "resource"
  type: DT_RESOURCE
}
output_arg {
  description: "a scalar boolean which is true if the variable has been\ninitialized."
  name: "is_initialized"
  type: DT_BOOL
}
-}

-- | Update '*var' according to the RMSProp algorithm.
--
-- Note that in dense implementation of this algorithm, ms and mom will
-- update even if the grad is zero, but in this sparse implementation, ms
-- and mom will not update in iterations during which the grad is zero.
-- 
-- mean_square = decay * mean_square + (1-decay) * gradient ** 2
-- Delta = learning_rate * gradient / sqrt(mean_square + epsilon)
-- 
-- ms <- rho * ms_{t-1} + (1-rho) * grad * grad
-- mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)
-- var <- var - mom
sparseApplyRMSProp :: forall v4 v5 v6 v7 v8 v9 t tindices . (TensorType t,
                                                             OneOf '[(Data.Complex.Complex Double),
                                                                     (Data.Complex.Complex Float),
                                                                     Data.Int.Int16,
                                                                     Data.Int.Int32,
                                                                     Data.Int.Int64,
                                                                     Data.Int.Int8,
                                                                     Data.Word.Word16,
                                                                     Data.Word.Word8,
                                                                     Double,
                                                                     Float] t,
                                                             TensorType tindices,
                                                             OneOf '[Data.Int.Int32,
                                                                     Data.Int.Int64] tindices) =>
                      Tensor Ref t -- ^ __var__: Should be from a Variable().
                      -> Tensor Ref t -- ^ __ms__: Should be from a Variable().
                      -> Tensor Ref t -- ^ __mom__: Should be from a Variable().
                      -> Tensor v4 t -- ^ __lr__: Scaling factor. Must be a scalar.
                      -> Tensor v5 t -- ^ __rho__: Decay rate. Must be a scalar.
                      -> Tensor v6 t -- ^ __momentum__
                      -> Tensor v7 t -- ^ __epsilon__: Ridge term. Must be a scalar.
                      -> Tensor v8 t -- ^ __grad__: The gradient.
                      -> Tensor v9 tindices -- ^ __indices__: A vector of indices into the first dimension of var, ms and mom.
                      -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
sparseApplyRMSProp var ms mom lr rho momentum epsilon grad
                   indices | eqLengthGuard [] =
    buildOp (opDef "SparseApplyRMSProp"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        var ms mom lr rho momentum epsilon grad indices
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var, ms, and mom tensors is protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "ms"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "mom"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "Decay rate. Must be a scalar."
  name: "rho"
  type_attr: "T"
}
input_arg { name: "momentum" type_attr: "T" }
input_arg {
  description: "Ridge term. Must be a scalar."
  name: "epsilon"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "A vector of indices into the first dimension of var, ms and mom."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | 

batchCholesky :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                 Tensor v1 t -- ^ __input__
                 -> Tensor Value t -- ^ __output__
batchCholesky input | eqLengthGuard [] =
    buildOp (opDef "BatchCholesky"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | 

tensorArrayGather :: forall v2 v3 dtype . (TensorType dtype) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                     -> Tensor v2 Data.Int.Int32 -- ^ __indices__
                     -> Tensor v3 Float -- ^ __flow_in__
                     -> Build (Tensor Value dtype) -- ^ __value__
tensorArrayGather handle indices flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayGather"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle indices flow_in
{-
attr { name: "dtype" type: "type" }
attr {
  default_value { shape { unknown_rank: true } }
  name: "element_shape"
  type: "shape"
}
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "indices" type: DT_INT32 }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "value" type_attr: "dtype" }
-}

-- | Restore a reader to a previously saved state.
--
-- Not all Readers support being restored, so this can produce an
-- Unimplemented error.
readerRestoreState :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
                      -> Tensor v2 Data.ByteString.ByteString -- ^ __state__: Result of a ReaderSerializeState of a Reader with type
                                                              -- matching reader_handle.
                      -> Build (ControlNode)
readerRestoreState reader_handle state | eqLengthGuard [] =
    buildOp (opDef "ReaderRestoreState")
        reader_handle state
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
input_arg {
  description: "Result of a ReaderSerializeState of a Reader with type\nmatching reader_handle."
  name: "state"
  type: DT_STRING
}
-}

-- | Computes the gradient for the sqrt of `x` wrt its input.
--
-- Specifically, `grad = dy * 0.5 / y`, where `y = sqrt(x)`, and `dy`
-- is the corresponding input gradient.
sqrtGrad :: forall v1 v2 t . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Word.Word16, Double, Float] t) =>
            Tensor v1 t -- ^ __x__
            -> Tensor v2 t -- ^ __y__
            -> Tensor Value t -- ^ __z__
sqrtGrad x y | eqLengthGuard [] =
    buildOp (opDef "SqrtGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Splits a tensor into `num_split` tensors along one dimension.

split :: forall v1 v2 t . (TensorType t) =>
         Data.Int.Int64 -- ^ __num_split__: The number of ways to split.  Must evenly divide
                        -- `value.shape[split_dim]`.
         -> Tensor v1 Data.Int.Int32 -- ^ __split_dim__: 0-D.  The dimension along which to split.  Must be in the range
                                     -- `[0, rank(value))`.
         -> Tensor v2 t -- ^ __value__: The tensor to split.
         -> [Tensor Value t] -- ^ __output__: They are identically shaped tensors, whose shape matches that of `value`
         -- except along `split_dim`, where their sizes are
         -- `values.shape[split_dim] / num_split`.
split num_split split_dim value | eqLengthGuard [] =
    buildListOp [num_split] (opDef "Split"
                             & opAttr "T" .~ tensorType (undefined :: t)
                             & opAttr "num_split" .~ num_split)
        split_dim value
{-
attr {
  description: "The number of ways to split.  Must evenly divide\n`value.shape[split_dim]`."
  has_minimum: true
  minimum: 1
  name: "num_split"
  type: "int"
}
attr { name: "T" type: "type" }
input_arg {
  description: "0-D.  The dimension along which to split.  Must be in the range\n`[0, rank(value))`."
  name: "split_dim"
  type: DT_INT32
}
input_arg {
  description: "The tensor to split." name: "value" type_attr: "T"
}
output_arg {
  description: "They are identically shaped tensors, whose shape matches that of `value`\nexcept along `split_dim`, where their sizes are\n`values.shape[split_dim] / num_split`."
  name: "output"
  number_attr: "num_split"
  type_attr: "T"
}
-}

-- | A Reader that outputs the lines of a file delimited by '\n'.

textLineReader :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __reader_handle__: The handle to reference the Reader.
textLineReader  | eqLengthGuard [] =
    buildOp (opDef "TextLineReader")
        
{-
attr {
  default_value { i: 0 }
  description: "Number of lines to skip from the beginning of every file."
  name: "skip_header_lines"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to reference the Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Copy a tensor setting everything outside a central band in each innermost matrix
--
-- to zero.
-- 
-- The `band` part is computed as follows:
-- Assume `input` has `k` dimensions `[I, J, K, ..., M, N]`, then the output is a
-- tensor with the same shape where
-- 
-- `band[i, j, k, ..., m, n] = in_band(m, n) * input[i, j, k, ..., m, n]`.
-- 
-- The indicator function
-- 
-- `in_band(m, n) = (num_lower < 0 || (m-n) <= num_lower)) &&
--                  (num_upper < 0 || (n-m) <= num_upper)`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # if 'input' is [[ 0,  1,  2, 3]
--                  [-1,  0,  1, 2]
--                  [-2, -1,  0, 1]
--                  [-3, -2, -1, 0]],
-- 
-- tf.matrix_band_part(input, 1, -1) ==> [[ 0,  1,  2, 3]
--                                        [-1,  0,  1, 2]
--                                        [ 0, -1,  0, 1]
--                                        [ 0,  0, -1, 0]],
-- 
-- tf.matrix_band_part(input, 2, 1) ==> [[ 0,  1,  0, 0]
--                                       [-1,  0,  1, 0]
--                                       [-2, -1,  0, 1]
--                                       [ 0, -2, -1, 0]]
-- ```
-- 
-- Useful special cases:
-- 
-- ```prettyprint
--  tf.matrix_band_part(input, 0, -1) ==> Upper triangular part.
--  tf.matrix_band_part(input, -1, 0) ==> Lower triangular part.
--  tf.matrix_band_part(input, 0, 0) ==> Diagonal.
-- ```
matrixBandPart :: forall v1 v2 v3 t . (TensorType t) =>
                  Tensor v1 t -- ^ __input__: Rank `k` tensor.
                  -> Tensor v2 Data.Int.Int64 -- ^ __num_lower__: 0-D tensor. Number of subdiagonals to keep. If negative, keep entire
                                              -- lower triangle.
                  -> Tensor v3 Data.Int.Int64 -- ^ __num_upper__: 0-D tensor. Number of superdiagonals to keep. If negative, keep
                                              -- entire upper triangle.
                  -> Tensor Value t -- ^ __band__: Rank `k` tensor of the same shape as input. The extracted banded tensor.
matrixBandPart input num_lower num_upper | eqLengthGuard [] =
    buildOp (opDef "MatrixBandPart"
             & opAttr "T" .~ tensorType (undefined :: t))
        input num_lower num_upper
{-
attr { name: "T" type: "type" }
input_arg {
  description: "Rank `k` tensor." name: "input" type_attr: "T"
}
input_arg {
  description: "0-D tensor. Number of subdiagonals to keep. If negative, keep entire\nlower triangle."
  name: "num_lower"
  type: DT_INT64
}
input_arg {
  description: "0-D tensor. Number of superdiagonals to keep. If negative, keep\nentire upper triangle."
  name: "num_upper"
  type: DT_INT64
}
output_arg {
  description: "Rank `k` tensor of the same shape as input. The extracted banded tensor."
  name: "band"
  type_attr: "T"
}
-}

-- | Closes the given queue.
--
-- This operation signals that no more elements will be enqueued in the
-- given queue. Subsequent Enqueue(Many) operations will fail.
-- Subsequent Dequeue(Many) operations will continue to succeed if
-- sufficient elements remain in the queue. Subsequent Dequeue(Many)
-- operations that would block will fail immediately.
queueClose :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a queue.
              -> Build (ControlNode)
queueClose handle | eqLengthGuard [] =
    buildOp (opDef "QueueClose")
        handle
{-
attr {
  default_value { b: false }
  description: "If true, all pending enqueue requests that are\nblocked on the given queue will be cancelled."
  name: "cancel_pending_enqueues"
  type: "bool"
}
input_arg {
  description: "The handle to a queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | V2 format specific: merges the metadata files of sharded checkpoints.  The
--
-- result is one logical checkpoint, with one physical metadata file and renamed
-- data files.
-- 
-- Intended for "grouping" multiple checkpoints in a sharded checkpoint setup.
-- 
-- If delete_old_dirs is true, attempts to delete recursively the dirname of each
-- path in the input checkpoint_prefixes.  This is useful when those paths are non
-- user-facing temporary locations.
mergeV2Checkpoints :: Tensor v1 Data.ByteString.ByteString -- ^ __checkpoint_prefixes__: prefixes of V2 checkpoints to merge.
                      -> Tensor v2 Data.ByteString.ByteString -- ^ __destination_prefix__: scalar.  The desired final prefix.  Allowed to be the same
                                                              -- as one of the checkpoint_prefixes.
                      -> ControlNode
mergeV2Checkpoints checkpoint_prefixes destination_prefix | eqLengthGuard [] =
    buildOp (opDef "MergeV2Checkpoints")
        checkpoint_prefixes destination_prefix
{-
attr {
  default_value { b: true }
  description: "see above."
  name: "delete_old_dirs"
  type: "bool"
}
input_arg {
  description: "prefixes of V2 checkpoints to merge."
  name: "checkpoint_prefixes"
  type: DT_STRING
}
input_arg {
  description: "scalar.  The desired final prefix.  Allowed to be the same\nas one of the checkpoint_prefixes."
  name: "destination_prefix"
  type: DT_STRING
}
-}

-- | Computes the number of complete elements in the given barrier.

barrierReadySize :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a barrier.
                    -> Build (Tensor Value Data.Int.Int32) -- ^ __size__: The number of complete elements (i.e. those with all of their value
                    -- components set) in the barrier.
barrierReadySize handle | eqLengthGuard [] =
    buildOp (opDef "BarrierReadySize")
        handle
{-
input_arg {
  description: "The handle to a barrier."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The number of complete elements (i.e. those with all of their value\ncomponents set) in the barrier."
  name: "size"
  type: DT_INT32
}
-}

-- | A queue that randomizes the order of elements.

randomShuffleQueue :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __handle__: The handle to the queue.
randomShuffleQueue  | eqLengthGuard [] =
    buildOp (opDef "RandomShuffleQueue")
        
{-
attr {
  description: "The type of each component in a value."
  has_minimum: true
  minimum: 1
  name: "component_types"
  type: "list(type)"
}
attr {
  default_value { list { } }
  description: "The shape of each component in a value. The length of this attr must\nbe either 0 or the same as the length of component_types. If the length of\nthis attr is 0, the shapes of queue elements are not constrained, and\nonly one element may be dequeued at a time."
  has_minimum: true
  name: "shapes"
  type: "list(shape)"
}
attr {
  default_value { i: -1 }
  description: "The upper bound on the number of elements in this queue.\nNegative numbers mean no limit."
  name: "capacity"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "Dequeue will block unless there would be this\nmany elements after the dequeue or the queue is closed. This\nensures a minimum level of mixing of elements."
  name: "min_after_dequeue"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 is set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, a random seed is used."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue will be shared under the given name\nacross multiple sessions."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to the queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Returns the truth value of (x != y) element-wise.
--
-- *NOTE*: `NotEqual` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
notEqual :: forall v1 v2 t . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float), Bool,
                                      Data.ByteString.ByteString,
                                      Data.Int.Int16, Data.Int.Int32,
                                      Data.Int.Int64, Data.Int.Int8,
                                      Data.Word.Word16, Data.Word.Word8, Double,
                                      Float] t) => Tensor v1 t -- ^ __x__
            -> Tensor v2 t -- ^ __y__
            -> Tensor Value Bool -- ^ __z__
notEqual x y | eqLengthGuard [] =
    buildOp (opDef "NotEqual"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_QUINT8
      type: DT_QINT8
      type: DT_QINT32
      type: DT_STRING
      type: DT_BOOL
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Greedily selects a subset of bounding boxes in descending order of score,
--
-- pruning away boxes that have high intersection-over-union (IOU) overlap
-- with previously selected boxes.  Bounding boxes are supplied as
-- [y1, x1, y2, x2], where (y1, x1) and (y2, x2) are the coordinates of any
-- diagonal pair of box corners and the coordinates can be provided as normalized
-- (i.e., lying in the interval [0, 1]) or absolute.  Note that this algorithm
-- is agnostic to where the origin is in the coordinate system.  Note that this
-- algorithm is invariant to orthogonal transformations and translations
-- of the coordinate system; thus translating or reflections of the coordinate
-- system result in the same boxes being selected by the algorithm.
-- 
-- The output of this operation is a set of integers indexing into the input
-- collection of bounding boxes representing the selected boxes.  The bounding
-- box coordinates corresponding to the selected indices can then be obtained
-- using the `tf.gather operation`.  For example:
-- 
--   selected_indices = tf.image.non_max_suppression(
--       boxes, scores, max_output_size, iou_threshold)
--   selected_boxes = tf.gather(boxes, selected_indices)
nonMaxSuppression :: Tensor v1 Float -- ^ __boxes__: A 2-D float tensor of shape `[num_boxes, 4]`.
                     -> Tensor v2 Float -- ^ __scores__: A 1-D float tensor of shape `[num_boxes]` representing a single
                                        -- score corresponding to each box (each row of boxes).
                     -> Tensor v3 Data.Int.Int32 -- ^ __max_output_size__: A scalar integer tensor representing the maximum number of
                                                 -- boxes to be selected by non max suppression.
                     -> Tensor Value Data.Int.Int32 -- ^ __selected_indices__: A 1-D integer tensor of shape `[M]` representing the selected
                     -- indices from the boxes tensor, where `M <= max_output_size`.
nonMaxSuppression boxes scores max_output_size | eqLengthGuard [] =
    buildOp (opDef "NonMaxSuppression")
        boxes scores max_output_size
{-
attr {
  default_value { f: 0.5 }
  description: "A float representing the threshold for deciding whether boxes\noverlap too much with respect to IOU."
  name: "iou_threshold"
  type: "float"
}
input_arg {
  description: "A 2-D float tensor of shape `[num_boxes, 4]`."
  name: "boxes"
  type: DT_FLOAT
}
input_arg {
  description: "A 1-D float tensor of shape `[num_boxes]` representing a single\nscore corresponding to each box (each row of boxes)."
  name: "scores"
  type: DT_FLOAT
}
input_arg {
  description: "A scalar integer tensor representing the maximum number of\nboxes to be selected by non max suppression."
  name: "max_output_size"
  type: DT_INT32
}
output_arg {
  description: "A 1-D integer tensor of shape `[M]` representing the selected\nindices from the boxes tensor, where `M <= max_output_size`."
  name: "selected_indices"
  type: DT_INT32
}
-}

-- | 

tensorArrayWrite :: forall v2 v3 v4 t . (TensorType t) =>
                    Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                    -> Tensor v2 Data.Int.Int32 -- ^ __index__
                    -> Tensor v3 t -- ^ __value__
                    -> Tensor v4 Float -- ^ __flow_in__
                    -> Build (Tensor Value Float) -- ^ __flow_out__
tensorArrayWrite handle index value flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayWrite"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle index value flow_in
{-
attr { name: "T" type: "type" }
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "index" type: DT_INT32 }
input_arg { name: "value" type_attr: "T" }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "flow_out" type: DT_FLOAT }
-}

-- | Quantizes then dequantizes a tensor.
--
-- This op simulates the precision loss from the quantized forward pass by:
-- 1. Quantizing the tensor to fixed point numbers, which should match the target
--    quantization method when it is used in inference.
-- 2. Dequantizing it back to floating point numbers for the following ops, most
--    likely matmul.
-- 
-- There are different ways to quantize. This version does not use the full range
-- of the output type, choosing to elide the lowest possible value for symmetry
-- (e.g., output range is -127 to 127, not -128 to 127 for signed 8 bit
-- quantization), so that 0.0 maps to 0.
-- 
-- To perform this op, we first find the range of values in our tensor. The range
-- we use is always centered on 0, so we find m such that
-- 
-- 1. m = max(abs(input_min), abs(input_max)) if range_given is true,
-- 2. m = max(max(abs(min_elem(input)), abs(max_elem(input))) otherwise.
-- 
-- Our input tensor range is then [-m, m].
-- 
-- Next, we choose our fixed-point quantization buckets, [min_fixed, max_fixed].
-- If signed_input is true, this is
-- 
--   [min_fixed, max_fixed ] =
--       [-(1 << (num_bits - 1) - 1), (1 << (num_bits - 1)) - 1].
-- 
-- Otherwise, if signed_input is false, the fixed-point range is
-- 
--   [min_fixed, max_fixed] = [0, (1 << num_bits) - 1].
-- 
-- From this we compute our scaling factor, s:
-- 
--   s = (max_fixed - min_fixed) / (2 * m).
-- 
-- Now we can quantize and dequantize the elements of our tensor.  An element e
-- is transformed into e':
-- 
--   e' = (e * s).round_to_nearest() / s.
-- 
-- Note that we have a different number of buckets in the signed vs. unsigned
-- cases.  For example, if num_bits == 8, we get 254 buckets in the signed case
-- vs. 255 in the unsigned case.
-- 
-- For example, suppose num_bits = 8 and m = 1.  Then
-- 
--   [min_fixed, max_fixed] = [-127, 127], and
--   s = (127 + 127) / 2 = 127.
-- 
-- Given the vector {-1, -0.5, 0, 0.3}, this is quantized to
-- {-127, -63, 0, 38}, and dequantized to {-1, -63.0/127, 0, 38.0/127}.
quantizeAndDequantize :: forall v1 t . (TensorType t, OneOf '[Double,
                                                              Float] t) =>
                         Tensor v1 t -- ^ __input__: Tensor to quantize and then dequantize.
                         -> Tensor Value t -- ^ __output__
quantizeAndDequantize input | eqLengthGuard [] =
    buildOp (opDef "QuantizeAndDequantize"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  default_value { b: true }
  description: "If the quantization is signed or unsigned."
  name: "signed_input"
  type: "bool"
}
attr {
  default_value { i: 8 }
  description: "The bitwidth of the quantization."
  name: "num_bits"
  type: "int"
}
attr {
  default_value { b: false }
  description: "If the range is given or should be computed from the tensor."
  name: "range_given"
  type: "bool"
}
attr {
  default_value { f: 0.0 }
  description: "If range is given, this is the min of the range."
  name: "input_min"
  type: "float"
}
attr {
  default_value { f: 0.0 }
  description: "If range is given, this is the max of the range."
  name: "input_max"
  type: "float"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Tensor to quantize and then dequantize."
  name: "input"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Returns the next record (key, value pair) produced by a Reader.
--
-- Will dequeue from the input queue if necessary (e.g. when the
-- Reader needs to start reading from a new file since it has finished
-- with the previous file).
readerRead :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
              -> Tensor Ref Data.ByteString.ByteString -- ^ __queue_handle__: Handle to a Queue, with string work items.
              -> Build ((Tensor Value Data.ByteString.ByteString,
                         Tensor Value Data.ByteString.ByteString))
              -- ^ (__key__, __value__)
              --
              -- * __key__: A scalar.
              --
              -- * __value__: A scalar.
readerRead reader_handle queue_handle | eqLengthGuard [] =
    buildOp (opDef "ReaderRead")
        reader_handle queue_handle
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
input_arg {
  description: "Handle to a Queue, with string work items."
  is_ref: true
  name: "queue_handle"
  type: DT_STRING
}
output_arg { description: "A scalar." name: "key" type: DT_STRING }
output_arg {
  description: "A scalar." name: "value" type: DT_STRING
}
-}

-- | Solves systems of linear equations with upper or lower triangular matrices by
--
-- backsubstitution.
-- 
-- `matrix` is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form
-- square matrices. If `lower` is `True` then the strictly upper triangular part
-- of each inner-most matrix is assumed to be zero and not accessed.
-- If `lower` is False then the strictly lower triangular part of each inner-most
-- matrix is assumed to be zero and not accessed.
-- `rhs` is a tensor of shape `[..., M, K]`.
-- 
-- The output is a tensor of shape `[..., M, K]`. If `adjoint` is
-- `True` then the innermost matrices in output` satisfy matrix equations
-- `matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]`.
-- If `adjoint` is `False` then the strictly then the  innermost matrices in
-- `output` satisfy matrix equations
-- `adjoint(matrix[..., i, k]) * output[..., k, j] = rhs[..., i, j]`.
matrixTriangularSolve :: forall v1 v2 t . (TensorType t, OneOf '[Double,
                                                                 Float] t) =>
                         Tensor v1 t -- ^ __matrix__: Shape is `[..., M, M]`.
                         -> Tensor v2 t -- ^ __rhs__: Shape is `[..., M, K]`.
                         -> Tensor Value t -- ^ __output__: Shape is `[..., M, K]`.
matrixTriangularSolve matrix rhs | eqLengthGuard [] =
    buildOp (opDef "MatrixTriangularSolve"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs
{-
attr {
  default_value { b: true }
  description: "Boolean indicating whether the innermost matrices in `matrix` are\nlower or upper triangular."
  name: "lower"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "Boolean indicating whether to solve with `matrix` or its (block-wise)\n         adjoint.\n\n@compatibility(numpy)\nEquivalent to np.linalg.triangular_solve\n@end_compatibility"
  name: "adjoint"
  type: "bool"
}
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Shape is `[..., M, M]`."
  name: "matrix"
  type_attr: "T"
}
input_arg {
  description: "Shape is `[..., M, K]`." name: "rhs" type_attr: "T"
}
output_arg {
  description: "Shape is `[..., M, K]`."
  name: "output"
  type_attr: "T"
}
-}

-- | Split the data from the input value into TensorArray elements.
--
-- Assuming that `lengths` takes on values
-- 
--   ```(n0, n1, ..., n(T-1))```
-- 
-- and that `value` has shape
-- 
--   ```(n0 + n1 + ... + n(T-1) x d0 x d1 x ...)```,
-- 
-- this splits values into a TensorArray with T tensors.
-- 
-- TensorArray index t will be the subtensor of values with starting position
-- 
--   ```(n0 + n1 + ... + n(t-1), 0, 0, ...)```
-- 
-- and having size
-- 
--   ```nt x d0 x d1 x ...```
tensorArraySplitV2 :: forall v1 v2 v3 v4 t . (TensorType t) =>
                      Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                      -> Tensor v2 t -- ^ __value__: The concatenated tensor to write to the TensorArray.
                      -> Tensor v3 Data.Int.Int64 -- ^ __lengths__: The vector of lengths, how to split the rows of value into the
                                                  -- TensorArray.
                      -> Tensor v4 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                      -> Tensor Value Float -- ^ __flow_out__: A float scalar that enforces proper chaining of operations.
tensorArraySplitV2 handle value lengths flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArraySplitV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle value lengths flow_in
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The concatenated tensor to write to the TensorArray."
  name: "value"
  type_attr: "T"
}
input_arg {
  description: "The vector of lengths, how to split the rows of value into the\nTensorArray."
  name: "lengths"
  type: DT_INT64
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_out"
  type: DT_FLOAT
}
-}

-- | Restores a tensor from checkpoint files.
--
-- Reads a tensor stored in one or several files. If there are several files (for
-- instance because a tensor was saved as slices), `file_pattern` may contain
-- wildcard symbols (`*` and `?`) in the filename portion only, not in the
-- directory portion.
-- 
-- If a `file_pattern` matches several files, `preferred_shard` can be used to hint
-- in which file the requested tensor is likely to be found. This op will first
-- open the file at index `preferred_shard` in the list of matching files and try
-- to restore tensors from that file.  Only if some tensors or tensor slices are
-- not found in that first file, then the Op opens all the files. Setting
-- `preferred_shard` to match the value passed as the `shard` input
-- of a matching `Save` Op may speed up Restore.  This attribute only affects
-- performance, not correctness.  The default value -1 means files are processed in
-- order.
-- 
-- See also `RestoreSlice`.
restore :: forall v1 v2 dt . (TensorType dt) =>
           Tensor v1 Data.ByteString.ByteString -- ^ __file_pattern__: Must have a single element. The pattern of the files from
                                                -- which we read the tensor.
           -> Tensor v2 Data.ByteString.ByteString -- ^ __tensor_name__: Must have a single element. The name of the tensor to be
                                                   -- restored.
           -> Tensor Value dt -- ^ __tensor__: The restored tensor.
restore file_pattern tensor_name | eqLengthGuard [] =
    buildOp (opDef "Restore"
             & opAttr "dt" .~ tensorType (undefined :: dt))
        file_pattern tensor_name
{-
attr {
  description: "The type of the tensor to be restored."
  name: "dt"
  type: "type"
}
attr {
  default_value { i: -1 }
  description: "Index of file to open first if multiple files match\n`file_pattern`."
  name: "preferred_shard"
  type: "int"
}
input_arg {
  description: "Must have a single element. The pattern of the files from\nwhich we read the tensor."
  name: "file_pattern"
  type: DT_STRING
}
input_arg {
  description: "Must have a single element. The name of the tensor to be\nrestored."
  name: "tensor_name"
  type: DT_STRING
}
output_arg {
  description: "The restored tensor." name: "tensor" type_attr: "dt"
}
-}

-- | Computes Quantized Rectified Linear X: `min(max(features, 0), max_value)`

quantizedReluX :: forall v1 v2 v3 v4 tinput out_type . (TensorType tinput,
                                                        OneOf '[Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8] tinput,
                                                        TensorType out_type,
                                                        OneOf '[Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8] out_type) =>
                  Tensor v1 tinput -- ^ __features__
                  -> Tensor v2 Float -- ^ __max_value__
                  -> Tensor v3 Float -- ^ __min_features__: The float value that the lowest quantized value represents.
                  -> Tensor v4 Float -- ^ __max_features__: The float value that the highest quantized value represents.
                  -> (Tensor Value out_type, Tensor Value Float,
                      Tensor Value Float)
                  -- ^ (__activations__, __min_activations__, __max_activations__)
                  --
                  -- * __activations__: Has the same output shape as "features".
                  --
                  -- * __min_activations__: The float value that the lowest quantized value represents.
                  --
                  -- * __max_activations__: The float value that the highest quantized value represents.
quantizedReluX features max_value min_features max_features | eqLengthGuard [] =
    buildOp (opDef "QuantizedReluX"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        features max_value min_features max_features
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  default_value { type: DT_QUINT8 }
  name: "out_type"
  type: "type"
}
input_arg { name: "features" type_attr: "Tinput" }
input_arg { name: "max_value" type: DT_FLOAT }
input_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_features"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_features"
  type: DT_FLOAT
}
output_arg {
  description: "Has the same output shape as \"features\"."
  name: "activations"
  type_attr: "out_type"
}
output_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_activations"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_activations"
  type: DT_FLOAT
}
-}

-- | Extracts the average gradient in the given ConditionalAccumulator, provided
--
-- that sufficient (i.e., more than num_required) gradients have been accumulated.
-- The op blocks until sufficient gradients have been accumulated.
-- If the accumulator has already aggregated more than num_required gradients, it
-- returns the average of the accumulated gradients.
-- Also automatically increments the recorded global_step in the accumulator by 1,
-- and resets the aggregate to 0.
accumulatorTakeGradient :: forall v2 dtype . (TensorType dtype,
                                              OneOf '[(Data.Complex.Complex Double),
                                                      (Data.Complex.Complex Float),
                                                      Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word16,
                                                      Data.Word.Word8, Double,
                                                      Float] dtype) =>
                           Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to an accumulator.
                           -> Tensor v2 Data.Int.Int32 -- ^ __num_required__: Number of gradients required before we return an aggregate.
                           -> Build (Tensor Value dtype) -- ^ __average__: The average of the accumulated gradients.
accumulatorTakeGradient handle num_required | eqLengthGuard [] =
    buildOp (opDef "AccumulatorTakeGradient"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle num_required
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type of accumulated gradients. Needs to correspond to the type\nof the accumulator."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "The handle to an accumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "Number of gradients required before we return an aggregate."
  name: "num_required"
  type: DT_INT32
}
output_arg {
  description: "The average of the accumulated gradients."
  name: "average"
  type_attr: "dtype"
}
-}

-- | Returns element-wise remainder of division. When `x < 0` xor `y < 0` is
--
-- true, this follows Python semantics in that the result here is consistent
-- with a flooring divide. E.g. `floor(x / y) * y + mod(x, y) = x`.
-- 
-- *NOTE*: `FloorMod` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
floorMod :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                    Data.Int.Int64, Double,
                                                    Float] t) =>
            Tensor v1 t -- ^ __x__
            -> Tensor v2 t -- ^ __y__
            -> Tensor Value t -- ^ __z__
floorMod x y | eqLengthGuard [] =
    buildOp (opDef "FloorMod"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_INT32 type: DT_INT64 type: DT_FLOAT type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns the set of files matching a pattern.
--
-- Note that this routine only supports wildcard characters in the
-- basename portion of the pattern, not in the directory portion.
matchingFiles :: Tensor v1 Data.ByteString.ByteString -- ^ __pattern__: A (scalar) shell wildcard pattern.
                 -> Tensor Value Data.ByteString.ByteString -- ^ __filenames__: A vector of matching filenames.
matchingFiles pattern | eqLengthGuard [] =
    buildOp (opDef "MatchingFiles")
        pattern
{-
input_arg {
  description: "A (scalar) shell wildcard pattern."
  name: "pattern"
  type: DT_STRING
}
output_arg {
  description: "A vector of matching filenames."
  name: "filenames"
  type: DT_STRING
}
-}

-- | Performs max pooling on the input.

maxPool :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Float] t) =>
           Tensor v1 t -- ^ __input__: 4-D input to pool over.
           -> Tensor Value t -- ^ __output__: The max pooled output tensor.
maxPool input | eqLengthGuard [] =
    buildOp (opDef "MaxPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
attr {
  description: "The size of the window for each dimension of the input tensor."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the\ninput tensor."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { s: "NHWC" s: "NCHW" } }
  default_value { s: "NHWC" }
  description: "Specify the data format of the input and output data. With the\ndefault format \"NHWC\", the data is stored in the order of:\n    [batch, in_height, in_width, in_channels].\nAlternatively, the format could be \"NCHW\", the data storage order of:\n    [batch, in_channels, in_height, in_width]."
  name: "data_format"
  type: "string"
}
input_arg {
  description: "4-D input to pool over." name: "input" type_attr: "T"
}
output_arg {
  description: "The max pooled output tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the ids of the positions in sampled_candidates that match true_labels.
--
-- When doing log-odds NCE, the result of this op should be passed through a
-- SparseToDense op, then added to the logits of the sampled candidates. This has
-- the effect of 'removing' the sampled labels that match the true labels by
-- making the classifier sure that they are sampled labels.
computeAccidentalHits :: Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                         -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: The true_classes output of UnpackSparseLabels.
                         -> Tensor v2 Data.Int.Int64 -- ^ __sampled_candidates__: The sampled_candidates output of CandidateSampler.
                         -> (Tensor Value Data.Int.Int32,
                             Tensor Value Data.Int.Int64, Tensor Value Float)
                         -- ^ (__indices__, __ids__, __weights__)
                         --
                         -- * __indices__: A vector of indices corresponding to rows of true_candidates.
                         --
                         -- * __ids__: A vector of IDs of positions in sampled_candidates that match a true_label
                         -- for the row with the corresponding index in indices.
                         --
                         -- * __weights__: A vector of the same length as indices and ids, in which each element
                         -- is -FLOAT_MAX.
computeAccidentalHits num_true true_classes
                      sampled_candidates | eqLengthGuard [] =
    buildOp (opDef "ComputeAccidentalHits"
             & opAttr "num_true" .~ num_true)
        true_classes sampled_candidates
{-
attr {
  description: "Number of true labels per context."
  name: "num_true"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "The true_classes output of UnpackSparseLabels."
  name: "true_classes"
  type: DT_INT64
}
input_arg {
  description: "The sampled_candidates output of CandidateSampler."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A vector of indices corresponding to rows of true_candidates."
  name: "indices"
  type: DT_INT32
}
output_arg {
  description: "A vector of IDs of positions in sampled_candidates that match a true_label\nfor the row with the corresponding index in indices."
  name: "ids"
  type: DT_INT64
}
output_arg {
  description: "A vector of the same length as indices and ids, in which each element\nis -FLOAT_MAX."
  name: "weights"
  type: DT_FLOAT
}
-}

-- | Deserialize and concatenate `SparseTensors` from a serialized minibatch.
--
-- The input `serialized_sparse` must be a string matrix of shape `[N x 3]` where
-- `N` is the minibatch size and the rows correspond to packed outputs of
-- `SerializeSparse`.  The ranks of the original `SparseTensor` objects
-- must all match.  When the final `SparseTensor` is created, it has rank one
-- higher than the ranks of the incoming `SparseTensor` objects
-- (they have been concatenated along a new row dimension).
-- 
-- The output `SparseTensor` object's shape values for all dimensions but the
-- first are the max across the input `SparseTensor` objects' shape values
-- for the corresponding dimensions.  Its first shape value is `N`, the minibatch
-- size.
-- 
-- The input `SparseTensor` objects' indices are assumed ordered in
-- standard lexicographic order.  If this is not the case, after this
-- step run `SparseReorder` to restore index ordering.
-- 
-- For example, if the serialized input is a `[2 x 3]` matrix representing two
-- original `SparseTensor` objects:
-- 
--     index = [ 0]
--             [10]
--             [20]
--     values = [1, 2, 3]
--     shape = [50]
-- 
-- and
-- 
--     index = [ 2]
--             [10]
--     values = [4, 5]
--     shape = [30]
-- 
-- then the final deserialized `SparseTensor` will be:
-- 
--     index = [0  0]
--             [0 10]
--             [0 20]
--             [1  2]
--             [1 10]
--     values = [1, 2, 3, 4, 5]
--     shape = [2 50]
deserializeManySparse :: forall v1 dtype . (TensorType dtype) =>
                         Tensor v1 Data.ByteString.ByteString -- ^ __serialized_sparse__: 2-D, The `N` serialized `SparseTensor` objects.
                                                              -- Must have 3 columns.
                         -> (Tensor Value Data.Int.Int64, Tensor Value dtype,
                             Tensor Value Data.Int.Int64)
                         -- ^ (__sparse_indices__, __sparse_values__, __sparse_shape__)
                         --
                         -- * __sparse_indices__
                         --
                         -- * __sparse_values__
                         --
                         -- * __sparse_shape__
deserializeManySparse serialized_sparse | eqLengthGuard [] =
    buildOp (opDef "DeserializeManySparse"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        serialized_sparse
{-
attr {
  description: "The `dtype` of the serialized `SparseTensor` objects."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "2-D, The `N` serialized `SparseTensor` objects.\nMust have 3 columns."
  name: "serialized_sparse"
  type: DT_STRING
}
output_arg { name: "sparse_indices" type: DT_INT64 }
output_arg { name: "sparse_values" type_attr: "dtype" }
output_arg { name: "sparse_shape" type: DT_INT64 }
-}

-- | Extracts crops from the input image tensor and bilinearly resizes them (possibly
--
-- with aspect ratio change) to a common output size specified by `crop_size`. This
-- is more general than the `crop_to_bounding_box` op which extracts a fixed size
-- slice from the input image and does not allow resizing or aspect ratio change.
-- 
-- Returns a tensor with `crops` from the input `image` at positions defined at the
-- bounding box locations in `boxes`. The cropped boxes are all resized (with
-- bilinear interpolation) to a fixed `size = [crop_height, crop_width]`. The
-- result is a 4-D tensor `[num_boxes, crop_height, crop_width, depth]`.
cropAndResize :: forall v1 v2 v3 v4 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Int.Int64,
                                                               Data.Int.Int8,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8,
                                                               Double,
                                                               Float] t) =>
                 Tensor v1 t -- ^ __image__: A 4-D tensor of shape `[batch, image_height, image_width, depth]`.
                             -- Both `image_height` and `image_width` need to be positive.
                 -> Tensor v2 Float -- ^ __boxes__: A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor
                                    -- specifies the coordinates of a box in the `box_ind[i]` image and is specified
                                    -- in normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of
                                    -- `y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the
                                    -- `[0, 1]` interval of normalized image height is mapped to
                                    -- `[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in
                                    -- which case the sampled crop is an up-down flipped version of the original
                                    -- image. The width dimension is treated similarly. Normalized coordinates
                                    -- outside the `[0, 1]` range are allowed, in which case we use
                                    -- `extrapolation_value` to extrapolate the input image values.
                 -> Tensor v3 Data.Int.Int32 -- ^ __box_ind__: A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.
                                             -- The value of `box_ind[i]` specifies the image that the `i`-th box refers to.
                 -> Tensor v4 Data.Int.Int32 -- ^ __crop_size__: A 1-D tensor of 2 elements, `size = [crop_height, crop_width]`. All
                                             -- cropped image patches are resized to this size. The aspect ratio of the image
                                             -- content is not preserved. Both `crop_height` and `crop_width` need to be
                                             -- positive.
                 -> Tensor Value Float -- ^ __crops__: A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`.
cropAndResize image boxes box_ind crop_size | eqLengthGuard [] =
    buildOp (opDef "CropAndResize"
             & opAttr "T" .~ tensorType (undefined :: t))
        image boxes box_ind crop_size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "bilinear" } }
  default_value { s: "bilinear" }
  description: "A string specifying the interpolation method. Only \'bilinear\' is\nsupported for now."
  name: "method"
  type: "string"
}
attr {
  default_value { f: 0.0 }
  description: "Value used for extrapolation, when applicable."
  name: "extrapolation_value"
  type: "float"
}
input_arg {
  description: "A 4-D tensor of shape `[batch, image_height, image_width, depth]`.\nBoth `image_height` and `image_width` need to be positive."
  name: "image"
  type_attr: "T"
}
input_arg {
  description: "A 2-D tensor of shape `[num_boxes, 4]`. The `i`-th row of the tensor\nspecifies the coordinates of a box in the `box_ind[i]` image and is specified\nin normalized coordinates `[y1, x1, y2, x2]`. A normalized coordinate value of\n`y` is mapped to the image coordinate at `y * (image_height - 1)`, so as the\n`[0, 1]` interval of normalized image height is mapped to\n`[0, image_height - 1] in image height coordinates. We do allow y1 > y2, in\nwhich case the sampled crop is an up-down flipped version of the original\nimage. The width dimension is treated similarly. Normalized coordinates\noutside the `[0, 1]` range are allowed, in which case we use\n`extrapolation_value` to extrapolate the input image values."
  name: "boxes"
  type: DT_FLOAT
}
input_arg {
  description: "A 1-D tensor of shape `[num_boxes]` with int32 values in `[0, batch)`.\nThe value of `box_ind[i]` specifies the image that the `i`-th box refers to."
  name: "box_ind"
  type: DT_INT32
}
input_arg {
  description: "A 1-D tensor of 2 elements, `size = [crop_height, crop_width]`. All\ncropped image patches are resized to this size. The aspect ratio of the image\ncontent is not preserved. Both `crop_height` and `crop_width` need to be\npositive."
  name: "crop_size"
  type: DT_INT32
}
output_arg {
  description: "A 4-D tensor of shape `[num_boxes, crop_height, crop_width, depth]`."
  name: "crops"
  type: DT_FLOAT
}
-}

-- | Applies sparse updates to a variable reference.
--
-- This operation computes
-- 
--     # Scalar indices
--     ref[indices, ...] = updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] = updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] = updates[i, ..., j, ...]
-- 
-- This operation outputs `ref` after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
-- 
-- If values in `ref` is to be updated more than once, because there are
-- duplicate entires in `indices`, the order at which the updates happen
-- for each value is undefined.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterUpdate.png" alt>
-- </div>
scatterUpdate :: forall v2 v3 t tindices . (TensorType t, TensorType tindices,
                                            OneOf '[Data.Int.Int32,
                                                    Data.Int.Int64] tindices) =>
                 Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
                 -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
                 -> Tensor v3 t -- ^ __updates__: A tensor of updated values to store in `ref`.
                 -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as `ref`.  Returned as a convenience for operations that want
                 -- to use the updated values after the update is done.
scatterUpdate ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterUpdate"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: true }
  description: "If True, the assignment will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of updated values to store in `ref`."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "= Same as `ref`.  Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Outputs random values from the Gamma distribution(s) described by alpha.
--
-- This op uses the algorithm by Marsaglia et al. to acquire samples via
-- transformation-rejection from pairs of uniform and normal random variables.
-- See http://dl.acm.org/citation.cfm?id=358414
randomGamma :: forall v1 v2 s t . (TensorType s, OneOf '[Data.Int.Int32,
                                                         Data.Int.Int64] s,
                                   TensorType t, OneOf '[Data.Word.Word16,
                                                         Double, Float] t) =>
               Tensor v1 s -- ^ __shape__: 1-D integer tensor. Shape of independent samples to draw from each
                           -- distribution described by the shape parameters given in alpha.
               -> Tensor v2 t -- ^ __alpha__: A tensor in which each scalar is a "shape" parameter describing the
                              -- associated gamma distribution.
               -> Build (Tensor Value t) -- ^ __output__: A tensor with shape `shape + shape(alpha)`. Each slice
               -- `[:, ..., :, i0, i1, ...iN]` contains the samples drawn for
               -- `alpha[i0, i1, ...iN]`. The dtype of the output matches the dtype of alpha.
randomGamma shape alpha | eqLengthGuard [] =
    buildOp (opDef "RandomGamma"
             & opAttr "S" .~ tensorType (undefined :: s)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape alpha
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "S"
  type: "type"
}
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D integer tensor. Shape of independent samples to draw from each\ndistribution described by the shape parameters given in alpha."
  name: "shape"
  type_attr: "S"
}
input_arg {
  description: "A tensor in which each scalar is a \"shape\" parameter describing the\nassociated gamma distribution."
  name: "alpha"
  type_attr: "T"
}
output_arg {
  description: "A tensor with shape `shape + shape(alpha)`. Each slice\n`[:, ..., :, i0, i1, ...iN]` contains the samples drawn for\n`alpha[i0, i1, ...iN]`. The dtype of the output matches the dtype of alpha."
  name: "output"
  type_attr: "T"
}
-}

-- | 

batchMatrixSolve :: forall v1 v2 t . (TensorType t, OneOf '[Double, Float] t) =>
                    Tensor v1 t -- ^ __matrix__
                    -> Tensor v2 t -- ^ __rhs__
                    -> Tensor Value t -- ^ __output__
batchMatrixSolve matrix rhs | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixSolve"
             & opAttr "T" .~ tensorType (undefined :: t))
        matrix rhs
{-
attr { default_value { b: false } name: "adjoint" type: "bool" }
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "matrix" type_attr: "T" }
input_arg { name: "rhs" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | 

batchMatrixBandPart :: forall v1 v2 v3 t . (TensorType t) =>
                       Tensor v1 t -- ^ __input__
                       -> Tensor v2 Data.Int.Int64 -- ^ __num_lower__
                       -> Tensor v3 Data.Int.Int64 -- ^ __num_upper__
                       -> Tensor Value t -- ^ __band__
batchMatrixBandPart input num_lower num_upper | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixBandPart"
             & opAttr "T" .~ tensorType (undefined :: t))
        input num_lower num_upper
{-
attr { name: "T" type: "type" }
input_arg { name: "input" type_attr: "T" }
input_arg { name: "num_lower" type: DT_INT64 }
input_arg { name: "num_upper" type: DT_INT64 }
output_arg { name: "band" type_attr: "T" }
-}

-- | 

tensorArrayClose :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                    -> Build (ControlNode)
tensorArrayClose handle | eqLengthGuard [] =
    buildOp (opDef "TensorArrayClose")
        handle
{-
input_arg { is_ref: true name: "handle" type: DT_STRING }
-}

-- | Computes the "logical and" of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
all :: forall v1 v2 tidx . (TensorType tidx, OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] tidx) =>
       Tensor v1 Bool -- ^ __input__: The tensor to reduce.
       -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
       -> Tensor Value Bool -- ^ __output__: The reduced tensor.
all input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "All"
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type: DT_BOOL
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type: DT_BOOL
}
-}

-- | Returns the number of records this Reader has produced.
--
-- This is the same as the number of ReaderRead executions that have
-- succeeded.
readerNumRecordsProduced :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
                            -> Build (Tensor Value Data.Int.Int64) -- ^ __records_produced__
readerNumRecordsProduced reader_handle | eqLengthGuard [] =
    buildOp (opDef "ReaderNumRecordsProduced")
        reader_handle
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
output_arg { name: "records_produced" type: DT_INT64 }
-}

-- | Pop the element at the top of the stack.

stackPop :: forall elem_type . (TensorType elem_type) =>
            Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a stack.
            -> Build (Tensor Value elem_type) -- ^ __elem__: The tensor that is popped from the top of the stack.
stackPop handle | eqLengthGuard [] =
    buildOp (opDef "StackPop"
             & opAttr "elem_type" .~ tensorType (undefined :: elem_type))
        handle
{-
attr {
  description: "The type of the elem that is popped."
  name: "elem_type"
  type: "type"
}
input_arg {
  description: "The handle to a stack."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The tensor that is popped from the top of the stack."
  name: "elem"
  type_attr: "elem_type"
}
-}

-- | Scatter the data from the input value into specific TensorArray elements.
--
-- `indices` must be a vector, its length must match the first dim of `value`.
tensorArrayScatterV2 :: forall v1 v2 v3 v4 t . (TensorType t) =>
                        Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                        -> Tensor v2 Data.Int.Int32 -- ^ __indices__: The locations at which to write the tensor elements.
                        -> Tensor v3 t -- ^ __value__: The concatenated tensor to write to the TensorArray.
                        -> Tensor v4 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                        -> Tensor Value Float -- ^ __flow_out__: A float scalar that enforces proper chaining of operations.
tensorArrayScatterV2 handle indices value flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayScatterV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle indices value flow_in
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The locations at which to write the tensor elements."
  name: "indices"
  type: DT_INT32
}
input_arg {
  description: "The concatenated tensor to write to the TensorArray."
  name: "value"
  type_attr: "T"
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_out"
  type: DT_FLOAT
}
-}

-- | Converts one or more images from RGB to HSV.
--
-- Outputs a tensor of the same shape as the `images` tensor, containing the HSV
-- value of the pixels. The output is only well defined if the value in `images`
-- are in `[0,1]`.
-- 
-- `output[..., 0]` contains hue, `output[..., 1]` contains saturation, and
-- `output[..., 2]` contains value. All HSV values are in `[0,1]`. A hue of 0
-- corresponds to pure red, hue 1/3 is pure green, and 2/3 is pure blue.
rGBToHSV :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
            Tensor v1 t -- ^ __images__: 1-D or higher rank. RGB data to convert. Last dimension must be size 3.
            -> Tensor Value t -- ^ __output__: `images` converted to HSV.
rGBToHSV images | eqLengthGuard [] =
    buildOp (opDef "RGBToHSV"
             & opAttr "T" .~ tensorType (undefined :: t))
        images
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "1-D or higher rank. RGB data to convert. Last dimension must be size 3."
  name: "images"
  type_attr: "T"
}
output_arg {
  description: "`images` converted to HSV."
  name: "output"
  type_attr: "T"
}
-}

-- | Serialize an `N`-minibatch `SparseTensor` into an `[N, 3]` string `Tensor`.
--
-- The `SparseTensor` must have rank `R` greater than 1, and the first dimension
-- is treated as the minibatch dimension.  Elements of the `SparseTensor`
-- must be sorted in increasing order of this first dimension.  The serialized
-- `SparseTensor` objects going into each row of `serialized_sparse` will have
-- rank `R-1`.
-- 
-- The minibatch size `N` is extracted from `sparse_shape[0]`.
serializeManySparse :: forall v1 v2 v3 t . (TensorType t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __sparse_indices__: 2-D.  The `indices` of the minibatch `SparseTensor`.
                       -> Tensor v2 t -- ^ __sparse_values__: 1-D.  The `values` of the minibatch `SparseTensor`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __sparse_shape__: 1-D.  The `shape` of the minibatch `SparseTensor`.
                       -> Tensor Value Data.ByteString.ByteString -- ^ __serialized_sparse__
serializeManySparse sparse_indices sparse_values
                    sparse_shape | eqLengthGuard [] =
    buildOp (opDef "SerializeManySparse"
             & opAttr "T" .~ tensorType (undefined :: t))
        sparse_indices sparse_values sparse_shape
{-
attr { name: "T" type: "type" }
input_arg {
  description: "2-D.  The `indices` of the minibatch `SparseTensor`."
  name: "sparse_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the minibatch `SparseTensor`."
  name: "sparse_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the minibatch `SparseTensor`."
  name: "sparse_shape"
  type: DT_INT64
}
output_arg { name: "serialized_sparse" type: DT_STRING }
-}

-- | Initializes a table from a text file.
--
-- It inserts one key-value pair into the table for each line of the file.
-- The key and value is extracted from the whole line content, elements from the
-- split line based on `delimiter` or the line number (starting from zero).
-- Where to extract the key and value from a line is specified by `key_index` and
-- `value_index`.
-- 
-- - A value of -1 means use the line number(starting from zero), expects `int64`.
-- - A value of -2 means use the whole line content, expects `string`.
-- - A value >= 0 means use the index (starting at zero) of the split line based
--   on `delimiter`.
initializeTableFromTextFile :: Data.Int.Int64 -- ^ __key_index__: Column index in a line to get the table `key` values from.
                               -> Data.Int.Int64 -- ^ __value_index__: Column index that represents information of a line to get the table
                                                 -- `value` values from.
                               -> Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to a table which will be initialized.
                               -> Tensor v2 Data.ByteString.ByteString -- ^ __filename__: Filename of a vocabulary text file.
                               -> Build (ControlNode)
initializeTableFromTextFile key_index value_index table_handle
                            filename | eqLengthGuard [] =
    buildOp (opDef "InitializeTableFromTextFile"
             & opAttr "key_index" .~ key_index
             & opAttr "value_index" .~ value_index)
        table_handle filename
{-
attr {
  description: "Column index in a line to get the table `key` values from."
  has_minimum: true
  minimum: -2
  name: "key_index"
  type: "int"
}
attr {
  description: "Column index that represents information of a line to get the table\n`value` values from."
  has_minimum: true
  minimum: -2
  name: "value_index"
  type: "int"
}
attr {
  default_value { i: -1 }
  description: "Number of elements of the file, use -1 if unknown."
  has_minimum: true
  minimum: -1
  name: "vocab_size"
  type: "int"
}
attr {
  default_value { s: "\t" }
  description: "Delimiter to separate fields in a line."
  name: "delimiter"
  type: "string"
}
input_arg {
  description: "Handle to a table which will be initialized."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
input_arg {
  description: "Filename of a vocabulary text file."
  name: "filename"
  type: DT_STRING
}
-}

-- | Decode a PNG-encoded image to a uint8 or uint16 tensor.
--
-- The attr `channels` indicates the desired number of color channels for the
-- decoded image.
-- 
-- Accepted values are:
-- 
-- *   0: Use the number of channels in the PNG-encoded image.
-- *   1: output a grayscale image.
-- *   3: output an RGB image.
-- *   4: output an RGBA image.
-- 
-- If needed, the PNG-encoded image is transformed to match the requested number
-- of color channels.
decodePng :: forall v1 dtype . (TensorType dtype, OneOf '[Data.Word.Word16,
                                                          Data.Word.Word8] dtype) =>
             Tensor v1 Data.ByteString.ByteString -- ^ __contents__: 0-D.  The PNG-encoded image.
             -> Tensor Value dtype -- ^ __image__: 3-D with shape `[height, width, channels]`.
decodePng contents | eqLengthGuard [] =
    buildOp (opDef "DecodePng"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        contents
{-
attr {
  default_value { i: 0 }
  description: "Number of color channels for the decoded image."
  name: "channels"
  type: "int"
}
attr {
  allowed_values { list { type: DT_UINT8 type: DT_UINT16 } }
  default_value { type: DT_UINT8 }
  name: "dtype"
  type: "type"
}
input_arg {
  description: "0-D.  The PNG-encoded image."
  name: "contents"
  type: DT_STRING
}
output_arg {
  description: "3-D with shape `[height, width, channels]`."
  name: "image"
  type_attr: "dtype"
}
-}

-- | Get the current size of the TensorArray.

tensorArraySizeV2 :: Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray (output of TensorArray or TensorArrayGrad).
                     -> Tensor v2 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                     -> Tensor Value Data.Int.Int32 -- ^ __size__: The current size of the TensorArray.
tensorArraySizeV2 handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArraySizeV2")
        handle flow_in
{-
input_arg {
  description: "The handle to a TensorArray (output of TensorArray or TensorArrayGrad)."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "The current size of the TensorArray."
  name: "size"
  type: DT_INT32
}
-}

-- | Returns x / y element-wise.
--
-- *NOTE*: `Div` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
div :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int16, Data.Int.Int32,
                                               Data.Int.Int64, Data.Int.Int8,
                                               Data.Word.Word16,
                                               Data.Word.Word8, Double,
                                               Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
div x y | eqLengthGuard [] =
    buildOp (opDef "Div"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Generates labels for candidate sampling with a log-uniform distribution.
--
-- See explanations of candidate sampling and the data formats at
-- go/candidate-sampling.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
logUniformCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to randomly sample per batch.
                              -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                              -> Data.Int.Int64 -- ^ __range_max__: The sampler will sample integers from the interval [0, range_max).
                              -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                                      -- candidates in a batch are unique. This requires some approximation to
                                      -- estimate the post-rejection sampling probabilities.
                              -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                          -- IDs of the num_true target_classes in the corresponding original label.
                              -> (Tensor Value Data.Int.Int64,
                                  Tensor Value Float, Tensor Value Float)
                              -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                              --
                              -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                              -- the ID of a sampled candidate.
                              --
                              -- * __true_expected_count__: A batch_size * num_true matrix, representing
                              -- the number of times each candidate is expected to occur in a batch
                              -- of sampled candidates. If unique=true, then this is a probability.
                              --
                              -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                              -- candidate representing the number of times the candidate is expected
                              -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                              -- probability.
logUniformCandidateSampler num_sampled num_true range_max unique
                           true_classes | eqLengthGuard [] =
    buildOp (opDef "LogUniformCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "range_max" .~ range_max
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to randomly sample per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  description: "The sampler will sample integers from the interval [0, range_max)."
  has_minimum: true
  minimum: 1
  name: "range_max"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Defines a barrier that persists across different graph executions.
--
-- A barrier represents a key-value map, where each key is a string, and
-- each value is a tuple of tensors.
-- 
-- At runtime, the barrier contains 'complete' and 'incomplete'
-- elements. A complete element has defined tensors for all components of
-- its value tuple, and may be accessed using BarrierTakeMany. An
-- incomplete element has some undefined components in its value tuple,
-- and may be updated using BarrierInsertMany.
barrier :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __handle__: The handle to the barrier.
barrier  | eqLengthGuard [] =
    buildOp (opDef "Barrier")
        
{-
attr {
  description: "The type of each component in a value."
  has_minimum: true
  minimum: 1
  name: "component_types"
  type: "list(type)"
}
attr {
  default_value { list { } }
  description: "The shape of each component in a value. Each shape must be 1 in the\nfirst dimension. The length of this attr must be the same as the length of\ncomponent_types."
  has_minimum: true
  name: "shapes"
  type: "list(shape)"
}
attr {
  default_value { i: -1 }
  description: "The capacity of the barrier.  The default capacity is MAX_INT32,\nwhich is the largest capacity of the underlying queue."
  name: "capacity"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this barrier is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this barrier will be shared under the given name\nacross multiple sessions."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to the barrier."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Creates a variable resource.

createVariableOp :: forall v2 dtype . (TensorType dtype) =>
                    ResourceHandle dtype -- ^ __resource__: handle to the resource in which to store the variable.
                    -> Tensor v2 dtype -- ^ __value__: the value to set the new tensor to use.
                    -> Build (ControlNode)
createVariableOp resource value | eqLengthGuard [] =
    buildOp (opDef "CreateVariableOp"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        resource value
{-
attr {
  description: "the dtype of the value." name: "dtype" type: "type"
}
input_arg {
  description: "handle to the resource in which to store the variable."
  name: "resource"
  type: DT_RESOURCE
}
input_arg {
  description: "the value to set the new tensor to use."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Applies a gradient to a given accumulator. Does not add if local_step is lesser
--
-- than the accumulator's global_step.
accumulatorApplyGradient :: forall v2 v3 dtype . (TensorType dtype,
                                                  OneOf '[(Data.Complex.Complex Double),
                                                          (Data.Complex.Complex Float),
                                                          Data.Int.Int16,
                                                          Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Data.Int.Int8,
                                                          Data.Word.Word16,
                                                          Data.Word.Word8,
                                                          Double,
                                                          Float] dtype) =>
                            Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a accumulator.
                            -> Tensor v2 Data.Int.Int64 -- ^ __local_step__: The local_step value at which the gradient was computed.
                            -> Tensor v3 dtype -- ^ __gradient__: A tensor of the gradient to be accumulated.
                            -> Build (ControlNode)
accumulatorApplyGradient handle local_step gradient | eqLengthGuard [] =
    buildOp (opDef "AccumulatorApplyGradient"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle local_step gradient
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type of accumulated gradients. Needs to correspond to the type\nof the accumulator."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "The handle to a accumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The local_step value at which the gradient was computed."
  name: "local_step"
  type: DT_INT64
}
input_arg {
  description: "A tensor of the gradient to be accumulated."
  name: "gradient"
  type_attr: "dtype"
}
-}

-- | Outputs random values from a normal distribution.
--
-- The generated values will have mean 0 and standard deviation 1.
randomStandardNormal :: forall v1 dtype t . (TensorType dtype,
                                             OneOf '[Data.Word.Word16, Double,
                                                     Float] dtype, TensorType t,
                                             OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] t) =>
                        Tensor v1 t -- ^ __shape__: The shape of the output tensor.
                        -> Build (Tensor Value dtype) -- ^ __output__: A tensor of the specified shape filled with random normal values.
randomStandardNormal shape | eqLengthGuard [] =
    buildOp (opDef "RandomStandardNormal"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  description: "The type of the output."
  name: "dtype"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "The shape of the output tensor."
  name: "shape"
  type_attr: "T"
}
output_arg {
  description: "A tensor of the specified shape filled with random normal values."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Outputs random values from a normal distribution. The parameters may each be a
--
-- scalar which applies to the entire output, or a vector of length shape[0] which
-- stores the parameters for each batch.
parameterizedTruncatedNormal :: forall v1 v2 v3 v4 v5 dtype
                                t . (TensorType dtype, OneOf '[Data.Word.Word16,
                                                               Double,
                                                               Float] dtype,
                                     TensorType t, OneOf '[Data.Int.Int32,
                                                           Data.Int.Int64] t) =>
                                Tensor v1 t -- ^ __shape__: The shape of the output tensor. Batches are indexed by the 0th dimension.
                                -> Tensor v2 dtype -- ^ __means__: The mean parameter of each batch.
                                -> Tensor v3 dtype -- ^ __stdevs__: The standard deviation parameter of each batch. Must be greater than 0.
                                -> Tensor v4 dtype -- ^ __minvals__: The minimum cutoff. May be -infinity.
                                -> Tensor v5 dtype -- ^ __maxvals__: The maximum cutoff. May be +infinity, and must be more than the minval
                                                   -- for each batch.
                                -> Build (Tensor Value dtype) -- ^ __output__: A matrix of shape num_batches x samples_per_batch, filled with random
                                -- truncated normal values using the parameters for each row.
parameterizedTruncatedNormal shape means stdevs minvals
                             maxvals | eqLengthGuard [] =
    buildOp (opDef "ParameterizedTruncatedNormal"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape means stdevs minvals maxvals
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  description: "The type of the output."
  name: "dtype"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "The shape of the output tensor. Batches are indexed by the 0th dimension."
  name: "shape"
  type_attr: "T"
}
input_arg {
  description: "The mean parameter of each batch."
  name: "means"
  type_attr: "dtype"
}
input_arg {
  description: "The standard deviation parameter of each batch. Must be greater than 0."
  name: "stdevs"
  type_attr: "dtype"
}
input_arg {
  description: "The minimum cutoff. May be -infinity."
  name: "minvals"
  type_attr: "dtype"
}
input_arg {
  description: "The maximum cutoff. May be +infinity, and must be more than the minval\nfor each batch."
  name: "maxvals"
  type_attr: "dtype"
}
output_arg {
  description: "A matrix of shape num_batches x samples_per_batch, filled with random\ntruncated normal values using the parameters for each row."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Updates the accumulator with a new value for global_step. Logs warning if the
--
-- accumulator's value is already higher than new_global_step.
accumulatorSetGlobalStep :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to an accumulator.
                            -> Tensor v2 Data.Int.Int64 -- ^ __new_global_step__: The new global_step value to set.
                            -> Build (ControlNode)
accumulatorSetGlobalStep handle new_global_step | eqLengthGuard [] =
    buildOp (opDef "AccumulatorSetGlobalStep")
        handle new_global_step
{-
input_arg {
  description: "The handle to an accumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The new global_step value to set."
  name: "new_global_step"
  type: DT_INT64
}
-}

-- | Resize `images` to `size` using bilinear interpolation.
--
-- Input images can be of different types but output images are always float.
resizeBilinear :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                          Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Data.Int.Int8,
                                                          Data.Word.Word16,
                                                          Data.Word.Word8,
                                                          Double, Float] t) =>
                  Tensor v1 t -- ^ __images__: 4-D with shape `[batch, height, width, channels]`.
                  -> Tensor v2 Data.Int.Int32 -- ^ __size__: = A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The
                                              -- new size for the images.
                  -> Tensor Value Float -- ^ __resized_images__: 4-D with shape
                  -- `[batch, new_height, new_width, channels]`.
resizeBilinear images size | eqLengthGuard [] =
    buildOp (opDef "ResizeBilinear"
             & opAttr "T" .~ tensorType (undefined :: t))
        images size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale input by (new_height - 1) / (height - 1), which\nexactly aligns the 4 corners of images and resized images. If false, rescale\nby new_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "images"
  type_attr: "T"
}
input_arg {
  description: "= A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The\nnew size for the images."
  name: "size"
  type: DT_INT32
}
output_arg {
  description: "4-D with shape\n`[batch, new_height, new_width, channels]`."
  name: "resized_images"
  type: DT_FLOAT
}
-}

-- | Quantize the 'input' tensor of type float to 'output' tensor of type 'T'.
--
-- [min_range, max_range] are scalar floats that specify the range for
-- the 'input' data. The 'mode' attribute controls exactly which calculations are
-- used to convert the float values to their quantized equivalents.
-- 
-- In 'MIN_COMBINED' mode, each value of the tensor will undergo the following:
-- 
-- ```
-- out[i] = (in[i] - min_range) * range(T) / (max_range - min_range)
-- if T == qint8, out[i] -= (range(T) + 1) / 2.0
-- ```
-- here `range(T) = numeric_limits<T>::max() - numeric_limits<T>::min()`
-- 
-- *MIN_COMBINED Mode Example*
-- 
-- Assume the input is type float and has a possible range of [0.0, 6.0] and the
-- output type is quint8 ([0, 255]). The min_range and max_range values should be
-- specified as 0.0 and 6.0. Quantizing from float to quint8 will multiply each
-- value of the input by 255/6 and cast to quint8.
-- 
-- If the output type was qint8 ([-128, 127]), the operation will additionally
-- subtract each value by 128 prior to casting, so that the range of values aligns
-- with the range of qint8.
-- 
-- If the mode is 'MIN_FIRST', then this approach is used:
-- 
-- ```
-- number_of_steps = 1 << (# of bits in T)
-- range_adjust = number_of_steps / (number_of_steps - 1)
-- range = (range_max - range_min) * range_adjust
-- range_scale = number_of_steps / range
-- quantized = round(input * range_scale) - round(range_min * range_scale) +
--   numeric_limits<T>::min()
-- quantized = max(quantized, numeric_limits<T>::min())
-- quantized = min(quantized, numeric_limits<T>::max())
-- ```
-- 
-- The biggest difference between this and MIN_COMBINED is that the minimum range
-- is rounded first, before it's subtracted from the rounded value. With
-- MIN_COMBINED, a small bias is introduced where repeated iterations of quantizing
-- and dequantizing will introduce a larger and larger error.
-- 
-- One thing to watch out for is that the operator may choose to adjust the
-- requested minimum and maximum values slightly during the quantization process,
-- so you should always use the output ports as the range for further calculations.
-- For example, if the requested minimum and maximum values are close to equal,
-- they will be separated by a small epsilon value to prevent ill-formed quantized
-- buffers from being created. Otherwise, you can end up with buffers where all the
-- quantized values map to the same float value, which causes problems for
-- operations that have to perform further calculations on them.
quantizeV2 :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8] t) =>
              Tensor v1 Float -- ^ __input__
              -> Tensor v2 Float -- ^ __min_range__: The minimum scalar value possibly produced for the input.
              -> Tensor v3 Float -- ^ __max_range__: The maximum scalar value possibly produced for the input.
              -> (Tensor Value t, Tensor Value Float, Tensor Value Float)
              -- ^ (__output__, __output_min__, __output_max__)
              --
              -- * __output__: The quantized data produced from the float input.
              --
              -- * __output_min__: The actual minimum scalar value used for the output.
              --
              -- * __output_max__: The actual maximum scalar value used for the output.
quantizeV2 input min_range max_range | eqLengthGuard [] =
    buildOp (opDef "QuantizeV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input min_range max_range
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "MIN_COMBINED" s: "MIN_FIRST" } }
  default_value { s: "MIN_COMBINED" }
  name: "mode"
  type: "string"
}
input_arg { name: "input" type: DT_FLOAT }
input_arg {
  description: "The minimum scalar value possibly produced for the input."
  name: "min_range"
  type: DT_FLOAT
}
input_arg {
  description: "The maximum scalar value possibly produced for the input."
  name: "max_range"
  type: DT_FLOAT
}
output_arg {
  description: "The quantized data produced from the float input."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "The actual minimum scalar value used for the output."
  name: "output_min"
  type: DT_FLOAT
}
output_arg {
  description: "The actual maximum scalar value used for the output."
  name: "output_max"
  type: DT_FLOAT
}
-}

-- | Decode a JPEG-encoded image to a uint8 tensor.
--
-- The attr `channels` indicates the desired number of color channels for the
-- decoded image.
-- 
-- Accepted values are:
-- 
-- *   0: Use the number of channels in the JPEG-encoded image.
-- *   1: output a grayscale image.
-- *   3: output an RGB image.
-- 
-- If needed, the JPEG-encoded image is transformed to match the requested number
-- of color channels.
-- 
-- The attr `ratio` allows downscaling the image by an integer factor during
-- decoding.  Allowed values are: 1, 2, 4, and 8.  This is much faster than
-- downscaling the image later.
decodeJpeg :: Tensor v1 Data.ByteString.ByteString -- ^ __contents__: 0-D.  The JPEG-encoded image.
              -> Tensor Value Data.Word.Word8 -- ^ __image__: 3-D with shape `[height, width, channels]`..
decodeJpeg contents | eqLengthGuard [] =
    buildOp (opDef "DecodeJpeg")
        contents
{-
attr {
  default_value { i: 0 }
  description: "Number of color channels for the decoded image."
  name: "channels"
  type: "int"
}
attr {
  default_value { i: 1 }
  description: "Downscaling ratio."
  name: "ratio"
  type: "int"
}
attr {
  default_value { b: true }
  description: "If true use a slower but nicer upscaling of the\nchroma planes (yuv420/422 only)."
  name: "fancy_upscaling"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If true try to recover an image from truncated input."
  name: "try_recover_truncated"
  type: "bool"
}
attr {
  default_value { f: 1.0 }
  description: "The minimum required fraction of lines before a truncated\ninput is accepted."
  name: "acceptable_fraction"
  type: "float"
}
input_arg {
  description: "0-D.  The JPEG-encoded image."
  name: "contents"
  type: DT_STRING
}
output_arg {
  description: "3-D with shape `[height, width, channels]`.."
  name: "image"
  type: DT_UINT8
}
-}

-- | Computes the power of one value to another.
--
-- Given a tensor `x` and a tensor `y`, this operation computes \\(x^y\\) for
-- corresponding elements in `x` and `y`. For example:
-- 
-- ```
-- # tensor 'x' is [[2, 2]], [3, 3]]
-- # tensor 'y' is [[8, 16], [2, 3]]
-- tf.pow(x, y) ==> [[256, 65536], [9, 27]]
-- ```
pow :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int32, Data.Int.Int64,
                                               Data.Word.Word16, Double,
                                               Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
pow x y | eqLengthGuard [] =
    buildOp (opDef "Pow"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Forwards the input to the output.
--
-- This operator represents the loop termination condition used by the
-- "pivot" switches of a loop.
loopCond :: Tensor v1 Bool -- ^ __input__: A boolean scalar, representing the branch predicate of the Switch op.
            -> Tensor Value Bool -- ^ __output__: The same tensor as `input`.
loopCond input | eqLengthGuard [] =
    buildOp (opDef "LoopCond")
        input
{-
input_arg {
  description: "A boolean scalar, representing the branch predicate of the Switch op."
  name: "input"
  type: DT_BOOL
}
output_arg {
  description: "The same tensor as `input`."
  name: "output"
  type: DT_BOOL
}
-}

-- | Reads and outputs the entire contents of the input filename.

readFile :: Tensor v1 Data.ByteString.ByteString -- ^ __filename__
            -> Tensor Value Data.ByteString.ByteString -- ^ __contents__
readFile filename | eqLengthGuard [] =
    buildOp (opDef "ReadFile")
        filename
{-
input_arg { name: "filename" type: DT_STRING }
output_arg { name: "contents" type: DT_STRING }
-}

-- | Returns the imaginary part of a complex number.
--
-- Given a tensor `input` of complex numbers, this operation returns a tensor of
-- type `float` that is the imaginary part of each element in `input`. All
-- elements in `input` must be complex numbers of the form \\(a + bj\\), where *a*
-- is the real part and *b* is the imaginary part returned by this operation.
-- 
-- For example:
-- 
-- ```
-- # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j]
-- tf.imag(input) ==> [4.75, 5.75]
-- ```
imag :: forall v1 t tout . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float)] t,
                            TensorType tout, OneOf '[Double, Float] tout) =>
        Tensor v1 t -- ^ __input__
        -> Tensor Value tout -- ^ __output__
imag input | eqLengthGuard [] =
    buildOp (opDef "Imag"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        input
{-
attr {
  allowed_values { list { type: DT_COMPLEX64 type: DT_COMPLEX128 } }
  default_value { type: DT_COMPLEX64 }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  default_value { type: DT_FLOAT }
  name: "Tout"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "Tout" }
-}

-- | 

tensorArrayGrad :: Tensor v1 Data.ByteString.ByteString -- ^ __handle__
                   -> Tensor v2 Float -- ^ __flow_in__
                   -> Build (Tensor Ref Data.ByteString.ByteString) -- ^ __grad_handle__
tensorArrayGrad handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayGrad")
        handle flow_in
{-
attr { name: "source" type: "string" }
input_arg { name: "handle" type: DT_STRING }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { is_ref: true name: "grad_handle" type: DT_STRING }
-}

-- | Outputs a `Summary` protocol buffer with a histogram.
--
-- The generated
-- [`Summary`](https://www.tensorflow.org/code/tensorflow/core/framework/summary.proto)
-- has one summary value containing a histogram for `values`.
-- 
-- This op reports an `InvalidArgument` error if any value is not finite.
histogramSummary :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double, Float] t) =>
                    Tensor v1 Data.ByteString.ByteString -- ^ __tag__: Scalar.  Tag to use for the `Summary.Value`.
                    -> Tensor v2 t -- ^ __values__: Any shape. Values to use to build the histogram.
                    -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar. Serialized `Summary` protocol buffer.
histogramSummary tag values | eqLengthGuard [] =
    buildOp (opDef "HistogramSummary"
             & opAttr "T" .~ tensorType (undefined :: t))
        tag values
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "Scalar.  Tag to use for the `Summary.Value`."
  name: "tag"
  type: DT_STRING
}
input_arg {
  description: "Any shape. Values to use to build the histogram."
  name: "values"
  type_attr: "T"
}
output_arg {
  description: "Scalar. Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Computes the gradients of 3-D convolution with respect to the input.

conv3DBackpropInputV2 :: forall v1 v2 v3 t . (TensorType t,
                                              OneOf '[(Data.Complex.Complex Double),
                                                      (Data.Complex.Complex Float),
                                                      Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word16,
                                                      Data.Word.Word8, Double,
                                                      Float] t) =>
                         Tensor v1 Data.Int.Int32 -- ^ __input_sizes__: An integer vector representing the tensor shape of `input`,
                                                  -- where `input` is a 5-D
                                                  -- `[batch, depth, rows, cols, in_channels]` tensor.
                         -> Tensor v2 t -- ^ __filter__: Shape `[depth, rows, cols, in_channels, out_channels]`.
                                        -- `in_channels` must match between `input` and `filter`.
                         -> Tensor v3 t -- ^ __out_backprop__: Backprop signal of shape `[batch, out_depth, out_rows, out_cols,
                                        -- out_channels]`.
                         -> Tensor Value t -- ^ __output__
conv3DBackpropInputV2 input_sizes filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv3DBackpropInputV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_sizes filter out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "An integer vector representing the tensor shape of `input`,\nwhere `input` is a 5-D\n`[batch, depth, rows, cols, in_channels]` tensor."
  name: "input_sizes"
  type: DT_INT32
}
input_arg {
  description: "Shape `[depth, rows, cols, in_channels, out_channels]`.\n`in_channels` must match between `input` and `filter`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "Backprop signal of shape `[batch, out_depth, out_rows, out_cols,\nout_channels]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes the gradient of bilinear interpolation.

resizeBilinearGrad :: forall v1 v2 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                              Double,
                                                              Float] t) =>
                      Tensor v1 Float -- ^ __grads__: 4-D with shape `[batch, height, width, channels]`.
                      -> Tensor v2 t -- ^ __original_image__: 4-D with shape `[batch, orig_height, orig_width, channels]`,
                                     -- The image tensor that was resized.
                      -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, orig_height, orig_width, channels]`.
                      -- Gradients with respect to the input image. Input image must have been
                      -- float or double.
resizeBilinearGrad grads original_image | eqLengthGuard [] =
    buildOp (opDef "ResizeBilinearGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        grads original_image
{-
attr {
  allowed_values {
    list { type: DT_FLOAT type: DT_HALF type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale grads by (orig_height - 1) / (height - 1), which\nexactly aligns the 4 corners of grads and original_image. If false, rescale by\norig_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "grads"
  type: DT_FLOAT
}
input_arg {
  description: "4-D with shape `[batch, orig_height, orig_width, channels]`,\nThe image tensor that was resized."
  name: "original_image"
  type_attr: "T"
}
output_arg {
  description: "4-D with shape `[batch, orig_height, orig_width, channels]`.\nGradients with respect to the input image. Input image must have been\nfloat or double."
  name: "output"
  type_attr: "T"
}
-}

-- | Add an `N`-minibatch `SparseTensor` to a `SparseTensorsMap`, return `N` handles.
--
-- A `SparseTensor` of rank `R` is represented by three tensors: `sparse_indices`,
-- `sparse_values`, and `sparse_shape`, where
-- 
-- ```sparse_indices.shape[1] == sparse_shape.shape[0] == R```
-- 
-- An `N`-minibatch of `SparseTensor` objects is represented as a `SparseTensor`
-- having a first `sparse_indices` column taking values between `[0, N)`, where
-- the minibatch size `N == sparse_shape[0]`.
-- 
-- The input `SparseTensor` must have rank `R` greater than 1, and the first
-- dimension is treated as the minibatch dimension.  Elements of the `SparseTensor`
-- must be sorted in increasing order of this first dimension.  The stored
-- `SparseTensor` objects pointed to by each row of the output `sparse_handles`
-- will have rank `R-1`.
-- 
-- The `SparseTensor` values can then be read out as part of a minibatch by passing
-- the given keys as vector elements to `TakeManySparseFromTensorsMap`.  To ensure
-- the correct `SparseTensorsMap` is accessed, ensure that the same
-- `container` and `shared_name` are passed to that Op.  If no `shared_name`
-- is provided here, instead use the *name* of the Operation created by calling
-- `AddManySparseToTensorsMap` as the `shared_name` passed to
-- `TakeManySparseFromTensorsMap`.  Ensure the Operations are colocated.
addManySparseToTensorsMap :: forall v1 v2 v3 t . (TensorType t) =>
                             Tensor v1 Data.Int.Int64 -- ^ __sparse_indices__: 2-D.  The `indices` of the minibatch `SparseTensor`.
                                                      -- `sparse_indices[:, 0]` must be ordered values in `[0, N)`.
                             -> Tensor v2 t -- ^ __sparse_values__: 1-D.  The `values` of the minibatch `SparseTensor`.
                             -> Tensor v3 Data.Int.Int64 -- ^ __sparse_shape__: 1-D.  The `shape` of the minibatch `SparseTensor`.
                                                         -- The minibatch size `N == sparse_shape[0]`.
                             -> Build (Tensor Value Data.Int.Int64) -- ^ __sparse_handles__: 1-D.  The handles of the `SparseTensor` now stored in the
                             -- `SparseTensorsMap`.  Shape: `[N]`.
addManySparseToTensorsMap sparse_indices sparse_values
                          sparse_shape | eqLengthGuard [] =
    buildOp (opDef "AddManySparseToTensorsMap"
             & opAttr "T" .~ tensorType (undefined :: t))
        sparse_indices sparse_values sparse_shape
{-
attr { name: "T" type: "type" }
attr {
  default_value { s: "" }
  description: "The container name for the `SparseTensorsMap` created by this op."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "The shared name for the `SparseTensorsMap` created by this op.\nIf blank, the new Operation\'s unique name is used."
  name: "shared_name"
  type: "string"
}
input_arg {
  description: "2-D.  The `indices` of the minibatch `SparseTensor`.\n`sparse_indices[:, 0]` must be ordered values in `[0, N)`."
  name: "sparse_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  The `values` of the minibatch `SparseTensor`."
  name: "sparse_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  The `shape` of the minibatch `SparseTensor`.\nThe minibatch size `N == sparse_shape[0]`."
  name: "sparse_shape"
  type: DT_INT64
}
output_arg {
  description: "1-D.  The handles of the `SparseTensor` now stored in the\n`SparseTensorsMap`.  Shape: `[N]`."
  name: "sparse_handles"
  type: DT_INT64
}
-}

-- | 

batchIFFT :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
             -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchIFFT input | eqLengthGuard [] =
    buildOp (opDef "BatchIFFT")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | 

batchMatrixDeterminant :: forall v1 t . (TensorType t, OneOf '[Double,
                                                               Float] t) =>
                          Tensor v1 t -- ^ __input__
                          -> Tensor Value t -- ^ __output__
batchMatrixDeterminant input | eqLengthGuard [] =
    buildOp (opDef "BatchMatrixDeterminant"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Delete the tensor specified by its handle in the session.

deleteSessionTensor :: Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle for a tensor stored in the session state.
                       -> ControlNode
deleteSessionTensor handle | eqLengthGuard [] =
    buildOp (opDef "DeleteSessionTensor")
        handle
{-
input_arg {
  description: "The handle for a tensor stored in the session state."
  name: "handle"
  type: DT_STRING
}
-}

-- | Computes the number of elements in the given table.

lookupTableSize :: Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to the table.
                   -> Build (Tensor Value Data.Int.Int64) -- ^ __size__: Scalar that contains number of elements in the table.
lookupTableSize table_handle | eqLengthGuard [] =
    buildOp (opDef "LookupTableSize")
        table_handle
{-
input_arg {
  description: "Handle to the table."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
output_arg {
  description: "Scalar that contains number of elements in the table."
  name: "size"
  type: DT_INT64
}
-}

-- | Computes rectified linear: `max(features, 0)`.

relu :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                             Data.Int.Int64, Data.Int.Int8,
                                             Data.Word.Word16, Data.Word.Word8,
                                             Double, Float] t) =>
        Tensor v1 t -- ^ __features__
        -> Tensor Value t -- ^ __activations__
relu features | eqLengthGuard [] =
    buildOp (opDef "Relu"
             & opAttr "T" .~ tensorType (undefined :: t))
        features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "features" type_attr: "T" }
output_arg { name: "activations" type_attr: "T" }
-}

-- | Interleave the values from the `data` tensors into a single tensor.
--
-- Builds a merged tensor such that
-- 
-- ```python
--     merged[indices[m][i, ..., j], ...] = data[m][i, ..., j, ...]
-- ```
-- 
-- For example, if each `indices[m]` is scalar or vector, we have
-- 
-- ```python
--     # Scalar indices:
--     merged[indices[m], ...] = data[m][...]
-- 
--     # Vector indices:
--     merged[indices[m][i], ...] = data[m][i, ...]
-- ```
-- 
-- Each `data[i].shape` must start with the corresponding `indices[i].shape`,
-- and the rest of `data[i].shape` must be constant w.r.t. `i`.  That is, we
-- must have `data[i].shape = indices[i].shape + constant`.  In terms of this
-- `constant`, the output shape is
-- 
--     merged.shape = [max(indices)] + constant
-- 
-- Values are merged in order, so if an index appears in both `indices[m][i]` and
-- `indices[n][j]` for `(m,i) < (n,j)` the slice `data[n][j]` will appear in the
-- merged result.
-- 
-- For example:
-- 
-- ```python
--     indices[0] = 6
--     indices[1] = [4, 1]
--     indices[2] = [[5, 2], [0, 3]]
--     data[0] = [61, 62]
--     data[1] = [[41, 42], [11, 12]]
--     data[2] = [[[51, 52], [21, 22]], [[1, 2], [31, 32]]]
--     merged = [[1, 2], [11, 12], [21, 22], [31, 32], [41, 42],
--               [51, 52], [61, 62]]
-- ```
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/DynamicStitch.png" alt>
-- </div>
dynamicStitch :: forall v1 v2 t . (TensorType t) =>
                 [Tensor v1 Data.Int.Int32] -- ^ __indices__
                 -> [Tensor v2 t] -- ^ __data__
                 -> Tensor Value t -- ^ __merged__
dynamicStitch indices data' | eqLengthGuard [("N", [("indices", length indices),
                                                    ("data", length data')])] =
    buildOp (opDef "DynamicStitch"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        indices data'
  where
    n = fromIntegral (length indices) :: Int64
{-
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
attr { name: "T" type: "type" }
input_arg { name: "indices" number_attr: "N" type: DT_INT32 }
input_arg { name: "data" number_attr: "N" type_attr: "T" }
output_arg { name: "merged" type_attr: "T" }
-}

-- | Looks up keys in a table, outputs the corresponding values.
--
-- The tensor `keys` must of the same type as the keys of the table.
-- The output `values` is of the type of the table values.
-- 
-- The scalar `default_value` is the value output for keys not present in the
-- table. It must also be of the same type as the table values.
lookupTableFind :: forall v2 v3 tin tout . (TensorType tin, TensorType tout) =>
                   Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to the table.
                   -> Tensor v2 tin -- ^ __keys__: Any shape.  Keys to look up.
                   -> Tensor v3 tout -- ^ __default_value__
                   -> Build (Tensor Value tout) -- ^ __values__: Same shape as `keys`.  Values found in the table, or `default_values`
                   -- for missing keys.
lookupTableFind table_handle keys default_value | eqLengthGuard [] =
    buildOp (opDef "LookupTableFind"
             & opAttr "Tin" .~ tensorType (undefined :: tin)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        table_handle keys default_value
{-
attr { name: "Tin" type: "type" }
attr { name: "Tout" type: "type" }
input_arg {
  description: "Handle to the table."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
input_arg {
  description: "Any shape.  Keys to look up."
  name: "keys"
  type_attr: "Tin"
}
input_arg { name: "default_value" type_attr: "Tout" }
output_arg {
  description: "Same shape as `keys`.  Values found in the table, or `default_values`\nfor missing keys."
  name: "values"
  type_attr: "Tout"
}
-}

-- | Generate a single randomly distorted bounding box for an image.
--
-- Bounding box annotations are often supplied in addition to ground-truth labels
-- in image recognition or object localization tasks. A common technique for
-- training such a system is to randomly distort an image while preserving
-- its content, i.e. *data augmentation*. This Op outputs a randomly distorted
-- localization of an object, i.e. bounding box, given an `image_size`,
-- `bounding_boxes` and a series of constraints.
-- 
-- The output of this Op is a single bounding box that may be used to crop the
-- original image. The output is returned as 3 tensors: `begin`, `size` and
-- `bboxes`. The first 2 tensors can be fed directly into `tf.slice` to crop the
-- image. The latter may be supplied to `tf.image.draw_bounding_boxes` to visualize
-- what the bounding box looks like.
-- 
-- Bounding boxes are supplied and returned as `[y_min, x_min, y_max, x_max]`. The
-- bounding box coordinates are floats in `[0.0, 1.0]` relative to the width and
-- height of the underlying image.
-- 
-- For example,
-- 
-- ```python
--     # Generate a single distorted bounding box.
--     begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(
--         tf.shape(image),
--         bounding_boxes=bounding_boxes)
-- 
--     # Draw the bounding box in an image summary.
--     image_with_box = tf.image.draw_bounding_boxes(tf.expand_dims(image, 0),
--                                                   bbox_for_draw)
--     tf.image_summary('images_with_box', image_with_box)
-- 
--     # Employ the bounding box to distort the image.
--     distorted_image = tf.slice(image, begin, size)
-- ```
-- 
-- Note that if no bounding box information is available, setting
-- `use_image_if_no_bounding_boxes = true` will assume there is a single implicit
-- bounding box covering the whole image. If `use_image_if_no_bounding_boxes` is
-- false and no bounding boxes are supplied, an error is raised.
sampleDistortedBoundingBox :: forall v1 v2 t . (TensorType t,
                                                OneOf '[Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word8] t) =>
                              Tensor v1 t -- ^ __image_size__: 1-D, containing `[height, width, channels]`.
                              -> Tensor v2 Float -- ^ __bounding_boxes__: 3-D with shape `[batch, N, 4]` describing the N bounding boxes
                                                 -- associated with the image.
                              -> Build ((Tensor Value t, Tensor Value t,
                                         Tensor Value Float))
                              -- ^ (__begin__, __size__, __bboxes__)
                              --
                              -- * __begin__: 1-D, containing `[offset_height, offset_width, 0]`. Provide as input to
                              -- `tf.slice`.
                              --
                              -- * __size__: 1-D, containing `[target_height, target_width, -1]`. Provide as input to
                              -- `tf.slice`.
                              --
                              -- * __bboxes__: 3-D with shape `[1, 1, 4]` containing the distorted bounding box.
                              -- Provide as input to `tf.image.draw_bounding_boxes`.
sampleDistortedBoundingBox image_size bounding_boxes | eqLengthGuard [] =
    buildOp (opDef "SampleDistortedBoundingBox"
             & opAttr "T" .~ tensorType (undefined :: t))
        image_size bounding_boxes
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to non-zero, the random number\ngenerator is seeded by the given `seed`.  Otherwise, it is seeded by a random\nseed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  default_value { f: 0.1 }
  description: "The cropped area of the image must contain at least this\nfraction of any bounding box supplied."
  name: "min_object_covered"
  type: "float"
}
attr {
  default_value { list { f: 0.75 f: 1.33 } }
  description: "The cropped area of the image must have an aspect ratio =\nwidth / height within this range."
  name: "aspect_ratio_range"
  type: "list(float)"
}
attr {
  default_value { list { f: 5.0e-2 f: 1.0 } }
  description: "The cropped area of the image must contain a fraction of the\nsupplied image within in this range."
  name: "area_range"
  type: "list(float)"
}
attr {
  default_value { i: 100 }
  description: "Number of attempts at generating a cropped region of the image\nof the specified constraints. After `max_attempts` failures, return the entire\nimage."
  name: "max_attempts"
  type: "int"
}
attr {
  default_value { b: false }
  description: "Controls behavior if no bounding boxes supplied.\nIf true, assume an implicit bounding box covering the whole input. If false,\nraise an error."
  name: "use_image_if_no_bounding_boxes"
  type: "bool"
}
input_arg {
  description: "1-D, containing `[height, width, channels]`."
  name: "image_size"
  type_attr: "T"
}
input_arg {
  description: "3-D with shape `[batch, N, 4]` describing the N bounding boxes\nassociated with the image."
  name: "bounding_boxes"
  type: DT_FLOAT
}
output_arg {
  description: "1-D, containing `[offset_height, offset_width, 0]`. Provide as input to\n`tf.slice`."
  name: "begin"
  type_attr: "T"
}
output_arg {
  description: "1-D, containing `[target_height, target_width, -1]`. Provide as input to\n`tf.slice`."
  name: "size"
  type_attr: "T"
}
output_arg {
  description: "3-D with shape `[1, 1, 4]` containing the distorted bounding box.\nProvide as input to `tf.image.draw_bounding_boxes`."
  name: "bboxes"
  type: DT_FLOAT
}
-}

-- | Splits a tensor into `num_split` tensors along one dimension.

splitV :: forall v1 v2 v3 t tlen . (TensorType t, TensorType tlen,
                                    OneOf '[Data.Int.Int32,
                                            Data.Int.Int64] tlen) =>
          Data.Int.Int64 -- ^ __num_split__
          -> Tensor v1 t -- ^ __value__: The tensor to split.
          -> Tensor v2 tlen -- ^ __size_splits__: list containing the sizes of each output tensor along the split
                            -- dimension. Must sum to the dimension of value along split_dim.
                            -- Can contain one -1 indicating that dimension is to be inferred.
          -> Tensor v3 Data.Int.Int32 -- ^ __split_dim__: 0-D.  The dimension along which to split.  Must be in the range
                                      -- `[0, rank(value))`.
          -> [Tensor Value t] -- ^ __output__: Tensors whose shape matches that of `value`
          -- except along `split_dim`, where their sizes are
          -- `size_splits[i]`.
splitV num_split value size_splits split_dim | eqLengthGuard [] =
    buildListOp [num_split] (opDef "SplitV"
                             & opAttr "T" .~ tensorType (undefined :: t)
                             & opAttr "Tlen" .~ tensorType (undefined :: tlen)
                             & opAttr "num_split" .~ num_split)
        value size_splits split_dim
{-
attr { has_minimum: true minimum: 1 name: "num_split" type: "int" }
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT64 }
  name: "Tlen"
  type: "type"
}
input_arg {
  description: "The tensor to split." name: "value" type_attr: "T"
}
input_arg {
  description: "list containing the sizes of each output tensor along the split\ndimension. Must sum to the dimension of value along split_dim.\nCan contain one -1 indicating that dimension is to be inferred."
  name: "size_splits"
  type_attr: "Tlen"
}
input_arg {
  description: "0-D.  The dimension along which to split.  Must be in the range\n`[0, rank(value))`."
  name: "split_dim"
  type: DT_INT32
}
output_arg {
  description: "Tensors whose shape matches that of `value`\nexcept along `split_dim`, where their sizes are\n`size_splits[i]`."
  name: "output"
  number_attr: "num_split"
  type_attr: "T"
}
-}

-- | Performs a padding as a preprocess during a convolution.
--
-- Similar to FusedResizeAndPadConv2d, this op allows for an optimized
-- implementation where the spatial padding transformation stage is fused with the
-- im2col lookup, but in this case without the bilinear filtering required for
-- resizing. Fusing the padding prevents the need to write out the intermediate
-- results as whole tensors, reducing memory pressure, and we can get some latency
-- gains by merging the transformation calculations.
-- The data_format attribute for Conv2D isn't supported by this op, and 'NHWC'
-- order is used instead.
-- Internally this op uses a single per-graph scratch buffer, which means that it
-- will block if multiple versions are being run in parallel. This is because this
-- operator is primarily an optimization to minimize memory usage.
fusedPadConv2D :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                             Double,
                                                             Float] t) =>
                  Tensor v1 t -- ^ __input__: 4-D with shape `[batch, in_height, in_width, in_channels]`.
                  -> Tensor v2 Data.Int.Int32 -- ^ __paddings__: A two-column matrix specifying the padding sizes. The number of
                                              -- rows must be the same as the rank of `input`.
                  -> Tensor v3 t -- ^ __filter__: 4-D with shape
                                 -- `[filter_height, filter_width, in_channels, out_channels]`.
                  -> Tensor Value t -- ^ __output__
fusedPadConv2D input paddings filter | eqLengthGuard [] =
    buildOp (opDef "FusedPadConv2D"
             & opAttr "T" .~ tensorType (undefined :: t))
        input paddings filter
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "REFLECT" s: "SYMMETRIC" } }
  name: "mode"
  type: "string"
}
attr {
  description: "1-D of length 4.  The stride of the sliding window for each dimension\nof `input`. Must be in the same order as the dimension specified with format."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "4-D with shape `[batch, in_height, in_width, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "A two-column matrix specifying the padding sizes. The number of\nrows must be the same as the rank of `input`."
  name: "paddings"
  type: DT_INT32
}
input_arg {
  description: "4-D with shape\n`[filter_height, filter_width, in_channels, out_channels]`."
  name: "filter"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | For each key, assigns the respective value to the specified component.
--
-- If a key is not found in the barrier, this operation will create a new
-- incomplete element. If a key is found in the barrier, and the element
-- already has a value at component_index, this operation will fail with
-- INVALID_ARGUMENT, and leave the barrier in an undefined state.
barrierInsertMany :: forall v2 v3 t . (TensorType t) =>
                     Data.Int.Int64 -- ^ __component_index__: The component of the barrier elements that is being assigned.
                     -> Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a barrier.
                     -> Tensor v2 Data.ByteString.ByteString -- ^ __keys__: A one-dimensional tensor of keys, with length n.
                     -> Tensor v3 t -- ^ __values__: An any-dimensional tensor of values, which are associated with the
                                    -- respective keys. The 0th dimension must have length n.
                     -> Build (ControlNode)
barrierInsertMany component_index handle keys values | eqLengthGuard [] =
    buildOp (opDef "BarrierInsertMany"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "component_index" .~ component_index)
        handle keys values
{-
attr { name: "T" type: "type" }
attr {
  description: "The component of the barrier elements that is being assigned."
  name: "component_index"
  type: "int"
}
input_arg {
  description: "The handle to a barrier."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "A one-dimensional tensor of keys, with length n."
  name: "keys"
  type: DT_STRING
}
input_arg {
  description: "An any-dimensional tensor of values, which are associated with the\nrespective keys. The 0th dimension must have length n."
  name: "values"
  type_attr: "T"
}
-}

-- | Raise a exception to abort the process when called.
--
-- Returns nothing but an exception.
abort :: ControlNode
abort  | eqLengthGuard [] =
    buildOp (opDef "Abort")
        
{-
attr {
  default_value { s: "" }
  description: "A string which is the message associated with the exception."
  name: "error_msg"
  type: "string"
}
-}

-- | Performs max pooling on the input and outputs both max values and indices.
--
-- The indices in `argmax` are flattened, so that a maximum value at position
-- `[b, y, x, c]` becomes flattened index
-- `((b * height + y) * width + x) * channels + c`.
maxPoolWithArgmax :: forall v1 targmax t . (TensorType targmax,
                                            OneOf '[Data.Int.Int32,
                                                    Data.Int.Int64] targmax,
                                            TensorType t,
                                            OneOf '[Data.Word.Word16,
                                                    Float] t) =>
                     Tensor v1 t -- ^ __input__: 4-D with shape `[batch, height, width, channels]`.  Input to pool over.
                     -> (Tensor Value t, Tensor Value targmax)
                     -- ^ (__output__, __argmax__)
                     --
                     -- * __output__: The max pooled output tensor.
                     --
                     -- * __argmax__: 4-D.  The flattened indices of the max values chosen for each output.
maxPoolWithArgmax input | eqLengthGuard [] =
    buildOp (opDef "MaxPoolWithArgmax"
             & opAttr "Targmax" .~ tensorType (undefined :: targmax)
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  description: "The size of the window for each dimension of the input tensor."
  has_minimum: true
  minimum: 4
  name: "ksize"
  type: "list(int)"
}
attr {
  description: "The stride of the sliding window for each dimension of the\ninput tensor."
  has_minimum: true
  minimum: 4
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT64 }
  name: "Targmax"
  type: "type"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`.  Input to pool over."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The max pooled output tensor."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "4-D.  The flattened indices of the max values chosen for each output."
  name: "argmax"
  type_attr: "Targmax"
}
-}

-- | Creates or finds a child frame, and makes `data` available to the child frame.
--
-- The unique `frame_name` is used by the `Executor` to identify frames. If
-- `is_constant` is true, `output` is a constant in the child frame; otherwise
-- it may be changed in the child frame. At most `parallel_iterations` iterations
-- are run in parallel in the child frame.
refEnter :: forall t . (TensorType t) =>
            Tensor Ref t -- ^ __data__: The tensor to be made available to the child frame.
            -> Build (Tensor Ref t) -- ^ __output__: The same tensor as `data`.
refEnter data' | eqLengthGuard [] =
    buildOp (opDef "RefEnter"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
attr {
  description: "The name of the child frame."
  name: "frame_name"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If true, the output is constant within the child frame."
  name: "is_constant"
  type: "bool"
}
attr {
  default_value { i: 10 }
  description: "The number of iterations allowed to run in parallel."
  name: "parallel_iterations"
  type: "int"
}
input_arg {
  description: "The tensor to be made available to the child frame."
  is_ref: true
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  is_ref: true
  name: "output"
  type_attr: "T"
}
-}

-- | Dequantize the 'input' tensor into a float Tensor.
--
-- [min_range, max_range] are scalar floats that specify the range for
-- the 'input' data. The 'mode' attribute controls exactly which calculations are
-- used to convert the float values to their quantized equivalents.
-- 
-- In 'MIN_COMBINED' mode, each value of the tensor will undergo the following:
-- 
-- ```
-- if T == qint8, in[i] += (range(T) + 1)/ 2.0
-- out[i] = min_range + (in[i]* (max_range - min_range) / range(T))
-- ```
-- here `range(T) = numeric_limits<T>::max() - numeric_limits<T>::min()`
-- 
-- *MIN_COMBINED Mode Example*
-- 
-- If the input comes from a QuantizedRelu6, the output type is
-- quint8 (range of 0-255) but the possible range of QuantizedRelu6 is
-- 0-6.  The min_range and max_range values are therefore 0.0 and 6.0.
-- Dequantize on quint8 will take each value, cast to float, and multiply
-- by 6 / 255.
-- Note that if quantizedtype is qint8, the operation will additionally add
-- each value by 128 prior to casting.
-- 
-- If the mode is 'MIN_FIRST', then this approach is used:
-- 
-- ```
-- number_of_steps = 1 << (# of bits in T)
-- range_adjust = number_of_steps / (number_of_steps - 1)
-- range = (range_max - range_min) * range_adjust
-- range_scale = range / number_of_steps
-- const double offset_input = static_cast<double>(input) - lowest_quantized;
-- result = range_min + ((input - numeric_limits<T>::min()) * range_scale)
-- ```
dequantize :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                         Data.Int.Int32,
                                                         Data.Word.Word16,
                                                         Data.Word.Word8] t) =>
              Tensor v1 t -- ^ __input__
              -> Tensor v2 Float -- ^ __min_range__: The minimum scalar value possibly produced for the input.
              -> Tensor v3 Float -- ^ __max_range__: The maximum scalar value possibly produced for the input.
              -> Tensor Value Float -- ^ __output__
dequantize input min_range max_range | eqLengthGuard [] =
    buildOp (opDef "Dequantize"
             & opAttr "T" .~ tensorType (undefined :: t))
        input min_range max_range
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { s: "MIN_COMBINED" s: "MIN_FIRST" } }
  default_value { s: "MIN_COMBINED" }
  name: "mode"
  type: "string"
}
input_arg { name: "input" type_attr: "T" }
input_arg {
  description: "The minimum scalar value possibly produced for the input."
  name: "min_range"
  type: DT_FLOAT
}
input_arg {
  description: "The maximum scalar value possibly produced for the input."
  name: "max_range"
  type: DT_FLOAT
}
output_arg { name: "output" type: DT_FLOAT }
-}

-- | Draw bounding boxes on a batch of images.
--
-- Outputs a copy of `images` but draws on top of the pixels zero or more bounding
-- boxes specified by the locations in `boxes`. The coordinates of the each
-- bounding box in `boxes` are encoded as `[y_min, x_min, y_max, x_max]`. The
-- bounding box coordinates are floats in `[0.0, 1.0]` relative to the width and
-- height of the underlying image.
-- 
-- For example, if an image is 100 x 200 pixels and the bounding box is
-- `[0.1, 0.2, 0.5, 0.9]`, the bottom-left and upper-right coordinates of the
-- bounding box will be `(10, 40)` to `(50, 180)`.
-- 
-- Parts of the bounding box may fall outside the image.
drawBoundingBoxes :: forall v1 v2 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                             Float] t) =>
                     Tensor v1 t -- ^ __images__: 4-D with shape `[batch, height, width, depth]`. A batch of images.
                     -> Tensor v2 Float -- ^ __boxes__: 3-D with shape `[batch, num_bounding_boxes, 4]` containing bounding
                                        -- boxes.
                     -> Tensor Value t -- ^ __output__: 4-D with the same shape as `images`. The batch of input images with
                     -- bounding boxes drawn on the images.
drawBoundingBoxes images boxes | eqLengthGuard [] =
    buildOp (opDef "DrawBoundingBoxes"
             & opAttr "T" .~ tensorType (undefined :: t))
        images boxes
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_HALF } }
  default_value { type: DT_FLOAT }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, depth]`. A batch of images."
  name: "images"
  type_attr: "T"
}
input_arg {
  description: "3-D with shape `[batch, num_bounding_boxes, 4]` containing bounding\nboxes."
  name: "boxes"
  type: DT_FLOAT
}
output_arg {
  description: "4-D with the same shape as `images`. The batch of input images with\nbounding boxes drawn on the images."
  name: "output"
  type_attr: "T"
}
-}

-- | 

tensorArraySplit :: forall v2 v3 v4 t . (TensorType t) =>
                    Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                    -> Tensor v2 t -- ^ __value__
                    -> Tensor v3 Data.Int.Int64 -- ^ __lengths__
                    -> Tensor v4 Float -- ^ __flow_in__
                    -> Build (Tensor Value Float) -- ^ __flow_out__
tensorArraySplit handle value lengths flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArraySplit"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle value lengths flow_in
{-
attr { name: "T" type: "type" }
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "value" type_attr: "T" }
input_arg { name: "lengths" type: DT_INT64 }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "flow_out" type: DT_FLOAT }
-}

-- | Converts each string in the input Tensor to its hash mod by a number of buckets.
--
-- The hash function is deterministic on the content of the string within the
-- process and will never change. However, it is not suitable for cryptography.
-- This function may be used when CPU time is scarce and inputs are trusted or
-- unimportant. There is a risk of adversaries constructing inputs that all hash
-- to the same bucket. To prevent this problem, use a strong hash function with
-- `tf.string_to_hash_bucket_strong`.
stringToHashBucketFast :: Data.Int.Int64 -- ^ __num_buckets__: The number of buckets.
                          -> Tensor v1 Data.ByteString.ByteString -- ^ __input__: The strings to assign a hash bucket.
                          -> Tensor Value Data.Int.Int64 -- ^ __output__: A Tensor of the same shape as the input `string_tensor`.
stringToHashBucketFast num_buckets input | eqLengthGuard [] =
    buildOp (opDef "StringToHashBucketFast"
             & opAttr "num_buckets" .~ num_buckets)
        input
{-
attr {
  description: "The number of buckets."
  has_minimum: true
  minimum: 1
  name: "num_buckets"
  type: "int"
}
input_arg {
  description: "The strings to assign a hash bucket."
  name: "input"
  type: DT_STRING
}
output_arg {
  description: "A Tensor of the same shape as the input `string_tensor`."
  name: "output"
  type: DT_INT64
}
-}

-- | 

tensorArrayScatter :: forall v2 v3 v4 t . (TensorType t) =>
                      Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                      -> Tensor v2 Data.Int.Int32 -- ^ __indices__
                      -> Tensor v3 t -- ^ __value__
                      -> Tensor v4 Float -- ^ __flow_in__
                      -> Build (Tensor Value Float) -- ^ __flow_out__
tensorArrayScatter handle indices value flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayScatter"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle indices value flow_in
{-
attr { name: "T" type: "type" }
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "indices" type: DT_INT32 }
input_arg { name: "value" type_attr: "T" }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "flow_out" type: DT_FLOAT }
-}

-- | Returns a one-hot tensor.
--
-- The locations represented by indices in `indices` take value `on_value`,
-- while all other locations take value `off_value`.
-- 
-- If the input `indices` is rank `N`, the output will have rank `N+1`,
-- The new axis is created at dimension `axis` (default: the new axis is
-- appended at the end).
-- 
-- If `indices` is a scalar the output shape will be a vector of length `depth`.
-- 
-- If `indices` is a vector of length `features`, the output shape will be:
-- ```
--   features x depth if axis == -1
--   depth x features if axis == 0
-- ```
-- 
-- If `indices` is a matrix (batch) with shape `[batch, features]`,
-- the output shape will be:
-- ```
--   batch x features x depth if axis == -1
--   batch x depth x features if axis == 1
--   depth x batch x features if axis == 0
-- ```
-- 
-- 
-- Examples
-- =========
-- 
-- Suppose that
-- 
-- ```
--   indices = [0, 2, -1, 1]
--   depth = 3
--   on_value = 5.0
--   off_value = 0.0
--   axis = -1
-- ```
-- 
-- Then output is `[4 x 3]`:
-- 
--     ```output =
--       [5.0 0.0 0.0]  // one_hot(0)
--       [0.0 0.0 5.0]  // one_hot(2)
--       [0.0 0.0 0.0]  // one_hot(-1)
--       [0.0 5.0 0.0]  // one_hot(1)
--     ```
-- 
-- Suppose that
-- 
-- ```
--   indices = [0, 2, -1, 1]
--   depth = 3
--   on_value = 0.0
--   off_value = 3.0
--   axis = 0
-- ```
-- 
-- Then output is `[3 x 4]`:
-- 
--     ```output =
--       [0.0 3.0 3.0 3.0]
--       [3.0 3.0 3.0 0.0]
--       [3.0 3.0 3.0 3.0]
--       [3.0 0.0 3.0 3.0]
--     //  ^                one_hot(0)
--     //      ^            one_hot(2)
--     //          ^        one_hot(-1)
--     //              ^    one_hot(1)
--     ```
-- Suppose that
-- 
-- ```
--   indices = [[0, 2], [1, -1]]
--   depth = 3
--   on_value = 1.0
--   off_value = 0.0
--   axis = -1
-- ```
-- 
-- Then output is `[2 x 2 x 3]`:
-- 
--     ```output =
--       [
--         [1.0, 0.0, 0.0]  // one_hot(0)
--         [0.0, 0.0, 1.0]  // one_hot(2)
--       ][
--         [0.0, 1.0, 0.0]  // one_hot(1)
--         [0.0, 0.0, 0.0]  // one_hot(-1)
--       ]```
oneHot :: forall v1 v2 v3 v4 t tI . (TensorType t, TensorType tI,
                                     OneOf '[Data.Int.Int32, Data.Int.Int64,
                                             Data.Word.Word8] tI) =>
          Tensor v1 tI -- ^ __indices__: A tensor of indices.
          -> Tensor v2 Data.Int.Int32 -- ^ __depth__: A scalar defining the depth of the one hot dimension.
          -> Tensor v3 t -- ^ __on_value__: A scalar defining the value to fill in output when `indices[j] = i`.
          -> Tensor v4 t -- ^ __off_value__: A scalar defining the value to fill in output when `indices[j] != i`.
          -> Tensor Value t -- ^ __output__: The one-hot tensor.
oneHot indices depth on_value off_value | eqLengthGuard [] =
    buildOp (opDef "OneHot"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "TI" .~ tensorType (undefined :: tI))
        indices depth on_value off_value
{-
attr {
  default_value { i: -1 }
  description: "The axis to fill (default: -1, a new inner-most axis)."
  name: "axis"
  type: "int"
}
attr { name: "T" type: "type" }
attr {
  allowed_values {
    list { type: DT_UINT8 type: DT_INT32 type: DT_INT64 }
  }
  default_value { type: DT_INT64 }
  name: "TI"
  type: "type"
}
input_arg {
  description: "A tensor of indices." name: "indices" type_attr: "TI"
}
input_arg {
  description: "A scalar defining the depth of the one hot dimension."
  name: "depth"
  type: DT_INT32
}
input_arg {
  description: "A scalar defining the value to fill in output when `indices[j] = i`."
  name: "on_value"
  type_attr: "T"
}
input_arg {
  description: "A scalar defining the value to fill in output when `indices[j] != i`."
  name: "off_value"
  type_attr: "T"
}
output_arg {
  description: "The one-hot tensor." name: "output" type_attr: "T"
}
-}

-- | 

batchIFFT3D :: Tensor v1 (Data.Complex.Complex Float) -- ^ __input__
               -> Tensor Value (Data.Complex.Complex Float) -- ^ __output__
batchIFFT3D input | eqLengthGuard [] =
    buildOp (opDef "BatchIFFT3D")
        input
{-
input_arg { name: "input" type: DT_COMPLEX64 }
output_arg { name: "output" type: DT_COMPLEX64 }
-}

-- | Reinterpret the bytes of a string as a vector of numbers.

decodeRaw :: forall v1 out_type . (TensorType out_type, OneOf '[Data.Int.Int16,
                                                                Data.Int.Int32,
                                                                Data.Int.Int64,
                                                                Data.Int.Int8,
                                                                Data.Word.Word16,
                                                                Data.Word.Word8,
                                                                Double,
                                                                Float] out_type) =>
             Tensor v1 Data.ByteString.ByteString -- ^ __bytes__: All the elements must have the same length.
             -> Tensor Value out_type -- ^ __output__: A Tensor with one more dimension than the input `bytes`.  The
             -- added dimension will have size equal to the length of the elements
             -- of `bytes` divided by the number of bytes to represent `out_type`.
decodeRaw bytes | eqLengthGuard [] =
    buildOp (opDef "DecodeRaw"
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        bytes
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_INT64
    }
  }
  name: "out_type"
  type: "type"
}
attr {
  default_value { b: true }
  description: "Whether the input `bytes` are in little-endian order.\nIgnored for `out_type` values that are stored in a single byte like\n`uint8`."
  name: "little_endian"
  type: "bool"
}
input_arg {
  description: "All the elements must have the same length."
  name: "bytes"
  type: DT_STRING
}
output_arg {
  description: "A Tensor with one more dimension than the input `bytes`.  The\nadded dimension will have size equal to the length of the elements\nof `bytes` divided by the number of bytes to represent `out_type`."
  name: "output"
  type_attr: "out_type"
}
-}

-- | 

tensorArrayPack :: forall v2 dtype . (TensorType dtype) =>
                   Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                   -> Tensor v2 Float -- ^ __flow_in__
                   -> Build (Tensor Value dtype) -- ^ __value__
tensorArrayPack handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayPack"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle flow_in
{-
attr { name: "dtype" type: "type" }
attr {
  default_value { shape { unknown_rank: true } }
  name: "element_shape"
  type: "shape"
}
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "value" type_attr: "dtype" }
-}

-- | Update '*var' and '*accum' according to FOBOS with Adagrad learning rate.
--
-- accum += grad * grad
-- prox_v = var - lr * grad * (1 / sqrt(accum))
-- var = sign(prox_v)/(1+lr*l2) * max{|prox_v|-lr*l1,0}
applyProximalAdagrad :: forall v3 v4 v5 v6 t . (TensorType t,
                                                OneOf '[(Data.Complex.Complex Double),
                                                        (Data.Complex.Complex Float),
                                                        Data.Int.Int16,
                                                        Data.Int.Int32,
                                                        Data.Int.Int64,
                                                        Data.Int.Int8,
                                                        Data.Word.Word16,
                                                        Data.Word.Word8, Double,
                                                        Float] t) =>
                        Tensor Ref t -- ^ __var__: Should be from a Variable().
                        -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
                        -> Tensor v3 t -- ^ __lr__: Scaling factor. Must be a scalar.
                        -> Tensor v4 t -- ^ __l1__: L1 regularization. Must be a scalar.
                        -> Tensor v5 t -- ^ __l2__: L2 regularization. Must be a scalar.
                        -> Tensor v6 t -- ^ __grad__: The gradient.
                        -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyProximalAdagrad var accum lr l1 l2 grad | eqLengthGuard [] =
    buildOp (opDef "ApplyProximalAdagrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        var accum lr l1 l2 grad
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, updating of the var and accum tensors will be protected by\na lock; otherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regularization. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regularization. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Applies a sparse gradient to a given accumulator. Does not add if local_step is
--
-- lesser than the accumulator's global_step.
sparseAccumulatorApplyGradient :: forall v2 v3 v4 v5 dtype . (TensorType dtype,
                                                              OneOf '[(Data.Complex.Complex Double),
                                                                      (Data.Complex.Complex Float),
                                                                      Data.Int.Int16,
                                                                      Data.Int.Int32,
                                                                      Data.Int.Int64,
                                                                      Data.Int.Int8,
                                                                      Data.Word.Word16,
                                                                      Data.Word.Word8,
                                                                      Double,
                                                                      Float] dtype) =>
                                  Bool -- ^ __has_known_shape__: Boolean indicating whether gradient_shape is unknown, in which
                                       -- case the input is ignored during validation.
                                  -> Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a accumulator.
                                  -> Tensor v2 Data.Int.Int64 -- ^ __local_step__: The local_step value at which the sparse gradient was computed.
                                  -> Tensor v3 Data.Int.Int64 -- ^ __gradient_indices__: Indices of the sparse gradient to be accumulated. Must be a
                                                              -- vector.
                                  -> Tensor v4 dtype -- ^ __gradient_values__: Values are the non-zero slices of the gradient, and must have
                                                     -- the same first dimension as indices, i.e., the nnz represented by indices and
                                                     -- values must be consistent.
                                  -> Tensor v5 Data.Int.Int64 -- ^ __gradient_shape__: Shape of the sparse gradient to be accumulated.
                                  -> Build (ControlNode)
sparseAccumulatorApplyGradient has_known_shape handle local_step
                               gradient_indices gradient_values
                               gradient_shape | eqLengthGuard [] =
    buildOp (opDef "SparseAccumulatorApplyGradient"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "has_known_shape" .~ has_known_shape)
        handle local_step gradient_indices gradient_values gradient_shape
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type of accumulated gradients. Needs to correspond to the type\nof the accumulator."
  name: "dtype"
  type: "type"
}
attr {
  description: "Boolean indicating whether gradient_shape is unknown, in which\ncase the input is ignored during validation."
  name: "has_known_shape"
  type: "bool"
}
input_arg {
  description: "The handle to a accumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The local_step value at which the sparse gradient was computed."
  name: "local_step"
  type: DT_INT64
}
input_arg {
  description: "Indices of the sparse gradient to be accumulated. Must be a\nvector."
  name: "gradient_indices"
  type: DT_INT64
}
input_arg {
  description: "Values are the non-zero slices of the gradient, and must have\nthe same first dimension as indices, i.e., the nnz represented by indices and\nvalues must be consistent."
  name: "gradient_values"
  type_attr: "dtype"
}
input_arg {
  description: "Shape of the sparse gradient to be accumulated."
  name: "gradient_shape"
  type: DT_INT64
}
-}

-- | Returns x + y element-wise.
--
-- *NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
add :: forall v1 v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.ByteString.ByteString,
                                               Data.Int.Int16, Data.Int.Int32,
                                               Data.Int.Int64, Data.Int.Int8,
                                               Data.Word.Word16,
                                               Data.Word.Word8, Double,
                                               Float] t) =>
       Tensor v1 t -- ^ __x__
       -> Tensor v2 t -- ^ __y__
       -> Tensor Value t -- ^ __z__
add x y | eqLengthGuard [] =
    buildOp (opDef "Add"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_STRING
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Computes softsign: `features / (abs(features) + 1)`.

softsign :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t) =>
            Tensor v1 t -- ^ __features__
            -> Tensor Value t -- ^ __activations__
softsign features | eqLengthGuard [] =
    buildOp (opDef "Softsign"
             & opAttr "T" .~ tensorType (undefined :: t))
        features
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "features" type_attr: "T" }
output_arg { name: "activations" type_attr: "T" }
-}

-- | 

tensorArrayRead :: forall v2 v3 dtype . (TensorType dtype) =>
                   Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                   -> Tensor v2 Data.Int.Int32 -- ^ __index__
                   -> Tensor v3 Float -- ^ __flow_in__
                   -> Build (Tensor Value dtype) -- ^ __value__
tensorArrayRead handle index flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayRead"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle index flow_in
{-
attr { name: "dtype" type: "type" }
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "index" type: DT_INT32 }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "value" type_attr: "dtype" }
-}

-- | Applies sparse subtraction between `updates` and individual values or slices
--
-- within a given variable according to `indices`.
-- 
-- `ref` is a `Tensor` with rank `P` and `indices` is a `Tensor` of rank `Q`.
-- 
-- `indices` must be integer tensor, containing indices into `ref`.
-- It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
-- 
-- The innermost dimension of `indices` (with length `K`) corresponds to
-- indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
-- dimension of `ref`.
-- 
-- `updates` is `Tensor` of rank `Q-1+P-K` with shape:
-- 
-- ```
-- [d_0, ..., d_{Q-2}, ref.shape[K], ..., ref.shape[P-1]].
-- ```
-- 
-- For example, say we want to subtract 4 scattered elements from a rank-1 tensor
-- with 8 elements. In Python, that subtraction would look like this:
-- 
--     ref = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8])
--     indices = tf.constant([[4], [3], [1], [7]])
--     updates = tf.constant([9, 10, 11, 12])
--     sub = tf.scatter_nd_sub(ref, indices, updates)
--     with tf.Session() as sess:
--       print sess.run(sub)
-- 
-- The resulting update to ref would look like this:
-- 
--     [1, -9, 3, -6, -4, 6, 7, -4]
-- 
-- See [tf.scatter_nd](#scatter_nd) for more details about how to make updates to
-- slices.
scatterNdSub :: forall v2 v3 t tindices . (TensorType t,
                                           OneOf '[(Data.Complex.Complex Double),
                                                   (Data.Complex.Complex Float),
                                                   Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t,
                                           TensorType tindices,
                                           OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64] tindices) =>
                Tensor Ref t -- ^ __ref__: A mutable Tensor. Should be from a Variable node.
                -> Tensor v2 tindices -- ^ __indices__: A Tensor. Must be one of the following types: int32, int64.
                                      -- A tensor of indices into ref.
                -> Tensor v3 t -- ^ __updates__: A Tensor. Must have the same type as ref. A tensor of updated values
                               -- to subtract from ref.
                -> Build (Tensor Ref t) -- ^ __output_ref__: Same as ref. Returned as a convenience for operations that want
                -- to use the updated values after the update is done.
scatterNdSub ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterNdSub"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "An optional bool. Defaults to True. If True, the assignment will\nbe protected by a lock; otherwise the behavior is undefined,\nbut may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "A mutable Tensor. Should be from a Variable node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A Tensor. Must be one of the following types: int32, int64.\nA tensor of indices into ref."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A Tensor. Must have the same type as ref. A tensor of updated values\nto subtract from ref."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "Same as ref. Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Restores a tensor from checkpoint files.
--
-- This is like `Restore` except that restored tensor can be listed as filling
-- only a slice of a larger tensor.  `shape_and_slice` specifies the shape of the
-- larger tensor and the slice that the restored tensor covers.
-- 
-- The `shape_and_slice` input has the same format as the
-- elements of the `shapes_and_slices` input of the `SaveSlices` op.
restoreSlice :: forall v1 v2 v3 dt . (TensorType dt) =>
                Tensor v1 Data.ByteString.ByteString -- ^ __file_pattern__: Must have a single element. The pattern of the files from
                                                     -- which we read the tensor.
                -> Tensor v2 Data.ByteString.ByteString -- ^ __tensor_name__: Must have a single element. The name of the tensor to be
                                                        -- restored.
                -> Tensor v3 Data.ByteString.ByteString -- ^ __shape_and_slice__: Scalar. The shapes and slice specifications to use when
                                                        -- restoring a tensors.
                -> Tensor Value dt -- ^ __tensor__: The restored tensor.
restoreSlice file_pattern tensor_name shape_and_slice | eqLengthGuard [] =
    buildOp (opDef "RestoreSlice"
             & opAttr "dt" .~ tensorType (undefined :: dt))
        file_pattern tensor_name shape_and_slice
{-
attr {
  description: "The type of the tensor to be restored."
  name: "dt"
  type: "type"
}
attr {
  default_value { i: -1 }
  description: "Index of file to open first if multiple files match\n`file_pattern`. See the documentation for `Restore`."
  name: "preferred_shard"
  type: "int"
}
input_arg {
  description: "Must have a single element. The pattern of the files from\nwhich we read the tensor."
  name: "file_pattern"
  type: DT_STRING
}
input_arg {
  description: "Must have a single element. The name of the tensor to be\nrestored."
  name: "tensor_name"
  type: DT_STRING
}
input_arg {
  description: "Scalar. The shapes and slice specifications to use when\nrestoring a tensors."
  name: "shape_and_slice"
  type: DT_STRING
}
output_arg {
  description: "The restored tensor." name: "tensor" type_attr: "dt"
}
-}

-- | Update 'ref' by adding 'value' to it.
--
-- This operation outputs "ref" after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
assignAdd :: forall v2 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                                  (Data.Complex.Complex Float),
                                                  Data.Int.Int16,
                                                  Data.Int.Int32,
                                                  Data.Int.Int64, Data.Int.Int8,
                                                  Data.Word.Word16,
                                                  Data.Word.Word8, Double,
                                                  Float] t) =>
             Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
             -> Tensor v2 t -- ^ __value__: The value to be added to the variable.
             -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as "ref".  Returned as a convenience for operations that want
             -- to use the new value after the variable has been updated.
assignAdd ref value | eqLengthGuard [] =
    buildOp (opDef "AssignAdd"
             & opAttr "T" .~ tensorType (undefined :: t))
        ref value
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the addition will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "The value to be added to the variable."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "= Same as \"ref\".  Returned as a convenience for operations that want\nto use the new value after the variable has been updated."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Returns the truth value of (x > y) element-wise.
--
-- *NOTE*: `Greater` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
greater :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t) =>
           Tensor v1 t -- ^ __x__
           -> Tensor v2 t -- ^ __y__
           -> Tensor Value Bool -- ^ __z__
greater x y | eqLengthGuard [] =
    buildOp (opDef "Greater"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Returns the number of work units this Reader has finished processing.

readerNumWorkUnitsCompleted :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
                               -> Build (Tensor Value Data.Int.Int64) -- ^ __units_completed__
readerNumWorkUnitsCompleted reader_handle | eqLengthGuard [] =
    buildOp (opDef "ReaderNumWorkUnitsCompleted")
        reader_handle
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
output_arg { name: "units_completed" type: DT_INT64 }
-}

-- | Gather specific elements from the TensorArray into output `value`.
--
-- All elements selected by `indices` must have the same shape.
tensorArrayGatherV2 :: forall v1 v2 v3 dtype . (TensorType dtype) =>
                       Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                       -> Tensor v2 Data.Int.Int32 -- ^ __indices__: The locations in the TensorArray from which to read tensor elements.
                       -> Tensor v3 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                       -> Tensor Value dtype -- ^ __value__: All of the elements in the TensorArray, concatenated along a new
                       -- axis (the new dimension 0).
tensorArrayGatherV2 handle indices flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayGatherV2"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle indices flow_in
{-
attr {
  description: "The type of the elem that is returned."
  name: "dtype"
  type: "type"
}
attr {
  default_value { shape { unknown_rank: true } }
  description: "The expected shape of an element, if known. Used to\nvalidate the shapes of TensorArray elements. If this shape is not\nfully specified, gathering zero-size TensorArrays is an error."
  name: "element_shape"
  type: "shape"
}
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The locations in the TensorArray from which to read tensor elements."
  name: "indices"
  type: DT_INT32
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "All of the elements in the TensorArray, concatenated along a new\naxis (the new dimension 0)."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Read an element from the TensorArray into output `value`.

tensorArrayReadV2 :: forall v1 v2 v3 dtype . (TensorType dtype) =>
                     Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                     -> Tensor v2 Data.Int.Int32 -- ^ __index__
                     -> Tensor v3 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                     -> Tensor Value dtype -- ^ __value__: The tensor that is read from the TensorArray.
tensorArrayReadV2 handle index flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayReadV2"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle index flow_in
{-
attr {
  description: "The type of the elem that is returned."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg { name: "index" type: DT_INT32 }
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "The tensor that is read from the TensorArray."
  name: "value"
  type_attr: "dtype"
}
-}

-- | Decode web-safe base64-encoded strings.
--
-- Input may or may not have padding at the end. See EncodeBase64 for padding.
-- Web-safe means that input must use - and _ instead of + and /.
decodeBase64 :: Tensor v1 Data.ByteString.ByteString -- ^ __input__: Base64 strings to decode.
                -> Tensor Value Data.ByteString.ByteString -- ^ __output__: Decoded strings.
decodeBase64 input | eqLengthGuard [] =
    buildOp (opDef "DecodeBase64")
        input
{-
input_arg {
  description: "Base64 strings to decode."
  name: "input"
  type: DT_STRING
}
output_arg {
  description: "Decoded strings." name: "output" type: DT_STRING
}
-}

-- | Push an element onto the tensor_array.

tensorArrayWriteV2 :: forall v1 v2 v3 v4 t . (TensorType t) =>
                      Tensor v1 Data.ByteString.ByteString -- ^ __handle__: The handle to a TensorArray.
                      -> Tensor v2 Data.Int.Int32 -- ^ __index__: The position to write to inside the TensorArray.
                      -> Tensor v3 t -- ^ __value__: The tensor to write to the TensorArray.
                      -> Tensor v4 Float -- ^ __flow_in__: A float scalar that enforces proper chaining of operations.
                      -> Tensor Value Float -- ^ __flow_out__: A float scalar that enforces proper chaining of operations.
tensorArrayWriteV2 handle index value flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayWriteV2"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle index value flow_in
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The handle to a TensorArray."
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The position to write to inside the TensorArray."
  name: "index"
  type: DT_INT32
}
input_arg {
  description: "The tensor to write to the TensorArray."
  name: "value"
  type_attr: "T"
}
input_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_in"
  type: DT_FLOAT
}
output_arg {
  description: "A float scalar that enforces proper chaining of operations."
  name: "flow_out"
  type: DT_FLOAT
}
-}

-- | Outputs a `Summary` protocol buffer with audio.
--
-- The summary has up to `max_outputs` summary values containing audio. The
-- audio is built from `tensor` which must be 3-D with shape `[batch_size,
-- frames, channels]` or 2-D with shape `[batch_size, frames]`. The values are
-- assumed to be in the range of `[-1.0, 1.0]` with a sample rate of `sample_rate`.
-- 
-- The `tag` argument is a scalar `Tensor` of type `string`.  It is used to
-- build the `tag` of the summary values:
-- 
-- *  If `max_outputs` is 1, the summary value tag is '*tag*/audio'.
-- *  If `max_outputs` is greater than 1, the summary value tags are
--    generated sequentially as '*tag*/audio/0', '*tag*/audio/1', etc.
audioSummary :: Float -- ^ __sample_rate__: The sample rate of the signal in hertz.
                -> Tensor v1 Data.ByteString.ByteString -- ^ __tag__: Scalar. Used to build the `tag` attribute of the summary values.
                -> Tensor v2 Float -- ^ __tensor__: 2-D of shape `[batch_size, frames]`.
                -> Tensor Value Data.ByteString.ByteString -- ^ __summary__: Scalar. Serialized `Summary` protocol buffer.
audioSummary sample_rate tag tensor | eqLengthGuard [] =
    buildOp (opDef "AudioSummary"
             & opAttr "sample_rate" .~ sample_rate)
        tag tensor
{-
attr {
  description: "The sample rate of the signal in hertz."
  name: "sample_rate"
  type: "float"
}
attr {
  default_value { i: 3 }
  description: "Max number of batch elements to generate audio for."
  has_minimum: true
  minimum: 1
  name: "max_outputs"
  type: "int"
}
input_arg {
  description: "Scalar. Used to build the `tag` attribute of the summary values."
  name: "tag"
  type: DT_STRING
}
input_arg {
  description: "2-D of shape `[batch_size, frames]`."
  name: "tensor"
  type: DT_FLOAT
}
output_arg {
  description: "Scalar. Serialized `Summary` protocol buffer."
  name: "summary"
  type: DT_STRING
}
-}

-- | Returns which elements of x are finite.
--
-- @compatibility(numpy)
-- Equivalent to np.isfinite
-- @end_compatibility
isFinite :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16, Double,
                                                 Float] t) =>
            Tensor v1 t -- ^ __x__
            -> Tensor Value Bool -- ^ __y__
isFinite x | eqLengthGuard [] =
    buildOp (opDef "IsFinite"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type: DT_BOOL }
-}

-- | 

tensorArrayConcat :: forall v2 dtype . (TensorType dtype) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                     -> Tensor v2 Float -- ^ __flow_in__
                     -> Build ((Tensor Value dtype,
                                Tensor Value Data.Int.Int64))
                     -- ^ (__value__, __lengths__)
                     --
                     -- * __value__
                     --
                     -- * __lengths__
tensorArrayConcat handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArrayConcat"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle flow_in
{-
attr { name: "dtype" type: "type" }
attr {
  default_value { shape { unknown_rank: true } }
  name: "element_shape_except0"
  type: "shape"
}
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "value" type_attr: "dtype" }
output_arg { name: "lengths" type: DT_INT64 }
-}

-- | Computes the sum of elements across dimensions of a SparseTensor.
--
-- This Op takes a SparseTensor and is the sparse counterpart to
-- `tf.reduce_sum()`.  In particular, this Op also returns a dense `Tensor`
-- instead of a sparse one.
-- 
-- Reduces `sp_input` along the dimensions given in `reduction_axes`.  Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_axes`. If `keep_dims` is true, the reduced dimensions are retained
-- with length 1.
-- 
-- If `reduction_axes` has no entries, all dimensions are reduced, and a tensor
-- with a single element is returned.  Additionally, the axes can be negative,
-- which are interpreted according to the indexing rules in Python.
sparseReduceSum :: forall v1 v2 v3 v4 t . (TensorType t,
                                           OneOf '[(Data.Complex.Complex Double),
                                                   (Data.Complex.Complex Float),
                                                   Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t) =>
                   Tensor v1 Data.Int.Int64 -- ^ __input_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                            -- SparseTensor, possibly not in canonical ordering.
                   -> Tensor v2 t -- ^ __input_values__: 1-D.  `N` non-empty values corresponding to `input_indices`.
                   -> Tensor v3 Data.Int.Int64 -- ^ __input_shape__: 1-D.  Shape of the input SparseTensor.
                   -> Tensor v4 Data.Int.Int32 -- ^ __reduction_axes__: 1-D.  Length-`K` vector containing the reduction axes.
                   -> Tensor Value t -- ^ __output__: `R-K`-D.  The reduced Tensor.
sparseReduceSum input_indices input_values input_shape
                reduction_axes | eqLengthGuard [] =
    buildOp (opDef "SparseReduceSum"
             & opAttr "T" .~ tensorType (undefined :: t))
        input_indices input_values input_shape reduction_axes
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "input_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `input_indices`."
  name: "input_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "input_shape"
  type: DT_INT64
}
input_arg {
  description: "1-D.  Length-`K` vector containing the reduction axes."
  name: "reduction_axes"
  type: DT_INT32
}
output_arg {
  description: "`R-K`-D.  The reduced Tensor."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns x / y element-wise for real types.
--
-- If `x` and `y` are reals, this will return the floating-point division.
-- 
-- *NOTE*: `Div` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
realDiv :: forall v1 v2 t . (TensorType t,
                             OneOf '[(Data.Complex.Complex Double),
                                     (Data.Complex.Complex Float),
                                     Data.Int.Int16, Data.Int.Int32,
                                     Data.Int.Int64, Data.Int.Int8,
                                     Data.Word.Word16, Data.Word.Word8, Double,
                                     Float] t) => Tensor v1 t -- ^ __x__
           -> Tensor v2 t -- ^ __y__
           -> Tensor Value t -- ^ __z__
realDiv x y | eqLengthGuard [] =
    buildOp (opDef "RealDiv"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_UINT8
      type: DT_INT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | 

tensorArraySize :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__
                   -> Tensor v2 Float -- ^ __flow_in__
                   -> Build (Tensor Value Data.Int.Int32) -- ^ __size__
tensorArraySize handle flow_in | eqLengthGuard [] =
    buildOp (opDef "TensorArraySize")
        handle flow_in
{-
input_arg { is_ref: true name: "handle" type: DT_STRING }
input_arg { name: "flow_in" type: DT_FLOAT }
output_arg { name: "size" type: DT_INT32 }
-}

-- | Adds `bias` to `value`.
--
-- This is a deprecated version of BiasAdd and will be soon removed.
-- 
-- This is a special case of `tf.add` where `bias` is restricted to be 1-D.
-- Broadcasting is supported, so `value` may have any number of dimensions.
biasAddV1 :: forall v1 v2 t . (TensorType t,
                               OneOf '[(Data.Complex.Complex Double),
                                       (Data.Complex.Complex Float),
                                       Data.Int.Int16, Data.Int.Int32,
                                       Data.Int.Int64, Data.Int.Int8,
                                       Data.Word.Word16, Data.Word.Word8,
                                       Double, Float] t) =>
             Tensor v1 t -- ^ __value__: Any number of dimensions.
             -> Tensor v2 t -- ^ __bias__: 1-D with size the last dimension of `value`.
             -> Tensor Value t -- ^ __output__: Broadcasted sum of `value` and `bias`.
biasAddV1 value bias | eqLengthGuard [] =
    buildOp (opDef "BiasAddV1"
             & opAttr "T" .~ tensorType (undefined :: t))
        value bias
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Any number of dimensions."
  name: "value"
  type_attr: "T"
}
input_arg {
  description: "1-D with size the last dimension of `value`."
  name: "bias"
  type_attr: "T"
}
output_arg {
  description: "Broadcasted sum of `value` and `bias`."
  name: "output"
  type_attr: "T"
}
-}

-- | Returns the truth value of x OR y element-wise.
--
-- *NOTE*: `LogicalOr` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
logicalOr :: Tensor v1 Bool -- ^ __x__
             -> Tensor v2 Bool -- ^ __y__
             -> Tensor Value Bool -- ^ __z__
logicalOr x y | eqLengthGuard [] =
    buildOp (opDef "LogicalOr")
        x y
{-
input_arg { name: "x" type: DT_BOOL }
input_arg { name: "y" type: DT_BOOL }
output_arg { name: "z" type: DT_BOOL }
-}

-- | Push an element onto the stack.

stackPush :: forall v2 t . (TensorType t) =>
             Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a stack.
             -> Tensor v2 t -- ^ __elem__: The tensor to be pushed onto the stack.
             -> Build (Tensor Value t) -- ^ __output__: The same tensor as the input 'elem'.
stackPush handle elem | eqLengthGuard [] =
    buildOp (opDef "StackPush"
             & opAttr "T" .~ tensorType (undefined :: t))
        handle elem
{-
attr { name: "T" type: "type" }
attr {
  default_value { b: false }
  description: "Swap `elem` to CPU. Default to false."
  name: "swap_memory"
  type: "bool"
}
input_arg {
  description: "The handle to a stack."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "The tensor to be pushed onto the stack."
  name: "elem"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as the input \'elem\'."
  name: "output"
  type_attr: "T"
}
-}

-- | Computes Quantized Rectified Linear: `max(features, 0)`

quantizedRelu :: forall v1 v2 v3 tinput out_type . (TensorType tinput,
                                                    OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8] tinput,
                                                    TensorType out_type,
                                                    OneOf '[Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8] out_type) =>
                 Tensor v1 tinput -- ^ __features__
                 -> Tensor v2 Float -- ^ __min_features__: The float value that the lowest quantized value represents.
                 -> Tensor v3 Float -- ^ __max_features__: The float value that the highest quantized value represents.
                 -> (Tensor Value out_type, Tensor Value Float,
                     Tensor Value Float)
                 -- ^ (__activations__, __min_activations__, __max_activations__)
                 --
                 -- * __activations__: Has the same output shape as "features".
                 --
                 -- * __min_activations__: The float value that the lowest quantized value represents.
                 --
                 -- * __max_activations__: The float value that the highest quantized value represents.
quantizedRelu features min_features max_features | eqLengthGuard [] =
    buildOp (opDef "QuantizedRelu"
             & opAttr "Tinput" .~ tensorType (undefined :: tinput)
             & opAttr "out_type" .~ tensorType (undefined :: out_type))
        features min_features max_features
{-
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  name: "Tinput"
  type: "type"
}
attr {
  allowed_values {
    list {
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT16
      type: DT_QUINT16
      type: DT_QINT32
    }
  }
  default_value { type: DT_QUINT8 }
  name: "out_type"
  type: "type"
}
input_arg { name: "features" type_attr: "Tinput" }
input_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_features"
  type: DT_FLOAT
}
input_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_features"
  type: DT_FLOAT
}
output_arg {
  description: "Has the same output shape as \"features\"."
  name: "activations"
  type_attr: "out_type"
}
output_arg {
  description: "The float value that the lowest quantized value represents."
  name: "min_activations"
  type: DT_FLOAT
}
output_arg {
  description: "The float value that the highest quantized value represents."
  name: "max_activations"
  type: DT_FLOAT
}
-}

-- | Return the reduction indices for computing gradients of s0 op s1 with broadcast.
--
-- This is typically used by gradient computations for a broadcasting operation.
broadcastGradientArgs :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                                 Data.Int.Int64] t) =>
                         Tensor v1 t -- ^ __s0__
                         -> Tensor v2 t -- ^ __s1__
                         -> (Tensor Value t, Tensor Value t)
                         -- ^ (__r0__, __r1__)
                         --
                         -- * __r0__
                         --
                         -- * __r1__
broadcastGradientArgs s0 s1 | eqLengthGuard [] =
    buildOp (opDef "BroadcastGradientArgs"
             & opAttr "T" .~ tensorType (undefined :: t))
        s0 s1
{-
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "T"
  type: "type"
}
input_arg { name: "s0" type_attr: "T" }
input_arg { name: "s1" type_attr: "T" }
output_arg { name: "r0" type_attr: "T" }
output_arg { name: "r1" type_attr: "T" }
-}

-- | Finds unique elements in a 1-D tensor.
--
-- This operation returns a tensor `y` containing all of the unique elements of `x`
-- sorted in the same order that they occur in `x`. This operation also returns a
-- tensor `idx` the same size as `x` that contains the index of each value of `x`
-- in the unique output `y`. Finally, it returns a third tensor `count` that
-- contains the count of each element of `y` in `x`. In other words:
-- 
-- `y[idx[i]] = x[i] for i in [0, 1,...,rank(x) - 1]`
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor 'x' is [1, 1, 2, 4, 4, 4, 7, 8, 8]
-- y, idx, count = unique_with_counts(x)
-- y ==> [1, 2, 4, 7, 8]
-- idx ==> [0, 0, 1, 2, 2, 2, 3, 4, 4]
-- count ==> [2, 1, 3, 1, 2]
-- ```
uniqueWithCounts :: forall v1 t out_idx . (TensorType t, TensorType out_idx,
                                           OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64] out_idx) =>
                    Tensor v1 t -- ^ __x__: 1-D.
                    -> (Tensor Value t, Tensor Value out_idx,
                        Tensor Value out_idx) -- ^ (__y__, __idx__, __count__)
                    --
                    -- * __y__: 1-D.
                    --
                    -- * __idx__: 1-D.
                    --
                    -- * __count__: 1-D.
uniqueWithCounts x | eqLengthGuard [] =
    buildOp (opDef "UniqueWithCounts"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "out_idx" .~ tensorType (undefined :: out_idx))
        x
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "out_idx"
  type: "type"
}
input_arg { description: "1-D." name: "x" type_attr: "T" }
output_arg { description: "1-D." name: "y" type_attr: "T" }
output_arg { description: "1-D." name: "idx" type_attr: "out_idx" }
output_arg {
  description: "1-D." name: "count" type_attr: "out_idx"
}
-}

-- | Returns element-wise remainder of division. This emulates C semantics where
--
-- true, this follows C semantics in that the result here is consistent
-- with a flooring divide. E.g. `floor(x / y) * y + mod(x, y) = x`.
-- 
-- *NOTE*: `Mod` supports broadcasting. More about broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
truncateMod :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                       Data.Int.Int64, Double,
                                                       Float] t) =>
               Tensor v1 t -- ^ __x__
               -> Tensor v2 t -- ^ __y__
               -> Tensor Value t -- ^ __z__
truncateMod x y | eqLengthGuard [] =
    buildOp (opDef "TruncateMod"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_INT32 type: DT_INT64 type: DT_FLOAT type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns the gradient of `StridedSlice`.
--
-- Since `StridedSlice` cuts out pieces of its `input` which is size
-- `shape`, its gradient will have the same shape (which is passed here
-- as `shape`). The gradient will be zero in any element that the slice
-- does not select.
-- 
-- Arguments are the same as StridedSliceGrad with the exception that
-- `dy` is the input gradient to be propagated and `shape` is the
-- shape of `StridedSlice`'s `input`.
stridedSliceGrad :: forall v1 v2 v3 v4 v5 t index . (TensorType t,
                                                     TensorType index,
                                                     OneOf '[Data.Int.Int32,
                                                             Data.Int.Int64] index) =>
                    Tensor v1 index -- ^ __shape__
                    -> Tensor v2 index -- ^ __begin__
                    -> Tensor v3 index -- ^ __end__
                    -> Tensor v4 index -- ^ __strides__
                    -> Tensor v5 t -- ^ __dy__
                    -> Tensor Value t -- ^ __output__
stridedSliceGrad shape begin end strides dy | eqLengthGuard [] =
    buildOp (opDef "StridedSliceGrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Index" .~ tensorType (undefined :: index))
        shape begin end strides dy
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Index"
  type: "type"
}
attr { default_value { i: 0 } name: "begin_mask" type: "int" }
attr { default_value { i: 0 } name: "end_mask" type: "int" }
attr { default_value { i: 0 } name: "ellipsis_mask" type: "int" }
attr { default_value { i: 0 } name: "new_axis_mask" type: "int" }
attr {
  default_value { i: 0 } name: "shrink_axis_mask" type: "int"
}
input_arg { name: "shape" type_attr: "Index" }
input_arg { name: "begin" type_attr: "Index" }
input_arg { name: "end" type_attr: "Index" }
input_arg { name: "strides" type_attr: "Index" }
input_arg { name: "dy" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Performs fractional average pooling on the input.
--
-- Fractional average pooling is similar to Fractional max pooling in the pooling
-- region generation step. The only difference is that after pooling regions are
-- generated, a mean operation is performed instead of a max operation in each
-- pooling region.
fractionalAvgPool :: forall v1 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                          Data.Int.Int64,
                                                          Double, Float] t) =>
                     Tensor v1 t -- ^ __value__: 4-D with shape `[batch, height, width, channels]`.
                     -> (Tensor Value t, Tensor Value Data.Int.Int64,
                         Tensor Value Data.Int.Int64)
                     -- ^ (__output__, __row_pooling_sequence__, __col_pooling_sequence__)
                     --
                     -- * __output__: output tensor after fractional avg pooling.
                     --
                     -- * __row_pooling_sequence__: row pooling sequence, needed to calculate gradient.
                     --
                     -- * __col_pooling_sequence__: column pooling sequence, needed to calculate gradient.
fractionalAvgPool value | eqLengthGuard [] =
    buildOp (opDef "FractionalAvgPool"
             & opAttr "T" .~ tensorType (undefined :: t))
        value
{-
attr {
  description: "Pooling ratio for each dimension of `value`, currently only\nsupports row and col dimension and should be >= 1.0. For example, a valid\npooling ratio looks like [1.0, 1.44, 1.73, 1.0]. The first and last elements\nmust be 1.0 because we don\'t allow pooling on batch and channels\ndimensions. 1.44 and 1.73 are pooling ratio on height and width dimensions\nrespectively."
  has_minimum: true
  minimum: 4
  name: "pooling_ratio"
  type: "list(float)"
}
attr {
  default_value { b: false }
  description: "When set to True, generates the pooling sequence in a\npseudorandom fashion, otherwise, in a random fashion. Check paper [Benjamin\nGraham, Fractional Max-Pooling](http://arxiv.org/abs/1412.6071) for\ndifference between pseudorandom and random."
  name: "pseudo_random"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "When set to True, it means when pooling, the values at the boundary\nof adjacent pooling cells are used by both cells. For example:\n\n`index  0  1  2  3  4`\n\n`value  20 5  16 3  7`\n\nIf the pooling sequence is [0, 2, 4], then 16, at index 2 will be used twice.\nThe result would be [41/3, 26/3] for fractional avg pooling."
  name: "overlapping"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "When set to True, a fixed pooling region will be used when\niterating over a FractionalAvgPool node in the computation graph. Mainly used\nin unit test to make FractionalAvgPool deterministic."
  name: "deterministic"
  type: "bool"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT type: DT_DOUBLE type: DT_INT32 type: DT_INT64
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "value"
  type_attr: "T"
}
output_arg {
  description: "output tensor after fractional avg pooling."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "row pooling sequence, needed to calculate gradient."
  name: "row_pooling_sequence"
  type: DT_INT64
}
output_arg {
  description: "column pooling sequence, needed to calculate gradient."
  name: "col_pooling_sequence"
  type: DT_INT64
}
-}

-- | Extracts the average sparse gradient in the given SparseConditionalAccumulator,
--
-- provided that sufficient (i.e., more than num_required) gradients have been
-- accumulated. The op will blocks until sufficient gradients have been
-- accumulated. If the accumulator has already aggregated more than num_required
-- gradients, it will return its average of the accumulated gradients.
-- Also automatically increments the recorded global_step in the accumulator by 1,
-- and resets the aggregate to 0.
sparseAccumulatorTakeGradient :: forall v2 dtype . (TensorType dtype,
                                                    OneOf '[(Data.Complex.Complex Double),
                                                            (Data.Complex.Complex Float),
                                                            Data.Int.Int16,
                                                            Data.Int.Int32,
                                                            Data.Int.Int64,
                                                            Data.Int.Int8,
                                                            Data.Word.Word16,
                                                            Data.Word.Word8,
                                                            Double,
                                                            Float] dtype) =>
                                 Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to a SparseConditionalAccumulator.
                                 -> Tensor v2 Data.Int.Int32 -- ^ __num_required__: Number of gradients required before we return an aggregate.
                                 -> Build ((Tensor Value Data.Int.Int64,
                                            Tensor Value dtype,
                                            Tensor Value Data.Int.Int64))
                                 -- ^ (__indices__, __values__, __shape__)
                                 --
                                 -- * __indices__: Indices of the average of the accumulated sparse gradients.
                                 --
                                 -- * __values__: Values of the average of the accumulated sparse gradients.
                                 --
                                 -- * __shape__: Shape of the average of the accumulated sparse gradients.
sparseAccumulatorTakeGradient handle num_required | eqLengthGuard [] =
    buildOp (opDef "SparseAccumulatorTakeGradient"
             & opAttr "dtype" .~ tensorType (undefined :: dtype))
        handle num_required
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  description: "The data type of accumulated gradients. Needs to correspond to the type\nof the accumulator."
  name: "dtype"
  type: "type"
}
input_arg {
  description: "The handle to a SparseConditionalAccumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
input_arg {
  description: "Number of gradients required before we return an aggregate."
  name: "num_required"
  type: DT_INT32
}
output_arg {
  description: "Indices of the average of the accumulated sparse gradients."
  name: "indices"
  type: DT_INT64
}
output_arg {
  description: "Values of the average of the accumulated sparse gradients."
  name: "values"
  type_attr: "dtype"
}
output_arg {
  description: "Shape of the average of the accumulated sparse gradients."
  name: "shape"
  type: DT_INT64
}
-}

-- | Convert JSON-encoded Example records to binary protocol buffer strings.
--
-- This op translates a tensor containing Example records, encoded using
-- the [standard JSON
-- mapping](https://developers.google.com/protocol-buffers/docs/proto3#json),
-- into a tensor containing the same records encoded as binary protocol
-- buffers. The resulting tensor can then be fed to any of the other
-- Example-parsing ops.
decodeJSONExample :: Tensor v1 Data.ByteString.ByteString -- ^ __json_examples__: Each string is a JSON object serialized according to the JSON
                                                          -- mapping of the Example proto.
                     -> Tensor Value Data.ByteString.ByteString -- ^ __binary_examples__: Each string is a binary Example protocol buffer corresponding
                     -- to the respective element of `json_examples`.
decodeJSONExample json_examples | eqLengthGuard [] =
    buildOp (opDef "DecodeJSONExample")
        json_examples
{-
input_arg {
  description: "Each string is a JSON object serialized according to the JSON\nmapping of the Example proto."
  name: "json_examples"
  type: DT_STRING
}
output_arg {
  description: "Each string is a binary Example protocol buffer corresponding\nto the respective element of `json_examples`."
  name: "binary_examples"
  type: DT_STRING
}
-}

-- | A placeholder op that passes though `input` when its output is not fed.

placeholderWithDefault :: forall v1 dtype . (TensorType dtype) =>
                          Shape -- ^ __shape__: The (possibly partial) shape of the tensor.
                          -> Tensor v1 dtype -- ^ __input__: The default value to produce when `output` is not fed.
                          -> Tensor Value dtype -- ^ __output__: A placeholder tensor that defaults to `input` if it is not fed.
placeholderWithDefault shape input | eqLengthGuard [] =
    buildOp (opDef "PlaceholderWithDefault"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "shape" .~ shape)
        input
{-
attr {
  description: "The type of elements in the tensor."
  name: "dtype"
  type: "type"
}
attr {
  description: "The (possibly partial) shape of the tensor."
  name: "shape"
  type: "shape"
}
input_arg {
  description: "The default value to produce when `output` is not fed."
  name: "input"
  type_attr: "dtype"
}
output_arg {
  description: "A placeholder tensor that defaults to `input` if it is not fed."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Update '*var' according to the Ftrl-proximal scheme.
--
-- accum_new = accum + grad * grad
-- linear += grad + (accum_new^(-lr_power) - accum^(-lr_power)) / lr * var
-- quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2
-- var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0
-- accum = accum_new
applyFtrl :: forall v4 v5 v6 v7 v8 t . (TensorType t,
                                        OneOf '[(Data.Complex.Complex Double),
                                                (Data.Complex.Complex Float),
                                                Data.Int.Int16, Data.Int.Int32,
                                                Data.Int.Int64, Data.Int.Int8,
                                                Data.Word.Word16,
                                                Data.Word.Word8, Double,
                                                Float] t) =>
             Tensor Ref t -- ^ __var__: Should be from a Variable().
             -> Tensor Ref t -- ^ __accum__: Should be from a Variable().
             -> Tensor Ref t -- ^ __linear__: Should be from a Variable().
             -> Tensor v4 t -- ^ __grad__: The gradient.
             -> Tensor v5 t -- ^ __lr__: Scaling factor. Must be a scalar.
             -> Tensor v6 t -- ^ __l1__: L1 regulariation. Must be a scalar.
             -> Tensor v7 t -- ^ __l2__: L2 regulariation. Must be a scalar.
             -> Tensor v8 t -- ^ __lr_power__: Scaling factor. Must be a scalar.
             -> Build (Tensor Ref t) -- ^ __out__: Same as "var".
applyFtrl var accum linear grad lr l1 l2 lr_power | eqLengthGuard [] =
    buildOp (opDef "ApplyFtrl"
             & opAttr "T" .~ tensorType (undefined :: t))
        var accum linear grad lr l1 l2 lr_power
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, updating of the var and accum tensors will be protected\nby a lock; otherwise the behavior is undefined, but may exhibit less\ncontention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "var"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "accum"
  type_attr: "T"
}
input_arg {
  description: "Should be from a Variable()."
  is_ref: true
  name: "linear"
  type_attr: "T"
}
input_arg {
  description: "The gradient." name: "grad" type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr"
  type_attr: "T"
}
input_arg {
  description: "L1 regulariation. Must be a scalar."
  name: "l1"
  type_attr: "T"
}
input_arg {
  description: "L2 regulariation. Must be a scalar."
  name: "l2"
  type_attr: "T"
}
input_arg {
  description: "Scaling factor. Must be a scalar."
  name: "lr_power"
  type_attr: "T"
}
output_arg {
  description: "Same as \"var\"."
  is_ref: true
  name: "out"
  type_attr: "T"
}
-}

-- | Applies L1 regularization shrink step on the parameters.

sdcaShrinkL1 :: Float -- ^ __l1__: Symmetric l1 regularization strength.
                -> Float -- ^ __l2__: Symmetric l2 regularization strength. Should be a positive float.
                -> [Tensor Ref Float] -- ^ __weights__: a list of vectors where each value is the weight associated with a
                                      -- feature group.
                -> Build (ControlNode)
sdcaShrinkL1 l1 l2
             weights | eqLengthGuard [("num_features", [("weights", length weights)])] =
    buildOp (opDef "SdcaShrinkL1"
             & opAttr "l1" .~ l1
             & opAttr "l2" .~ l2
             & opAttr "num_features" .~ num_features)
        weights
  where
    num_features = fromIntegral (length weights) :: Int64
{-
attr {
  description: "Number of feature groups to apply shrinking step."
  has_minimum: true
  name: "num_features"
  type: "int"
}
attr {
  description: "Symmetric l1 regularization strength."
  name: "l1"
  type: "float"
}
attr {
  description: "Symmetric l2 regularization strength. Should be a positive float."
  name: "l2"
  type: "float"
}
input_arg {
  description: "a list of vectors where each value is the weight associated with a\nfeature group."
  is_ref: true
  name: "weights"
  number_attr: "num_features"
  type: DT_FLOAT
}
-}

-- | Generate a sharded filename. The filename is printf formatted as
--
--    %s-%05d-of-%05d, basename, shard, num_shards.
shardedFilename :: Tensor v1 Data.ByteString.ByteString -- ^ __basename__
                   -> Tensor v2 Data.Int.Int32 -- ^ __shard__
                   -> Tensor v3 Data.Int.Int32 -- ^ __num_shards__
                   -> Tensor Value Data.ByteString.ByteString -- ^ __filename__
shardedFilename basename shard num_shards | eqLengthGuard [] =
    buildOp (opDef "ShardedFilename")
        basename shard num_shards
{-
input_arg { name: "basename" type: DT_STRING }
input_arg { name: "shard" type: DT_INT32 }
input_arg { name: "num_shards" type: DT_INT32 }
output_arg { name: "filename" type: DT_STRING }
-}

-- | Fake-quantize the 'inputs' tensor, type float to 'outputs' tensor of same type.
--
-- Attributes [min; max] define the clamping range for the 'inputs' data.  Op
-- divides this range into 255 steps (total of 256 values), then replaces each
-- 'inputs' value with the closest of the quantized step values.
-- 
-- Quantization is called fake since the output is still in floating point.
fakeQuantWithMinMaxArgs :: Tensor v1 Float -- ^ __inputs__
                           -> Tensor Value Float -- ^ __outputs__
fakeQuantWithMinMaxArgs inputs | eqLengthGuard [] =
    buildOp (opDef "FakeQuantWithMinMaxArgs")
        inputs
{-
attr { default_value { f: -6.0 } name: "min" type: "float" }
attr { default_value { f: 6.0 } name: "max" type: "float" }
input_arg { name: "inputs" type: DT_FLOAT }
output_arg { name: "outputs" type: DT_FLOAT }
-}

-- | Applies sparse addition between `updates` and individual values or slices
--
-- within a given variable according to `indices`.
-- 
-- `ref` is a `Tensor` with rank `P` and `indices` is a `Tensor` of rank `Q`.
-- 
-- `indices` must be integer tensor, containing indices into `ref`.
-- It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
-- 
-- The innermost dimension of `indices` (with length `K`) corresponds to
-- indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
-- dimension of `ref`.
-- 
-- `updates` is `Tensor` of rank `Q-1+P-K` with shape:
-- 
-- ```
-- [d_0, ..., d_{Q-2}, ref.shape[K], ..., ref.shape[P-1]].
-- ```
-- 
-- For example, say we want to add 4 scattered elements to a rank-1 tensor to 8
-- elements. In Python, that addition would look like this:
-- 
--     ref = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8])
--     indices = tf.constant([[4], [3], [1], [7]])
--     updates = tf.constant([9, 10, 11, 12])
--     add = tf.scatter_nd_add(ref, indices, updates)
--     with tf.Session() as sess:
--       print sess.run(add)
-- 
-- The resulting update to ref would look like this:
-- 
--     [1, 13, 3, 14, 14, 6, 7, 20]
-- 
-- See [tf.scatter_nd](#scatter_nd) for more details about how to make updates to
-- slices.
scatterNdAdd :: forall v2 v3 t tindices . (TensorType t,
                                           OneOf '[(Data.Complex.Complex Double),
                                                   (Data.Complex.Complex Float),
                                                   Data.Int.Int16,
                                                   Data.Int.Int32,
                                                   Data.Int.Int64,
                                                   Data.Int.Int8,
                                                   Data.Word.Word16,
                                                   Data.Word.Word8, Double,
                                                   Float] t,
                                           TensorType tindices,
                                           OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64] tindices) =>
                Tensor Ref t -- ^ __ref__: A mutable Tensor. Should be from a Variable node.
                -> Tensor v2 tindices -- ^ __indices__: A Tensor. Must be one of the following types: int32, int64.
                                      -- A tensor of indices into ref.
                -> Tensor v3 t -- ^ __updates__: A Tensor. Must have the same type as ref. A tensor of updated values
                               -- to add to ref.
                -> Build (Tensor Ref t) -- ^ __output_ref__: Same as ref. Returned as a convenience for operations that want
                -- to use the updated values after the update is done.
scatterNdAdd ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterNdAdd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "An optional bool. Defaults to True. If True, the assignment will\nbe protected by a lock; otherwise the behavior is undefined,\nbut may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "A mutable Tensor. Should be from a Variable node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A Tensor. Must be one of the following types: int32, int64.\nA tensor of indices into ref."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A Tensor. Must have the same type as ref. A tensor of updated values\nto add to ref."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "Same as ref. Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Returns the number of gradients aggregated in the given accumulators.

accumulatorNumAccumulated :: Tensor Ref Data.ByteString.ByteString -- ^ __handle__: The handle to an accumulator.
                             -> Build (Tensor Value Data.Int.Int32) -- ^ __num_accumulated__: The number of gradients aggregated in the given accumulator.
accumulatorNumAccumulated handle | eqLengthGuard [] =
    buildOp (opDef "AccumulatorNumAccumulated")
        handle
{-
input_arg {
  description: "The handle to an accumulator."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
output_arg {
  description: "The number of gradients aggregated in the given accumulator."
  name: "num_accumulated"
  type: DT_INT32
}
-}

-- | Computes the sum along sparse segments of a tensor divided by the sqrt of N.
--
-- N is the size of the segment being reduced.
-- 
-- Read [the section on
-- Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
-- of segments.
sparseSegmentSqrtN :: forall v1 v2 v3 t tidx . (TensorType t, OneOf '[Double,
                                                                      Float] t,
                                                TensorType tidx,
                                                OneOf '[Data.Int.Int32,
                                                        Data.Int.Int64] tidx) =>
                      Tensor v1 t -- ^ __data__
                      -> Tensor v2 tidx -- ^ __indices__: A 1-D tensor. Has same rank as `segment_ids`.
                      -> Tensor v3 Data.Int.Int32 -- ^ __segment_ids__: A 1-D tensor. Values should be sorted and can be repeated.
                      -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
                      -- has size `k`, the number of segments.
sparseSegmentSqrtN data' indices segment_ids | eqLengthGuard [] =
    buildOp (opDef "SparseSegmentSqrtN"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        data' indices segment_ids
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor. Has same rank as `segment_ids`."
  name: "indices"
  type_attr: "Tidx"
}
input_arg {
  description: "A 1-D tensor. Values should be sorted and can be repeated."
  name: "segment_ids"
  type: DT_INT32
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | DepthToSpace for tensors of type T.
--
-- Rearranges data from depth into blocks of spatial data.
-- This is the reverse transformation of SpaceToDepth. More specifically,
-- this op outputs a copy of the input tensor where values from the `depth`
-- dimension are moved in spatial blocks to the `height` and `width` dimensions.
-- The attr `block_size` indicates the input block size and how the data is moved.
-- 
--   * Chunks of data of size `block_size * block_size` from depth are rearranged
--     into non-overlapping blocks of size `block_size x block_size`
--   * The width the output tensor is `input_depth * block_size`, whereas the
--     height is `input_height * block_size`.
--   * The depth of the input tensor must be divisible by
--     `block_size * block_size`.
-- 
-- That is, assuming the input is in the shape:
-- `[batch, height, width, depth]`,
-- the shape of the output will be:
-- `[batch, height*block_size, width*block_size, depth/(block_size*block_size)]`
-- 
-- This operation requires that the input tensor be of rank 4, and that
-- `block_size` be >=1 and that `block_size * block_size` be a divisor of the
-- input depth.
-- 
-- This operation is useful for resizing the activations between convolutions
-- (but keeping all data), e.g. instead of pooling. It is also useful for training
-- purely convolutional models.
-- 
-- For example, given this input of shape `[1, 1, 1, 4]`, and a block size of 2:
-- 
-- ```prettyprint
-- x = [[[[1, 2, 3, 4]]]]
-- 
-- ```
-- 
-- This operation will output a tensor of shape `[1, 2, 2, 1]`:
-- 
-- ```prettyprint
--    [[[[1], [2]],
--      [[3], [4]]]]
-- ```
-- 
-- Here, the input has a batch of 1 and each batch element has shape `[1, 1, 4]`,
-- the corresponding output will have 2x2 elements and will have a depth of
-- 1 channel (1 = `4 / (block_size * block_size)`).
-- The output element shape is `[2, 2, 1]`.
-- 
-- For an input tensor with larger depth, here of shape `[1, 1, 1, 12]`, e.g.
-- 
-- ```prettyprint
-- x = [[[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]]]
-- ```
-- 
-- This operation, for block size of 2, will return the following tensor of shape
-- `[1, 2, 2, 3]`
-- 
-- ```prettyprint
--    [[[[1, 2, 3], [4, 5, 6]],
--      [[7, 8, 9], [10, 11, 12]]]]
-- 
-- ```
-- 
-- Similarly, for the following input of shape `[1 2 2 4]`, and a block size of 2:
-- 
-- ```prettyprint
-- x =  [[[[1, 2, 3, 4],
--        [5, 6, 7, 8]],
--       [[9, 10, 11, 12],
--        [13, 14, 15, 16]]]]
-- ```
-- 
-- the operator will return the following tensor of shape `[1 4 4 1]`:
-- 
-- ```prettyprint
-- x = [[ [1],   [2],  [5],  [6]],
--      [ [3],   [4],  [7],  [8]],
--      [ [9],  [10], [13],  [14]],
--      [ [11], [12], [15],  [16]]]
-- 
-- ```
depthToSpace :: forall v1 t . (TensorType t) =>
                Data.Int.Int64 -- ^ __block_size__: The size of the spatial block, same as in Space2Depth.
                -> Tensor v1 t -- ^ __input__
                -> Tensor Value t -- ^ __output__
depthToSpace block_size input | eqLengthGuard [] =
    buildOp (opDef "DepthToSpace"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "block_size" .~ block_size)
        input
{-
attr { name: "T" type: "type" }
attr {
  description: "The size of the spatial block, same as in Space2Depth."
  has_minimum: true
  minimum: 2
  name: "block_size"
  type: "int"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Generates labels for candidate sampling with a learned unigram distribution.
--
-- See explanations of candidate sampling and the data formats at
-- go/candidate-sampling.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
allCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to produce per batch.
                       -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                       -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                               -- candidates in a batch are unique. This requires some approximation to
                               -- estimate the post-rejection sampling probabilities.
                       -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                   -- IDs of the num_true target_classes in the corresponding original label.
                       -> (Tensor Value Data.Int.Int64, Tensor Value Float,
                           Tensor Value Float)
                       -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                       --
                       -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                       -- the ID of a sampled candidate.
                       --
                       -- * __true_expected_count__: A batch_size * num_true matrix, representing
                       -- the number of times each candidate is expected to occur in a batch
                       -- of sampled candidates. If unique=true, then this is a probability.
                       --
                       -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                       -- candidate representing the number of times the candidate is expected
                       -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                       -- probability.
allCandidateSampler num_sampled num_true unique
                    true_classes | eqLengthGuard [] =
    buildOp (opDef "AllCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to produce per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Computes the gradient of nearest neighbor interpolation.

resizeNearestNeighborGrad :: forall v1 v2 t . (TensorType t,
                                               OneOf '[Data.Int.Int32,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
                             Tensor v1 t -- ^ __grads__: 4-D with shape `[batch, height, width, channels]`.
                             -> Tensor v2 Data.Int.Int32 -- ^ __size__: = A 1-D int32 Tensor of 2 elements: `orig_height, orig_width`. The
                                                         -- original input size.
                             -> Tensor Value t -- ^ __output__: 4-D with shape `[batch, orig_height, orig_width, channels]`. Gradients
                             -- with respect to the input image.
resizeNearestNeighborGrad grads size | eqLengthGuard [] =
    buildOp (opDef "ResizeNearestNeighborGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        grads size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT32
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale grads by (orig_height - 1) / (height - 1), which\nexactly aligns the 4 corners of grads and original_image. If false, rescale by\norig_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "grads"
  type_attr: "T"
}
input_arg {
  description: "= A 1-D int32 Tensor of 2 elements: `orig_height, orig_width`. The\noriginal input size."
  name: "size"
  type: DT_INT32
}
output_arg {
  description: "4-D with shape `[batch, orig_height, orig_width, channels]`. Gradients\nwith respect to the input image."
  name: "output"
  type_attr: "T"
}
-}

-- | Performs greedy decoding on the logits given in inputs.
--
-- A note about the attribute merge_repeated: if enabled, when
-- consecutive logits' maximum indices are the same, only the first of
-- these is emitted.  Labeling the blank '*', the sequence "A B B * B B"
-- becomes "A B" if merge_repeated = True and "A B B B B" if
-- merge_repeated = False.
-- 
-- Regardless of the value of merge_repeated, if the maximum index of a given
-- time and batch corresponds to the blank, index `(num_classes - 1)`, no new
-- element is emitted.
cTCGreedyDecoder :: Tensor v1 Float -- ^ __inputs__: 3-D, shape: `(max_time x batch_size x num_classes)`, the logits.
                    -> Tensor v2 Data.Int.Int32 -- ^ __sequence_length__: A vector containing sequence lengths, size `(batch_size)`.
                    -> (Tensor Value Data.Int.Int64,
                        Tensor Value Data.Int.Int64,
                        Tensor Value Data.Int.Int64, Tensor Value Float)
                    -- ^ (__decoded_indices__, __decoded_values__, __decoded_shape__, __log_probability__)
                    --
                    -- * __decoded_indices__: Indices matrix, size `(total_decoded_outputs x 2)`,
                    -- of a `SparseTensor<int64, 2>`.  The rows store: [batch, time].
                    --
                    -- * __decoded_values__: Values vector, size: `(total_decoded_outputs)`,
                    -- of a `SparseTensor<int64, 2>`.  The vector stores the decoded classes.
                    --
                    -- * __decoded_shape__: Shape vector, size `(2)`, of the decoded SparseTensor.
                    -- Values are: `[batch_size, max_decoded_length]`.
                    --
                    -- * __log_probability__: Matrix, size `(batch_size x 1)`, containing sequence
                    -- log-probabilities.
cTCGreedyDecoder inputs sequence_length | eqLengthGuard [] =
    buildOp (opDef "CTCGreedyDecoder")
        inputs sequence_length
{-
attr {
  default_value { b: false }
  description: "If True, merge repeated classes in output."
  name: "merge_repeated"
  type: "bool"
}
input_arg {
  description: "3-D, shape: `(max_time x batch_size x num_classes)`, the logits."
  name: "inputs"
  type: DT_FLOAT
}
input_arg {
  description: "A vector containing sequence lengths, size `(batch_size)`."
  name: "sequence_length"
  type: DT_INT32
}
output_arg {
  description: "Indices matrix, size `(total_decoded_outputs x 2)`,\nof a `SparseTensor<int64, 2>`.  The rows store: [batch, time]."
  name: "decoded_indices"
  type: DT_INT64
}
output_arg {
  description: "Values vector, size: `(total_decoded_outputs)`,\nof a `SparseTensor<int64, 2>`.  The vector stores the decoded classes."
  name: "decoded_values"
  type: DT_INT64
}
output_arg {
  description: "Shape vector, size `(2)`, of the decoded SparseTensor.\nValues are: `[batch_size, max_decoded_length]`."
  name: "decoded_shape"
  type: DT_INT64
}
output_arg {
  description: "Matrix, size `(batch_size x 1)`, containing sequence\nlog-probabilities."
  name: "log_probability"
  type: DT_FLOAT
}
-}

-- | L2 Loss.
--
-- Computes half the L2 norm of a tensor without the `sqrt`:
-- 
--     output = sum(t ** 2) / 2
l2Loss :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                               (Data.Complex.Complex Float),
                                               Data.Int.Int16, Data.Int.Int32,
                                               Data.Int.Int64, Data.Int.Int8,
                                               Data.Word.Word16,
                                               Data.Word.Word8, Double,
                                               Float] t) =>
          Tensor v1 t -- ^ __t__: Typically 2-D, but may have any dimensions.
          -> Tensor Value t -- ^ __output__: 0-D.
l2Loss t | eqLengthGuard [] =
    buildOp (opDef "L2Loss"
             & opAttr "T" .~ tensorType (undefined :: t))
        t
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "Typically 2-D, but may have any dimensions."
  name: "t"
  type_attr: "T"
}
output_arg { description: "0-D." name: "output" type_attr: "T" }
-}

-- | Computes the maximum along segments of a tensor.
--
-- Read [the section on Segmentation](../../api_docs/python/math_ops.md#segmentation)
-- for an explanation of segments.
-- 
-- Computes a tensor such that
-- \\(output_i = \max_j(data_j)\\) where `max` is over `j` such
-- that `segment_ids[j] == i`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/SegmentMax.png" alt>
-- </div>
segmentMax :: forall v1 v2 t tindices . (TensorType t, OneOf '[Data.Int.Int16,
                                                               Data.Int.Int32,
                                                               Data.Int.Int64,
                                                               Data.Int.Int8,
                                                               Data.Word.Word16,
                                                               Data.Word.Word8,
                                                               Double, Float] t,
                                         TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor v1 t -- ^ __data__
              -> Tensor v2 tindices -- ^ __segment_ids__: A 1-D tensor whose rank is equal to the rank of `data`'s
                                    -- first dimension.  Values should be sorted and can be repeated.
              -> Tensor Value t -- ^ __output__: Has same shape as data, except for dimension 0 which
              -- has size `k`, the number of segments.
segmentMax data' segment_ids | eqLengthGuard [] =
    buildOp (opDef "SegmentMax"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        data' segment_ids
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension.  Values should be sorted and can be repeated."
  name: "segment_ids"
  type_attr: "Tindices"
}
output_arg {
  description: "Has same shape as data, except for dimension 0 which\nhas size `k`, the number of segments."
  name: "output"
  type_attr: "T"
}
-}

-- | Increments 'ref' until it reaches 'limit'.

countUpTo :: forall t . (TensorType t, OneOf '[Data.Int.Int32,
                                               Data.Int.Int64] t) =>
             Data.Int.Int64 -- ^ __limit__: If incrementing ref would bring it above limit, instead generates an
                            -- 'OutOfRange' error.
             -> Tensor Ref t -- ^ __ref__: Should be from a scalar `Variable` node.
             -> Build (Tensor Value t) -- ^ __output__: A copy of the input before increment. If nothing else modifies the
             -- input, the values produced will all be distinct.
countUpTo limit ref | eqLengthGuard [] =
    buildOp (opDef "CountUpTo"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "limit" .~ limit)
        ref
{-
attr {
  description: "If incrementing ref would bring it above limit, instead generates an\n\'OutOfRange\' error."
  name: "limit"
  type: "int"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Should be from a scalar `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
output_arg {
  description: "A copy of the input before increment. If nothing else modifies the\ninput, the values produced will all be distinct."
  name: "output"
  type_attr: "T"
}
-}

-- | A Reader that outputs the records from a TensorFlow Records file.

tFRecordReader :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __reader_handle__: The handle to reference the Reader.
tFRecordReader  | eqLengthGuard [] =
    buildOp (opDef "TFRecordReader")
        
{-
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
attr {
  default_value { s: "" } name: "compression_type" type: "string"
}
output_arg {
  description: "The handle to reference the Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Forwards `data` to the output port determined by `pred`.
--
-- If `pred` is true, the `data` input is forwarded to `output_true`. Otherwise,
-- the data goes to `output_false`.
-- 
-- See also `RefSwitch` and `Merge`.
switch :: forall v1 v2 t . (TensorType t) =>
          Tensor v1 t -- ^ __data__: The tensor to be forwarded to the appropriate output.
          -> Tensor v2 Bool -- ^ __pred__: A scalar that specifies which output port will receive data.
          -> (Tensor Value t, Tensor Value t)
          -- ^ (__output_false__, __output_true__)
          --
          -- * __output_false__: If `pred` is false, data will be forwarded to this output.
          --
          -- * __output_true__: If `pred` is true, data will be forwarded to this output.
switch data' pred | eqLengthGuard [] =
    buildOp (opDef "Switch"
             & opAttr "T" .~ tensorType (undefined :: t))
        data' pred
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be forwarded to the appropriate output."
  name: "data"
  type_attr: "T"
}
input_arg {
  description: "A scalar that specifies which output port will receive data."
  name: "pred"
  type: DT_BOOL
}
output_arg {
  description: "If `pred` is false, data will be forwarded to this output."
  name: "output_false"
  type_attr: "T"
}
output_arg {
  description: "If `pred` is true, data will be forwarded to this output."
  name: "output_true"
  type_attr: "T"
}
-}

-- | Computes gradients for SparseSegmentMean.
--
-- Returns tensor "output" with same shape as grad, except for dimension 0 whose
-- value is output_dim0.
sparseSegmentMeanGrad :: forall v1 v2 v3 v4 t tidx . (TensorType t,
                                                      OneOf '[Double, Float] t,
                                                      TensorType tidx,
                                                      OneOf '[Data.Int.Int32,
                                                              Data.Int.Int64] tidx) =>
                         Tensor v1 t -- ^ __grad__: gradient propagated to the SparseSegmentMean op.
                         -> Tensor v2 tidx -- ^ __indices__: indices passed to the corresponding SparseSegmentMean op.
                         -> Tensor v3 Data.Int.Int32 -- ^ __segment_ids__: segment_ids passed to the corresponding SparseSegmentMean op.
                         -> Tensor v4 Data.Int.Int32 -- ^ __output_dim0__: dimension 0 of "data" passed to SparseSegmentMean op.
                         -> Tensor Value t -- ^ __output__
sparseSegmentMeanGrad grad indices segment_ids output_dim0 | eqLengthGuard [] =
    buildOp (opDef "SparseSegmentMeanGrad"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        grad indices segment_ids output_dim0
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "gradient propagated to the SparseSegmentMean op."
  name: "grad"
  type_attr: "T"
}
input_arg {
  description: "indices passed to the corresponding SparseSegmentMean op."
  name: "indices"
  type_attr: "Tidx"
}
input_arg {
  description: "segment_ids passed to the corresponding SparseSegmentMean op."
  name: "segment_ids"
  type: DT_INT32
}
input_arg {
  description: "dimension 0 of \"data\" passed to SparseSegmentMean op."
  name: "output_dim0"
  type: DT_INT32
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Gather values or slices from `params` according to `indices`.
--
-- `params` is a Tensor of rank `P` and `indices` is a Tensor of rank `Q`.
-- 
-- `indices` must be integer tensor, containing indices into `params`.
-- It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
-- 
-- The innermost dimension of `indices` (with length `K`) corresponds to
-- indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
-- dimension of `params`.
-- 
-- Produces an output tensor with shape
-- 
-- ```
-- [d_0, ..., d_{Q-2}, params.shape[K], ..., params.shape[P-1]].
-- ```
-- 
-- Some examples below.
-- 
-- Simple indexing into a matrix:
-- 
-- ```python
--     indices = [[0, 0], [1, 1]]
--     params = [['a', 'b'], ['c', 'd']]
--     output = ['a', 'd']
-- ```
-- 
-- Slice indexing into a matrix:
-- 
-- ```python
--     indices = [[1], [0]]
--     params = [['a', 'b'], ['c', 'd']]
--     output = [['c', 'd'], ['a', 'b']]
-- ```
-- 
-- Indexing into a 3-tensor:
-- 
-- ```python
--     indices = [[1]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = [[['a1', 'b1'], ['c1', 'd1']]]
-- 
-- 
--     indices = [[0, 1], [1, 0]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = [['c0', 'd0'], ['a1', 'b1']]
-- 
-- 
--     indices = [[0, 0, 1], [1, 0, 1]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = ['b0', 'b1']
-- ```
-- 
-- Batched indexing into a matrix:
-- 
-- ```python
--     indices = [[[0, 0]], [[0, 1]]]
--     params = [['a', 'b'], ['c', 'd']]
--     output = [['a'], ['b']]
-- ```
-- 
-- Batched slice indexing into a matrix:
-- 
-- ```python
--     indices = [[[1]], [[0]]]
--     params = [['a', 'b'], ['c', 'd']]
--     output = [[['c', 'd']], [['a', 'b']]]
-- ```
-- 
-- Batched indexing into a 3-tensor:
-- 
-- ```python
--     indices = [[[1]], [[0]]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = [[[['a1', 'b1'], ['c1', 'd1']]],
--               [[['a0', 'b0'], ['c0', 'd0']]]]
-- 
--     indices = [[[0, 1], [1, 0]], [[0, 0], [1, 1]]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = [[['c0', 'd0'], ['a1', 'b1']],
--               [['a0', 'b0'], ['c1', 'd1']]]
-- 
-- 
--     indices = [[[0, 0, 1], [1, 0, 1]], [[0, 1, 1], [1, 1, 0]]]
--     params = [[['a0', 'b0'], ['c0', 'd0']],
--               [['a1', 'b1'], ['c1', 'd1']]]
--     output = [['b0', 'b1'], ['d0', 'c1']]
-- ```
gatherNd :: forall v1 v2 tparams tindices . (TensorType tparams,
                                             TensorType tindices,
                                             OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] tindices) =>
            Tensor v1 tparams -- ^ __params__: `P-D`.  The tensor from which to gather values.
            -> Tensor v2 tindices -- ^ __indices__: `Q-D`.  Index tensor having shape `[d_0, ..., d_{Q-2}, K]`.
            -> Tensor Value tparams -- ^ __output__: `(P+Q-K-1)-D`.  Values from `params` gathered from indices given by
            -- `indices`.
gatherNd params indices | eqLengthGuard [] =
    buildOp (opDef "GatherNd"
             & opAttr "Tparams" .~ tensorType (undefined :: tparams)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        params indices
{-
attr { name: "Tparams" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg {
  description: "`P-D`.  The tensor from which to gather values."
  name: "params"
  type_attr: "Tparams"
}
input_arg {
  description: "`Q-D`.  Index tensor having shape `[d_0, ..., d_{Q-2}, K]`."
  name: "indices"
  type_attr: "Tindices"
}
output_arg {
  description: "`(P+Q-K-1)-D`.  Values from `params` gathered from indices given by\n`indices`."
  name: "output"
  type_attr: "Tparams"
}
-}

-- | Removes dimensions of size 1 from the shape of a tensor.
--
-- Given a tensor `input`, this operation returns a tensor of the same type with
-- all dimensions of size 1 removed. If you don't want to remove all size 1
-- dimensions, you can remove specific size 1 dimensions by specifying
-- `squeeze_dims`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 't' is a tensor of shape [1, 2, 1, 3, 1, 1]
-- shape(squeeze(t)) ==> [2, 3]
-- ```
-- 
-- Or, to remove specific size 1 dimensions:
-- 
-- ```prettyprint
-- # 't' is a tensor of shape [1, 2, 1, 3, 1, 1]
-- shape(squeeze(t, [2, 4])) ==> [1, 2, 3, 1]
-- ```
squeeze :: forall v1 t . (TensorType t) =>
           Tensor v1 t -- ^ __input__: The `input` to squeeze.
           -> Tensor Value t -- ^ __output__: Contains the same data as `input`, but has one or more dimensions of
           -- size 1 removed.
squeeze input | eqLengthGuard [] =
    buildOp (opDef "Squeeze"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
attr {
  default_value { list { } }
  description: "If specified, only squeezes the dimensions listed. The dimension\nindex starts at 0. It is an error to squeeze a dimension that is not 1."
  has_minimum: true
  name: "squeeze_dims"
  type: "list(int)"
}
input_arg {
  description: "The `input` to squeeze." name: "input" type_attr: "T"
}
output_arg {
  description: "Contains the same data as `input`, but has one or more dimensions of\nsize 1 removed."
  name: "output"
  type_attr: "T"
}
-}

-- | Outputs random values from a uniform distribution.
--
-- The generated values follow a uniform distribution in the range `[0, 1)`. The
-- lower bound 0 is included in the range, while the upper bound 1 is excluded.
randomUniform :: forall v1 dtype t . (TensorType dtype,
                                      OneOf '[Data.Word.Word16, Double,
                                              Float] dtype, TensorType t,
                                      OneOf '[Data.Int.Int32,
                                              Data.Int.Int64] t) =>
                 Tensor v1 t -- ^ __shape__: The shape of the output tensor.
                 -> Build (Tensor Value dtype) -- ^ __output__: A tensor of the specified shape filled with uniform random values.
randomUniform shape | eqLengthGuard [] =
    buildOp (opDef "RandomUniform"
             & opAttr "dtype" .~ tensorType (undefined :: dtype)
             & opAttr "T" .~ tensorType (undefined :: t))
        shape
{-
attr {
  default_value { i: 0 }
  description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "A second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
attr {
  allowed_values {
    list { type: DT_HALF type: DT_FLOAT type: DT_DOUBLE }
  }
  description: "The type of the output."
  name: "dtype"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "The shape of the output tensor."
  name: "shape"
  type_attr: "T"
}
output_arg {
  description: "A tensor of the specified shape filled with uniform random values."
  name: "output"
  type_attr: "dtype"
}
-}

-- | Returns up to `num_records` (key, value) pairs produced by a Reader.
--
-- Will dequeue from the input queue if necessary (e.g. when the
-- Reader needs to start reading from a new file since it has finished
-- with the previous file).
-- It may return less than `num_records` even before the last batch.
readerReadUpTo :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a `Reader`.
                  -> Tensor Ref Data.ByteString.ByteString -- ^ __queue_handle__: Handle to a `Queue`, with string work items.
                  -> Tensor v3 Data.Int.Int64 -- ^ __num_records__: number of records to read from `Reader`.
                  -> Build ((Tensor Value Data.ByteString.ByteString,
                             Tensor Value Data.ByteString.ByteString))
                  -- ^ (__keys__, __values__)
                  --
                  -- * __keys__: A 1-D tensor.
                  --
                  -- * __values__: A 1-D tensor.
readerReadUpTo reader_handle queue_handle num_records | eqLengthGuard [] =
    buildOp (opDef "ReaderReadUpTo")
        reader_handle queue_handle num_records
{-
input_arg {
  description: "Handle to a `Reader`."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
input_arg {
  description: "Handle to a `Queue`, with string work items."
  is_ref: true
  name: "queue_handle"
  type: DT_STRING
}
input_arg {
  description: "number of records to read from `Reader`."
  name: "num_records"
  type: DT_INT64
}
output_arg {
  description: "A 1-D tensor." name: "keys" type: DT_STRING
}
output_arg {
  description: "A 1-D tensor." name: "values" type: DT_STRING
}
-}

-- | Computes the gradients of 3-D convolution with respect to the input.

conv3DBackpropInput :: forall v1 v2 v3 t . (TensorType t,
                                            OneOf '[(Data.Complex.Complex Double),
                                                    (Data.Complex.Complex Float),
                                                    Data.Int.Int16,
                                                    Data.Int.Int32,
                                                    Data.Int.Int64,
                                                    Data.Int.Int8,
                                                    Data.Word.Word16,
                                                    Data.Word.Word8, Double,
                                                    Float] t) =>
                       Tensor v1 t -- ^ __input__: Shape `[batch, depth, rows, cols, in_channels]`.
                       -> Tensor v2 t -- ^ __filter__: Shape `[depth, rows, cols, in_channels, out_channels]`.
                                      -- `in_channels` must match between `input` and `filter`.
                       -> Tensor v3 t -- ^ __out_backprop__: Backprop signal of shape `[batch, out_depth, out_rows, out_cols,
                                      -- out_channels]`.
                       -> Tensor Value t -- ^ __output__
conv3DBackpropInput input filter out_backprop | eqLengthGuard [] =
    buildOp (opDef "Conv3DBackpropInput"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter out_backprop
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  description: "1-D tensor of length 5. The stride of the sliding window for each\ndimension of `input`. Must have `strides[0] = strides[4] = 1`."
  has_minimum: true
  minimum: 5
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg {
  description: "Shape `[batch, depth, rows, cols, in_channels]`."
  name: "input"
  type_attr: "T"
}
input_arg {
  description: "Shape `[depth, rows, cols, in_channels, out_channels]`.\n`in_channels` must match between `input` and `filter`."
  name: "filter"
  type_attr: "T"
}
input_arg {
  description: "Backprop signal of shape `[batch, out_depth, out_rows, out_cols,\nout_channels]`."
  name: "out_backprop"
  type_attr: "T"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | Computes a 2-D depthwise convolution given 4-D `input` and `filter` tensors.
--
-- Given an input tensor of shape `[batch, in_height, in_width, in_channels]`
-- and a filter / kernel tensor of shape
-- `[filter_height, filter_width, in_channels, channel_multiplier]`, containing
-- `in_channels` convolutional filters of depth 1, `depthwise_conv2d` applies
-- a different filter to each input channel (expanding from 1 channel to
-- `channel_multiplier` channels for each), then concatenates the results
-- together. Thus, the output has `in_channels * channel_multiplier` channels.
-- 
-- for k in 0..in_channels-1
--   for q in 0..channel_multiplier-1
--     output[b, i, j, k * channel_multiplier + q] =
--       sum_{di, dj} input[b, strides[1] * i + di, strides[2] * j + dj, k] *
--                         filter[di, dj, k, q]
-- 
-- Must have `strides[0] = strides[3] = 1`.  For the most common case of the same
-- horizontal and vertices strides, `strides = [1, stride, stride, 1]`.
depthwiseConv2dNative :: forall v1 v2 t . (TensorType t, OneOf '[Double,
                                                                 Float] t) =>
                         Tensor v1 t -- ^ __input__
                         -> Tensor v2 t -- ^ __filter__
                         -> Tensor Value t -- ^ __output__
depthwiseConv2dNative input filter | eqLengthGuard [] =
    buildOp (opDef "DepthwiseConv2dNative"
             & opAttr "T" .~ tensorType (undefined :: t))
        input filter
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  description: "1-D of length 4.  The stride of the sliding window for each dimension\nof `input`."
  name: "strides"
  type: "list(int)"
}
attr {
  allowed_values { list { s: "SAME" s: "VALID" } }
  description: "The type of padding algorithm to use."
  name: "padding"
  type: "string"
}
input_arg { name: "input" type_attr: "T" }
input_arg { name: "filter" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Generates labels for candidate sampling with a learned unigram distribution.
--
-- See explanations of candidate sampling and the data formats at
-- go/candidate-sampling.
-- 
-- For each batch, this op picks a single set of sampled candidate labels.
-- 
-- The advantages of sampling candidates per-batch are simplicity and the
-- possibility of efficient dense matrix multiplication. The disadvantage is that
-- the sampled candidates must be chosen independently of the context and of the
-- true labels.
learnedUnigramCandidateSampler :: Data.Int.Int64 -- ^ __num_sampled__: Number of candidates to randomly sample per batch.
                                  -> Data.Int.Int64 -- ^ __num_true__: Number of true labels per context.
                                  -> Data.Int.Int64 -- ^ __range_max__: The sampler will sample integers from the interval [0, range_max).
                                  -> Bool -- ^ __unique__: If unique is true, we sample with rejection, so that all sampled
                                          -- candidates in a batch are unique. This requires some approximation to
                                          -- estimate the post-rejection sampling probabilities.
                                  -> Tensor v1 Data.Int.Int64 -- ^ __true_classes__: A batch_size * num_true matrix, in which each row contains the
                                                              -- IDs of the num_true target_classes in the corresponding original label.
                                  -> (Tensor Value Data.Int.Int64,
                                      Tensor Value Float, Tensor Value Float)
                                  -- ^ (__sampled_candidates__, __true_expected_count__, __sampled_expected_count__)
                                  --
                                  -- * __sampled_candidates__: A vector of length num_sampled, in which each element is
                                  -- the ID of a sampled candidate.
                                  --
                                  -- * __true_expected_count__: A batch_size * num_true matrix, representing
                                  -- the number of times each candidate is expected to occur in a batch
                                  -- of sampled candidates. If unique=true, then this is a probability.
                                  --
                                  -- * __sampled_expected_count__: A vector of length num_sampled, for each sampled
                                  -- candidate representing the number of times the candidate is expected
                                  -- to occur in a batch of sampled candidates.  If unique=true, then this is a
                                  -- probability.
learnedUnigramCandidateSampler num_sampled num_true range_max unique
                               true_classes | eqLengthGuard [] =
    buildOp (opDef "LearnedUnigramCandidateSampler"
             & opAttr "num_sampled" .~ num_sampled
             & opAttr "num_true" .~ num_true
             & opAttr "range_max" .~ range_max
             & opAttr "unique" .~ unique)
        true_classes
{-
attr {
  description: "Number of true labels per context."
  has_minimum: true
  minimum: 1
  name: "num_true"
  type: "int"
}
attr {
  description: "Number of candidates to randomly sample per batch."
  has_minimum: true
  minimum: 1
  name: "num_sampled"
  type: "int"
}
attr {
  description: "If unique is true, we sample with rejection, so that all sampled\ncandidates in a batch are unique. This requires some approximation to\nestimate the post-rejection sampling probabilities."
  name: "unique"
  type: "bool"
}
attr {
  description: "The sampler will sample integers from the interval [0, range_max)."
  has_minimum: true
  minimum: 1
  name: "range_max"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "A batch_size * num_true matrix, in which each row contains the\nIDs of the num_true target_classes in the corresponding original label."
  name: "true_classes"
  type: DT_INT64
}
output_arg {
  description: "A vector of length num_sampled, in which each element is\nthe ID of a sampled candidate."
  name: "sampled_candidates"
  type: DT_INT64
}
output_arg {
  description: "A batch_size * num_true matrix, representing\nthe number of times each candidate is expected to occur in a batch\nof sampled candidates. If unique=true, then this is a probability."
  name: "true_expected_count"
  type: DT_FLOAT
}
output_arg {
  description: "A vector of length num_sampled, for each sampled\ncandidate representing the number of times the candidate is expected\nto occur in a batch of sampled candidates.  If unique=true, then this is a\nprobability."
  name: "sampled_expected_count"
  type: DT_FLOAT
}
-}

-- | Table initializer that takes two tensors for keys and values respectively.

initializeTable :: forall v2 v3 tkey tval . (TensorType tkey,
                                             TensorType tval) =>
                   Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to a table which will be initialized.
                   -> Tensor v2 tkey -- ^ __keys__: Keys of type Tkey.
                   -> Tensor v3 tval -- ^ __values__: Values of type Tval.
                   -> Build (ControlNode)
initializeTable table_handle keys values | eqLengthGuard [] =
    buildOp (opDef "InitializeTable"
             & opAttr "Tkey" .~ tensorType (undefined :: tkey)
             & opAttr "Tval" .~ tensorType (undefined :: tval))
        table_handle keys values
{-
attr { name: "Tkey" type: "type" }
attr { name: "Tval" type: "type" }
input_arg {
  description: "Handle to a table which will be initialized."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
input_arg {
  description: "Keys of type Tkey." name: "keys" type_attr: "Tkey"
}
input_arg {
  description: "Values of type Tval."
  name: "values"
  type_attr: "Tval"
}
-}

-- | Forwards the value of an available tensor from `inputs` to `output`.
--
-- `Merge` waits for at least one of the tensors in `inputs` to become available.
-- It is usually combined with `Switch` to implement branching.
-- 
-- `Merge` forwards the first tensor for become available to `output`, and sets
-- `value_index` to its index in `inputs`.
merge :: forall v1 t . (TensorType t) =>
         [Tensor v1 t] -- ^ __inputs__: The input tensors, exactly one of which will become available.
         -> (Tensor Value t, Tensor Value Data.Int.Int32)
         -- ^ (__output__, __value_index__)
         --
         -- * __output__: Will be set to the available input tensor.
         --
         -- * __value_index__: The index of the chosen input tensor in `inputs`.
merge inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "Merge"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { name: "T" type: "type" }
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
input_arg {
  description: "The input tensors, exactly one of which will become available."
  name: "inputs"
  number_attr: "N"
  type_attr: "T"
}
output_arg {
  description: "Will be set to the available input tensor."
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "The index of the chosen input tensor in `inputs`."
  name: "value_index"
  type: DT_INT32
}
-}

-- | Forwards the value of an available tensor from `inputs` to `output`.
--
-- `Merge` waits for at least one of the tensors in `inputs` to become available.
-- It is usually combined with `Switch` to implement branching.
-- 
-- `Merge` forwards the first tensor for become available to `output`, and sets
-- `value_index` to its index in `inputs`.
refMerge :: forall t . (TensorType t) =>
            [Tensor Ref t] -- ^ __inputs__: The input tensors, exactly one of which will become available.
            -> Build ((Tensor Ref t, Tensor Value Data.Int.Int32))
            -- ^ (__output__, __value_index__)
            --
            -- * __output__: Will be set to the available input tensor.
            --
            -- * __value_index__: The index of the chosen input tensor in `inputs`.
refMerge inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "RefMerge"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { name: "T" type: "type" }
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
input_arg {
  description: "The input tensors, exactly one of which will become available."
  is_ref: true
  name: "inputs"
  number_attr: "N"
  type_attr: "T"
}
output_arg {
  description: "Will be set to the available input tensor."
  is_ref: true
  name: "output"
  type_attr: "T"
}
output_arg {
  description: "The index of the chosen input tensor in `inputs`."
  name: "value_index"
  type: DT_INT32
}
-}

-- | Rounds the values of a tensor to the nearest integer, element-wise.
--
-- Rounds half to even.  Also known as bankers rounding. If you want to round
-- according to the current system rounding mode use std::cint.
round :: forall v1 t . (TensorType t, OneOf '[(Data.Complex.Complex Double),
                                              (Data.Complex.Complex Float),
                                              Data.Int.Int32, Data.Int.Int64,
                                              Data.Word.Word16, Double,
                                              Float] t) =>
         Tensor v1 t -- ^ __x__
         -> Tensor Value t -- ^ __y__
round x | eqLengthGuard [] =
    buildOp (opDef "Round"
             & opAttr "T" .~ tensorType (undefined :: t))
        x
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
output_arg { name: "y" type_attr: "T" }
-}

-- | 

batchSelfAdjointEig :: forall v1 t . (TensorType t, OneOf '[Double, Float] t) =>
                       Tensor v1 t -- ^ __input__
                       -> Tensor Value t -- ^ __output__
batchSelfAdjointEig input | eqLengthGuard [] =
    buildOp (opDef "BatchSelfAdjointEig"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr {
  allowed_values { list { type: DT_DOUBLE type: DT_FLOAT } }
  name: "T"
  type: "type"
}
input_arg { name: "input" type_attr: "T" }
output_arg { name: "output" type_attr: "T" }
-}

-- | Partitions `data` into `num_partitions` tensors using indices from `partitions`.
--
-- For each index tuple `js` of size `partitions.ndim`, the slice `data[js, ...]`
-- becomes part of `outputs[partitions[js]]`.  The slices with `partitions[js] = i`
-- are placed in `outputs[i]` in lexicographic order of `js`, and the first
-- dimension of `outputs[i]` is the number of entries in `partitions` equal to `i`.
-- In detail,
-- 
-- ```python
--     outputs[i].shape = [sum(partitions == i)] + data.shape[partitions.ndim:]
-- 
--     outputs[i] = pack([data[js, ...] for js if partitions[js] == i])
-- ```
-- 
-- `data.shape` must start with `partitions.shape`.
-- 
-- For example:
-- 
-- ```python
--     # Scalar partitions.
--     partitions = 1
--     num_partitions = 2
--     data = [10, 20]
--     outputs[0] = []  # Empty with shape [0, 2]
--     outputs[1] = [[10, 20]]
-- 
--     # Vector partitions.
--     partitions = [0, 0, 1, 1, 0]
--     num_partitions = 2
--     data = [10, 20, 30, 40, 50]
--     outputs[0] = [10, 20, 50]
--     outputs[1] = [30, 40]
-- ```
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/DynamicPartition.png" alt>
-- </div>
dynamicPartition :: forall v1 v2 t . (TensorType t) =>
                    Data.Int.Int64 -- ^ __num_partitions__: The number of partitions to output.
                    -> Tensor v1 t -- ^ __data__
                    -> Tensor v2 Data.Int.Int32 -- ^ __partitions__: Any shape.  Indices in the range `[0, num_partitions)`.
                    -> [Tensor Value t] -- ^ __outputs__
dynamicPartition num_partitions data' partitions | eqLengthGuard [] =
    buildListOp [num_partitions] (opDef "DynamicPartition"
                                  & opAttr "T" .~ tensorType (undefined :: t)
                                  & opAttr "num_partitions" .~ num_partitions)
        data' partitions
{-
attr {
  description: "The number of partitions to output."
  has_minimum: true
  minimum: 1
  name: "num_partitions"
  type: "int"
}
attr { name: "T" type: "type" }
input_arg { name: "data" type_attr: "T" }
input_arg {
  description: "Any shape.  Indices in the range `[0, num_partitions)`."
  name: "partitions"
  type: DT_INT32
}
output_arg {
  name: "outputs" number_attr: "num_partitions" type_attr: "T"
}
-}

-- | Reshapes a tensor.
--
-- Given `tensor`, this operation returns a tensor that has the same values
-- as `tensor` with shape `shape`.
-- 
-- If one component of `shape` is the special value -1, the size of that dimension
-- is computed so that the total size remains constant.  In particular, a `shape`
-- of `[-1]` flattens into 1-D.  At most one component of `shape` can be -1.
-- 
-- If `shape` is 1-D or higher, then the operation returns a tensor with shape
-- `shape` filled with the values of `tensor`. In this case, the number of elements
-- implied by `shape` must be the same as the number of elements in `tensor`.
-- 
-- For example:
-- 
-- ```prettyprint
-- # tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
-- # tensor 't' has shape [9]
-- reshape(t, [3, 3]) ==> [[1, 2, 3],
--                         [4, 5, 6],
--                         [7, 8, 9]]
-- 
-- # tensor 't' is [[[1, 1], [2, 2]],
-- #                [[3, 3], [4, 4]]]
-- # tensor 't' has shape [2, 2, 2]
-- reshape(t, [2, 4]) ==> [[1, 1, 2, 2],
--                         [3, 3, 4, 4]]
-- 
-- # tensor 't' is [[[1, 1, 1],
-- #                 [2, 2, 2]],
-- #                [[3, 3, 3],
-- #                 [4, 4, 4]],
-- #                [[5, 5, 5],
-- #                 [6, 6, 6]]]
-- # tensor 't' has shape [3, 2, 3]
-- # pass '[-1]' to flatten 't'
-- reshape(t, [-1]) ==> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]
-- 
-- # -1 can also be used to infer the shape
-- 
-- # -1 is inferred to be 9:
-- reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
--                          [4, 4, 4, 5, 5, 5, 6, 6, 6]]
-- # -1 is inferred to be 2:
-- reshape(t, [-1, 9]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
--                          [4, 4, 4, 5, 5, 5, 6, 6, 6]]
-- # -1 is inferred to be 3:
-- reshape(t, [ 2, -1, 3]) ==> [[[1, 1, 1],
--                               [2, 2, 2],
--                               [3, 3, 3]],
--                              [[4, 4, 4],
--                               [5, 5, 5],
--                               [6, 6, 6]]]
-- 
-- # tensor 't' is [7]
-- # shape `[]` reshapes to a scalar
-- reshape(t, []) ==> 7
-- ```
reshape :: forall v1 v2 t tshape . (TensorType t, TensorType tshape,
                                    OneOf '[Data.Int.Int32,
                                            Data.Int.Int64] tshape) =>
           Tensor v1 t -- ^ __tensor__
           -> Tensor v2 tshape -- ^ __shape__: Defines the shape of the output tensor.
           -> Tensor Value t -- ^ __output__
reshape tensor shape | eqLengthGuard [] =
    buildOp (opDef "Reshape"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tshape" .~ tensorType (undefined :: tshape))
        tensor shape
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tshape"
  type: "type"
}
input_arg { name: "tensor" type_attr: "T" }
input_arg {
  description: "Defines the shape of the output tensor."
  name: "shape"
  type_attr: "Tshape"
}
output_arg { name: "output" type_attr: "T" }
-}

-- | A Reader that outputs fixed-length records from a file.

fixedLengthRecordReader :: Data.Int.Int64 -- ^ __record_bytes__
                           -> Build (Tensor Ref Data.ByteString.ByteString) -- ^ __reader_handle__: The handle to reference the Reader.
fixedLengthRecordReader record_bytes | eqLengthGuard [] =
    buildOp (opDef "FixedLengthRecordReader"
             & opAttr "record_bytes" .~ record_bytes)
        
{-
attr { default_value { i: 0 } name: "header_bytes" type: "int" }
attr { name: "record_bytes" type: "int" }
attr { default_value { i: 0 } name: "footer_bytes" type: "int" }
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this reader is named in the given bucket\nwith this shared_name. Otherwise, the node name is used instead."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to reference the Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
-}

-- | Distributed version of Stochastic Dual Coordinate Ascent (SDCA) optimizer for
--
-- linear models with L1 + L2 regularization. As global optimization objective is
-- strongly-convex, the optimizer optimizes the dual objective at each step. The
-- optimizer applies each update one example at a time. Examples are sampled
-- uniformly, and the optimizer is learning rate free and enjoys linear convergence
-- rate.
-- 
-- Proximal Stochastic Dual Coordinate Ascent, Shalev-Shwartz, Shai; Zhang, Tong.
-- 2012 arXiv1211.2717S: http://arxiv.org/pdf/1211.2717v1.pdf
-- 
--   Loss objective = \sum f_{i}(wx_{i}) + (l2 / 2) * |w|^2 + l1 * |w|
-- 
-- Adding vs. Averaging in Distributed Primal-Dual Optimization.
-- Chenxin Ma, Virginia Smith, Martin Jaggi, Michael I. Jordan, Peter Richtarik,
-- Martin Takac http://arxiv.org/abs/1502.03508
-- 
-- Stochastic Dual Coordinate Ascent with Adaptive Probabilities
-- Dominik Csiba, Zheng Qu, Peter Richtarik https://arxiv.org/abs/1502.08053
sdcaOptimizer :: Float -- ^ __l1__: Symmetric l1 regularization strength.
                 -> Float -- ^ __l2__: Symmetric l2 regularization strength.
                 -> Data.Int.Int64 -- ^ __num_inner_iterations__: Number of iterations per mini-batch.
                 -> Data.Int.Int64 -- ^ __num_loss_partitions__: Number of partitions of the global loss function.
                 -> [Tensor v1 Data.Int.Int64] -- ^ __sparse_example_indices__: a list of vectors which contain example indices.
                 -> [Tensor v2 Data.Int.Int64] -- ^ __sparse_feature_indices__: a list of vectors which contain feature indices.
                 -> [Tensor v3 Float] -- ^ __sparse_feature_values__: a list of vectors which contains feature value
                                      -- associated with each feature group.
                 -> [Tensor v4 Float] -- ^ __dense_features__: a list of matrices which contains the dense feature values.
                 -> Tensor v5 Float -- ^ __example_weights__: a vector which contains the weight associated with each
                                    -- example.
                 -> Tensor v6 Float -- ^ __example_labels__: a vector which contains the label/target associated with each
                                    -- example.
                 -> [Tensor v7 Data.Int.Int64] -- ^ __sparse_indices__: a list of vectors where each value is the indices which has
                                               -- corresponding weights in sparse_weights. This field maybe ommitted for the
                                               -- dense approach.
                 -> [Tensor v8 Float] -- ^ __sparse_weights__: a list of vectors where each value is the weight associated with
                                      -- a sparse feature group.
                 -> [Tensor v9 Float] -- ^ __dense_weights__: a list of vectors where the values are the weights associated
                                      -- with a dense feature group.
                 -> Tensor v10 Float -- ^ __example_state_data__: a list of vectors containing the example state data.
                 -> (Tensor Value Float, [Tensor Value Float],
                     [Tensor Value Float])
                 -- ^ (__out_example_state_data__, __out_delta_sparse_weights__, __out_delta_dense_weights__)
                 --
                 -- * __out_example_state_data__: a list of vectors containing the updated example state
                 -- data.
                 --
                 -- * __out_delta_sparse_weights__: a list of vectors where each value is the delta
                 -- weights associated with a sparse feature group.
                 --
                 -- * __out_delta_dense_weights__: a list of vectors where the values are the delta
                 -- weights associated with a dense feature group.
sdcaOptimizer l1 l2 num_inner_iterations num_loss_partitions
              sparse_example_indices sparse_feature_indices
              sparse_feature_values dense_features example_weights
              example_labels sparse_indices sparse_weights dense_weights
              example_state_data | eqLengthGuard [("num_sparse_features", [("sparse_example_indices", length sparse_example_indices),
                                                                           ("sparse_feature_indices", length sparse_feature_indices),
                                                                           ("sparse_indices", length sparse_indices),
                                                                           ("sparse_weights", length sparse_weights)]),
                                                  ("num_sparse_features_with_values", [("sparse_feature_values", length sparse_feature_values)]),
                                                  ("num_dense_features", [("dense_features", length dense_features),
                                                                          ("dense_weights", length dense_weights)])] =
    buildListOp [num_sparse_features, num_dense_features] (opDef "SdcaOptimizer"
                                                           & opAttr "l1" .~ l1
                                                           & opAttr "l2" .~ l2
                                                           & opAttr "num_inner_iterations" .~ num_inner_iterations
                                                           & opAttr "num_loss_partitions" .~ num_loss_partitions
                                                           & opAttr "num_sparse_features" .~ num_sparse_features
                                                           & opAttr "num_sparse_features_with_values" .~ num_sparse_features_with_values
                                                           & opAttr "num_dense_features" .~ num_dense_features)
        sparse_example_indices sparse_feature_indices sparse_feature_values
        dense_features example_weights example_labels sparse_indices
        sparse_weights dense_weights example_state_data
  where
    num_sparse_features = fromIntegral (length sparse_example_indices) :: Int64
    num_sparse_features_with_values = fromIntegral (length sparse_feature_values) :: Int64
    num_dense_features = fromIntegral (length dense_features) :: Int64
{-
attr {
  allowed_values {
    list {
      s: "logistic_loss"
      s: "squared_loss"
      s: "hinge_loss"
      s: "smooth_hinge_loss"
    }
  }
  description: "Type of the primal loss. Currently SdcaSolver supports logistic,\nsquared and hinge losses."
  name: "loss_type"
  type: "string"
}
attr {
  default_value { b: false }
  description: "Whether to use Adapative SDCA for the inner loop."
  name: "adaptative"
  type: "bool"
}
attr {
  description: "Number of sparse feature groups to train on."
  has_minimum: true
  name: "num_sparse_features"
  type: "int"
}
attr {
  description: "Number of sparse feature groups with values\nassociated with it, otherwise implicitly treats values as 1.0."
  has_minimum: true
  name: "num_sparse_features_with_values"
  type: "int"
}
attr {
  description: "Number of dense feature groups to train on."
  has_minimum: true
  name: "num_dense_features"
  type: "int"
}
attr {
  description: "Symmetric l1 regularization strength."
  name: "l1"
  type: "float"
}
attr {
  description: "Symmetric l2 regularization strength."
  name: "l2"
  type: "float"
}
attr {
  description: "Number of partitions of the global loss function."
  has_minimum: true
  minimum: 1
  name: "num_loss_partitions"
  type: "int"
}
attr {
  description: "Number of iterations per mini-batch."
  has_minimum: true
  minimum: 1
  name: "num_inner_iterations"
  type: "int"
}
input_arg {
  description: "a list of vectors which contain example indices."
  name: "sparse_example_indices"
  number_attr: "num_sparse_features"
  type: DT_INT64
}
input_arg {
  description: "a list of vectors which contain feature indices."
  name: "sparse_feature_indices"
  number_attr: "num_sparse_features"
  type: DT_INT64
}
input_arg {
  description: "a list of vectors which contains feature value\nassociated with each feature group."
  name: "sparse_feature_values"
  number_attr: "num_sparse_features_with_values"
  type: DT_FLOAT
}
input_arg {
  description: "a list of matrices which contains the dense feature values."
  name: "dense_features"
  number_attr: "num_dense_features"
  type: DT_FLOAT
}
input_arg {
  description: "a vector which contains the weight associated with each\nexample."
  name: "example_weights"
  type: DT_FLOAT
}
input_arg {
  description: "a vector which contains the label/target associated with each\nexample."
  name: "example_labels"
  type: DT_FLOAT
}
input_arg {
  description: "a list of vectors where each value is the indices which has\ncorresponding weights in sparse_weights. This field maybe ommitted for the\ndense approach."
  name: "sparse_indices"
  number_attr: "num_sparse_features"
  type: DT_INT64
}
input_arg {
  description: "a list of vectors where each value is the weight associated with\na sparse feature group."
  name: "sparse_weights"
  number_attr: "num_sparse_features"
  type: DT_FLOAT
}
input_arg {
  description: "a list of vectors where the values are the weights associated\nwith a dense feature group."
  name: "dense_weights"
  number_attr: "num_dense_features"
  type: DT_FLOAT
}
input_arg {
  description: "a list of vectors containing the example state data."
  name: "example_state_data"
  type: DT_FLOAT
}
output_arg {
  description: "a list of vectors containing the updated example state\ndata."
  name: "out_example_state_data"
  type: DT_FLOAT
}
output_arg {
  description: "a list of vectors where each value is the delta\nweights associated with a sparse feature group."
  name: "out_delta_sparse_weights"
  number_attr: "num_sparse_features"
  type: DT_FLOAT
}
output_arg {
  description: "a list of vectors where the values are the delta\nweights associated with a dense feature group."
  name: "out_delta_dense_weights"
  number_attr: "num_dense_features"
  type: DT_FLOAT
}
-}

-- | Resize `images` to `size` using area interpolation.
--
-- Input images can be of different types but output images are always float.
resizeArea :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word16,
                                                      Data.Word.Word8, Double,
                                                      Float] t) =>
              Tensor v1 t -- ^ __images__: 4-D with shape `[batch, height, width, channels]`.
              -> Tensor v2 Data.Int.Int32 -- ^ __size__: = A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The
                                          -- new size for the images.
              -> Tensor Value Float -- ^ __resized_images__: 4-D with shape
              -- `[batch, new_height, new_width, channels]`.
resizeArea images size | eqLengthGuard [] =
    buildOp (opDef "ResizeArea"
             & opAttr "T" .~ tensorType (undefined :: t))
        images size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If true, rescale input by (new_height - 1) / (height - 1), which\nexactly aligns the 4 corners of images and resized images. If false, rescale\nby new_height / height. Treat similarly the width dimension."
  name: "align_corners"
  type: "bool"
}
input_arg {
  description: "4-D with shape `[batch, height, width, channels]`."
  name: "images"
  type_attr: "T"
}
input_arg {
  description: "= A 1-D int32 Tensor of 2 elements: `new_height, new_width`.  The\nnew size for the images."
  name: "size"
  type: DT_INT32
}
output_arg {
  description: "4-D with shape\n`[batch, new_height, new_width, channels]`."
  name: "resized_images"
  type: DT_FLOAT
}
-}

-- | Generates values in an interval.
--
-- A sequence of `num` evenly-spaced values are generated beginning at `start`.
-- If `num > 1`, the values in the sequence increase by `stop - start / num - 1`,
-- so that the last one is exactly `stop`.
-- 
-- For example:
-- 
-- ```
-- tf.linspace(10.0, 12.0, 3, name="linspace") => [ 10.0  11.0  12.0]
-- ```
linSpace :: forall v1 v2 v3 t tidx . (TensorType t, OneOf '[Double, Float] t,
                                      TensorType tidx, OneOf '[Data.Int.Int32,
                                                               Data.Int.Int64] tidx) =>
            Tensor v1 t -- ^ __start__: First entry in the range.
            -> Tensor v2 t -- ^ __stop__: Last entry in the range.
            -> Tensor v3 tidx -- ^ __num__: Number of values to generate.
            -> Tensor Value t -- ^ __output__: 1-D. The generated values.
linSpace start stop num | eqLengthGuard [] =
    buildOp (opDef "LinSpace"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        start stop num
{-
attr {
  allowed_values { list { type: DT_FLOAT type: DT_DOUBLE } }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "First entry in the range."
  name: "start"
  type_attr: "T"
}
input_arg {
  description: "Last entry in the range." name: "stop" type_attr: "T"
}
input_arg {
  description: "Number of values to generate."
  name: "num"
  type_attr: "Tidx"
}
output_arg {
  description: "1-D. The generated values."
  name: "output"
  type_attr: "T"
}
-}

-- | Calculates the CTC Loss (log probability) for each batch entry.  Also calculates
--
-- the gradient.  This class performs the softmax operation for you, so inputs
-- should be e.g. linear projections of outputs by an LSTM.
cTCLoss :: Tensor v1 Float -- ^ __inputs__: 3-D, shape: `(max_time x batch_size x num_classes)`, the logits.
           -> Tensor v2 Data.Int.Int64 -- ^ __labels_indices__: The indices of a `SparseTensor<int32, 2>`.
                                       -- `labels_indices(i, :) == [b, t]` means `labels_values(i)` stores the id for
                                       -- `(batch b, time t)`.
           -> Tensor v3 Data.Int.Int32 -- ^ __labels_values__: The values (labels) associated with the given batch and time.
           -> Tensor v4 Data.Int.Int32 -- ^ __sequence_length__: A vector containing sequence lengths (batch).
           -> (Tensor Value Float, Tensor Value Float)
           -- ^ (__loss__, __gradient__)
           --
           -- * __loss__: A vector (batch) containing log-probabilities.
           --
           -- * __gradient__: The gradient of `loss`.  3-D, shape:
           -- `(max_time x batch_size x num_classes)`.
cTCLoss inputs labels_indices labels_values sequence_length | eqLengthGuard [] =
    buildOp (opDef "CTCLoss")
        inputs labels_indices labels_values sequence_length
{-
attr {
  default_value { b: false }
  description: "Scalar, if true then repeated labels are\ncollapsed prior to the CTC calculation."
  name: "preprocess_collapse_repeated"
  type: "bool"
}
attr {
  default_value { b: true }
  description: "Scalar.  If set to false, *during* CTC calculation\nrepeated non-blank labels will not be merged and are interpreted as\nindividual labels.  This is a simplified version of CTC."
  name: "ctc_merge_repeated"
  type: "bool"
}
input_arg {
  description: "3-D, shape: `(max_time x batch_size x num_classes)`, the logits."
  name: "inputs"
  type: DT_FLOAT
}
input_arg {
  description: "The indices of a `SparseTensor<int32, 2>`.\n`labels_indices(i, :) == [b, t]` means `labels_values(i)` stores the id for\n`(batch b, time t)`."
  name: "labels_indices"
  type: DT_INT64
}
input_arg {
  description: "The values (labels) associated with the given batch and time."
  name: "labels_values"
  type: DT_INT32
}
input_arg {
  description: "A vector containing sequence lengths (batch)."
  name: "sequence_length"
  type: DT_INT32
}
output_arg {
  description: "A vector (batch) containing log-probabilities."
  name: "loss"
  type: DT_FLOAT
}
output_arg {
  description: "The gradient of `loss`.  3-D, shape:\n`(max_time x batch_size x num_classes)`."
  name: "gradient"
  type: DT_FLOAT
}
-}

-- | Returns the batched diagonal part of a batched tensor.
--
-- This operation returns a tensor with the `diagonal` part
-- of the batched `input`. The `diagonal` part is computed as follows:
-- 
-- Assume `input` has `k` dimensions `[I, J, K, ..., M, N]`, then the output is a
-- tensor of rank `k - 1` with dimensions `[I, J, K, ..., min(M, N)]` where:
-- 
-- `diagonal[i, j, k, ..., n] = input[i, j, k, ..., n, n]`.
-- 
-- The input must be at least a matrix.
-- 
-- For example:
-- 
-- ```prettyprint
-- # 'input' is [[[1, 0, 0, 0]
--                [0, 2, 0, 0]
--                [0, 0, 3, 0]
--                [0, 0, 0, 4]],
--               [[5, 0, 0, 0]
--                [0, 6, 0, 0]
--                [0, 0, 7, 0]
--                [0, 0, 0, 8]]]
-- 
-- and input.shape = (2, 4, 4)
-- 
-- tf.matrix_diag_part(input) ==> [[1, 2, 3, 4], [5, 6, 7, 8]]
-- 
-- which has shape (2, 4)
-- ```
matrixDiagPart :: forall v1 t . (TensorType t) =>
                  Tensor v1 t -- ^ __input__: Rank `k` tensor where `k >= 2`.
                  -> Tensor Value t -- ^ __diagonal__: The extracted diagonal(s) having shape
                  -- `diagonal.shape = input.shape[:-2] + [min(input.shape[-2:])]`.
matrixDiagPart input | eqLengthGuard [] =
    buildOp (opDef "MatrixDiagPart"
             & opAttr "T" .~ tensorType (undefined :: t))
        input
{-
attr { name: "T" type: "type" }
input_arg {
  description: "Rank `k` tensor where `k >= 2`."
  name: "input"
  type_attr: "T"
}
output_arg {
  description: "The extracted diagonal(s) having shape\n`diagonal.shape = input.shape[:-2] + [min(input.shape[-2:])]`."
  name: "diagonal"
  type_attr: "T"
}
-}

-- | Creates or finds a child frame, and makes `data` available to the child frame.
--
-- This op is used together with `Exit` to create loops in the graph.
-- The unique `frame_name` is used by the `Executor` to identify frames. If
-- `is_constant` is true, `output` is a constant in the child frame; otherwise
-- it may be changed in the child frame. At most `parallel_iterations` iterations
-- are run in parallel in the child frame.
enter :: forall v1 t . (TensorType t) =>
         Tensor v1 t -- ^ __data__: The tensor to be made available to the child frame.
         -> Tensor Value t -- ^ __output__: The same tensor as `data`.
enter data' | eqLengthGuard [] =
    buildOp (opDef "Enter"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
attr {
  description: "The name of the child frame."
  name: "frame_name"
  type: "string"
}
attr {
  default_value { b: false }
  description: "If true, the output is constant within the child frame."
  name: "is_constant"
  type: "bool"
}
attr {
  default_value { i: 10 }
  description: "The number of iterations allowed to run in parallel."
  name: "parallel_iterations"
  type: "int"
}
input_arg {
  description: "The tensor to be made available to the child frame."
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  name: "output"
  type_attr: "T"
}
-}

-- | PNG-encode an image.
--
-- `image` is a 3-D uint8 or uint16 Tensor of shape `[height, width, channels]`
-- where `channels` is:
-- 
-- *   1: for grayscale.
-- *   2: for grayscale + alpha.
-- *   3: for RGB.
-- *   4: for RGBA.
-- 
-- The ZLIB compression level, `compression`, can be -1 for the PNG-encoder
-- default or a value from 0 to 9.  9 is the highest compression level, generating
-- the smallest output, but is slower.
encodePng :: forall v1 t . (TensorType t, OneOf '[Data.Word.Word16,
                                                  Data.Word.Word8] t) =>
             Tensor v1 t -- ^ __image__: 3-D with shape `[height, width, channels]`.
             -> Tensor Value Data.ByteString.ByteString -- ^ __contents__: 0-D. PNG-encoded image.
encodePng image | eqLengthGuard [] =
    buildOp (opDef "EncodePng"
             & opAttr "T" .~ tensorType (undefined :: t))
        image
{-
attr {
  default_value { i: -1 }
  description: "Compression level."
  name: "compression"
  type: "int"
}
attr {
  allowed_values { list { type: DT_UINT8 type: DT_UINT16 } }
  default_value { type: DT_UINT8 }
  name: "T"
  type: "type"
}
input_arg {
  description: "3-D with shape `[height, width, channels]`."
  name: "image"
  type_attr: "T"
}
output_arg {
  description: "0-D. PNG-encoded image."
  name: "contents"
  type: DT_STRING
}
-}

-- | Exits the current frame to its parent frame.
--
-- Exit makes its input `data` available to the parent frame.
exit :: forall v1 t . (TensorType t) =>
        Tensor v1 t -- ^ __data__: The tensor to be made available to the parent frame.
        -> Tensor Value t -- ^ __output__: The same tensor as `data`.
exit data' | eqLengthGuard [] =
    buildOp (opDef "Exit"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be made available to the parent frame."
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  name: "output"
  type_attr: "T"
}
-}

-- | Creates a new tensor by applying sparse `updates` to individual
--
-- values or slices within a zero tensor of the given `shape` tensor according to
-- indices.  This operator is the inverse of the [tf.gather_nd](#gather_nd)
-- operator which extracts values or slices from a given tensor.
-- 
-- TODO(simister): Add a link to Variable.__getitem__ documentation on slice
-- syntax.
-- 
-- `shape` is a `TensorShape` with rank `P` and `indices` is a `Tensor` of rank
-- `Q`.
-- 
-- `indices` must be integer tensor, containing indices into `shape`.
-- It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
-- 
-- The innermost dimension of `indices` (with length `K`) corresponds to
-- indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
-- dimension of `shape`.
-- 
-- `updates` is Tensor of rank `Q-1+P-K` with shape:
-- 
-- ```
-- [d_0, ..., d_{Q-2}, shape[K], ..., shape[P-1]].
-- ```
-- 
-- The simplest form of scatter is to insert individual elements in a tensor by
-- index. For example, say we want to insert 4 scattered elements in a rank-1
-- tensor with 8 elements.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterNd1.png" alt>
-- </div>
-- 
-- In Python, this scatter operation would look like this:
-- 
--     indices = tf.constant([[4], [3], [1], [7]])
--     updates = tf.constant([9, 10, 11, 12])
--     shape = tf.constant([8])
--     scatter = tf.scatter_nd(indices, updates, shape)
--     with tf.Session() as sess:
--       print sess.run(scatter)
-- 
-- The resulting tensor would look like this:
-- 
--     [0, 11, 0, 10, 9, 0, 0, 12]
-- 
-- We can also, insert entire slices of a higher rank tensor all at once. For
-- example, if we wanted to insert two slices in the first dimension of a
-- rank-3 tensor with two matrices of new values.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterNd2.png" alt>
-- </div>
-- 
-- In Python, this scatter operation would look like this:
-- 
--     indices = tf.constant([[0], [2]])
--     updates = tf.constant([[[5, 5, 5, 5], [6, 6, 6, 6],
--                             [7, 7, 7, 7], [8, 8, 8, 8]],
--                            [[5, 5, 5, 5], [6, 6, 6, 6],
--                             [7, 7, 7, 7], [8, 8, 8, 8]]])
--     shape = tf.constant([4, 4, 4])
--     scatter = tf.scatter_nd(indices, updates, shape)
--     with tf.Session() as sess:
--       print sess.run(scatter)
-- 
-- The resulting tensor would look like this:
-- 
--     [[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],
--      [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
--      [[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],
--      [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
scatterNd :: forall v1 v2 v3 t tindices . (TensorType t, TensorType tindices,
                                           OneOf '[Data.Int.Int32,
                                                   Data.Int.Int64] tindices) =>
             Tensor v1 tindices -- ^ __indices__: A Tensor. Must be one of the following types: int32, int64.
                                -- A tensor of indices into ref.
             -> Tensor v2 t -- ^ __updates__: A Tensor. Must have the same type as tensor. A tensor of updated values
                            -- to store in ref.
             -> Tensor v3 tindices -- ^ __shape__: A vector. The shape of the resulting tensor.
             -> Tensor Value t -- ^ __output__: A new tensor with the given shape and updates applied according
             -- to the indices.
scatterNd indices updates shape | eqLengthGuard [] =
    buildOp (opDef "ScatterNd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        indices updates shape
{-
attr { name: "T" type: "type" }
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
input_arg {
  description: "A Tensor. Must be one of the following types: int32, int64.\nA tensor of indices into ref."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A Tensor. Must have the same type as tensor. A tensor of updated values\nto store in ref."
  name: "updates"
  type_attr: "T"
}
input_arg {
  description: "A vector. The shape of the resulting tensor."
  name: "shape"
  type_attr: "Tindices"
}
output_arg {
  description: "A new tensor with the given shape and updates applied according\nto the indices."
  name: "output"
  type_attr: "T"
}
-}

-- | A queue that produces elements sorted by the first component value.
--
-- Note that the PriorityQueue requires the first component of any element
-- to be a scalar int64, in addition to the other elements declared by
-- component_types.  Therefore calls to Enqueue and EnqueueMany (resp. Dequeue
-- and DequeueMany) on a PriorityQueue will all require (resp. output) one extra
-- entry in their input (resp. output) lists.
priorityQueue :: Build (Tensor Ref Data.ByteString.ByteString) -- ^ __handle__: The handle to the queue.
priorityQueue  | eqLengthGuard [] =
    buildOp (opDef "PriorityQueue")
        
{-
attr {
  default_value { list { } }
  description: "The type of each component in a value."
  has_minimum: true
  name: "component_types"
  type: "list(type)"
}
attr {
  description: "The shape of each component in a value. The length of this attr must\nbe either 0 or the same as the length of component_types. If the length of\nthis attr is 0, the shapes of queue elements are not constrained, and\nonly one element may be dequeued at a time."
  has_minimum: true
  name: "shapes"
  type: "list(shape)"
}
attr {
  default_value { i: -1 }
  description: "The upper bound on the number of elements in this queue.\nNegative numbers mean no limit."
  name: "capacity"
  type: "int"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue is placed in the given container.\nOtherwise, a default container is used."
  name: "container"
  type: "string"
}
attr {
  default_value { s: "" }
  description: "If non-empty, this queue will be shared under the given name\nacross multiple sessions."
  name: "shared_name"
  type: "string"
}
output_arg {
  description: "The handle to the queue."
  is_ref: true
  name: "handle"
  type: DT_STRING
}
-}

-- | Forwards the ref tensor `data` to the output port determined by `pred`.
--
-- If `pred` is true, the `data` input is forwarded to `output_true`. Otherwise,
-- the data goes to `output_false`.
-- 
-- See also `Switch` and `Merge`.
refSwitch :: forall v2 t . (TensorType t) =>
             Tensor Ref t -- ^ __data__: The ref tensor to be forwarded to the appropriate output.
             -> Tensor v2 Bool -- ^ __pred__: A scalar that specifies which output port will receive data.
             -> Build ((Tensor Ref t, Tensor Ref t))
             -- ^ (__output_false__, __output_true__)
             --
             -- * __output_false__: If `pred` is false, data will be forwarded to this output.
             --
             -- * __output_true__: If `pred` is true, data will be forwarded to this output.
refSwitch data' pred | eqLengthGuard [] =
    buildOp (opDef "RefSwitch"
             & opAttr "T" .~ tensorType (undefined :: t))
        data' pred
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The ref tensor to be forwarded to the appropriate output."
  is_ref: true
  name: "data"
  type_attr: "T"
}
input_arg {
  description: "A scalar that specifies which output port will receive data."
  name: "pred"
  type: DT_BOOL
}
output_arg {
  description: "If `pred` is false, data will be forwarded to this output."
  is_ref: true
  name: "output_false"
  type_attr: "T"
}
output_arg {
  description: "If `pred` is true, data will be forwarded to this output."
  is_ref: true
  name: "output_true"
  type_attr: "T"
}
-}

-- | Makes its input available to the next iteration.

nextIteration :: forall v1 t . (TensorType t) =>
                 Tensor v1 t -- ^ __data__: The tensor to be made available to the next iteration.
                 -> Tensor Value t -- ^ __output__: The same tensor as `data`.
nextIteration data' | eqLengthGuard [] =
    buildOp (opDef "NextIteration"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be made available to the next iteration."
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  name: "output"
  type_attr: "T"
}
-}

-- | Makes its input available to the next iteration.

refNextIteration :: forall t . (TensorType t) =>
                    Tensor Ref t -- ^ __data__: The tensor to be made available to the next iteration.
                    -> Build (Tensor Ref t) -- ^ __output__: The same tensor as `data`.
refNextIteration data' | eqLengthGuard [] =
    buildOp (opDef "RefNextIteration"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be made available to the next iteration."
  is_ref: true
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  is_ref: true
  name: "output"
  type_attr: "T"
}
-}

-- | Multiplies slices of two tensors in batches.
--
-- Multiplies all slices of `Tensor` `x` and `y` (each slice can be
-- viewed as an element of a batch), and arranges the individual results
-- in a single output tensor of the same batch size. Each of the
-- individual slices can optionally be adjointed (to adjoint a matrix
-- means to transpose and conjugate it) before multiplication by setting
-- the `adj_x` or `adj_y` flag to `True`, which are by default `False`.
-- 
-- The input tensors `x` and `y` are 3-D or higher with shape `[..., r_x, c_x]`
-- and `[..., r_y, c_y]`.
-- 
-- The output tensor is 3-D or higher with shape `[..., r_o, c_o]`, where:
-- 
--     r_o = c_x if adj_x else r_x
--     c_o = r_y if adj_y else c_y
-- 
-- It is computed as:
-- 
--     output[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :])
batchMatMul :: forall v1 v2 t . (TensorType t,
                                 OneOf '[(Data.Complex.Complex Double),
                                         (Data.Complex.Complex Float),
                                         Data.Int.Int32, Data.Word.Word16,
                                         Double, Float] t) =>
               Tensor v1 t -- ^ __x__: 3-D or higher with shape `[..., r_x, c_x]`.
               -> Tensor v2 t -- ^ __y__: 3-D or higher with shape `[..., r_y, c_y]`.
               -> Tensor Value t -- ^ __output__: 3-D or higher with shape `[..., r_o, c_o]`
batchMatMul x y | eqLengthGuard [] =
    buildOp (opDef "BatchMatMul"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If `True`, adjoint the slices of `x`. Defaults to `False`."
  name: "adj_x"
  type: "bool"
}
attr {
  default_value { b: false }
  description: "If `True`, adjoint the slices of `y`. Defaults to `False`."
  name: "adj_y"
  type: "bool"
}
input_arg {
  description: "3-D or higher with shape `[..., r_x, c_x]`."
  name: "x"
  type_attr: "T"
}
input_arg {
  description: "3-D or higher with shape `[..., r_y, c_y]`."
  name: "y"
  type_attr: "T"
}
output_arg {
  description: "3-D or higher with shape `[..., r_o, c_o]`"
  name: "output"
  type_attr: "T"
}
-}

-- | Forwards the `index`th element of `inputs` to `output`.

refSelect :: forall v1 t . (TensorType t) =>
             Tensor v1 Data.Int.Int32 -- ^ __index__: A scalar that determines the input that gets selected.
             -> [Tensor Ref t] -- ^ __inputs__: A list of ref tensors, one of which will be forwarded to `output`.
             -> Build (Tensor Ref t) -- ^ __output__: The forwarded tensor.
refSelect index inputs | eqLengthGuard [("N", [("inputs", length inputs)])] =
    buildOp (opDef "RefSelect"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "N" .~ n)
        index inputs
  where
    n = fromIntegral (length inputs) :: Int64
{-
attr { name: "T" type: "type" }
attr { has_minimum: true minimum: 1 name: "N" type: "int" }
input_arg {
  description: "A scalar that determines the input that gets selected."
  name: "index"
  type: DT_INT32
}
input_arg {
  description: "A list of ref tensors, one of which will be forwarded to `output`."
  is_ref: true
  name: "inputs"
  number_attr: "N"
  type_attr: "T"
}
output_arg {
  description: "The forwarded tensor."
  is_ref: true
  name: "output"
  type_attr: "T"
}
-}

-- | Computes the mean of elements across dimensions of a tensor.
--
-- Reduces `input` along the dimensions given in `reduction_indices`. Unless
-- `keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
-- `reduction_indices`. If `keep_dims` is true, the reduced dimensions are
-- retained with length 1.
mean :: forall v1 v2 t tidx . (TensorType t,
                               OneOf '[(Data.Complex.Complex Double),
                                       (Data.Complex.Complex Float),
                                       Data.Int.Int16, Data.Int.Int32,
                                       Data.Int.Int64, Data.Int.Int8,
                                       Data.Word.Word16, Data.Word.Word8,
                                       Double, Float] t, TensorType tidx,
                               OneOf '[Data.Int.Int32, Data.Int.Int64] tidx) =>
        Tensor v1 t -- ^ __input__: The tensor to reduce.
        -> Tensor v2 tidx -- ^ __reduction_indices__: The dimensions to reduce.
        -> Tensor Value t -- ^ __output__: The reduced tensor.
mean input reduction_indices | eqLengthGuard [] =
    buildOp (opDef "Mean"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tidx" .~ tensorType (undefined :: tidx))
        input reduction_indices
{-
attr {
  default_value { b: false }
  description: "If true, retain reduced dimensions with length 1."
  name: "keep_dims"
  type: "bool"
}
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  default_value { type: DT_INT32 }
  name: "Tidx"
  type: "type"
}
input_arg {
  description: "The tensor to reduce." name: "input" type_attr: "T"
}
input_arg {
  description: "The dimensions to reduce."
  name: "reduction_indices"
  type_attr: "Tidx"
}
output_arg {
  description: "The reduced tensor." name: "output" type_attr: "T"
}
-}

-- | Adds sparse updates to a variable reference.
--
-- This operation computes
-- 
--     # Scalar indices
--     ref[indices, ...] += updates[...]
-- 
--     # Vector indices (for each i)
--     ref[indices[i], ...] += updates[i, ...]
-- 
--     # High rank indices (for each i, ..., j)
--     ref[indices[i, ..., j], ...] += updates[i, ..., j, ...]
-- 
-- This operation outputs `ref` after the update is done.
-- This makes it easier to chain operations that need to use the reset value.
-- 
-- Duplicate entries are handled correctly: if multiple `indices` reference
-- the same location, their contributions add.
-- 
-- Requires `updates.shape = indices.shape + ref.shape[1:]`.
-- 
-- <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
-- <img style="width:100%" src="../../images/ScatterAdd.png" alt>
-- </div>
scatterAdd :: forall v2 v3 t tindices . (TensorType t,
                                         OneOf '[(Data.Complex.Complex Double),
                                                 (Data.Complex.Complex Float),
                                                 Data.Int.Int16, Data.Int.Int32,
                                                 Data.Int.Int64, Data.Int.Int8,
                                                 Data.Word.Word16,
                                                 Data.Word.Word8, Double,
                                                 Float] t, TensorType tindices,
                                         OneOf '[Data.Int.Int32,
                                                 Data.Int.Int64] tindices) =>
              Tensor Ref t -- ^ __ref__: Should be from a `Variable` node.
              -> Tensor v2 tindices -- ^ __indices__: A tensor of indices into the first dimension of `ref`.
              -> Tensor v3 t -- ^ __updates__: A tensor of updated values to add to `ref`.
              -> Build (Tensor Ref t) -- ^ __output_ref__: = Same as `ref`.  Returned as a convenience for operations that want
              -- to use the updated values after the update is done.
scatterAdd ref indices updates | eqLengthGuard [] =
    buildOp (opDef "ScatterAdd"
             & opAttr "T" .~ tensorType (undefined :: t)
             & opAttr "Tindices" .~ tensorType (undefined :: tindices))
        ref indices updates
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "Tindices"
  type: "type"
}
attr {
  default_value { b: false }
  description: "If True, the addition will be protected by a lock;\notherwise the behavior is undefined, but may exhibit less contention."
  name: "use_locking"
  type: "bool"
}
input_arg {
  description: "Should be from a `Variable` node."
  is_ref: true
  name: "ref"
  type_attr: "T"
}
input_arg {
  description: "A tensor of indices into the first dimension of `ref`."
  name: "indices"
  type_attr: "Tindices"
}
input_arg {
  description: "A tensor of updated values to add to `ref`."
  name: "updates"
  type_attr: "T"
}
output_arg {
  description: "= Same as `ref`.  Returned as a convenience for operations that want\nto use the updated values after the update is done."
  is_ref: true
  name: "output_ref"
  type_attr: "T"
}
-}

-- | Randomly crop `image`.
--
-- `size` is a 1-D int64 tensor with 2 elements representing the crop height and
-- width.  The values must be non negative.
-- 
-- This Op picks a random location in `image` and crops a `height` by `width`
-- rectangle from that location.  The random location is picked so the cropped
-- area will fit inside the original image.
randomCrop :: forall v1 v2 t . (TensorType t, OneOf '[Data.Int.Int16,
                                                      Data.Int.Int32,
                                                      Data.Int.Int64,
                                                      Data.Int.Int8,
                                                      Data.Word.Word8, Double,
                                                      Float] t) =>
              Tensor v1 t -- ^ __image__: 3-D of shape `[height, width, channels]`.
              -> Tensor v2 Data.Int.Int64 -- ^ __size__: 1-D of length 2 containing: `crop_height`, `crop_width`..
              -> Build (Tensor Value t) -- ^ __output__: 3-D of shape `[crop_height, crop_width, channels].`
randomCrop image size | eqLengthGuard [] =
    buildOp (opDef "RandomCrop"
             & opAttr "T" .~ tensorType (undefined :: t))
        image size
{-
attr {
  allowed_values {
    list {
      type: DT_UINT8
      type: DT_INT8
      type: DT_INT16
      type: DT_INT32
      type: DT_INT64
      type: DT_FLOAT
      type: DT_DOUBLE
    }
  }
  name: "T"
  type: "type"
}
attr {
  default_value { i: 0 }
  description: "If either seed or seed2 are set to be non-zero, the random number\ngenerator is seeded by the given seed.  Otherwise, it is seeded by a\nrandom seed."
  name: "seed"
  type: "int"
}
attr {
  default_value { i: 0 }
  description: "An second seed to avoid seed collision."
  name: "seed2"
  type: "int"
}
input_arg {
  description: "3-D of shape `[height, width, channels]`."
  name: "image"
  type_attr: "T"
}
input_arg {
  description: "1-D of length 2 containing: `crop_height`, `crop_width`.."
  name: "size"
  type: DT_INT64
}
output_arg {
  description: "3-D of shape `[crop_height, crop_width, channels].`"
  name: "output"
  type_attr: "T"
}
-}

-- | Exits the current frame to its parent frame.
--
-- Exit makes its input `data` available to the parent frame.
refExit :: forall t . (TensorType t) =>
           Tensor Ref t -- ^ __data__: The tensor to be made available to the parent frame.
           -> Build (Tensor Ref t) -- ^ __output__: The same tensor as `data`.
refExit data' | eqLengthGuard [] =
    buildOp (opDef "RefExit"
             & opAttr "T" .~ tensorType (undefined :: t))
        data'
{-
attr { name: "T" type: "type" }
input_arg {
  description: "The tensor to be made available to the parent frame."
  is_ref: true
  name: "data"
  type_attr: "T"
}
output_arg {
  description: "The same tensor as `data`."
  is_ref: true
  name: "output"
  type_attr: "T"
}
-}

-- | Produce a string tensor that encodes the state of a Reader.
--
-- Not all Readers support being serialized, so this can produce an
-- Unimplemented error.
readerSerializeState :: Tensor Ref Data.ByteString.ByteString -- ^ __reader_handle__: Handle to a Reader.
                        -> Build (Tensor Value Data.ByteString.ByteString) -- ^ __state__
readerSerializeState reader_handle | eqLengthGuard [] =
    buildOp (opDef "ReaderSerializeState")
        reader_handle
{-
input_arg {
  description: "Handle to a Reader."
  is_ref: true
  name: "reader_handle"
  type: DT_STRING
}
output_arg { name: "state" type: DT_STRING }
-}

-- | Computes the gradient for the tanh of `x` wrt its input.
--
-- Specifically, `grad = dy * (1 - y*y)`, where `y = tanh(x)`, and `dy`
-- is the corresponding input gradient.
tanhGrad :: forall v1 v2 t . (TensorType t,
                              OneOf '[(Data.Complex.Complex Double),
                                      (Data.Complex.Complex Float),
                                      Data.Word.Word16, Double, Float] t) =>
            Tensor v1 t -- ^ __x__
            -> Tensor v2 t -- ^ __y__
            -> Tensor Value t -- ^ __z__
tanhGrad x y | eqLengthGuard [] =
    buildOp (opDef "TanhGrad"
             & opAttr "T" .~ tensorType (undefined :: t))
        x y
{-
attr {
  allowed_values {
    list {
      type: DT_HALF
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_COMPLEX64
      type: DT_COMPLEX128
    }
  }
  name: "T"
  type: "type"
}
input_arg { name: "x" type_attr: "T" }
input_arg { name: "y" type_attr: "T" }
output_arg { name: "z" type_attr: "T" }
-}

-- | Returns the element-wise max of two SparseTensors.
--
-- Assumes the two SparseTensors have the same shape, i.e., no broadcasting.
sparseSparseMaximum :: forall v1 v2 v3 v4 v5 v6 t . (TensorType t,
                                                     OneOf '[Data.Int.Int16,
                                                             Data.Int.Int32,
                                                             Data.Int.Int64,
                                                             Data.Int.Int8,
                                                             Data.Word.Word16,
                                                             Data.Word.Word8,
                                                             Double,
                                                             Float] t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __a_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                -- SparseTensor, in the canonical lexicographic ordering.
                       -> Tensor v2 t -- ^ __a_values__: 1-D.  `N` non-empty values corresponding to `a_indices`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __a_shape__: 1-D.  Shape of the input SparseTensor.
                       -> Tensor v4 Data.Int.Int64 -- ^ __b_indices__: counterpart to `a_indices` for the other operand.
                       -> Tensor v5 t -- ^ __b_values__: counterpart to `a_values` for the other operand; must be of the same dtype.
                       -> Tensor v6 Data.Int.Int64 -- ^ __b_shape__: counterpart to `a_shape` for the other operand; the two shapes must be equal.
                       -> (Tensor Value Data.Int.Int64, Tensor Value t)
                       -- ^ (__output_indices__, __output_values__)
                       --
                       -- * __output_indices__: 2-D.  The indices of the output SparseTensor.
                       --
                       -- * __output_values__: 1-D.  The values of the output SparseTensor.
sparseSparseMaximum a_indices a_values a_shape b_indices b_values
                    b_shape | eqLengthGuard [] =
    buildOp (opDef "SparseSparseMaximum"
             & opAttr "T" .~ tensorType (undefined :: t))
        a_indices a_values a_shape b_indices b_values b_shape
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT32
      type: DT_INT64
      type: DT_UINT8
      type: DT_INT16
      type: DT_INT8
      type: DT_UINT16
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, in the canonical lexicographic ordering."
  name: "a_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `a_indices`."
  name: "a_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "a_shape"
  type: DT_INT64
}
input_arg {
  description: "counterpart to `a_indices` for the other operand."
  name: "b_indices"
  type: DT_INT64
}
input_arg {
  description: "counterpart to `a_values` for the other operand; must be of the same dtype."
  name: "b_values"
  type_attr: "T"
}
input_arg {
  description: "counterpart to `a_shape` for the other operand; the two shapes must be equal."
  name: "b_shape"
  type: DT_INT64
}
output_arg {
  description: "2-D.  The indices of the output SparseTensor."
  name: "output_indices"
  type: DT_INT64
}
output_arg {
  description: "1-D.  The values of the output SparseTensor."
  name: "output_values"
  type_attr: "T"
}
-}

-- | Decode the first frame of a GIF-encoded image to a uint8 tensor.
--
-- GIF with frame or transparency compression are not supported
-- convert animated GIF from compressed to uncompressed by:
-- 
-- convert $src.gif -coalesce $dst.gif
decodeGif :: Tensor v1 Data.ByteString.ByteString -- ^ __contents__: 0-D.  The GIF-encoded image.
             -> Tensor Value Data.Word.Word8 -- ^ __image__: 4-D with shape `[num_frames, height, width, 3]`. RGB order
decodeGif contents | eqLengthGuard [] =
    buildOp (opDef "DecodeGif")
        contents
{-
input_arg {
  description: "0-D.  The GIF-encoded image."
  name: "contents"
  type: DT_STRING
}
output_arg {
  description: "4-D with shape `[num_frames, height, width, 3]`. RGB order"
  name: "image"
  type: DT_UINT8
}
-}

-- | Return substrings from `Tensor` of strings.
--
-- For each string in the input `Tensor`, creates a substring starting at index
-- `pos` with a total length of `len`.
-- 
-- If `len` defines a substring that would extend beyond the length of the input
-- string, then as many characters as possible are used.
-- 
-- If `pos` is negative or specifies a character index larger than any of the input
-- strings, then an `InvalidArgumentError` is thrown.
-- 
-- `pos` and `len` must have the same shape, otherwise a `ValueError` is thrown on
-- Op creation.
-- 
-- *NOTE*: `Substr` supports broadcasting up to two dimensions. More about
-- broadcasting
-- [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
-- 
-- ---
-- 
-- Examples
-- 
-- Using scalar `pos` and `len`:
-- 
-- ```
-- input = [b'Hello', b'World']
-- position = 1
-- length = 3
-- 
-- output = [b'ell', b'orl']
-- ```
-- 
-- Using `pos` and `len` with same shape as `input`:
-- 
-- ```
-- input = [[b'ten', b'eleven', b'twelve'],
--          [b'thirteen', b'fourteen', b'fifteen'],
--          [b'sixteen', b'seventeen', b'eighteen']]
-- position = [[1, 2, 3],
--             [1, 2, 3],
--             [1, 2, 3]]
-- length =   [[2, 3, 4],
--             [4, 3, 2],
--             [5, 5, 5]]
-- 
-- output = [[b'en', b'eve', b'lve'],
--           [b'hirt', b'urt', b'te'],
--           [b'ixtee', b'vente', b'hteen']]
-- ```
-- 
-- Broadcasting `pos` and `len` onto `input`:
-- 
-- ```
-- input = [[b'ten', b'eleven', b'twelve'],
--          [b'thirteen', b'fourteen', b'fifteen'],
--          [b'sixteen', b'seventeen', b'eighteen'],
--          [b'nineteen', b'twenty', b'twentyone']]
-- position = [1, 2, 3]
-- length =   [1, 2, 3]
-- 
-- output = [[b'e', b'ev', b'lve'],
--           [b'h', b'ur', b'tee'],
--           [b'i', b've', b'hte'],
--           [b'i', b'en', b'nty']]
-- ```
-- 
-- Broadcasting `input` onto `pos` and `len`:
-- 
-- ```
-- input = b'thirteen'
-- position = [1, 5, 7]
-- length =   [3, 2, 1]
-- 
-- output = [b'hir', b'ee', b'n"]
-- ```
substr :: forall v1 v2 v3 t . (TensorType t, OneOf '[Data.Int.Int32,
                                                     Data.Int.Int64] t) =>
          Tensor v1 Data.ByteString.ByteString -- ^ __input__: Tensor of strings
          -> Tensor v2 t -- ^ __pos__: Scalar defining the position of first character in each substring
          -> Tensor v3 t -- ^ __len__: Scalar defining the number of characters to include in each substring
          -> Tensor Value Data.ByteString.ByteString -- ^ __output__: Tensor of substrings
substr input pos len | eqLengthGuard [] =
    buildOp (opDef "Substr"
             & opAttr "T" .~ tensorType (undefined :: t))
        input pos len
{-
attr {
  allowed_values { list { type: DT_INT32 type: DT_INT64 } }
  name: "T"
  type: "type"
}
input_arg {
  description: "Tensor of strings" name: "input" type: DT_STRING
}
input_arg {
  description: "Scalar defining the position of first character in each substring"
  name: "pos"
  type_attr: "T"
}
input_arg {
  description: "Scalar defining the number of characters to include in each substring"
  name: "len"
  type_attr: "T"
}
output_arg {
  description: "Tensor of substrings" name: "output" type: DT_STRING
}
-}

-- | Updates the table to associates keys with values.
--
-- The tensor `keys` must be of the same type as the keys of the table.
-- The tensor `values` must be of the type of the table values.
lookupTableInsert :: forall v2 v3 tin tout . (TensorType tin,
                                              TensorType tout) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to the table.
                     -> Tensor v2 tin -- ^ __keys__: Any shape.  Keys to look up.
                     -> Tensor v3 tout -- ^ __values__: Values to associate with keys.
                     -> Build (ControlNode)
lookupTableInsert table_handle keys values | eqLengthGuard [] =
    buildOp (opDef "LookupTableInsert"
             & opAttr "Tin" .~ tensorType (undefined :: tin)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        table_handle keys values
{-
attr { name: "Tin" type: "type" }
attr { name: "Tout" type: "type" }
input_arg {
  description: "Handle to the table."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
input_arg {
  description: "Any shape.  Keys to look up."
  name: "keys"
  type_attr: "Tin"
}
input_arg {
  description: "Values to associate with keys."
  name: "values"
  type_attr: "Tout"
}
-}

-- | Component-wise divides a SparseTensor by a dense Tensor.
--
-- *Limitation*: this Op only broadcasts the dense side to the sparse side, but not
-- the other direction.
sparseDenseCwiseDiv :: forall v1 v2 v3 v4 t . (TensorType t,
                                               OneOf '[(Data.Complex.Complex Double),
                                                       (Data.Complex.Complex Float),
                                                       Data.Int.Int16,
                                                       Data.Int.Int32,
                                                       Data.Int.Int64,
                                                       Data.Int.Int8,
                                                       Data.Word.Word16,
                                                       Data.Word.Word8, Double,
                                                       Float] t) =>
                       Tensor v1 Data.Int.Int64 -- ^ __sp_indices__: 2-D.  `N x R` matrix with the indices of non-empty values in a
                                                -- SparseTensor, possibly not in canonical ordering.
                       -> Tensor v2 t -- ^ __sp_values__: 1-D.  `N` non-empty values corresponding to `sp_indices`.
                       -> Tensor v3 Data.Int.Int64 -- ^ __sp_shape__: 1-D.  Shape of the input SparseTensor.
                       -> Tensor v4 t -- ^ __dense__: `R`-D.  The dense Tensor operand.
                       -> Tensor Value t -- ^ __output__: 1-D.  The `N` values that are operated on.
sparseDenseCwiseDiv sp_indices sp_values sp_shape dense | eqLengthGuard [] =
    buildOp (opDef "SparseDenseCwiseDiv"
             & opAttr "T" .~ tensorType (undefined :: t))
        sp_indices sp_values sp_shape dense
{-
attr {
  allowed_values {
    list {
      type: DT_FLOAT
      type: DT_DOUBLE
      type: DT_INT64
      type: DT_INT32
      type: DT_UINT8
      type: DT_UINT16
      type: DT_INT16
      type: DT_INT8
      type: DT_COMPLEX64
      type: DT_COMPLEX128
      type: DT_QINT8
      type: DT_QUINT8
      type: DT_QINT32
      type: DT_HALF
    }
  }
  name: "T"
  type: "type"
}
input_arg {
  description: "2-D.  `N x R` matrix with the indices of non-empty values in a\nSparseTensor, possibly not in canonical ordering."
  name: "sp_indices"
  type: DT_INT64
}
input_arg {
  description: "1-D.  `N` non-empty values corresponding to `sp_indices`."
  name: "sp_values"
  type_attr: "T"
}
input_arg {
  description: "1-D.  Shape of the input SparseTensor."
  name: "sp_shape"
  type: DT_INT64
}
input_arg {
  description: "`R`-D.  The dense Tensor operand."
  name: "dense"
  type_attr: "T"
}
output_arg {
  description: "1-D.  The `N` values that are operated on."
  name: "output"
  type_attr: "T"
}
-}

-- | Replaces the contents of the table with the specified keys and values.
--
-- The tensor `keys` must be of the same type as the keys of the table.
-- The tensor `values` must be of the type of the table values.
lookupTableImport :: forall v2 v3 tin tout . (TensorType tin,
                                              TensorType tout) =>
                     Tensor Ref Data.ByteString.ByteString -- ^ __table_handle__: Handle to the table.
                     -> Tensor v2 tin -- ^ __keys__: Any shape.  Keys to look up.
                     -> Tensor v3 tout -- ^ __values__: Values to associate with keys.
                     -> Build (ControlNode)
lookupTableImport table_handle keys values | eqLengthGuard [] =
    buildOp (opDef "LookupTableImport"
             & opAttr "Tin" .~ tensorType (undefined :: tin)
             & opAttr "Tout" .~ tensorType (undefined :: tout))
        table_handle keys values
{-
attr { name: "Tin" type: "type" }
attr { name: "Tout" type: "type" }
input_arg {
  description: "Handle to the table."
  is_ref: true
  name: "table_handle"
  type: DT_STRING
}
input_arg {
  description: "Any shape.  Keys to look up."
  name: "keys"
  type_attr: "Tin"
}
input_arg {
  description: "Values to associate with keys."
  name: "values"
  type_attr: "Tout"
}
-}