class_docstr: LocalGradientAggregationHelper aggregates gradient updates locally,
  and communicates the updates across machines only once every
  backward_passes_per_step. Only supports graph mode execution.
class_docstr_tok: ["LocalGradientAggregationHelper","aggregates","gradient","updates","locally",",","and","communicates","the","updates","across","machines","only","once","every","backward_passes_per_step",".","Only","supports","graph","mode","execution","."]
docstr: Applies the new gradient updates the locally aggregated gradients, and
  performs cross-machine communication every backward_passes_per_step
  times it is called.
docstr_tok: ["Applies","the","new","gradient","updates","the","locally","aggregated","gradients",",","and","performs","cross-machine","communication","every","backward_passes_per_step","times","it","is","called","."]
code: def compute_gradients(self, grads, vars):
      """
      Applies the new gradient updates the locally aggregated gradients, and
      performs cross-machine communication every backward_passes_per_step
      times it is called.
      """
      self._init_aggregation_vars(grads)
  
      # Clear the locally aggregated gradients when the counter is at zero.
      clear_op = tf.cond(
          pred=tf.equal(self.counter, 0),
          true_fn=lambda: self._clear_grads(),
          false_fn=tf.no_op,
      )
  
      # Add new gradients to the locally aggregated gradients.
      with tf.control_dependencies([clear_op]):
          aggregation_ops_list = self._aggregate_grads(grads)
  
      # Increment the counter once new gradients have been applied.
      aggregation_ops = tf.group(*aggregation_ops_list)
      with tf.control_dependencies([aggregation_ops]):
          update_counter = self.counter.assign_add(tf.constant(1))
  
      with tf.control_dependencies([update_counter]):
          grads = get_not_none_from_list(grads)
          assert len(grads) == len(self.locally_aggregated_grads)
  
          # Allreduce locally aggregated gradients when the counter is equivalent to
          # `backward_passes_per_step`. This the condition is true, it also resets
          # the counter back to 0.
          allreduced_grads = tf.cond(
              tf.equal(self.counter, self.backward_passes_per_step),
              lambda: self._allreduce_grads_helper(vars),
              lambda: [self._maybe_convert_grad(g) for g in grads],
          )
  
          # Handle case where there is only one variable.
          if not isinstance(allreduced_grads, (list, tuple)):
              allreduced_grads = (allreduced_grads,)
          assert len(allreduced_grads) == len(
              self.locally_aggregated_grads
          )
  
          # Insert gradients that are None back in.
          allreduced_grads = [
              allreduced_grads[self.not_none_indexes[idx]]
              if idx in self.not_none_indexes
              else None
              for idx in range(
                  len(self.locally_aggregated_grads)
                  + self.num_none_grad_updates
              )
          ]
          assert (
              len(allreduced_grads)
              == len(self.locally_aggregated_grads)
              + self.num_none_grad_updates
          )
  
      # If gradients have not been allreduced this batch, we return the gradients
      # that were submitted as the updates (the input).
      return allreduced_grads
  
file_path: horovod/horovod/tensorflow/gradient_aggregation.py
imports: import os
  import tensorflow
  from packaging import version
  from horovod.tensorflow.mpi_ops import size_op
  from horovod.tensorflow.mpi_ops import global_process_set
label_desc: Use image node_id 8 for calling the LocalGradientAggregationHelper obj's underlying member method code with example usage: obj.compute_gradients(grads, vars) and returns: allreduced_grads