class_docstr: Manages a MXNet model for training.
class_docstr_tok: ["Manages","a","MXNet","model","for","training","."]
code: def setup_distributed(
      self,
      env,
      config,
      model_creator,
      loss_creator=None,
      validation_metrics_creator=None,
      eval_metrics_creator=None,
  ):
      logging.basicConfig(
          level=logging.INFO
      )  # This can print log messages to console.
      self.logger = logging.getLogger()
      self.config = config
      self.model_creator = model_creator
      self.loss_creator = loss_creator
      self.validation_metrics_creator = validation_metrics_creator
      self.eval_metrics_creator = eval_metrics_creator
      self.is_worker = False
      env["DMLC_NODE_HOST"] = self.get_node_ip()
      if env["DMLC_ROLE"] == "worker":
          self.is_worker = True
  
      if self.is_worker:
          os.environ.update(env)
          self.kv = mx.kv.create("dist_sync")
          # Set seed so that the model on each worker is initialized with the same weights.
          if "seed" in self.config:
              mx.random.seed(self.config["seed"])
  
          self.model = self.model_creator(self.config)
          self.loss = (
              self.loss_creator(self.config)
              if self.loss_creator
              else None
          )
          self.eval_metrics = (
              self.eval_metrics_creator(self.config)
              if self.eval_metrics_creator
              else None
          )
          from mxnet.metric import CompositeEvalMetric
  
          if isinstance(self.eval_metrics, list):
              self.eval_metrics = CompositeEvalMetric(self.eval_metrics)
          self.val_metrics = (
              self.validation_metrics_creator(self.config)
              if self.validation_metrics_creator
              else None
          )
          if isinstance(self.val_metrics, list):
              self.val_metrics = CompositeEvalMetric(self.val_metrics)
          # For BaseModule, use symbolic API. Otherwise, use imperative API.
          # TODO: change Gluon Trainer to Estimator API?
          if not isinstance(self.model, mx.module.BaseModule):
              invalidInputError(
                  self.loss,
                  "Loss not defined for gluon model, please specify loss_creator",
              )
              self.trainer = gluon.Trainer(
                  self.model.collect_params(),
                  self.config["optimizer"],
                  optimizer_params=self.config["optimizer_params"],
                  kvstore=self.kv,
              )
          else:  # Trainer is not needed for symbolic API.
              self.trainer = None
      else:  # server
          # Need to use the environment on each raylet process for the correct python environment.
          # TODO: Need to kill this process manually?
          modified_env = os.environ.copy()
          modified_env.update(env)
          # For servers, just import mxnet and no need to do anything else.
          subprocess.Popen(
              ["python", "-c", "import mxnet"],
              shell=False,
              env=modified_env,
          )
  
file_path: BigDL/python/orca/src/bigdl/orca/learn/mxnet/mxnet_runner.py
imports: import os
  import time
  import logging
  import subprocess
  import ray._private.services
  import mxnet
  from mxnet import gluon
  import copy
  from bigdl.orca.ray.utils import to_list
  from bigdl.dllib.utils.log4Error import *
label_desc: Use image node_id 1 for calling the MXNetRunner obj's underlying member method code with example usage: obj.setup_distributed(env, config, model_creator, loss_creator, validation_metrics_creator, eval_metrics_creator) without return types