prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve the example of Timer's usage
  ## 📚 Documentation
  
  The example in the `Timer's documentation suggest to estimate the processing time for a batch as follows:
  ```python
  timer.attach(
      trainer, 
      start=Events.EPOCH_STARTED, 
      resume=Events.ITERATION_STARTED, 
      pause=Events.ITERATION_COMPLETED, 
      step=Events.ITERATION_COMPLETED)
  ```
  It is to note that this timer will be reset at the start of each epoch. When we use multiple workers in the data loader, the first couple of iterations at each epoch often take longer than the later ones. The reset behavior will incur an inaccurate estimation of the remaining training time (ETA), even when the `average` flag is set to `True`. Specifically, the ETA is computed as `(engine.state.max_iters - engine.state.iteration) * time_per_iter`. So the small fluctuation in `time_per_iter` will be magnified by remaining number of iterations. To address this problem, we can let the timer only start once in the whole training process:
  ```python
   timer.attach(
      trainer, 
      start=Events.EPOCH_STARTED(once=1), 
      resume=Events.ITERATION_STARTED, 
      pause=Events.ITERATION_COMPLETED, 
      step=Events.ITERATION_COMPLETED)
  ```
  I have empirically verified the effectiveness of this modification.
  
  --- 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/handlers/timing.py`
  Content:
  ```
  1 from time import perf_counter
  2 from typing import Any, Optional
  3 
  4 from ignite.engine import Engine, Events
  5 
  6 __all__ = ["Timer"]
  7 
  8 
  9 class Timer:
  10     """ Timer object can be used to measure (average) time between events.
  11 
  12     Args:
  13         average: if True, then when ``.value()`` method is called, the returned value
  14             will be equal to total time measured, divided by the value of internal counter.
  15 
  16     Attributes:
  17         total (float): total time elapsed when the Timer was running (in seconds).
  18         step_count (int): internal counter, useful to measure average time, e.g. of processing a single batch.
  19             Incremented with the ``.step()`` method.
  20         running (bool): flag indicating if timer is measuring time.
  21 
  22     Note:
  23         When using ``Timer(average=True)`` do not forget to call ``timer.step()`` every time an event occurs. See
  24         the examples below.
  25 
  26     Examples:
  27 
  28         Measuring total time of the epoch:
  29 
  30         >>> from ignite.handlers import Timer
  31         >>> import time
  32         >>> work = lambda : time.sleep(0.1)
  33         >>> idle = lambda : time.sleep(0.1)
  34         >>> t = Timer(average=False)
  35         >>> for _ in range(10):
  36         ...    work()
  37         ...    idle()
  38         ...
  39         >>> t.value()
  40         2.003073937026784
  41 
  42         Measuring average time of the epoch:
  43 
  44         >>> t = Timer(average=True)
  45         >>> for _ in range(10):
  46         ...    work()
  47         ...    idle()
  48         ...    t.step()
  49         ...
  50         >>> t.value()
  51         0.2003182829997968
  52 
  53         Measuring average time it takes to execute a single ``work()`` call:
  54 
  55         >>> t = Timer(average=True)
  56         >>> for _ in range(10):
  57         ...    t.resume()
  58         ...    work()
  59         ...    t.pause()
  60         ...    idle()
  61         ...    t.step()
  62         ...
  63         >>> t.value()
  64         0.10016545779653825
  65 
  66         Using the Timer to measure average time it takes to process a single batch of examples:
  67 
  68         >>> from ignite.engine import Engine, Events
  69         >>> from ignite.handlers import Timer
  70         >>> trainer = Engine(training_update_function)
  71         >>> timer = Timer(average=True)
  72         >>> timer.attach(trainer,
  73         ...              start=Events.EPOCH_STARTED,
  74         ...              resume=Events.ITERATION_STARTED,
  75         ...              pause=Events.ITERATION_COMPLETED,
  76         ...              step=Events.ITERATION_COMPLETED)
  77     """
  78 
  79     def __init__(self, average: bool = False):
  80         self._average = average
  81 
  82         self.reset()
  83 
  84     def attach(
  85         self,
  86         engine: Engine,
  87         start: Events = Events.STARTED,
  88         pause: Events = Events.COMPLETED,
  89         resume: Optional[Events] = None,
  90         step: Optional[Events] = None,
  91     ) -> "Timer":
  92         """ Register callbacks to control the timer.
  93 
  94         Args:
  95             engine: Engine that this timer will be attached to.
  96             start: Event which should start (reset) the timer.
  97             pause: Event which should pause the timer.
  98             resume: Event which should resume the timer.
  99             step: Event which should call the `step` method of the counter.
  100 
  101         Returns:
  102             this timer
  103         """
  104 
  105         engine.add_event_handler(start, self.reset)
  106         engine.add_event_handler(pause, self.pause)
  107 
  108         if resume is not None:
  109             engine.add_event_handler(resume, self.resume)
  110 
  111         if step is not None:
  112             engine.add_event_handler(step, self.step)
  113 
  114         return self
  115 
  116     def reset(self, *args: Any) -> "Timer":
  117         """Reset the timer to zero."""
  118         self._t0 = perf_counter()
  119         self.total = 0.0
  120         self.step_count = 0.0
  121         self.running = True
  122 
  123         return self
  124 
  125     def pause(self, *args: Any) -> None:
  126         """Pause the current running timer."""
  127         if self.running:
  128             self.total += self._elapsed()
  129             self.running = False
  130 
  131     def resume(self, *args: Any) -> None:
  132         """Resume the current running timer."""
  133         if not self.running:
  134             self.running = True
  135             self._t0 = perf_counter()
  136 
  137     def value(self) -> float:
  138         """Return the average timer value."""
  139         total = self.total
  140         if self.running:
  141             total += self._elapsed()
  142 
  143         if self._average:
  144             denominator = max(self.step_count, 1.0)
  145         else:
  146             denominator = 1.0
  147 
  148         return total / denominator
  149 
  150     def step(self, *args: Any) -> None:
  151         """Increment the timer."""
  152         self.step_count += 1.0
  153 
  154     def _elapsed(self) -> float:
  155         return perf_counter() - self._t0
  156
  ```
  --- 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/handlers/timing.py b/ignite/handlers/timing.py
  --- a/ignite/handlers/timing.py
  +++ b/ignite/handlers/timing.py
  @@ -70,7 +70,7 @@
           >>> trainer = Engine(training_update_function)
           >>> timer = Timer(average=True)
           >>> timer.attach(trainer,
  -        ...              start=Events.EPOCH_STARTED,
  +        ...              start=Events.STARTED,
           ...              resume=Events.ITERATION_STARTED,
           ...              pause=Events.ITERATION_COMPLETED,
           ...              step=Events.ITERATION_COMPLETED)
  
