Repository: pytorch/ignite

Issue:
EpochOutputStore can optionally store the data to the state
## 🚀 Feature

The idea is to give an option to have the following:
```python
eos = EpochOutputStore()

evaluator = create_supervised_evaluator(model, metrics)
eos.attach(evaluator, name="eval_data")

# Adding the name is equivalent to
# name = "eval_data"
# @evaluator.on(Events.EPOCH_COMPLETED, name)
# def store_data(engine, name):
#     setattr(engine.state, name, eos.data)

state = evaluator.run(data)
print(len(state.eval_data))
```

In addition, it would make sense to move it from contrib to core as well, keeping BC.


Discussion:
Read the code of `EpochOutputStore` and I think I understand what this is about :slightly_smiling_face: Maybe this is something I could work on after I finish #1919?

Could I please ask what BC stands for? 
There is 2 meaning AFAIK
Here BC means Backward Compatibility
Another one is Breaking Change
Thanks Jeff! 

@radekosmulski Yes, BC is backward compatibility and a PR breaking it is called "BC-breaking" as far as I know.
@radekosmulski would you like to work on this issue ?
@vfdev-5 - would love to! Will read through the code today and either come here to ask questions if anything is unclear or will start working on a draft of the implementation :slightly_smiling_face: 
I opened #1974 but it is probably quite basic, happy to implement any changes that might be needed :slightly_smiling_face: 

This is only a draft - as a next step, will move it out of contrib keeping BC.

Resolving patch:
diff --git a/ignite/contrib/handlers/__init__.py b/ignite/contrib/handlers/__init__.py
--- a/ignite/contrib/handlers/__init__.py
+++ b/ignite/contrib/handlers/__init__.py
@@ -12,11 +12,11 @@
     create_lr_scheduler_with_warmup,
 )
 from ignite.contrib.handlers.polyaxon_logger import PolyaxonLogger
-from ignite.contrib.handlers.stores import EpochOutputStore
 from ignite.contrib.handlers.tensorboard_logger import TensorboardLogger
 from ignite.contrib.handlers.time_profilers import BasicTimeProfiler, HandlersTimeProfiler
 from ignite.contrib.handlers.tqdm_logger import ProgressBar
 from ignite.contrib.handlers.trains_logger import TrainsLogger
 from ignite.contrib.handlers.visdom_logger import VisdomLogger
 from ignite.contrib.handlers.wandb_logger import WandBLogger
+from ignite.handlers import EpochOutputStore  # ref
 from ignite.handlers import global_step_from_engine  # ref
diff --git a/ignite/handlers/__init__.py b/ignite/handlers/__init__.py
--- a/ignite/handlers/__init__.py
+++ b/ignite/handlers/__init__.py
@@ -4,6 +4,7 @@
 from ignite.engine.events import Events
 from ignite.handlers.checkpoint import Checkpoint, DiskSaver, ModelCheckpoint
 from ignite.handlers.early_stopping import EarlyStopping
+from ignite.handlers.stores import EpochOutputStore
 from ignite.handlers.terminate_on_nan import TerminateOnNan
 from ignite.handlers.time_limit import TimeLimit
 from ignite.handlers.timing import Timer
@@ -17,6 +18,7 @@
     "TerminateOnNan",
     "global_step_from_engine",
     "TimeLimit",
+    "EpochOutputStore",
 ]
 
 
diff --git a/ignite/contrib/handlers/stores.py b/ignite/handlers/stores.py
similarity index 88%
rename from ignite/contrib/handlers/stores.py
rename to ignite/handlers/stores.py
--- a/ignite/contrib/handlers/stores.py
+++ b/ignite/handlers/stores.py
@@ -1,4 +1,4 @@
-from typing import Callable, List, Optional, Tuple, Union
+from typing import Any, Callable, List, Optional
 
 from ignite.engine import Engine, Events
 
@@ -16,6 +16,10 @@ class EpochOutputStore:
             transform the :class:`~ignite.engine.engine.Engine`'s
             ``process_function``'s output , e.g., lambda x: x[0]
 
+    Attributes:
+        data: a list of :class:`~ignite.engine.engine.Engine` outputs,
+            optionally transformed by `output_transform`.
+
     Examples::
 
         eos = EpochOutputStore()
@@ -27,6 +31,7 @@ class EpochOutputStore:
         def log_training_results(engine):
             train_evaluator.run(train_loader)
             output = train_evaluator.output
+            # output = [(y_pred0, y0), (y_pred1, y1), ...]
             # do something with output, e.g., plotting
 
     .. versionadded:: 0.4.2
@@ -35,7 +40,7 @@ def log_training_results(engine):
     """
 
     def __init__(self, output_transform: Callable = lambda x: x):
-        self.data = []  # type: List[Union[int, Tuple[int, int]]]
+        self.data = []  # type: List[Any]
         self.output_transform = output_transform
 
     def reset(self) -> None:


Test patch:
diff --git a/tests/ignite/contrib/handlers/test_stores.py b/tests/ignite/handlers/test_stores.py
similarity index 96%
rename from tests/ignite/contrib/handlers/test_stores.py
rename to tests/ignite/handlers/test_stores.py
--- a/tests/ignite/contrib/handlers/test_stores.py
+++ b/tests/ignite/handlers/test_stores.py
@@ -1,7 +1,7 @@
 import pytest
 
-from ignite.contrib.handlers import EpochOutputStore
 from ignite.engine.engine import Engine, Events
+from ignite.handlers import EpochOutputStore
 
 
 @pytest.fixture