class_docstr: The distributed trainer for data parallel training.
  
  Arguments:
      params: dict of parameters to train
      optimizer: mx.optim.Optimizer. the choice of optimizer
      optimizer_params: hyper-parameter of the chosen optimizer
      compression: Compression algorithm used during allreduce to reduce the amount
                   of data sent during the each parameter update step.  Defaults to
                   not using compression.
      gradient_predivide_factor: gradient_predivide_factor splits the averaging
            before and after the sum. Gradients are scaled by
            1.0 / gradient_predivide_factor before the sum and
            gradient_predivide_factor / size after the sum.
      prefix: the prefix of the parameters this trainer manages.
            If multiple trainers are used in the same program,
            they must be specified by different prefixes to avoid tensor name collision.
code: def __init__(
      self,
      params,
      optimizer,
      optimizer_params=None,
      compression=Compression.none,
      gradient_predivide_factor=1.0,
      prefix=None,
      num_groups=0,
      process_set=global_process_set,
  ):
      self._compression = compression
      self._process_set = process_set
  
      if gradient_predivide_factor != 1.0 and rocm_built():
          raise ValueError(
              "gradient_predivide_factor not supported yet with ROCm"
          )
      if isinstance(optimizer, DistributedOptimizer):
          optimizer = optimizer._optimizer
          warnings.warn(
              "DistributedTrainer does not take DistributedOptimizer "
              "as its optimizer. We have unwrapped it for you."
          )
  
      # To ensure consistent parameter ordering across workers, sort params before
      # passing to base Trainer constructor. This logic is consistent with trainer.py
      # since v1.6 but we do it here for backwards compatability
      if isinstance(params, dict):
          params = OrderedDict(params)
      elif isinstance(params, (list, tuple)):
          params = sorted(params)
  
      super(DistributedTrainer, self).__init__(
          params,
          optimizer,
          optimizer_params=optimizer_params,
          kvstore=None,
      )
  
      self._gradient_predivide_factor = gradient_predivide_factor
      self._average_in_framework = False
      # C++ backend will apply additional 1 / size() factor to postscale_factor for op == Average.
      self._postscale_factor = self._gradient_predivide_factor
      if rocm_built() or nccl_built() < 21000:
          # Perform average in framework via rescale_grad for ROCM or older NCCL versions
          # without average support
          self._scale *= gradient_predivide_factor / process_set.size()
          self._postscale_factor = 1.0
          self._average_in_framework = True
      assert prefix is None or isinstance(prefix, str)
      self._prefix = prefix if prefix else ""
      self._num_groups = num_groups
  
imports: from horovod.common.util import check_extension, split_list
  from horovod.mxnet.compression import Compression
  from horovod.mxnet.functions import allgather_object, broadcast_object
  from horovod.mxnet.mpi_ops import allgather, grouped_allgather
  from horovod.mxnet.mpi_ops import allreduce, allreduce_, grouped_allreduce, grouped_allreduce_
  from horovod.mxnet.mpi_ops import alltoall
  from horovod.mxnet.mpi_ops import broadcast, broadcast_
  from horovod.mxnet.mpi_ops import reducescatter, grouped_reducescatter
  from horovod.mxnet.mpi_ops import init, shutdown
  from horovod.mxnet.mpi_ops import is_initialized, start_timeline, stop_timeline
  from horovod.mxnet.mpi_ops import size, local_size, cross_size, rank, local_rank, cross_rank
  from horovod.mxnet.mpi_ops import mpi_threads_supported, mpi_enabled, mpi_built
  from horovod.mxnet.mpi_ops import gloo_enabled, gloo_built
  from horovod.mxnet.mpi_ops import nccl_built, ddl_built, ccl_built, cuda_built, rocm_built
  from horovod.mxnet.mpi_ops import ProcessSet, global_process_set, add_process_set, remove_process_set
  from horovod.mxnet.mpi_ops import Average, Sum, Adasum, Min, Max, Product
  import mxnet
  from collections import OrderedDict, defaultdict
  import types
  import warnings
label_desc: Use image node_id 1 to create a new DistributedTrainer object from inherited base classes: mx.gluon with example: obj = DistributedTrainer(params, optimizer, optimizer_params, compression, gradient_predivide_factor, prefix, num_groups, process_set)