code: def _get_compatible_gpus_v02(
      micro_batches,
      max_acceptable_batch_size,
      current_num_gpus,
      min_gpus=None,
      max_gpus=None,
      prefer_larger=True,
      num_gpus_per_node=1,
      model_parallel_size=1,
  ):
      """
      Returns:
          final_batch_size
          valid_gpus
          micro-batch size
      """
      if num_gpus_per_node % model_parallel_size != 0:
          raise ElasticityError(
              f"In Elasticity v0.2, number of GPUs per node:"
              f"{num_gpus_per_node} should be divisible by "
              f"model parallel size {model_parallel_size}"
          )
  
      def get_microbatch(final_batch_size):
          candidate_microbatch = None
  
          for micro_batch in micro_batches:
              if (
                  final_batch_size // current_num_gpus % micro_batch
                  == 0
              ):
                  if candidate_microbatch is None:
                      candidate_microbatch = micro_batch
                  if (
                      prefer_larger
                      and candidate_microbatch < micro_batch
                  ):
                      candidate_microbatch = micro_batch
          return candidate_microbatch
  
      dp_size_per_node = num_gpus_per_node // model_parallel_size
  
      final_batch_size, valid_world_size = _get_compatible_gpus_v01(
          micro_batches,
          int(max_acceptable_batch_size / dp_size_per_node),
          int(min_gpus / num_gpus_per_node),
          int(
              max_gpus / num_gpus_per_node
          ),  # Passing number of max nodes as Elasticity v2 works at node level
          prefer_larger=prefer_larger,
      )
  
      final_batch_size = int(final_batch_size) * dp_size_per_node
      valid_dp_world_size = [
          i * dp_size_per_node for i in valid_world_size
      ]
      if current_num_gpus // model_parallel_size in valid_dp_world_size:
          candidate_microbatch = get_microbatch(final_batch_size)
          return (
              final_batch_size,
              valid_dp_world_size,
              candidate_microbatch,
          )
  
      current_dp_size = (
          current_num_gpus / num_gpus_per_node
      ) * dp_size_per_node
      candidate_batch_sizes = []
      for micro_batch in micro_batches:
          min_batch_size = micro_batch * current_dp_size
  
          factor = math.floor(
              max_acceptable_batch_size / float(min_batch_size)
          )
          candidate_batch_sizes.append(factor * min_batch_size)
  
      used_microbatch = None
      if prefer_larger:
          candidate_batch_size = max(candidate_batch_sizes)
      else:
          candidate_batch_size = min(candidate_batch_sizes)
  
      candidate_microbatch = get_microbatch(candidate_batch_size)
  
      return (
          candidate_batch_size,
          [int(current_dp_size)],
          candidate_microbatch,
      )
  
file_path: DeepSpeed/deepspeed/elasticity/elasticity.py
imports: import os
  import json
  import numpy
  import math
  from packaging import version
  from .config import ElasticityConfig, ElasticityConfigError, ElasticityError, ElasticityIncompatibleWorldSize
  from .constants import ELASTICITY, ENABLED, ENABLED_DEFAULT, LATEST_ELASTICITY_VERSION, MINIMUM_DEEPSPEED_VERSION, DEEPSPEED_ELASTICITY_CONFIG
  from ..git_version_info import version
  from ..utils import logger
label_desc: Use image node_id 5 for calling a global function with example usage: _get_compatible_gpus_v02(micro_batches, max_acceptable_batch_size, current_num_gpus, min_gpus, max_gpus, prefer_larger, num_gpus_per_node, model_parallel_size) and returns: candidate_batch_size,  list,  candidate_microbatch, candidate_microbatch, final_batch_size,  valid_dp_world_size,  candidate_microbatch