def _update_global_epoch(self, grad_scaler: Optional[GradScaler]) -> None:
    'Depending on the configuration: aggregate gradients and/or parameters, perform global optimizer step'
    assert (self._schema_hash == self._compute_schema_hash()), 'parameters or gradients changed during iteration'
    _epoch_start_time = time.perf_counter()
    with self.tracker.pause_updates():
        wait_for_trigger = None
        if self.use_gradient_averaging:
            logger.log(self.status_loglevel, f'Beginning optimizer step #{self.local_epoch}')
            if self.delay_optimizer_step:
                self.state_averager.step(wait_for_delayed_updates=True)
            began_averaging_gradients = self._begin_averaging_gradients(grad_scaler)
            if (not began_averaging_gradients):
                self.grad_averager.load_accumulators_into_averager_()
            elif self.delay_grad_averaging:
                wait_for_trigger = partial(self._average_gradients_and_load_into_optimizer, self.scheduled_grads)
            else:
                self._average_gradients_and_load_into_optimizer(self.scheduled_grads)
        next_epoch = max((self.local_epoch + 1), self.tracker.global_epoch)
        swarm_not_empty = (self.tracker.global_progress.num_peers > 1)
        should_perform_optimizer_step = ((not self.auxiliary) and (not self.use_local_updates))
        should_average_state = (swarm_not_empty and ((next_epoch % self.average_state_every) == 0) and (not self.state_averager.averaging_in_progress))
        if (should_average_state and (self.scheduled_state is not None)):
            if (self.scheduled_state.triggered or self.scheduled_state.done()):
                logger.log(self.status_loglevel, f'Not using pre-scheduled group for state averaging because itwas already used elsewhere: {self.scheduled_state}')
                self.scheduled_state = None
            self.delay_before_state_averaging.update(task_size=1, interval=(time.perf_counter() - _epoch_start_time))
        self.state_averager.step(increment_epoch=True, wait_for_trigger=wait_for_trigger, optimizer_step=should_perform_optimizer_step, delay_optimizer_step=(self.delay_optimizer_step and should_perform_optimizer_step), grad_scaler=grad_scaler, averaging_round=should_average_state, delay_averaging=(self.delay_state_averaging and (not self.auxiliary)), averaging_control=(self.scheduled_state if should_average_state else None), averaging_opts=(dict(timeout=self.averaging_timeout) if should_average_state else None))
        if ((not should_average_state) and (self.scheduled_state is not None) and (not self.scheduled_state.done())):
            self.scheduled_state.cancel()
        self.scheduled_state = None
        self.tracker.update_epoch(new_epoch=self.state_averager.local_epoch)
        self._should_check_synchronization_on_update = True
        if (not self.client_mode):
            self.state_averager.state_sharing_priority = self.local_epoch
        if (self.use_gradient_averaging and (not self.auxiliary)):
            self.grad_averager.reset_accumulated_grads_()
            if (not self.client_mode):
                self.grad_averager.state_sharing_priority = self.local_epoch
        logger.log(self.status_loglevel, f'Transitioning to epoch {self.local_epoch}')
Depending on the configuration: aggregate gradients and/or parameters, perform global optimizer step
def _update_global_epoch(self, grad_scaler: Optional[GradScaler]) -> None:
    
    assert (self._schema_hash == self._compute_schema_hash()), 'parameters or gradients changed during iteration'
    _epoch_start_time = time.perf_counter()
    with self.tracker.pause_updates():
        wait_for_trigger = None
        if self.use_gradient_averaging:
            logger.log(self.status_loglevel, f'Beginning optimizer step #{self.local_epoch}')
            if self.delay_optimizer_step:
                self.state_averager.step(wait_for_delayed_updates=True)
            began_averaging_gradients = self._begin_averaging_gradients(grad_scaler)
            if (not began_averaging_gradients):
                self.grad_averager.load_accumulators_into_averager_()
            elif self.delay_grad_averaging:
                wait_for_trigger = partial(self._average_gradients_and_load_into_optimizer, self.scheduled_grads)
            else:
                self._average_gradients_and_load_into_optimizer(self.scheduled_grads)
        next_epoch = max((self.local_epoch + 1), self.tracker.global_epoch)
        swarm_not_empty = (self.tracker.global_progress.num_peers > 1)
        should_perform_optimizer_step = ((not self.auxiliary) and (not self.use_local_updates))
        should_average_state = (swarm_not_empty and ((next_epoch % self.average_state_every) == 0) and (not self.state_averager.averaging_in_progress))
        if (should_average_state and (self.scheduled_state is not None)):
            if (self.scheduled_state.triggered or self.scheduled_state.done()):
                logger.log(self.status_loglevel, f'Not using pre-scheduled group for state averaging because itwas already used elsewhere: {self.scheduled_state}')
                self.scheduled_state = None
            self.delay_before_state_averaging.update(task_size=1, interval=(time.perf_counter() - _epoch_start_time))
        self.state_averager.step(increment_epoch=True, wait_for_trigger=wait_for_trigger, optimizer_step=should_perform_optimizer_step, delay_optimizer_step=(self.delay_optimizer_step and should_perform_optimizer_step), grad_scaler=grad_scaler, averaging_round=should_average_state, delay_averaging=(self.delay_state_averaging and (not self.auxiliary)), averaging_control=(self.scheduled_state if should_average_state else None), averaging_opts=(dict(timeout=self.averaging_timeout) if should_average_state else None))
        if ((not should_average_state) and (self.scheduled_state is not None) and (not self.scheduled_state.done())):
            self.scheduled_state.cancel()
        self.scheduled_state = None
        self.tracker.update_epoch(new_epoch=self.state_averager.local_epoch)
        self._should_check_synchronization_on_update = True
        if (not self.client_mode):
            self.state_averager.state_sharing_priority = self.local_epoch
        if (self.use_gradient_averaging and (not self.auxiliary)):
            self.grad_averager.reset_accumulated_grads_()
            if (not self.client_mode):
                self.grad_averager.state_sharing_priority = self.local_epoch
        logger.log(self.status_loglevel, f'Transitioning to epoch {self.local_epoch}')