class_docstr: This class provides interface functions for users to get the parallel context,
  such as the global rank, the local rank, the world size, etc. of each device.
  
  Note:
      The parallel_mode used in this class should be concluded in ``ParallelMode``.
      More details about ``ParallelMode`` could be found in
      `parallel_mode <https://github.com/hpcaitech/ColossalAI/blob/main/colossalai/context/parallel_mode.py>`_.
docstr: Initializes the parallel groups.
  
  Raises:
      AssertionError: Raises an AssertionError if the field parallel is not present in the config file.
docstr_tok: ["Initializes","the","parallel","groups",".","Raises",":","AssertionError",":","Raises","an","AssertionError","if","the","field","parallel","is","not","present","in","the","config","file","."]
code: def init_parallel_groups(self):
      """Initializes the parallel groups.
  
      Raises:
          AssertionError: Raises an AssertionError if the field parallel is not present in the config file.
      """
  
      # get rank and world size
      rank = self.get_global_rank()
      world_size = self.get_world_size(ParallelMode.GLOBAL)
      self.world_size = world_size
  
      # set parallel size as attributes for global context
      parallel_config = self.config.get("parallel", None)
      if parallel_config is not None:
          self._set_parallel_size_from_config(
              parallel_config, "pipeline", "pipeline_parallel_size"
          )
          self._set_parallel_size_from_config(
              parallel_config, "tensor", "tensor_parallel_size"
          )
  
      # the user should not set the data parallel size manually
      # instead, it should be calculated based on other parallel config
      self.data_parallel_size = self.world_size // (
          self.pipeline_parallel_size * self.tensor_parallel_size
      )
  
      # get the tensor parallel mode and check
      tensor_parallel_mode = None
      if (
          parallel_config is not None
          and "tensor" in parallel_config
          and "mode" in parallel_config["tensor"]
      ):
          tensor_parallel_mode = parallel_config["tensor"]["mode"]
      assert (
          tensor_parallel_mode in ALLOWED_MODES
      ), f"mode in the parallel config must be set to one of {ALLOWED_MODES}"
      env.mode = tensor_parallel_mode
  
      self.check_sanity()
  
      pg_init = []
      # LSG: init data parallel process group for compatibility with other parallel module such as zero
      pg_init.append(dict(type=INITIALIZER_MAPPING["data"]))
  
      # LSG: init model parallel process group for compatibility with amp and clip grad
      pg_init.append(dict(type=INITIALIZER_MAPPING["model"]))
  
      if self.pipeline_parallel_size > 1:
          pg_init.append(dict(type=INITIALIZER_MAPPING["pipeline"]))
      pg_init.append(dict(type=INITIALIZER_MAPPING["tensor"]))
  
      # init specific tensor parallel group
      if tensor_parallel_mode is not None:
          tensor_parallel_cfg = parallel_config["tensor"].copy()
  
          # remove duplicate parameters
          tensor_parallel_cfg.pop("mode")
          tensor_parallel_cfg.pop("size")
  
          # add this config to initialize later
          pg_init.append(
              dict(
                  type=INITIALIZER_MAPPING[
                      tensor_parallel_mode.lower()
                  ],
                  **tensor_parallel_cfg,
              )
          )
  
      # run initialization of different process groups
      for initializer_cfg in pg_init:
          cfg = initializer_cfg.copy()
          initializer_type = cfg.pop("type")
          initializer = DIST_GROUP_INITIALIZER.get_module(
              initializer_type
          )(
              rank,
              world_size,
              self.config,
              self.data_parallel_size,
              self.pipeline_parallel_size,
              self.tensor_parallel_size,
              **cfg,
          )
          parallel_setting = initializer.init_dist_group()
          if isinstance(parallel_setting, list):
              for args in parallel_setting:
                  self._register_dist(*args)
          else:
              self._register_dist(*parallel_setting)
  
imports: import random
  import socket
  from collections import Counter
  from typing import Union
  import numpy
  import torch
  import torch.distributed
  from colossalai.context.config import Config
  from colossalai.context.singleton_meta import SingletonMeta
  from colossalai.legacy.constants import ALLOWED_MODES, INITIALIZER_MAPPING
  from colossalai.legacy.global_variables import tensor_parallel_env
  from colossalai.legacy.registry import DIST_GROUP_INITIALIZER
  from colossalai.logging import get_dist_logger
  from .parallel_mode import ParallelMode
  from .random import add_seed, get_seeds, set_mode
label_desc: Use image node_id 31 for calling the ParallelContext obj's underlying member method code with example usage: obj.init_parallel_groups() without return types