class_docstr: Runs a given ``process_function`` over each batch of a dataset, emitting events as it goes.
  
  Args:
      process_function: A function receiving a handle to the engine and the current batch
          in each iteration, and returns data to be stored in the engine's state.
  
  Attributes:
      state: object that is used to pass internal and user-defined state between event handlers.
          It is created with the engine and its attributes (e.g. ``state.iteration``, ``state.epoch`` etc) are reset
          on every :meth:`~ignite.engine.engine.Engine.run`.
      last_event_name: last event name triggered by the engine.
  
  Note:
      :class:`~ignite.engine.engine.Engine` implementation has changed in v0.4.10 with "interrupt/resume" feature.
      Engine may behave differently on certain corner cases compared to the one from v0.4.9 and before.
      In such case, you can set ``Engine.interrupt_resume_enabled = False`` to restore previous behaviour.
  
  Examples:
      Create a basic trainer
  
      .. code-block:: python
  
          model = ...
          model = model.cuda()
          optimized = ...
          criterion = ...
  
          def train_step(engine, batch):
              model.train()
              inputs, targets = batch[0].cuda(), batch[1].cuda()
              optimizer.zero_grad()
              outputs = model(inputs)
              loss = criterion(outputs, targets)
              loss.backward()
              optimizer.step()
              return loss.item()
  
          trainer = Engine(update_model)
  
          @trainer.on(Events.ITERATION_COMPLETED(every=100))
          def log_training(engine):
              batch_loss = engine.state.output
              lr = optimizer.param_groups[0]['lr']
              e = engine.state.epoch
              n = engine.state.max_epochs
              i = engine.state.iteration
              print(f"Epoch {e}/{n} : {i} - batch loss: {batch_loss}, lr: {lr}")
  
          trainer.run(data_loader, max_epochs=5)
  
          > Epoch 1/5 : 100 - batch loss: 0.10874069479016124, lr: 0.01
          > ...
          > Epoch 2/5 : 1700 - batch loss: 0.4217900575859437, lr: 0.01
  
      Create a basic evaluator to compute metrics
  
      .. code-block:: python
  
          from ignite.metrics import Accuracy
  
          def predict_on_batch(engine, batch)
              model.eval()
              with torch.no_grad():
                  x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)
                  y_pred = model(x)
  
              return y_pred, y
  
          evaluator = Engine(predict_on_batch)
          Accuracy().attach(evaluator, "val_acc")
          evaluator.run(val_dataloader)
  
      Compute image mean/std on training dataset
  
      .. code-block:: python
  
          from ignite.metrics import Average
  
          def compute_mean_std(engine, batch):
              b, c, *_ = batch['image'].shape
              data = batch['image'].reshape(b, c, -1).to(dtype=torch.float64)
              mean = torch.mean(data, dim=-1).sum(dim=0)
              mean2 = torch.mean(data ** 2, dim=-1).sum(dim=0)
              return {"mean": mean, "mean^2": mean2}
  
          compute_engine = Engine(compute_mean_std)
          img_mean = Average(output_transform=lambda output: output['mean'])
          img_mean.attach(compute_engine, 'mean')
          img_mean2 = Average(output_transform=lambda output: output['mean^2'])
          img_mean2.attach(compute_engine, 'mean2')
          state = compute_engine.run(train_loader)
          state.metrics['std'] = torch.sqrt(state.metrics['mean2'] - state.metrics['mean'] ** 2)
          mean = state.metrics['mean'].tolist()
          std = state.metrics['std'].tolist()
  
      Resume engine's run from a state. User can load a `state_dict` and run engine starting from loaded state :
  
      .. code-block:: python
  
          # Restore from an epoch
          state_dict = {"epoch": 3, "max_epochs": 100, "epoch_length": len(data_loader)}
          # or an iteration
          # state_dict = {"iteration": 500, "max_epochs": 100, "epoch_length": len(data_loader)}
  
          trainer = Engine(...)
          trainer.load_state_dict(state_dict)
          trainer.run(data)
