def _run_once_on_dataset()

in ignite/engine/engine.py [0:0]


    def _run_once_on_dataset(self) -> float:
        start_time = time.time()

        # We need to setup iter_counter > 0 if we resume from an iteration
        iter_counter = self._init_iter.pop() if len(self._init_iter) > 0 else 0
        should_exit = False
        try:
            if self._dataloader_iter is None:
                raise RuntimeError(
                    "Internal error, self._dataloader_iter is None. "
                    "Please, file an issue if you encounter this error."
                )

            while True:
                self.state.batch = self.state.output = None
                try:
                    # Avoid Events.GET_BATCH_STARTED triggered twice when data iter is restarted
                    if self.last_event_name != Events.DATALOADER_STOP_ITERATION:
                        self._fire_event(Events.GET_BATCH_STARTED)
                    self.state.batch = next(self._dataloader_iter)
                    self._fire_event(Events.GET_BATCH_COMPLETED)
                    iter_counter += 1
                    should_exit = False
                except StopIteration:
                    # Define self.state.epoch_length if it is not yet set
                    if self.state.epoch_length is None:
                        # Define epoch length and stop the epoch
                        self.state.epoch_length = iter_counter
                        if self.state.max_iters is not None:
                            self.state.max_epochs = math.ceil(self.state.max_iters / self.state.epoch_length)
                        break

                    # Should exit while loop if we can not iterate
                    if should_exit:
                        if not self._is_done(self.state):
                            total_iters = (
                                self.state.epoch_length * self.state.max_epochs
                                if self.state.max_epochs is not None
                                else self.state.max_iters
                            )

                            warnings.warn(
                                "Data iterator can not provide data anymore but required total number of "
                                "iterations to run is not reached. "
                                f"Current iteration: {self.state.iteration} vs Total iterations to run : {total_iters}"
                            )
                        break

                    self._fire_event(Events.DATALOADER_STOP_ITERATION)
                    self._setup_dataloader_iter()

                    should_exit = True

                    continue

                self.state.iteration += 1
                self._fire_event(Events.ITERATION_STARTED)
                self.state.output = self._process_function(self, self.state.batch)
                self._fire_event(Events.ITERATION_COMPLETED)

                if self.should_terminate or self.should_terminate_single_epoch:
                    self._fire_event(Events.TERMINATE_SINGLE_EPOCH, iter_counter=iter_counter)
                    self.should_terminate_single_epoch = False
                    self._setup_dataloader_iter()
                    break

                if self.state.epoch_length is not None and iter_counter == self.state.epoch_length:
                    break

                if self.state.max_iters is not None and self.state.iteration == self.state.max_iters:
                    self.should_terminate = True
                    break

        except Exception as e:
            self.logger.error(f"Current run is terminating due to exception: {e}")
            self._handle_exception(e)

        return time.time() - start_time