File indexing completed on 2025-01-18 09:58:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifndef G4Profiler_hh
0035 #define G4Profiler_hh 1
0036
0037
0038 #ifndef G4GMAKE
0039 # include "G4GlobalConfig.hh"
0040 #endif
0041
0042
0043 #include "G4Profiler.icc"
0044
0045 #if defined(GEANT4_USE_TIMEMORY)
0046 # include <timemory/utility/argparse.hpp>
0047 #endif
0048
0049 #include "globals.hh"
0050
0051 #include <cstddef>
0052 #include <functional>
0053 #include <string>
0054 #include <utility>
0055 #include <type_traits>
0056 #include <tuple>
0057 #include <vector>
0058 #include <array>
0059
0060
0061
0062 class G4Run;
0063 class G4Event;
0064 class G4Track;
0065 class G4Step;
0066
0067 struct G4ProfileType
0068 {
0069 enum : size_t
0070 {
0071 Run = 0,
0072 Event,
0073 Track,
0074 Step,
0075 User,
0076 TypeEnd
0077 };
0078 };
0079
0080 struct G4ProfileOp
0081 {
0082 enum : int
0083 {
0084 Query = 0,
0085 Label,
0086 Tool
0087 };
0088 };
0089
0090
0091
0092 class G4Profiler
0093 {
0094 public:
0095 using array_type = std::array<bool, G4ProfileType::TypeEnd>;
0096
0097 #if defined(GEANT4_USE_TIMEMORY)
0098 using ArgumentParser = tim::argparse::argument_parser;
0099 #else
0100 struct ArgumentParser
0101 {
0102 explicit ArgumentParser(std::string) {}
0103 };
0104 #endif
0105
0106 static void Configure(const std::vector<std::string>& args);
0107 static void Configure(int argc, char** argv);
0108 static void Configure(ArgumentParser&, const std::vector<std::string>& args);
0109 static void Configure(ArgumentParser&, int argc, char** argv);
0110 static void Finalize();
0111
0112 static bool GetEnabled(size_t v) { return GetEnabled().at(v); }
0113 static void SetEnabled(size_t v, bool val) { GetEnabled().at(v) = val; }
0114
0115 static bool GetPerEvent() { return GetPerEventImpl(); }
0116 static void SetPerEvent(bool val) { GetPerEventImpl() = val; }
0117
0118 private:
0119 static array_type& GetEnabled();
0120 static bool& GetPerEventImpl()
0121 {
0122 static bool _value = false;
0123 return _value;
0124 }
0125 };
0126
0127
0128
0129
0130 template <size_t Category>
0131 struct G4ProfilerObject
0132 {
0133 using type = void;
0134 };
0135
0136 template <size_t Category>
0137 using G4ProfilerObject_t = typename G4ProfilerObject<Category>::type;
0138
0139 template <>
0140 struct G4ProfilerObject<G4ProfileType::Run>
0141 {
0142 using type = const G4Run*;
0143 };
0144
0145 template <>
0146 struct G4ProfilerObject<G4ProfileType::Event>
0147 {
0148 using type = const G4Event*;
0149 };
0150
0151 template <>
0152 struct G4ProfilerObject<G4ProfileType::Track>
0153 {
0154 using type = const G4Track*;
0155 };
0156
0157 template <>
0158 struct G4ProfilerObject<G4ProfileType::Step>
0159 {
0160 using type = const G4Step*;
0161 };
0162
0163 template <>
0164 struct G4ProfilerObject<G4ProfileType::User>
0165 {
0166 using type = const std::string&;
0167 };
0168
0169
0170
0171 template <size_t Category>
0172 struct G4ProfilerArgs
0173 {
0174
0175
0176 using value_type = G4ProfilerObject_t<Category>;
0177
0178
0179
0180 using type = G4TypeList<G4PROFILER_ARG_SET(value_type)>;
0181
0182
0183
0184
0185 };
0186
0187 template <size_t Category>
0188 using G4ProfilerArgs_t = typename G4ProfilerArgs<Category>::type;
0189
0190
0191
0192 template <size_t Category, typename RetT, typename CommonT = G4CommonTypeList<>>
0193 struct G4ProfilerFunctors
0194 {
0195 using type = G4Impl::Functors_t<RetT, CommonT, G4ProfilerArgs_t<Category>>;
0196 };
0197
0198 template <size_t Category, typename RetT, typename... CommonT>
0199 using G4ProfilerFunctors_t =
0200 typename G4ProfilerFunctors<Category, RetT,
0201 G4CommonTypeList<CommonT...>>::type;
0202
0203
0204
0205 #ifdef GEANT4_USE_TIMEMORY
0206
0207
0208 namespace tim
0209 {
0210 namespace component
0211 {
0212 template <size_t, typename Tag>
0213 struct user_bundle;
0214 }
0215
0216 template <typename... Types>
0217 class auto_tuple;
0218
0219 template <typename Tag, typename... Types>
0220 class auto_bundle;
0221 }
0222
0223 namespace g4tim
0224 {
0225 using namespace tim;
0226 using tim::component::user_bundle;
0227
0228 struct G4api : public tim::concepts::api
0229 {};
0230
0231 using ProfilerArgparser = argparse::argument_parser;
0232
0233 }
0234
0235 using G4RunProfiler = g4tim::user_bundle<G4ProfileType::Run, G4ProfileType>;
0236 using G4EventProfiler = g4tim::user_bundle<G4ProfileType::Event, G4ProfileType>;
0237 using G4TrackProfiler = g4tim::user_bundle<G4ProfileType::Track, G4ProfileType>;
0238 using G4StepProfiler = g4tim::user_bundle<G4ProfileType::Step, G4ProfileType>;
0239 using G4UserProfiler = g4tim::user_bundle<G4ProfileType::User, G4ProfileType>;
0240
0241 template <typename... Types>
0242 using G4ProfilerBundle = g4tim::auto_bundle<g4tim::G4api, Types...>;
0243
0244 #else
0245
0246 namespace g4tim
0247 {
0248 struct ProfilerArgparser
0249 {};
0250
0251
0252 template <typename... Types>
0253 struct handler
0254 {
0255 template <typename... Args>
0256 handler(Args&&...)
0257 {}
0258 ~handler() = default;
0259 handler(const handler&) = default;
0260 handler(handler&&) = default;
0261 handler& operator=(const handler&) = default;
0262 handler& operator=(handler&&) = default;
0263
0264 void record() {}
0265 template <typename... Args>
0266 void start(Args&&...)
0267 {}
0268 template <typename... Args>
0269 void stop(Args&&...)
0270 {}
0271 void push() {}
0272 void pop() {}
0273 void reset() {}
0274 void report_at_exit(bool) {}
0275 template <typename... Args>
0276 void mark_begin(Args&&...)
0277 {}
0278 template <typename... Args>
0279 void mark_end(Args&&...)
0280 {}
0281 friend std::ostream& operator<<(std::ostream& os, const handler&)
0282 {
0283 return os;
0284 }
0285 };
0286
0287 template <size_t Idx, typename Tp>
0288 struct user_bundle
0289 {
0290 template <typename... Args>
0291 user_bundle(Args&&...)
0292 {}
0293
0294 template <typename... Types, typename... Args>
0295 static void configure(Args&&...)
0296 {}
0297
0298 static void reset() {}
0299 };
0300
0301 }
0302
0303 using G4RunProfiler = g4tim::handler<>;
0304 using G4EventProfiler = g4tim::handler<>;
0305 using G4TrackProfiler = g4tim::handler<>;
0306 using G4StepProfiler = g4tim::handler<>;
0307 using G4UserProfiler = g4tim::handler<>;
0308
0309 template <typename... Types>
0310 using G4ProfilerBundle = g4tim::handler<Types...>;
0311
0312 #endif
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 template <size_t Category>
0324 class G4ProfilerConfig
0325 {
0326 public:
0327 using type = G4ProfilerBundle<g4tim::user_bundle<Category, G4ProfileType>>;
0328 using this_type = G4ProfilerConfig<Category>;
0329
0330 static constexpr size_t arg_sets =
0331 G4TypeListSize<G4ProfilerArgs_t<Category>>::value;
0332
0333 using QueryFunc_t = G4ProfilerFunctors_t<Category, bool>;
0334 using LabelFunc_t = G4ProfilerFunctors_t<Category, std::string>;
0335 using ToolFunc_t = std::tuple<std::function<type*(const std::string&)>>;
0336
0337 public:
0338
0339 G4ProfilerConfig() = default;
0340
0341
0342 template <typename Arg, typename... Args>
0343 G4ProfilerConfig(Arg, Args...);
0344
0345
0346 ~G4ProfilerConfig();
0347
0348
0349 G4ProfilerConfig(G4ProfilerConfig&&) = default;
0350 G4ProfilerConfig& operator=(G4ProfilerConfig&&) = default;
0351
0352
0353 G4ProfilerConfig(const G4ProfilerConfig&) = delete;
0354 G4ProfilerConfig& operator=(const G4ProfilerConfig&) = delete;
0355
0356
0357 template <typename... Args>
0358 bool operator()(Args...);
0359
0360
0361 operator bool() const { return (m_bundle != nullptr); }
0362
0363 private:
0364 type* m_bundle = nullptr;
0365
0366 static QueryFunc_t& GetQueries()
0367 {
0368 static QueryFunc_t _value;
0369 return _value;
0370 }
0371
0372 static LabelFunc_t& GetLables()
0373 {
0374 static LabelFunc_t _value;
0375 return _value;
0376 }
0377
0378 static ToolFunc_t& GetTools()
0379 {
0380 static ToolFunc_t _value;
0381 return _value;
0382 }
0383
0384 public:
0385
0386 template <typename... Args>
0387 static bool Query(Args... _args);
0388
0389
0390 template <typename... Args>
0391 static std::string Label(Args... _args);
0392
0393
0394 template <typename... Args>
0395 static type* Tool(const std::string&);
0396
0397 using QueryHandler_t = FuncHandler<this_type, QueryFunc_t, bool>;
0398 using LabelHandler_t = FuncHandler<this_type, LabelFunc_t, std::string>;
0399 using ToolHandler_t = FuncHandler<this_type, ToolFunc_t, type*>;
0400
0401 static QueryHandler_t GetQueryFunctor();
0402 static QueryHandler_t GetFallbackQueryFunctor();
0403
0404 static LabelHandler_t GetLabelFunctor();
0405 static LabelHandler_t GetFallbackLabelFunctor();
0406
0407 static ToolHandler_t GetToolFunctor();
0408 static ToolHandler_t GetFallbackToolFunctor();
0409
0410 private:
0411 template <bool B, typename Lhs, typename Rhs>
0412 using conditional_t = typename std::conditional<B, Lhs, Rhs>::type;
0413
0414
0415 template <int Idx>
0416 struct PersistentSettings
0417 {
0418
0419 using functor_type = conditional_t<
0420 Idx == G4ProfileOp::Query, QueryFunc_t,
0421 conditional_t<Idx == G4ProfileOp::Label, LabelFunc_t, ToolFunc_t>>;
0422
0423 PersistentSettings() = default;
0424 ~PersistentSettings() = default;
0425
0426 functor_type m_functor;
0427 };
0428
0429 template <int Idx>
0430 static PersistentSettings<Idx>& GetPersistentFallback();
0431
0432 template <int Idx>
0433 static PersistentSettings<Idx>& GetPersistent();
0434 };
0435
0436
0437
0438
0439 template <size_t Category>
0440 using G4ProfilerConfig_t = typename G4ProfilerConfig<Category>::type;
0441
0442
0443
0444 template <size_t Cat>
0445 template <typename Arg, typename... Args>
0446 G4ProfilerConfig<Cat>::G4ProfilerConfig(Arg _arg, Args... _args)
0447 {
0448 this->operator()(_arg, _args...);
0449 }
0450
0451
0452
0453 template <size_t Cat>
0454 template <typename... Args>
0455 bool G4ProfilerConfig<Cat>::operator()(Args... _args)
0456 {
0457 if(Query(_args...))
0458 {
0459 m_bundle = Tool(Label(_args...));
0460 if(m_bundle)
0461 m_bundle->start(_args...);
0462 return (m_bundle != nullptr);
0463 }
0464 return false;
0465 }
0466
0467
0468
0469
0470 template <size_t Cat>
0471 template <typename... Args>
0472 bool G4ProfilerConfig<Cat>::Query(Args... _args)
0473 {
0474 return QueryHandler_t{ GetPersistent<G4ProfileOp::Query>().m_functor }(
0475 _args...);
0476 }
0477
0478
0479
0480
0481 template <size_t Cat>
0482 template <typename... Args>
0483 std::string G4ProfilerConfig<Cat>::Label(Args... _args)
0484 {
0485 return LabelHandler_t{ GetPersistent<G4ProfileOp::Label>().m_functor }(
0486 _args...);
0487 }
0488
0489
0490
0491
0492 template <size_t Cat>
0493 template <typename... Args>
0494 typename G4ProfilerConfig<Cat>::type* G4ProfilerConfig<Cat>::Tool(
0495 const std::string& _args)
0496 {
0497 return ToolHandler_t{ GetPersistent<G4ProfileOp::Tool>().m_functor }(_args);
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 extern template class G4ProfilerConfig<G4ProfileType::Run>;
0509 extern template class G4ProfilerConfig<G4ProfileType::Event>;
0510 extern template class G4ProfilerConfig<G4ProfileType::Track>;
0511 extern template class G4ProfilerConfig<G4ProfileType::Step>;
0512 extern template class G4ProfilerConfig<G4ProfileType::User>;
0513 extern template G4ProfilerConfig<G4ProfileType::Run>::G4ProfilerConfig(const G4Run*);
0514 extern template G4ProfilerConfig<G4ProfileType::Event>::G4ProfilerConfig(const G4Event*);
0515 extern template G4ProfilerConfig<G4ProfileType::Track>::G4ProfilerConfig(const G4Track*);
0516 extern template G4ProfilerConfig<G4ProfileType::Step>::G4ProfilerConfig(const G4Step*);
0517 extern template G4ProfilerConfig<G4ProfileType::User>::G4ProfilerConfig(const std::string&);
0518
0519
0520
0521
0522 #ifndef GEANT4_USE_TIMEMORY
0523
0524 # include <ostream>
0525 # include <string>
0526
0527 #endif
0528
0529 #if defined(GEANT4_USE_TIMEMORY)
0530
0531 # define G4USER_PROFILER_VAR_JOIN(X, Y) X##Y
0532 # define G4USER_PROFILER_VAR(Y) G4USER_PROFILER_VAR_JOIN(g4user_profiler_, Y)
0533
0534
0535 # define G4USER_SCOPED_PROFILE(...) \
0536 G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
0537 TIMEMORY_JOIN("", __VA_ARGS__))
0538
0539
0540 # define G4USER_SCOPED_PROFILE_FUNC(...) \
0541 G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
0542 TIMEMORY_JOIN("", __FUNCTION__, "/", __VA_ARGS__))
0543
0544
0545 # define G4USER_SCOPED_PROFILE_FUNC_FILE(...) \
0546 G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
0547 TIMEMORY_JOIN("", __FUNCTION__, '@', __FILE__, '/', __VA_ARGS__))
0548
0549
0550 # define G4USER_SCOPED_PROFILE_FUNC_FILE_LINE(...) \
0551 G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
0552 TIMEMORY_JOIN("", __FUNCTION__, '@', __FILE__, ':', __LINE__, '/', \
0553 __VA_ARGS__))
0554 #else
0555 # define G4USER_SCOPED_PROFILE(...)
0556 # define G4USER_SCOPED_PROFILE_FUNC(...)
0557 # define G4USER_SCOPED_PROFILE_FUNC_FILE(...)
0558 # define G4USER_SCOPED_PROFILE_FUNC_FILE_LINE(...)
0559 #endif
0560
0561 #endif