We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Start current_epoch + current_iteration from 1 instead of 0.
Also increment these counters *after* the `ITERATION_COMPLETE`/`EPOCH_COMPLETE` events.

See discussion in #59 for more details

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ignite/engine.py`
Content:
```
1 import logging
2 from abc import ABCMeta, abstractmethod
3 from enum import Enum
4 import time
5 
6 from ignite.history import History
7 from ignite._utils import _to_hours_mins_secs
8 
9 
10 class Events(Enum):
11     EPOCH_STARTED = "epoch_started"
12     EPOCH_COMPLETED = "epoch_completed"
13     STARTED = "started"
14     COMPLETED = "completed"
15     ITERATION_STARTED = "iteration_started"
16     ITERATION_COMPLETED = "iteration_completed"
17     EXCEPTION_RAISED = "exception_raised"
18 
19 
20 class Engine(object):
21     __metaclass__ = ABCMeta
22 
23     """
24     Abstract Engine class that is the super class of the Trainer and Evaluator engines.
25 
26     Parameters
27     ----------
28     process_function : callable
29         A function receiving the current training batch in each iteration, outputing data to be stored in the history
30 
31     """
32     def __init__(self, process_function):
33         self._event_handlers = {}
34         self._logger = logging.getLogger(__name__ + "." + self.__class__.__name__)
35         self._logger.addHandler(logging.NullHandler())
36         self._process_function = process_function
37         self.current_iteration = 0
38         self.history = History()
39         self.should_terminate = False
40 
41         if self._process_function is None:
42             raise ValueError("Engine must be given a processing function in order to run")
43 
44     def add_event_handler(self, event_name, handler, *args, **kwargs):
45         """
46         Add an event handler to be executed when the specified event is fired
47 
48         Parameters
49         ----------
50         event_name: enum
51             event from ignite.trainer.TrainingEvents to attach the
52             handler to
53         handler: Callable
54             the callable event handler that should be invoked
55         args:
56             optional args to be passed to `handler`
57         kwargs:
58             optional keyword args to be passed to `handler`
59 
60         Returns
61         -------
62         None
63         """
64         if event_name not in Events.__members__.values():
65             self._logger.error("attempt to add event handler to an invalid event %s ", event_name)
66             raise ValueError("Event {} is not a valid event for this Engine".format(event_name))
67 
68         if event_name not in self._event_handlers:
69             self._event_handlers[event_name] = []
70 
71         self._event_handlers[event_name].append((handler, args, kwargs))
72         self._logger.debug("added handler for event % ", event_name)
73 
74     def on(self, event_name, *args, **kwargs):
75         """
76         Decorator shortcut for add_event_handler
77 
78         Parameters
79         ----------
80         event_name: enum
81             event to attach the handler to
82         args:
83             optional args to be passed to `handler`
84         kwargs:
85             optional keyword args to be passed to `handler`
86 
87         Returns
88         -------
89         None
90         """
91         def decorator(f):
92             self.add_event_handler(event_name, f, *args, **kwargs)
93             return f
94         return decorator
95 
96     def _fire_event(self, event_name):
97         if event_name in self._event_handlers.keys():
98             self._logger.debug("firing handlers for event %s ", event_name)
99             for func, args, kwargs in self._event_handlers[event_name]:
100                 func(self, *args, **kwargs)
101 
102     def terminate(self):
103         """
104         Sends terminate signal to the engine, so that it terminates after the current iteration
105         """
106         self._logger.info("Terminate signaled. Engine will stop after current iteration is finished")
107         self.should_terminate = True
108 
109     def _run_once_on_dataset(self, dataset):
110         self.dataset = dataset
111         try:
112             start_time = time.time()
113             for batch in dataset:
114                 self._fire_event(Events.ITERATION_STARTED)
115                 step_result = self._process_function(batch)
116                 if step_result is not None:
117                     self.history.append(step_result)
118 
119                 self.current_iteration += 1
120                 self._fire_event(Events.ITERATION_COMPLETED)
121                 if self.should_terminate:
122                     break
123             time_taken = time.time() - start_time
124             hours, mins, secs = _to_hours_mins_secs(time_taken)
125             return hours, mins, secs
126         except BaseException as e:
127             self._logger.error("Current run is terminating due to exception: %s", str(e))
128             self._fire_event(Events.EXCEPTION_RAISED)
129             raise e
130 
131     @abstractmethod
132     def run(self, data, **kwargs):
133         """
134         Train the model, evaluate the validation set and update best parameters if the validation loss
135         improves.
136         In the event that the validation set is not run (or doesn't exist), the training loss is used
137         to update the best parameters.
138 
139         Parameters
140         ----------
141         data : Iterable
142             Collection of batches allowing for the engine to iterate over(e.g., list or DataLoader)
143         **kwargs: optional
144             Any additional kwargs
145 
146         Returns
147         -------
148         None
149         """
150         raise NotImplementedError("This method should be implemented by a subclass")
151
```

Path: `ignite/trainer.py`
Content:
```
1 from __future__ import division
2 
3 import time
4 from collections import Iterable
5 from torch.autograd import Variable
6 
7 from ignite.engine import Engine, Events
8 from ignite._utils import _to_hours_mins_secs, to_variable
9 
10 __all__ = ["Trainer", "create_supervised_trainer"]
11 
12 
13 class Trainer(Engine):
14     """
15     Generic trainer class.
16 
17     Training update and validation functions receive batches of data and return values which will
18     be stored in the `training_history` and `validation_history`. The trainer defines multiple
19     events in `TrainingEvents` for which the user can attach event handlers to. The events get
20     passed the trainer, so they can access the training/validation history
21 
22 
23     Parameters
24     ----------
25     training_update_function : callable
26         Update function receiving the current training batch in each iteration
27     """
28 
29     def __init__(self, training_update_function):
30         super(Trainer, self).__init__(training_update_function)
31         self.current_epoch = 0
32         self.max_epochs = 0
33 
34     def _train_one_epoch(self, training_data):
35         hours, mins, secs = self._run_once_on_dataset(training_data)
36         self._logger.info("Epoch[%s] Complete. Time taken: %02d:%02d:%02d", self.current_epoch, hours,
37                           mins, secs)
38 
39     def run(self, training_data, max_epochs=1):
40         """
41         Train the model, evaluate the validation set and update best parameters if the validation loss
42         improves.
43         In the event that the validation set is not run (or doesn't exist), the training loss is used
44         to update the best parameters.
45 
46         Parameters
47         ----------
48         training_data : Iterable
49             Collection of training batches allowing repeated iteration (e.g., list or DataLoader)
50         max_epochs: int, optional
51             max epochs to train for [default=1]
52 
53         Returns
54         -------
55         None
56         """
57         self.dataset = training_data
58         self.current_iteration = 0
59         self.current_epoch = 0
60 
61         try:
62             self._logger.info("Training starting with max_epochs={}".format(max_epochs))
63 
64             self.max_epochs = max_epochs
65 
66             start_time = time.time()
67 
68             self._fire_event(Events.STARTED)
69             while self.current_epoch < max_epochs and not self.should_terminate:
70                 self._fire_event(Events.EPOCH_STARTED)
71                 self._train_one_epoch(training_data)
72                 if self.should_terminate:
73                     break
74                 self._fire_event(Events.EPOCH_COMPLETED)
75                 self.current_epoch += 1
76 
77             self._fire_event(Events.COMPLETED)
78             time_taken = time.time() - start_time
79             hours, mins, secs = _to_hours_mins_secs(time_taken)
80             self._logger.info("Training complete. Time taken %02d:%02d:%02d" % (hours, mins, secs))
81 
82         except BaseException as e:
83             self._logger.error("Training is terminating due to exception: %s", str(e))
84             self._fire_event(Events.EXCEPTION_RAISED)
85             raise e
86 
87 
88 def create_supervised_trainer(model, optimizer, loss_fn, cuda=False):
89     """
90     Factory function for creating a trainer for supervised models
91 
92     Args:
93         model (torch.nn.Module): the model to train
94         optimizer (torch.optim.Optimizer): the optimizer to use
95         loss_fn (torch.nn loss function): the loss function to use
96         cuda (bool, optional): whether or not to transfer batch to GPU (default: False)
97 
98     Returns:
99         Trainer: a trainer instance with supervised update function
100     """
101 
102     def _prepare_batch(batch):
103         x, y = batch
104         x = to_variable(x, cuda=cuda)
105         y = to_variable(y, cuda=cuda)
106         return x, y
107 
108     def _update(batch):
109         model.train()
110         optimizer.zero_grad()
111         x, y = _prepare_batch(batch)
112         y_pred = model(x)
113         loss = loss_fn(y_pred, y)
114         loss.backward()
115         optimizer.step()
116         return loss.data.cpu()[0]
117 
118     return Trainer(_update)
119
```
--- 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/engine.py b/ignite/engine.py
--- a/ignite/engine.py
+++ b/ignite/engine.py
@@ -111,15 +111,16 @@
         try:
             start_time = time.time()
             for batch in dataset:
+                self.current_iteration += 1
                 self._fire_event(Events.ITERATION_STARTED)
                 step_result = self._process_function(batch)
                 if step_result is not None:
                     self.history.append(step_result)
 
-                self.current_iteration += 1
                 self._fire_event(Events.ITERATION_COMPLETED)
                 if self.should_terminate:
                     break
+
             time_taken = time.time() - start_time
             hours, mins, secs = _to_hours_mins_secs(time_taken)
             return hours, mins, secs
diff --git a/ignite/trainer.py b/ignite/trainer.py
--- a/ignite/trainer.py
+++ b/ignite/trainer.py
@@ -67,12 +67,12 @@
 
             self._fire_event(Events.STARTED)
             while self.current_epoch < max_epochs and not self.should_terminate:
+                self.current_epoch += 1
                 self._fire_event(Events.EPOCH_STARTED)
                 self._train_one_epoch(training_data)
                 if self.should_terminate:
                     break
                 self._fire_event(Events.EPOCH_COMPLETED)
-                self.current_epoch += 1
 
             self._fire_event(Events.COMPLETED)
             time_taken = time.time() - start_time

{"golden_diff": "diff --git a/ignite/engine.py b/ignite/engine.py\n--- a/ignite/engine.py\n+++ b/ignite/engine.py\n@@ -111,15 +111,16 @@\n         try:\n             start_time = time.time()\n             for batch in dataset:\n+                self.current_iteration += 1\n                 self._fire_event(Events.ITERATION_STARTED)\n                 step_result = self._process_function(batch)\n                 if step_result is not None:\n                     self.history.append(step_result)\n \n-                self.current_iteration += 1\n                 self._fire_event(Events.ITERATION_COMPLETED)\n                 if self.should_terminate:\n                     break\n+\n             time_taken = time.time() - start_time\n             hours, mins, secs = _to_hours_mins_secs(time_taken)\n             return hours, mins, secs\ndiff --git a/ignite/trainer.py b/ignite/trainer.py\n--- a/ignite/trainer.py\n+++ b/ignite/trainer.py\n@@ -67,12 +67,12 @@\n \n             self._fire_event(Events.STARTED)\n             while self.current_epoch < max_epochs and not self.should_terminate:\n+                self.current_epoch += 1\n                 self._fire_event(Events.EPOCH_STARTED)\n                 self._train_one_epoch(training_data)\n                 if self.should_terminate:\n                     break\n                 self._fire_event(Events.EPOCH_COMPLETED)\n-                self.current_epoch += 1\n \n             self._fire_event(Events.COMPLETED)\n             time_taken = time.time() - start_time\n", "issue": "Start current_epoch + current_iteration from 1 instead of 0.\nAlso increment these counters *after* the `ITERATION_COMPLETE`/`EPOCH_COMPLETE` events.\r\n\r\nSee discussion in #59 for more details\n", "before_files": [{"content": "import logging\nfrom abc import ABCMeta, abstractmethod\nfrom enum import Enum\nimport time\n\nfrom ignite.history import History\nfrom ignite._utils import _to_hours_mins_secs\n\n\nclass Events(Enum):\n    EPOCH_STARTED = \"epoch_started\"\n    EPOCH_COMPLETED = \"epoch_completed\"\n    STARTED = \"started\"\n    COMPLETED = \"completed\"\n    ITERATION_STARTED = \"iteration_started\"\n    ITERATION_COMPLETED = \"iteration_completed\"\n    EXCEPTION_RAISED = \"exception_raised\"\n\n\nclass Engine(object):\n    __metaclass__ = ABCMeta\n\n    \"\"\"\n    Abstract Engine class that is the super class of the Trainer and Evaluator engines.\n\n    Parameters\n    ----------\n    process_function : callable\n        A function receiving the current training batch in each iteration, outputing data to be stored in the history\n\n    \"\"\"\n    def __init__(self, process_function):\n        self._event_handlers = {}\n        self._logger = logging.getLogger(__name__ + \".\" + self.__class__.__name__)\n        self._logger.addHandler(logging.NullHandler())\n        self._process_function = process_function\n        self.current_iteration = 0\n        self.history = History()\n        self.should_terminate = False\n\n        if self._process_function is None:\n            raise ValueError(\"Engine must be given a processing function in order to run\")\n\n    def add_event_handler(self, event_name, handler, *args, **kwargs):\n        \"\"\"\n        Add an event handler to be executed when the specified event is fired\n\n        Parameters\n        ----------\n        event_name: enum\n            event from ignite.trainer.TrainingEvents to attach the\n            handler to\n        handler: Callable\n            the callable event handler that should be invoked\n        args:\n            optional args to be passed to `handler`\n        kwargs:\n            optional keyword args to be passed to `handler`\n\n        Returns\n        -------\n        None\n        \"\"\"\n        if event_name not in Events.__members__.values():\n            self._logger.error(\"attempt to add event handler to an invalid event %s \", event_name)\n            raise ValueError(\"Event {} is not a valid event for this Engine\".format(event_name))\n\n        if event_name not in self._event_handlers:\n            self._event_handlers[event_name] = []\n\n        self._event_handlers[event_name].append((handler, args, kwargs))\n        self._logger.debug(\"added handler for event % \", event_name)\n\n    def on(self, event_name, *args, **kwargs):\n        \"\"\"\n        Decorator shortcut for add_event_handler\n\n        Parameters\n        ----------\n        event_name: enum\n            event to attach the handler to\n        args:\n            optional args to be passed to `handler`\n        kwargs:\n            optional keyword args to be passed to `handler`\n\n        Returns\n        -------\n        None\n        \"\"\"\n        def decorator(f):\n            self.add_event_handler(event_name, f, *args, **kwargs)\n            return f\n        return decorator\n\n    def _fire_event(self, event_name):\n        if event_name in self._event_handlers.keys():\n            self._logger.debug(\"firing handlers for event %s \", event_name)\n            for func, args, kwargs in self._event_handlers[event_name]:\n                func(self, *args, **kwargs)\n\n    def terminate(self):\n        \"\"\"\n        Sends terminate signal to the engine, so that it terminates after the current iteration\n        \"\"\"\n        self._logger.info(\"Terminate signaled. Engine will stop after current iteration is finished\")\n        self.should_terminate = True\n\n    def _run_once_on_dataset(self, dataset):\n        self.dataset = dataset\n        try:\n            start_time = time.time()\n            for batch in dataset:\n                self._fire_event(Events.ITERATION_STARTED)\n                step_result = self._process_function(batch)\n                if step_result is not None:\n                    self.history.append(step_result)\n\n                self.current_iteration += 1\n                self._fire_event(Events.ITERATION_COMPLETED)\n                if self.should_terminate:\n                    break\n            time_taken = time.time() - start_time\n            hours, mins, secs = _to_hours_mins_secs(time_taken)\n            return hours, mins, secs\n        except BaseException as e:\n            self._logger.error(\"Current run is terminating due to exception: %s\", str(e))\n            self._fire_event(Events.EXCEPTION_RAISED)\n            raise e\n\n    @abstractmethod\n    def run(self, data, **kwargs):\n        \"\"\"\n        Train the model, evaluate the validation set and update best parameters if the validation loss\n        improves.\n        In the event that the validation set is not run (or doesn't exist), the training loss is used\n        to update the best parameters.\n\n        Parameters\n        ----------\n        data : Iterable\n            Collection of batches allowing for the engine to iterate over(e.g., list or DataLoader)\n        **kwargs: optional\n            Any additional kwargs\n\n        Returns\n        -------\n        None\n        \"\"\"\n        raise NotImplementedError(\"This method should be implemented by a subclass\")\n", "path": "ignite/engine.py"}, {"content": "from __future__ import division\n\nimport time\nfrom collections import Iterable\nfrom torch.autograd import Variable\n\nfrom ignite.engine import Engine, Events\nfrom ignite._utils import _to_hours_mins_secs, to_variable\n\n__all__ = [\"Trainer\", \"create_supervised_trainer\"]\n\n\nclass Trainer(Engine):\n    \"\"\"\n    Generic trainer class.\n\n    Training update and validation functions receive batches of data and return values which will\n    be stored in the `training_history` and `validation_history`. The trainer defines multiple\n    events in `TrainingEvents` for which the user can attach event handlers to. The events get\n    passed the trainer, so they can access the training/validation history\n\n\n    Parameters\n    ----------\n    training_update_function : callable\n        Update function receiving the current training batch in each iteration\n    \"\"\"\n\n    def __init__(self, training_update_function):\n        super(Trainer, self).__init__(training_update_function)\n        self.current_epoch = 0\n        self.max_epochs = 0\n\n    def _train_one_epoch(self, training_data):\n        hours, mins, secs = self._run_once_on_dataset(training_data)\n        self._logger.info(\"Epoch[%s] Complete. Time taken: %02d:%02d:%02d\", self.current_epoch, hours,\n                          mins, secs)\n\n    def run(self, training_data, max_epochs=1):\n        \"\"\"\n        Train the model, evaluate the validation set and update best parameters if the validation loss\n        improves.\n        In the event that the validation set is not run (or doesn't exist), the training loss is used\n        to update the best parameters.\n\n        Parameters\n        ----------\n        training_data : Iterable\n            Collection of training batches allowing repeated iteration (e.g., list or DataLoader)\n        max_epochs: int, optional\n            max epochs to train for [default=1]\n\n        Returns\n        -------\n        None\n        \"\"\"\n        self.dataset = training_data\n        self.current_iteration = 0\n        self.current_epoch = 0\n\n        try:\n            self._logger.info(\"Training starting with max_epochs={}\".format(max_epochs))\n\n            self.max_epochs = max_epochs\n\n            start_time = time.time()\n\n            self._fire_event(Events.STARTED)\n            while self.current_epoch < max_epochs and not self.should_terminate:\n                self._fire_event(Events.EPOCH_STARTED)\n                self._train_one_epoch(training_data)\n                if self.should_terminate:\n                    break\n                self._fire_event(Events.EPOCH_COMPLETED)\n                self.current_epoch += 1\n\n            self._fire_event(Events.COMPLETED)\n            time_taken = time.time() - start_time\n            hours, mins, secs = _to_hours_mins_secs(time_taken)\n            self._logger.info(\"Training complete. Time taken %02d:%02d:%02d\" % (hours, mins, secs))\n\n        except BaseException as e:\n            self._logger.error(\"Training is terminating due to exception: %s\", str(e))\n            self._fire_event(Events.EXCEPTION_RAISED)\n            raise e\n\n\ndef create_supervised_trainer(model, optimizer, loss_fn, cuda=False):\n    \"\"\"\n    Factory function for creating a trainer for supervised models\n\n    Args:\n        model (torch.nn.Module): the model to train\n        optimizer (torch.optim.Optimizer): the optimizer to use\n        loss_fn (torch.nn loss function): the loss function to use\n        cuda (bool, optional): whether or not to transfer batch to GPU (default: False)\n\n    Returns:\n        Trainer: a trainer instance with supervised update function\n    \"\"\"\n\n    def _prepare_batch(batch):\n        x, y = batch\n        x = to_variable(x, cuda=cuda)\n        y = to_variable(y, cuda=cuda)\n        return x, y\n\n    def _update(batch):\n        model.train()\n        optimizer.zero_grad()\n        x, y = _prepare_batch(batch)\n        y_pred = model(x)\n        loss = loss_fn(y_pred, y)\n        loss.backward()\n        optimizer.step()\n        return loss.data.cpu()[0]\n\n    return Trainer(_update)\n", "path": "ignite/trainer.py"}], "after_files": [{"content": "import logging\nfrom abc import ABCMeta, abstractmethod\nfrom enum import Enum\nimport time\n\nfrom ignite.history import History\nfrom ignite._utils import _to_hours_mins_secs\n\n\nclass Events(Enum):\n    EPOCH_STARTED = \"epoch_started\"\n    EPOCH_COMPLETED = \"epoch_completed\"\n    STARTED = \"started\"\n    COMPLETED = \"completed\"\n    ITERATION_STARTED = \"iteration_started\"\n    ITERATION_COMPLETED = \"iteration_completed\"\n    EXCEPTION_RAISED = \"exception_raised\"\n\n\nclass Engine(object):\n    __metaclass__ = ABCMeta\n\n    \"\"\"\n    Abstract Engine class that is the super class of the Trainer and Evaluator engines.\n\n    Parameters\n    ----------\n    process_function : callable\n        A function receiving the current training batch in each iteration, outputing data to be stored in the history\n\n    \"\"\"\n    def __init__(self, process_function):\n        self._event_handlers = {}\n        self._logger = logging.getLogger(__name__ + \".\" + self.__class__.__name__)\n        self._logger.addHandler(logging.NullHandler())\n        self._process_function = process_function\n        self.current_iteration = 0\n        self.history = History()\n        self.should_terminate = False\n\n        if self._process_function is None:\n            raise ValueError(\"Engine must be given a processing function in order to run\")\n\n    def add_event_handler(self, event_name, handler, *args, **kwargs):\n        \"\"\"\n        Add an event handler to be executed when the specified event is fired\n\n        Parameters\n        ----------\n        event_name: enum\n            event from ignite.trainer.TrainingEvents to attach the\n            handler to\n        handler: Callable\n            the callable event handler that should be invoked\n        args:\n            optional args to be passed to `handler`\n        kwargs:\n            optional keyword args to be passed to `handler`\n\n        Returns\n        -------\n        None\n        \"\"\"\n        if event_name not in Events.__members__.values():\n            self._logger.error(\"attempt to add event handler to an invalid event %s \", event_name)\n            raise ValueError(\"Event {} is not a valid event for this Engine\".format(event_name))\n\n        if event_name not in self._event_handlers:\n            self._event_handlers[event_name] = []\n\n        self._event_handlers[event_name].append((handler, args, kwargs))\n        self._logger.debug(\"added handler for event % \", event_name)\n\n    def on(self, event_name, *args, **kwargs):\n        \"\"\"\n        Decorator shortcut for add_event_handler\n\n        Parameters\n        ----------\n        event_name: enum\n            event to attach the handler to\n        args:\n            optional args to be passed to `handler`\n        kwargs:\n            optional keyword args to be passed to `handler`\n\n        Returns\n        -------\n        None\n        \"\"\"\n        def decorator(f):\n            self.add_event_handler(event_name, f, *args, **kwargs)\n            return f\n        return decorator\n\n    def _fire_event(self, event_name):\n        if event_name in self._event_handlers.keys():\n            self._logger.debug(\"firing handlers for event %s \", event_name)\n            for func, args, kwargs in self._event_handlers[event_name]:\n                func(self, *args, **kwargs)\n\n    def terminate(self):\n        \"\"\"\n        Sends terminate signal to the engine, so that it terminates after the current iteration\n        \"\"\"\n        self._logger.info(\"Terminate signaled. Engine will stop after current iteration is finished\")\n        self.should_terminate = True\n\n    def _run_once_on_dataset(self, dataset):\n        self.dataset = dataset\n        try:\n            start_time = time.time()\n            for batch in dataset:\n                self.current_iteration += 1\n                self._fire_event(Events.ITERATION_STARTED)\n                step_result = self._process_function(batch)\n                if step_result is not None:\n                    self.history.append(step_result)\n\n                self._fire_event(Events.ITERATION_COMPLETED)\n                if self.should_terminate:\n                    break\n\n            time_taken = time.time() - start_time\n            hours, mins, secs = _to_hours_mins_secs(time_taken)\n            return hours, mins, secs\n        except BaseException as e:\n            self._logger.error(\"Current run is terminating due to exception: %s\", str(e))\n            self._fire_event(Events.EXCEPTION_RAISED)\n            raise e\n\n    @abstractmethod\n    def run(self, data, **kwargs):\n        \"\"\"\n        Train the model, evaluate the validation set and update best parameters if the validation loss\n        improves.\n        In the event that the validation set is not run (or doesn't exist), the training loss is used\n        to update the best parameters.\n\n        Parameters\n        ----------\n        data : Iterable\n            Collection of batches allowing for the engine to iterate over(e.g., list or DataLoader)\n        **kwargs: optional\n            Any additional kwargs\n\n        Returns\n        -------\n        None\n        \"\"\"\n        raise NotImplementedError(\"This method should be implemented by a subclass\")\n", "path": "ignite/engine.py"}, {"content": "from __future__ import division\n\nimport time\nfrom collections import Iterable\nfrom torch.autograd import Variable\n\nfrom ignite.engine import Engine, Events\nfrom ignite._utils import _to_hours_mins_secs, to_variable\n\n__all__ = [\"Trainer\", \"create_supervised_trainer\"]\n\n\nclass Trainer(Engine):\n    \"\"\"\n    Generic trainer class.\n\n    Training update and validation functions receive batches of data and return values which will\n    be stored in the `training_history` and `validation_history`. The trainer defines multiple\n    events in `TrainingEvents` for which the user can attach event handlers to. The events get\n    passed the trainer, so they can access the training/validation history\n\n\n    Parameters\n    ----------\n    training_update_function : callable\n        Update function receiving the current training batch in each iteration\n    \"\"\"\n\n    def __init__(self, training_update_function):\n        super(Trainer, self).__init__(training_update_function)\n        self.current_epoch = 0\n        self.max_epochs = 0\n\n    def _train_one_epoch(self, training_data):\n        hours, mins, secs = self._run_once_on_dataset(training_data)\n        self._logger.info(\"Epoch[%s] Complete. Time taken: %02d:%02d:%02d\", self.current_epoch, hours,\n                          mins, secs)\n\n    def run(self, training_data, max_epochs=1):\n        \"\"\"\n        Train the model, evaluate the validation set and update best parameters if the validation loss\n        improves.\n        In the event that the validation set is not run (or doesn't exist), the training loss is used\n        to update the best parameters.\n\n        Parameters\n        ----------\n        training_data : Iterable\n            Collection of training batches allowing repeated iteration (e.g., list or DataLoader)\n        max_epochs: int, optional\n            max epochs to train for [default=1]\n\n        Returns\n        -------\n        None\n        \"\"\"\n        self.dataset = training_data\n        self.current_iteration = 0\n        self.current_epoch = 0\n\n        try:\n            self._logger.info(\"Training starting with max_epochs={}\".format(max_epochs))\n\n            self.max_epochs = max_epochs\n\n            start_time = time.time()\n\n            self._fire_event(Events.STARTED)\n            while self.current_epoch < max_epochs and not self.should_terminate:\n                self.current_epoch += 1\n                self._fire_event(Events.EPOCH_STARTED)\n                self._train_one_epoch(training_data)\n                if self.should_terminate:\n                    break\n                self._fire_event(Events.EPOCH_COMPLETED)\n\n            self._fire_event(Events.COMPLETED)\n            time_taken = time.time() - start_time\n            hours, mins, secs = _to_hours_mins_secs(time_taken)\n            self._logger.info(\"Training complete. Time taken %02d:%02d:%02d\" % (hours, mins, secs))\n\n        except BaseException as e:\n            self._logger.error(\"Training is terminating due to exception: %s\", str(e))\n            self._fire_event(Events.EXCEPTION_RAISED)\n            raise e\n\n\ndef create_supervised_trainer(model, optimizer, loss_fn, cuda=False):\n    \"\"\"\n    Factory function for creating a trainer for supervised models\n\n    Args:\n        model (torch.nn.Module): the model to train\n        optimizer (torch.optim.Optimizer): the optimizer to use\n        loss_fn (torch.nn loss function): the loss function to use\n        cuda (bool, optional): whether or not to transfer batch to GPU (default: False)\n\n    Returns:\n        Trainer: a trainer instance with supervised update function\n    \"\"\"\n\n    def _prepare_batch(batch):\n        x, y = batch\n        x = to_variable(x, cuda=cuda)\n        y = to_variable(y, cuda=cuda)\n        return x, y\n\n    def _update(batch):\n        model.train()\n        optimizer.zero_grad()\n        x, y = _prepare_batch(batch)\n        y_pred = model(x)\n        loss = loss_fn(y_pred, y)\n        loss.backward()\n        optimizer.step()\n        return loss.data.cpu()[0]\n\n    return Trainer(_update)\n", "path": "ignite/trainer.py"}]}