diff --git a/python/dune/perftool/cgen/clazz.py b/python/dune/perftool/cgen/clazz.py
index 7bcd5e8bab3435c4c92f440caae27c4241317b96..c673b7c495007591e34dd105beb49c7027b72a55 100644
--- a/python/dune/perftool/cgen/clazz.py
+++ b/python/dune/perftool/cgen/clazz.py
@@ -1,3 +1,5 @@
+from dune.perftool.error import PerftoolCodegenError
+
 from cgen import Generable, Block
 
 
@@ -14,7 +16,7 @@ def access_modifier_string(am):
         return "public"
     if am == AccessModifier.PROTECTED:
         return "protected"
-    raise ValueError("Unknown access modifier in class generation")
+    raise PerftoolCodegenError("Unknown access modifier in class generation")
 
 
 class BaseClass(Generable):
diff --git a/python/dune/perftool/error.py b/python/dune/perftool/error.py
new file mode 100644
index 0000000000000000000000000000000000000000..2ee56bca6e3bf6f3018c8fe599f4d55eb9fb7139
--- /dev/null
+++ b/python/dune/perftool/error.py
@@ -0,0 +1,16 @@
+""" Some error classes for dune-perftool """
+
+class PerftoolError(Exception):
+    pass
+
+
+class PerftoolUFLError(PerftoolError):
+    pass
+
+
+class PerftoolCodegenError(PerftoolError):
+    pass
+
+
+class PerftoolLoopyError(PerftoolError):
+    pass
\ No newline at end of file
diff --git a/python/dune/perftool/generation/loopy.py b/python/dune/perftool/generation/loopy.py
index 451149cf4f2e92a5b0903368a696cc7500bc9923..6266b5fbb3a83aa6472700e844344bd5ab7e5fc0 100644
--- a/python/dune/perftool/generation/loopy.py
+++ b/python/dune/perftool/generation/loopy.py
@@ -7,6 +7,7 @@ from dune.perftool.generation import (get_counter,
                                       preamble,
                                       )
 from dune.perftool.generation.context import get_global_context_value
+from dune.perftool.error import PerftoolLoopyError
 
 import loopy
 import numpy
@@ -125,10 +126,3 @@ def instruction(code=None, expression=None, **kwargs):
 @generator_factory(item_tags=("instruction",), cache_key_generator=lambda **kw: kw['id'])
 def noop_instruction(**kwargs):
     return loopy.NoOpInstruction(**kwargs)
-
-
-@generator_factory(item_tags=("transformation",),
-                   cache_key_generator=no_caching,
-                   )
-def transform(trafo, *args):
-    return (trafo, args)
diff --git a/python/dune/perftool/loopy/buffer.py b/python/dune/perftool/loopy/buffer.py
index 7999ef4ea3b4f9fd3b141e8ad52398b1ea1aae7c..bd94d995a847e3f4a5eaf2648fc41124fe4d4cea 100644
--- a/python/dune/perftool/loopy/buffer.py
+++ b/python/dune/perftool/loopy/buffer.py
@@ -1,3 +1,4 @@
+from dune.perftool.error import PerftoolLoopyError
 from dune.perftool.generation import (generator_factory,
                                       temporary_variable,
                                       )
@@ -46,7 +47,7 @@ class FlipFlopBuffer(object):
 @generator_factory(item_tags=("kernel", "buffer"), cache_key_generator=lambda i, **kw: i)
 def initialize_buffer(identifier, base_storage_size=None, num=2):
     if base_storage_size is None:
