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.
tsettings.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
31#include "timemory/tpls/cereal/cereal.hpp"
34
35#include <cstdlib>
36#include <iomanip>
37#include <iosfwd>
38#include <iostream>
39#include <map>
40#include <memory>
41#include <regex>
42#include <string>
43#include <type_traits>
44#include <typeindex>
45#include <typeinfo>
46#include <utility>
47#include <vector>
48
49namespace tim
50{
51//
52/// \struct tim::tsettings
53/// \brief Implements a specific setting
54template <typename Tp, typename Vp>
55struct tsettings final : public vsettings
56{
57private:
58 template <typename Up>
59 static constexpr bool is_bool_type()
60 {
61 return std::is_same<decay_t<Up>, bool>::value;
62 }
63
64 template <typename Up>
65 static constexpr bool is_string_type()
66 {
67 return std::is_same<decay_t<Up>, std::string>::value;
68 }
69
70 template <typename Up>
71 static constexpr bool is_else_type()
72 {
73 return !is_bool_type<Up>() && !is_string_type<Up>();
74 }
75
76public:
77 using type = Tp;
78 using value_type = Vp;
82 using vpointer_t = std::shared_ptr<vsettings>;
83
84public:
85 template <typename Up = Vp, enable_if_t<!std::is_reference<Up>::value> = 0>
86 tsettings();
87
88 template <typename... Args>
89 tsettings(Vp, Args&&...);
90
91 template <typename... Args>
92 tsettings(noparse, Vp, Args&&...);
93
94 ~tsettings() override = default;
95
96 tsettings(const tsettings&) = default;
97 tsettings(tsettings&&) noexcept = default;
98 tsettings& operator=(const tsettings&) = default;
99 tsettings& operator=(tsettings&&) noexcept = default;
100
101public:
102 Tp& get();
103 const Tp& get() const;
104 Tp get_value(const std::string& val) const;
105 std::string as_string() const override;
106
107 void set(Tp);
108 void reset() final;
109 void parse() final;
110 void parse(const std::string& v) final;
111 void clone(std::shared_ptr<vsettings> rhs) final;
112 void add_argument(argparse::argument_parser& p) final;
113
114 vpointer_t clone() final;
116 display_map_t get_display(std::ios::fmtflags fmt = {}, int _w = -1,
117 int _p = -1) override;
118
119 template <typename Archive, typename Up = Vp>
120 void save(Archive& ar, const unsigned int,
121 enable_if_t<!std::is_reference<Up>::value, int> = 0) const;
122
123 template <typename Archive>
124 void load(Archive& ar, const unsigned int);
125
126private:
127 template <typename Up>
128 auto get_action(enable_if_t<is_bool_type<Up>(), int> = 0)
129 TIMEMORY_VISIBILITY("hidden");
130
131 template <typename Up>
132 auto get_action(enable_if_t<is_string_type<Up>(), long> = 0)
133 TIMEMORY_VISIBILITY("hidden");
134
135 template <typename Up>
136 auto get_action(enable_if_t<is_else_type<Up>(), long long> = 0)
137 TIMEMORY_VISIBILITY("hidden");
138
139 template <typename Up>
140 Up get_value(const std::string& val, enable_if_t<is_bool_type<Up>(), int> = 0) const
141 TIMEMORY_VISIBILITY("hidden");
142
143 template <typename Up>
144 Up get_value(const std::string& val,
145 enable_if_t<is_string_type<Up>(), long> = 0) const
146 TIMEMORY_VISIBILITY("hidden");
147
148 template <typename Up>
149 Up get_value(const std::string& str,
150 enable_if_t<is_else_type<Up>(), long long> = 0) const
151 TIMEMORY_VISIBILITY("hidden");
152
153private:
154 using base_type::m_count;
155 using base_type::m_description;
156 using base_type::m_env_name;
157 using base_type::m_max_count;
158 using base_type::m_name;
159 using base_type::m_type_index;
160 value_type m_value;
161 type m_init = {};
162};
163//
164template <typename Tp, typename Vp>
165template <typename Up, enable_if_t<!std::is_reference<Up>::value, int>>
167: base_type{}
168, m_value{ Tp{} }
169, m_init{ Tp{} }
170{
171 this->parse();
172}
173//
174template <typename Tp, typename Vp>
175template <typename... Args>
176tsettings<Tp, Vp>::tsettings(Vp _value, Args&&... _args) // NOLINT
177: base_type{ std::forward<Args>(_args)... }
178, m_value{ _value } // NOLINT
179, m_init{ _value } // NOLINT
180{
181 this->parse();
182 m_type_index = std::type_index(typeid(type));
183 m_value_index = std::type_index(typeid(value_type));
184}
185//
186template <typename Tp, typename Vp>
187template <typename... Args>
188tsettings<Tp, Vp>::tsettings(noparse, Vp _value, Args&&... _args) // NOLINT
189: base_type{ std::forward<Args>(_args)... }
190, m_value{ _value } // NOLINT
191, m_init{ _value } // NOLINT
192{
193 m_type_index = std::type_index(typeid(type));
194 m_value_index = std::type_index(typeid(value_type));
195}
196//
197template <typename Tp, typename Vp>
198Tp&
200{
201 return m_value;
202}
203//
204template <typename Tp, typename Vp>
205const Tp&
207{
208 return m_value;
209}
210//
211template <typename Tp, typename Vp>
212Tp
214{
215 return get_value<Tp>(val);
216}
217//
218template <typename Tp, typename Vp>
219void
221{
222 auto _old = m_value;
223 m_value = std::move(_value);
224 report_change(std::move(_old), m_value);
225}
226//
227template <typename Tp, typename Vp>
230{
231 std::stringstream ss;
232 ss << std::boolalpha;
233 ss << m_value;
234 return ss.str();
235}
236//
237template <typename Tp, typename Vp>
238void
240{
241 set(m_init);
242}
243//
244template <typename Tp, typename Vp>
245void
247{
248 if(!m_env_name.empty())
249 {
250 char* c_env_val = std::getenv(m_env_name.c_str());
251 if(c_env_val)
252 parse(std::string{ c_env_val });
253 }
254}
255//
256template <typename Tp, typename Vp>
257void
259{
260 set(std::move(get_value<decay_t<Tp>>(v)));
261}
262//
263template <typename Tp, typename Vp>
264void
266{
267 if(!m_cmdline.empty())
268 {
269 if(std::is_same<Tp, bool>::value)
270 m_max_count = 1;
271 p.add_argument(m_cmdline, m_description)
272 .action(get_action(TIMEMORY_API{}))
273 .count(m_count)
274 .max_count(m_max_count)
275 .choices(m_choices);
276 }
277}
278//
279template <typename Tp, typename Vp>
280void
281tsettings<Tp, Vp>::clone(std::shared_ptr<vsettings> rhs)
282{
283 vsettings::clone(rhs);
284 if(dynamic_cast<tsettings<Tp>*>(rhs.get()))
285 {
286 set(dynamic_cast<tsettings<Tp>*>(rhs.get())->get());
287 }
288 else if(dynamic_cast<tsettings<Tp, Tp&>*>(rhs.get()))
289 {
290 set(dynamic_cast<tsettings<Tp, Tp&>*>(rhs.get())->get());
291 }
292}
293//
294template <typename Tp, typename Vp>
295std::shared_ptr<vsettings>
297{
298 using Up = decay_t<Tp>;
299 return std::make_shared<tsettings<Up>>(
300 noparse{}, Up{ m_value }, std::string{ m_name }, std::string{ m_env_name },
301 std::string{ m_description }, std::vector<std::string>{ m_cmdline },
302 int32_t{ m_count }, int32_t{ m_max_count },
303 std::vector<std::string>{ m_choices });
304}
305//
306template <typename Tp, typename Vp>
308{
309 return get_action<Tp>();
310}
311//
312template <typename Tp, typename Vp>
314tsettings<Tp, Vp>::get_display(std::ios::fmtflags fmt, int _w, int _p)
315{
316 auto _data = vsettings::get_display(fmt, _w, _p);
317 auto _as_str = [&](auto _val) {
318 std::stringstream _ss;
319 _ss.setf(fmt);
320 if(_w > -1)
321 _ss << std::setw(_w);
322 if(_p > -1)
323 _ss << std::setprecision(_p);
324 _ss << std::boolalpha << _val;
325 return _ss.str();
326 };
327 _data["value"] = _as_str(m_value);
328 _data["type"] = _as_str(demangle<Tp>());
329 return _data;
330}
331//
332template <typename Tp, typename Vp>
333template <typename Archive, typename Up>
334void
335tsettings<Tp, Vp>::save(Archive& ar, const unsigned int,
336 enable_if_t<!std::is_reference<Up>::value, int>) const
337{
338 std::string _dtype =
339 (std::is_same<Tp, std::string>::value) ? "string" : demangle<Tp>();
340 ar(cereal::make_nvp("name", m_name));
341 ar(cereal::make_nvp("environ", m_env_name));
342 ar(cereal::make_nvp("description", m_description));
343 ar(cereal::make_nvp("count", m_count));
344 ar(cereal::make_nvp("max_count", m_max_count));
345 ar(cereal::make_nvp("cmdline", m_cmdline));
346 ar(cereal::make_nvp("data_type", _dtype));
347 ar(cereal::make_nvp("initial", m_init));
348 ar(cereal::make_nvp("value", m_value));
349}
350//
351template <typename Tp, typename Vp>
352template <typename Archive>
353void
354tsettings<Tp, Vp>::load(Archive& ar, const unsigned int)
355{
356 try
357 {
358 std::string _dtype{};
359 ar(cereal::make_nvp("name", m_name));
360 ar(cereal::make_nvp("environ", m_env_name));
361 ar(cereal::make_nvp("description", m_description));
362 ar(cereal::make_nvp("count", m_count));
363 ar(cereal::make_nvp("max_count", m_max_count));
364 ar(cereal::make_nvp("cmdline", m_cmdline));
365 ar(cereal::make_nvp("data_type", _dtype));
366 ar(cereal::make_nvp("initial", m_init));
367 } catch(...)
368 {}
369 ar(cereal::make_nvp("value", m_value));
370}
371//
372template <typename Tp, typename Vp>
373template <typename Up>
374auto tsettings<Tp, Vp>::get_action(enable_if_t<is_bool_type<Up>(), int>)
375{
376 return [&](parser_t& p) {
377 std::string id = m_cmdline.back();
378 auto pos = m_cmdline.back().find_first_not_of('-');
379 if(pos != std::string::npos)
380 id = id.substr(pos);
381 auto val = p.get<std::string>(id);
382 if(val.empty())
383 {
384 set(true);
385 }
386 else
387 {
388 set(get_bool(val, true));
389 }
390 };
391}
392//
393template <typename Tp, typename Vp>
394template <typename Up>
395auto tsettings<Tp, Vp>::get_action(enable_if_t<is_string_type<Up>(), long>)
396{
397 return [&](parser_t& p) {
398 std::string id = m_cmdline.back();
399 auto pos = m_cmdline.back().find_first_not_of('-');
400 if(pos != std::string::npos)
401 id = id.substr(pos);
402 auto _vec = p.get<std::vector<std::string>>(id);
403 if(_vec.empty())
404 {
405 set("");
406 }
407 else
408 {
409 std::stringstream ss;
410 for(auto& itr : _vec)
411 ss << ", " << itr;
412 set(ss.str().substr(2));
413 }
414 };
415}
416//
417template <typename Tp, typename Vp>
418template <typename Up>
419auto tsettings<Tp, Vp>::get_action(enable_if_t<is_else_type<Up>(), long long>)
420{
421 return [&](parser_t& p) {
422 std::string id = m_cmdline.back();
423 auto pos = m_cmdline.back().find_first_not_of('-');
424 if(pos != std::string::npos)
425 id = id.substr(pos);
426 set(p.get<decay_t<Up>>(id));
427 };
428}
429//
430template <typename Tp, typename Vp>
431template <typename Up>
432Up
434 enable_if_t<is_bool_type<Up>(), int>) const
435{
436 if(!val.empty())
437 return get_bool(val, true);
438 return true;
439}
440//
441template <typename Tp, typename Vp>
442template <typename Up>
443Up
445 enable_if_t<is_string_type<Up>(), long>) const
446{
447 return val;
448}
449//
450template <typename Tp, typename Vp>
451template <typename Up>
452Up
454 enable_if_t<is_else_type<Up>(), long long>) const
455{
456 std::stringstream ss;
457 ss << str;
458 Up val{};
459 ss >> val;
460 return val;
461}
462//
463} // namespace tim
464
465namespace tim
466{
467namespace cereal
468{
469template <typename Archive, typename Tp>
470void
471save(Archive& ar, std::shared_ptr<tim::tsettings<Tp, Tp&>> obj)
472{
473 auto _obj = obj->clone();
474 ar(_obj);
475}
476} // namespace cereal
477} // namespace tim
STL namespace.
void save(Archive &ar, std::shared_ptr< tim::tsettings< Tp, Tp & > > obj)
Definition: tsettings.hpp:471
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
bool get_bool(const std::string &strbool, bool _default) noexcept
Definition: utility.cpp:75
typename std::decay< T >::type decay_t
Alias template for decay.
Definition: types.hpp:194
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
argparse::argument_parser parser_t
Definition: config.cpp:264
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
size_t pos
Definition: config.cpp:102
argument & action(ActionFuncT &&_func)
Definition: argparse.hpp:495
argument & choices(const std::initializer_list< T > &_choices)
Definition: argparse.hpp:469
Implements a specific setting.
Definition: tsettings.hpp:56
parser_func_t get_action(TIMEMORY_API) override
Definition: tsettings.hpp:307
display_map_t get_display(std::ios::fmtflags fmt={}, int _w=-1, int _p=-1) override
Definition: tsettings.hpp:314
tsettings(const tsettings &)=default
base_type::parser_func_t parser_func_t
Definition: tsettings.hpp:81
vpointer_t clone() final
Definition: tsettings.hpp:296
void parse() final
Definition: tsettings.hpp:246
void save(Archive &ar, const unsigned int, enable_if_t<!std::is_reference< Up >::value, int >=0) const
Definition: tsettings.hpp:335
vsettings base_type
Definition: tsettings.hpp:79
void add_argument(argparse::argument_parser &p) final
Definition: tsettings.hpp:265
std::shared_ptr< vsettings > vpointer_t
Definition: tsettings.hpp:82
tsettings(Vp, Args &&...)
tsettings(tsettings &&) noexcept=default
void reset() final
Definition: tsettings.hpp:239
~tsettings() override=default
std::string as_string() const override
Definition: tsettings.hpp:229
tsettings(noparse, Vp, Args &&...)
Tp get_value(const std::string &val) const
Definition: tsettings.hpp:213
void set(Tp)
Definition: tsettings.hpp:220
void load(Archive &ar, const unsigned int)
Definition: tsettings.hpp:354
Virtual base class for storing settings.
Definition: vsettings.hpp:56
virtual display_map_t get_display(std::ios::fmtflags fmt={}, int _w=-1, int _p=-1)
vsettings(std::string _name="", std::string _env_name="", std::string _descript="", std::vector< std::string > _cmdline={}, int32_t _count=-1, int32_t _max_count=-1, std::vector< std::string > _choices={})
Definition: vsettings.cpp:44
std::type_index m_value_index
Definition: vsettings.hpp:143
argparse::argument_parser parser_t
Definition: vsettings.hpp:57
std::map< std::string, std::string > display_map_t
Definition: vsettings.hpp:59
virtual std::shared_ptr< vsettings > clone()=0
std::function< void(parser_t &)> parser_func_t
Definition: vsettings.hpp:58
typename typename typename
Definition: types.hpp:226