class_docstr: MoE manager. This class manages different
  parallel groups in MoE context and MoE loss in training.
docstr: Calculate the Data Parallel Group and Expert Parallel Group.
  
  Parameters
  ----------
  num_experts : int
      The number experts
  
  Returns
  -------
  int, MoeParallelInfo
      number of local experts, the MoeParallelInfo of the current ep_size
docstr_tok: ["Calculate","the","Data","Parallel","Group","and","Expert","Parallel","Group",".","Parameters","--","--","--","--","--","num_experts",":","int","The","number","experts","Returns","--","--","--","-","int",",","MoeParallelInfo","number","of","local","experts",",","the","MoeParallelInfo","of","the","current","ep_size"]
code: def get_info(
      self, num_experts: int, use_tp: bool = False
  ) -> Tuple[int, MoeParallelInfo]:
      """Calculate the Data Parallel Group and Expert Parallel Group.
  
      Parameters
      ----------
      num_experts : int
          The number experts
  
      Returns
      -------
      int, MoeParallelInfo
          number of local experts, the MoeParallelInfo of the current ep_size
      """
  
      if self.mode == "dynamic":
          gt_flag = (
              num_experts % self.max_ep_size == 0
          )  # check whether num_experts is greater
          lt_flag = (
              self.max_ep_size % num_experts == 0
          )  # check whether num_experts is less
          assert gt_flag or lt_flag, (
              "Automatic experts placement dose not not support expert number"
              " is not a multiple of ep size or vice versa."
          )
          dp_size = 1 if gt_flag else self.world_size // num_experts
          ep_size = min(self.world_size // dp_size, self.max_ep_size)
          dp_size = self.world_size // ep_size
          pp_size = 1
      else:
          dp_size = self.dp_size
          ep_size = self.ep_size
          pp_size = self.pp_size
  
      # Calculate the number of experts for each GPU
      if use_tp:
          num_local_experts = num_experts
      else:
          if self.mode == "dynamic":
              num_local_experts = (
                  1 if lt_flag else num_experts // self.max_ep_size
              )
          else:
              num_local_experts = num_experts // ep_size
  
      if not (ep_size in self.parallel_info_dict):
          self.parallel_info_dict[ep_size] = get_moe_info(
              ep_size, dp_size, pp_size, ep_inside=self.use_ep_inside
          )
          if dist.get_rank() == 0:
              if self.use_ep_inside:
                  print(
                      f"MoE Parallel: pp {pp_size}, dp {dp_size}, ep {ep_size}"
                  )
              else:
                  print(
                      f"MoE Parallel: pp {pp_size}, ep {ep_size}, dp {dp_size}"
                  )
  
      return num_local_experts, self.parallel_info_dict[ep_size]
  
file_path: colossalai/colossalai/moe/manager.py
imports: from typing import Tuple
  import torch
  import torch.distributed
  from colossalai.context.singleton_meta import SingletonMeta
  from colossalai.tensor.moe_tensor.api import get_moe_info
  from colossalai.tensor.moe_tensor.moe_info import MoeParallelInfo
label_desc: Use image node_id 5 for calling the MoEManager obj's underlying member method code with example usage: obj.get_info(num_experts, use_tp) and returns: num_local_experts,  self