9#include <boost/python.hpp>
10#include <framework/pybasf2/ProcessStatisticsPython.h>
11#include <framework/core/Module.h>
12#include <framework/core/Environment.h>
13#include <framework/datastore/StoreObjPtr.h>
14#include <framework/logging/Logger.h>
15#include <framework/core/PyObjConvUtils.h>
19using namespace boost::python;
26 B2ERROR(
"ProcessStatistics data object is not available, you either disabled statistics with --no-stats or didn't run process(path) yet.");
48 const boost::python::list& modulesPyList)
53 std::vector<ModuleStatistics> moduleStats;
58 if (stats.getName().empty()) stats.setName(ptr->getName());
59 moduleStats.push_back(stats);
66 boost::python::list result;
70 result.append(module);
107 namespace bp = boost::python;
112 docstring_options options(
true,
true,
false);
115 class_<ProcessStatisticsPython> stats(
"ProcessStatistics", R
"DOCSTRING(
116Interface for retrieving statistics about module execution at runtime or after
117:py:func:`basf2.process()` returns. Should be accessed through a global instance `basf2.statistics`.
119Statistics for `event() <Module.event()>` calls are available as a string representation of the object:
121>>> from basf2 import statistics
123=================================================================================
124Name | Calls | Memory(MB) | Time(s) | Time(ms)/Call
125=================================================================================
126RootInput | 101 | 0 | 0.01 | 0.05 +- 0.02
127RootOutput | 100 | 0 | 0.02 | 0.20 +- 0.87
128ProgressBar | 100 | 0 | 0.00 | 0.00 +- 0.00
129=================================================================================
130Total | 101 | 0 | 0.03 | 0.26 +- 0.86
131=================================================================================
133This provides information on the number of calls, elapsed time, and the average
134difference in resident memory before and after the `event() <Module.event>` call.
138 The module responsible for reading (or generating) events usually has one
139 additional event() call which is used to determine whether event processing
144 Memory consumption is reporting the difference in memory usage as reported
145 by the kernel before and after the call. This is not the maximum memory the
146 module has consumed. Negative values indicate that this module has freed
147 momemory which was allocated in other modules or function calls.
149Information on other calls like `initialize() <Module.initialize>`,
150`terminate() <Module.terminate>`, etc. are also available through the different
151counters defined in `StatisticCounters`:
153>>> print(statistics(statistics.INIT))
154>>> print(statistics(statistics.BEGIN_RUN))
155>>> print(statistics(statistics.END_RUN))
156>>> print(statistics(statistics.TERM))
157)DOCSTRING", no_init);
161 "Get `ModuleStatistics` for given Module.")
163 "Get global `ModuleStatistics` containing total elapsed time etc.")
170 scope statistics{stats};
172 enum_<ModuleStatistics::EStatisticCounters>(
"StatisticCounters", R
"DOCSTRING(
173Available types of statistic counters (corresponds to Module functions)
177Time spent or memory used in the `initialize() <Module.initialize>` function
179.. attribute:: BEGIN_RUN
181Time spent or memory used in the `beginRun() <Module.beginRun>` function
185Time spent or memory used in the `event() <Module.event>` function
187.. attribute:: END_RUN
189Time spent or memory used in the `endRun() <Module.endRun>` function
193Time spent or memory used in the `terminate() <Module.terminate>` function
197Time spent or memory used in any module function. This is the sum of all of the above.
211 docstring_options custom_options(
true,
false,
false);
214 "Return the event statistics as a string in a human readable form")
216 "Return an html represenation of the statistics (used by ipython/jupyter)")
218 R
"DOCSTRING(__call__(counter=StatisticCounters.EVENT, modules=None)
220Calling the statistics object directly like a function will return a string
221with the execution statistics in human readable form.
224 counter (StatisticCounters): Which counter to use
225 modules (list[Module]): A list of modules to include in the returned string.
226 If omitted the statistics for all modules will be included.
228* print the `beginRun() <Module.beginRun>` statistics for all modules:
230 >>> print(statistics(statistics.BEGIN_RUN))
232* print the total execution times and memory consumption but only for the
233 modules ``module1`` and ``module2``
235 >>> print(statistics(statistics.TOTAL, [module1, module2]))
237* print the event statistics (default) for only two modules
239 >>> print(statistics(modules=[module1, module2]))
246 docstring_options new_options(
true,
false,
false);
247 class_<ModuleStatistics>(
"ModuleStatistics",
"Execution statistics for a single module. "
248 "All member functions take exactly one argument to select which "
249 "counter to query which defaults to `StatisticCounters.TOTAL` if omitted.")
251 "property to get the name of the module to be displayed in the statistics")
253 "time_sum(counter=StatisticCounters.TOTAL)\nReturn the sum of all execution times")
255 "time_mean(counter=StatisticCounters.TOTAL)\nReturn the mean of all execution times")
257 "time_stddev(counter=StatisticCounters.TOTAL)\nReturn the standard deviation of all execution times")
259 "memory_sum(counter=StatisticCounters.TOTAL)\nReturn the sum of the total memory usage")
261 "memory_mean(counter=StatisticCounters.TOTAL)\nReturn the mean of the memory usage")
263 "memory_stddev(counter=StatisticCounters.TOTAL)\nReturn the standard deviation of the memory usage")
265 "time_memory_corr(counter=StatisticCounters.TOTAL)\nReturn the correlaction factor between time and memory consumption")
267 "calls(counter=StatisticCounters.TOTAL)\nReturn the total number of calls")
@ c_Persistent
Object is available during entire execution time.
static Environment & Instance()
Static method to get a reference to the Environment instance.
Keep track of time and memory consumption during processing.
value_type getTimeStddev(EStatisticCounters type=c_Total) const
return the stddev of the execution times for a given counter
value_type getCalls(EStatisticCounters type=c_Total) const
return the number of calls for a given counter type
value_type getTimeMemoryCorrelation(EStatisticCounters type=c_Total) const
return the pearson correlation coefficient between execution times and memory consumption changes
value_type getMemoryStddev(EStatisticCounters type=c_Total) const
return the stddev of the memory consumption changes per call
const std::string & getName() const
Return the previously set name.
value_type getMemoryMean(EStatisticCounters type=c_Total) const
return the average memory change per call
EStatisticCounters
Enum to define all counter types.
@ c_Init
Counting time/calls in initialize()
@ c_EndRun
Counting time/calls in endRun()
@ c_Term
Counting time/calls in terminate()
@ c_BeginRun
Counting time/calls in beginRun()
@ c_Event
Counting time/calls in event()
@ c_Total
Sum of the above.
value_type getMemorySum(EStatisticCounters type=c_Total) const
return the total used memory for a given counter
value_type getTimeSum(EStatisticCounters type=c_Total) const
return the sum of all execution times for a given counter
value_type getTimeMean(EStatisticCounters type=c_Total) const
return the mean execution time for a given counter
Python interface for ProcessStatistics.
std::string getStatisticsStringHTML()
Return string with statistics for all selected modules as html table.
ProcessStatisticsPython getModuleStatistics(ModuleStatistics::EStatisticCounters type, const boost::python::list &modulesPyList)
Get a new statistics object for a different counter/different list of modules.
std::vector< ModuleStatistics > m_modules
Which modules to show.
void csv(const char *filename)
Write statistics to a csv file.
const ModuleStatistics * get(const std::shared_ptr< Module > &module)
Get statistics for given module.
std::string getStatisticsString()
Return string with statistics for all selected modules.
static void exposePythonAPI()
Define python wrappers to make functionality avaiable in python.
ModuleStatistics::EStatisticCounters m_type
Which counter to show when printing the statistics.
ProcessStatistics * getWrapped()
Get wrapped ProcessStatistics object.
void clear()
Clear collected statistics but keep names of modules.
boost::python::list getAll()
Get statistics for all modules as python list.
const ModuleStatistics * getGlobal()
Get statistics for the framework itself.
Class to collect call statistics for all modules.
const ModuleStatistics & getGlobal() const
Get global statistics.
ModuleStatistics & getStatistics(const Module *module)
Get statistics for single module.
std::string getStatisticsString(ModuleStatistics::EStatisticCounters type=ModuleStatistics::c_Event, const std::vector< Belle2::ModuleStatistics > *modules=nullptr, bool html=false) const
Return string with statistics for all modules.
void write_csv(const char *filename="ProcessStatistics.csv") const
Write process statistics to a csv file.
virtual void clear() override
Clear collected statistics but keep names of modules.
Type-safe access to single objects in the data store.
std::shared_ptr< Module > ModulePtr
Defines a pointer to a module object as a boost shared pointer.
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.
Abstract base class for different kinds of events.