Working with timers

The module cactus_timers (Reference on kuibit.cactus_timers) can be used to read timing information from the output of Carpet. Timers are useful to profile the code and individuate bottlenecks.

At the moment, only XML timers are supported. These files are output when the option Carpet::output_xml_timer_tree is set to yes.

Trees

The way timers are represented in kuibit is with the Tree structure. The tree structure is ideal because XML timers contains a report on the call-stack of the simulation, which is naturally hierarchical: it is the set of functions called, and which functions each function called, and so on. The only functions that are profiled are the ones that are scheduled. In kuibit, a Tree is a collection of three elements: a name, a value, and possibly a collection of children. For timers, the name is the name of the function, the value is the total time that was spent inside this function, and children is the set of functions that were called inside this one.

For example,

# Assuming tim is a Tree
print(tim.name)  # main
print(tim.value)  # 1.4 (seconds)

# The name of the first child
print(tim[0].name)  # evolve
# Can also be called with
print(tim["evolve"].name)  # evolve

# This prints the cumulative value of all the leaves of the tree
print(tim["evolve"].tot_value_leaves)

# This can be used to transform the tree into percentual instead of seconds
tim_in_perc = tim / tim.tot_value_leaves

# Trees can be exported to dictionaries of JSON
tim_dict = tim.to_dict()
print(tim.to_json())

Timer trees

The easiest way to access timing information is starting from SimDir:

# Assuming sim is a SimDir

tim = sim.timers

tim is a TimersDir object: a dictionary-like object that has as keys the process numbers (the various MPI ranks), and as values a Tree with all the timing information (see above). kuibit automatically detects restarts and sums them up in a single tree. More often than not, however, we are not interest in timers for a specific process, but we want to have a general idea. In that case, we can use the average(), or the median() methods to obtain the average (or median) timers across all the processes.

Note

Check out the examples to see a neat and useful application of this module. In particular, interactive_timertree.py