prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve State documentation
  Hi,
  
  I think the documentation of states and the way they're used by engines is not detailed enough.
  Currently the only way to know what attributes are available in the default State object, used by the engines generated by convenience methods such as `create_supervised_trainer`, is to look at the source code.  
  Some of them are mentioned in the [Concept](https://pytorch.org/ignite/concepts.html#state) part of the documentation but there is still a lot of room for confusion about the way they work and some are missing.
  For example, no information about the `batch` attribute which without documentation some might assume to correspond to the batch index (kinda like `epoch` for the epoch index) which is actually `iteration`. Same thing for `epoch` which is used implicitly in examples but no mention of it in the default `State` documentation, and you might think it's obvious but then someone will try to create a default `State` and assume `epoch` is a built-in attribute set to 0 at instantiation when in fact you'll have to search through the source code to figure out that it's not a default attribute and is only created by the default `Engine` through a kwarg passed to the `State` class.
  
  Additionally this kind of explicit documentation of the state should be done every time a custom `State` is created otherwise the user is left to guess what attributes are available in it, what they mean and what format they're in. For example, is `output` the return from the forward pass of your model? The loss?
  You'll have to look at `Engine` then find out it's the output of the process_function argument. Then figure out that in the case of the  `create_supervised_trainer` that function is `_update` which returns `loss.item()` and in the case of `create_supervised_evaluator` returns `(y_pred, y)`.
  
  Thank you, and sorry for the verbosity but without it I was afraid this would be rejected as trivial.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ignite/engine/__init__.py`
  Content:
  ```
  1 import torch
  2 
  3 from ignite.engine.engine import Engine, State, Events
  4 from ignite.utils import convert_tensor
  5 
  6 
  7 def _prepare_batch(batch, device=None, non_blocking=False):
  8     """Prepare batch for training: pass to a device with options.
  9 
  10     """
  11     x, y = batch
  12     return (convert_tensor(x, device=device, non_blocking=non_blocking),
  13             convert_tensor(y, device=device, non_blocking=non_blocking))
  14 
  15 
  16 def create_supervised_trainer(model, optimizer, loss_fn,
  17                               device=None, non_blocking=False,
  18                               prepare_batch=_prepare_batch):
  19     """
  20     Factory function for creating a trainer for supervised models.
  21 
  22     Args:
  23         model (`torch.nn.Module`): the model to train.
  24         optimizer (`torch.optim.Optimizer`): the optimizer to use.
  25         loss_fn (torch.nn loss function): the loss function to use.
  26         device (str, optional): device type specification (default: None).
  27             Applies to both model and batches.
  28         non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously
  29             with respect to the host. For other cases, this argument has no effect.
  30         prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs
  31             tuple of tensors `(batch_x, batch_y)`.
  32 
  33     Returns:
  34         Engine: a trainer engine with supervised update function.
  35     """
  36     if device:
  37         model.to(device)
  38 
  39     def _update(engine, batch):
  40         model.train()
  41         optimizer.zero_grad()
  42         x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)
  43         y_pred = model(x)
  44         loss = loss_fn(y_pred, y)
  45         loss.backward()
  46         optimizer.step()
  47         return loss.item()
  48 
  49     return Engine(_update)
  50 
  51 
  52 def create_supervised_evaluator(model, metrics={},
  53                                 device=None, non_blocking=False,
  54                                 prepare_batch=_prepare_batch):
  55     """
  56     Factory function for creating an evaluator for supervised models.
  57 
  58     Args:
  59         model (`torch.nn.Module`): the model to train.
  60         metrics (dict of str - :class:`~ignite.metrics.Metric`): a map of metric names to Metrics.
  61         device (str, optional): device type specification (default: None).
  62             Applies to both model and batches.
  63         non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously
  64             with respect to the host. For other cases, this argument has no effect.
  65         prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs
  66             tuple of tensors `(batch_x, batch_y)`.
  67 
  68     Returns:
  69         Engine: an evaluator engine with supervised inference function.
  70     """
  71     if device:
  72         model.to(device)
  73 
  74     def _inference(engine, batch):
  75         model.eval()
  76         with torch.no_grad():
  77             x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)
  78             y_pred = model(x)
  79             return y_pred, y
  80 
  81     engine = Engine(_inference)
  82 
  83     for name, metric in metrics.items():
  84         metric.attach(engine, name)
  85 
  86     return engine
  87
  ```
  
  Path: `ignite/__init__.py`
  Content:
  ```
  1 import ignite.engine
  2 import ignite.handlers
  3 import ignite.metrics
  4 import ignite.exceptions
  5 import ignite.contrib
  6 
  7 __version__ = '0.1.2'
  8
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/ignite/__init__.py b/ignite/__init__.py
  --- a/ignite/__init__.py
  +++ b/ignite/__init__.py
  @@ -3,5 +3,6 @@
   import ignite.metrics
   import ignite.exceptions
   import ignite.contrib
  +import ignite.utils
   
   __version__ = '0.1.2'
  diff --git a/ignite/engine/__init__.py b/ignite/engine/__init__.py
  --- a/ignite/engine/__init__.py
  +++ b/ignite/engine/__init__.py
  @@ -30,6 +30,8 @@
           prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs
               tuple of tensors `(batch_x, batch_y)`.
   
  +    Note: `engine.state.output` for this engine is the loss of the processed batch.
  +
       Returns:
           Engine: a trainer engine with supervised update function.
       """
  @@ -65,6 +67,8 @@
           prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs
               tuple of tensors `(batch_x, batch_y)`.
   
  +    Note: `engine.state.output` for this engine is a tuple of `(batch_pred, batch_y)`.
  +
       Returns:
           Engine: an evaluator engine with supervised inference function.
       """
  
