We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ProgressBar does not close the bar on Colab if every is used
## 🐛 Bug description

Progress bar is set with `common.setup_common_training_handlers(... log_every_iters=15, ...)` and it does not close itself as being not terminated ...

<img width="451" alt="Screen Shot 2020-06-09 at 16 34 53" src="https://user-images.githubusercontent.com/2459423/84161178-48effa80-aa6f-11ea-9fd1-5b6c673c940f.png">

## Environment

 - PyTorch Version (e.g., 1.4): 
 - Ignite Version (e.g., 0.3.0):
 - OS (e.g., Linux):
 - How you installed Ignite (`conda`, `pip`, source):
 - Python version:
 - Any other relevant information:


--- 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/contrib/handlers/tqdm_logger.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 import warnings
3 from typing import Any, Mapping
4 
5 import torch
6 
7 from ignite.contrib.handlers.base_logger import BaseLogger, BaseOutputHandler
8 from ignite.engine import Engine, Events
9 from ignite.engine.events import CallableEventWithFilter
10 
11 
12 class _OutputHandler(BaseOutputHandler):
13     """Helper handler to log engine's output and/or metrics
14 
15     Args:
16         description (str): progress bar description.
17         metric_names (list of str, optional): list of metric names to plot or a string "all" to plot all available
18             metrics.
19         output_transform (callable, optional): output transform function to prepare `engine.state.output` as a number.
20             For example, `output_transform = lambda output: output`
21             This function can also return a dictionary, e.g `{'loss': loss1, 'another_loss': loss2}` to label the plot
22             with corresponding keys.
23         closing_event_name: event's name on which the progress bar is closed. Valid events are from
24             :class:`~ignite.engine.events.Events` or any `event_name` added by
25             :meth:`~ignite.engine.engine.Engine.register_events`.
26 
27     """
28 
29     def __init__(
30         self, description, metric_names=None, output_transform=None, closing_event_name=Events.EPOCH_COMPLETED
31     ):
32         if metric_names is None and output_transform is None:
33             # This helps to avoid 'Either metric_names or output_transform should be defined' of BaseOutputHandler
34             metric_names = []
35         super(_OutputHandler, self).__init__(description, metric_names, output_transform, global_step_transform=None)
36         self.closing_event_name = closing_event_name
37 
38     @staticmethod
39     def get_max_number_events(event_name, engine):
40         if event_name in (Events.ITERATION_STARTED, Events.ITERATION_COMPLETED):
41             return engine.state.epoch_length
42         if event_name in (Events.EPOCH_STARTED, Events.EPOCH_COMPLETED):
43             return engine.state.max_epochs
44         return 1
45 
46     def __call__(self, engine, logger, event_name):
47 
48         pbar_total = self.get_max_number_events(event_name, engine)
49         if logger.pbar is None:
50             logger._reset(pbar_total=pbar_total)
51 
52         desc = self.tag
53         max_num_of_closing_events = self.get_max_number_events(self.closing_event_name, engine)
54         if max_num_of_closing_events > 1:
55             global_step = engine.state.get_event_attrib_value(self.closing_event_name)
56             desc += " [{}/{}]".format(global_step, max_num_of_closing_events)
57         logger.pbar.set_description(desc)
58 
59         metrics = self._setup_output_metrics(engine)
60 
61         rendered_metrics = {}
62         for key, value in metrics.items():
63             if isinstance(value, torch.Tensor):
64                 if value.ndimension() == 0:
65                     rendered_metrics[key] = value.item()
66                 elif value.ndimension() == 1:
67                     for i, v in enumerate(value):
68                         k = "{}_{}".format(key, i)
69                         rendered_metrics[k] = v.item()
70                 else:
71                     warnings.warn("ProgressBar can not log " "tensor with {} dimensions".format(value.ndimension()))
72             else:
73                 rendered_metrics[key] = value
74 
75         if rendered_metrics:
76             logger.pbar.set_postfix(**rendered_metrics)
77 
78         global_step = engine.state.get_event_attrib_value(event_name)
79         if pbar_total is not None:
80             global_step = (global_step - 1) % pbar_total + 1
81         logger.pbar.update(global_step - logger.pbar.n)
82 
83 
84 class ProgressBar(BaseLogger):
85     """
86     TQDM progress bar handler to log training progress and computed metrics.
87 
88     Args:
89         persist (bool, optional): set to ``True`` to persist the progress bar after completion (default = ``False``)
90         bar_format  (str, optional): Specify a custom bar string formatting. May impact performance.
91             [default: '{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]'].
92             Set to ``None`` to use ``tqdm`` default bar formatting: '{l_bar}{bar}{r_bar}', where
93             l_bar='{desc}: {percentage:3.0f}%|' and
94             r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'. For more details on the
95             formatting, see `tqdm docs <https://tqdm.github.io/docs/tqdm/>`_.
96         **tqdm_kwargs: kwargs passed to tqdm progress bar.
97             By default, progress bar description displays "Epoch [5/10]" where 5 is the current epoch and 10 is the
98             number of epochs. If tqdm_kwargs defines `desc`, e.g. "Predictions", than the description is
99             "Predictions [5/10]" if number of epochs is more than one otherwise it is simply "Predictions".
100 
101     Examples:
102 
103         Simple progress bar
104 
105         .. code-block:: python
106 
107             trainer = create_supervised_trainer(model, optimizer, loss)
108 
109             pbar = ProgressBar()
110             pbar.attach(trainer)
111 
112             # Progress bar will looks like
113             # Epoch [2/50]: [64/128]  50%|█████      [06:17<12:34]
114 
115         Log output to a file instead of stderr (tqdm's default output)
116 
117         .. code-block:: python
118 
119             trainer = create_supervised_trainer(model, optimizer, loss)
120 
121             log_file = open("output.log", "w")
122             pbar = ProgressBar(file=log_file)
123             pbar.attach(trainer)
124 
125         Attach metrics that already have been computed at :attr:`~ignite.engine.events.Events.ITERATION_COMPLETED`
126         (such as :class:`~ignite.metrics.RunningAverage`)
127 
128         .. code-block:: python
129 
130             trainer = create_supervised_trainer(model, optimizer, loss)
131 
132             RunningAverage(output_transform=lambda x: x).attach(trainer, 'loss')
133 
134             pbar = ProgressBar()
135             pbar.attach(trainer, ['loss'])
136 
137             # Progress bar will looks like
138             # Epoch [2/50]: [64/128]  50%|█████      , loss=0.123 [06:17<12:34]
139 
140         Directly attach the engine's output
141 
142         .. code-block:: python
143 
144             trainer = create_supervised_trainer(model, optimizer, loss)
145 
146             pbar = ProgressBar()
147             pbar.attach(trainer, output_transform=lambda x: {'loss': x})
148 
149             # Progress bar will looks like
150             # Epoch [2/50]: [64/128]  50%|█████      , loss=0.123 [06:17<12:34]
151 
152     Note:
153         When adding attaching the progress bar to an engine, it is recommend that you replace
154         every print operation in the engine's handlers triggered every iteration with
155         ``pbar.log_message`` to guarantee the correct format of the stdout.
156 
157     Note:
158         When using inside jupyter notebook, `ProgressBar` automatically uses `tqdm_notebook`. For correct rendering,
159         please install `ipywidgets <https://ipywidgets.readthedocs.io/en/stable/user_install.html#installation>`_.
160         Due to `tqdm notebook bugs <https://github.com/tqdm/tqdm/issues/594>`_, bar format may be needed to be set
161         to an empty string value.
162 
163     """
164 
165     _events_order = [
166         Events.STARTED,
167         Events.EPOCH_STARTED,
168         Events.ITERATION_STARTED,
169         Events.ITERATION_COMPLETED,
170         Events.EPOCH_COMPLETED,
171         Events.COMPLETED,
172     ]
173 
174     def __init__(
175         self,
176         persist=False,
177         bar_format="{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]",
178         **tqdm_kwargs
179     ):
180 
181         try:
182             from tqdm.autonotebook import tqdm
183         except ImportError:
184             raise RuntimeError(
185                 "This contrib module requires tqdm to be installed. "
186                 "Please install it with command: \n pip install tqdm"
187             )
188 
189         self.pbar_cls = tqdm
190         self.pbar = None
191         self.persist = persist
192         self.bar_format = bar_format
193         self.tqdm_kwargs = tqdm_kwargs
194 
195     def _reset(self, pbar_total):
196         self.pbar = self.pbar_cls(
197             total=pbar_total, leave=self.persist, bar_format=self.bar_format, initial=1, **self.tqdm_kwargs
198         )
199 
200     def _close(self, engine):
201         if self.pbar is not None:
202             self.pbar.close()
203         self.pbar = None
204 
205     @staticmethod
206     def _compare_lt(event1, event2):
207         i1 = ProgressBar._events_order.index(event1)
208         i2 = ProgressBar._events_order.index(event2)
209         return i1 < i2
210 
211     def log_message(self, message):
212         """
213         Logs a message, preserving the progress bar correct output format.
214 
215         Args:
216             message (str): string you wish to log.
217         """
218         from tqdm import tqdm
219 
220         tqdm.write(message, file=self.tqdm_kwargs.get("file", None))
221 
222     def attach(
223         self,
224         engine,
225         metric_names=None,
226         output_transform=None,
227         event_name=Events.ITERATION_COMPLETED,
228         closing_event_name=Events.EPOCH_COMPLETED,
229     ):
230         """
231         Attaches the progress bar to an engine object.
232 
233         Args:
234             engine (Engine): engine object.
235             metric_names (list of str, optional): list of metric names to plot or a string "all" to plot all available
236                 metrics.
237             output_transform (callable, optional): a function to select what you want to print from the engine's
238                 output. This function may return either a dictionary with entries in the format of ``{name: value}``,
239                 or a single scalar, which will be displayed with the default name `output`.
240             event_name: event's name on which the progress bar advances. Valid events are from
241                 :class:`~ignite.engine.events.Events`.
242             closing_event_name: event's name on which the progress bar is closed. Valid events are from
243                 :class:`~ignite.engine.events.Events`.
244 
245         Note: accepted output value types are numbers, 0d and 1d torch tensors and strings
246 
247         """
248         desc = self.tqdm_kwargs.get("desc", "Epoch")
249 
250         if event_name not in engine._allowed_events:
251             raise ValueError("Logging event {} is not in allowed events for this engine".format(event_name.name))
252 
253         if isinstance(closing_event_name, CallableEventWithFilter):
254             if closing_event_name.filter != CallableEventWithFilter.default_event_filter:
255                 raise ValueError("Closing Event should not be a filtered event")
256 
257         if not self._compare_lt(event_name, closing_event_name):
258             raise ValueError(
259                 "Logging event {} should be called before closing event {}".format(event_name, closing_event_name)
260             )
261 
262         log_handler = _OutputHandler(desc, metric_names, output_transform, closing_event_name=closing_event_name)
263 
264         super(ProgressBar, self).attach(engine, log_handler, event_name)
265         engine.add_event_handler(closing_event_name, self._close)
266 
267     def attach_opt_params_handler(self, engine: Engine, event_name: str, *args: Any, **kwargs: Mapping):
268         """Intentionally empty"""
269         pass
270 
271     def _create_output_handler(self, *args, **kwargs):
272         return _OutputHandler(*args, **kwargs)
273 
274     def _create_opt_params_handler(self, *args, **kwargs):
275         """Intentionally empty"""
276         pass
277
```
--- 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/contrib/handlers/tqdm_logger.py b/ignite/contrib/handlers/tqdm_logger.py
--- a/ignite/contrib/handlers/tqdm_logger.py
+++ b/ignite/contrib/handlers/tqdm_logger.py
@@ -199,6 +199,11 @@
 
     def _close(self, engine):
         if self.pbar is not None:
+            # https://github.com/tqdm/notebook.py#L240-L250
+            # issue #1115 : notebook backend of tqdm checks if n < total (error or KeyboardInterrupt)
+            # and the bar persists in 'danger' mode
+            if self.pbar.total is not None:
+                self.pbar.n = self.pbar.total
             self.pbar.close()
         self.pbar = None

{"golden_diff": "diff --git a/ignite/contrib/handlers/tqdm_logger.py b/ignite/contrib/handlers/tqdm_logger.py\n--- a/ignite/contrib/handlers/tqdm_logger.py\n+++ b/ignite/contrib/handlers/tqdm_logger.py\n@@ -199,6 +199,11 @@\n \n     def _close(self, engine):\n         if self.pbar is not None:\n+            # https://github.com/tqdm/notebook.py#L240-L250\n+            # issue #1115 : notebook backend of tqdm checks if n < total (error or KeyboardInterrupt)\n+            # and the bar persists in 'danger' mode\n+            if self.pbar.total is not None:\n+                self.pbar.n = self.pbar.total\n             self.pbar.close()\n         self.pbar = None\n", "issue": "ProgressBar does not close the bar on Colab if every is used\n## \ud83d\udc1b Bug description\r\n\r\nProgress bar is set with `common.setup_common_training_handlers(... log_every_iters=15, ...)` and it does not close itself as being not terminated ...\r\n\r\n<img width=\"451\" alt=\"Screen Shot 2020-06-09 at 16 34 53\" src=\"https://user-images.githubusercontent.com/2459423/84161178-48effa80-aa6f-11ea-9fd1-5b6c673c940f.png\">\r\n\r\n## Environment\r\n\r\n - PyTorch Version (e.g., 1.4): \r\n - Ignite Version (e.g., 0.3.0):\r\n - OS (e.g., Linux):\r\n - How you installed Ignite (`conda`, `pip`, source):\r\n - Python version:\r\n - Any other relevant information:\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport warnings\nfrom typing import Any, Mapping\n\nimport torch\n\nfrom ignite.contrib.handlers.base_logger import BaseLogger, BaseOutputHandler\nfrom ignite.engine import Engine, Events\nfrom ignite.engine.events import CallableEventWithFilter\n\n\nclass _OutputHandler(BaseOutputHandler):\n    \"\"\"Helper handler to log engine's output and/or metrics\n\n    Args:\n        description (str): progress bar description.\n        metric_names (list of str, optional): list of metric names to plot or a string \"all\" to plot all available\n            metrics.\n        output_transform (callable, optional): output transform function to prepare `engine.state.output` as a number.\n            For example, `output_transform = lambda output: output`\n            This function can also return a dictionary, e.g `{'loss': loss1, 'another_loss': loss2}` to label the plot\n            with corresponding keys.\n        closing_event_name: event's name on which the progress bar is closed. Valid events are from\n            :class:`~ignite.engine.events.Events` or any `event_name` added by\n            :meth:`~ignite.engine.engine.Engine.register_events`.\n\n    \"\"\"\n\n    def __init__(\n        self, description, metric_names=None, output_transform=None, closing_event_name=Events.EPOCH_COMPLETED\n    ):\n        if metric_names is None and output_transform is None:\n            # This helps to avoid 'Either metric_names or output_transform should be defined' of BaseOutputHandler\n            metric_names = []\n        super(_OutputHandler, self).__init__(description, metric_names, output_transform, global_step_transform=None)\n        self.closing_event_name = closing_event_name\n\n    @staticmethod\n    def get_max_number_events(event_name, engine):\n        if event_name in (Events.ITERATION_STARTED, Events.ITERATION_COMPLETED):\n            return engine.state.epoch_length\n        if event_name in (Events.EPOCH_STARTED, Events.EPOCH_COMPLETED):\n            return engine.state.max_epochs\n        return 1\n\n    def __call__(self, engine, logger, event_name):\n\n        pbar_total = self.get_max_number_events(event_name, engine)\n        if logger.pbar is None:\n            logger._reset(pbar_total=pbar_total)\n\n        desc = self.tag\n        max_num_of_closing_events = self.get_max_number_events(self.closing_event_name, engine)\n        if max_num_of_closing_events > 1:\n            global_step = engine.state.get_event_attrib_value(self.closing_event_name)\n            desc += \" [{}/{}]\".format(global_step, max_num_of_closing_events)\n        logger.pbar.set_description(desc)\n\n        metrics = self._setup_output_metrics(engine)\n\n        rendered_metrics = {}\n        for key, value in metrics.items():\n            if isinstance(value, torch.Tensor):\n                if value.ndimension() == 0:\n                    rendered_metrics[key] = value.item()\n                elif value.ndimension() == 1:\n                    for i, v in enumerate(value):\n                        k = \"{}_{}\".format(key, i)\n                        rendered_metrics[k] = v.item()\n                else:\n                    warnings.warn(\"ProgressBar can not log \" \"tensor with {} dimensions\".format(value.ndimension()))\n            else:\n                rendered_metrics[key] = value\n\n        if rendered_metrics:\n            logger.pbar.set_postfix(**rendered_metrics)\n\n        global_step = engine.state.get_event_attrib_value(event_name)\n        if pbar_total is not None:\n            global_step = (global_step - 1) % pbar_total + 1\n        logger.pbar.update(global_step - logger.pbar.n)\n\n\nclass ProgressBar(BaseLogger):\n    \"\"\"\n    TQDM progress bar handler to log training progress and computed metrics.\n\n    Args:\n        persist (bool, optional): set to ``True`` to persist the progress bar after completion (default = ``False``)\n        bar_format  (str, optional): Specify a custom bar string formatting. May impact performance.\n            [default: '{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]'].\n            Set to ``None`` to use ``tqdm`` default bar formatting: '{l_bar}{bar}{r_bar}', where\n            l_bar='{desc}: {percentage:3.0f}%|' and\n            r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'. For more details on the\n            formatting, see `tqdm docs <https://tqdm.github.io/docs/tqdm/>`_.\n        **tqdm_kwargs: kwargs passed to tqdm progress bar.\n            By default, progress bar description displays \"Epoch [5/10]\" where 5 is the current epoch and 10 is the\n            number of epochs. If tqdm_kwargs defines `desc`, e.g. \"Predictions\", than the description is\n            \"Predictions [5/10]\" if number of epochs is more than one otherwise it is simply \"Predictions\".\n\n    Examples:\n\n        Simple progress bar\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            pbar = ProgressBar()\n            pbar.attach(trainer)\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      [06:17<12:34]\n\n        Log output to a file instead of stderr (tqdm's default output)\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            log_file = open(\"output.log\", \"w\")\n            pbar = ProgressBar(file=log_file)\n            pbar.attach(trainer)\n\n        Attach metrics that already have been computed at :attr:`~ignite.engine.events.Events.ITERATION_COMPLETED`\n        (such as :class:`~ignite.metrics.RunningAverage`)\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            RunningAverage(output_transform=lambda x: x).attach(trainer, 'loss')\n\n            pbar = ProgressBar()\n            pbar.attach(trainer, ['loss'])\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      , loss=0.123 [06:17<12:34]\n\n        Directly attach the engine's output\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            pbar = ProgressBar()\n            pbar.attach(trainer, output_transform=lambda x: {'loss': x})\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      , loss=0.123 [06:17<12:34]\n\n    Note:\n        When adding attaching the progress bar to an engine, it is recommend that you replace\n        every print operation in the engine's handlers triggered every iteration with\n        ``pbar.log_message`` to guarantee the correct format of the stdout.\n\n    Note:\n        When using inside jupyter notebook, `ProgressBar` automatically uses `tqdm_notebook`. For correct rendering,\n        please install `ipywidgets <https://ipywidgets.readthedocs.io/en/stable/user_install.html#installation>`_.\n        Due to `tqdm notebook bugs <https://github.com/tqdm/tqdm/issues/594>`_, bar format may be needed to be set\n        to an empty string value.\n\n    \"\"\"\n\n    _events_order = [\n        Events.STARTED,\n        Events.EPOCH_STARTED,\n        Events.ITERATION_STARTED,\n        Events.ITERATION_COMPLETED,\n        Events.EPOCH_COMPLETED,\n        Events.COMPLETED,\n    ]\n\n    def __init__(\n        self,\n        persist=False,\n        bar_format=\"{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]\",\n        **tqdm_kwargs\n    ):\n\n        try:\n            from tqdm.autonotebook import tqdm\n        except ImportError:\n            raise RuntimeError(\n                \"This contrib module requires tqdm to be installed. \"\n                \"Please install it with command: \\n pip install tqdm\"\n            )\n\n        self.pbar_cls = tqdm\n        self.pbar = None\n        self.persist = persist\n        self.bar_format = bar_format\n        self.tqdm_kwargs = tqdm_kwargs\n\n    def _reset(self, pbar_total):\n        self.pbar = self.pbar_cls(\n            total=pbar_total, leave=self.persist, bar_format=self.bar_format, initial=1, **self.tqdm_kwargs\n        )\n\n    def _close(self, engine):\n        if self.pbar is not None:\n            self.pbar.close()\n        self.pbar = None\n\n    @staticmethod\n    def _compare_lt(event1, event2):\n        i1 = ProgressBar._events_order.index(event1)\n        i2 = ProgressBar._events_order.index(event2)\n        return i1 < i2\n\n    def log_message(self, message):\n        \"\"\"\n        Logs a message, preserving the progress bar correct output format.\n\n        Args:\n            message (str): string you wish to log.\n        \"\"\"\n        from tqdm import tqdm\n\n        tqdm.write(message, file=self.tqdm_kwargs.get(\"file\", None))\n\n    def attach(\n        self,\n        engine,\n        metric_names=None,\n        output_transform=None,\n        event_name=Events.ITERATION_COMPLETED,\n        closing_event_name=Events.EPOCH_COMPLETED,\n    ):\n        \"\"\"\n        Attaches the progress bar to an engine object.\n\n        Args:\n            engine (Engine): engine object.\n            metric_names (list of str, optional): list of metric names to plot or a string \"all\" to plot all available\n                metrics.\n            output_transform (callable, optional): a function to select what you want to print from the engine's\n                output. This function may return either a dictionary with entries in the format of ``{name: value}``,\n                or a single scalar, which will be displayed with the default name `output`.\n            event_name: event's name on which the progress bar advances. Valid events are from\n                :class:`~ignite.engine.events.Events`.\n            closing_event_name: event's name on which the progress bar is closed. Valid events are from\n                :class:`~ignite.engine.events.Events`.\n\n        Note: accepted output value types are numbers, 0d and 1d torch tensors and strings\n\n        \"\"\"\n        desc = self.tqdm_kwargs.get(\"desc\", \"Epoch\")\n\n        if event_name not in engine._allowed_events:\n            raise ValueError(\"Logging event {} is not in allowed events for this engine\".format(event_name.name))\n\n        if isinstance(closing_event_name, CallableEventWithFilter):\n            if closing_event_name.filter != CallableEventWithFilter.default_event_filter:\n                raise ValueError(\"Closing Event should not be a filtered event\")\n\n        if not self._compare_lt(event_name, closing_event_name):\n            raise ValueError(\n                \"Logging event {} should be called before closing event {}\".format(event_name, closing_event_name)\n            )\n\n        log_handler = _OutputHandler(desc, metric_names, output_transform, closing_event_name=closing_event_name)\n\n        super(ProgressBar, self).attach(engine, log_handler, event_name)\n        engine.add_event_handler(closing_event_name, self._close)\n\n    def attach_opt_params_handler(self, engine: Engine, event_name: str, *args: Any, **kwargs: Mapping):\n        \"\"\"Intentionally empty\"\"\"\n        pass\n\n    def _create_output_handler(self, *args, **kwargs):\n        return _OutputHandler(*args, **kwargs)\n\n    def _create_opt_params_handler(self, *args, **kwargs):\n        \"\"\"Intentionally empty\"\"\"\n        pass\n", "path": "ignite/contrib/handlers/tqdm_logger.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport warnings\nfrom typing import Any, Mapping\n\nimport torch\n\nfrom ignite.contrib.handlers.base_logger import BaseLogger, BaseOutputHandler\nfrom ignite.engine import Engine, Events\nfrom ignite.engine.events import CallableEventWithFilter\n\n\nclass _OutputHandler(BaseOutputHandler):\n    \"\"\"Helper handler to log engine's output and/or metrics\n\n    Args:\n        description (str): progress bar description.\n        metric_names (list of str, optional): list of metric names to plot or a string \"all\" to plot all available\n            metrics.\n        output_transform (callable, optional): output transform function to prepare `engine.state.output` as a number.\n            For example, `output_transform = lambda output: output`\n            This function can also return a dictionary, e.g `{'loss': loss1, 'another_loss': loss2}` to label the plot\n            with corresponding keys.\n        closing_event_name: event's name on which the progress bar is closed. Valid events are from\n            :class:`~ignite.engine.events.Events` or any `event_name` added by\n            :meth:`~ignite.engine.engine.Engine.register_events`.\n\n    \"\"\"\n\n    def __init__(\n        self, description, metric_names=None, output_transform=None, closing_event_name=Events.EPOCH_COMPLETED\n    ):\n        if metric_names is None and output_transform is None:\n            # This helps to avoid 'Either metric_names or output_transform should be defined' of BaseOutputHandler\n            metric_names = []\n        super(_OutputHandler, self).__init__(description, metric_names, output_transform, global_step_transform=None)\n        self.closing_event_name = closing_event_name\n\n    @staticmethod\n    def get_max_number_events(event_name, engine):\n        if event_name in (Events.ITERATION_STARTED, Events.ITERATION_COMPLETED):\n            return engine.state.epoch_length\n        if event_name in (Events.EPOCH_STARTED, Events.EPOCH_COMPLETED):\n            return engine.state.max_epochs\n        return 1\n\n    def __call__(self, engine, logger, event_name):\n\n        pbar_total = self.get_max_number_events(event_name, engine)\n        if logger.pbar is None:\n            logger._reset(pbar_total=pbar_total)\n\n        desc = self.tag\n        max_num_of_closing_events = self.get_max_number_events(self.closing_event_name, engine)\n        if max_num_of_closing_events > 1:\n            global_step = engine.state.get_event_attrib_value(self.closing_event_name)\n            desc += \" [{}/{}]\".format(global_step, max_num_of_closing_events)\n        logger.pbar.set_description(desc)\n\n        metrics = self._setup_output_metrics(engine)\n\n        rendered_metrics = {}\n        for key, value in metrics.items():\n            if isinstance(value, torch.Tensor):\n                if value.ndimension() == 0:\n                    rendered_metrics[key] = value.item()\n                elif value.ndimension() == 1:\n                    for i, v in enumerate(value):\n                        k = \"{}_{}\".format(key, i)\n                        rendered_metrics[k] = v.item()\n                else:\n                    warnings.warn(\"ProgressBar can not log \" \"tensor with {} dimensions\".format(value.ndimension()))\n            else:\n                rendered_metrics[key] = value\n\n        if rendered_metrics:\n            logger.pbar.set_postfix(**rendered_metrics)\n\n        global_step = engine.state.get_event_attrib_value(event_name)\n        if pbar_total is not None:\n            global_step = (global_step - 1) % pbar_total + 1\n        logger.pbar.update(global_step - logger.pbar.n)\n\n\nclass ProgressBar(BaseLogger):\n    \"\"\"\n    TQDM progress bar handler to log training progress and computed metrics.\n\n    Args:\n        persist (bool, optional): set to ``True`` to persist the progress bar after completion (default = ``False``)\n        bar_format  (str, optional): Specify a custom bar string formatting. May impact performance.\n            [default: '{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]'].\n            Set to ``None`` to use ``tqdm`` default bar formatting: '{l_bar}{bar}{r_bar}', where\n            l_bar='{desc}: {percentage:3.0f}%|' and\n            r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'. For more details on the\n            formatting, see `tqdm docs <https://tqdm.github.io/docs/tqdm/>`_.\n        **tqdm_kwargs: kwargs passed to tqdm progress bar.\n            By default, progress bar description displays \"Epoch [5/10]\" where 5 is the current epoch and 10 is the\n            number of epochs. If tqdm_kwargs defines `desc`, e.g. \"Predictions\", than the description is\n            \"Predictions [5/10]\" if number of epochs is more than one otherwise it is simply \"Predictions\".\n\n    Examples:\n\n        Simple progress bar\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            pbar = ProgressBar()\n            pbar.attach(trainer)\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      [06:17<12:34]\n\n        Log output to a file instead of stderr (tqdm's default output)\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            log_file = open(\"output.log\", \"w\")\n            pbar = ProgressBar(file=log_file)\n            pbar.attach(trainer)\n\n        Attach metrics that already have been computed at :attr:`~ignite.engine.events.Events.ITERATION_COMPLETED`\n        (such as :class:`~ignite.metrics.RunningAverage`)\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            RunningAverage(output_transform=lambda x: x).attach(trainer, 'loss')\n\n            pbar = ProgressBar()\n            pbar.attach(trainer, ['loss'])\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      , loss=0.123 [06:17<12:34]\n\n        Directly attach the engine's output\n\n        .. code-block:: python\n\n            trainer = create_supervised_trainer(model, optimizer, loss)\n\n            pbar = ProgressBar()\n            pbar.attach(trainer, output_transform=lambda x: {'loss': x})\n\n            # Progress bar will looks like\n            # Epoch [2/50]: [64/128]  50%|\u2588\u2588\u2588\u2588\u2588      , loss=0.123 [06:17<12:34]\n\n    Note:\n        When adding attaching the progress bar to an engine, it is recommend that you replace\n        every print operation in the engine's handlers triggered every iteration with\n        ``pbar.log_message`` to guarantee the correct format of the stdout.\n\n    Note:\n        When using inside jupyter notebook, `ProgressBar` automatically uses `tqdm_notebook`. For correct rendering,\n        please install `ipywidgets <https://ipywidgets.readthedocs.io/en/stable/user_install.html#installation>`_.\n        Due to `tqdm notebook bugs <https://github.com/tqdm/tqdm/issues/594>`_, bar format may be needed to be set\n        to an empty string value.\n\n    \"\"\"\n\n    _events_order = [\n        Events.STARTED,\n        Events.EPOCH_STARTED,\n        Events.ITERATION_STARTED,\n        Events.ITERATION_COMPLETED,\n        Events.EPOCH_COMPLETED,\n        Events.COMPLETED,\n    ]\n\n    def __init__(\n        self,\n        persist=False,\n        bar_format=\"{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]\",\n        **tqdm_kwargs\n    ):\n\n        try:\n            from tqdm.autonotebook import tqdm\n        except ImportError:\n            raise RuntimeError(\n                \"This contrib module requires tqdm to be installed. \"\n                \"Please install it with command: \\n pip install tqdm\"\n            )\n\n        self.pbar_cls = tqdm\n        self.pbar = None\n        self.persist = persist\n        self.bar_format = bar_format\n        self.tqdm_kwargs = tqdm_kwargs\n\n    def _reset(self, pbar_total):\n        self.pbar = self.pbar_cls(\n            total=pbar_total, leave=self.persist, bar_format=self.bar_format, initial=1, **self.tqdm_kwargs\n        )\n\n    def _close(self, engine):\n        if self.pbar is not None:\n            # https://github.com/tqdm/notebook.py#L240-L250\n            # issue #1115 : notebook backend of tqdm checks if n < total (error or KeyboardInterrupt)\n            # and the bar persists in 'danger' mode\n            if self.pbar.total is not None:\n                self.pbar.n = self.pbar.total\n            self.pbar.close()\n        self.pbar = None\n\n    @staticmethod\n    def _compare_lt(event1, event2):\n        i1 = ProgressBar._events_order.index(event1)\n        i2 = ProgressBar._events_order.index(event2)\n        return i1 < i2\n\n    def log_message(self, message):\n        \"\"\"\n        Logs a message, preserving the progress bar correct output format.\n\n        Args:\n            message (str): string you wish to log.\n        \"\"\"\n        from tqdm import tqdm\n\n        tqdm.write(message, file=self.tqdm_kwargs.get(\"file\", None))\n\n    def attach(\n        self,\n        engine,\n        metric_names=None,\n        output_transform=None,\n        event_name=Events.ITERATION_COMPLETED,\n        closing_event_name=Events.EPOCH_COMPLETED,\n    ):\n        \"\"\"\n        Attaches the progress bar to an engine object.\n\n        Args:\n            engine (Engine): engine object.\n            metric_names (list of str, optional): list of metric names to plot or a string \"all\" to plot all available\n                metrics.\n            output_transform (callable, optional): a function to select what you want to print from the engine's\n                output. This function may return either a dictionary with entries in the format of ``{name: value}``,\n                or a single scalar, which will be displayed with the default name `output`.\n            event_name: event's name on which the progress bar advances. Valid events are from\n                :class:`~ignite.engine.events.Events`.\n            closing_event_name: event's name on which the progress bar is closed. Valid events are from\n                :class:`~ignite.engine.events.Events`.\n\n        Note: accepted output value types are numbers, 0d and 1d torch tensors and strings\n\n        \"\"\"\n        desc = self.tqdm_kwargs.get(\"desc\", \"Epoch\")\n\n        if event_name not in engine._allowed_events:\n            raise ValueError(\"Logging event {} is not in allowed events for this engine\".format(event_name.name))\n\n        if isinstance(closing_event_name, CallableEventWithFilter):\n            if closing_event_name.filter != CallableEventWithFilter.default_event_filter:\n                raise ValueError(\"Closing Event should not be a filtered event\")\n\n        if not self._compare_lt(event_name, closing_event_name):\n            raise ValueError(\n                \"Logging event {} should be called before closing event {}\".format(event_name, closing_event_name)\n            )\n\n        log_handler = _OutputHandler(desc, metric_names, output_transform, closing_event_name=closing_event_name)\n\n        super(ProgressBar, self).attach(engine, log_handler, event_name)\n        engine.add_event_handler(closing_event_name, self._close)\n\n    def attach_opt_params_handler(self, engine: Engine, event_name: str, *args: Any, **kwargs: Mapping):\n        \"\"\"Intentionally empty\"\"\"\n        pass\n\n    def _create_output_handler(self, *args, **kwargs):\n        return _OutputHandler(*args, **kwargs)\n\n    def _create_opt_params_handler(self, *args, **kwargs):\n        \"\"\"Intentionally empty\"\"\"\n        pass\n", "path": "ignite/contrib/handlers/tqdm_logger.py"}]}