From 6d32cf08f115b95dc3a406d0c33f4eb0c5d8e56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20He=C3=9F?= <rene.hess@iwr.uni-heidelberg.de> Date: Tue, 10 Jan 2017 13:05:39 +0100 Subject: [PATCH] Allow different instrumentation levels for opcounting problems --- python/dune/perftool/options.py | 2 +- python/dune/perftool/pdelab/driver.py | 79 +++++++++++-------- python/dune/perftool/pdelab/localoperator.py | 2 + test/poisson/opcount_poisson_dg_symdiff.mini | 3 +- .../poisson/opcount_poisson_2d_order2.mini | 1 + .../opcount_sumfact_poisson_dg_2d_vec.mini | 2 + 6 files changed, 54 insertions(+), 35 deletions(-) diff --git a/python/dune/perftool/options.py b/python/dune/perftool/options.py index b521bf6d..9f75b3ce 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 775b3bda..f6a2052d 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 839c57f8..3e389c5a 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 e87f17a5..7cc43b6b 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 7c52a120..627f5bb3 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 9ae884dd..b7e8b6c7 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 -- GitLab