verification_info: {"golden_diff": "diff --git a/ignite/__init__.py b/ignite/__init__.py\n--- a/ignite/__init__.py\n+++ b/ignite/__init__.py\n@@ -3,5 +3,6 @@\n import ignite.metrics\n import ignite.exceptions\n import ignite.contrib\n+import ignite.utils\n \n __version__ = '0.1.2'\ndiff --git a/ignite/engine/__init__.py b/ignite/engine/__init__.py\n--- a/ignite/engine/__init__.py\n+++ b/ignite/engine/__init__.py\n@@ -30,6 +30,8 @@\n         prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n             tuple of tensors `(batch_x, batch_y)`.\n \n+    Note: `engine.state.output` for this engine is the loss of the processed batch.\n+\n     Returns:\n         Engine: a trainer engine with supervised update function.\n     \"\"\"\n@@ -65,6 +67,8 @@\n         prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n             tuple of tensors `(batch_x, batch_y)`.\n \n+    Note: `engine.state.output` for this engine is a tuple of `(batch_pred, batch_y)`.\n+\n     Returns:\n         Engine: an evaluator engine with supervised inference function.\n     \"\"\"\n", "issue": "Improve State documentation\nHi,\r\n\r\nI think the documentation of states and the way they're used by engines is not detailed enough.\r\nCurrently the only way to know what attributes are available in the default State object, used by the engines generated by convenience methods such as `create_supervised_trainer`, is to look at the source code.  \r\nSome of them are mentioned in the [Concept](https://pytorch.org/ignite/concepts.html#state) part of the documentation but there is still a lot of room for confusion about the way they work and some are missing.\r\nFor example, no information about the `batch` attribute which without documentation some might assume to correspond to the batch index (kinda like `epoch` for the epoch index) which is actually `iteration`. Same thing for `epoch` which is used implicitly in examples but no mention of it in the default `State` documentation, and you might think it's obvious but then someone will try to create a default `State` and assume `epoch` is a built-in attribute set to 0 at instantiation when in fact you'll have to search through the source code to figure out that it's not a default attribute and is only created by the default `Engine` through a kwarg passed to the `State` class.\r\n\r\nAdditionally this kind of explicit documentation of the state should be done every time a custom `State` is created otherwise the user is left to guess what attributes are available in it, what they mean and what format they're in. For example, is `output` the return from the forward pass of your model? The loss?\r\nYou'll have to look at `Engine` then find out it's the output of the process_function argument. Then figure out that in the case of the  `create_supervised_trainer` that function is `_update` which returns `loss.item()` and in the case of `create_supervised_evaluator` returns `(y_pred, y)`.\r\n\r\nThank you, and sorry for the verbosity but without it I was afraid this would be rejected as trivial.\n", "before_files": [{"content": "import torch\n\nfrom ignite.engine.engine import Engine, State, Events\nfrom ignite.utils import convert_tensor\n\n\ndef _prepare_batch(batch, device=None, non_blocking=False):\n    \"\"\"Prepare batch for training: pass to a device with options.\n\n    \"\"\"\n    x, y = batch\n    return (convert_tensor(x, device=device, non_blocking=non_blocking),\n            convert_tensor(y, device=device, non_blocking=non_blocking))\n\n\ndef create_supervised_trainer(model, optimizer, loss_fn,\n                              device=None, non_blocking=False,\n                              prepare_batch=_prepare_batch):\n    \"\"\"\n    Factory function for creating a trainer for supervised models.\n\n    Args:\n        model (`torch.nn.Module`): the model to train.\n        optimizer (`torch.optim.Optimizer`): the optimizer to use.\n        loss_fn (torch.nn loss function): the loss function to use.\n        device (str, optional): device type specification (default: None).\n            Applies to both model and batches.\n        non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously\n            with respect to the host. For other cases, this argument has no effect.\n        prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n            tuple of tensors `(batch_x, batch_y)`.\n\n    Returns:\n        Engine: a trainer engine with supervised update function.\n    \"\"\"\n    if device:\n        model.to(device)\n\n    def _update(engine, batch):\n        model.train()\n        optimizer.zero_grad()\n        x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)\n        y_pred = model(x)\n        loss = loss_fn(y_pred, y)\n        loss.backward()\n        optimizer.step()\n        return loss.item()\n\n    return Engine(_update)\n\n\ndef create_supervised_evaluator(model, metrics={},\n                                device=None, non_blocking=False,\n                                prepare_batch=_prepare_batch):\n    \"\"\"\n    Factory function for creating an evaluator for supervised models.\n\n    Args:\n        model (`torch.nn.Module`): the model to train.\n        metrics (dict of str - :class:`~ignite.metrics.Metric`): a map of metric names to Metrics.\n        device (str, optional): device type specification (default: None).\n            Applies to both model and batches.\n        non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously\n            with respect to the host. For other cases, this argument has no effect.\n        prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n            tuple of tensors `(batch_x, batch_y)`.\n\n    Returns:\n        Engine: an evaluator engine with supervised inference function.\n    \"\"\"\n    if device:\n        model.to(device)\n\n    def _inference(engine, batch):\n        model.eval()\n        with torch.no_grad():\n            x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)\n            y_pred = model(x)\n            return y_pred, y\n\n    engine = Engine(_inference)\n\n    for name, metric in metrics.items():\n        metric.attach(engine, name)\n\n    return engine\n", "path": "ignite/engine/__init__.py"}, {"content": "import ignite.engine\nimport ignite.handlers\nimport ignite.metrics\nimport ignite.exceptions\nimport ignite.contrib\n\n__version__ = '0.1.2'\n", "path": "ignite/__init__.py"}], "after_files": [{"content": "import torch\n\nfrom ignite.engine.engine import Engine, State, Events\nfrom ignite.utils import convert_tensor\n\n\ndef _prepare_batch(batch, device=None, non_blocking=False):\n    \"\"\"Prepare batch for training: pass to a device with options.\n\n    \"\"\"\n    x, y = batch\n    return (convert_tensor(x, device=device, non_blocking=non_blocking),\n            convert_tensor(y, device=device, non_blocking=non_blocking))\n\n\ndef create_supervised_trainer(model, optimizer, loss_fn,\n                              device=None, non_blocking=False,\n                              prepare_batch=_prepare_batch):\n    \"\"\"\n    Factory function for creating a trainer for supervised models.\n\n    Args:\n        model (`torch.nn.Module`): the model to train.\n        optimizer (`torch.optim.Optimizer`): the optimizer to use.\n        loss_fn (torch.nn loss function): the loss function to use.\n        device (str, optional): device type specification (default: None).\n            Applies to both model and batches.\n        non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously\n            with respect to the host. For other cases, this argument has no effect.\n        prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n            tuple of tensors `(batch_x, batch_y)`.\n\n    Note: `engine.state.output` for this engine is the loss of the processed batch.\n\n    Returns:\n        Engine: a trainer engine with supervised update function.\n    \"\"\"\n    if device:\n        model.to(device)\n\n    def _update(engine, batch):\n        model.train()\n        optimizer.zero_grad()\n        x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)\n        y_pred = model(x)\n        loss = loss_fn(y_pred, y)\n        loss.backward()\n        optimizer.step()\n        return loss.item()\n\n    return Engine(_update)\n\n\ndef create_supervised_evaluator(model, metrics={},\n                                device=None, non_blocking=False,\n                                prepare_batch=_prepare_batch):\n    \"\"\"\n    Factory function for creating an evaluator for supervised models.\n\n    Args:\n        model (`torch.nn.Module`): the model to train.\n        metrics (dict of str - :class:`~ignite.metrics.Metric`): a map of metric names to Metrics.\n        device (str, optional): device type specification (default: None).\n            Applies to both model and batches.\n        non_blocking (bool, optional): if True and this copy is between CPU and GPU, the copy may occur asynchronously\n            with respect to the host. For other cases, this argument has no effect.\n        prepare_batch (callable, optional): function that receives `batch`, `device`, `non_blocking` and outputs\n            tuple of tensors `(batch_x, batch_y)`.\n\n    Note: `engine.state.output` for this engine is a tuple of `(batch_pred, batch_y)`.\n\n    Returns:\n        Engine: an evaluator engine with supervised inference function.\n    \"\"\"\n    if device:\n        model.to(device)\n\n    def _inference(engine, batch):\n        model.eval()\n        with torch.no_grad():\n            x, y = prepare_batch(batch, device=device, non_blocking=non_blocking)\n            y_pred = model(x)\n            return y_pred, y\n\n    engine = Engine(_inference)\n\n    for name, metric in metrics.items():\n        metric.attach(engine, name)\n\n    return engine\n", "path": "ignite/engine/__init__.py"}, {"content": "import ignite.engine\nimport ignite.handlers\nimport ignite.metrics\nimport ignite.exceptions\nimport ignite.contrib\nimport ignite.utils\n\n__version__ = '0.1.2'\n", "path": "ignite/__init__.py"}]}