docstr: Runs the ``process_function`` over the passed data.
  
  Engine has a state and the following logic is applied in this function:
  
  - At the first call, new state is defined by `max_epochs`, `max_iters`, `epoch_length`, if provided.
    A timer for total and per-epoch time is initialized when Events.STARTED is handled.
  - If state is already defined such that there are iterations to run until `max_epochs` and no input arguments
    provided, state is kept and used in the function.
  - If state is defined and engine is "done" (no iterations to run until `max_epochs`), a new state is defined.
  - If state is defined, engine is NOT "done", then input arguments if provided override defined state.
  
  Args:
      data: Collection of batches allowing repeated iteration (e.g., list or `DataLoader`). If not provided, then
          ``epoch_length`` is required and ``batch`` argument of ``process_function`` will be ``None``.
      max_epochs: Max epochs to run for (default: None).
          If a new state should be created (first run or run again from ended engine), it's default value is 1.
          If run is resuming from a state, provided `max_epochs` will be taken into account and should be larger
          than `engine.state.max_epochs`.
      epoch_length: Number of iterations to count as one epoch. By default, it can be set as
          `len(data)`. If `data` is an iterator and `epoch_length` is not set, then it will be automatically
          determined as the iteration on which data iterator raises `StopIteration`.
          This argument should not change if run is resuming from a state.
      max_iters: Number of iterations to run for.
          `max_iters` and `max_epochs` are mutually exclusive; only one of the two arguments should be provided.
  
  Returns:
      State: output state.
  
  Note:
      User can dynamically preprocess input batch at :attr:`~ignite.engine.events.Events.ITERATION_STARTED` and
      store output batch in `engine.state.batch`. Latter is passed as usually to `process_function` as argument:
  
      .. code-block:: python
  
          trainer = ...
  
          @trainer.on(Events.ITERATION_STARTED)
          def switch_batch(engine):
              engine.state.batch = preprocess_batch(engine.state.batch)
  
      Restart the training from the beginning. User can reset `max_epochs = None`:
  
      .. code-block:: python
  
          # ...
          trainer.run(train_loader, max_epochs=5)
  
          # Reset model weights etc. and restart the training
          trainer.state.max_epochs = None
          trainer.run(train_loader, max_epochs=2)
