code: def train_loop_per_worker(config):
      import horovod.torch as hvd
      import torch
  
      hvd.init()
      device = ray.train.torch.get_device()
      mode = config["mode"]
      net = Net(mode).to(device)
      optimizer = torch.optim.SGD(
          net.parameters(),
          lr=config["lr"],
      )
      optimizer = hvd.DistributedOptimizer(optimizer)
  
      num_steps = 5
      print(hvd.size())
      np.random.seed(1 + hvd.rank())
      torch.manual_seed(1234)
      # To ensure consistent initialization across workers,
      hvd.broadcast_parameters(net.state_dict(), root_rank=0)
      hvd.broadcast_optimizer_state(optimizer, root_rank=0)
  
      start = time.time()
      x_max = config["x_max"]
      for step in range(1, num_steps + 1):
          features = torch.Tensor(
              np.random.rand(1) * 2 * x_max - x_max
          ).to(device)
          if mode == "square":
              labels = sq(features)
          else:
              labels = qu(features)
          optimizer.zero_grad()
          outputs = net(features)
          loss = torch.nn.MSELoss()(outputs, labels)
          loss.backward()
  
          optimizer.step()
          time.sleep(0.1)
          train.report(dict(loss=loss.item()))
      total = time.time() - start
      print(f"Took {total:0.3f} s. Avg: {total / num_steps:0.3f} s.")
  
file_path: ray/python/ray/train/examples/horovod/horovod_tune_example.py
imports: import time
  import numpy
  import torch
  import ray
  import ray.train.torch
  from ray import train, tune
  from ray.train import ScalingConfig
  from ray.train.horovod import HorovodTrainer
  from ray.tune.tune_config import TuneConfig
  from ray.tune.tuner import Tuner
label_desc: Use image node_id 3 for calling a global function with example usage: train_loop_per_worker(config) without return types