diff --git a/python/dune/perftool/options.py b/python/dune/perftool/options.py
index b521bf6dc61b99c0c614116fada26f476926e51a..9f75b3cebf075ab3dc6280f0d563bf9e039b9597 100644
--- a/python/dune/perftool/options.py
+++ b/python/dune/perftool/options.py
@@ -39,7 +39,7 @@ def get_form_compiler_arguments():
     parser.add_argument("--diagonal-transformation-matrix", action="store_true", help="set option if the jacobian of the transformation is diagonal (axiparallel grids)")
     parser.add_argument("--constant-transformation-matrix", action="store_true", help="set option if the jacobian of the transformation is constant on a cell")
     parser.add_argument("--ini-file", type=str, help="An inifile to use. A generated driver will be hard-coded to it, a [formcompiler] section will be used as default values to form compiler arguments (use snake case)")
-    parser.add_argument("--opcounter", action="store_true", help="Count operations. Note: In this case only oparor applications are generated since solving and operator counting does not work.")
+    parser.add_argument("--opcounter", action="store_true", help="Count operations. Note: In this case only oparor applications are generated since solving and operator counting does not work. You probably want to set instrumentation level>0.")
     parser.add_argument("--time-opcounter", action="store_true", help="Generate opcounter codepath. Can be used for timing opcounter programs without setting the opcounter option.")
     parser.add_argument("--instrumentation-level", type=int, default=0, help="Control time/opcounter measurements. 0-do nothing, 1-measure program as a whole, 2-operator applications, 3-measure kernel (eg. alpha-volume, ...), 4-parts of kernel (eg. stage 1-3 of SF)")
     parser.add_argument("--project-basedir", type=str, help="The base (build) directory of the dune-perftool project")
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index 775b3bda292210ab142d4c37dcfde16cf3852fe5..f6a2052de91935f8f26635c13d115a9438d2b5e2 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -1152,6 +1152,7 @@ def define_timing_stream(name):
 
 
 def name_timing_stream():
+    define_exec()
     name = "timestream"
     define_timing_stream(name)
     return name
@@ -1197,7 +1198,6 @@ def dune_solve():
         from dune.perftool.generation import get_global_context_value
         formdatas = get_global_context_value("formdatas")
         print_times = []
-        define_exec()
         for formdata in formdatas:
             lop_name = name_localoperator(formdata)
             timestream = name_timing_stream()
@@ -1393,8 +1393,6 @@ def name_test_fail_variable():
 
 @cached
 def setup_timer():
-    assert(get_option('instrumentation_level') >= 1)
-
     # Necessary includes and defines
     from dune.perftool.generation import pre_include
 
@@ -1416,27 +1414,32 @@ def evaluate_residual_timer():
     n_go = name_gridoperator(formdata)
     v = name_vector(formdata)
     t_v = type_vector(formdata)
-
-    # Write back times
     setup_timer()
-    from dune.perftool.generation import post_include
-    post_include("HP_DECLARE_TIMER(residual_evaluation);", filetag="driver")
-    timestream = name_timing_stream()
-    define_exec()
-    print_times = []
+
+    if get_option('instrumentation_level') >= 2:
+        # Write back times
+        from dune.perftool.generation import post_include
+        post_include("HP_DECLARE_TIMER(residual_evaluation);", filetag="driver")
+        timestream = name_timing_stream()
+        print_times = []
+
     from dune.perftool.generation import get_global_context_value
     formdatas = get_global_context_value("formdatas")
     for formdata in formdatas:
         lop_name = name_localoperator(formdata)
-        print_times.append("{}.dump_timers({}, argv[0], true);".format(lop_name, timestream))
+        if get_option('intrumentation_level') >= 3:
+            print_times.append("{}.dump_timers({}, argv[0], true);".format(lop_name, timestream))
+
+    if get_option('instrumentation_level') >= 2:
+        evaluation = ["HP_TIMER_START(residual_evaluation);",
+                      "{}.residual({}, r);".format(n_go, v),
+                      "HP_TIMER_STOP(residual_evaluation);",
+                      "DUMP_TIMER(residual_evaluation, {}, true);".format(timestream)]
+        evaluation.extend(print_times)
+    else:
+        evaluation = ["{}.residual({}, r);".format(n_go, v)]
 
-    evaluation = ["{} r({});".format(t_v, v),
-                  "r=0.0;",
-                  "HP_TIMER_START(residual_evaluation);",
-                  "{}.residual({}, r);".format(n_go, v),
-                  "HP_TIMER_STOP(residual_evaluation);",
-                  "DUMP_TIMER(residual_evaluation, {}, true);".format(timestream)]
-    evaluation.extend(print_times)
+    evaluation = ["{} r({});".format(t_v, v), "r=0.0;"] + evaluation
 
     return evaluation
 
@@ -1448,27 +1451,33 @@ def assemble_matrix_timer():
     n_go = name_gridoperator(formdata)
     v = name_vector(formdata)
     t_v = type_vector(formdata)
-
-    # Write back times
     setup_timer()
