code: def call_for_each_tower(
              towers, func, devices=None, use_vs=None):
          
  
          ret = []
          if devices is not None:
              assert len(devices) == len(towers)
          if use_vs is not None:
              assert len(use_vs) == len(towers)
  
          tower_names = ['tower{}'.format(idx) for idx in range(len(towers))]
  
          for idx, t in enumerate(towers):
              device = devices[idx] if devices is not None else '/gpu:{}'.format(t)
              usevs = use_vs[idx] if use_vs is not None else False
              reuse = not usevs and idx > 0
              with tfv1.device(device), _maybe_reuse_vs(reuse), TrainTowerContext(
                      tower_names[idx],
                      vs_name=tower_names[idx] if usevs else '',
                      index=idx, total=len(towers)):
                  if len(str(device)) < 10:   # a device function doesn't have good string description
                      logger.info("Building graph for training tower {} on device {} ...".format(idx, device))
                  else:
                      logger.info("Building graph for training tower {} ...".format(idx))
  
                  # When use_vs is True, use LOCAL_VARIABLES,
                  # so these duplicated variables won't be saved by default.
                  with override_to_local_variable(enable=usevs):
                      ret.append(func())
          return ret
docs: Run `func` on all GPUs (towers) and return the results.
  
          Args:
              towers (list[int]): a list of GPU id.
              func: a lambda to be called inside each tower
              devices: a list of devices to be used. By default will use '/gpu:{tower}'
              use_vs (list[bool]): list of use_vs to passed to TowerContext
  
          Returns:
              List of outputs of ``func``, evaluated on each tower.