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