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.
config.cpp
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#ifndef TIMEMORY_CONFIG_CONFIG_CPP_
26#define TIMEMORY_CONFIG_CONFIG_CPP_ 1
27
29
30#if defined(TIMEMORY_CONFIG_SOURCE) || !defined(TIMEMORY_USE_CONFIG_EXTERN)
31//
32# include "timemory/backends/process.hpp"
41
42# include <fstream>
43# include <string>
44
45namespace tim
46{
47//
48//--------------------------------------------------------------------------------------//
49//
50// config
51//
52//--------------------------------------------------------------------------------------//
53//
55timemory_init(int argc, char** argv, const std::string& _prefix,
56 const std::string& _suffix)
57{
60 {
61 if(_settings->get_debug() || _settings->get_verbose() > 3)
62 PRINT_HERE("%s", "");
63
64 if(_settings->get_enable_signal_handler())
65 {
66 auto default_signals = signal_settings::get_default();
67 for(const auto& itr : default_signals)
69 // should return default and any modifications from environment
70 auto enabled_signals = signal_settings::get_enabled();
71 enable_signal_detection(enabled_signals);
72 }
73
74 _settings->init_config();
75 }
76
77 std::string exe_name = (argc > 0) ? argv[0] : "";
78
79 while(exe_name.find('\\') != std::string::npos)
80 exe_name = exe_name.substr(exe_name.find_last_of('\\') + 1);
81
82 while(exe_name.find('/') != std::string::npos)
83 exe_name = exe_name.substr(exe_name.find_last_of('/') + 1);
84
85 static const std::vector<std::string> _exe_suffixes = { ".py", ".exe" };
86 for(const auto& ext : _exe_suffixes)
87 {
88 if(exe_name.find(ext) != std::string::npos)
89 exe_name.erase(exe_name.find(ext), ext.length() + 1);
90 }
91
92 if(_settings)
93 _settings->set_tag(exe_name);
94
96 for(auto& itr : exe_name)
97 {
98 if(itr == '_')
99 itr = '-';
100 }
101
102 size_t pos = std::string::npos;
103 while((pos = exe_name.find("--")) != std::string::npos)
104 exe_name.erase(pos, 1);
105
106 if(exe_name.empty())
107 exe_name = "timemory-output";
108
109 if(_settings)
110 {
111 _settings->get_output_path() = exe_name;
112
113 // allow environment overrides
115
116 if(_settings->get_enable_signal_handler())
117 {
118 auto _exit_action = [](int nsig) {
119 auto _manager = manager::master_instance();
120 if(_manager)
121 {
122 std::cout << "Finalizing after signal: " << nsig << " :: "
123 << signal_settings::str(static_cast<sys_signal>(nsig))
124 << std::endl;
125 _manager->finalize();
126 }
127 };
129 }
130
132 }
133
134 static auto _manager = manager::instance();
135
136 if(_settings)
137 _settings->set_initialized(true);
138
139 if(_manager)
140 {
141 _manager->update_metadata_prefix();
142 _manager->initialize();
143 }
144}
145//
146//--------------------------------------------------------------------------------------//
147//
150 const std::string& _suffix)
151{
152 auto* cstr = const_cast<char*>(exe_name.c_str());
153 auto _argc = 1;
154 auto* _argv = &cstr;
155 timemory_init(_argc, _argv, _prefix, _suffix);
156}
157//
158//--------------------------------------------------------------------------------------//
159//
161timemory_init(int* argc, char*** argv, const std::string& _prefix,
162 const std::string& _suffix)
163{
165 {
166 if(settings::debug())
167 PRINT_HERE("%s", "initializing mpi");
168
169 mpi::initialize(argc, argv);
170 }
171
173 {
174 if(settings::debug())
175 PRINT_HERE("%s", "initializing upcxx");
176
178 }
179
182}
183//
184//--------------------------------------------------------------------------------------//
185//
187timemory_init(int* argc, char*** argv, argparse::argument_parser& parser,
188 const std::string& _prefix, const std::string& _suffix)
189{
191 {
192 if(settings::debug())
193 PRINT_HERE("%s", "initializing mpi");
194
195 mpi::initialize(argc, argv);
196 }
197
199 {
200 if(settings::debug())
201 PRINT_HERE("%s", "initializing upcxx");
202
204 }
205
208}
209//
210//--------------------------------------------------------------------------------------//
211//
213timemory_init(std::vector<std::string>& args, argparse::argument_parser& parser,
214 const std::string& _prefix, const std::string& _suffix)
215{
216 int argc = args.size();
217 char** argv = new char*[argc];
218 for(int i = 0; i < argc; ++i)
219 {
220 auto len = args.at(i).length();
221 argv[i] = new char[len + 1];
222 strcpy(argv[i], args.at(i).c_str());
223 argv[i][len] = '\0';
224 }
225
227 {
228 if(settings::debug())
229 PRINT_HERE("%s", "initializing mpi");
230
231 mpi::initialize(argc, argv);
232 }
233
235 {
236 if(settings::debug())
237 PRINT_HERE("%s", "initializing upcxx");
238
240 }
241
244
245 for(int i = 0; i < argc; ++i)
246 delete[] argv[i];
247 delete[] argv;
248}
249//
250//--------------------------------------------------------------------------------------//
251//
253timemory_argparse(int* argc, char*** argv, argparse::argument_parser* parser,
255{
256 // if pointers are null, return
257 if(!argc || !argv)
258 return;
259
260 // if only one argument, return
261 if(*argc < 2)
262 return;
263
266
267 // print help
268 auto help_action = [](parser_t& p) {
269 if(dmp::rank() == 0)
270 p.print_help("-- <NON_TIMEMORY_ARGS>");
271 exit(EXIT_SUCCESS);
272 };
273
274 auto err_action = [=](const parser_err_t& _err) {
275 if(dmp::rank() == 0 && _err)
276 std::cerr << "[timemory_argparse]> Error! " << _err << std::endl;
277 };
278
279 // if argument parser was not provided
280 bool _cleanup_parser = parser == nullptr;
282 parser = new parser_t{ (*argv)[0] };
283
284 // if settings instance was not provided
285 bool _cleanup_settings = _settings == nullptr;
286 static auto _shared_settings = tim::settings::shared_instance();
287 if(_cleanup_settings && !_shared_settings)
288 return;
290 _settings = _shared_settings.get();
291
292 // enable help
294 parser->on_error([=](parser_t& p, const parser_err_t& _err) {
295 err_action(_err);
296 if(dmp::rank() == 0 && _settings->get_verbose() > 0)
297 p.print_help("-- <NON_TIMEMORY_ARGS>");
298 });
299
300 // add the arguments in the order they were appended to the settings
301 for(const auto& itr : _settings->ordering())
302 {
303 auto sitr = _settings->find(itr);
304 if(sitr != _settings->end() && sitr->second)
305 {
306 sitr->second->add_argument(*parser);
307 }
308 }
309
311 .names({ "--timemory-args" })
312 .description("A generic option for any setting. Each argument MUST be passed in "
313 "form: 'NAME=VALUE'. E.g. --timemory-args "
314 "\"papi_events=PAPI_TOT_INS,PAPI_TOT_CYC\" text_output=off")
315 .action([&](parser_t& p) {
316 // get the options
317 auto vopt = p.get<std::vector<std::string>>("timemory-args");
318 for(auto& str : vopt)
319 {
320 // get the args
321 auto vec = tim::delimit(str, " \t;:");
322 for(const auto& itr : vec)
323 {
324 DEBUG_PRINT_HERE("Processing: %s", itr.c_str());
325 auto _pos = itr.find('=');
326 auto _key = itr.substr(0, _pos);
327 auto _val = (_pos == std::string::npos) ? "" : itr.substr(_pos + 1);
328 if(!_settings->update(_key, _val, false))
329 {
330 std::cerr << "[timemory_argparse]> Warning! For "
331 "--timemory-args, key \""
332 << _key << "\" is not a recognized setting. \"" << _val
333 << "\" was not applied." << std::endl;
334 }
335 }
336 }
337 });
338
340 if(parser->exists("help"))
342
343 // cleanup if argparse was not provided
345 delete parser;
346}
347//
348//--------------------------------------------------------------------------------------//
349//
351timemory_argparse(std::vector<std::string>& args, argparse::argument_parser* parser,
353{
354 int argc = args.size();
355 char** argv = new char*[argc];
356 for(int i = 0; i < argc; ++i)
357 {
358 // intentional memory leak
359 auto len = args.at(i).length();
360 argv[i] = new char[len + 1];
361 strcpy(argv[i], args.at(i).c_str());
362 argv[i][len] = '\0';
363 }
364
366
367 // updates args
368 args.clear();
369 for(int i = 0; i < argc; ++i)
370 args.emplace_back(argv[i]);
371}
372//
373//--------------------------------------------------------------------------------------//
374//
375TIMEMORY_CONFIG_LINKAGE(void) // NOLINT
377{
379 auto _manager = manager::instance();
380
381 if(_settings)
382 _settings->set_initialized(false);
383
384 if(_manager)
385 {
386 if(_settings && _settings->get_debug())
387 PRINT_HERE("%s", "finalizing manager");
388 _manager->finalize();
389 }
390
391 if(_settings)
392 {
393 if(_settings->get_upcxx_finalize())
394 {
395 if(_settings->get_debug())
396 PRINT_HERE("%s", "finalizing upcxx");
397
399 }
400
401 if(_settings->get_mpi_finalize())
402 {
403 if(_settings->get_debug())
404 PRINT_HERE("%s", "finalizing mpi");
406 }
407
408 if(_settings->get_debug() || _settings->get_verbose() > 3)
409 PRINT_HERE("%s", "");
410
411 if(_settings->get_enable_signal_handler())
412 {
413 if(_settings->get_debug())
414 PRINT_HERE("%s", "disabling signal detection");
416 }
417
418 if(_settings->get_debug())
419 PRINT_HERE("%s", "done");
420 }
421}
422//
423} // namespace tim
424//
425//--------------------------------------------------------------------------------------//
426//
427#endif // defined(TIMEMORY_CONFIG_SOURCE) || !defined(TIMEMORY_USE_CONFIG_EXTERN)
428
429#endif
static pointer_t instance()
Get a shared pointer to the instance for the current thread.
static pointer_t master_instance()
Get a shared pointer to the instance on the primary thread.
static std::string str(const sys_signal &)
Definition: signals.hpp:147
static void enable(const sys_signal &)
Definition: signals.hpp:74
static signal_set_t get_enabled()
Definition: signals.hpp:296
static void set_exit_action(signal_function_t _f)
Definition: signals.hpp:280
static signal_set_t get_default()
Definition: signals.hpp:312
The declaration for the types for config without definitions.
Include the macros for config.
Declare the config types.
The declaration for the types for manager without definitions.
STL namespace.
Definition: kokkosp.cpp:39
bool _cleanup_settings
Definition: config.cpp:285
char const std::string & _prefix
Definition: config.cpp:55
void timemory_finalize()
finalization of the specified types
bool _cleanup_parser
Definition: config.cpp:280
timemory_argparse(argc, argv)
std::string exe_name
Definition: config.cpp:77
bool enable_signal_detection(signal_settings::signal_set_t=signal_settings::get_default())
Definition: signals.hpp:368
sys_signal
Definition: declaration.hpp:69
void initialize(CompList< CompTypes... > &obj, std::initializer_list< EnumT > components)
Definition: initialize.hpp:53
upcxx_init
Definition: settings.cpp:1706
void timemory_init(Args &&... _args)
Definition: config.hpp:49
auto err_action
Definition: config.cpp:274
char ** argv
Definition: config.cpp:55
auto help_action
Definition: config.cpp:268
char argparse::argument_parser & parser
Definition: config.cpp:187
char argparse::argument_parser tim::settings * _settings
Definition: config.cpp:255
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
size_t pos
Definition: config.cpp:102
void disable_signal_detection()
Definition: signals.hpp:379
mpi_init
Definition: settings.cpp:1701
typename parser_t::result_type parser_err_t
Definition: config.cpp:265
void finalize()
Definition: types.hpp:119
description("A generic option for any setting. Each argument MUST be passed in " "form: 'NAME=VALUE'. E.g. --timemory-args " "\"papi_events=PAPI_TOT_INS,PAPI_TOT_CYC\" text_output=off") .action([&](parser_t &p)
Definition: config.cpp:312
TIMEMORY_CONFIG_LINKAGE(void) timemory_init(int argc
Definition: config.cpp:148
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})
Definition: delimit.hpp:68
char const std::string const std::string & _suffix
Definition: config.cpp:57
argument & names(const std::vector< std::string > &names)
Definition: argparse.hpp:383
void on_error(ErrorFuncT &&_func)
Definition: argparse.hpp:979
bool exists(const std::string &name) const
Returns whether or not an option was found in the arguments. Only useful after a call to parse or par...
Definition: argparse.hpp:912
known_args_t parse_known_args(int argc, char **argv, const std::string &_delim="--", int verbose_level=0)
Basic variant of parse_known_args which does not replace argc/argv and does not provide an array of s...
Definition: argparse.hpp:765
arg_result get(size_t _idx, Tp &_value)
Definition: argparse.hpp:674
void print_help(const std::string &_extra="")
Definition: argparse.cpp:109
argument & enable_help()
Add a help command.
Definition: argparse.hpp:871
static pointer_t shared_instance()
static void store_command_line(int argc, char **argv)
Definition: settings.cpp:211
static void parse(settings *=instance< TIMEMORY_API >())
Definition: settings.cpp:410
static settings * instance()
Definition: settings.hpp:536
#define DEBUG_PRINT_HERE(...)
Definition: macros.hpp:168
#define PRINT_HERE(...)
Definition: macros.hpp:152