..  Copyright (c) 2013-2020, SIB - Swiss Institute of Bioinformatics and
..                           Biozentrum - University of Basel
..  
..  Licensed under the Apache License, Version 2.0 (the "License");
..  you may not use this file except in compliance with the License.
..  You may obtain a copy of the License at
..  
..    http://www.apache.org/licenses/LICENSE-2.0
..  
..  Unless required by applicable law or agreed to in writing, software
..  distributed under the License is distributed on an "AS IS" BASIS,
..  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
..  See the License for the specific language governing permissions and
..  limitations under the License.


Runtime profiling
================================================================================

.. currentmodule:: promod3.core

.. class:: StaticRuntimeProfiler

  Defines functionality for runtime profiling.
  
  All profiling is completely turned off by default and must be activated at
  compile-time by adding ``-DPM3_RUNTIME_PROFILING_LEVEL=N`` to your |cmake|
  call, where ``N`` must be larger than 0. If turned off, all these functions
  will still exist and work but will not do anything. Functionality in the |C++|
  code is usually profiled at level 2, while |python| functionality is profiled
  at level 1. The default profiling only covers the steps of the modelling
  pipeline.

  You can start multiple timers with the same id and statistics will be
  generated considering the number of timings and the total runtime for that
  timer. If a timer within another timed entity, the outer timer is paused,
  while the inner one is running. Hence, the sum of all timers will be the
  total time spent in any timer (nothing is counted twice!).

  .. staticmethod:: Start(id, level=1)

    Start a timer for the given `id`. This pauses any other currently running
    timer.

    :param id: Identifier for this timer.
    :type id:  :class:`str`
    :param level: Timer only started if level <= ``PM3_RUNTIME_PROFILING_LEVEL``
    :type level:  :class:`int`

  .. staticmethod:: StartScoped(id, level=1)

    Start a timer for the given `id` as in :meth:`Start`, but this will stop it
    automatically when the returned variable goes out of scope.

    :param id: Identifier for this timer.
    :type id:  :class:`str`
    :param level: Timer only started if level <= ``PM3_RUNTIME_PROFILING_LEVEL``
    :type level:  :class:`int`
    :return: Object that will call :meth:`Stop` when it goes out of scope

  .. staticmethod:: Stop(id, level=1)

    Stop the currently running timer. If a timer was paused when starting this
    timer, it will be resumed now. Note that there is no error checking here, so
    this will fail miserably if no timer is currently running.

    :param level: Timer only stopped if level <= ``PM3_RUNTIME_PROFILING_LEVEL``
    :type level:  :class:`int`

  .. staticmethod:: PrintSummary(max_to_show=-1)

    Display a summary of all timed entities. The timers are collected by id and
    sorted by total runtime. If more than 10 entries are shown and the used id's
    have the form "GROUP::NAME", an additional summary is shown with the total
    times spent in each "GROUP".

    :param max_to_show: if >= 0, show only top `max_to_show` entries.
    :type max_to_show:  :class:`int`

  .. staticmethod:: IsEnabled()

    :return: True, if ``PM3_RUNTIME_PROFILING_LEVEL`` > 0. Otherwise, profiling
             is completely turned off.
    :rtype:  :class:`bool`

  .. staticmethod:: Clear()

    Clears all timed entries. Note that there is no error checking here, so this
    will fail miserably if timers are currently running.