verification_info: {"golden_diff": "diff --git a/ignite/handlers/timing.py b/ignite/handlers/timing.py\n--- a/ignite/handlers/timing.py\n+++ b/ignite/handlers/timing.py\n@@ -70,7 +70,7 @@\n         >>> trainer = Engine(training_update_function)\n         >>> timer = Timer(average=True)\n         >>> timer.attach(trainer,\n-        ...              start=Events.EPOCH_STARTED,\n+        ...              start=Events.STARTED,\n         ...              resume=Events.ITERATION_STARTED,\n         ...              pause=Events.ITERATION_COMPLETED,\n         ...              step=Events.ITERATION_COMPLETED)\n", "issue": "Improve the example of Timer's usage\n## \ud83d\udcda Documentation\r\n\r\nThe example in the `Timer's documentation suggest to estimate the processing time for a batch as follows:\r\n```python\r\ntimer.attach(\r\n    trainer, \r\n    start=Events.EPOCH_STARTED, \r\n    resume=Events.ITERATION_STARTED, \r\n    pause=Events.ITERATION_COMPLETED, \r\n    step=Events.ITERATION_COMPLETED)\r\n```\r\nIt is to note that this timer will be reset at the start of each epoch. When we use multiple workers in the data loader, the first couple of iterations at each epoch often take longer than the later ones. The reset behavior will incur an inaccurate estimation of the remaining training time (ETA), even when the `average` flag is set to `True`. Specifically, the ETA is computed as `(engine.state.max_iters - engine.state.iteration) * time_per_iter`. So the small fluctuation in `time_per_iter` will be magnified by remaining number of iterations. To address this problem, we can let the timer only start once in the whole training process:\r\n```python\r\n timer.attach(\r\n    trainer, \r\n    start=Events.EPOCH_STARTED(once=1), \r\n    resume=Events.ITERATION_STARTED, \r\n    pause=Events.ITERATION_COMPLETED, \r\n    step=Events.ITERATION_COMPLETED)\r\n```\r\nI have empirically verified the effectiveness of this modification.\n", "before_files": [{"content": "from time import perf_counter\nfrom typing import Any, Optional\n\nfrom ignite.engine import Engine, Events\n\n__all__ = [\"Timer\"]\n\n\nclass Timer:\n    \"\"\" Timer object can be used to measure (average) time between events.\n\n    Args:\n        average: if True, then when ``.value()`` method is called, the returned value\n            will be equal to total time measured, divided by the value of internal counter.\n\n    Attributes:\n        total (float): total time elapsed when the Timer was running (in seconds).\n        step_count (int): internal counter, useful to measure average time, e.g. of processing a single batch.\n            Incremented with the ``.step()`` method.\n        running (bool): flag indicating if timer is measuring time.\n\n    Note:\n        When using ``Timer(average=True)`` do not forget to call ``timer.step()`` every time an event occurs. See\n        the examples below.\n\n    Examples:\n\n        Measuring total time of the epoch:\n\n        >>> from ignite.handlers import Timer\n        >>> import time\n        >>> work = lambda : time.sleep(0.1)\n        >>> idle = lambda : time.sleep(0.1)\n        >>> t = Timer(average=False)\n        >>> for _ in range(10):\n        ...    work()\n        ...    idle()\n        ...\n        >>> t.value()\n        2.003073937026784\n\n        Measuring average time of the epoch:\n\n        >>> t = Timer(average=True)\n        >>> for _ in range(10):\n        ...    work()\n        ...    idle()\n        ...    t.step()\n        ...\n        >>> t.value()\n        0.2003182829997968\n\n        Measuring average time it takes to execute a single ``work()`` call:\n\n        >>> t = Timer(average=True)\n        >>> for _ in range(10):\n        ...    t.resume()\n        ...    work()\n        ...    t.pause()\n        ...    idle()\n        ...    t.step()\n        ...\n        >>> t.value()\n        0.10016545779653825\n\n        Using the Timer to measure average time it takes to process a single batch of examples:\n\n        >>> from ignite.engine import Engine, Events\n        >>> from ignite.handlers import Timer\n        >>> trainer = Engine(training_update_function)\n        >>> timer = Timer(average=True)\n        >>> timer.attach(trainer,\n        ...              start=Events.EPOCH_STARTED,\n        ...              resume=Events.ITERATION_STARTED,\n        ...              pause=Events.ITERATION_COMPLETED,\n        ...              step=Events.ITERATION_COMPLETED)\n    \"\"\"\n\n    def __init__(self, average: bool = False):\n        self._average = average\n\n        self.reset()\n\n    def attach(\n        self,\n        engine: Engine,\n        start: Events = Events.STARTED,\n        pause: Events = Events.COMPLETED,\n        resume: Optional[Events] = None,\n        step: Optional[Events] = None,\n    ) -> \"Timer\":\n        \"\"\" Register callbacks to control the timer.\n\n        Args:\n            engine: Engine that this timer will be attached to.\n            start: Event which should start (reset) the timer.\n            pause: Event which should pause the timer.\n            resume: Event which should resume the timer.\n            step: Event which should call the `step` method of the counter.\n\n        Returns:\n            this timer\n        \"\"\"\n\n        engine.add_event_handler(start, self.reset)\n        engine.add_event_handler(pause, self.pause)\n\n        if resume is not None:\n            engine.add_event_handler(resume, self.resume)\n\n        if step is not None:\n            engine.add_event_handler(step, self.step)\n\n        return self\n\n    def reset(self, *args: Any) -> \"Timer\":\n        \"\"\"Reset the timer to zero.\"\"\"\n        self._t0 = perf_counter()\n        self.total = 0.0\n        self.step_count = 0.0\n        self.running = True\n\n        return self\n\n    def pause(self, *args: Any) -> None:\n        \"\"\"Pause the current running timer.\"\"\"\n        if self.running:\n            self.total += self._elapsed()\n            self.running = False\n\n    def resume(self, *args: Any) -> None:\n        \"\"\"Resume the current running timer.\"\"\"\n        if not self.running:\n            self.running = True\n            self._t0 = perf_counter()\n\n    def value(self) -> float:\n        \"\"\"Return the average timer value.\"\"\"\n        total = self.total\n        if self.running:\n            total += self._elapsed()\n\n        if self._average:\n            denominator = max(self.step_count, 1.0)\n        else:\n            denominator = 1.0\n\n        return total / denominator\n\n    def step(self, *args: Any) -> None:\n        \"\"\"Increment the timer.\"\"\"\n        self.step_count += 1.0\n\n    def _elapsed(self) -> float:\n        return perf_counter() - self._t0\n", "path": "ignite/handlers/timing.py"}], "after_files": [{"content": "from time import perf_counter\nfrom typing import Any, Optional\n\nfrom ignite.engine import Engine, Events\n\n__all__ = [\"Timer\"]\n\n\nclass Timer:\n    \"\"\" Timer object can be used to measure (average) time between events.\n\n    Args:\n        average: if True, then when ``.value()`` method is called, the returned value\n            will be equal to total time measured, divided by the value of internal counter.\n\n    Attributes:\n        total (float): total time elapsed when the Timer was running (in seconds).\n        step_count (int): internal counter, useful to measure average time, e.g. of processing a single batch.\n            Incremented with the ``.step()`` method.\n        running (bool): flag indicating if timer is measuring time.\n\n    Note:\n        When using ``Timer(average=True)`` do not forget to call ``timer.step()`` every time an event occurs. See\n        the examples below.\n\n    Examples:\n\n        Measuring total time of the epoch:\n\n        >>> from ignite.handlers import Timer\n        >>> import time\n        >>> work = lambda : time.sleep(0.1)\n        >>> idle = lambda : time.sleep(0.1)\n        >>> t = Timer(average=False)\n        >>> for _ in range(10):\n        ...    work()\n        ...    idle()\n        ...\n        >>> t.value()\n        2.003073937026784\n\n        Measuring average time of the epoch:\n\n        >>> t = Timer(average=True)\n        >>> for _ in range(10):\n        ...    work()\n        ...    idle()\n        ...    t.step()\n        ...\n        >>> t.value()\n        0.2003182829997968\n\n        Measuring average time it takes to execute a single ``work()`` call:\n\n        >>> t = Timer(average=True)\n        >>> for _ in range(10):\n        ...    t.resume()\n        ...    work()\n        ...    t.pause()\n        ...    idle()\n        ...    t.step()\n        ...\n        >>> t.value()\n        0.10016545779653825\n\n        Using the Timer to measure average time it takes to process a single batch of examples:\n\n        >>> from ignite.engine import Engine, Events\n        >>> from ignite.handlers import Timer\n        >>> trainer = Engine(training_update_function)\n        >>> timer = Timer(average=True)\n        >>> timer.attach(trainer,\n        ...              start=Events.STARTED,\n        ...              resume=Events.ITERATION_STARTED,\n        ...              pause=Events.ITERATION_COMPLETED,\n        ...              step=Events.ITERATION_COMPLETED)\n    \"\"\"\n\n    def __init__(self, average: bool = False):\n        self._average = average\n\n        self.reset()\n\n    def attach(\n        self,\n        engine: Engine,\n        start: Events = Events.STARTED,\n        pause: Events = Events.COMPLETED,\n        resume: Optional[Events] = None,\n        step: Optional[Events] = None,\n    ) -> \"Timer\":\n        \"\"\" Register callbacks to control the timer.\n\n        Args:\n            engine: Engine that this timer will be attached to.\n            start: Event which should start (reset) the timer.\n            pause: Event which should pause the timer.\n            resume: Event which should resume the timer.\n            step: Event which should call the `step` method of the counter.\n\n        Returns:\n            this timer\n        \"\"\"\n\n        engine.add_event_handler(start, self.reset)\n        engine.add_event_handler(pause, self.pause)\n\n        if resume is not None:\n            engine.add_event_handler(resume, self.resume)\n\n        if step is not None:\n            engine.add_event_handler(step, self.step)\n\n        return self\n\n    def reset(self, *args: Any) -> \"Timer\":\n        \"\"\"Reset the timer to zero.\"\"\"\n        self._t0 = perf_counter()\n        self.total = 0.0\n        self.step_count = 0.0\n        self.running = True\n\n        return self\n\n    def pause(self, *args: Any) -> None:\n        \"\"\"Pause the current running timer.\"\"\"\n        if self.running:\n            self.total += self._elapsed()\n            self.running = False\n\n    def resume(self, *args: Any) -> None:\n        \"\"\"Resume the current running timer.\"\"\"\n        if not self.running:\n            self.running = True\n            self._t0 = perf_counter()\n\n    def value(self) -> float:\n        \"\"\"Return the average timer value.\"\"\"\n        total = self.total\n        if self.running:\n            total += self._elapsed()\n\n        if self._average:\n            denominator = max(self.step_count, 1.0)\n        else:\n            denominator = 1.0\n\n        return total / denominator\n\n    def step(self, *args: Any) -> None:\n        \"\"\"Increment the timer.\"\"\"\n        self.step_count += 1.0\n\n    def _elapsed(self) -> float:\n        return perf_counter() - self._t0\n", "path": "ignite/handlers/timing.py"}]}