code: def save_and_eval(
      args,
      trainer,
      task,
      extra_state: Dict[str, Any],
      checkpoint_manager: Optional[checkpoint.CheckpointManager],
      end_of_epoch=False,
  ) -> Tuple[Dict[str, Any], bool, Optional[List]]:
      # Checks for time limit stopping criterion even when we're not doing
      # eval/saving checkpoints.
      max_update = args.max_update or math.inf
      stop_due_to_max_update = trainer.get_num_updates() > max_update
      stop_due_to_time_limit = is_training_over_time_limit(
          extra_state, args.stop_time_hr
      )
      if not end_of_epoch and (
          args.save_interval_updates <= 0
          or (
              extra_state["num_iterations"] % args.save_interval_updates
              != 0
          )
      ):
          return extra_state, stop_due_to_time_limit
  
      # Update training time before saving the checkpoint.
      time_now: float = time.time()
      extra_state["previous_training_time"] += (
          time_now - extra_state["start_time"]
      )
      extra_state["start_time"] = time_now
  
      # Under multiprocessing, each process will run eval over a different
      # shard of the tune data set and then aggregate the results across all
      # processes, so the eval stats from all processes' trainer should
      # remain synchronized.
  
      # Tune loss
      extra_state, stop_due_to_tune_loss = eval_tune_loss(
          args=args,
          trainer=trainer,
          task=task,
          subset=args.valid_subset,
          extra_state=extra_state,
      )
  
      is_master: bool = distributed_utils.is_master(args)
      if is_master:
          assert checkpoint_manager is not None, (
              f"Master worker (rank {args.distributed_rank}) should "
              f"have a checkpoint_manager defined."
          )
      else:
          assert checkpoint_manager is None, (
              f"Non-master worker (rank {args.distributed_rank}) should not "
              f"have a checkpoint_manager defined."
          )
  
      if is_master:
          averaged_params: OrderedDict = (
              checkpoint_manager.get_averaged_params(
                  new_params=trainer.get_model().state_dict()
              )
          )
          new_best_averaged_checkpoint = (
              extra_state["tune_eval"]["num_since_best"] == 0
          )
          # checkpoint_manager takes ownership of averaged_params.
          extra_state = checkpoint_manager.save(
              args=args,
              trainer=trainer,
              extra_state=extra_state,
              new_averaged_params=averaged_params,
          )
          if new_best_averaged_checkpoint:
              checkpoint_manager.save_best_averaged_checkpoint(
                  args=args, trainer=trainer, extra_state=extra_state
              )
  
      master_stop_training = None
      if is_master:
          master_stop_training = (
              stop_due_to_time_limit
              or stop_due_to_tune_loss
              or stop_due_to_max_update
          )
      stop_training = pytorch_translate_utils.all_gather_from_master(
          args=args, data=[master_stop_training]
      )[0]
  
      # TODO: fix after masked lm work completes
      if "save_only" not in args or not args.save_only:
          # Basic sanity checks that extra_state is populated correctly.
          assert (
              extra_state["tune_eval"]["loss"] is not None
              and extra_state["tune_eval"]["perplexity"] is not None
          )
      return extra_state, stop_training
  
file_path: translate/pytorch_translate/evals.py
imports: import math
  import time
  from collections import defaultdict, OrderedDict
  from typing import Any, Dict, List, Optional, Tuple
  from fairseq import distributed_utils, progress_bar, utils
  from fairseq.meters import AverageMeter
  from pytorch_translate import checkpoint, generate, utils
  from pytorch_translate.dual_learning.dual_learning_task import DualLearningTask
  from pytorch_translate.tasks.pytorch_translate_multi_task import PyTorchTranslateMultiTask
label_desc: Use image node_id 8 for calling a global function with example usage: save_and_eval(args, trainer, task, extra_state, checkpoint_manager, end_of_epoch) and returns: extra_state,  stop_training, extra_state,  stop_due_to_time_limit