code: def _py_func_with_gradient(
      func, inp, Tout, stateful=True, name=None, grad_func=None
  ):
      """
      PyFunc defined as given by Tensorflow
      :param func: Custom Function
      :param inp: Function Inputs
      :param Tout: Ouput Type of out Custom Function
      :param stateful: Calculate Gradients when stateful is True
      :param name: Name of the PyFunction
      :param grad: Custom Gradient Function
      :return:
      """
      # Generate random name in order to avoid conflicts with inbuilt names
      rnd_name = "PyFuncGrad-" + "%0x" % getrandbits(30 * 4)
  
      # Register Tensorflow Gradient
      tf.RegisterGradient(rnd_name)(grad_func)
  
      # Get current graph
      g = tf.get_default_graph()
  
      # Add gradient override map
      with g.gradient_override_map(
          {"PyFunc": rnd_name, "PyFuncStateless": rnd_name}
      ):
          return tf.py_func(
              func, inp, Tout, stateful=stateful, name=name
          )
  
file_path: cleverhans/cleverhans_v3.1.0/cleverhans/utils_pytorch.py
imports: import warnings
  from random import getrandbits
  import numpy
  import tensorflow
  import torch
  from torch.autograd import Variable
label_desc: Use image node_id 1 for calling a global function with example usage: _py_func_with_gradient(func, inp, Tout, stateful, name, grad_func) and returns: tf