class_docstr: TrainLoop contains the core training loop logic.
class_docstr_tok: ["TrainLoop","contains","the","core","training","loop","logic","."]
docstr: Return train, log, and validate timing.
  
  If relying on the time for validation/logging/max train time purposes,
  we sync and return primary worker's time.
  
  Otherwise, it's not super relevant what we do here.
  
  **SIDE EFFECT**: Update _total_epochs trained.
  
  :param world:
      current running world
  
  :return (train, log, valid):
      return time for each of train, log, and validation
docstr_tok: ["Return","train",",","log",",","and","validate","timing",".","If","relying","on","the","time","for","validation\/logging\/max","train","time","purposes",",","we","sync","and","return","primary","worker","'s","time",".","Otherwise",",","it","'s","not","super","relevant","what","we","do","here",".","*","*","SIDE","EFFECT","*","*",":","Update","_total_epochs","trained",".",":","param","world",":","current","running","world",":","return","(","train",",","log",",","valid",")",":","return","time","for","each","of","train",",","log",",","and","validation"]
code: def _get_time(self, world: World) -> Tuple[float, float, float]:
      """
      Return train, log, and validate timing.
  
      If relying on the time for validation/logging/max train time purposes,
      we sync and return primary worker's time.
  
      Otherwise, it's not super relevant what we do here.
  
      **SIDE EFFECT**: Update _total_epochs trained.
  
      :param world:
          current running world
  
      :return (train, log, valid):
          return time for each of train, log, and validation
      """
      if (
          self.max_train_time < float("inf")
          or self.log_every_n_secs < float("inf")
          or self.val_every_n_secs < float("inf")
          or self.val_every_n_epochs < float("inf")
          or self.max_num_epochs < float("inf")
      ):
          self._total_epochs = self._preempted_epochs + sum(
              all_gather_list(world.get_total_epochs())
          )
          train_time, log_time, validate_time, save_time = sync_object(
              (
                  self.train_time.time(),
                  self.log_time.time(),
                  self.validate_time.time(),
                  self.save_time.time(),
              )
          )
      else:
          train_time, log_time, validate_time, save_time = (
              self.train_time.time(),
              self.log_time.time(),
              self.validate_time.time(),
              self.save_time.time(),
          )
          self._total_epochs = self._preempted_epochs + (
              num_workers() * world.get_total_epochs()
          )
  
      return train_time, log_time, validate_time, save_time
  
imports: import copy
  import random
  import torch
  import json
  import os
  import signal
  from typing import Tuple
  import numpy
  import parlai.utils.logging
  from parlai.core.agents import create_agent, create_agent_from_shared
  from parlai.core.exceptions import StopTrainException
  from parlai.core.logs import TensorboardLogger, WandbLogger, ClearMLLogger
  from parlai.core.metrics import Metric
  from parlai.core.metrics import aggregate_named_reports, aggregate_unnamed_reports, dict_report
  from parlai.core.opt import Opt
  from parlai.core.params import ParlaiParser, print_announcements
  from parlai.core.script import ParlaiScript, register_script
  from parlai.core.worlds import create_task, World
  from parlai.scripts.build_dict import build_dict, setup_args
  from parlai.scripts.eval_model import get_task_world_logs
  from parlai.utils.distributed import sync_object, is_primary_worker, all_gather_list, is_distributed, get_rank, num_workers
  from parlai.utils.io import PathManager
  from parlai.utils.misc import Timer, nice_report
  from parlai.utils.world_logging import WorldLogger
label_desc: Use image node_id 10 for calling the TrainLoop obj's underlying member method code with example usage: obj._get_time(world) and returns: train_time,  log_time,  validate_time,  save_time