-        raise ValueError("The buffer for identifier {} has not been initialized.".format(identifier))
+        raise PerftoolLoopyError("The buffer for identifier {} has not been initialized.".format(identifier))
     return FlipFlopBuffer(identifier,
                           base_storage_size=base_storage_size,
                           num=num,
diff --git a/python/dune/perftool/loopy/temporary.py b/python/dune/perftool/loopy/temporary.py
index cfbfa5764e678831d5c52ad2c4eb92c7e81764e9..f74e2dc68987e39ca6a2697d69e36530ed98d07a 100644
--- a/python/dune/perftool/loopy/temporary.py
+++ b/python/dune/perftool/loopy/temporary.py
@@ -1,6 +1,7 @@
 """
 Class for temporary variables that allows us to use very non-standard types.
 """
+from dune.perftool.error import PerftoolLoopyError
 
 from loopy import TemporaryVariable
 
@@ -12,7 +13,7 @@ def _temporary_type(shape_impl, shape, first=True):
         return 'double'
     if shape_impl[0] == 'arr':
         if not first or len(set(shape_impl)) != 1:
-            raise ValueError("We do not allow mixing of C++ containers and plain C arrays, for reasons of mental sanity")
+            raise PerftoolLoopyError("We do not allow mixing of C++ containers and plain C arrays, for reasons of mental sanity")
         return 'double'
     if shape_impl[0] == 'vec':
         return "std::vector<{}>".format(_temporary_type(shape_impl[1:], shape[1:], first=False))
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index abb8938c6f0bb786aa0cef1f08c5ee880f05fffe..6d47731038bb96652cf7f50fa27f3791a224423e 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -6,6 +6,7 @@ Currently, these are hardcoded as strings. It would be possible
 to switch these to cgen expression. OTOH, there is not much to be
 gained there.
 """
+from dune.perftool.error import PerftoolCodegenError
 from dune.perftool.generation import (generator_factory,
                                       include_file,
                                       cached,
@@ -188,7 +189,7 @@ def typedef_grid(name):
             gridt = "Dune::ALUGrid<{}, {}, Dune::simplex, Dune::conforming>".format(dim, dim)
             include_file("dune/alugrid/grid.hh", filetag="driver")
         else:
-            raise ValueError("Cant match your geometry with a DUNE grid. Please report bug.")
+            raise PerftoolCodegenError("Cant match your geometry with a DUNE grid. Please report bug.")
     return "using {} = {};".format(name, gridt)
 
 
diff --git a/python/dune/perftool/ufl/execution.py b/python/dune/perftool/ufl/execution.py
index 32717a9ed2b703eaf2fe44e9081e61fdc98f82a2..57d337fbe541beb5de6afe429c5a3930dccf962e 100644
--- a/python/dune/perftool/ufl/execution.py
+++ b/python/dune/perftool/ufl/execution.py
@@ -2,6 +2,7 @@
 So, this module contains all our extensions and monkey patches to
 UFL.
 """
+from dune.perftool.error import PerftoolUFLError
 
 import ufl
 
@@ -22,7 +23,7 @@ class TrialFunction(ufl.Coefficient):
     """ A coefficient that always takes the reserved index 0 """
     def __init__(self, element, count=None):
         if count and count is not 0:
-            raise ValueError("The trial function must be the coefficient of index 0 in uflpdelab")
+            raise PerftoolUFLError("The trial function must be the coefficient of index 0 in uflpdelab")
         ufl.Coefficient.__init__(self, element, count=0)
 
 
@@ -30,9 +31,9 @@ class Coefficient(ufl.Coefficient):
     """ A coefficient that honors the reserved index 0. """
     def __init__(self, element, count=None):
         if count and count is 0:
-            raise ValueError("The coefficient of index 0 is reserved for the trial function in uflpdelab")
+            raise PerftoolUFLError("The coefficient of index 0 is reserved for the trial function in uflpdelab")
         if count and count is 1:
-            raise ValueError("The coefficient of index 1 is reserved for the jacobian apply vector in uflpdelab")
+            raise PerftoolUFLError("The coefficient of index 1 is reserved for the jacobian apply vector in uflpdelab")
         if not count and ufl.Coefficient._globalcount < 2:
             count = 2
         ufl.Coefficient.__init__(self, element, count)