From 726613daa929d12c8ef1bba65ae4df3f12ceec05 Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Thu, 27 Sep 2018 16:18:22 +0200
Subject: [PATCH] Add a cache restoring context manager

---
 python/dune/perftool/generation/__init__.py |  3 ++-
 python/dune/perftool/generation/cache.py    |  2 +-
 python/dune/perftool/generation/context.py  | 19 +++++++++++++++++++
 python/dune/perftool/sumfact/autotune.py    |  6 ++++--
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/python/dune/perftool/generation/__init__.py b/python/dune/perftool/generation/__init__.py
index e541e713..b3974b5d 100644
--- a/python/dune/perftool/generation/__init__.py
+++ b/python/dune/perftool/generation/__init__.py
@@ -49,6 +49,7 @@ from dune.perftool.generation.loopy import (barrier,
                                             valuearg,
                                             )
 
-from dune.perftool.generation.context import (global_context,
+from dune.perftool.generation.context import (cache_restoring,
+                                              global_context,
                                               get_global_context_value,
                                               )
diff --git a/python/dune/perftool/generation/cache.py b/python/dune/perftool/generation/cache.py
index b4ae54f2..31b1b85e 100644
--- a/python/dune/perftool/generation/cache.py
+++ b/python/dune/perftool/generation/cache.py
@@ -268,7 +268,7 @@ def delete_cache_items(condition=True, keep=False):
         gen._memoize_cache = _filter_cache_items(gen, condition)
 
 
-def retrieve_cache_functions(condition=True):
+def retrieve_cache_functions(condition="True"):
     return [g.func for g in _generators if eval(condition, _ConditionDict(g.item_tags))]
 
 
diff --git a/python/dune/perftool/generation/context.py b/python/dune/perftool/generation/context.py
index 55feda42..2dca239d 100644
--- a/python/dune/perftool/generation/context.py
+++ b/python/dune/perftool/generation/context.py
@@ -31,3 +31,22 @@ def global_context(**kwargs):
 
 def get_global_context_value(key, default=None):
     return _global_context_cache.get(key, default)
+
+
+class _CacheRestoringContext(object):
+    def __enter__(self):
+        from dune.perftool.generation.cache import _generators as g
+        self.cache = {}
+        for i in g:
+            self.cache[i] = {}
+            for k, v in i._memoize_cache.items():
+                self.cache[i][k] = v
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        for i, c in self.cache.items():
+            for k, v in c.items():
+                i._memoize_cache[k] = v
+
+
+def cache_restoring():
+    return _CacheRestoringContext()
diff --git a/python/dune/perftool/sumfact/autotune.py b/python/dune/perftool/sumfact/autotune.py
index 8d171ecf..8199196f 100644
--- a/python/dune/perftool/sumfact/autotune.py
+++ b/python/dune/perftool/sumfact/autotune.py
@@ -1,6 +1,6 @@
 """ Autotuning for sum factorization kernels """
 
-from dune.perftool.generation import delete_cache_items
+from dune.perftool.generation import cache_restoring, delete_cache_items
 from dune.perftool.loopy.target import DuneTarget
 from dune.perftool.sumfact.realization import realize_sumfact_kernel_function
 from dune.perftool.options import get_option
@@ -169,7 +169,9 @@ def autotune_realization(sf):
     logname = "{}.log".format(name)
 
     # Generate and compile a benchmark program
-    generate_standalone_code(sf, filename, logname)
+    with cache_restoring():
+        generate_standalone_code(sf, filename, logname)
+
     ret = subprocess.call(compiler_invocation(name, filename))
     assert ret == 0
 
-- 
GitLab