We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
log_message() method fails `desc` is passed to contrib tqdm
## 🐛 Bug description

If I pass a `desc` argument when instantiating a `ignite.contrib.handlers.ProgressBar` the calls to its `log_message()` method fail with this exception:

```
TypeError: write() got an unexpected keyword argument 'desc'
```

## Environment

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

{"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@@ -146,7 +146,8 @@\n             message (str): string you wish to log.\n         \"\"\"\n         from tqdm import tqdm\n-        tqdm.write(message, **self.tqdm_kwargs)\n+\n+        tqdm.write(message, file=self.tqdm_kwargs.get(\"file\", None))\n \n     def attach(self, engine, metric_names=None, output_transform=None,\n                event_name=Events.ITERATION_COMPLETED,\n", "issue": "log_message() method fails `desc` is passed to contrib tqdm\n## \ud83d\udc1b Bug description\r\n\r\nIf I pass a `desc` argument when instantiating a `ignite.contrib.handlers.ProgressBar` the calls to its `log_message()` method fail with this exception:\r\n\r\n```\r\nTypeError: write() got an unexpected keyword argument 'desc'\r\n```\r\n\r\n## Environment\r\n\r\n - PyTorch Version: 1.3.1\r\n - Ignite Version: 0.3.0\r\n - OS: Linux\r\n - How you installed Ignite (`conda`, `pip`, source): Conda\r\n - Python version: 3.7\r\n - Any other relevant information:\r\n\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport warnings\n\nimport torch\n\nfrom ignite.engine import Events\nfrom ignite.engine.engine import EventWithFilter\nfrom ignite.contrib.handlers.base_logger import BaseLogger, BaseOutputHandler\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.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__(self, persist=False,\n                 bar_format='{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]',\n                 **tqdm_kwargs):\n\n        try:\n            from tqdm.autonotebook import tqdm\n        except ImportError:\n            raise RuntimeError(\"This contrib module requires tqdm to be installed. \"\n                               \"Please install it with command: \\n pip install tqdm\")\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,\n            leave=self.persist,\n            bar_format=self.bar_format,\n            initial=1,\n            **self.tqdm_kwargs\n        )\n\n    def _close(self, engine):\n        if self.pbar:\n            self.pbar.close()\n        self.pbar = None\n\n    @staticmethod\n    def _compare_lt(event1, event2):\n        if isinstance(event1, EventWithFilter):\n            event1 = event1.event\n        if isinstance(event2, EventWithFilter):\n            event2 = event2.event\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        tqdm.write(message, **self.tqdm_kwargs)\n\n    def attach(self, engine, metric_names=None, output_transform=None,\n               event_name=Events.ITERATION_COMPLETED,\n               closing_event_name=Events.EPOCH_COMPLETED):\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`.\n            closing_event_name: event's name on which the progress bar is closed. Valid events are from\n                :class:`~ignite.engine.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 not isinstance(event_name, (Events, EventWithFilter)):\n            raise ValueError(\"Logging event should be only `ignite.engine.Events`\")\n\n        if isinstance(closing_event_name, EventWithFilter):\n            raise ValueError(\"Closing event should not use any event filter\")\n\n        if not self._compare_lt(event_name, closing_event_name):\n            raise ValueError(\"Logging event {} should be called before closing event {}\"\n                             .format(event_name, closing_event_name))\n\n        log_handler = _OutputHandler(desc, metric_names, output_transform,\n                                     closing_event_name=closing_event_name)\n        # if event_name is EventWithFilter, filter is passed here\n        super(ProgressBar, self).attach(engine, log_handler, event_name)\n        engine.add_event_handler(closing_event_name, self._close)\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` or any `event_name` added by\n            :meth:`~ignite.engine.Engine.register_events`.\n\n    \"\"\"\n\n    def __init__(self, description, metric_names=None, output_transform=None,\n                 closing_event_name=Events.EPOCH_COMPLETED):\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,\n                                             another_engine=None, 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 len(engine.state.dataloader)\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 \"\n                                  \"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        global_step = (global_step - 1) % pbar_total + 1\n        logger.pbar.update(global_step - logger.pbar.n)\n", "path": "ignite/contrib/handlers/tqdm_logger.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport warnings\n\nimport torch\n\nfrom ignite.engine import Events\nfrom ignite.engine.engine import EventWithFilter\nfrom ignite.contrib.handlers.base_logger import BaseLogger, BaseOutputHandler\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.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__(self, persist=False,\n                 bar_format='{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]',\n                 **tqdm_kwargs):\n\n        try:\n            from tqdm.autonotebook import tqdm\n        except ImportError:\n            raise RuntimeError(\"This contrib module requires tqdm to be installed. \"\n                               \"Please install it with command: \\n pip install tqdm\")\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,\n            leave=self.persist,\n            bar_format=self.bar_format,\n            initial=1,\n            **self.tqdm_kwargs\n        )\n\n    def _close(self, engine):\n        if self.pbar:\n            self.pbar.close()\n        self.pbar = None\n\n    @staticmethod\n    def _compare_lt(event1, event2):\n        if isinstance(event1, EventWithFilter):\n            event1 = event1.event\n        if isinstance(event2, EventWithFilter):\n            event2 = event2.event\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(self, engine, metric_names=None, output_transform=None,\n               event_name=Events.ITERATION_COMPLETED,\n               closing_event_name=Events.EPOCH_COMPLETED):\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`.\n            closing_event_name: event's name on which the progress bar is closed. Valid events are from\n                :class:`~ignite.engine.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 not isinstance(event_name, (Events, EventWithFilter)):\n            raise ValueError(\"Logging event should be only `ignite.engine.Events`\")\n\n        if isinstance(closing_event_name, EventWithFilter):\n            raise ValueError(\"Closing event should not use any event filter\")\n\n        if not self._compare_lt(event_name, closing_event_name):\n            raise ValueError(\"Logging event {} should be called before closing event {}\"\n                             .format(event_name, closing_event_name))\n\n        log_handler = _OutputHandler(desc, metric_names, output_transform,\n                                     closing_event_name=closing_event_name)\n        # if event_name is EventWithFilter, filter is passed here\n        super(ProgressBar, self).attach(engine, log_handler, event_name)\n        engine.add_event_handler(closing_event_name, self._close)\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` or any `event_name` added by\n            :meth:`~ignite.engine.Engine.register_events`.\n\n    \"\"\"\n\n    def __init__(self, description, metric_names=None, output_transform=None,\n                 closing_event_name=Events.EPOCH_COMPLETED):\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,\n                                             another_engine=None, 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 len(engine.state.dataloader)\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 \"\n                                  \"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        global_step = (global_step - 1) % pbar_total + 1\n        logger.pbar.update(global_step - logger.pbar.n)\n", "path": "ignite/contrib/handlers/tqdm_logger.py"}]}