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()

```

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.
     """

{"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"}]}