From 91ff1e2a080f3ca8d5900fee97799df4da19f1a0 Mon Sep 17 00:00:00 2001 From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de> Date: Wed, 21 Jun 2017 11:14:45 +0200 Subject: [PATCH] Move timings stuff to separate module Conflicts: python/dune/perftool/pdelab/driver/taskbased.py --- .../dune/perftool/pdelab/driver/__init__.py | 177 +--------------- python/dune/perftool/pdelab/driver/timings.py | 198 ++++++++++++++++++ 2 files changed, 207 insertions(+), 168 deletions(-) create mode 100644 python/dune/perftool/pdelab/driver/timings.py diff --git a/python/dune/perftool/pdelab/driver/__init__.py b/python/dune/perftool/pdelab/driver/__init__.py index c5701a37..abce3936 100644 --- a/python/dune/perftool/pdelab/driver/__init__.py +++ b/python/dune/perftool/pdelab/driver/__init__.py @@ -55,6 +55,10 @@ def get_trial_element(): return _driver_data['form'].coefficients()[0].ufl_element() +def get_formdata(): + return _driver_data['formdata'] + + def is_stationary(): return 'mass_form' not in _driver_data @@ -181,7 +185,7 @@ def name_initree(): @preamble def define_dimension(name): - return "static const int {} = {};".format(name, get_dimension) + return "static const int {} = {};".format(name, get_dimension()) def name_dimension(): @@ -303,6 +307,7 @@ def type_domainfield(): def basetype_range(): if get_option('opcounter'): + from dune.perftool.pdelab.driver.timings import setup_timer setup_timer() return "oc::OpCounter<double>" else: @@ -1176,35 +1181,6 @@ def name_mpihelper(): return name -@preamble -def define_timing_stream(name): - include_file('fstream', filetag='driver', system=True) - include_file('sstream', filetag='driver', system=True) - include_file('sys/types.h', filetag='driver', system=True) - include_file('unistd.h', filetag='driver', system=True) - - return ["std::stringstream ss;", - "ss << \"{}/timings-rank-\" << {}.rank() << \"-pid-\" << getpid() << \".csv\";".format(get_option('project_basedir'), name_mpihelper()), - "std::ofstream {};".format(name), - "{}.open(ss.str(), std::ios_base::app);".format(name), - ] - - -@preamble -def dump_dof_numbers(stream): - ident = name_timing_identifier() - return "{} << {} << \" dofs dofs \" << {}.size() << std::endl;".format(stream, - ident, - name_gfs(get_trial_element())) - - -def name_timing_stream(): - name = "timestream" - define_timing_stream(name) - dump_dof_numbers(name) - return name - - @preamble def dune_solve(): # Test if form is linear in ansatzfunction @@ -1237,6 +1213,7 @@ def dune_solve(): solve = "{}.apply();".format(snp) if get_option('instrumentation_level') >= 2: + from dune.perftool.pdelab.driver.timings import setup_timer, name_timing_stream setup_timer() from dune.perftool.generation import post_include post_include("HP_DECLARE_TIMER(solve);", filetag="driver") @@ -1438,144 +1415,6 @@ def name_test_fail_variable(): return name -@cached -def setup_timer(): - # Necessary includes and defines - from dune.perftool.generation import pre_include - - # TODO check that we are using YASP? - if get_option('opcounter'): - pre_include("#define ENABLE_COUNTER", filetag="driver") - pre_include("#define ENABLE_HP_TIMERS", filetag="driver") - include_file("dune/perftool/common/timer.hh", filetag="driver") - - -@preamble -def define_timing_identifier(name): - ini = name_initree() - return "auto {} = {}.get<std::string>(\"identifier\", std::string(argv[0]));".format(name, ini) - - -def name_timing_identifier(): - name = "ident" - define_timing_identifier(name) - return name - - -@preamble -def evaluate_residual_timer(): - formdata = _driver_data['formdata'] - n_go = name_gridoperator(formdata) - v = name_vector(formdata) - t_v = type_vector(formdata) - setup_timer() - - 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) - if get_option('instrumentation_level') >= 3: - print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) - - 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;"] + evaluation - - return evaluation - - -@preamble -def apply_jacobian_timer(): - # Set the matrix_free option to True! - from dune.perftool.options import set_option - set_option("matrix_free", True) - - formdata = _driver_data['formdata'] - n_go = name_gridoperator(formdata) - v = name_vector(formdata) - t_v = type_vector(formdata) - setup_timer() - - if get_option('instrumentation_level') >= 2: - # Write back times - from dune.perftool.generation import post_include - post_include("HP_DECLARE_TIMER(apply_jacobian);", 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) - if get_option('instrumentation_level') >= 3: - print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) - - if get_option('instrumentation_level') >= 2: - evaluation = ["HP_TIMER_START(apply_jacobian);", - "{}.jacobian_apply({}, j);".format(n_go, v), - "HP_TIMER_STOP(apply_jacobian);", - "DUMP_TIMER(apply_jacobian, {}, true);".format(timestream)] - evaluation.extend(print_times) - else: - evaluation = ["{}.jacobian_apply({}, j);".format(n_go, v)] - - evaluation = ["{} j({});".format(t_v, v), "j=0.0;"] + evaluation - - return evaluation - - -@preamble -def assemble_matrix_timer(): - formdata = _driver_data['formdata'] - t_go = type_gridoperator(formdata) - n_go = name_gridoperator(formdata) - v = name_vector(formdata) - t_v = type_vector(formdata) - setup_timer() - - 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) - if get_option('instrumentation_level') >= 3: - print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) - - 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)] + assembly - - return assembly - - @preamble def print_residual(): ini = name_initree() @@ -1840,6 +1679,7 @@ def generate_driver(formdatas, data): ["vertex", "interval", "quadrilateral", "hexahedron"])) # In case of operator conunting we only assemble the matrix and evaluate the residual # assemble_matrix_timer() + from dune.perftool.pdelab.driver.timings import apply_jacobian_timer, evaluate_residual_timer evaluate_residual_timer() apply_jacobian_timer() elif is_stationary(): @@ -1850,6 +1690,7 @@ def generate_driver(formdatas, data): # Make sure that timestream is declared before retrieving chache items if get_option("instrumentation_level") >= 1: + from dune.perftool.pdelab.driver.timings import setup_timer, name_timing_stream setup_timer() timestream = name_timing_stream() diff --git a/python/dune/perftool/pdelab/driver/timings.py b/python/dune/perftool/pdelab/driver/timings.py new file mode 100644 index 00000000..67576153 --- /dev/null +++ b/python/dune/perftool/pdelab/driver/timings.py @@ -0,0 +1,198 @@ +""" Timing related generator functions """ + +from dune.perftool.options import get_option, set_option +from dune.perftool.generation import (cached, + include_file, + post_include, + preamble, + ) + + +@preamble +def define_timing_identifier(name): + from dune.perftool.pdelab.driver import name_initree + ini = name_initree() + return "auto {} = {}.get<std::string>(\"identifier\", std::string(argv[0]));".format(name, ini) + + +def name_timing_identifier(): + name = "ident" + define_timing_identifier(name) + return name + + +@preamble +def dump_dof_numbers(stream): + ident = name_timing_identifier() + from dune.perftool.pdelab.driver import get_trial_element, name_gfs + return "{} << {} << \" dofs dofs \" << {}.size() << std::endl;".format(stream, + ident, + name_gfs(get_trial_element())) + +@preamble +def define_timing_stream(name): + from dune.perftool.pdelab.driver import name_mpihelper + + include_file('fstream', filetag='driver', system=True) + include_file('sstream', filetag='driver', system=True) + include_file('sys/types.h', filetag='driver', system=True) + include_file('unistd.h', filetag='driver', system=True) + + return ["std::stringstream ss;", + "ss << \"{}/timings-rank-\" << {}.rank() << \"-pid-\" << getpid() << \".csv\";".format(get_option('project_basedir'), name_mpihelper()), + "std::ofstream {};".format(name), + "{}.open(ss.str(), std::ios_base::app);".format(name), + ] + + +def name_timing_stream(): + name = "timestream" + define_timing_stream(name) + dump_dof_numbers(name) + return name + + +@cached +def setup_timer(): + # Necessary includes and defines + from dune.perftool.generation import pre_include + + # TODO check that we are using YASP? + if get_option('opcounter'): + pre_include("#define ENABLE_COUNTER", filetag="driver") + pre_include("#define ENABLE_HP_TIMERS", filetag="driver") + include_file("dune/perftool/common/timer.hh", filetag="driver") + + +@preamble +def evaluate_residual_timer(): + from dune.perftool.pdelab.driver import (get_formdata, + name_gridoperator, + name_localoperator, + name_vector, + type_vector, + ) + + formdata = get_formdata() + n_go = name_gridoperator(formdata) + v = name_vector(formdata) + t_v = type_vector(formdata) + setup_timer() + + 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) + if get_option('instrumentation_level') >= 3: + print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) + + 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;"] + evaluation + + return evaluation + + +@preamble +def apply_jacobian_timer(): + # Set the matrix_free option to True! + set_option("matrix_free", True) + + from dune.perftool.pdelab.driver import (get_formdata, + name_gridoperator, + name_localoperator, + name_vector, + type_vector, + ) + + formdata = get_formdata() + n_go = name_gridoperator(formdata) + v = name_vector(formdata) + t_v = type_vector(formdata) + setup_timer() + + if get_option('instrumentation_level') >= 2: + # Write back times + from dune.perftool.generation import post_include + post_include("HP_DECLARE_TIMER(apply_jacobian);", 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) + if get_option('instrumentation_level') >= 3: + print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) + + if get_option('instrumentation_level') >= 2: + evaluation = ["HP_TIMER_START(apply_jacobian);", + "{}.jacobian_apply({}, j);".format(n_go, v), + "HP_TIMER_STOP(apply_jacobian);", + "DUMP_TIMER(apply_jacobian, {}, true);".format(timestream)] + evaluation.extend(print_times) + else: + evaluation = ["{}.jacobian_apply({}, j);".format(n_go, v)] + + evaluation = ["{} j({});".format(t_v, v), "j=0.0;"] + evaluation + + return evaluation + + +@preamble +def assemble_matrix_timer(): + from dune.perftool.pdelab.driver import (get_formdata, + name_gridoperator, + name_localoperator, + name_vector, + type_vector, + ) + + formdata = get_formdata() + t_go = type_gridoperator(formdata) + n_go = name_gridoperator(formdata) + v = name_vector(formdata) + t_v = type_vector(formdata) + setup_timer() + + 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) + if get_option('instrumentation_level') >= 3: + print_times.append("{}.dump_timers({}, {}, true);".format(lop_name, timestream, name_timing_identifier())) + + 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)] + assembly + + return assembly -- GitLab