timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
child.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#pragma once
26
28#include "timemory/components/timing/backends.hpp"
31
32TIMEMORY_DECLARE_COMPONENT(child_system_clock)
33TIMEMORY_DECLARE_COMPONENT(child_user_clock)
34TIMEMORY_DECLARE_COMPONENT(child_cpu_clock)
35TIMEMORY_DECLARE_COMPONENT(child_cpu_util)
36//
37TIMEMORY_STATISTICS_TYPE(component::child_system_clock, double)
38TIMEMORY_STATISTICS_TYPE(component::child_user_clock, double)
39TIMEMORY_STATISTICS_TYPE(component::child_cpu_clock, double)
40TIMEMORY_STATISTICS_TYPE(component::child_cpu_util, double)
41//
42TIMEMORY_DEFINE_CONCRETE_TRAIT(is_timing_category, component::child_system_clock,
43 true_type)
44TIMEMORY_DEFINE_CONCRETE_TRAIT(is_timing_category, component::child_user_clock, true_type)
45TIMEMORY_DEFINE_CONCRETE_TRAIT(is_timing_category, component::child_cpu_clock, true_type)
46//
47TIMEMORY_DEFINE_CONCRETE_TRAIT(uses_timing_units, component::child_system_clock,
48 true_type)
49TIMEMORY_DEFINE_CONCRETE_TRAIT(uses_timing_units, component::child_user_clock, true_type)
50TIMEMORY_DEFINE_CONCRETE_TRAIT(uses_timing_units, component::child_cpu_clock, true_type)
51//
52TIMEMORY_DEFINE_CONCRETE_TRAIT(uses_percent_units, component::child_cpu_util, true_type)
53//
54TIMEMORY_DEFINE_CONCRETE_TRAIT(supports_flamegraph, component::child_system_clock,
55 true_type)
56TIMEMORY_DEFINE_CONCRETE_TRAIT(supports_flamegraph, component::child_user_clock,
57 true_type)
58TIMEMORY_DEFINE_CONCRETE_TRAIT(supports_flamegraph, component::child_cpu_clock, true_type)
59//
60namespace tim
61{
62namespace trait
63{
64//
65template <>
66struct derivation_types<component::child_cpu_util>
67{
68 using type = type_list<type_list<component::wall_clock, component::child_cpu_clock>,
69 type_list<component::wall_clock, component::child_user_clock,
70 component::child_system_clock>>;
71};
72//
73} // namespace trait
74//
75namespace component
76{
77/// \struct tim::component::child_system_clock
78/// \brief Similar to \ref system_clock except only reports values for child processes
79struct child_system_clock : public base<child_system_clock>
80{
81 using ratio_t = std::nano;
82 using value_type = int64_t;
83 using base_type = base<child_system_clock, value_type>;
84
85 static std::string label() { return "sys"; }
86 static std::string description() { return "CPU time spent in kernel-mode"; }
87 static value_type record() noexcept
88 {
89 return tim::get_child_clock_system_now<int64_t, ratio_t>();
90 }
91 double get() const noexcept
92 {
93 return load() / static_cast<double>(base_type::get_unit());
94 }
95 double get_display() const noexcept { return get(); }
96 void start() noexcept { value = record(); }
97 void stop() noexcept
98 {
99 value = (record() - value);
100 accum += value;
101 }
102};
103/// \struct tim::component::child_user_clock
104/// \brief Similar to \ref user_clock except only reports values for child processes
105struct child_user_clock : public base<child_user_clock>
106{
107 using ratio_t = std::nano;
108 using value_type = int64_t;
109 using base_type = base<child_user_clock, value_type>;
110
111 static std::string label() { return "user"; }
112 static std::string description() { return "CPU time spent in user-mode"; }
113 static value_type record() noexcept
114 {
115 return tim::get_child_clock_user_now<int64_t, ratio_t>();
116 }
117 double get() const noexcept
118 {
119 return load() / static_cast<double>(base_type::get_unit());
120 }
121 double get_display() const noexcept { return get(); }
122 void start() noexcept { value = record(); }
123 void stop() noexcept
124 {
125 value = (record() - value);
126 accum += value;
127 }
128};
129/// \struct tim::component::child_cpu_clock
130/// \brief Similar to \ref cpu_clock except only reports values for child processes
131struct child_cpu_clock : public base<child_cpu_clock>
132{
133 using ratio_t = std::nano;
134 using value_type = int64_t;
135 using base_type = base<child_cpu_clock, value_type>;
136
137 static std::string label() { return "cpu"; }
138 static std::string description()
139 {
140 return "Total CPU time spent in both user- and kernel-mode";
141 }
142 static value_type record() noexcept
143 {
144 return tim::get_child_clock_cpu_now<int64_t, ratio_t>();
145 }
146 double get() const noexcept
147 {
148 return load() / static_cast<double>(base_type::get_unit());
149 }
150 double get_display() const noexcept { return get(); }
151 void start() noexcept { value = record(); }
152 void stop() noexcept
153 {
154 value = (record() - value);
155 accum += value;
156 }
157};
158/// \struct tim::component::child_cpu_util
159/// \brief Similar to \ref cpu_util except only reports values for child processes
160struct child_cpu_util : public base<child_cpu_util, std::pair<int64_t, int64_t>>
161{
162 using ratio_t = std::nano;
163 using value_type = std::pair<int64_t, int64_t>;
164 using base_type = base<child_cpu_util, value_type>;
165
166 static std::string label() { return "cpu_util"; }
167 static std::string description()
168 {
169 return "Percentage of CPU-clock time divided by wall-clock time";
170 }
171 static value_type record()
172 {
173 return value_type(child_cpu_clock::record(), wall_clock::record());
174 }
175
176 double get() const noexcept
177 {
178 auto _data = base_type::load();
179 double denom = (_data.second > 0) ? _data.second : 1;
180 double numer = (_data.second > 0) ? _data.first : 0;
181 return 100.0 * static_cast<double>(numer) / static_cast<double>(denom);
182 }
183
184 double get_display() const noexcept { return get(); }
185
186 void start() noexcept
187 {
188 if(!m_derive)
189 value = record();
190 }
191
192 void stop() noexcept
193 {
194 using namespace tim::component::operators;
195 if(!m_derive)
196 {
197 value = (record() - value);
198 accum += value;
199 }
200 }
201
202public:
203 bool is_derived() const noexcept { return m_derive; }
204
205 bool assemble(const wall_clock* wc, const child_cpu_clock* cc) noexcept
206 {
207 if(wc && cc)
208 m_derive = true;
209 return m_derive;
210 }
211
212 bool assemble(const wall_clock* wc, const child_user_clock* uc,
213 const child_system_clock* sc) noexcept
214 {
215 if(wc && uc && sc)
216 m_derive = true;
217 return m_derive;
218 }
219
220 bool derive(const wall_clock* wc, const child_cpu_clock* cc) noexcept
221 {
222 if(m_derive && wc && cc)
223 {
224 value.first = cc->get_value();
225 value.second = wc->get_value();
226 accum += value;
227 return true;
228 }
229 return false;
230 }
231
232 bool derive(const wall_clock* wc, const child_user_clock* uc,
233 const child_system_clock* sc) noexcept
234 {
235 if(m_derive && wc && uc && sc)
236 {
237 value.first = uc->get_value() + sc->get_value();
238 value.second = wc->get_value();
239 accum += value;
240 return true;
241 }
242 return false;
243 }
244
245public:
246 this_type& operator+=(const this_type& rhs) noexcept
247 {
248 accum += rhs.accum;
249 value += rhs.value;
250 return *this;
251 }
252
253 this_type& operator-=(const this_type& rhs) noexcept
254 {
255 accum -= rhs.accum;
256 value -= rhs.value;
257 return *this;
258 }
259
260private:
261 bool m_derive = false;
262};
263//
264} // namespace component
265} // namespace tim
#define TIMEMORY_DECLARE_COMPONENT(NAME)
Declare a non-templated component type in the tim::component namespace.
Definition: macros.hpp:54
#define TIMEMORY_DEFINE_CONCRETE_TRAIT(TRAIT, COMPONENT, VALUE)
Definition: macros.hpp:110
#define TIMEMORY_STATISTICS_TYPE(COMPONENT, TYPE)
Definition: macros.hpp:207
void load(Archive &ar, tim::node::graph< Tp > &d)
Definition: node.hpp:520
void assemble(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:868
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:634
void derive(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:904
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:386
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:316
std::array< Tp, N > & operator+=(std::array< Tp, N > &, Other &&)
std::array< Tp, N > & operator-=(std::array< Tp, N > &, const std::array< Tp, N > &)
Definition: stl.hpp:96
Definition: kokkosp.cpp:39
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
auto get(const auto_bundle< Tag, Types... > &_obj)
description("A generic option for any setting. Each argument MUST be passed in " "form: 'NAME=VALUE'. E.g. --timemory-args " "\"papi_events=PAPI_TOT_INS,PAPI_TOT_CYC\" text_output=off") .action([&](parser_t &p)
Definition: config.cpp:312
static value_type record() noexcept
Definition: wall_clock.hpp:55
std::tuple< type_list<> > type
type_list
Definition: types.hpp:211