timemory  3.2.1
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.
properties.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 /** \file component/properties.hpp
26  * \headerfile component/properties.hpp "timemory/component/properties.hpp"
27  * Provides properties for components
28  *
29  */
30 
31 #pragma once
32 
33 #include "timemory/backends/process.hpp"
34 #include "timemory/backends/threading.hpp"
35 #include "timemory/enum.h"
39 
40 #include <cstdio>
41 #include <cstring>
42 #include <regex>
43 #include <set>
44 #include <string>
45 
46 namespace tim
47 {
48 namespace component
49 {
50 //
51 template <typename... Types>
52 struct placeholder;
53 //
54 using idset_t = std::set<std::string>;
55 //
56 struct nothing;
57 //
58 struct opaque;
59 //
60 namespace factory
61 {
62 //
63 template <typename Toolset, typename Arg, typename... Args>
64 opaque
65 get_opaque(Arg&& arg, Args&&... args);
66 //
67 template <typename Toolset>
68 opaque
69 get_opaque();
70 //
71 template <typename Toolset>
72 std::set<size_t>
73 get_typeids();
74 //
75 } // namespace factory
76 //
77 //--------------------------------------------------------------------------------------//
78 //
79 /// \struct tim::component::static_properties
80 /// \tparam Tp Component type
81 /// \tparam Placeholder Whether or not the component type is a placeholder type that
82 /// should be ignored during runtime initialization.
83 ///
84 /// \brief Provides three variants of a `matches` function for determining if a
85 /// component is identified by a given string or enumeration value
86 ///
87 template <typename Tp, bool PlaceHolder = concepts::is_placeholder<Tp>::value>
89 //
90 template <typename Tp>
91 struct properties;
92 //
93 //--------------------------------------------------------------------------------------//
94 //
95 template <typename Tp>
96 struct state
97 {
98  static bool& has_storage()
99  {
100  static thread_local bool _instance = false;
101  return _instance;
102  }
103 };
104 //
105 //--------------------------------------------------------------------------------------//
106 //
107 // single specialization
108 //
109 template <>
110 struct static_properties<void, false>
111 {
112  static bool matches(const char* _ckey, const char* _enum_str, const idset_t& _ids)
113  {
114  static bool _debug = tim::get_env<bool>("TIMEMORY_DEBUG", false);
115  static const auto regex_consts = std::regex_constants::ECMAScript |
116  std::regex_constants::icase |
117  std::regex_constants::optimize;
118  std::string _opts{ _enum_str };
119  _opts.reserve(_opts.size() + 512);
120  for(const auto& itr : _ids)
121  {
122  if(!itr.empty())
123  _opts += "|" + itr;
124  }
125  auto _option = std::string{ "\\b(" } + _opts + std::string{ ")\\b" };
126  try
127  {
128  if(std::regex_search(_ckey, std::regex{ _option, regex_consts }))
129  {
130  if(_debug)
131  {
132  auto _doption = std::string{ "\\b(" } + _opts + std::string{ ")\\b" };
133  fprintf(stderr,
134  "[component::static_properties::matches] '%s' matches (%s) "
135  "[regex: '%s']\n",
136  _ckey, _opts.c_str(), _doption.c_str());
137  fflush(stderr);
138  }
139  return true;
140  }
141  } catch(std::regex_error& err)
142  {
143  auto _doption = std::string{ "\\b(" } + _opts + std::string{ ")\\b" };
144  PRINT_HERE("regex error in regex_match(\"%s\", regex{ \"%s\", egrep | icase "
145  "| optimize }): %s [real: %s]",
146  _ckey, _doption.c_str(), err.what(), _option.c_str());
147  TIMEMORY_TESTING_EXCEPTION("regex error in: \"" << _doption << "\" for "
148  << _ckey)
149  }
150 
151  return false;
152  }
153 };
154 //
155 //--------------------------------------------------------------------------------------//
156 //
157 // non-placeholder types
158 //
159 template <typename Tp>
160 struct static_properties<Tp, false>
161 {
164 
165  static bool matches(int _idx) { return (_idx == ptype{}()); }
166  static bool matches(const std::string& _key) { return matches(_key.c_str()); }
167  static bool matches(const char* _key)
168  {
169  // don't allow checks for placeholder types
171  "static_properties is instantiating a placeholder type");
172 
173  return vtype::matches(_key, ptype::enum_string(), ptype::ids());
174  }
175 };
176 //
177 // placeholder types
178 //
179 template <typename Tp>
180 struct static_properties<Tp, true>
181 {
182  static bool matches(int) { return false; }
183  static bool matches(const char*) { return false; }
184  static bool matches(const std::string&) { return false; }
185 };
186 //
187 //--------------------------------------------------------------------------------------//
188 //
189 /// \struct tim::component::properties
190 /// \tparam Tp Component type
191 ///
192 /// \brief This is a critical specialization for mapping string and integers to
193 /// component types at runtime. The `enum_string()` function is the enum id as
194 /// a string. The `id()` function is (typically) the name of the C++ component
195 /// as a string. The `ids()` function returns a set of strings which are alternative
196 /// string identifiers to the enum string or the string ID. Additionally, it
197 /// provides serializaiton of these values.
198 ///
199 /// A macro is provides to simplify this specialization:
200 ///
201 /// \code{.cpp}
202 /// TIMEMORY_PROPERTY_SPECIALIZATION(wall_clock, TIMEMORY_WALL_CLOCK, "wall_clock",
203 /// "real_clock", "virtual_clock")
204 /// \endcode
205 ///
206 /// In the above, the first parameter is the C++ type, the second is the enumeration
207 /// id, the enum string is automatically generated via preprocessor `#` on the second
208 /// parameter, the third parameter is the string ID, and the remaining values are placed
209 /// in the `ids()`. Additionally, this macro specializes the
210 /// \ref tim::component::enumerator.
211 ///
212 template <typename Tp>
214 {
215  using type = Tp;
218 
219  static constexpr bool specialized() { return false; }
220  static constexpr const char* enum_string() { return "TIMEMORY_COMPONENTS_END"; }
221  static constexpr const char* id() { return ""; }
222  static idset_t ids() { return idset_t{}; }
223  template <typename Archive>
224  void serialize(Archive&, const unsigned int)
225  {}
227  //
228  constexpr operator TIMEMORY_COMPONENT() const { return TIMEMORY_COMPONENTS_END; }
229 };
230 //
231 //--------------------------------------------------------------------------------------//
232 //
233 /// \struct tim::component::enumerator
234 /// \tparam Idx Enumeration value
235 ///
236 /// \brief This is a critical specialization for mapping string and integers to
237 /// component types at runtime (should always be specialized alongside \ref
238 /// tim::component::properties) and it is also critical for performing template
239 /// metaprogramming "loops" over all the components. E.g.:
240 ///
241 /// \code{.cpp}
242 /// template <size_t Idx>
243 /// using Enumerator_t = typename tim::component::enumerator<Idx>::type;
244 ///
245 /// template <size_t... Idx>
246 /// auto init(std::index_sequence<Idx...>)
247 /// {
248 /// // expand for [0, TIMEMORY_COMPONENTS_END)
249 /// TIMEMORY_FOLD_EXPRESSION(tim::storage_initializer::get<
250 /// Enumerator_t<Idx>>());
251 /// }
252 ///
253 /// void init()
254 /// {
255 /// init(std::make_index_sequence<TIMEMORY_COMPONENTS_END>{});
256 /// }
257 /// \endcode
258 ///
259 template <int Idx>
260 struct enumerator : properties<placeholder<nothing>>
261 {
263  static constexpr bool value = false;
264 
265  bool operator==(int) const { return false; }
266  bool operator==(const char*) const { return false; }
267  bool operator==(const std::string&) const { return false; }
268 };
269 //
270 //--------------------------------------------------------------------------------------//
271 //
272 template <int Idx>
274 //
275 template <int Idx>
277 //
278 //--------------------------------------------------------------------------------------//
279 //
280 } // namespace component
281 } // namespace tim
Toolset
Definition: types.hpp:39
int TIMEMORY_COMPONENT
Definition: enum.h:633
#define TIMEMORY_COMPONENTS_END
Definition: enum.h:150
opaque get_opaque(Arg &&arg, Args &&... args)
Definition: definition.hpp:327
std::set< size_t > get_typeids()
Definition: definition.hpp:361
typename enumerator< Idx >::type enumerator_t
Definition: properties.hpp:273
typename enumerator< Idx >::type properties_t
Definition: properties.hpp:276
std::set< std::string > idset_t
Definition: properties.hpp:54
Definition: kokkosp.cpp:38
tim::mpl::apply< std::string > string
Definition: macros.hpp:52
This is a critical specialization for mapping string and integers to component types at runtime (shou...
Definition: properties.hpp:261
bool operator==(int) const
Definition: properties.hpp:265
bool operator==(const std::string &) const
Definition: properties.hpp:267
bool operator==(const char *) const
Definition: properties.hpp:266
static constexpr bool value
Definition: properties.hpp:263
provides nothing, used for dummy types in enum
Definition: placeholder.hpp:44
This is a critical specialization for mapping string and integers to component types at runtime....
Definition: properties.hpp:214
static constexpr const char * id()
Definition: properties.hpp:221
void serialize(Archive &, const unsigned int)
Definition: properties.hpp:224
TIMEMORY_COMPONENT value_type
Definition: properties.hpp:216
TIMEMORY_COMPONENT operator()()
Definition: properties.hpp:226
static constexpr bool specialized()
Definition: properties.hpp:219
static constexpr const char * enum_string()
Definition: properties.hpp:220
static constexpr TIMEMORY_COMPONENT value
Definition: properties.hpp:217
static bool & has_storage()
Definition: properties.hpp:98
static bool matches(const char *_key)
Definition: properties.hpp:167
static bool matches(const std::string &_key)
Definition: properties.hpp:166
static bool matches(const std::string &)
Definition: properties.hpp:184
static bool matches(const char *_ckey, const char *_enum_str, const idset_t &_ids)
Definition: properties.hpp:112
Provides three variants of a matches function for determining if a component is identified by a given...
Definition: properties.hpp:88
concept that specifies that a type is not necessarily marked as not available but is still a dummy ty...
Definition: concepts.hpp:179
#define PRINT_HERE(...)
Definition: macros.hpp:147
#define TIMEMORY_TESTING_EXCEPTION(...)
Definition: types.hpp:155