-    from dune.perftool.generation import post_include
-    post_include("HP_DECLARE_TIMER(matrix_assembly);", filetag="driver")
-    timestream = name_timing_stream()
-    define_exec()
-    print_times = []
+
+    if get_option('instrumentation_level') >= 2:
+        # Write back times
+        from dune.perftool.generation import post_include
+        post_include("HP_DECLARE_TIMER(matrix_assembly);", filetag="driver")
+        timestream = name_timing_stream()
+        print_times = []
+
     from dune.perftool.generation import get_global_context_value
     formdatas = get_global_context_value("formdatas")
     for formdata in formdatas:
         lop_name = name_localoperator(formdata)
-        print_times.append("{}.dump_timers({}, argv[0], true);".format(lop_name, timestream))
+        if get_option('instrumentation_level') >= 3:
+            print_times.append("{}.dump_timers({}, argv[0], true);".format(lop_name, timestream))
+
+    if get_option('instrumentation_level') >= 2:
+        assembly = ["HP_TIMER_START(matrix_assembly);",
+                    "{}.jacobian({},m);".format(n_go, v),
+                    "HP_TIMER_STOP(matrix_assembly);",
+                    "DUMP_TIMER(matrix_assembly, {}, true);".format(timestream)]
+        assembly.extend(print_times)
+    else:
+        assembly = ["{}.jacobian({},m);".format(n_go, v)]
 
     assembly = ["using M = typename {}::Traits::Jacobian;".format(t_go),
-                "M m({});".format(n_go),
-                "HP_TIMER_START(matrix_assembly);",
-                "{}.jacobian({},m);".format(n_go, v),
-                "HP_TIMER_STOP(matrix_assembly);",
-                "DUMP_TIMER(matrix_assembly, {}, true);".format(timestream)]
-    assembly.extend(print_times)
+                "M m({});".format(n_go)] + assembly
 
     return assembly
 
@@ -1713,6 +1722,11 @@ def generate_driver(formdatas, data):
     else:
         solve_instationary()
 
+    # Make sure that timestream is declared before retrieving chache items
+    if get_option("instrumentation_level") >= 1:
+        setup_timer()
+        timestream = name_timing_stream()
+
     return_statement()
 
     from dune.perftool.generation import retrieve_cache_items
@@ -1726,7 +1740,6 @@ def generate_driver(formdatas, data):
         post_include("HP_DECLARE_TIMER(driver);\n", filetag="driver")
         contents.insert(0, Line(text="HP_TIMER_START(driver);\n"))
         contents.insert(len(contents) - 1, Line(text="HP_TIMER_STOP(driver);\n"))
-        timestream = name_timing_stream()
         contents.insert(len(contents) - 1, Line(text="DUMP_TIMER(driver, {}, true);\n".format(timestream)))
     contents.insert(0, Line(text="\n"))
     driver_body = Block(contents)
diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index 839c57f8f5bef06cd85a241a283684ab87311f4b..3e389c5a9913ab6d88ca5be00c1732195c88294b 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -816,6 +816,8 @@ def generate_localoperator_file(formdata, kernels, filename):
     if get_option('instrumentation_level') >= 3:
         include_file('dune/perftool/common/timer.hh', filetag='operatorfile')
         operator_methods.append(TimerMethod())
+    elif get_option('opcounter'):
+        include_file('dune/perftool/common/timer.hh', filetag='operatorfile')
 
     # Write the file!
     from dune.perftool.file import generate_file
diff --git a/test/poisson/opcount_poisson_dg_symdiff.mini b/test/poisson/opcount_poisson_dg_symdiff.mini
index e87f17a5109046fbff44d92cac4c3bd9d113ea01..7cc43b6bf4a523e22bad146e9129f8ba322e1d25 100644
--- a/test/poisson/opcount_poisson_dg_symdiff.mini
+++ b/test/poisson/opcount_poisson_dg_symdiff.mini
@@ -11,4 +11,5 @@ extension = vtu
 exact_solution_expression = g
 compare_dofs = 1e-1
 compare_l2errorsquared = 1e-4
-opcounter = 1
\ No newline at end of file
+opcounter = 1
+instrumentation_level = 3
\ No newline at end of file
diff --git a/test/sumfact/poisson/opcount_poisson_2d_order2.mini b/test/sumfact/poisson/opcount_poisson_2d_order2.mini
index 7c52a1200294e31ba8c67cb6cdfaa4770fed69ab..627f5bb3eb7cee357a8dc10db82353491153d648 100644
--- a/test/sumfact/poisson/opcount_poisson_2d_order2.mini
+++ b/test/sumfact/poisson/opcount_poisson_2d_order2.mini
@@ -17,3 +17,4 @@ exact_solution_expression = g
 compare_l2errorsquared = 1e-8
 sumfact = 1
 opcounter = 1
+instrumentation_level = 4
diff --git a/test/sumfact/poisson/opcount_sumfact_poisson_dg_2d_vec.mini b/test/sumfact/poisson/opcount_sumfact_poisson_dg_2d_vec.mini
index 9ae884ddef753819c3ea40a72548fe5fa8a9987d..b7e8b6c71db3781ea6531b391d1b236503743202 100644
--- a/test/sumfact/poisson/opcount_sumfact_poisson_dg_2d_vec.mini
+++ b/test/sumfact/poisson/opcount_sumfact_poisson_dg_2d_vec.mini
@@ -15,6 +15,8 @@ exact_solution_expression = g
 compare_l2errorsquared = 1e-8
 sumfact = 1
 opcounter = 1
+instrumentation_level = 4
+
 
 [formcompiler.ufl_variants]
 degree = 1