We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add helper decorators to use event handler or method with specified rank 
## 🚀 Feature

Idea is to simplify the following code:
```python
import torch.distributed as dist

if dist.get_rank() == 0:
     
    @trainer.on(...)
    def some_handler(_):
        ...

    tb_logger = TensorboardLogger(log_dir="experiments/tb_logs")        
```
into 

```python
from ignite.utils import one_rank_only

@trainer.on(...)
@one_rank_only   #  equivalent @one_rank_only(rank=0)
def some_handler(_):
    ...

# implicitly work only on rank 0
tb_logger = TensorboardLogger(log_dir="experiments/tb_logs") 
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/contrib/mnist/mnist_with_neptune_logger.py`
Content:
```
1 """
2  MNIST example with training and validation monitoring using Neptune.
3 
4  Requirements:
5     Neptune: `pip install neptune-client`
6 
7  Usage:
8 
9     Run the example:
10     ```bash
11     python mnist_with_neptune_logger.py
12     ```
13 
14     Go to https://neptune.ai and explore your experiment.
15 
16 Note:
17     You can see an example experiment here:
18     https://ui.neptune.ai/o/shared/org/pytorch-ignite-integration/e/PYTOR-26/charts
19 """
20 import sys
21 from argparse import ArgumentParser
22 import logging
23 
24 import torch
25 from torch.utils.data import DataLoader
26 from torch import nn
27 import torch.nn.functional as F
28 from torch.optim import SGD
29 from torchvision.datasets import MNIST
30 from torchvision.transforms import Compose, ToTensor, Normalize
31 
32 from ignite.engine import Events, create_supervised_trainer, create_supervised_evaluator
33 from ignite.metrics import Accuracy, Loss
34 from ignite.handlers import Checkpoint
35 
36 from ignite.contrib.handlers.neptune_logger import *
37 
38 LOG_INTERVAL = 10
39 
40 
41 class Net(nn.Module):
42     def __init__(self):
43         super(Net, self).__init__()
44         self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
45         self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
46         self.conv2_drop = nn.Dropout2d()
47         self.fc1 = nn.Linear(320, 50)
48         self.fc2 = nn.Linear(50, 10)
49 
50     def forward(self, x):
51         x = F.relu(F.max_pool2d(self.conv1(x), 2))
52         x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
53         x = x.view(-1, 320)
54         x = F.relu(self.fc1(x))
55         x = F.dropout(x, training=self.training)
56         x = self.fc2(x)
57         return F.log_softmax(x, dim=-1)
58 
59 
60 def get_data_loaders(train_batch_size, val_batch_size):
61     data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])
62 
63     train_loader = DataLoader(
64         MNIST(download=True, root=".", transform=data_transform, train=True), batch_size=train_batch_size, shuffle=True
65     )
66 
67     val_loader = DataLoader(
68         MNIST(download=False, root=".", transform=data_transform, train=False), batch_size=val_batch_size, shuffle=False
69     )
70     return train_loader, val_loader
71 
72 
73 def run(train_batch_size, val_batch_size, epochs, lr, momentum):
74     train_loader, val_loader = get_data_loaders(train_batch_size, val_batch_size)
75     model = Net()
76     device = "cpu"
77 
78     if torch.cuda.is_available():
79         device = "cuda"
80 
81     optimizer = SGD(model.parameters(), lr=lr, momentum=momentum)
82     criterion = nn.CrossEntropyLoss()
83     trainer = create_supervised_trainer(model, optimizer, criterion, device=device)
84 
85     if sys.version_info > (3,):
86         from ignite.contrib.metrics.gpu_info import GpuInfo
87 
88         try:
89             GpuInfo().attach(trainer)
90         except RuntimeError:
91             print(
92                 "INFO: By default, in this example it is possible to log GPU information (used memory, utilization). "
93                 "As there is no pynvml python package installed, GPU information won't be logged. Otherwise, please "
94                 "install it : `pip install pynvml`"
95             )
96 
97     metrics = {"accuracy": Accuracy(), "loss": Loss(criterion)}
98 
99     train_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)
100     validation_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)
101 
102     @trainer.on(Events.EPOCH_COMPLETED)
103     def compute_metrics(engine):
104         train_evaluator.run(train_loader)
105         validation_evaluator.run(val_loader)
106 
107     npt_logger = NeptuneLogger(
108         api_token="ANONYMOUS",
109         project_name="shared/pytorch-ignite-integration",
110         name="ignite-mnist-example",
111         params={
112             "train_batch_size": train_batch_size,
113             "val_batch_size": val_batch_size,
114             "epochs": epochs,
115             "lr": lr,
116             "momentum": momentum,
117         },
118     )
119 
120     npt_logger.attach(
121         trainer,
122         log_handler=OutputHandler(
123             tag="training", output_transform=lambda loss: {"batchloss": loss}, metric_names="all"
124         ),
125         event_name=Events.ITERATION_COMPLETED(every=100),
126     )
127 
128     npt_logger.attach(
129         train_evaluator,
130         log_handler=OutputHandler(tag="training", metric_names=["loss", "accuracy"], another_engine=trainer),
131         event_name=Events.EPOCH_COMPLETED,
132     )
133 
134     npt_logger.attach(
135         validation_evaluator,
136         log_handler=OutputHandler(tag="validation", metric_names=["loss", "accuracy"], another_engine=trainer),
137         event_name=Events.EPOCH_COMPLETED,
138     )
139 
140     npt_logger.attach(
141         trainer, log_handler=OptimizerParamsHandler(optimizer), event_name=Events.ITERATION_COMPLETED(every=100)
142     )
143 
144     npt_logger.attach(
145         trainer, log_handler=WeightsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100)
146     )
147 
148     npt_logger.attach(trainer, log_handler=GradsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100))
149 
150     def score_function(engine):
151         return engine.state.metrics['accuracy']
152 
153     to_save = {'model': model}
154     handler = Checkpoint(to_save, NeptuneSaver(npt_logger), n_saved=2,
155                          filename_prefix='best', score_function=score_function,
156                          score_name="validation_accuracy",
157                          global_step_transform=global_step_from_engine(trainer))
158     validation_evaluator.add_event_handler(Events.COMPLETED, handler)
159 
160     # kick everything off
161     trainer.run(train_loader, max_epochs=epochs)
162     npt_logger.close()
163 
164 
165 if __name__ == "__main__":
166     parser = ArgumentParser()
167     parser.add_argument("--batch_size", type=int, default=64, help="input batch size for training (default: 64)")
168     parser.add_argument(
169         "--val_batch_size", type=int, default=1000, help="input batch size for validation (default: 1000)"
170     )
171     parser.add_argument("--epochs", type=int, default=10, help="number of epochs to train (default: 10)")
172     parser.add_argument("--lr", type=float, default=0.01, help="learning rate (default: 0.01)")
173     parser.add_argument("--momentum", type=float, default=0.5, help="SGD momentum (default: 0.5)")
174 
175     args = parser.parse_args()
176 
177     # Setup engine logger
178     logger = logging.getLogger("ignite.engine.engine.Engine")
179     handler = logging.StreamHandler()
180     formatter = logging.Formatter("%(asctime)s %(name)-12s %(levelname)-8s %(message)s")
181     handler.setFormatter(formatter)
182     logger.addHandler(handler)
183     logger.setLevel(logging.INFO)
184 
185     run(args.batch_size, args.val_batch_size, args.epochs, args.lr, args.momentum)
186
```

