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.
declaration.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 <cassert>
36#include <cstdlib>
37#include <functional>
38#include <iosfwd>
39#include <map>
40#include <mutex>
41#include <string>
42#include <utility>
43#include <vector>
44
45namespace tim
46{
47//
48//--------------------------------------------------------------------------------------//
49//
50// environment
51//
52//--------------------------------------------------------------------------------------//
53//
55{
56public:
58 using env_map_t = std::map<string_t, string_t>;
59 using env_uomap_t = std::map<string_t, string_t>;
60 using env_pair_t = std::pair<string_t, string_t>;
61 using iterator = typename env_map_t::iterator;
62 using const_iterator = typename env_map_t::const_iterator;
63 using filter_func_t = std::function<bool(const std::string&)>;
64
65public:
67
68private:
69 // if passed a global, insert m_env into it's array
70 env_settings(env_settings* _global = nullptr, int _id = 0);
71
72 // only the zero id deletes
74
75public:
76 template <typename Tp>
77 void insert(const std::string& env_id, Tp val);
78
79 env_map_t get() const;
80 iterator get(const string_t& _entry) { return m_env->find(_entry); }
81 const_iterator get(const string_t& _entry) const { return m_env->find(_entry); }
82 iterator begin() { return m_env->begin(); }
83 iterator end() { return m_env->end(); }
84 const_iterator begin() const { return m_env->begin(); }
85 const_iterator end() const { return m_env->end(); }
86
87 void print(
88 std::ostream&,
89 filter_func_t&& _filter = [](const std::string&) { return true; }) const;
90 friend std::ostream& operator<<(std::ostream& os, const env_settings& env)
91 {
92 env.print(os);
93 return os;
94 }
95
96 //----------------------------------------------------------------------------------//
97 // serialization
98 //
99 template <typename Archive>
100 void serialize(Archive& ar, unsigned int);
101
102 template <typename Archive>
103 static void serialize_environment(Archive& ar)
104 {
105 if(instance())
107 }
108
109private:
110 static std::atomic_bool& lock_flag()
111 {
112 static std::atomic_bool _instance(false);
113 return _instance;
114 }
115
116 void collapse();
117
118private:
119 int m_id = 0;
120 env_uomap_t* m_env = new env_uomap_t{};
121 std::vector<env_uomap_t*> m_env_other;
122};
123//
124//--------------------------------------------------------------------------------------//
125//
126template <typename Tp>
127void
128env_settings::insert(const std::string& env_id, Tp val)
129{
130#if !defined(TIMEMORY_DISABLE_STORE_ENVIRONMENT)
131 std::stringstream ss;
132 ss << std::boolalpha << val;
133
134 auto_lock_t lk(type_mutex<env_settings>(), std::defer_lock);
135 if(lock_flag().load() && !lk.owns_lock())
136 lk.lock();
137
138 if(m_env &&
139 (m_env->find(env_id) == m_env->end() || m_env->find(env_id)->second != ss.str()))
140 (*m_env)[env_id] = ss.str();
141#else
142 consume_parameters(env_id, val);
143#endif
144}
145//
146//--------------------------------------------------------------------------------------//
147//
148template <typename Archive>
149void
150env_settings::serialize(Archive& ar, const unsigned int)
151{
152 auto _tmp = env_uomap_t{};
153 if(!m_env)
154 m_env = &_tmp;
155
156 collapse();
157
158 auto_lock_t lk(type_mutex<env_settings>(), std::defer_lock);
159 lock_flag().store(true);
160
161 if(!lk.owns_lock())
162 lk.lock();
163
164 ar(cereal::make_nvp("environment", *m_env));
165
166 if(m_env == &_tmp)
167 m_env = nullptr;
168
169 lock_flag().store(false);
170}
171//
172//--------------------------------------------------------------------------------------//
173//
174template <typename Tp>
175Tp
176get_env(const std::string& env_id, Tp _default, bool _store)
177{
178 if(env_id.empty())
179 return _default;
180
181 auto* _env_settings = env_settings::instance();
182 char* env_var = std::getenv(env_id.c_str());
183 if(env_var)
184 {
185 std::string str_var = std::string(env_var);
186 std::stringstream iss{ str_var };
187 auto var = Tp{};
188 iss >> var;
189 if(_env_settings && _store)
190 _env_settings->insert<Tp>(env_id, var);
191 return var;
192 }
193 // record default value
194 if(_env_settings && _store)
195 _env_settings->insert<Tp>(env_id, _default);
196
197 // return default if not specified in environment
198 return _default;
199}
200//
201//--------------------------------------------------------------------------------------//
202//
203template <typename Tp>
204Tp
205get_env_choice(const std::string& env_id, Tp _default, std::set<Tp> _choices, bool _store)
206{
207 assert(!_choices.empty());
208 auto _choice = get_env<Tp>(env_id, _default, _store);
209
210 // check that the choice is valid
211 if(_choices.find(_choice) == _choices.end())
212 {
213 std::ostringstream _msg{};
214 _msg << "Error! Invalid value \"" << _choice << "\" for " << env_id
215 << ". Valid choices are: ";
216 std::ostringstream _opts{};
217 for(const auto& itr : _choices)
218 _opts << ", \"" << itr << "\"";
219 _msg << _opts.str().substr(2);
220 throw std::runtime_error(_msg.str());
221 }
222
223 return _choice;
224}
225//
226//--------------------------------------------------------------------------------------//
227//
228template <typename Tp>
229Tp
230load_env(const std::string& env_id, Tp _default)
231{
232 if(env_id.empty())
233 return _default;
234
235 auto* _env_settings = env_settings::instance();
236 if(!_env_settings)
237 return _default;
238
239 auto itr = _env_settings->get(env_id);
240 if(itr != _env_settings->end())
241 {
242 std::stringstream iss{ itr->second };
243 auto var = Tp{};
244 iss >> var;
245 return var;
246 }
247
248 // return default if not specified in environment
249 return _default;
250}
251//
252//--------------------------------------------------------------------------------------//
253//
254template <typename Tp>
255void
256set_env(const std::string& env_var, const Tp& _val, int override)
257{
258 std::stringstream ss_val;
259 ss_val << _val;
260#if defined(TIMEMORY_MACOS) || (defined(TIMEMORY_LINUX) && (_POSIX_C_SOURCE >= 200112L))
261 setenv(env_var.c_str(), ss_val.str().c_str(), override);
262#elif defined(TIMEMORY_WINDOWS)
263 auto _curr = get_env<std::string>(env_var, "");
264 if(_curr.empty() || override > 0)
265 _putenv_s(env_var.c_str(), ss_val.str().c_str());
266#else
267 consume_parameters(env_var, _val, override, ss_val);
268#endif
269}
270//
271//--------------------------------------------------------------------------------------//
272//
273template <typename FuncT>
274void
275print_env(std::ostream& os, FuncT&& _filter)
276{
277 static_assert(
278 std::is_same<bool, decltype(_filter(std::declval<std::string>()))>::value,
279 "Error! filter must accept string and return bool");
281 env_settings::instance()->print(os, std::forward<FuncT>(_filter));
282}
283
284} // namespace tim
typename env_map_t::const_iterator const_iterator
Definition: declaration.hpp:62
std::map< string_t, string_t > env_uomap_t
Definition: declaration.hpp:59
std::function< bool(const std::string &)> filter_func_t
Definition: declaration.hpp:63
iterator begin()
Definition: declaration.hpp:82
const_iterator end() const
Definition: declaration.hpp:85
std::string string_t
Definition: declaration.hpp:57
iterator get(const string_t &_entry)
Definition: declaration.hpp:80
static void serialize_environment(Archive &ar)
std::map< string_t, string_t > env_map_t
Definition: declaration.hpp:58
void serialize(Archive &ar, unsigned int)
static env_settings * instance()
const_iterator get(const string_t &_entry) const
Definition: declaration.hpp:81
typename env_map_t::iterator iterator
Definition: declaration.hpp:61
void print(std::ostream &, filter_func_t &&_filter=[](const std::string &) { return true;}) const
friend std::ostream & operator<<(std::ostream &os, const env_settings &env)
Definition: declaration.hpp:90
std::pair< string_t, string_t > env_pair_t
Definition: declaration.hpp:60
env_map_t get() const
void insert(const std::string &env_id, Tp val)
const_iterator begin() const
Definition: declaration.hpp:84
void load(Archive &ar, tim::node::graph< Tp > &d)
Definition: node.hpp:520
Definition: kokkosp.cpp:39
Tp get_env_choice(const std::string &env_id, Tp _default, std::set< Tp > _choices, bool _store)
void set_env(const std::string &env_var, const Tp &_val, int override)
std::unique_lock< mutex_t > auto_lock_t
Unique lock type around mutex_t.
Definition: locking.hpp:42
void print_env(std::ostream &os, FuncT &&_filter)
Print all environment queries and their values which satisfy the filter conditions.
Tp get_env(const std::string &env_id, Tp _default, bool _store)
Tp load_env(const std::string &env_id, Tp _default)
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
const std::string std::ostream * os
void consume_parameters(ArgsT &&...)
Definition: types.hpp:285
#define TIMEMORY_GET_CLASS_VERSION(...)
Definition: types.hpp:844