code: def get_tower_results(iterator, optimizer, dropout_rates):
      r"""
      With this preliminary step out of the way, we can for each GPU introduce a
      tower for which's batch we calculate and return the optimization gradients
      and the average loss across towers.
      """
      # To calculate the mean of the losses
      tower_avg_losses = []
  
      # Tower gradients to return
      tower_gradients = []
  
      # Aggregate any non finite files in the batches
      tower_non_finite_files = []
  
      with tfv1.variable_scope(tfv1.get_variable_scope()):
          # Loop over available_devices
          for i in range(len(Config.available_devices)):
              # Execute operations of tower i on device i
              device = Config.available_devices[i]
              with tf.device(device):
                  # Create a scope for all operations of tower i
                  with tf.name_scope("tower_%d" % i):
                      # Calculate the avg_loss and mean_edit_distance and retrieve the decoded
                      # batch along with the original batch's labels (Y) of this tower
                      (
                          avg_loss,
                          non_finite_files,
                      ) = calculate_mean_edit_distance_and_loss(
                          iterator, dropout_rates, reuse=i > 0
                      )
  
                      # Allow for variables to be re-used by the next tower
                      tfv1.get_variable_scope().reuse_variables()
  
                      # Retain tower's avg losses
                      tower_avg_losses.append(avg_loss)
  
                      # Compute gradients for model parameters using tower's mini-batch
                      gradients = optimizer.compute_gradients(avg_loss)
  
                      # Retain tower's gradients
                      tower_gradients.append(gradients)
  
                      tower_non_finite_files.append(non_finite_files)
  
      avg_loss_across_towers = tf.reduce_mean(
          input_tensor=tower_avg_losses, axis=0
      )
      tfv1.summary.scalar(
          name="step_loss",
          tensor=avg_loss_across_towers,
          collections=["step_summaries"],
      )
  
      all_non_finite_files = tf.concat(tower_non_finite_files, axis=0)
  
      # Return gradients and the average loss
      return (
          tower_gradients,
          avg_loss_across_towers,
          all_non_finite_files,
      )
  
imports: from __future__ import absolute_import, division, print_function
  import os
  import sys
  import absl.app
  import numpy
  import progressbar
  import shutil
  import tensorflow
  import tensorflow.compat.v1
  import time
  from datetime import datetime
  from ds_ctcdecoder import ctc_beam_search_decoder, Scorer
  from .evaluate import evaluate
  from six.moves import zip, range
  from .util.config import Config, initialize_globals
  from .util.checkpoints import load_or_init_graph_for_training, load_graph_for_evaluation, reload_best_checkpoint
  from .util.evaluate_tools import save_samples_json
  from .util.feeding import create_dataset, audio_to_features, audiofile_to_features
  from .util.flags import create_flags, FLAGS
  from .util.helpers import check_ctcdecoder_version, ExceptionBox
  from .util.logging import create_progressbar, log_debug, log_error, log_info, log_progress, log_warn
  from .util.io import open_remote, remove_remote, listdir_remote, is_remote_path, isdir_remote
label_desc: Use image node_id 10 for calling a global function with example usage: get_tower_results(iterator, optimizer, dropout_rates) and returns: tower_gradients,  avg_loss_across_towers,  all_non_finite_files