docstr_tok: ["Runs","the","``","process_function","``","over","the","passed","data",".","Engine","has","a","state","and","the","following","logic","is","applied","in","this","function",":","-","At","the","first","call",",","new","state","is","defined","by","`","max_epochs","`",",","`","max_iters","`",",","`","epoch_length","`",",","if","provided",".","A","timer","for","total","and","per-epoch","time","is","initialized","when","Events.STARTED","is","handled",".","-","If","state","is","already","defined","such","that","there","are","iterations","to","run","until","`","max_epochs","`","and","no","input","arguments","provided",",","state","is","kept","and","used","in","the","function",".","-","If","state","is","defined","and","engine","is","``","done","''","(","no","iterations","to","run","until","`","max_epochs","`",")",",","a","new","state","is","defined",".","-","If","state","is","defined",",","engine","is","NOT","``","done","''",",","then","input","arguments","if","provided","override","defined","state",".","Args",":","data",":","Collection","of","batches","allowing","repeated","iteration","(","e.g.",",","list","or","`","DataLoader","`",")",".","If","not","provided",",","then","``","epoch_length","``","is","required","and","``","batch","``","argument","of","``","process_function","``","will","be","``","None","``",".","max_epochs",":","Max","epochs","to","run","for","(","default",":","None",")",".","If","a","new","state","should","be","created","(","first","run","or","run","again","from","ended","engine",")",",","it","'s","default","value","is","1",".","If","run","is","resuming","from","a","state",",","provided","`","max_epochs","`","will","be","taken","into","account","and","should","be","larger","than","`","engine.state.max_epochs","`",".","epoch_length",":","Number","of","iterations","to","count","as","one","epoch",".","By","default",",","it","can","be","set","as","`","len","(","data",")","`",".","If","`","data","`","is","an","iterator","and","`","epoch_length","`","is","not","set",",","then","it","will","be","automatically","determined","as","the","iteration","on","which","data","iterator","raises","`","StopIteration","`",".","This","argument","should","not","change","if","run","is","resuming","from","a","state",".","max_iters",":","Number","of","iterations","to","run","for",".","`","max_iters","`","and","`","max_epochs","`","are","mutually","exclusive",";","only","one","of","the","two","arguments","should","be","provided",".","Returns",":","State",":","output","state",".","Note",":","User","can","dynamically","preprocess","input","batch","at",":","attr",":","`","~ignite.engine.events.Events.ITERATION_STARTED","`","and","store","output","batch","in","`","engine.state.batch","`",".","Latter","is","passed","as","usually","to","`","process_function","`","as","argument",":","..","code-block",":",":","python","trainer","=","...","@","trainer.on","(","Events.ITERATION_STARTED",")","def","switch_batch","(","engine",")",":","engine.state.batch","=","preprocess_batch","(","engine.state.batch",")","Restart","the","training","from","the","beginning",".","User","can","reset","`","max_epochs","=","None","`",":","..","code-block",":",":","python","#","...","trainer.run","(","train_loader",",","max_epochs=5",")","#","Reset","model","weights","etc",".","and","restart","the","training","trainer.state.max_epochs","=","None","trainer.run","(","train_loader",",","max_epochs=2",")"]
code: def run(
      self,
      data: Optional[Iterable] = None,
      max_epochs: Optional[int] = None,
      max_iters: Optional[int] = None,
      epoch_length: Optional[int] = None,
  ) -> State:
      """Runs the ``process_function`` over the passed data.
  
      Engine has a state and the following logic is applied in this function:
  
      - At the first call, new state is defined by `max_epochs`, `max_iters`, `epoch_length`, if provided.
        A timer for total and per-epoch time is initialized when Events.STARTED is handled.
      - If state is already defined such that there are iterations to run until `max_epochs` and no input arguments
        provided, state is kept and used in the function.
      - If state is defined and engine is "done" (no iterations to run until `max_epochs`), a new state is defined.
      - If state is defined, engine is NOT "done", then input arguments if provided override defined state.
  
      Args:
          data: Collection of batches allowing repeated iteration (e.g., list or `DataLoader`). If not provided, then
              ``epoch_length`` is required and ``batch`` argument of ``process_function`` will be ``None``.
          max_epochs: Max epochs to run for (default: None).
              If a new state should be created (first run or run again from ended engine), it's default value is 1.
              If run is resuming from a state, provided `max_epochs` will be taken into account and should be larger
              than `engine.state.max_epochs`.
          epoch_length: Number of iterations to count as one epoch. By default, it can be set as
              `len(data)`. If `data` is an iterator and `epoch_length` is not set, then it will be automatically
              determined as the iteration on which data iterator raises `StopIteration`.
              This argument should not change if run is resuming from a state.
          max_iters: Number of iterations to run for.
              `max_iters` and `max_epochs` are mutually exclusive; only one of the two arguments should be provided.
  
      Returns:
          State: output state.
  
      Note:
          User can dynamically preprocess input batch at :attr:`~ignite.engine.events.Events.ITERATION_STARTED` and
          store output batch in `engine.state.batch`. Latter is passed as usually to `process_function` as argument:
  
          .. code-block:: python
  
              trainer = ...
  
              @trainer.on(Events.ITERATION_STARTED)
              def switch_batch(engine):
                  engine.state.batch = preprocess_batch(engine.state.batch)
  
          Restart the training from the beginning. User can reset `max_epochs = None`:
  
          .. code-block:: python
  
              # ...
              trainer.run(train_loader, max_epochs=5)
  
              # Reset model weights etc. and restart the training
              trainer.state.max_epochs = None
              trainer.run(train_loader, max_epochs=2)
  
      """
      if data is not None and not isinstance(data, Iterable):
          raise TypeError("Argument data should be iterable")
  
      if self.state.max_epochs is not None:
          # Check and apply overridden parameters
          if max_epochs is not None:
              if max_epochs < self.state.epoch:
                  raise ValueError(
                      "Argument max_epochs should be greater than or equal to the start "
                      f"epoch defined in the state: {max_epochs} vs {self.state.epoch}. "
                      "Please, set engine.state.max_epochs = None "
                      "before calling engine.run() in order to restart the training from the beginning."
                  )
              self.state.max_epochs = max_epochs
          if epoch_length is not None:
              if epoch_length != self.state.epoch_length:
                  raise ValueError(
                      "Argument epoch_length should be same as in the state, "
                      f"but given {epoch_length} vs {self.state.epoch_length}"
                  )
  
      if self.state.max_epochs is None or (
          self._is_done(self.state)
          and self._internal_run_generator is None
      ):
          # Create new state
          if epoch_length is None:
              if data is None:
                  raise ValueError(
                      "epoch_length should be provided if data is None"
                  )
  
              epoch_length = self._get_data_length(data)
              if epoch_length is not None and epoch_length < 1:
                  raise ValueError(
                      "Input data has zero size. Please provide non-empty data"
                  )
  
          if max_iters is None:
              if max_epochs is None:
                  max_epochs = 1
          else:
              if max_epochs is not None:
                  raise ValueError(
                      "Arguments max_iters and max_epochs are mutually exclusive."
                      "Please provide only max_epochs or max_iters."
                  )
              if epoch_length is not None:
                  max_epochs = math.ceil(max_iters / epoch_length)
  
          self.state.iteration = 0
          self.state.epoch = 0
          self.state.max_epochs = max_epochs
          self.state.max_iters = max_iters
          self.state.epoch_length = epoch_length
          # Reset generator if previously used
          self._internal_run_generator = None
          self.logger.info(
              f"Engine run starting with max_epochs={max_epochs}."
          )
      else:
          self.logger.info(
              f"Engine run resuming from iteration {self.state.iteration}, "
              f"epoch {self.state.epoch} until {self.state.max_epochs} epochs"
          )
          if self.state.epoch_length is None and data is None:
              raise ValueError(
                  "epoch_length should be provided if data is None"
              )
  
          if self.should_terminate:
              # If engine was terminated and now is resuming from terminated state
              # we need to initialize iter_counter as 0
              self._init_iter = 0
  
      if self._dataloader_iter is None:
          self.state.dataloader = data
  
      if self.interrupt_resume_enabled:
          return self._internal_run()
      else:
          return self._internal_run_legacy()
  
imports: import functools
  import logging
  import math
  import time
  import warnings
  import weakref
  from collections import defaultdict, OrderedDict
  from collections.abc import Mapping
  from typing import Any, Callable, Dict, Generator, Iterable, Iterator, List, Optional, Tuple, Union
  from torch.utils.data import DataLoader
  from ignite.base import Serializable
  from ignite.engine.events import CallableEventWithFilter, EventEnum, Events, EventsList, RemovableEventHandle, State
  from ignite.engine.utils import _check_signature, _to_hours_mins_secs
label_desc: Use image node_id 21 for calling the Engine obj's underlying member method code with example usage: obj.run(data, max_epochs, max_iters, epoch_length) and returns: self, self