 |
Belle II Software
release-05-02-19
|
11 #include <boost/python.hpp>
12 #include <framework/pybasf2/ProcessStatisticsPython.h>
13 #include <framework/core/Module.h>
14 #include <framework/core/Environment.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 #include <framework/logging/Logger.h>
17 #include <framework/core/PyObjConvUtils.h>
21 using namespace boost::python;
34 B2ERROR(
"ProcessStatistics data object is not available, you either disabled statistics with --no-stats or didn't run process(path) yet.");
42 const std::vector<ModuleStatistics>* modules)
46 return getWrapped()->getStatisticsString(mode, modules);
55 std::vector<ModuleStatistics> moduleStats;
60 if (stats.getName().empty()) stats.setName(ptr->getName());
61 moduleStats.push_back(stats);
63 return getStatisticsString(mode, &moduleStats);
68 boost::python::list result;
71 for (
auto& module : getWrapped()->getAll()) {
72 result.append(module);
81 return &getWrapped()->getStatistics(module.get());
88 return &getWrapped()->getGlobal();
95 getWrapped()->clear();
99 #if !defined(__GNUG__) || defined(__ICC)
101 #pragma GCC diagnostic push
102 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
106 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getStatistics_overloads, getStatisticsString, 0, 1)
107 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getModuleStatistics_overloads, getModuleStatistics, 1, 2)
108 #if !defined(__GNUG__) || defined(__ICC)
110 #pragma GCC diagnostic pop
116 namespace bp = boost::python;
121 docstring_options options(
true,
true,
false);
124 class_<ProcessStatisticsPython, boost::noncopyable> stats(
"ProcessStatistics", R
"DOCSTRING(
125 Interface for retrieving statistics about module execution at runtime or after
126 :py:func:`basf2.process()` returns. Should be accessed through a global instance `basf2.statistics`.
128 Statistics for `event() <Module.event()>` calls are available as a string representation of the object:
130 >>> from basf2 import statistics
131 >>> print(statistics)
132 =================================================================================
133 Name | Calls | Memory(MB) | Time(s) | Time(ms)/Call
134 =================================================================================
135 RootInput | 101 | 0 | 0.01 | 0.05 +- 0.02
136 RootOutput | 100 | 0 | 0.02 | 0.20 +- 0.87
137 ProgressBar | 100 | 0 | 0.00 | 0.00 +- 0.00
138 =================================================================================
139 Total | 101 | 0 | 0.03 | 0.26 +- 0.86
140 =================================================================================
142 This provides information on the number of calls, elapsed time, and the average
143 difference in resident memory before and after the `event() <Module.event>` call.
147 The module responsible for reading (or generating) events usually has one
148 additional event() call which is used to determine whether event processing
153 Memory consumption is reporting the difference in memory usage as reported
154 by the kernel before and after the call. This is not the maximum memory the
155 module has consumed. Negative values indicate that this module has freed
156 momemory which was allocated in other modules or function calls.
158 Information on other calls like `initialize() <Module.initialize>`,
159 `terminate() <Module.terminate>`, etc. are also available through the different
160 counters defined in `StatisticCounters`:
162 >>> print(statistics(statistics.INIT))
163 >>> print(statistics(statistics.BEGIN_RUN))
164 >>> print(statistics(statistics.END_RUN))
165 >>> print(statistics(statistics.TERM))
166 )DOCSTRING", no_init);
170 R
"DOCSTRING(Set name for module in statistics.
172 Normally, all modules get assigned their default name which is
173 used to register them. If multiple instances of the same module
174 are present at the same time, this can be used to distinguish
177 .. deprecated:: release-01-00-00
178 Use `Module.set_name` instead
181 "Get `ModuleStatistics` for given Module.")
183 "Get global `ModuleStatistics` containing total elapsed time etc.")
191 docstring_options custom_options(
true,
false,
false);
194 getStatistics_overloads(
"Return the event statistics for all modules as string in a human readable form"))
197 __call__(modules=None, counter=StatisticCounters.TOTAL)
199 Calling the statistics object directly like a function will return a string
200 with the execution statistics in human readable form.
203 modules (list[Module]): A list of modules to include in the returned string.
204 If omitted the statistics for all modules will be included.
205 counter (StatisticCounters): Which counter to use
207 * print the `beginRun() <Module.beginRun>` statistics for all modules:
209 >>> print(statistics(statistics.BEGIN_RUN))
211 * print the total execution times and memory consumption but only for the
212 modules ``module1`` and ``module2``
214 >>> print(statistics([module1, module2], statistics.TOTAL))
220 scope statistics = stats;
222 enum_<ModuleStatistics::EStatisticCounters>(
"StatisticCounters", R
"DOCSTRING(
223 Available types of statistic counters (corresponds to Module functions)
227 Time spent or memory used in the `initialize() <Module.initialize>` function
229 .. attribute:: BEGIN_RUN
231 Time spent or memory used in the `beginRun() <Module.beginRun>` function
235 Time spent or memory used in the `event() <Module.event>` function
237 .. attribute:: END_RUN
239 Time spent or memory used in the `endRun() <Module.endRun>` function
243 Time spent or memory used in the `terminate() <Module.terminate>` function
247 Time spent or memory used in any module function. This is the sum of all of the above.
261 docstring_options new_options(
true,
false,
false);
262 class_<ModuleStatistics>(
"ModuleStatistics",
"Execution statistics for a single module. "
263 "All member functions take exactly one argument to select which "
264 "counter to query which defaults to `StatisticCounters.TOTAL` if omitted.")
267 "\n\n.. deprecated:: release-01-00-00\n use `Module.set_name` instead")
269 "time_sum(counter=StatisticCounters.TOTAL)\nReturn the sum of all execution times")
271 "time_mean(counter=StatisticCounters.TOTAL)\nReturn the mean of all execution times")
273 "time_stddev(counter=StatisticCounters.TOTAL)\nReturn the standard deviation of all execution times")
275 "memory_sum(counter=StatisticCounters.TOTAL)\nReturn the sum of the total memory usage")
277 "memory_mean(counter=StatisticCounters.TOTAL)\nReturn the mean of the memory usage")
279 "memory_stddev(counter=StatisticCounters.TOTAL)\nReturn the standard deviation of the memory usage")
281 "time_memory_corr(counter=StatisticCounters.TOTAL)\nReturn the correlaction factor between time and memory consumption")
283 "calls(counter=StatisticCounters.TOTAL)\nReturn the total number of calls")
288 global.attr(
"statistics") = object(ptr(&instance));
const ModuleStatistics * get(const std::shared_ptr< Module > &module)
Get statistics for given module.
void setModuleName(Module *module, const std::string &name)
Set name for module in statistics.
@ c_Event
Counting time/calls in event()
static ProcessStatisticsPython & getInstance()
Return singleton instance of the statistics.
@ c_EndRun
Counting time/calls in endRun()
EStatisticCounters
Enum to define all counter types.
value_type getMemorySum(EStatisticCounters type=c_Total) const
return the total used memory for a given counter
@ c_Term
Counting time/calls in terminate()
@ c_Total
Sum of the above.
void clear()
Clear collected statistics but keep names of modules.
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.
void setName(const std::string &name)
Set the name of the module for display.
std::string getStatisticsString(ModuleStatistics::EStatisticCounters type=ModuleStatistics::c_Event, const std::vector< ModuleStatistics > *modules=nullptr)
Return string with statistics for all modules.
Abstract base class for different kinds of events.
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.
value_type getMemoryMean(EStatisticCounters type=c_Total) const
return the average memory change per call
const ModuleStatistics * getGlobal()
Get statistics for the framework itself.
std::string getModuleStatistics(const boost::python::list &modulesPyList, ModuleStatistics::EStatisticCounters type=ModuleStatistics::c_Event)
Return string with statistics for selected modules.
@ c_BeginRun
Counting time/calls in beginRun()
static void exposePythonAPI()
Define python wrappers to make functionality avaiable in python.
@ c_Persistent
Object is available during entire execution time.
value_type getTimeMemoryCorrelation(EStatisticCounters type=c_Total) const
return the pearson correlation coefficient between execution times and memory consumption changes
value_type getCalls(EStatisticCounters type=c_Total) const
return the number of calls for a given counter type
boost::python::list getAll()
Get statistics for all modules as python list.
static Environment & Instance()
Static method to get a reference to the Environment instance.
value_type getTimeMean(EStatisticCounters type=c_Total) const
return the mean execution time for a given counter
value_type getTimeStddev(EStatisticCounters type=c_Total) const
return the stddev of the execution times for a given counter
Class to collect call statistics for all modules.
ProcessStatistics * getWrapped()
Get wrapped ProcessStatistics object.
value_type getTimeSum(EStatisticCounters type=c_Total) const
return the sum of all execution times for a given counter
Python interface for ProcessStatistics.
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.
Keep track of time and memory consumption during processing.
@ c_Init
Counting time/calls in initialize()