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.
definition.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
27#include "timemory/api.hpp"
32
33#include <cstdint>
34#include <iomanip>
35#include <iosfwd>
36#include <set>
37#include <sstream>
38#include <string>
39#include <unordered_map>
40
41#if defined(TIMEMORY_HASH_SOURCE) || !defined(TIMEMORY_USE_HASH_EXTERN)
42
43namespace tim
44{
45inline namespace hash
46{
47//
48//--------------------------------------------------------------------------------------//
49//
52{
53 static thread_local auto _inst =
54 get_shared_ptr_pair_instance<hash_map_t, TIMEMORY_API>();
55 static thread_local auto _dtor = scope::destructor{ []() {
56 auto _main = get_shared_ptr_pair_main_instance<hash_map_t, TIMEMORY_API>();
57 if(!_inst || !_main || _inst == _main)
58 return;
59 auto_lock_t _lk{ type_mutex<hash_map_t>(), std::defer_lock };
60 if(!_lk.owns_lock())
61 _lk.lock();
62 for(const auto& itr : *_inst)
63 {
64 if(_main->find(itr.first) == _main->end())
65 _main->emplace(itr.first, itr.second);
66 }
67 } };
68 return _inst;
69 (void) _dtor;
70}
71//
72//--------------------------------------------------------------------------------------//
73//
76{
77 static thread_local auto _inst =
78 get_shared_ptr_pair_instance<hash_alias_map_t, TIMEMORY_API>();
79 static thread_local auto _dtor = scope::destructor{ []() {
80 auto _main = get_shared_ptr_pair_main_instance<hash_alias_map_t, TIMEMORY_API>();
81 if(!_inst || !_main || _inst == _main)
82 return;
83 auto_lock_t _lk{ type_mutex<hash_alias_map_t>(), std::defer_lock };
84 if(!_lk.owns_lock())
85 _lk.lock();
86 for(const auto& itr : *_inst)
87 {
88 if(_main->find(itr.first) == _main->end())
89 _main->emplace(itr.first, itr.second);
90 }
91 } };
92 return _inst;
93 (void) _dtor;
94}
95//
96//--------------------------------------------------------------------------------------//
97//
98TIMEMORY_HASH_LINKAGE(std::shared_ptr<hash_resolver_vec_t>&)
100{
101 static auto _inst = []() {
102 auto _subinst = get_shared_ptr_lone_instance<hash_resolver_vec_t, TIMEMORY_API>();
103 if(_subinst && _subinst->empty())
104 _subinst->reserve(10);
105 return _subinst;
106 }();
107 return _inst;
108}
109//
110//--------------------------------------------------------------------------------------//
111//
114{
115 auto _alias_itr = _hash_alias->find(_hash_id);
116 if(_alias_itr != _hash_alias->end())
117 return _alias_itr->second;
118 return _hash_id;
119}
120//
121//--------------------------------------------------------------------------------------//
122//
126{
128}
129//
130//--------------------------------------------------------------------------------------//
131//
135{
137}
138//
139//--------------------------------------------------------------------------------------//
140//
143{
145}
146//
147//--------------------------------------------------------------------------------------//
148//
152{
153 static thread_local std::set<hash_value_t> _reported{};
154 if(_reported.count(_hash_id) > 0)
155 return;
156
157 _reported.insert(_hash_id);
158
159 if(!_hash_map)
160 {
161 fprintf(stderr,
162 "[%s@%s:%i]> hash identifier %llu could not be found bc the pointer to "
163 "the hash map is null\n",
164 __FUNCTION__, TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), __LINE__,
165 (unsigned long long) _hash_id);
166 return;
167 }
168
169 if(!_hash_alias)
170 {
171 fprintf(stderr,
172 "[%s@%s:%i]> hash identifier %llu could not be found bc the pointer to "
173 "the hash alias map is null\n",
174 __FUNCTION__, TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), __LINE__,
175 (unsigned long long) _hash_id);
176 return;
177 }
178
179 for(const auto& aitr : *_hash_alias)
180 {
181 if(_hash_id == aitr.first)
182 {
183 for(const auto& mitr : *_hash_map)
184 {
185 if(mitr.first == aitr.second)
186 {
187 fprintf(stderr,
188 "[%s@%s:%i]> found hash identifier %llu in alias map via "
189 "iteration after uomap->find failed! This might be an ABI or "
190 "an integer overflow problem\n",
191 __FUNCTION__,
192 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), __LINE__,
193 (unsigned long long) _hash_id);
194 }
195 }
196 }
197 }
198
199 for(auto& mitr : *_hash_map)
200 {
201 if(_hash_id == mitr.first)
202 {
203 fprintf(stderr,
204 "[%s@%s:%i]> found hash identifier %llu in hash map via iteration "
205 "after uomap->find failed! This might be an ABI or an integer "
206 "overflow problem\n",
207 __FUNCTION__, TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(),
208 __LINE__, (unsigned long long) _hash_id);
209 }
210 }
211
212 if(_hash_id > 0)
213 {
214 std::stringstream ss;
215 ss << "Error! node with hash " << _hash_id
216 << " does not have an associated string!\n";
217 static std::set<hash_value_t> _reported{};
218 if(_reported.count(_hash_id) == 0)
219 {
220 _reported.emplace(_hash_id);
221 bool _found_direct = (_hash_map->find(_hash_id) != _hash_map->end());
222 ss << " Found in map : " << std::boolalpha << _found_direct << '\n';
223 bool _found_alias = (_hash_alias->find(_hash_id) != _hash_alias->end());
224 ss << " Found in alias map : " << std::boolalpha << _found_alias << '\n';
225 if(_found_alias)
226 {
227 auto aitr = _hash_alias->find(_hash_id);
228 ss << " Found aliasing : " << aitr->first << " -> " << aitr->second
229 << '\n';
230 auto mitr = _hash_map->find(aitr->second);
231 if(mitr != _hash_map->end())
232 ss << " Found mapping : " << mitr->first << " -> " << mitr->second
233 << '\n';
234 else
235 ss << " Missing mapping\n";
236 }
237 else
238 {
239 ss << " Missing aliasing\n";
240 }
241 ss << " Hash map:\n";
242 auto _w = 20;
243 for(const auto& itr : *_hash_map)
244 ss << " " << std::setw(_w) << itr.first << " : " << (itr.second)
245 << "\n";
246 if(!_hash_alias->empty())
247 {
248 ss << " Alias hash map:\n";
249 for(const auto& itr : *_hash_alias)
250 ss << " " << std::setw(_w) << itr.first << " : " << itr.second
251 << "\n";
252 }
253 auto _registry = static_string::get_registry();
254 if(!_registry.empty())
255 {
256 ss << " Static strings:\n";
257 for(const auto* itr : _registry)
258 {
259 ss << " " << std::setw(_w)
260 << reinterpret_cast<std::size_t>(itr) << " : " << itr << "\n";
261 }
262 }
263 fprintf(stderr, "%s", ss.str().c_str());
264 }
265 }
266}
267//
268//--------------------------------------------------------------------------------------//
269//
270TIMEMORY_HASH_LINKAGE(typename hash_map_t::const_iterator)
273{
274 auto _map_itr = _hash_map->find(_hash_id);
275 if(_map_itr != _hash_map->end())
276 return _map_itr;
277
280 {
281 return find_hash_identifier(_hash_map, _hash_alias, _alias_itr->second);
282 }
283
284 return _hash_map->end();
285}
286//
287//--------------------------------------------------------------------------------------//
288//
289TIMEMORY_HASH_LINKAGE(typename hash_map_t::const_iterator)
291{
293}
294//
295//--------------------------------------------------------------------------------------//
296//
300{
301 // NOTE: for brevity, all statements returning true use comma operator to assign to
302 // result before returning true
303 if(!_hash_map)
304 return false;
305
306 auto _map_itr = _hash_map->find(_hash_id);
307 if(_map_itr != _hash_map->end())
308 return (_ret = &_map_itr->second, true);
309
310 // static_string
312 {
313 auto itr = _hash_map->emplace(_hash_id, reinterpret_cast<const char*>(_hash_id));
314 return (_ret = &itr.first->second, true);
315 }
316
318 {
319 auto _alias_itr = _hash_alias->find(_hash_id);
320 if(_alias_itr != _hash_alias->end())
321 {
322 return get_hash_identifier(_hash_map, _hash_alias, _alias_itr->second, _ret);
323 }
324 }
325
326 return false;
327}
328//
329//--------------------------------------------------------------------------------------//
330//
333 hash_value_t _hash_id, const char*& _ret)
334{
335 // NOTE: for brevity, all statements returning true use comma operator to assign to
336 // result before returning true
337 if(!_hash_map)
338 return false;
339
340 auto _map_itr = _hash_map->find(_hash_id);
341 if(_map_itr != _hash_map->end())
342 return (_ret = _map_itr->second.c_str(), true);
343
344 // static_string
346 return (_ret = reinterpret_cast<const char*>(_hash_id), true);
347
348 if(_hash_alias)
349 {
350 auto _alias_itr = _hash_alias->find(_hash_id);
351 if(_alias_itr != _hash_alias->end())
352 {
353 return get_hash_identifier(_hash_map, _hash_alias, _alias_itr->second, _ret);
354 }
355 }
356
357 return false;
358}
359//
360//--------------------------------------------------------------------------------------//
361//
364{
365 std::string* _ret = nullptr;
367 return *_ret;
369 return std::string("unknown-hash=") + std::to_string(_hash_id);
370}
371//
372//--------------------------------------------------------------------------------------//
373//
376{
378}
379//
380//--------------------------------------------------------------------------------------//
381//
384{
386}
387//
388//--------------------------------------------------------------------------------------//
389//
393{
394 std::string* _ret = nullptr;
396 return *_ret;
398 return std::string("unknown-hash=") + std::to_string(_hash_id);
399}
400//
401//--------------------------------------------------------------------------------------//
402//
404demangle_hash_identifier(std::string inp, char bdelim, char edelim)
405{
406 inp = demangle(inp);
407 size_t _beg = inp.find_first_of(bdelim);
408 while(_beg != std::string::npos)
409 {
410 size_t _end = inp.find_first_of(edelim, _beg);
411 if(_end == std::string::npos)
412 break;
413 auto _sz = _end - _beg - 1;
414 inp = inp.replace(_beg + 1, _sz, demangle(inp.substr(_beg + 1, _sz)));
415 _beg = inp.find_first_of(bdelim, _end + 1);
416 }
417 return demangle(inp);
418}
419//
420//--------------------------------------------------------------------------------------//
421//
422} // namespace hash
423} // namespace tim
424
425#endif
Include the macros for hash.
const hash_alias_ptr_t hash_value_t hash_value_t _alias_hash_id
Definition: definition.hpp:126
hash_value_t _hash_id
Definition: definition.hpp:114
std::shared_ptr< hash_resolver_vec_t > & get_hash_resolvers()
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, string_view_cref_t _prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
Definition: types.hpp:190
std::shared_ptr< hash_alias_map_t > hash_alias_ptr_t
Definition: types.hpp:89
hash_alias_ptr_t & get_hash_aliases()
bool get_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id, std::string *&_ret)
std::shared_ptr< hash_map_t > hash_map_ptr_t
Definition: types.hpp:87
const hash_alias_ptr_t hash_value_t std::string *& _ret
Definition: definition.hpp:300
const hash_alias_ptr_t & _hash_alias
Definition: definition.hpp:124
auto _map_itr
Definition: definition.hpp:306
TIMEMORY_HASH_LINKAGE(hash_map_ptr_t &) get_hash_ids()
Definition: definition.hpp:50
hash_map_t::const_iterator find_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id)
hash_map_ptr_t & get_hash_ids()
hash_value_t get_hash_id(Tp &&_prefix)
Definition: types.hpp:143
hash_identifier_error(_hash_map, _hash_alias, _hash_id)
auto _alias_itr
Definition: definition.hpp:278
std::string demangle_hash_identifier(std::string, char bdelim='[', char edelim=']')
size_t hash_value_t
Definition: types.hpp:84
Definition: kokkosp.cpp:39
std::unique_lock< mutex_t > auto_lock_t
Unique lock type around mutex_t.
Definition: locking.hpp:42
std::string demangle(const char *_mangled_name, int *_status=nullptr)
Definition: demangle.hpp:47
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
static string_registry_t get_registry()
static bool is_registered(const char *)
provides an object which can be returned from functions that will execute the lambda provided during ...
Definition: types.hpp:700
#define TIMEMORY_TRUNCATED_FILE_STRING(FILE)
Definition: macros.hpp:95