From 3e9f1e00feff62670888a307562092cb6b015099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20He=C3=9F?= <rene@debian> Date: Fri, 30 Sep 2016 15:47:07 +0200 Subject: [PATCH] Test cache behaviour --- python/CMakeLists.txt | 2 + python/dune/perftool/pdelab/localoperator.py | 4 +- python/test/CMakeLists.txt | 1 + python/test/dune/CMakeLists.txt | 1 + python/test/dune/perftool/CMakeLists.txt | 1 + .../dune/perftool/generation/CMakeLists.txt | 3 + .../dune/perftool/generation/test_cache.py | 233 ++++++++++++++++++ 7 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 python/test/CMakeLists.txt create mode 100644 python/test/dune/CMakeLists.txt create mode 100644 python/test/dune/perftool/CMakeLists.txt create mode 100644 python/test/dune/perftool/generation/CMakeLists.txt create mode 100644 python/test/dune/perftool/generation/test_cache.py diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 3e72e618..b04dea7b 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -20,3 +20,5 @@ dune_install_python_package(PATH .) add_python_test_command(COMMAND python -m pytest --pep8 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/python/dune/perftool REQUIRED_PACKAGES pytest pytest-pep8) + +add_subdirectory(test) diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index 7936437e..475c052d 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -471,7 +471,7 @@ def generate_localoperator_kernels(formdata, data): # Numerical jacobian apply initializer list initializer_list("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype), ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())], - classtag="operator", + classtag="operator", ) else: # Numerical nonlinear jacobian apply base class @@ -480,7 +480,7 @@ def generate_localoperator_kernels(formdata, data): # Numerical nonlinear jacobian apply initializer list initializer_list("Dune::PDELab::NumericalNonlinearJacobianApply{}<{}>".format(which, loptype), ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())], - classtag="operator", + classtag="operator", ) operator_kernels[(measure, 'residual')] = kernel diff --git a/python/test/CMakeLists.txt b/python/test/CMakeLists.txt new file mode 100644 index 00000000..22fc2134 --- /dev/null +++ b/python/test/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(dune) diff --git a/python/test/dune/CMakeLists.txt b/python/test/dune/CMakeLists.txt new file mode 100644 index 00000000..aa7576d1 --- /dev/null +++ b/python/test/dune/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(perftool) diff --git a/python/test/dune/perftool/CMakeLists.txt b/python/test/dune/perftool/CMakeLists.txt new file mode 100644 index 00000000..f7023229 --- /dev/null +++ b/python/test/dune/perftool/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(generation) diff --git a/python/test/dune/perftool/generation/CMakeLists.txt b/python/test/dune/perftool/generation/CMakeLists.txt new file mode 100644 index 00000000..47b168ae --- /dev/null +++ b/python/test/dune/perftool/generation/CMakeLists.txt @@ -0,0 +1,3 @@ +add_python_test_command(COMMAND python -m pytest --pep8 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/python/test/dune/perftool/generation + REQUIRED_PACKAGES pytest pytest-pep8) diff --git a/python/test/dune/perftool/generation/test_cache.py b/python/test/dune/perftool/generation/test_cache.py new file mode 100644 index 00000000..4bdc47ae --- /dev/null +++ b/python/test/dune/perftool/generation/test_cache.py @@ -0,0 +1,233 @@ +from collections import Counter + +from dune.perftool.generation.cache import(delete_cache_items, + generator_factory, + no_caching, + retrieve_cache_functions, + retrieve_cache_items, + ) + + +def print_cache(): + """Print all cache items""" + for i in retrieve_cache_items("True"): + print i + + +# ================================================ +# Test retrieve_cache_items and delete_cache_items +# ================================================ + + +# Some generators +gen_foo = generator_factory(item_tags=("foo",)) +gen_bar = generator_factory(item_tags=("bar",)) +gen_foobar = generator_factory(item_tags=("foo", "bar")) + + +# Some decorated functions +@gen_foo +def foo(name): + return "foo {}".format(name) + + +@gen_bar +def bar(name): + return "bar {}".format(name) + + +@gen_foobar +def foobar(name): + return "foobar {}".format(name) + + +# Will add two cache entries one with tag foo and one with tag bar +@gen_foo +@gen_bar +def foobar_two(name): + return "foobar_two {}".format(name) + + +def setup_cache(): + """Empty cache and fill it in a specific way + + After calling this function the cache will be filled with the + following entries: + + foo foo (tag foo) + foobar_two foobar_two_1 (tag foo) + bar bar_1 (tag bar) + bar bar_2 (tag bar) + foobar_two foobar_two_1 (tag bar) + foobar foobar (tag foo and bar) + + """ + delete_cache_items() + assert not list(retrieve_cache_items("True")) + + foo("foo") + bar("bar_1") + bar("bar_2") + foobar("foobar") + foobar_two("foobar_two") + + # This call shouldn't change anything + foo("foo") + + # print_cache() + + +# Some lists for comparison +# Empty +list_empty = [] +list_not_foo_not_bar = [] + + +# One field +list_foo_not_bar = ["foo foo", "foobar_two foobar_two"] +list_not_foo_and_bar = ["bar bar_1", "bar bar_2", "foobar_two foobar_two"] +list_foo_and_bar = ["foobar foobar"] + + +# Two fields +list_foo = list_foo_not_bar + list_foo_and_bar +list_bar = list_not_foo_and_bar + list_foo_and_bar +list_not_foobar = list_foo_not_bar + list_not_foo_and_bar + + +# All three fields +list_foo_or_bar = list_foo_not_bar + list_not_foo_and_bar + list_foo_and_bar +list_full = list_foo_or_bar + + +def compare(x, y): + """Compare if lists x and y have the same entries + + Having the same entries means: + + - If item a can be found k times in x it must also be k times in y + - Vice versa. + - Ordering of items doesn't matter. + """ + return Counter(x) == Counter(y) + + +def test_retrieve_cache(): + """Test all combinations of retrieve_cache for our test setup""" + # Setup cache in the way descibed above + setup_cache() + + # Load global lists for comparison + global list_empty + global list_not_foo_not_bar + + global list_foo_not_bar + global list_not_foo_and_bar + global list_foo_and_bar + + global list_foo + global list_bar + global list_not_foobar + + global list_foo_or_bar + global list_full + + # Empty + assert compare(list_empty, list(retrieve_cache_items("False"))) + assert compare(list_not_foo_not_bar, list(retrieve_cache_items("not foo and not bar"))) + + # One field + assert compare(list_foo_not_bar, list(retrieve_cache_items("foo and not bar"))) + assert compare(list_not_foo_and_bar, list(retrieve_cache_items("not foo and bar"))) + assert compare(list_foo_and_bar, list(retrieve_cache_items("foo and bar"))) + + # Two fields + assert compare(list_foo, list(retrieve_cache_items("foo"))) + assert compare(list_bar, list(retrieve_cache_items("bar"))) + assert compare(list_not_foobar, list(retrieve_cache_items("not (foo and bar)"))) + + # All three fields + assert compare(list_foo_or_bar, list(retrieve_cache_items("foo or bar"))) + assert compare(list_full, list(retrieve_cache_items("True"))) + + +def test_delete_cache_items(): + """Test all combinations of delete_cache_items for our test setup""" + # Load global list used for comparison + global list_empty + global list_not_foo_not_bar + + global list_foo_not_bar + global list_not_foo_and_bar + global list_foo_and_bar + + global list_foo + global list_bar + global list_not_foobar + + global list_foo_or_bar + global list_full + + # Tests deleting "all three fields" + setup_cache() + delete_cache_items("True") + assert compare(list_empty, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("foo or bar") + assert compare(list_not_foo_not_bar, list(retrieve_cache_items("True"))) + + # Tests deleting "two fields" + setup_cache() + delete_cache_items("bar") + assert compare(list_foo_not_bar, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("foo") + assert compare(list_not_foo_and_bar, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("(foo and not bar) or (not foo and bar)") + assert compare(list_foo_and_bar, list(retrieve_cache_items("True"))) + + # Tests deleting "one field" + setup_cache() + delete_cache_items("not foo and bar") + assert compare(list_foo, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("foo and not bar") + assert compare(list_bar, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("foo and bar") + assert compare(list_not_foobar, list(retrieve_cache_items("True"))) + + # Tests deleting nothing + setup_cache() + delete_cache_items("not foo and not bar") + assert compare(list_foo_or_bar, list(retrieve_cache_items("True"))) + + setup_cache() + delete_cache_items("False") + assert compare(list_full, list(retrieve_cache_items("True"))) + + +# =============== +# Test no caching +# =============== + + +@generator_factory(item_tags=("no_caching",), cache_key_generator=no_caching) +def no_caching_function(name): + return "{}".format(name) + + +def test_no_caching_function(): + delete_cache_items() + no_caching_function("one") + assert compare(["one"], list(retrieve_cache_items("no_caching"))) + no_caching_function("one") + assert compare(["one", "one"], list(retrieve_cache_items("no_caching"))) + no_caching_function("two") + assert compare(["one", "one", "two"], list(retrieve_cache_items("no_caching"))) -- GitLab