     }
 }
 
-
-/// TensorFlow builtin conv2d gradient helper for the input.
-@differentiable(wrt: (x, filter), vjp: _vjpConv2DBackpropInput)
-@usableFromInline
-func conv2DBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    shape: Tensor<Int32>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding,
-    dilations: (Int, Int, Int, Int) = (1, 1, 1, 1)
-) -> Tensor<Scalar> {
-    return Raw.conv2DBackpropInput(
-        inputSizes: shape,
-        filter: filter,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3)],
-        padding: padding.raw2,
-        explicitPaddings: [],
-        dilations: [Int32(dilations.0), Int32(dilations.1), Int32(dilations.2), Int32(dilations.3)])
-}
-
-/// TensorFlow builtin conv2d gradient helper for the filter.
-@differentiable(wrt: (x, input), vjp: _vjpConv2DBackpropFilter)
-@usableFromInline
-func conv2DBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    input: Tensor<Scalar>,
-    filterSizes: Tensor<Int32>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding,
-    dilations: (Int, Int, Int, Int)
-) -> Tensor<Scalar> {
-    return Raw.conv2DBackpropFilter(
-        input,
-        filterSizes: filterSizes,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3)],
-        padding: padding.raw2,
-        explicitPaddings: [],
-        dilations: [Int32(dilations.0), Int32(dilations.1), Int32(dilations.2), Int32(dilations.3)])
-}
-
-@usableFromInline
-func _vjpConv2DBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ shape: Tensor<Int32>,
-    _ filter: Tensor<Scalar>,
-    _ strides: (Int, Int, Int, Int),
-    _ padding: Padding,
-    _ dilations: (Int, Int, Int, Int)
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv2DBackpropInput(x, shape: shape, filter: filter,
-                                    strides: strides, padding: padding, dilations: dilations)
-    return (value, { v in
-        (conv2DBackpropFilter(x, input: v, filterSizes: shape, strides: strides,
-                              padding: padding, dilations: dilations),
-         conv2D(v, filter: filter, strides: strides, padding: padding, dilations: dilations))
-    })
-}
-
-@usableFromInline
-func _vjpConv2DBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ input: Tensor<Scalar>,
-    _ filterSizes: Tensor<Int32>,
-    _ strides: (Int, Int, Int, Int),
-    _ padding: Padding,
-    _ dilations: (Int, Int, Int, Int)
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv2DBackpropFilter(x, input: input, filterSizes: filterSizes,
-                                     strides: strides, padding: padding, dilations: dilations)
-    return (value, { v in
-        (conv2DBackpropInput(x, shape: filterSizes, filter: v, strides: strides,
-                             padding: padding, dilations: dilations),
-         conv2D(input, filter: v, strides: strides, padding: padding, dilations: dilations))
-    })
-}
-
-@usableFromInline
-func _vjpConv2D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding,
-    dilations: (Int, Int, Int, Int)
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv2D(x, filter: filter, strides: strides, padding: padding, dilations: dilations)
-    return (value, { v in
-        (conv2DBackpropInput(v, shape: x.shapeTensor, filter: filter,
-                             strides: strides, padding: padding, dilations: dilations),
-         conv2DBackpropFilter(v, input: x, filterSizes: filter.shapeTensor,
-                              strides: strides, padding: padding, dilations: dilations))
-    })
-}
-
-/// TensorFlow builtin conv3d gradient helper for the input.
-@differentiable(wrt: (x, filter), vjp: _vjpConv3DBackpropInput)
-@usableFromInline
-func conv3DBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    shape: Tensor<Int32>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int, Int),
-    padding: Padding
-) -> Tensor<Scalar> {
-    return Raw.conv3DBackpropInputV2(
-        inputSizes: shape,
-        filter: filter,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2),
-                  Int32(strides.3), Int32(strides.4)],
-        padding: padding.raw)
-}
-
-/// TensorFlow builtin conv3d gradient helper for the filter.
-@differentiable(wrt: (x, input), vjp: _vjpConv3DBackpropFilter)
-@usableFromInline
-func conv3DBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    input: Tensor<Scalar>,
-    filterSizes: Tensor<Int32>,
-    strides: (Int, Int, Int, Int, Int),
-    padding: Padding
-) -> Tensor<Scalar> {
-    return Raw.conv3DBackpropFilterV2(
-        x,
-        filterSizes: filterSizes,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2),
-                  Int32(strides.3), Int32(strides.4)],
-        padding: padding.raw)
-}
-
-@usableFromInline
-func _vjpConv3DBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ shape: Tensor<Int32>,
-    _ filter: Tensor<Scalar>,
-    _ strides: (Int, Int, Int, Int, Int),
-    _ padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv3DBackpropInput(x, shape: shape, filter: filter, strides: strides,
-                                    padding: padding)
-    return (value, { v in
-        return (
-            conv3DBackpropFilter(x, input: v, filterSizes: shape, strides: strides,
-                                 padding: padding),
-            conv3D(v, filter: filter, strides: strides, padding: padding)
-        )
-    })
-}
-
-@usableFromInline
-func _vjpConv3DBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ input: Tensor<Scalar>,
-    _ filterSizes: Tensor<Int32>,
-    _ strides: (Int, Int, Int, Int, Int),
-    _ padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv3DBackpropFilter(x, input: input, filterSizes: filterSizes,
-                                     strides: strides, padding: padding)
-    return (value, { v in
-        return (
-            conv3DBackpropInput(x, shape: filterSizes, filter: v, strides: strides,
-                                  padding: padding),
-            conv3D(input, filter: v, strides: strides, padding: padding)
-        )
-    })
-}
-
-@usableFromInline
-func _vjpConv3D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = conv3D(x, filter: filter, strides: strides,
-                       padding: padding)
-    return (value, { v in
-        return (
-            conv3DBackpropInput(v, shape: x.shapeTensor, filter: filter,
-                                strides: strides, padding: padding),
-            conv3DBackpropFilter(v, input: x, filterSizes: filter.shapeTensor,
-                                 strides: strides, padding: padding)
-        )
-    })
-}
-
-/// TensorFlow builtin depthwiseConv2D gradient helper for the input.
-@differentiable(wrt: (x, filter), vjp: _vjpdepthwiseConv2dBackpropInput)
-@usableFromInline
-func depthwiseConv2dBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    shape: Tensor<Int32>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding
-) -> Tensor<Scalar> {
-    return Raw.depthwiseConv2dNativeBackpropInput(
-        inputSizes: shape,
-        filter: filter,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3)],
-        padding: padding.raw)
-}
-
-/// TensorFlow builtin depthwiseConv2D gradient helper for the filter.
-@differentiable(wrt: (x, input), vjp: _vjpdepthwiseConv2dBackpropFilter)
-@usableFromInline
-func depthwiseConv2dBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    input: Tensor<Scalar>,
-    filterSizes: Tensor<Int32>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding
-) -> Tensor<Scalar> {
-    return Raw.depthwiseConv2dNativeBackpropFilter(
-        x,
-        filterSizes: filterSizes,
-        outBackprop: x,
-        strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3)],
-        padding: padding.raw)
-}
-
-@usableFromInline
-func _vjpdepthwiseConv2dBackpropInput<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ shape: Tensor<Int32>,
-    _ filter: Tensor<Scalar>,
-    _ strides: (Int, Int, Int, Int),
-    _ padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = depthwiseConv2dBackpropInput(x, shape: shape, filter: filter, strides: strides,
-                                             padding: padding)
-    return (value, { v in
-        return (
-            depthwiseConv2dBackpropFilter(x, input: v, filterSizes: shape, strides: strides,
-                                          padding: padding),
-            depthwiseConv2D(v, filter: filter, strides: strides, padding: padding)
-        )
-    })
-}
-
-@usableFromInline
-func _vjpdepthwiseConv2dBackpropFilter<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    _ input: Tensor<Scalar>,
-    _ filterSizes: Tensor<Int32>,
-    _ strides: (Int, Int, Int, Int),
-    _ padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = depthwiseConv2dBackpropFilter(x, input: input, filterSizes: filterSizes,
-                                              strides: strides, padding: padding)
-    return (value, { v in
-        return (
-            depthwiseConv2dBackpropInput(x, shape: filterSizes, filter: v, strides: strides,
-                                         padding: padding),
-            depthwiseConv2D(input, filter: v, strides: strides, padding: padding)
-        )
-    })
-}
-
-@usableFromInline
-func _vjpDepthwiseConv2D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filter: Tensor<Scalar>,
-    strides: (Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> (Tensor<Scalar>, Tensor<Scalar>)) {
-    let value = depthwiseConv2D(x, filter: filter, strides: strides,
-                                padding: padding)
-    return (value, { v in
-        return (
-            depthwiseConv2dBackpropInput(v, shape: x.shapeTensor, filter: filter,
-                                         strides: strides, padding: padding
-            ),
-            depthwiseConv2dBackpropFilter(v, input: x, filterSizes: filter.shapeTensor,
-                                          strides: strides, padding: padding
-            )
-        )
-    })
-}
-
-@usableFromInline
-func _vjpMaxPool2D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filterSize: (Int, Int, Int, Int),
-    strides: (Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> Tensor<Scalar>) {
-    // TODO: Currently this is not higher order differentiable. Redefine in
-    // closed form.
-    let value = maxPool2D(x, filterSize: filterSize, strides: strides, padding: padding)
-    return (value, { v in
-        Raw.maxPoolGradV2(
-            origInput: x,
-            origOutput: value,
-            grad: v,
-            ksize: Tensor<Int32>([Int32(filterSize.0), Int32(filterSize.1),
-                                  Int32(filterSize.2), Int32(filterSize.3)]),
-            strides: Tensor<Int32>([Int32(strides.0), Int32(strides.1),
-                                    Int32(strides.2), Int32(strides.3)]),
-            padding: padding.raw)
-    })
-}
-
-@usableFromInline
-func _vjpMaxPool3D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filterSize: (Int, Int, Int, Int, Int),
-    strides: (Int, Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> Tensor<Scalar>) {
-    // TODO: Currently this is not higher order differentiable. Redefine in
-    // closed form.
-    let value = maxPool3D(x, filterSize: filterSize, strides: strides, padding: padding)
-    return (value, { v in
-        return Raw.maxPool3DGrad(
-            origInput: x,
-            origOutput: value,
-            grad: v,
-            ksize: [Int32(filterSize.0), Int32(filterSize.1), Int32(filterSize.2),
-                    Int32(filterSize.3), Int32(filterSize.4)],
-            strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3),
-                      Int32(strides.4)],
-            padding: padding.raw
-        )
-    })
-}
-
-@usableFromInline
-func _vjpAvgPool2D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filterSize: (Int, Int, Int, Int),
-    strides: (Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> Tensor<Scalar>) {
-    // TODO: Currently this is not higher order differentiable. Redefine in
-    // closed form.
-    let value = avgPool2D(x, filterSize: filterSize, strides: strides, padding: padding)
-    return (value, { v in
-        Raw.avgPoolGrad(
-            origInputShape: x.shapeTensor,
-            grad: v,
-            ksize: [Int32(filterSize.0), Int32(filterSize.1),
-                    Int32(filterSize.2), Int32(filterSize.3)],
-            strides: [Int32(strides.0), Int32(strides.1),
-                      Int32(strides.2), Int32(strides.3)],
-            padding: padding.raw
-        )
-    })
-}
-
-@usableFromInline
-func _vjpAvgPool3D<Scalar: TensorFlowFloatingPoint>(
-    _ x: Tensor<Scalar>,
-    filterSize: (Int, Int, Int, Int, Int),
-    strides: (Int, Int, Int, Int, Int),
-    padding: Padding
-) -> (Tensor<Scalar>, (Tensor<Scalar>) -> Tensor<Scalar>) {
-    // TODO: Currently this is not higher order differentiable. Redefine in
-    // closed form.
-    let value = avgPool3D(x, filterSize: filterSize, strides: strides, padding: padding)
-    return (value, { v in
-        return Raw.avgPool3DGrad(
-            origInputShape: x.shapeTensor,
-            grad: v,
-            ksize: [Int32(filterSize.0), Int32(filterSize.1), Int32(filterSize.2),
-                    Int32(filterSize.3), Int32(filterSize.4)],
-            strides: [Int32(strides.0), Int32(strides.1), Int32(strides.2), Int32(strides.3),
-                      Int32(strides.4)],
-            padding: padding.raw
-        )
-    })
-}
-
 /// Returns a 2-D convolution with the specified input, filter, strides, and padding.
 ///
 /// - Parameters:

        padding: padding.raw)
}

/// Returns a 2-D depthwise convolution with the specified input, filter, strides, and padding.
///
/// - Parameters:

        padding: padding.raw)
}

@usableFromInline
func _vjpMaxPool2D<Scalar: TensorFlowFloatingPoint>(
    _ x: Tensor<Scalar>,
    filterSize: (Int, Int, Int, Int),
    strides: (Int, Int, Int, Int),
    padding: Padding
) -> (Tensor<Scalar>, (Tensor<Scalar>) -> Tensor<Scalar>) {
    // TODO: Currently this is not higher order differentiable. Redefine in
    // closed form.
    let value = maxPool2D(x, filterSize: filterSize, strides: strides, padding: padding)
    return (value, { v in
        Raw.maxPoolGradV2(
            origInput: x,
            origOutput: value,
            grad: v,
            ksize: Tensor<Int32>([Int32(filterSize.0), Int32(filterSize.1),
                                  Int32(filterSize.2), Int32(filterSize.3)]),
            strides: Tensor<Int32>([Int32(strides.0), Int32(strides.1),
                                    Int32(strides.2), Int32(strides.3)]),
            padding: padding.raw)
    })
}

/// Returns a 3-D max pooling, with the specified filter sizes, strides, and
/// padding.
///
