     T$dtype: T.tensorFlowDataType)
 }
 
+/// Outputs a tensor containing the reduction across all input tensors.
+///
+/// Outputs a tensor containing the reduction across all input tensors passed to ops
+/// within the same `shared_name.
+///
+/// The graph should be constructed so if one op runs with shared_name value `c`,
+/// then `num_devices` ops will run with shared_name value `c`.  Failure to do so
+/// will cause the graph execution to fail to complete.
+///
+/// input: the input to the reduction
+/// data: the value of the reduction across all `num_devices` devices.
+/// reduction: the reduction operation to perform.
+/// num_devices: The number of devices participating in this reduction.
+/// shared_name: Identifier that shared between ops of the same reduction.
+@inlinable @inline(__always)
+public static func ncclAllReduce<T: Numeric & TensorFlowScalar>(
+  _ input: Tensor<T>,
+  reduction: Reduction,
+  numDevices: Int64,
+  sharedName: String
+) -> Tensor<T> {
+  let ret: TensorHandle<T> = #tfop("NcclAllReduce",
+    input,
+    T$dtype: T.tensorFlowDataType,
+    reduction: reduction.cName,
+    num_devices: numDevices,
+    shared_name: sharedName)
+  return Tensor(handle: ret)
+}
+
+/// Reduces `input` from `num_devices` using `reduction` to a single device.
+///
+/// Reduces `input` from `num_devices` using `reduction` to a single device.
+///
+/// The graph should be constructed so that all inputs have a valid device
+/// assignment, and the op itself is assigned one of these devices.
+///
+/// input: The input to the reduction.
+/// data: the value of the reduction across all `num_devices` devices.
+/// reduction: the reduction operation to perform.
+@inlinable @inline(__always)
+public static func ncclReduce<T: Numeric & TensorFlowScalar>(
+  _ input: [Tensor<T>],
+  reduction: Reduction
+) -> Tensor<T> {
+  let ret: TensorHandle<T> = #tfop("NcclReduce",
+    input,
+    T$dtype: T.tensorFlowDataType,
+    reduction: reduction.cName)
+  return Tensor(handle: ret)
+}
+
+/// Selects the k nearest centers for each point.
+///
+/// Rows of points are assumed to be input points. Rows of centers are assumed to be
+/// the list of candidate centers. For each point, the k centers that have least L2
+/// distance to it are computed.
+///
+/// - Parameters:
+///   - points: Matrix of shape (n, d). Rows are assumed to be input points.
+///   - centers: Matrix of shape (m, d). Rows are assumed to be centers.
+///   - k: Number of nearest centers to return for each point. If k is larger than m, then
+///     only m centers are returned.
+///
+/// - Outputs:
+///   - nearest_center_indices: Matrix of shape (n, min(m, k)). Each row contains the indices of the centers
+///     closest to the corresponding point, ordered by increasing distance.
+///   - nearest_center_distances: Matrix of shape (n, min(m, k)). Each row contains the squared L2 distance to the
+///     corresponding center in nearest_center_indices.
+@inlinable @inline(__always)
+public static func nearestNeighbors(
+  points: Tensor<Float>,
+  centers: Tensor<Float>,
+  k: Tensor<Int64>
+) -> (nearestCenterIndices: Tensor<Int64>, nearestCenterDistances: Tensor<Float>) {
+  let ret: (TensorHandle<Int64>, TensorHandle<Float>) = #tfop("NearestNeighbors",
+    points,
+    centers,
+    k)
+  return (Tensor(handle: ret.0), Tensor(handle: ret.1))
+}
+
 /// Computes numerical negative value element-wise.
 ///
 /// I.e., \\(y = -x\\).

public static func refOutputFloatOutput(
) -> (a: Tensor<Float>, b: Tensor<Float>) {
  let ret: (TensorHandle<Float>, TensorHandle<Float>) = #tfop("RefOutputFloatOutput")
  return (Tensor(handle: ret.0), Tensor(handle: ret.1))
}

/// Forwards the `index`th element of `inputs` to `output`.
///
/// - Parameters:
///   - index: A scalar that determines the input that gets selected.
///   - inputs: A list of ref tensors, one of which will be forwarded to `output`.
///
/// - Output output: The forwarded tensor.
@inlinable @inline(__always)
public static func refSelect<T: TensorFlowScalar>(
  index: Tensor<Int32>,
  inputs: [Tensor<T>]
) -> Tensor<T> {
  let ret: TensorHandle<T> = #tfop("RefSelect",
    index,
    inputs,
    T$dtype: T.tensorFlowDataType)
  return Tensor(handle: ret)
}

/// 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`.
///
/// - Parameters:
///   - data: The ref tensor to be forwarded to the appropriate output.
///   - pred: A scalar that specifies which output port will receive data.
///
/// - Outputs:
///   - 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.
@inlinable @inline(__always)
public static func refSwitch<T: TensorFlowScalar>(
  data: Tensor<T>,
  pred: Tensor<Bool>
) -> (outputFalse: Tensor<T>, outputTrue: Tensor<T>) {
  let ret: (TensorHandle<T>, TensorHandle<T>) = #tfop("RefSwitch",
    data,
    pred,
    T$dtype: T.tensorFlowDataType)
  return (Tensor(handle: ret.0), Tensor(handle: ret.1))
}


    strides: strides,
    use_cudnn_on_gpu: useCudnnOnGpu,
    padding: padding.cName,
    explicit_paddings: explicitPaddings,
    data_format: dataFormat.cName,
    dilations: dilations)
  return Tensor(handle: ret)
