From 6c93ae554db193e5745bb8a44cdbfb1354d68857 Mon Sep 17 00:00:00 2001 From: Landon Owen Date: Wed, 25 Sep 2024 10:20:40 -0700 Subject: [PATCH] Updated Caliper diagnostic documentation --- docs/developer/dev/diagnostic_tools.rst | 51 ++++++++++++++++--------- src/PYB11/Utilities/TimerMgr.py | 37 ++++++++---------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/docs/developer/dev/diagnostic_tools.rst b/docs/developer/dev/diagnostic_tools.rst index d16a2e94c..95b66b04e 100644 --- a/docs/developer/dev/diagnostic_tools.rst +++ b/docs/developer/dev/diagnostic_tools.rst @@ -1,7 +1,7 @@ -Diagnostics -########### +Code Performance Diagnostics +############################ -Spheral uses Caliper to preform diagnostics, such as timing. To enable this functionality in the code, Spheral needs to be configured with ``ENABLE_TIMER=ON``. Otherwise the diagnostic regions are no-ops for improved preformance. +Spheral uses Caliper to preform code diagnostics, such as timing. To enable this functionality in the code, Spheral needs to be configured with ``ENABLE_TIMER=ON``. Otherwise, the timing regions are no-ops for improved preformance. :: ./scripts/devtools/host-config-build.py -.cmake -DENABLE_TIMER=ON @@ -10,33 +10,32 @@ Spheral uses Caliper to preform diagnostics, such as timing. To enable this func Querying using Caliper ====================== -Caliper is configured and started through the :kbd:`cali::ConfigManager`. -The :kbd:`cali::ConfigManager` is wrapped in a :kbd:`TimerMgr` singleton class, which has a python interface. -:kbd:`TimerMgr` is initialized and started in the :kbd:`InitTimers` routine which is called in :kbd:`commandLine()` in ``src/SimulationControl/SpheralOptionParser.py``. +Caliper is configured and started through the ``cali::ConfigManager``. +The ``cali::ConfigManager`` is wrapped in a ``TimerMgr`` singleton class, which has a python interface. + +.. note:: + ``TimerMgr`` is initialized and started during ``commandLine()`` in ``src/SimulationControl/SpheralOptionParser.py``. This is because ``commandLine()`` is almost always invoked directly near the start of a problem. However, if ``commandLine()`` is not called, the timers would need to be configured and started directly using the ``TimerMgr`` class. See :ref:`below ` for more details. + By default, the Caliper configuration is set to ``spot`` and outputs Caliper files (``.cali``). For the default configuration, the Caliper files are named based on what file is being run, for example: :: - python Noh-cylindrical-2d.py + python Noh-cylindrical-2d.py -will produce timing files called -:: +will produce a timing file called ``Noh-cylindrical-2d_YEAR_MONTH_DATE_TIME.cali`` where the file name includes the current date and time. - Noh-cylindrical-2d_YEAR_MONTH_DATE_TIME.cali - -where the file name includes the current date and time. The Caliper file name can be specified using the command line :: python Noh-cylindrical-2d.py --caliperFilename 'new_test_name.cali' -Non-default Caliper configurations can be set at the command line using ``--caliperConfig`` like so +Different Caliper configurations can be set at the command line using ``--caliperConfig`` like so :: python Noh-cylindrical-2d.py --caliperConfig 'runtime-report(output=time.txt),calc.inclusive,region.count' .. note:: - The above configuration produces timing results similar to the previous :kbd:`Spheral::Timer` method. This results in a file named ``time.txt`` with cumulative times for the nested regions as well as a count of how many times each region ran. + The above configuration produces timing results similar to the previous ``Spheral::Timer`` method. This results in a file named ``time.txt`` with cumulative times for the nested regions as well as a count of how many times each region ran. Similarly, a non-default Caliper configuration can be read in from a JSON file using ``--caliperConfigJSON`` and providing the file name. Lastly, Caliper timers can be turned off using ``--caliperConfig none``. @@ -56,12 +55,16 @@ So far there are two different types of regions in Spheral, using the following :: TIME_FUNCTION + +or + +:: TIME_BEGIN("timer_name") TIME_END("timer_name") -- :kbd:`TIME_FUNCTION` can be added to the very beginning of a function and creates a region for the entire function using the function's name. :kbd:`TIME_FUNCTION` uses just the function name and no class or parameter information, so be careful when using this method with functions that could share names. +- ``TIME_FUNCTION`` can be added to the very beginning of a function and creates a region for the entire function using the function's name. ``TIME_FUNCTION`` uses just the function name and no class or parameter information, so be careful when using this method with functions that could share names. -- :kbd:`TIME_BEGIN("timer_name")` and :kbd:`TIME_END("timer_name")` create a region between the two different calls and use the string (in this case timer_name) as the name. +- ``TIME_BEGIN("timer_name")`` and ``TIME_END("timer_name")`` create a region between the two different calls and use the string (in this case ``timer_name``) as the name. Adding Region Timers in Python @@ -70,9 +73,21 @@ Adding Region Timers in Python Region timers can be added inside the python code using the following function calls: :: - TimerMgr.timer_start("some_function") + TimerMgr.timer_start("timer_name") some_function_call() - TimerMgr.timer_end("some_function") + TimerMgr.timer_end("timer_name") .. note:: IMPORTANT: All timers must have both a start and end call. Otherwise, memory issues will occur. + +.. _manual_caliper: + +Starting Caliper Manually +======================== + +As mentioned above, Caliper (not an individual Caliper timer) is normally configured and started in ``commandLine()`` python routine. However, Caliper can be directly configured and started through the python interface, if desired. This can be done by putting the following into the python file: +:: + + caliper_config = "some_configuration,(output=some_filename.txt)" + TimerMgr.add(caliper_config) + TimerMgr.start() diff --git a/src/PYB11/Utilities/TimerMgr.py b/src/PYB11/Utilities/TimerMgr.py index 6b47214cd..8158110c5 100644 --- a/src/PYB11/Utilities/TimerMgr.py +++ b/src/PYB11/Utilities/TimerMgr.py @@ -6,28 +6,7 @@ @PYB11singleton class TimerMgr: - "Singleton wrapper for CaliperManager. Access through TimerMgr.instance(), ie TimerMgr.instance().start()." - - @PYB11static - @PYB11returnpolicy("reference") - def instance(self): - "Access the singleton instance of the timer manager" - return "TimerMgr&" - - @PYB11static - def timer_start(self, region_name = "std::string"): - "Start custom region Caliper timer, must have corresponding timer_end call" - return "void" - - @PYB11static - def timer_end(self, region_name = "std::string"): - "End custom region Caliper timer" - return "void" - - @PYB11static - def is_started(self): - "Check if ConfigManager has been started" - return "bool" + "Singleton wrapper for CaliperManager. Accesses a C++ singleton object." @PYB11static def add(self, config_str = "std::string"): @@ -73,3 +52,17 @@ def get_filename(self): def timers_usable(self): "Return whether the code has been compiled with timers turned on" return "bool" + @PYB11static + def timer_start(self, region_name = "std::string"): + "Start custom region Caliper timer, must have corresponding timer_end call" + return "void" + + @PYB11static + def timer_end(self, region_name = "std::string"): + "End custom region Caliper timer" + return "void" + + @PYB11static + def is_started(self): + "Check if ConfigManager has been started" + return "bool"