docstr: Args:
      grad_list: list of list of tuples, shape is Ngpu x Nvar x 2
docstr_tok: ["Args",":","grad_list",":","list","of","list","of","tuples",",","shape","is","Ngpu","x","Nvar","x","2"]
code: def _check_grad_list(grad_list):
      """
      Args:
          grad_list: list of list of tuples, shape is Ngpu x Nvar x 2
      """
      nvars = [len(k) for k in grad_list]
  
      def basename(x):
          return re.sub("tower[0-9]+/", "", x.op.name)
  
      if len(set(nvars)) != 1:
          names_per_gpu = [
              {basename(k[1]) for k in grad_and_vars}
              for grad_and_vars in grad_list
          ]
          inters = copy.copy(names_per_gpu[0])
          for s in names_per_gpu:
              inters &= s
          for s in names_per_gpu:
              s -= inters
          logger.error(
              "Unique trainable variables on towers: "
              + pprint.pformat(names_per_gpu)
          )
          raise ValueError(
              "Number of gradients from each tower is different! "
              + str(nvars)
          )
  
imports: import copy
  import pprint
  import re
  from abc import ABCMeta, abstractmethod
  from contextlib import contextmanager
  import six
  import tensorflow
  from ..compat import tfv1
  from ..tfutils.common import get_tf_version_tuple
  from ..tfutils.gradproc import ScaleGradient
  from ..tfutils.tower import TrainTowerContext
  from ..utils import logger
  from ..utils.develop import HIDE_DOC
  from .utils import GradientPacker, LeastLoadedDeviceSetter, aggregate_grads_colocate, allreduce_grads_naive, allreduce_grads, allreduce_grads_hierarchical, merge_grad_list, override_to_local_variable, split_grad_list
label_desc: Use image node_id 2 for calling the DataParallelBuilder obj's underlying member method code with example usage: obj._check_grad_list(grad_list) and returns: re