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.
components.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
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/network/backends.hpp"
32#include "timemory/units.hpp"
33
34//======================================================================================//
35//
36namespace tim
37{
38namespace component
39{
40/// \struct tim::component::network
41/// \brief Records the network activity
42//
43struct network_stats : public base<network_stats, cache::network_stats>
44{
45 static constexpr size_t data_size = cache::network_stats::data_size;
46
47 using value_type = cache::network_stats;
51 using string_array_type = typename cache::network_stats::string_array_type;
52 using iface_map_type = std::unordered_map<std::string, string_array_type>;
53
54 static std::string label();
55 static std::string description();
61 static value_type record(const std::string& _interface);
62 static value_type record(const std::vector<std::string>& _interfaces);
63 static std::vector<std::string>& get_interfaces();
64
66 network_stats(std::vector<std::string>);
67
68 network_stats() = default;
69 ~network_stats() = default;
70 network_stats(const network_stats&) = default;
72
75
76 data_array_type get() const;
78
79 void sample();
80 void start();
81 void stop();
82
83private:
84 bool m_first = true;
85 std::vector<std::string> m_interfaces = get_interfaces();
86
87private:
88 static const string_array_type& get_iface_paths(const std::string& _name);
89};
90//
91inline std::string
93{
94 return "network_stats";
95}
96//
97inline std::string
99{
100 return "Reports network bytes, packets, errors, dropped";
101}
102//
105{
106 if(_interface.empty())
107 return cache::network_stats{};
108 // const auto& _iface_paths = get_iface_paths(_name);
109 return cache::network_stats{ _interface };
110}
111//
113network_stats::record(const std::vector<std::string>& _interfaces)
114{
115 if(_interfaces.empty())
116 return cache::network_stats{};
117 cache::network_stats _data{};
118 for(const auto& itr : _interfaces)
119 {
120 if(!itr.empty())
121 _data += cache::network_stats{ itr };
122 }
123 return _data;
124}
125//
127: m_interfaces{ std::move(_interface) }
128{}
129//
130inline network_stats::network_stats(std::vector<std::string> _interfaces)
131: m_interfaces{ std::move(_interfaces) }
132{}
133//
134inline std::vector<std::string>&
136{
137 static std::string _last{};
138 static std::string _value{};
139 static std::vector<std::string> _instance{};
140
142 if(!_settings)
143 return _instance;
144 _settings->get(TIMEMORY_SETTINGS_KEY("NETWORK_INTERFACE"), _value, true);
145
146 auto _update_instance = []() {
147 _instance.clear();
148 for(auto&& itr : delimit(_value, " ,\t;"))
149 {
150 if(itr != "." && itr != "..")
151 _instance.emplace_back(std::move(itr));
152 }
153 };
154
155 if(_instance.empty())
156 {
157 if(!_value.empty())
158 {
159 _update_instance();
160 _last = _value;
161 }
162 else
163 {
164 for(auto&& itr : utility::filesystem::list_directory("/sys/class/net"))
165 {
166 if(itr != "." && itr != "..")
167 _instance.emplace_back(std::move(itr));
168 }
169 if(_instance.empty())
170 return _instance;
171 std::stringstream _ss;
172 for(const auto& itr : _instance)
173 _ss << ", " << itr;
174 _value = _last = _ss.str().substr(2);
175 _settings->set(TIMEMORY_SETTINGS_KEY("NETWORK_INTERFACE"), _value, true);
176 }
177 }
178 else if(_last != _value)
179 {
180 _update_instance();
181 _last = _value;
182 }
183
184 return _instance;
185}
186//
189{
190 auto _data = load();
191 if(!m_first && !get_is_transient())
192 {
193 _data.get_data().fill(0);
194 return _data.get_data();
195 }
196
197 static auto _data_units = cache::network_stats::data_units();
198 for(size_t i = 0; i < data_size; ++i)
199 _data.get_data()[i] /= _data_units[i];
200 return _data.get_data();
201}
202//
203inline std::string
205{
206 auto&& _get_display = [](const int64_t& _val, const std::string& _lbl,
207 const std::string& _units) {
208 std::stringstream ss;
210 ss << std::setw(base_type::get_width())
211 << std::setprecision(base_type::get_precision()) << _val;
212 if(!_units.empty())
213 ss << " " << _units;
214 if(!_lbl.empty())
215 ss << " " << _lbl;
216 return ss.str();
217 };
218
219 auto&& _val = value_type{ get() };
220 auto _disp = cache::network_stats::data_display_units();
221 auto _labels = cache::network_stats::data_labels();
222 std::stringstream ss;
223 for(size_t i = 0; i < data_size; ++i)
224 ss << ", " << _get_display(_val.get_data()[i], _labels[i], _disp[i]);
225 return ss.str().substr(2);
226}
227//
228inline void
230{
231 if(m_first)
232 {
233 m_first = false;
234 value = record(m_interfaces);
235 }
236 else
237 {
238 auto _current = record(m_interfaces);
239 accum += _current - value;
240 value = _current;
241 set_is_transient(true);
242 }
243}
244//
245inline void
247{
248 if(m_interfaces.empty())
249 m_interfaces = get_interfaces();
250 value = record(m_interfaces);
251}
252//
253inline void
255{
256 value = record(m_interfaces) - value;
257 accum += value;
258}
259//
262{
263 return _data.get_data();
264}
265//
268{
269 return cache::network_stats::data_units();
270}
271//
274{
275 return cache::network_stats::data_labels();
276}
277//
280{
281 return cache::network_stats::data_display_units();
282}
283//
286{
287 return cache::network_stats::data_descriptions();
288}
289//
291network_stats::get_iface_paths(const std::string& _name)
292{
293 static iface_map_type _iface_paths{};
294 auto itr = _iface_paths.find(_name);
295 if(itr == _iface_paths.end())
296 {
297 string_array_type _data{};
298 static const std::string _base = "/sys/class/net/";
299 for(size_t i = 0; i < data_size; ++i)
300 {
301 _data.at(i) = _base + _name + "/statistics/" +
302 cache::network_stats::data_labels().at(i);
303 }
304 auto_lock_t _lk(type_mutex<network_stats>());
305 _iface_paths.insert({ _name, _data });
306 }
307 itr = _iface_paths.find(_name);
308 return itr->second;
309}
310} // namespace component
311} // namespace tim
312//
313//======================================================================================//
STL namespace.
std::bitset< scope_count > data_type
Definition: types.hpp:399
Definition: kokkosp.cpp:39
std::unique_lock< mutex_t > auto_lock_t
Unique lock type around mutex_t.
Definition: locking.hpp:42
char argparse::argument_parser tim::settings * _settings
Definition: config.cpp:255
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
TIMEMORY_SETTINGS_KEY("SUPPRESS_PARSING")) TIMEMORY_SETTINGS_MEMBER_DEF(bool
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})
Definition: delimit.hpp:68
arg_result get(size_t _idx, Tp &_value)
Definition: argparse.hpp:674
static short get_precision()
static short get_width()
static fmtflags get_format_flags()
static string_array_type display_unit_array()
Definition: components.hpp:279
static std::string label()
Definition: components.hpp:92
cache::network_stats value_type
Definition: components.hpp:47
network_stats & operator=(const network_stats &)=default
network_stats & operator=(network_stats &&)=default
static string_array_type description_array()
Definition: components.hpp:285
static data_array_type unit_array()
Definition: components.hpp:267
static std::vector< std::string > & get_interfaces()
Definition: components.hpp:135
static std::string description()
Definition: components.hpp:98
std::string get_display() const
Definition: components.hpp:204
static value_type record(const std::string &_interface)
Definition: components.hpp:104
typename cache::network_stats::string_array_type string_array_type
Definition: components.hpp:51
data_array_type get() const
Definition: components.hpp:188
static data_array_type data_array(value_type)
Definition: components.hpp:261
network_stats(network_stats &&)=default
static constexpr size_t data_size
Definition: components.hpp:45
static string_array_type label_array()
Definition: components.hpp:273
network_stats(const network_stats &)=default
typename cache::network_stats::data_type data_array_type
Definition: components.hpp:50
std::unordered_map< std::string, string_array_type > iface_map_type
Definition: components.hpp:52
static settings * instance()
Definition: settings.hpp:536