code: def clip_eta(eta, ord, eps):
      """
      Helper function to clip the perturbation to epsilon norm ball.
      :param eta: A tensor with the current perturbation.
      :param ord: Order of the norm (mimics Numpy).
                  Possible values: np.inf, 1 or 2.
      :param eps: Epsilon, bound of the perturbation.
      """
  
      # Clipping perturbation eta to self.ord norm ball
      if ord not in [np.inf, 1, 2]:
          raise ValueError("ord must be np.inf, 1, or 2.")
      reduc_ind = list(xrange(1, len(eta.get_shape())))
      avoid_zero_div = 1e-12
      if ord == np.inf:
          eta = clip_by_value(eta, -eps, eps)
      elif ord == 1:
          # Implements a projection algorithm onto the l1-ball from
          # (Duchi et al. 2008) that runs in time O(d*log(d)) where d is the
          # input dimension.
          # Paper link (Duchi et al. 2008): https://dl.acm.org/citation.cfm?id=1390191
  
          eps = tf.cast(eps, eta.dtype)
  
          dim = tf.reduce_prod(tf.shape(eta)[1:])
          eta_flat = tf.reshape(eta, (-1, dim))
          abs_eta = tf.abs(eta_flat)
  
          if "sort" in dir(tf):
              mu = -tf.sort(-abs_eta, axis=-1)
          else:
              # `tf.sort` is only available in TF 1.13 onwards
              mu = tf.nn.top_k(abs_eta, k=dim, sorted=True)[0]
          cumsums = tf.cumsum(mu, axis=-1)
          js = tf.cast(tf.divide(1, tf.range(1, dim + 1)), eta.dtype)
          t = tf.cast(
              tf.greater(mu - js * (cumsums - eps), 0), eta.dtype
          )
  
          rho = tf.argmax(t * cumsums, axis=-1)
          rho_val = tf.reduce_max(t * cumsums, axis=-1)
          theta = tf.divide(rho_val - eps, tf.cast(1 + rho, eta.dtype))
  
          eta_sgn = tf.sign(eta_flat)
          eta_proj = eta_sgn * tf.maximum(
              abs_eta - theta[:, tf.newaxis], 0
          )
          eta_proj = tf.reshape(eta_proj, tf.shape(eta))
  
          norm = tf.reduce_sum(tf.abs(eta), reduc_ind)
          eta = tf.where(tf.greater(norm, eps), eta_proj, eta)
  
      elif ord == 2:
          # avoid_zero_div must go inside sqrt to avoid a divide by zero
          # in the gradient through this operation
          norm = tf.sqrt(
              tf.maximum(
                  avoid_zero_div,
                  reduce_sum(tf.square(eta), reduc_ind, keepdims=True),
              )
          )
          # We must *clip* to within the norm ball, not *normalize* onto the
          # surface of the ball
          factor = tf.minimum(1.0, div(eps, norm))
          eta = eta * factor
      return eta
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals
  import logging
  import math
  import os
  import time
  import warnings
  import numpy
  import six
  from six.moves import xrange
  import tensorflow
  from cleverhans.compat import device_lib
  from cleverhans.compat import reduce_sum, reduce_mean
  from cleverhans.compat import reduce_max
  from cleverhans.compat import softmax_cross_entropy_with_logits
  from cleverhans.utils import batch_indices, _ArgsWrapper, create_logger
label_desc: Use image node_id 10 for calling a global function with example usage: clip_eta(eta, ord, eps) and returns: eta