Path: `ignite/utils.py`
Content:
```
1 import collections.abc as collections
2 import logging
3 from typing import Union, Optional, Callable, Any, Type, Tuple
4 
5 import torch
6 
7 __all__ = ["convert_tensor", "apply_to_tensor", "apply_to_type", "to_onehot", "setup_logger"]
8 
9 
10 def convert_tensor(
11     input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes],
12     device: Optional[Union[str, torch.device]] = None,
13     non_blocking: bool = False,
14 ) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:
15     """Move tensors to relevant device."""
16 
17     def _func(tensor: torch.Tensor) -> torch.Tensor:
18         return tensor.to(device=device, non_blocking=non_blocking) if device is not None else tensor
19 
20     return apply_to_tensor(input_, _func)
21 
22 
23 def apply_to_tensor(
24     input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes], func: Callable
25 ) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:
26     """Apply a function on a tensor or mapping, or sequence of tensors.
27     """
28     return apply_to_type(input_, torch.Tensor, func)
29 
30 
31 def apply_to_type(
32     input_: Union[Any, collections.Sequence, collections.Mapping, str, bytes],
33     input_type: Union[Type, Tuple[Type[Any], Any]],
34     func: Callable,
35 ) -> Union[Any, collections.Sequence, collections.Mapping, str, bytes]:
36     """Apply a function on a object of `input_type` or mapping, or sequence of objects of `input_type`.
37     """
38     if isinstance(input_, input_type):
39         return func(input_)
40     elif isinstance(input_, (str, bytes)):
41         return input_
42     elif isinstance(input_, collections.Mapping):
43         return type(input_)({k: apply_to_type(sample, input_type, func) for k, sample in input_.items()})
44     elif isinstance(input_, tuple) and hasattr(input_, "_fields"):  # namedtuple
45         return type(input_)(*(apply_to_type(sample, input_type, func) for sample in input_))
46     elif isinstance(input_, collections.Sequence):
47         return type(input_)([apply_to_type(sample, input_type, func) for sample in input_])
48     else:
49         raise TypeError(("input must contain {}, dicts or lists; found {}".format(input_type, type(input_))))
50 
51 
52 def to_onehot(indices: torch.Tensor, num_classes: int) -> torch.Tensor:
53     """Convert a tensor of indices of any shape `(N, ...)` to a
54     tensor of one-hot indicators of shape `(N, num_classes, ...) and of type uint8. Output's device is equal to the
55     input's device`.
56     """
57     onehot = torch.zeros(indices.shape[0], num_classes, *indices.shape[1:], dtype=torch.uint8, device=indices.device)
58     return onehot.scatter_(1, indices.unsqueeze(1), 1)
59 
60 
61 def setup_logger(
62     name: str,
63     level: int = logging.INFO,
64     format: str = "%(asctime)s %(name)s %(levelname)s: %(message)s",
65     filepath: Optional[str] = None,
66     distributed_rank: int = 0,
67 ) -> logging.Logger:
68     """Setups logger: name, level, format etc.
69 
70     Args:
71         name (str): new name for the logger.
72         level (int): logging level, e.g. CRITICAL, ERROR, WARNING, INFO, DEBUG
73         format (str): logging format. By default, `%(asctime)s %(name)s %(levelname)s: %(message)s`
74         filepath (str, optional): Optional logging file path. If not None, logs are written to the file.
75         distributed_rank (int, optional): Optional, rank in distributed configuration to avoid logger setup for workers.
76 
77     Returns:
78         logging.Logger
79 
80     For example, to improve logs readability when training with a trainer and evaluator:
81 
82     .. code-block:: python
83 
84         from ignite.utils import setup_logger
85 
86         trainer = ...
87         evaluator = ...
88 
89         trainer.logger = setup_logger("trainer")
90         evaluator.logger = setup_logger("evaluator")
91 
92         trainer.run(data, max_epochs=10)
93 
94         # Logs will look like
95         # 2020-01-21 12:46:07,356 trainer INFO: Engine run starting with max_epochs=5.
96         # 2020-01-21 12:46:07,358 trainer INFO: Epoch[1] Complete. Time taken: 00:5:23
97         # 2020-01-21 12:46:07,358 evaluator INFO: Engine run starting with max_epochs=1.
98         # 2020-01-21 12:46:07,358 evaluator INFO: Epoch[1] Complete. Time taken: 00:01:02
99         # ...
100 
101     """
102     logger = logging.getLogger(name)
103 
104     if distributed_rank > 0:
105         return logger
106 
107     logger.setLevel(level)
108 
109     # Remove previous handlers
110     if logger.hasHandlers():
111         for h in list(logger.handlers):
112             logger.removeHandler(h)
113 
114     formatter = logging.Formatter(format)
115 
116     ch = logging.StreamHandler()
117     ch.setLevel(level)
118     ch.setFormatter(formatter)
119     logger.addHandler(ch)
120 
121     if filepath is not None:
122         fh = logging.FileHandler(filepath)
123         fh.setLevel(level)
124         fh.setFormatter(formatter)
125         logger.addHandler(fh)
126 
127     return logger
128
```
--- 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/examples/contrib/mnist/mnist_with_neptune_logger.py b/examples/contrib/mnist/mnist_with_neptune_logger.py
--- a/examples/contrib/mnist/mnist_with_neptune_logger.py
+++ b/examples/contrib/mnist/mnist_with_neptune_logger.py
@@ -148,13 +148,18 @@
     npt_logger.attach(trainer, log_handler=GradsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100))
 
     def score_function(engine):
-        return engine.state.metrics['accuracy']
-
-    to_save = {'model': model}
-    handler = Checkpoint(to_save, NeptuneSaver(npt_logger), n_saved=2,
-                         filename_prefix='best', score_function=score_function,
-                         score_name="validation_accuracy",
-                         global_step_transform=global_step_from_engine(trainer))
+        return engine.state.metrics["accuracy"]
+
+    to_save = {"model": model}
+    handler = Checkpoint(
+        to_save,
+        NeptuneSaver(npt_logger),
+        n_saved=2,
+        filename_prefix="best",
+        score_function=score_function,
+        score_name="validation_accuracy",
+        global_step_transform=global_step_from_engine(trainer),
+    )
     validation_evaluator.add_event_handler(Events.COMPLETED, handler)
 
     # kick everything off
diff --git a/ignite/utils.py b/ignite/utils.py
--- a/ignite/utils.py
+++ b/ignite/utils.py
@@ -1,10 +1,12 @@
 import collections.abc as collections
 import logging
+from functools import wraps
 from typing import Union, Optional, Callable, Any, Type, Tuple
 
 import torch
+import torch.distributed as dist
 
-__all__ = ["convert_tensor", "apply_to_tensor", "apply_to_type", "to_onehot", "setup_logger"]
+__all__ = ["convert_tensor", "apply_to_tensor", "apply_to_type", "to_onehot", "setup_logger", "one_rank_only"]
 
 
 def convert_tensor(
@@ -125,3 +127,37 @@
         logger.addHandler(fh)
 
     return logger
+
+
+def one_rank_only(rank: int = 0, barrier: bool = False):
+    """Decorator to filter handlers wrt a rank number
+
+    Args:
+        rank (int): rank number of the handler (default: 0).
+        barrier (bool): synchronisation with a barrier (default: False).
+
+    .. code-block:: python
+        engine = ...
+
+        @engine.on(...)
+        @one_rank_only() # means @one_rank_only(rank=0)
+        def some_handler(_):
+            ...
+
+        @engine.on(...)
+        @one_rank_only(rank=1)
+        def some_handler(_):
+            ...
+    """
+    def _one_rank_only(func):
+        @wraps(func)
+        def wrapper(*args, **kwargs):
+            ret = None
+            if dist.get_rank() == rank:
+                ret = func(*args, **kwargs)
+            if barrier:
+                dist.barrier()
+            return ret
+        return wrapper
+
+    return _one_rank_only

{"golden_diff": "diff --git a/examples/contrib/mnist/mnist_with_neptune_logger.py b/examples/contrib/mnist/mnist_with_neptune_logger.py\n--- a/examples/contrib/mnist/mnist_with_neptune_logger.py\n+++ b/examples/contrib/mnist/mnist_with_neptune_logger.py\n@@ -148,13 +148,18 @@\n     npt_logger.attach(trainer, log_handler=GradsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100))\n \n     def score_function(engine):\n-        return engine.state.metrics['accuracy']\n-\n-    to_save = {'model': model}\n-    handler = Checkpoint(to_save, NeptuneSaver(npt_logger), n_saved=2,\n-                         filename_prefix='best', score_function=score_function,\n-                         score_name=\"validation_accuracy\",\n-                         global_step_transform=global_step_from_engine(trainer))\n+        return engine.state.metrics[\"accuracy\"]\n+\n+    to_save = {\"model\": model}\n+    handler = Checkpoint(\n+        to_save,\n+        NeptuneSaver(npt_logger),\n+        n_saved=2,\n+        filename_prefix=\"best\",\n+        score_function=score_function,\n+        score_name=\"validation_accuracy\",\n+        global_step_transform=global_step_from_engine(trainer),\n+    )\n     validation_evaluator.add_event_handler(Events.COMPLETED, handler)\n \n     # kick everything off\ndiff --git a/ignite/utils.py b/ignite/utils.py\n--- a/ignite/utils.py\n+++ b/ignite/utils.py\n@@ -1,10 +1,12 @@\n import collections.abc as collections\n import logging\n+from functools import wraps\n from typing import Union, Optional, Callable, Any, Type, Tuple\n \n import torch\n+import torch.distributed as dist\n \n-__all__ = [\"convert_tensor\", \"apply_to_tensor\", \"apply_to_type\", \"to_onehot\", \"setup_logger\"]\n+__all__ = [\"convert_tensor\", \"apply_to_tensor\", \"apply_to_type\", \"to_onehot\", \"setup_logger\", \"one_rank_only\"]\n \n \n def convert_tensor(\n@@ -125,3 +127,37 @@\n         logger.addHandler(fh)\n \n     return logger\n+\n+\n+def one_rank_only(rank: int = 0, barrier: bool = False):\n+    \"\"\"Decorator to filter handlers wrt a rank number\n+\n+    Args:\n+        rank (int): rank number of the handler (default: 0).\n+        barrier (bool): synchronisation with a barrier (default: False).\n+\n+    .. code-block:: python\n+        engine = ...\n+\n+        @engine.on(...)\n+        @one_rank_only() # means @one_rank_only(rank=0)\n+        def some_handler(_):\n+            ...\n+\n+        @engine.on(...)\n+        @one_rank_only(rank=1)\n+        def some_handler(_):\n+            ...\n+    \"\"\"\n+    def _one_rank_only(func):\n+        @wraps(func)\n+        def wrapper(*args, **kwargs):\n+            ret = None\n+            if dist.get_rank() == rank:\n+                ret = func(*args, **kwargs)\n+            if barrier:\n+                dist.barrier()\n+            return ret\n+        return wrapper\n+\n+    return _one_rank_only\n", "issue": "Add helper decorators to use event handler or method with specified rank \n## \ud83d\ude80 Feature\r\n\r\nIdea is to simplify the following code:\r\n```python\r\nimport torch.distributed as dist\r\n\r\nif dist.get_rank() == 0:\r\n     \r\n    @trainer.on(...)\r\n    def some_handler(_):\r\n        ...\r\n\r\n    tb_logger = TensorboardLogger(log_dir=\"experiments/tb_logs\")        \r\n```\r\ninto \r\n\r\n```python\r\nfrom ignite.utils import one_rank_only\r\n\r\n@trainer.on(...)\r\n@one_rank_only   #  equivalent @one_rank_only(rank=0)\r\ndef some_handler(_):\r\n    ...\r\n\r\n# implicitly work only on rank 0\r\ntb_logger = TensorboardLogger(log_dir=\"experiments/tb_logs\") \r\n```\r\n\n", "before_files": [{"content": "\"\"\"\n MNIST example with training and validation monitoring using Neptune.\n\n Requirements:\n    Neptune: `pip install neptune-client`\n\n Usage:\n\n    Run the example:\n    ```bash\n    python mnist_with_neptune_logger.py\n    ```\n\n    Go to https://neptune.ai and explore your experiment.\n\nNote:\n    You can see an example experiment here:\n    https://ui.neptune.ai/o/shared/org/pytorch-ignite-integration/e/PYTOR-26/charts\n\"\"\"\nimport sys\nfrom argparse import ArgumentParser\nimport logging\n\nimport torch\nfrom torch.utils.data import DataLoader\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.optim import SGD\nfrom torchvision.datasets import MNIST\nfrom torchvision.transforms import Compose, ToTensor, Normalize\n\nfrom ignite.engine import Events, create_supervised_trainer, create_supervised_evaluator\nfrom ignite.metrics import Accuracy, Loss\nfrom ignite.handlers import Checkpoint\n\nfrom ignite.contrib.handlers.neptune_logger import *\n\nLOG_INTERVAL = 10\n\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n        self.conv2_drop = nn.Dropout2d()\n        self.fc1 = nn.Linear(320, 50)\n        self.fc2 = nn.Linear(50, 10)\n\n    def forward(self, x):\n        x = F.relu(F.max_pool2d(self.conv1(x), 2))\n        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))\n        x = x.view(-1, 320)\n        x = F.relu(self.fc1(x))\n        x = F.dropout(x, training=self.training)\n        x = self.fc2(x)\n        return F.log_softmax(x, dim=-1)\n\n\ndef get_data_loaders(train_batch_size, val_batch_size):\n    data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])\n\n    train_loader = DataLoader(\n        MNIST(download=True, root=\".\", transform=data_transform, train=True), batch_size=train_batch_size, shuffle=True\n    )\n\n    val_loader = DataLoader(\n        MNIST(download=False, root=\".\", transform=data_transform, train=False), batch_size=val_batch_size, shuffle=False\n    )\n    return train_loader, val_loader\n\n\ndef run(train_batch_size, val_batch_size, epochs, lr, momentum):\n    train_loader, val_loader = get_data_loaders(train_batch_size, val_batch_size)\n    model = Net()\n    device = \"cpu\"\n\n    if torch.cuda.is_available():\n        device = \"cuda\"\n\n    optimizer = SGD(model.parameters(), lr=lr, momentum=momentum)\n    criterion = nn.CrossEntropyLoss()\n    trainer = create_supervised_trainer(model, optimizer, criterion, device=device)\n\n    if sys.version_info > (3,):\n        from ignite.contrib.metrics.gpu_info import GpuInfo\n\n        try:\n            GpuInfo().attach(trainer)\n        except RuntimeError:\n            print(\n                \"INFO: By default, in this example it is possible to log GPU information (used memory, utilization). \"\n                \"As there is no pynvml python package installed, GPU information won't be logged. Otherwise, please \"\n                \"install it : `pip install pynvml`\"\n            )\n\n    metrics = {\"accuracy\": Accuracy(), \"loss\": Loss(criterion)}\n\n    train_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)\n    validation_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)\n\n    @trainer.on(Events.EPOCH_COMPLETED)\n    def compute_metrics(engine):\n        train_evaluator.run(train_loader)\n        validation_evaluator.run(val_loader)\n\n    npt_logger = NeptuneLogger(\n        api_token=\"ANONYMOUS\",\n        project_name=\"shared/pytorch-ignite-integration\",\n        name=\"ignite-mnist-example\",\n        params={\n            \"train_batch_size\": train_batch_size,\n            \"val_batch_size\": val_batch_size,\n            \"epochs\": epochs,\n            \"lr\": lr,\n            \"momentum\": momentum,\n        },\n    )\n\n    npt_logger.attach(\n        trainer,\n        log_handler=OutputHandler(\n            tag=\"training\", output_transform=lambda loss: {\"batchloss\": loss}, metric_names=\"all\"\n        ),\n        event_name=Events.ITERATION_COMPLETED(every=100),\n    )\n\n    npt_logger.attach(\n        train_evaluator,\n        log_handler=OutputHandler(tag=\"training\", metric_names=[\"loss\", \"accuracy\"], another_engine=trainer),\n        event_name=Events.EPOCH_COMPLETED,\n    )\n\n    npt_logger.attach(\n        validation_evaluator,\n        log_handler=OutputHandler(tag=\"validation\", metric_names=[\"loss\", \"accuracy\"], another_engine=trainer),\n        event_name=Events.EPOCH_COMPLETED,\n    )\n\n    npt_logger.attach(\n        trainer, log_handler=OptimizerParamsHandler(optimizer), event_name=Events.ITERATION_COMPLETED(every=100)\n    )\n\n    npt_logger.attach(\n        trainer, log_handler=WeightsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100)\n    )\n\n    npt_logger.attach(trainer, log_handler=GradsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100))\n\n    def score_function(engine):\n        return engine.state.metrics['accuracy']\n\n    to_save = {'model': model}\n    handler = Checkpoint(to_save, NeptuneSaver(npt_logger), n_saved=2,\n                         filename_prefix='best', score_function=score_function,\n                         score_name=\"validation_accuracy\",\n                         global_step_transform=global_step_from_engine(trainer))\n    validation_evaluator.add_event_handler(Events.COMPLETED, handler)\n\n    # kick everything off\n    trainer.run(train_loader, max_epochs=epochs)\n    npt_logger.close()\n\n\nif __name__ == \"__main__\":\n    parser = ArgumentParser()\n    parser.add_argument(\"--batch_size\", type=int, default=64, help=\"input batch size for training (default: 64)\")\n    parser.add_argument(\n        \"--val_batch_size\", type=int, default=1000, help=\"input batch size for validation (default: 1000)\"\n    )\n    parser.add_argument(\"--epochs\", type=int, default=10, help=\"number of epochs to train (default: 10)\")\n    parser.add_argument(\"--lr\", type=float, default=0.01, help=\"learning rate (default: 0.01)\")\n    parser.add_argument(\"--momentum\", type=float, default=0.5, help=\"SGD momentum (default: 0.5)\")\n\n    args = parser.parse_args()\n\n    # Setup engine logger\n    logger = logging.getLogger(\"ignite.engine.engine.Engine\")\n    handler = logging.StreamHandler()\n    formatter = logging.Formatter(\"%(asctime)s %(name)-12s %(levelname)-8s %(message)s\")\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n    logger.setLevel(logging.INFO)\n\n    run(args.batch_size, args.val_batch_size, args.epochs, args.lr, args.momentum)\n", "path": "examples/contrib/mnist/mnist_with_neptune_logger.py"}, {"content": "import collections.abc as collections\nimport logging\nfrom typing import Union, Optional, Callable, Any, Type, Tuple\n\nimport torch\n\n__all__ = [\"convert_tensor\", \"apply_to_tensor\", \"apply_to_type\", \"to_onehot\", \"setup_logger\"]\n\n\ndef convert_tensor(\n    input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes],\n    device: Optional[Union[str, torch.device]] = None,\n    non_blocking: bool = False,\n) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Move tensors to relevant device.\"\"\"\n\n    def _func(tensor: torch.Tensor) -> torch.Tensor:\n        return tensor.to(device=device, non_blocking=non_blocking) if device is not None else tensor\n\n    return apply_to_tensor(input_, _func)\n\n\ndef apply_to_tensor(\n    input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes], func: Callable\n) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Apply a function on a tensor or mapping, or sequence of tensors.\n    \"\"\"\n    return apply_to_type(input_, torch.Tensor, func)\n\n\ndef apply_to_type(\n    input_: Union[Any, collections.Sequence, collections.Mapping, str, bytes],\n    input_type: Union[Type, Tuple[Type[Any], Any]],\n    func: Callable,\n) -> Union[Any, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Apply a function on a object of `input_type` or mapping, or sequence of objects of `input_type`.\n    \"\"\"\n    if isinstance(input_, input_type):\n        return func(input_)\n    elif isinstance(input_, (str, bytes)):\n        return input_\n    elif isinstance(input_, collections.Mapping):\n        return type(input_)({k: apply_to_type(sample, input_type, func) for k, sample in input_.items()})\n    elif isinstance(input_, tuple) and hasattr(input_, \"_fields\"):  # namedtuple\n        return type(input_)(*(apply_to_type(sample, input_type, func) for sample in input_))\n    elif isinstance(input_, collections.Sequence):\n        return type(input_)([apply_to_type(sample, input_type, func) for sample in input_])\n    else:\n        raise TypeError((\"input must contain {}, dicts or lists; found {}\".format(input_type, type(input_))))\n\n\ndef to_onehot(indices: torch.Tensor, num_classes: int) -> torch.Tensor:\n    \"\"\"Convert a tensor of indices of any shape `(N, ...)` to a\n    tensor of one-hot indicators of shape `(N, num_classes, ...) and of type uint8. Output's device is equal to the\n    input's device`.\n    \"\"\"\n    onehot = torch.zeros(indices.shape[0], num_classes, *indices.shape[1:], dtype=torch.uint8, device=indices.device)\n    return onehot.scatter_(1, indices.unsqueeze(1), 1)\n\n\ndef setup_logger(\n    name: str,\n    level: int = logging.INFO,\n    format: str = \"%(asctime)s %(name)s %(levelname)s: %(message)s\",\n    filepath: Optional[str] = None,\n    distributed_rank: int = 0,\n) -> logging.Logger:\n    \"\"\"Setups logger: name, level, format etc.\n\n    Args:\n        name (str): new name for the logger.\n        level (int): logging level, e.g. CRITICAL, ERROR, WARNING, INFO, DEBUG\n        format (str): logging format. By default, `%(asctime)s %(name)s %(levelname)s: %(message)s`\n        filepath (str, optional): Optional logging file path. If not None, logs are written to the file.\n        distributed_rank (int, optional): Optional, rank in distributed configuration to avoid logger setup for workers.\n\n    Returns:\n        logging.Logger\n\n    For example, to improve logs readability when training with a trainer and evaluator:\n\n    .. code-block:: python\n\n        from ignite.utils import setup_logger\n\n        trainer = ...\n        evaluator = ...\n\n        trainer.logger = setup_logger(\"trainer\")\n        evaluator.logger = setup_logger(\"evaluator\")\n\n        trainer.run(data, max_epochs=10)\n\n        # Logs will look like\n        # 2020-01-21 12:46:07,356 trainer INFO: Engine run starting with max_epochs=5.\n        # 2020-01-21 12:46:07,358 trainer INFO: Epoch[1] Complete. Time taken: 00:5:23\n        # 2020-01-21 12:46:07,358 evaluator INFO: Engine run starting with max_epochs=1.\n        # 2020-01-21 12:46:07,358 evaluator INFO: Epoch[1] Complete. Time taken: 00:01:02\n        # ...\n\n    \"\"\"\n    logger = logging.getLogger(name)\n\n    if distributed_rank > 0:\n        return logger\n\n    logger.setLevel(level)\n\n    # Remove previous handlers\n    if logger.hasHandlers():\n        for h in list(logger.handlers):\n            logger.removeHandler(h)\n\n    formatter = logging.Formatter(format)\n\n    ch = logging.StreamHandler()\n    ch.setLevel(level)\n    ch.setFormatter(formatter)\n    logger.addHandler(ch)\n\n    if filepath is not None:\n        fh = logging.FileHandler(filepath)\n        fh.setLevel(level)\n        fh.setFormatter(formatter)\n        logger.addHandler(fh)\n\n    return logger\n", "path": "ignite/utils.py"}], "after_files": [{"content": "\"\"\"\n MNIST example with training and validation monitoring using Neptune.\n\n Requirements:\n    Neptune: `pip install neptune-client`\n\n Usage:\n\n    Run the example:\n    ```bash\n    python mnist_with_neptune_logger.py\n    ```\n\n    Go to https://neptune.ai and explore your experiment.\n\nNote:\n    You can see an example experiment here:\n    https://ui.neptune.ai/o/shared/org/pytorch-ignite-integration/e/PYTOR-26/charts\n\"\"\"\nimport sys\nfrom argparse import ArgumentParser\nimport logging\n\nimport torch\nfrom torch.utils.data import DataLoader\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.optim import SGD\nfrom torchvision.datasets import MNIST\nfrom torchvision.transforms import Compose, ToTensor, Normalize\n\nfrom ignite.engine import Events, create_supervised_trainer, create_supervised_evaluator\nfrom ignite.metrics import Accuracy, Loss\nfrom ignite.handlers import Checkpoint\n\nfrom ignite.contrib.handlers.neptune_logger import *\n\nLOG_INTERVAL = 10\n\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n        self.conv2_drop = nn.Dropout2d()\n        self.fc1 = nn.Linear(320, 50)\n        self.fc2 = nn.Linear(50, 10)\n\n    def forward(self, x):\n        x = F.relu(F.max_pool2d(self.conv1(x), 2))\n        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))\n        x = x.view(-1, 320)\n        x = F.relu(self.fc1(x))\n        x = F.dropout(x, training=self.training)\n        x = self.fc2(x)\n        return F.log_softmax(x, dim=-1)\n\n\ndef get_data_loaders(train_batch_size, val_batch_size):\n    data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])\n\n    train_loader = DataLoader(\n        MNIST(download=True, root=\".\", transform=data_transform, train=True), batch_size=train_batch_size, shuffle=True\n    )\n\n    val_loader = DataLoader(\n        MNIST(download=False, root=\".\", transform=data_transform, train=False), batch_size=val_batch_size, shuffle=False\n    )\n    return train_loader, val_loader\n\n\ndef run(train_batch_size, val_batch_size, epochs, lr, momentum):\n    train_loader, val_loader = get_data_loaders(train_batch_size, val_batch_size)\n    model = Net()\n    device = \"cpu\"\n\n    if torch.cuda.is_available():\n        device = \"cuda\"\n\n    optimizer = SGD(model.parameters(), lr=lr, momentum=momentum)\n    criterion = nn.CrossEntropyLoss()\n    trainer = create_supervised_trainer(model, optimizer, criterion, device=device)\n\n    if sys.version_info > (3,):\n        from ignite.contrib.metrics.gpu_info import GpuInfo\n\n        try:\n            GpuInfo().attach(trainer)\n        except RuntimeError:\n            print(\n                \"INFO: By default, in this example it is possible to log GPU information (used memory, utilization). \"\n                \"As there is no pynvml python package installed, GPU information won't be logged. Otherwise, please \"\n                \"install it : `pip install pynvml`\"\n            )\n\n    metrics = {\"accuracy\": Accuracy(), \"loss\": Loss(criterion)}\n\n    train_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)\n    validation_evaluator = create_supervised_evaluator(model, metrics=metrics, device=device)\n\n    @trainer.on(Events.EPOCH_COMPLETED)\n    def compute_metrics(engine):\n        train_evaluator.run(train_loader)\n        validation_evaluator.run(val_loader)\n\n    npt_logger = NeptuneLogger(\n        api_token=\"ANONYMOUS\",\n        project_name=\"shared/pytorch-ignite-integration\",\n        name=\"ignite-mnist-example\",\n        params={\n            \"train_batch_size\": train_batch_size,\n            \"val_batch_size\": val_batch_size,\n            \"epochs\": epochs,\n            \"lr\": lr,\n            \"momentum\": momentum,\n        },\n    )\n\n    npt_logger.attach(\n        trainer,\n        log_handler=OutputHandler(\n            tag=\"training\", output_transform=lambda loss: {\"batchloss\": loss}, metric_names=\"all\"\n        ),\n        event_name=Events.ITERATION_COMPLETED(every=100),\n    )\n\n    npt_logger.attach(\n        train_evaluator,\n        log_handler=OutputHandler(tag=\"training\", metric_names=[\"loss\", \"accuracy\"], another_engine=trainer),\n        event_name=Events.EPOCH_COMPLETED,\n    )\n\n    npt_logger.attach(\n        validation_evaluator,\n        log_handler=OutputHandler(tag=\"validation\", metric_names=[\"loss\", \"accuracy\"], another_engine=trainer),\n        event_name=Events.EPOCH_COMPLETED,\n    )\n\n    npt_logger.attach(\n        trainer, log_handler=OptimizerParamsHandler(optimizer), event_name=Events.ITERATION_COMPLETED(every=100)\n    )\n\n    npt_logger.attach(\n        trainer, log_handler=WeightsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100)\n    )\n\n    npt_logger.attach(trainer, log_handler=GradsScalarHandler(model), event_name=Events.ITERATION_COMPLETED(every=100))\n\n    def score_function(engine):\n        return engine.state.metrics[\"accuracy\"]\n\n    to_save = {\"model\": model}\n    handler = Checkpoint(\n        to_save,\n        NeptuneSaver(npt_logger),\n        n_saved=2,\n        filename_prefix=\"best\",\n        score_function=score_function,\n        score_name=\"validation_accuracy\",\n        global_step_transform=global_step_from_engine(trainer),\n    )\n    validation_evaluator.add_event_handler(Events.COMPLETED, handler)\n\n    # kick everything off\n    trainer.run(train_loader, max_epochs=epochs)\n    npt_logger.close()\n\n\nif __name__ == \"__main__\":\n    parser = ArgumentParser()\n    parser.add_argument(\"--batch_size\", type=int, default=64, help=\"input batch size for training (default: 64)\")\n    parser.add_argument(\n        \"--val_batch_size\", type=int, default=1000, help=\"input batch size for validation (default: 1000)\"\n    )\n    parser.add_argument(\"--epochs\", type=int, default=10, help=\"number of epochs to train (default: 10)\")\n    parser.add_argument(\"--lr\", type=float, default=0.01, help=\"learning rate (default: 0.01)\")\n    parser.add_argument(\"--momentum\", type=float, default=0.5, help=\"SGD momentum (default: 0.5)\")\n\n    args = parser.parse_args()\n\n    # Setup engine logger\n    logger = logging.getLogger(\"ignite.engine.engine.Engine\")\n    handler = logging.StreamHandler()\n    formatter = logging.Formatter(\"%(asctime)s %(name)-12s %(levelname)-8s %(message)s\")\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n    logger.setLevel(logging.INFO)\n\n    run(args.batch_size, args.val_batch_size, args.epochs, args.lr, args.momentum)\n", "path": "examples/contrib/mnist/mnist_with_neptune_logger.py"}, {"content": "import collections.abc as collections\nimport logging\nfrom functools import wraps\nfrom typing import Union, Optional, Callable, Any, Type, Tuple\n\nimport torch\nimport torch.distributed as dist\n\n__all__ = [\"convert_tensor\", \"apply_to_tensor\", \"apply_to_type\", \"to_onehot\", \"setup_logger\", \"one_rank_only\"]\n\n\ndef convert_tensor(\n    input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes],\n    device: Optional[Union[str, torch.device]] = None,\n    non_blocking: bool = False,\n) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Move tensors to relevant device.\"\"\"\n\n    def _func(tensor: torch.Tensor) -> torch.Tensor:\n        return tensor.to(device=device, non_blocking=non_blocking) if device is not None else tensor\n\n    return apply_to_tensor(input_, _func)\n\n\ndef apply_to_tensor(\n    input_: Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes], func: Callable\n) -> Union[torch.Tensor, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Apply a function on a tensor or mapping, or sequence of tensors.\n    \"\"\"\n    return apply_to_type(input_, torch.Tensor, func)\n\n\ndef apply_to_type(\n    input_: Union[Any, collections.Sequence, collections.Mapping, str, bytes],\n    input_type: Union[Type, Tuple[Type[Any], Any]],\n    func: Callable,\n) -> Union[Any, collections.Sequence, collections.Mapping, str, bytes]:\n    \"\"\"Apply a function on a object of `input_type` or mapping, or sequence of objects of `input_type`.\n    \"\"\"\n    if isinstance(input_, input_type):\n        return func(input_)\n    elif isinstance(input_, (str, bytes)):\n        return input_\n    elif isinstance(input_, collections.Mapping):\n        return type(input_)({k: apply_to_type(sample, input_type, func) for k, sample in input_.items()})\n    elif isinstance(input_, tuple) and hasattr(input_, \"_fields\"):  # namedtuple\n        return type(input_)(*(apply_to_type(sample, input_type, func) for sample in input_))\n    elif isinstance(input_, collections.Sequence):\n        return type(input_)([apply_to_type(sample, input_type, func) for sample in input_])\n    else:\n        raise TypeError((\"input must contain {}, dicts or lists; found {}\".format(input_type, type(input_))))\n\n\ndef to_onehot(indices: torch.Tensor, num_classes: int) -> torch.Tensor:\n    \"\"\"Convert a tensor of indices of any shape `(N, ...)` to a\n    tensor of one-hot indicators of shape `(N, num_classes, ...) and of type uint8. Output's device is equal to the\n    input's device`.\n    \"\"\"\n    onehot = torch.zeros(indices.shape[0], num_classes, *indices.shape[1:], dtype=torch.uint8, device=indices.device)\n    return onehot.scatter_(1, indices.unsqueeze(1), 1)\n\n\ndef setup_logger(\n    name: str,\n    level: int = logging.INFO,\n    format: str = \"%(asctime)s %(name)s %(levelname)s: %(message)s\",\n    filepath: Optional[str] = None,\n    distributed_rank: int = 0,\n) -> logging.Logger:\n    \"\"\"Setups logger: name, level, format etc.\n\n    Args:\n        name (str): new name for the logger.\n        level (int): logging level, e.g. CRITICAL, ERROR, WARNING, INFO, DEBUG\n        format (str): logging format. By default, `%(asctime)s %(name)s %(levelname)s: %(message)s`\n        filepath (str, optional): Optional logging file path. If not None, logs are written to the file.\n        distributed_rank (int, optional): Optional, rank in distributed configuration to avoid logger setup for workers.\n\n    Returns:\n        logging.Logger\n\n    For example, to improve logs readability when training with a trainer and evaluator:\n\n    .. code-block:: python\n\n        from ignite.utils import setup_logger\n\n        trainer = ...\n        evaluator = ...\n\n        trainer.logger = setup_logger(\"trainer\")\n        evaluator.logger = setup_logger(\"evaluator\")\n\n        trainer.run(data, max_epochs=10)\n\n        # Logs will look like\n        # 2020-01-21 12:46:07,356 trainer INFO: Engine run starting with max_epochs=5.\n        # 2020-01-21 12:46:07,358 trainer INFO: Epoch[1] Complete. Time taken: 00:5:23\n        # 2020-01-21 12:46:07,358 evaluator INFO: Engine run starting with max_epochs=1.\n        # 2020-01-21 12:46:07,358 evaluator INFO: Epoch[1] Complete. Time taken: 00:01:02\n        # ...\n\n    \"\"\"\n    logger = logging.getLogger(name)\n\n    if distributed_rank > 0:\n        return logger\n\n    logger.setLevel(level)\n\n    # Remove previous handlers\n    if logger.hasHandlers():\n        for h in list(logger.handlers):\n            logger.removeHandler(h)\n\n    formatter = logging.Formatter(format)\n\n    ch = logging.StreamHandler()\n    ch.setLevel(level)\n    ch.setFormatter(formatter)\n    logger.addHandler(ch)\n\n    if filepath is not None:\n        fh = logging.FileHandler(filepath)\n        fh.setLevel(level)\n        fh.setFormatter(formatter)\n        logger.addHandler(fh)\n\n    return logger\n\n\ndef one_rank_only(rank: int = 0, barrier: bool = False):\n    \"\"\"Decorator to filter handlers wrt a rank number\n\n    Args:\n        rank (int): rank number of the handler (default: 0).\n        barrier (bool): synchronisation with a barrier (default: False).\n\n    .. code-block:: python\n        engine = ...\n\n        @engine.on(...)\n        @one_rank_only() # means @one_rank_only(rank=0)\n        def some_handler(_):\n            ...\n\n        @engine.on(...)\n        @one_rank_only(rank=1)\n        def some_handler(_):\n            ...\n    \"\"\"\n    def _one_rank_only(func):\n        @wraps(func)\n        def wrapper(*args, **kwargs):\n            ret = None\n            if dist.get_rank() == rank:\n                ret = func(*args, **kwargs)\n            if barrier:\n                dist.barrier()\n            return ret\n        return wrapper\n\n    return _one_rank_only\n", "path": "ignite/utils.py"}]}