class_docstr: WorkloadSequencer is the python rewrite of the old golang
  TrialWorkloadSequencer.
  
  Like the go version, it fuses the dual stream of searcher operations +
  descheduling decisions into a single stream of Workload events.
  
  When the sequencer was in the master, the resulting stream of Workloads was
  the basis for all master/harness communications, but now that the sequencer
  lives in the harness, all master/harness communications are over the new
  push APIs.
  
  This Workload stream (and the whole WorkloadSequencer) is only even needed
  for reverse-compatibility with the old TrialControllers that we don't care
  to update (TFKerasTrial and EstimatorTrial).
class_docstr_tok: ["WorkloadSequencer","is","the","python","rewrite","of","the","old","golang","TrialWorkloadSequencer",".","Like","the","go","version",",","it","fuses","the","dual","stream","of","searcher","operations","+","descheduling","decisions","into","a","single","stream","of","Workload","events",".","When","the","sequencer","was","in","the","master",",","the","resulting","stream","of","Workloads","was","the","basis","for","all","master\/harness","communications",",","but","now","that","the","sequencer","lives","in","the","harness",",","all","master\/harness","communications","are","over","the","new","push","APIs",".","This","Workload","stream","(","and","the","whole","WorkloadSequencer",")","is","only","even","needed","for","reverse-compatibility","with","the","old","TrialControllers","that","we","do","n't","care","to","update","(","TFKerasTrial","and","EstimatorTrial",")","."]
code: def __iter__(self) -> workload.Stream:
      try:
          # Step-zero Validations.
          if (
              self.want_initial_val
              and self.val_from_previous_run is None
              and self.state.steps_completed == 0
          ):
              yield from self.validate(None)
  
          for op in self.core_context.searcher.operations(
              core.SearcherMode.ChiefOnly
          ):
              while self.batches_until_op_complete(op) > 0:
                  # Do some training.
                  yield from self.train(
                      max(
                          1,
                          min(
                              self.batches_until_ckpt(),
                              self.batches_until_val(),
                              self.batches_until_op_complete(op),
                              self.env.experiment_config.scheduling_unit(),
                          ),
                      ),
                      op,
                  )
  
                  # Note: for historical compatibility we do validate-then-checkpoint here but
                  # when doing searcher-requested validations, we do checkpoint-then-validate.
                  # Most users preferred validate-then-checkpoint, but the distributed snapshot
                  # master restart logic required checkpoint-then-validate for searcher
                  # validations.
  
                  # Pause training to validate?
                  if self.batches_until_val() < 1:
                      yield from self.validate(op)
  
                  # Pause training to checkpoint?
                  if self.batches_until_ckpt() < 1:
                      yield from self.checkpoint(already_exiting=False)
  
              # Done training for this searcher operation!
  
              if not self.checkpoint_is_current():
                  yield from self.checkpoint(already_exiting=False)
  
              if not self.validation_is_current():
                  yield from self.validate(op)
  
              if not op._completed:
                  # The only case where op isn't reported as completed is if we restarted but
                  # op.length was already trained for and validated on; in that case just break
                  # out of the operations loop; we have nothing to do.
                  break
  
      except ShouldExit as e:
          # Checkpoint unsaved work and exit.
          if (
              not e.skip_exit_checkpoint
              and not self.checkpoint_is_current()
          ):
              yield from self.checkpoint(already_exiting=True)
  
imports: import logging
  import sys
  from typing import Any, Generator, Optional, Tuple
  import determined
  from determined import core, util, workload
  from determined.common import check
label_desc: Use image node_id 15 for calling the WorkloadSequencer obj's underlying member method code with example usage: obj.__iter__() without return types