107{
108#if defined(GEANT4_USE_TIMEMORY)
109 using parser_t = ArgumentParser;
110 using parser_err_t = typename parser_t::result_type;
111
112 if(args.empty())
113 return;
114
115 static std::mutex mtx;
116 std::unique_lock<std::mutex> lk(mtx);
117
118 static auto tid = std::this_thread::get_id();
119 if(std::this_thread::get_id() != tid)
120 return;
121
122
123
124
125
126
127 auto help_action = [](parser_t& p) {
128 p.print_help();
129 exit(EXIT_FAILURE);
130 };
131
132 parser.enable_help();
133 parser.on_error([=](parser_t& p, parser_err_t _err) {
134 std::cerr << _err << std::endl;
135 help_action(p);
136 });
137
138 auto get_bool = [](const std::string& _str, bool _default) {
139 if(_str.empty())
140 return _default;
141 using namespace std::regex_constants;
142 const auto regex_config = egrep | icase;
143 if(std::regex_match(_str, std::regex("on|true|yes|1", regex_config)))
144 return true;
145 else if(std::regex_match(_str, std::regex("off|false|no|0", regex_config)))
146 return false;
147 return _default;
148 };
149
150
151
152 parser.add_argument()
153 .names({ "-p", "--profile" })
154 .description("Profiler modes")
155 .choices({ "run", "event", "track", "step", "user" })
156 .action([&](parser_t& p) {
157 using namespace std::regex_constants;
158 const auto regex_config = egrep | icase;
159 for(auto&& itr : p.get<std::vector<std::string>>("profile"))
160 {
161 if(std::regex_match(itr, std::regex("run", regex_config)))
163 else if(std::regex_match(itr, std::regex("event", regex_config)))
165 else if(std::regex_match(itr, std::regex("track", regex_config)))
167 else if(std::regex_match(itr, std::regex("step", regex_config)))
169 else if(std::regex_match(itr, std::regex("user", regex_config)))
171 }
172 });
173
174
175
176 parser.add_argument()
177 .names({ "-r", "--run-components" })
178 .description("Components for run profiling (see 'timemory-avail -s')")
179 .action([&](parser_t& p) {
181 tim::configure<G4RunProfiler>(
182 p.get<std::vector<std::string>>("run-components"));
183 });
184 parser.add_argument()
185 .names({ "-e", "--event-components" })
186 .description("Components for event profiling (see 'timemory-avail -s')")
187 .action([&](parser_t& p) {
189 tim::configure<G4EventProfiler>(
190 p.get<std::vector<std::string>>("event-components"));
191 });
192 parser.add_argument()
193 .names({ "-t", "--track-components" })
194 .description("Components for track profiling (see 'timemory-avail -s')")
195 .action([&](parser_t& p) {
197 tim::configure<G4TrackProfiler>(
198 p.get<std::vector<std::string>>("track-components"));
199 });
200 parser.add_argument()
201 .names({ "-s", "--step-components" })
202 .description("Components for step profiling (see 'timemory-avail -s')")
203 .action([&](parser_t& p) {
205 tim::configure<G4StepProfiler>(
206 p.get<std::vector<std::string>>("step-components"));
207 });
208 parser.add_argument()
209 .names({ "-u", "--user-components" })
210 .description("Components for user profiling (see 'timemory-avail -s')")
211 .action([&](parser_t& p) {
213 tim::configure<G4UserProfiler>(
214 p.get<std::vector<std::string>>("user-components"));
215 });
216
217
218
219 parser.add_argument()
220 .names({ "-H", "--hierarchy", "--tree" })
221 .description("Display the results as a call-stack hierarchy.")
222 .max_count(1)
223 .action([&](parser_t& p) {
224 tim::settings::flat_profile() =
225 !get_bool(p.get<std::string>("tree"), true);
226 });
227 parser.add_argument()
228 .names({ "-F", "--flat" })
229 .description("Display the results as a flat call-stack")
230 .max_count(1)
231 .action([&](parser_t& p) {
232 tim::settings::flat_profile() =
233 get_bool(p.get<std::string>("flat"), true);
234 });
235 parser.add_argument()
236 .names({ "-T", "--timeline" })
237 .description(
238 "Do not merge duplicate entries at the same call-stack position")
239 .max_count(1)
240 .action([&](parser_t& p) {
241 tim::settings::timeline_profile() =
242 get_bool(p.get<std::string>("timeline"), true);
243 });
244 parser.add_argument()
245 .names({ "--per-thread" })
246 .description(
247 "Display the results for each individual thread (default: aggregation)")
248 .max_count(1)
249 .action([&](parser_t& p) {
250 tim::settings::flat_profile() =
251 get_bool(p.get<std::string>("per-thread"), true);
252 });
253 parser.add_argument()
254 .names({ "--per-event" })
255 .description("Each G4Event is a unique entry")
256 .max_count(1)
257 .action([&](parser_t& p) {
258 tim::settings::timeline_profile() =
259 get_bool(p.get<std::string>("per-event"), true);
260 });
261
262
263
264 parser.add_argument()
265 .names({ "-D", "--dart" })
266 .description("Enable Dart output (CTest/CDash data tracking)")
267 .max_count(1)
268 .action([&](parser_t& p) {
269 tim::settings::dart_output() = get_bool(p.get<std::string>("dart"), true);
270 });
271 parser.add_argument()
272 .names({ "-J", "--json" })
273 .description("Enable JSON output")
274 .max_count(1)
275 .action([&](parser_t& p) {
276 tim::settings::json_output() = get_bool(p.get<std::string>("json"), true);
277 });
278 parser.add_argument()
279 .names({ "-P", "--plot" })
280 .description("Plot the JSON output")
281 .max_count(1)
282 .action([&](parser_t& p) {
283 tim::settings::plot_output() = get_bool(p.get<std::string>("plot"), true);
284 });
285 parser.add_argument()
286 .names({ "-X", "--text" })
287 .description("Enable TEXT output")
288 .max_count(1)
289 .action([&](parser_t& p) {
290 tim::settings::text_output() = get_bool(p.get<std::string>("text"), true);
291 });
292 parser.add_argument()
293 .names({ "-C", "--cout" })
294 .description("Enable output to terminal")
295 .max_count(1)
296 .action([&](parser_t& p) {
297 tim::settings::cout_output() = get_bool(p.get<std::string>("cout"), true);
298 });
299 parser.add_argument()
300 .names({ "-O", "--output-path" })
301 .description("Set the output directory")
302 .count(1)
303 .action([&](parser_t& p) {
304 tim::settings::output_path() = p.get<std::string>("output-path");
305 });
306 parser.add_argument()
307 .names({ "-W", "--hw-counters" })
308 .description(
309 "Set the hardware counters to collect (see 'timemory-avail -H')")
310 .action([&](parser_t& p) {
311 tim::settings::papi_events() = p.get<std::string>("hw-counters");
312 });
313
314 tim::settings::time_output() = true;
315 tim::settings::time_format() = "%F_%I.%M_%p";
316
317 auto err = parser.parse(args);
318 if(err)
319 {
320 std::cout << "Error! " << err << std::endl;
321 help_action(parser);
322 }
323
324#else
325 G4Impl::consume_parameters(parser, args);
326#endif
327}
static void SetEnabled(size_t v, bool val)