Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
+40 -6
View File
@@ -6,22 +6,56 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-25 Pere Mato (global-V11-01-28)
- Changed Windows.h to windows.h since for MinGW always seems to be lower case, not relevant for native builds.
_MSC_VER is only available for VC compiler, the os one is _WIN32.
## 2024-06-28 Gabriele Cosmo (global-V11-02-13)
- Updated tag IDs for geant4-11-02-ref-06.
## 2024-04-20 Gabriele Cosmo
## 2024-05-30 Gabriele Cosmo (global-V11-02-12)
- Updated tag IDs for geant4-11-02-ref-05.
## 2024-05-29 Alberto Ribon (global-V11-02-11)
- G4PhysicsModelCatalog : added ID for the NuDEX nuclear de-excitation model;
removed unnecessary ID (24110) for internal conversion.
## 2024-05-03 Ben Morgan (global-V11-02-10)
- Remove use of no longer supported TiMemory.
## 2024-05-06 Vladimir Ivanchenko (global-V11-02-09)
- G4PhysicsTable - avoid crash in printout for the case if a vector in the
table is not yet created. This is useful for debugging.
## 2024-04-30 Gabriele Cosmo (global-V11-02-08)
- Updated tag IDs for geant4-11-02-ref-04.
## 2024-04-25 Pere Mato (global-V11-02-07)
- Changed Windows.h to windows.h since for MinGW always seems to be lower case, not relevant for native builds.
- _MSC_VER is only available for VC compiler, the os one is _WIN32
## 2024-04-20 Gabriele Cosmo (global-V11-02-06)
- Fixed compilation error in G4PhysicsModelCatalog on Windows VC++ with
C++20 Standard enabled.
Based on [GitHub PR#69](https://github.com/Geant4/geant4/pull/69).
## 2024-04-04 Stephan Hageboeck
## 2024-04-04 Stephan Hageboeck (global-V11-02-05)
- Provide a helpful error message when GEANT4_DATA_DIR is set to an invalid
location.
## 2023-12-21 Yoshihide Sato (global-V11-01-27)
## 2024-03-28 Gabriele Cosmo (global-V11-02-04)
- Updated tag IDs for geant4-11-02-ref-03.
## 2024-02-29 Gabriele Cosmo (global-V11-02-03)
- Updated tag IDs for geant4-11-02-ref-02.
## 2024-01-31 Gabriele Cosmo (global-V11-02-02)
- Updated tag IDs for geant4-11-02-ref-01.
## 2023-12-21 Yoshihide Sato (global-V11-02-01)
- G4PhysicsModelCatalog.cc: added the ID for the Light-Ion QMD model.
## 2023-12-18 Makoto Asai (global-V11-02-00)
- G4StateManager, G4VStateDependent - added notifying methods when an event
or a run is deleted for the sake of avoiding a state-dependent class from
accessing to an obsolete event/run object.
## 2023-11-23 Gabriele Cosmo (global-V11-01-26)
- Updated tag IDs for geant4-11-02-ref-00.
@@ -45,9 +45,5 @@
//! \brief Defined if Geant4 built with TBB support
#cmakedefine GEANT4_USE_TBB
//! \def GEANT4_USE_TIMEMORY
//! \brief Defined if Geant4 built with TiMemory support
#cmakedefine GEANT4_USE_TIMEMORY
#endif // G4GLOBALCONFIG_HH
@@ -1,561 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4Profiler
//
// Class description:
//
// Class providing the internal profiling interface for Geant4.
// Author: Jonathan Madsen, LBNL - November 2020
// --------------------------------------------------------------------
#ifndef G4Profiler_hh
#define G4Profiler_hh 1
// Fundamental definitions
#ifndef G4GMAKE
# include "G4GlobalConfig.hh"
#endif
// for meta-programming stuff
#include "G4Profiler.icc"
#if defined(GEANT4_USE_TIMEMORY)
# include <timemory/utility/argparse.hpp>
#endif
#include "globals.hh"
#include <cstddef>
#include <functional>
#include <string>
#include <utility>
#include <type_traits>
#include <tuple>
#include <vector>
#include <array>
//----------------------------------------------------------------------------//
class G4Run;
class G4Event;
class G4Track;
class G4Step;
struct G4ProfileType
{
enum : size_t
{
Run = 0,
Event,
Track,
Step,
User,
TypeEnd
};
};
struct G4ProfileOp
{
enum : int
{
Query = 0,
Label,
Tool
};
};
//----------------------------------------------------------------------------//
class G4Profiler
{
public:
using array_type = std::array<bool, G4ProfileType::TypeEnd>;
#if defined(GEANT4_USE_TIMEMORY)
using ArgumentParser = tim::argparse::argument_parser;
#else
struct ArgumentParser
{
explicit ArgumentParser(std::string) {}
};
#endif
static void Configure(const std::vector<std::string>& args);
static void Configure(int argc, char** argv);
static void Configure(ArgumentParser&, const std::vector<std::string>& args);
static void Configure(ArgumentParser&, int argc, char** argv);
static void Finalize();
static bool GetEnabled(size_t v) { return GetEnabled().at(v); }
static void SetEnabled(size_t v, bool val) { GetEnabled().at(v) = val; }
static bool GetPerEvent() { return GetPerEventImpl(); }
static void SetPerEvent(bool val) { GetPerEventImpl() = val; }
private:
static array_type& GetEnabled();
static bool& GetPerEventImpl()
{
static bool _value = false;
return _value;
}
};
//----------------------------------------------------------------------------//
// maps enumerations to types
//
template <size_t Category>
struct G4ProfilerObject
{
using type = void;
};
template <size_t Category>
using G4ProfilerObject_t = typename G4ProfilerObject<Category>::type;
template <>
struct G4ProfilerObject<G4ProfileType::Run>
{
using type = const G4Run*;
};
template <>
struct G4ProfilerObject<G4ProfileType::Event>
{
using type = const G4Event*;
};
template <>
struct G4ProfilerObject<G4ProfileType::Track>
{
using type = const G4Track*;
};
template <>
struct G4ProfilerObject<G4ProfileType::Step>
{
using type = const G4Step*;
};
template <>
struct G4ProfilerObject<G4ProfileType::User>
{
using type = const std::string&;
};
//----------------------------------------------------------------------------//
// default set of profiler args
template <size_t Category>
struct G4ProfilerArgs
{
// this resolves to the G4ProfilerObject type-trait above, e.g.
// "const G4Step*" when category is G4ProfileType::Step
using value_type = G4ProfilerObject_t<Category>;
// two-dimensional type-list where each inner type-list is a set
// of arguments to support creating a profiler type from
using type = G4TypeList<G4PROFILER_ARG_SET(value_type)>;
// so above means there are functors in use which apply:
//
// G4StepProfiler _profiler(const G4Step*);
//
};
template <size_t Category>
using G4ProfilerArgs_t = typename G4ProfilerArgs<Category>::type;
//----------------------------------------------------------------------------//
template <size_t Category, typename RetT, typename CommonT = G4CommonTypeList<>>
struct G4ProfilerFunctors
{
using type = G4Impl::Functors_t<RetT, CommonT, G4ProfilerArgs_t<Category>>;
};
template <size_t Category, typename RetT, typename... CommonT>
using G4ProfilerFunctors_t =
typename G4ProfilerFunctors<Category, RetT,
G4CommonTypeList<CommonT...>>::type;
//----------------------------------------------------------------------------//
#ifdef GEANT4_USE_TIMEMORY
// Pre-declare the timemory component that will be used
namespace tim
{
namespace component
{
template <size_t, typename Tag>
struct user_bundle;
} // namespace component
template <typename... Types>
class auto_tuple;
template <typename Tag, typename... Types>
class auto_bundle;
} // namespace tim
namespace g4tim
{
using namespace tim;
using tim::component::user_bundle;
struct G4api : public tim::concepts::api
{};
using ProfilerArgparser = argparse::argument_parser;
} // namespace g4tim
using G4RunProfiler = g4tim::user_bundle<G4ProfileType::Run, G4ProfileType>;
using G4EventProfiler = g4tim::user_bundle<G4ProfileType::Event, G4ProfileType>;
using G4TrackProfiler = g4tim::user_bundle<G4ProfileType::Track, G4ProfileType>;
using G4StepProfiler = g4tim::user_bundle<G4ProfileType::Step, G4ProfileType>;
using G4UserProfiler = g4tim::user_bundle<G4ProfileType::User, G4ProfileType>;
template <typename... Types>
using G4ProfilerBundle = g4tim::auto_bundle<g4tim::G4api, Types...>;
#else
namespace g4tim
{
struct ProfilerArgparser
{};
/// this provides a dummy wrapper for the profiling
template <typename... Types>
struct handler
{
template <typename... Args>
handler(Args&&...)
{}
~handler() = default;
handler(const handler&) = default;
handler(handler&&) = default;
handler& operator=(const handler&) = default;
handler& operator=(handler&&) = default;
void record() {}
template <typename... Args>
void start(Args&&...)
{}
template <typename... Args>
void stop(Args&&...)
{}
void push() {}
void pop() {}
void reset() {}
void report_at_exit(bool) {}
template <typename... Args>
void mark_begin(Args&&...)
{}
template <typename... Args>
void mark_end(Args&&...)
{}
friend std::ostream& operator<<(std::ostream& os, const handler&)
{
return os;
}
};
template <size_t Idx, typename Tp>
struct user_bundle
{
template <typename... Args>
user_bundle(Args&&...)
{}
template <typename... Types, typename... Args>
static void configure(Args&&...)
{}
static void reset() {}
};
} // namespace g4tim
using G4RunProfiler = g4tim::handler<>;
using G4EventProfiler = g4tim::handler<>;
using G4TrackProfiler = g4tim::handler<>;
using G4StepProfiler = g4tim::handler<>;
using G4UserProfiler = g4tim::handler<>;
template <typename... Types>
using G4ProfilerBundle = g4tim::handler<Types...>;
#endif
//----------------------------------------------------------------------------//
/// @brief G4ProfilerConfig
/// This class is used to determine whether to activate profiling in the code
///
/// @example extended/parallel/ThreadsafeScorers/ts_scorers.cc
/// The main for this file contains an example for configuring the G4Profiler
/// for G4Track and G4Step
///
template <size_t Category>
class G4ProfilerConfig
{
public:
using type = G4ProfilerBundle<g4tim::user_bundle<Category, G4ProfileType>>;
using this_type = G4ProfilerConfig<Category>;
static constexpr size_t arg_sets =
G4TypeListSize<G4ProfilerArgs_t<Category>>::value;
using QueryFunc_t = G4ProfilerFunctors_t<Category, bool>;
using LabelFunc_t = G4ProfilerFunctors_t<Category, std::string>;
using ToolFunc_t = std::tuple<std::function<type*(const std::string&)>>;
public:
// when constructed with no args, should call operator()
G4ProfilerConfig() = default;
// constructor calls Query(...), Label(...), Tool(...)
template <typename Arg, typename... Args>
G4ProfilerConfig(Arg, Args...);
// will delete m_bundle is allocated
~G4ProfilerConfig();
// default the move-constructor and move-assignment
G4ProfilerConfig(G4ProfilerConfig&&) = default;
G4ProfilerConfig& operator=(G4ProfilerConfig&&) = default;
// do not allow copy-construct and copy-assign bc of raw pointer
G4ProfilerConfig(const G4ProfilerConfig&) = delete;
G4ProfilerConfig& operator=(const G4ProfilerConfig&) = delete;
// if constructed without args, this function should be called
template <typename... Args>
bool operator()(Args...);
// provide nullptr check
operator bool() const { return (m_bundle != nullptr); }
private:
type* m_bundle = nullptr;
static QueryFunc_t& GetQueries()
{
static QueryFunc_t _value;
return _value;
}
static LabelFunc_t& GetLables()
{
static LabelFunc_t _value;
return _value;
}
static ToolFunc_t& GetTools()
{
static ToolFunc_t _value;
return _value;
}
public:
// invokes the functor that determines whether to enable profiling
template <typename... Args>
static bool Query(Args... _args);
// invokes the functor for generating a Label when profiling is enabled
template <typename... Args>
static std::string Label(Args... _args);
// invokes the functor for configuring a Tool instance
template <typename... Args>
static type* Tool(const std::string&);
using QueryHandler_t = FuncHandler<this_type, QueryFunc_t, bool>;
using LabelHandler_t = FuncHandler<this_type, LabelFunc_t, std::string>;
using ToolHandler_t = FuncHandler<this_type, ToolFunc_t, type*>;
static QueryHandler_t GetQueryFunctor();
static QueryHandler_t GetFallbackQueryFunctor();
static LabelHandler_t GetLabelFunctor();
static LabelHandler_t GetFallbackLabelFunctor();
static ToolHandler_t GetToolFunctor();
static ToolHandler_t GetFallbackToolFunctor();
private:
template <bool B, typename Lhs, typename Rhs>
using conditional_t = typename std::conditional<B, Lhs, Rhs>::type;
// this provides the global statics for the functors
template <int Idx>
struct PersistentSettings
{
// determine the functor type
using functor_type = conditional_t<
Idx == G4ProfileOp::Query, QueryFunc_t,
conditional_t<Idx == G4ProfileOp::Label, LabelFunc_t, ToolFunc_t>>;
PersistentSettings() = default;
~PersistentSettings() = default;
// default member initialization
functor_type m_functor;
};
template <int Idx>
static PersistentSettings<Idx>& GetPersistentFallback();
template <int Idx>
static PersistentSettings<Idx>& GetPersistent();
};
//----------------------------------------------------------------------------//
// alias for getting type
template <size_t Category>
using G4ProfilerConfig_t = typename G4ProfilerConfig<Category>::type;
// ----------------------------------------------------------------------
template <size_t Cat>
template <typename Arg, typename... Args>
G4ProfilerConfig<Cat>::G4ProfilerConfig(Arg _arg, Args... _args)
{
this->operator()(_arg, _args...);
}
// ----------------------------------------------------------------------
template <size_t Cat>
template <typename... Args>
bool G4ProfilerConfig<Cat>::operator()(Args... _args)
{
if(Query(_args...))
{
m_bundle = Tool(Label(_args...));
if(m_bundle)
m_bundle->start(_args...);
return (m_bundle != nullptr);
}
return false;
}
// ----------------------------------------------------------------------
// invokes the functor that determines whether to enable profiling
template <size_t Cat>
template <typename... Args>
bool G4ProfilerConfig<Cat>::Query(Args... _args)
{
return QueryHandler_t{ GetPersistent<G4ProfileOp::Query>().m_functor }(
_args...);
}
//----------------------------------------------------------------------------//
// invokes the functor for generating a label when profiling is enabled
template <size_t Cat>
template <typename... Args>
std::string G4ProfilerConfig<Cat>::Label(Args... _args)
{
return LabelHandler_t{ GetPersistent<G4ProfileOp::Label>().m_functor }(
_args...);
}
//----------------------------------------------------------------------------//
// invokes the functor for configuring a tool instance
template <size_t Cat>
template <typename... Args>
typename G4ProfilerConfig<Cat>::type* G4ProfilerConfig<Cat>::Tool(
const std::string& _args)
{
return ToolHandler_t{ GetPersistent<G4ProfileOp::Tool>().m_functor }(_args);
}
//----------------------------------------------------------------------------//
// ensure that any implicit instantiations of the G4ProfilerConfig
// are not done in another translation units because we will
// explicitly instantiate G4ProfilerConfig in the .cc file
// line breaks make this much harder to read
// clang-format off
extern template class G4ProfilerConfig<G4ProfileType::Run>;
extern template class G4ProfilerConfig<G4ProfileType::Event>;
extern template class G4ProfilerConfig<G4ProfileType::Track>;
extern template class G4ProfilerConfig<G4ProfileType::Step>;
extern template class G4ProfilerConfig<G4ProfileType::User>;
extern template G4ProfilerConfig<G4ProfileType::Run>::G4ProfilerConfig(const G4Run*);
extern template G4ProfilerConfig<G4ProfileType::Event>::G4ProfilerConfig(const G4Event*);
extern template G4ProfilerConfig<G4ProfileType::Track>::G4ProfilerConfig(const G4Track*);
extern template G4ProfilerConfig<G4ProfileType::Step>::G4ProfilerConfig(const G4Step*);
extern template G4ProfilerConfig<G4ProfileType::User>::G4ProfilerConfig(const std::string&);
// clang-format on
//----------------------------------------------------------------------------//
#ifndef GEANT4_USE_TIMEMORY
# include <ostream>
# include <string>
#endif
#if defined(GEANT4_USE_TIMEMORY)
// two macros below create a unique variable name based on the line number
# define G4USER_PROFILER_VAR_JOIN(X, Y) X##Y
# define G4USER_PROFILER_VAR(Y) G4USER_PROFILER_VAR_JOIN(g4user_profiler_, Y)
// inserts just the string
# define G4USER_SCOPED_PROFILE(...) \
G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
TIMEMORY_JOIN("", __VA_ARGS__))
// inserts the function
# define G4USER_SCOPED_PROFILE_FUNC(...) \
G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
TIMEMORY_JOIN("", __FUNCTION__, "/", __VA_ARGS__))
// inserts the function and file
# define G4USER_SCOPED_PROFILE_FUNC_FILE(...) \
G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
TIMEMORY_JOIN("", __FUNCTION__, '@', __FILE__, '/', __VA_ARGS__))
// inserts the function, file, and line number
# define G4USER_SCOPED_PROFILE_FUNC_FILE_LINE(...) \
G4ProfilerConfig<G4ProfileType::User> G4USER_PROFILER_VAR(__LINE__)( \
TIMEMORY_JOIN("", __FUNCTION__, '@', __FILE__, ':', __LINE__, '/', \
__VA_ARGS__))
#else
# define G4USER_SCOPED_PROFILE(...)
# define G4USER_SCOPED_PROFILE_FUNC(...)
# define G4USER_SCOPED_PROFILE_FUNC_FILE(...)
# define G4USER_SCOPED_PROFILE_FUNC_FILE_LINE(...)
#endif
#endif // G4Profiler_hh
@@ -1,391 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4Profiler
//
// Template definition file
//
// Author: Jonathan Madsen, LBNL - November 2020
// --------------------------------------------------------------------
#if !defined(G4PROFILER_ICC_)
# define G4PROFILER_ICC_ 1
# include <functional>
# include <type_traits>
# include <tuple>
# include <initializer_list>
# include <string>
# include <sstream>
// for index_sequence implementation
# include "PTL/Globals.hh"
# if defined(GEANT4_USE_TIMEMORY)
# include <timemory/utility/utility.hpp>
# endif
# if !defined(GEANT4_FOLD_EXPRESSION)
# define GEANT4_FOLD_EXPRESSION(...) \
::G4Impl::consume_parameters( \
::std::initializer_list<int>{ (__VA_ARGS__, 0)... })
# endif
# if !defined(G4PROFILER_ARG_SET)
# define G4PROFILER_ARG_SET(...) G4TypeList<__VA_ARGS__>
# endif
//----------------------------------------------------------------------------//
// lightweight (w.r.t. compile-time) alternative to std::tuple that doesn't
// store anything and cannot be instantiated because it has no definition. This
// guards against meta-programming mistakes where:
// std::function<void(const G4Step*)>
// ends up as
// std::function<void(G4TypeList<const G4Step*>)>
template <typename... Types>
struct G4TypeList;
// this is used in G4Impl::Functors to add a common set of arguments to all of
// the functors
template <typename... Types>
struct G4CommonTypeList;
//--------------------------------------------------------------------------------------//
//
template <typename... Types>
struct G4TypeListSize;
template <typename... Types>
struct G4TypeListSize<G4TypeList<Types...>>
{
static constexpr size_t value = sizeof...(Types);
};
template <typename... Types>
struct G4TypeListSize<std::tuple<Types...>>
{
static constexpr size_t value = std::tuple_size<std::tuple<Types...>>::value;
};
namespace G4Impl
{
template <typename Tp>
std::string demangle()
{
# if defined(GEANT4_USE_TIMEMORY)
return tim::demangle<Tp>();
# else
return typeid(Tp).name();
# endif
}
template <typename... Tp>
void consume_parameters(Tp&&...)
{}
//------------------------------------------------------------------------//
// don't provide a definition that works without G4TypeList
template <typename RetT, typename... Tail>
struct Functors;
//------------------------------------------------------------------------//
template <typename RetT, typename... Tail>
struct Functors<RetT, G4TypeList<Tail...>>
{
using type = std::function<RetT(Tail...)>;
};
//------------------------------------------------------------------------//
template <typename RetT, typename... CommonT, typename... Tail>
struct Functors<RetT, G4CommonTypeList<CommonT...>, G4TypeList<Tail...>>
{
using type = std::function<RetT(CommonT..., Tail...)>;
};
//------------------------------------------------------------------------//
template <typename RetT, typename... Types, typename... Tail>
struct Functors<RetT, G4TypeList<G4TypeList<Types...>, Tail...>>
{
using type = std::tuple<std::function<RetT(Types...)>,
typename Functors<RetT, Tail>::type...>;
};
//------------------------------------------------------------------------//
template <typename RetT, typename... CommonT, typename... Types,
typename... Tail>
struct Functors<RetT, G4CommonTypeList<CommonT...>,
G4TypeList<G4TypeList<Types...>, Tail...>>
{
using type = std::tuple<
std::function<RetT(CommonT..., Types...)>,
typename Functors<RetT, G4CommonTypeList<CommonT...>, Tail>::type...>;
};
//------------------------------------------------------------------------//
template <typename RetT, typename... Tail>
using Functors_t = typename Functors<RetT, Tail...>::type;
} // namespace G4Impl
//
// this allows the generic invocation or assignment of a functor
//
template <typename Type, typename FuncT, typename RetT = void>
struct FuncHandler
{
using this_type = FuncHandler<Type, FuncT, RetT>;
// until Geant4 updates to C++14 as a minimum
template <typename Tp>
using decay_t = typename std::decay<Tp>::type;
template <bool Bv, typename Tp = void>
using enable_if_t = typename std::enable_if<Bv, Tp>::type;
template <size_t... Idx>
using index_sequence = PTL::mpl::index_sequence<Idx...>;
template <size_t NumT>
using make_index_sequence = PTL::mpl::make_index_sequence<NumT>;
static constexpr size_t size = std::tuple_size<FuncT>::value;
FuncHandler(FuncT& _functors)
: m_functors(_functors)
{}
// overloading the assignment operator will let users
// be able to use one method for the G4ProfilerConfig
// despite the potential variants. Thus this is valid:
//
// GetLabelFunctor() = [](int i) { return std::to_string(i); }
// GetLabelFunctor() = [](float v) { return std::to_string(v); }
//
// but will only compile for types that are explicitly
// supported --> the assign function iterates through the
// specific variants at compile-time
template <typename Func>
void operator=(Func&& f)
{
assign(m_functors, std::forward<Func>(f), 0, make_index_sequence<size>{});
}
private:
FuncT& m_functors;
template <typename Tp>
static enable_if_t<std::is_same<decay_t<Tp>, bool>::value, Tp>
get_default_return_value()
{
return false;
}
template <typename Tp>
static enable_if_t<std::is_same<decay_t<Tp>, std::string>::value, Tp>
get_default_return_value()
{
// this may return an ugly mangled name but will at least but useful
// and can be demangled with c++filt
return std::string("label-functor-not-set-for-") + G4Impl::demangle<Tp>();
}
template <typename Tp>
static enable_if_t<std::is_pointer<decay_t<Tp>>::value, Tp>
get_default_return_value()
{
return nullptr;
}
private:
using return_t = decay_t<RetT>;
//
// NOTE: All references to "iterations" in the comments
// below refer to compile-time iterations, which are
// implemented through recusion below. Iterations stop
// when a valid statement has been found and thus necessitates
// four versions of the same function: two of these functions
// handle the end of the recursion 'sizeof...(Tail) == 0'
// and the first of these functions (1.a) is used if a valid
// statement is found and the second (1.b, if reached) introduces
// a compilation error. The third and fourth start the iteration
// when 'sizeof...(Tail) > 0'. If a valid statement is found
// in the third function (2.a), recursion stops. If not, the
// iteration is continued to the next index via the fourth
// function (2.b).
//
// INVOKE 1.a
//
// this is the end of the iteration through the potential
// functor variants and the trailing '->' tests whether the
// functor can be called with the given arguments. The
// 'int' as the second parameter ensures (through overload
// resolution rules) that this gets tested before the
// function after this (1.b).
// If the size of 'FuncT' is equal to 1, then this is also
// the start of the iteration through the potential functor
// variants.
template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
enable_if_t<sizeof...(Tail) == 0, int> = 0>
static auto invoke(Tp& _obj, int, index_sequence<Idx, Tail...>,
Args&&... _args)
-> decltype(std::get<Idx>(_obj)(std::forward<Args>(_args)...), return_t{})
{
// if the functor has been set, then execute it
if(std::get<Idx>(_obj))
return std::get<Idx>(_obj)(std::forward<Args>(_args)...);
else
{
std::stringstream ss;
ss << "Error! Functor "
<< G4Impl::demangle<decltype(std::get<Idx>(_obj))>()
<< " was not set for " << G4Impl::demangle<Type>();
throw std::runtime_error(ss.str());
}
// the default for booleans should return false
return get_default_return_value<return_t>();
}
// INVOKE 1.b
//
// this is the end of the iteration through the potential
// functor variants and if this function is reached during
// compile-time, this means that the given arguments are
// not supported by any of the functors and will fail to
// compile. The 'long' as the second parameter ensures that
// it has lower precedence than the one above
template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
enable_if_t<sizeof...(Tail) == 0, int> = 0>
static auto invoke(Tp&, long, index_sequence<Idx, Tail...>, Args&&...)
-> return_t
{
// this will cause a failure at compile-time.
// this ensures that this static assert is dependent
// on this function getting instantiated, simply putting
// 'false' here would result in compile-time failure
// even if no code ever instantiated this function
static_assert(!std::is_same<Tp, Tp>::value, "Error! No valid functor!");
throw std::runtime_error(
"Error! No valid functor! This should have caused a compilation error!");
return return_t{};
}
// INVOKE 2.a
//
// If the size of 'FuncT' is greater than one, this is the
// start of the iteration through the potential functor variants.
// This version will be used if the X in '-> decltype(X, Y)'
// is valid. If it is not valid, then overload resolution
// rules will dictate that the compiler will move on to the
// 'invoke' member function 2.b
template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
enable_if_t<(sizeof...(Tail) > 0), int> = 0>
static auto invoke(Tp& _obj, int, index_sequence<Idx, Tail...>,
Args&&... _args)
-> decltype(std::get<Idx>(_obj)(std::forward<Args>(_args)...), return_t{})
{
return std::get<Idx>(_obj)(std::forward<Args>(_args)...);
}
// INVOKE 2.b
//
// If the above test was not valid, we discard the current index
// ('Idx') and proceed to the next index. If there is only
// one index remaining, then this will call proceed to the
// first invoke member function (1.a). If there are multiple
// indexes remaining, then this will proceed to the previous
// invoke member function (2.a) and this will continue until
// a valid match is found or will fail to compile.
template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
enable_if_t<(sizeof...(Tail) > 0), int> = 0>
static auto invoke(Tp& _obj, long, index_sequence<Idx, Tail...>,
Args&&... _args)
-> decltype(invoke(_obj, 0, index_sequence<Tail...>{},
std::forward<Args>(_args)...))
{
return invoke(_obj, 0, index_sequence<Tail...>{},
std::forward<Args>(_args)...);
}
private:
// this uses the same principles as the invoke member function.
// See the comments there.
template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
enable_if_t<sizeof...(Tail) == 0, int> = 0>
static auto assign(LhsT& _lhs, RhsT&& _rhs, int, index_sequence<Idx, Tail...>)
-> decltype((std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs)), void())
{
std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs);
}
// this uses the same principles as the invoke member function.
// See the comments there.
template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
enable_if_t<sizeof...(Tail) == 0, int> = 0>
static void assign(LhsT&, RhsT&&, long, index_sequence<Idx, Tail...>)
{
// this will cause a failure at compile-time.
// this ensures that this static assert is dependent
// on this function getting instantiated, simply putting
// 'false' here would result in compile-time failure
// even if no code ever instantiated this function
static_assert(!std::is_same<LhsT, LhsT>::value,
"Error! No valid functor assignment!");
throw std::runtime_error(
"Error! No valid functor! This should have caused a compilation error!");
}
// this uses the same principles as the invoke member function.
// See the comments there.
template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
enable_if_t<(sizeof...(Tail) > 0), int> = 0>
static auto assign(LhsT& _lhs, RhsT&& _rhs, int, index_sequence<Idx, Tail...>)
-> decltype((std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs)), void())
{
std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs);
}
// this uses the same principles as the invoke member function.
// See the comments there.
template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
enable_if_t<(sizeof...(Tail) > 0), int> = 0>
static void assign(LhsT& _lhs, RhsT&& _rhs, long,
index_sequence<Idx, Tail...>)
{
assign(_lhs, std::forward<RhsT>(_rhs), 0, index_sequence<Tail...>{});
}
public:
// overloading the call operator makes it generic to call
// the functors but will only compile for types that are
// explicitly supported --> the invoke function iterates
// through the specific variants at compile-time to
// ensure using SFINAE
template <typename... Args>
auto operator()(Args&&... _args)
-> decltype(std::declval<this_type>().invoke(std::declval<FuncT&>(), 0,
make_index_sequence<size>{},
std::forward<Args>(_args)...))
{
return invoke(m_functors, 0, make_index_sequence<size>{},
std::forward<Args>(_args)...);
}
};
//----------------------------------------------------------------------------//
#endif
@@ -46,6 +46,9 @@
#include "G4VStateDependent.hh"
#include <vector>
class G4Run;
class G4Event;
class G4StateManager
{
public:
@@ -89,6 +92,11 @@ class G4StateManager
G4String GetStateString(const G4ApplicationState& aState) const;
// Utility method which returns a string of the state name
void NotifyDeletion(const G4Event*);
void NotifyDeletion(const G4Run*);
// Notifying when an event or a run is deleted for the sake of avoiding
// a state-dependent class from accessing to an obsolete event/run object.
inline void SetSuppressAbortion(G4int i);
inline G4int GetSuppressAbortion() const;
inline const char* GetMessage() const;
@@ -1,172 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4TiMemory
//
// Description:
//
// Provides empty macros when Geant4 is compiled with TiMemory disabled
// Author: Jonathan R. Madsen, 25 April 2019
// --------------------------------------------------------------------
#ifndef g4timemory_hh
#define g4timemory_hh 1
// Fundamental definitions
#ifndef G4GMAKE
# include "G4GlobalConfig.hh"
#endif
#include "globals.hh"
#include <cstddef>
#include <functional>
#include <string>
#include <utility>
//----------------------------------------------------------------------------//
#ifdef GEANT4_USE_TIMEMORY
# include <timemory/timemory.hpp>
namespace g4tim
{
using namespace tim;
} // namespace g4tim
using G4AutoTimer = g4tim::auto_timer;
#else
# include <ostream>
# include <string>
namespace g4tim
{
/// this provides "functionality" for *_HANDLE macros
/// and can be omitted if these macros are not utilized
struct dummy
{
template <typename... _Types, typename... _Args>
static void configure(_Args&&...)
{}
template <typename... _Args>
dummy(_Args&&...)
{}
~dummy() = default;
dummy(const dummy&) = default;
dummy(dummy&&) = default;
dummy& operator=(const dummy&) = default;
dummy& operator=(dummy&&) = default;
void record() {}
void start() {}
void stop() {}
void push() {}
void pop() {}
void reset() {}
void report_at_exit(bool) {}
template <typename... _Args>
void mark_begin(_Args&&...)
{}
template <typename... _Args>
void mark_end(_Args&&...)
{}
friend std::ostream& operator<<(std::ostream& os, const dummy&)
{
return os;
}
};
} // namespace g4tim
// startup/shutdown/configure
# define TIMEMORY_INIT(...)
# define TIMEMORY_FINALIZE()
# define TIMEMORY_CONFIGURE(...)
// label creation
# define TIMEMORY_BASIC_LABEL(...) std::string("")
# define TIMEMORY_LABEL(...) std::string("")
# define TIMEMORY_JOIN(...) std::string("")
// define an object
# define TIMEMORY_BLANK_MARKER(...)
# define TIMEMORY_BASIC_MARKER(...)
# define TIMEMORY_MARKER(...)
// define an unique pointer object
# define TIMEMORY_BLANK_POINTER(...)
# define TIMEMORY_BASIC_POINTER(...)
# define TIMEMORY_POINTER(...)
// define an object with a caliper reference
# define TIMEMORY_BLANK_CALIPER(...)
# define TIMEMORY_BASIC_CALIPER(...)
# define TIMEMORY_CALIPER(...)
// define a static object with a caliper reference
# define TIMEMORY_STATIC_BLANK_CALIPER(...)
# define TIMEMORY_STATIC_BASIC_CALIPER(...)
# define TIMEMORY_STATIC_CALIPER(...)
// invoke member function on caliper reference or type within reference
# define TIMEMORY_CALIPER_APPLY(...)
# define TIMEMORY_CALIPER_TYPE_APPLY(...)
// get an object
# define TIMEMORY_BLANK_HANDLE(...) g4tim::dummy()
# define TIMEMORY_BASIC_HANDLE(...) g4tim::dummy()
# define TIMEMORY_HANDLE(...) tim::dummy()
// get a pointer to an object
# define TIMEMORY_BLANK_POINTER_HANDLE(...) nullptr
# define TIMEMORY_BASIC_POINTER_HANDLE(...) nullptr
# define TIMEMORY_POINTER_HANDLE(...) nullptr
// debug only
# define TIMEMORY_DEBUG_BLANK_MARKER(...)
# define TIMEMORY_DEBUG_BASIC_MARKER(...)
# define TIMEMORY_DEBUG_MARKER(...)
// auto-timers
# define TIMEMORY_BLANK_AUTO_TIMER(...)
# define TIMEMORY_BASIC_AUTO_TIMER(...)
# define TIMEMORY_AUTO_TIMER(...)
# define TIMEMORY_BLANK_AUTO_TIMER_HANDLE(...)
# define TIMEMORY_BASIC_AUTO_TIMER_HANDLE(...)
# define TIMEMORY_AUTO_TIMER_HANDLE(...)
# define TIMEMORY_DEBUG_BASIC_AUTO_TIMER(...)
# define TIMEMORY_DEBUG_AUTO_TIMER(...)
using G4AutoTimer = g4tim::dummy;
#endif
//----------------------------------------------------------------------------//
#endif
@@ -40,6 +40,9 @@
#include "G4ApplicationState.hh"
#include "G4Types.hh"
class G4Event;
class G4Run;
class G4VStateDependent
{
public:
@@ -55,6 +58,9 @@ class G4VStateDependent
// NOT recommended. All commands which are state sensitive MUST assign
// available state(s).
virtual void NotifyDeletion(const G4Event*) {}
virtual void NotifyDeletion(const G4Run*) {}
private:
G4VStateDependent(const G4VStateDependent& right);
G4VStateDependent& operator=(const G4VStateDependent& right);
@@ -43,7 +43,7 @@
/// |--> patch number (single digit)
///
#ifndef G4VERSION_NUMBER
#define G4VERSION_NUMBER 1122
#define G4VERSION_NUMBER 1130
#endif
/// @def G4VERSION_REFERENCE_TAG
@@ -55,11 +55,11 @@
/// (taking December as 0, the start of new development of the next major/minor release).
///
#ifndef G4VERSION_REFERENCE_TAG
#define G4VERSION_REFERENCE_TAG 00
#define G4VERSION_REFERENCE_TAG 06
#endif
#ifndef G4VERSION_TAG
#define G4VERSION_TAG "$Name: geant4-11-02-patch-02 $"
#define G4VERSION_TAG "$Name: geant4-11-03-beta-01 $"
#endif
// as variables
@@ -68,10 +68,10 @@
#include "G4Types.hh"
#ifdef G4MULTITHREADED
static const G4String G4Version = "$Name: geant4-11-02-patch-02 [MT]$";
static const G4String G4Version = "$Name: geant4-11-03-beta-01 [MT]$";
#else
static const G4String G4Version = "$Name: geant4-11-02-patch-02 $";
static const G4String G4Version = "$Name: geant4-11-03-beta-01 $";
#endif
static const G4String G4Date = "(21-June-2024)";
static const G4String G4Date = "(28-June-2024)";
#endif
-5
View File
@@ -75,8 +75,6 @@ geant4_add_module(G4globman
G4PhysicsVector.icc
G4PhysicsVectorType.hh
G4Pow.hh
G4Profiler.hh
G4Profiler.icc
G4ReferenceCountedHandle.hh
G4RotationMatrix.hh
G4SliceTimer.hh
@@ -96,7 +94,6 @@ geant4_add_module(G4globman
G4ThreadLocalSingleton.hh
G4ThreadPool.hh
G4ThreeVector.hh
G4TiMemory.hh
G4Timer.hh
G4Timer.icc
G4Tokenizer.hh
@@ -146,7 +143,6 @@ geant4_add_module(G4globman
G4PhysicsVector.cc
G4Physics2DVector.cc
G4Pow.cc
G4Profiler.cc
G4ReferenceCountedHandle.cc
G4SliceTimer.cc
G4StateManager.cc
@@ -164,7 +160,6 @@ geant4_module_include_directories(G4globman
geant4_module_link_libraries(G4globman
PUBLIC
${CLHEP_LIBRARIES}
${timemory_LIBRARIES}
${PTL_LIBRARIES}
${GEANT4_CXX_FILESYSTEM_LIBRARY} # to temporarily support libstdc++fs, libc++fs
)
@@ -317,9 +317,6 @@ void G4PhysicsModelCatalog::Initialize() {
// Class: G4EvaporationChannel
InsertModel( 24100, "model_G4EvaporationChannel" );
// Classes that use it: G4NeutronRadCapture and G4ExcitationHandler
InsertModel( 24110, "model_e-InternalConversion" );
// Class: G4UnstableFragmentBreakUp
InsertModel( 24120, "model_G4UnstableFragmentBreakUp" );
@@ -599,6 +596,12 @@ void G4PhysicsModelCatalog::Initialize() {
// Class: G4LightIonQMDReaction
InsertModel( 23310, "model_LightIonQMDModel" );
// Class: G4NuDEXEvaporation (to be added in the future)
// InsertModel( 24700, "model_nuDEX_evaporation" );
// Class: G4NuDEXNeutronCapture
InsertModel( 25300, "model_nuDEX_neutronCapture" );
// ...
SanityCheck();
@@ -230,6 +230,11 @@ std::ostream& operator<<(std::ostream& out, G4PhysicsTable& right)
for(auto itr = right.cbegin(); itr != right.cend(); ++itr)
{
out << std::setw(8) << i << "-th Vector ";
if (nullptr == (*itr)) {
out << "empty" << G4endl;
++i;
continue;
}
out << ": Type " << G4int((*itr)->GetType());
out << ": Flag ";
if(right.GetFlag(i))
-590
View File
@@ -1,590 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4Profiler class implementation
//
// Author: J.Madsen (LBL), Aug 2020
// --------------------------------------------------------------------
#include "G4Profiler.hh"
#include "G4TiMemory.hh"
#if defined(GEANT4_USE_TIMEMORY)
# include <timemory/runtime/configure.hpp>
#endif
#include <regex>
#include <thread>
//---------------------------------------------------------------------------//
typename G4Profiler::array_type& G4Profiler::GetEnabled()
{
static array_type _instance = []() {
array_type _tmp{};
_tmp.fill(false);
// environment settings introduce the defaults
// but will be overridden by messenger and/or command line
_tmp.at(G4ProfileType::Run) = G4GetEnv<bool>("G4PROFILE_RUN", true);
_tmp.at(G4ProfileType::Event) = G4GetEnv<bool>("G4PROFILE_EVENT", false);
_tmp.at(G4ProfileType::Track) = G4GetEnv<bool>("G4PROFILE_TRACK", false);
_tmp.at(G4ProfileType::Step) = G4GetEnv<bool>("G4PROFILE_STEP", false);
_tmp.at(G4ProfileType::User) = G4GetEnv<bool>("G4PROFILE_USER", true);
return _tmp;
}();
return _instance;
}
//---------------------------------------------------------------------------//
void G4Profiler::Configure(int argc, char** argv)
{
#if defined(GEANT4_USE_TIMEMORY)
tim::timemory_init(argc, argv);
std::vector<std::string> _args;
for(int i = 0; i < argc; ++i)
_args.push_back(argv[i]);
Configure(_args);
#else
G4Impl::consume_parameters(argc, argv);
#endif
}
//---------------------------------------------------------------------------//
void G4Profiler::Configure(ArgumentParser& parser, int argc, char** argv)
{
#if defined(GEANT4_USE_TIMEMORY)
tim::timemory_init(argc, argv);
std::vector<std::string> _args;
for(int i = 0; i < argc; ++i)
_args.push_back(argv[i]);
Configure(parser, _args);
#else
G4Impl::consume_parameters(parser, argc, argv);
#endif
}
//---------------------------------------------------------------------------//
void G4Profiler::Configure(const std::vector<std::string>& args)
{
#if defined(GEANT4_USE_TIMEMORY)
if(args.empty())
return;
ArgumentParser p{ args.at(0) };
Configure(p, args);
#else
G4Impl::consume_parameters(args);
#endif
}
//---------------------------------------------------------------------------//
void G4Profiler::Configure(ArgumentParser& parser,
const std::vector<std::string>& args)
{
#if defined(GEANT4_USE_TIMEMORY)
using parser_t = ArgumentParser;
using parser_err_t = typename parser_t::result_type;
if(args.empty())
return;
static std::mutex mtx;
std::unique_lock<std::mutex> lk(mtx);
static auto tid = std::this_thread::get_id();
if(std::this_thread::get_id() != tid)
return;
// std::cout << "Arguments:";
// for(auto itr : args)
// std::cout << " " << itr;
// std::cout << std::endl;
auto help_action = [](parser_t& p) {
p.print_help();
exit(EXIT_FAILURE);
};
parser.enable_help();
parser.on_error([=](parser_t& p, parser_err_t _err) {
std::cerr << _err << std::endl;
help_action(p);
});
auto get_bool = [](const std::string& _str, bool _default) {
if(_str.empty())
return _default;
using namespace std::regex_constants;
const auto regex_config = egrep | icase;
if(std::regex_match(_str, std::regex("on|true|yes|1", regex_config)))
return true;
else if(std::regex_match(_str, std::regex("off|false|no|0", regex_config)))
return false;
return _default;
};
//
// Collection control
//
parser.add_argument()
.names({ "-p", "--profile" })
.description("Profiler modes")
.choices({ "run", "event", "track", "step", "user" })
.action([&](parser_t& p) {
using namespace std::regex_constants;
const auto regex_config = egrep | icase;
for(auto&& itr : p.get<std::vector<std::string>>("profile"))
{
if(std::regex_match(itr, std::regex("run", regex_config)))
G4Profiler::SetEnabled(G4ProfileType::Run, true);
else if(std::regex_match(itr, std::regex("event", regex_config)))
G4Profiler::SetEnabled(G4ProfileType::Event, true);
else if(std::regex_match(itr, std::regex("track", regex_config)))
G4Profiler::SetEnabled(G4ProfileType::Track, true);
else if(std::regex_match(itr, std::regex("step", regex_config)))
G4Profiler::SetEnabled(G4ProfileType::Step, true);
else if(std::regex_match(itr, std::regex("user", regex_config)))
G4Profiler::SetEnabled(G4ProfileType::User, true);
}
});
//
// Component controls
//
parser.add_argument()
.names({ "-r", "--run-components" })
.description("Components for run profiling (see 'timemory-avail -s')")
.action([&](parser_t& p) {
G4RunProfiler::reset();
tim::configure<G4RunProfiler>(
p.get<std::vector<std::string>>("run-components"));
});
parser.add_argument()
.names({ "-e", "--event-components" })
.description("Components for event profiling (see 'timemory-avail -s')")
.action([&](parser_t& p) {
G4EventProfiler::reset();
tim::configure<G4EventProfiler>(
p.get<std::vector<std::string>>("event-components"));
});
parser.add_argument()
.names({ "-t", "--track-components" })
.description("Components for track profiling (see 'timemory-avail -s')")
.action([&](parser_t& p) {
G4TrackProfiler::reset();
tim::configure<G4TrackProfiler>(
p.get<std::vector<std::string>>("track-components"));
});
parser.add_argument()
.names({ "-s", "--step-components" })
.description("Components for step profiling (see 'timemory-avail -s')")
.action([&](parser_t& p) {
G4StepProfiler::reset();
tim::configure<G4StepProfiler>(
p.get<std::vector<std::string>>("step-components"));
});
parser.add_argument()
.names({ "-u", "--user-components" })
.description("Components for user profiling (see 'timemory-avail -s')")
.action([&](parser_t& p) {
G4StepProfiler::reset();
tim::configure<G4UserProfiler>(
p.get<std::vector<std::string>>("user-components"));
});
//
// Display controls
//
parser.add_argument()
.names({ "-H", "--hierarchy", "--tree" })
.description("Display the results as a call-stack hierarchy.")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::flat_profile() =
!get_bool(p.get<std::string>("tree"), true);
});
parser.add_argument()
.names({ "-F", "--flat" })
.description("Display the results as a flat call-stack")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::flat_profile() =
get_bool(p.get<std::string>("flat"), true);
});
parser.add_argument()
.names({ "-T", "--timeline" })
.description(
"Do not merge duplicate entries at the same call-stack position")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::timeline_profile() =
get_bool(p.get<std::string>("timeline"), true);
});
parser.add_argument()
.names({ "--per-thread" })
.description(
"Display the results for each individual thread (default: aggregation)")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::flat_profile() =
get_bool(p.get<std::string>("per-thread"), true);
});
parser.add_argument()
.names({ "--per-event" })
.description("Each G4Event is a unique entry")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::timeline_profile() =
get_bool(p.get<std::string>("per-event"), true);
});
//
// Output controls
//
parser.add_argument()
.names({ "-D", "--dart" })
.description("Enable Dart output (CTest/CDash data tracking)")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::dart_output() = get_bool(p.get<std::string>("dart"), true);
});
parser.add_argument()
.names({ "-J", "--json" })
.description("Enable JSON output")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::json_output() = get_bool(p.get<std::string>("json"), true);
});
parser.add_argument()
.names({ "-P", "--plot" })
.description("Plot the JSON output")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::plot_output() = get_bool(p.get<std::string>("plot"), true);
});
parser.add_argument()
.names({ "-X", "--text" })
.description("Enable TEXT output")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::text_output() = get_bool(p.get<std::string>("text"), true);
});
parser.add_argument()
.names({ "-C", "--cout" })
.description("Enable output to terminal")
.max_count(1)
.action([&](parser_t& p) {
tim::settings::cout_output() = get_bool(p.get<std::string>("cout"), true);
});
parser.add_argument()
.names({ "-O", "--output-path" })
.description("Set the output directory")
.count(1)
.action([&](parser_t& p) {
tim::settings::output_path() = p.get<std::string>("output-path");
});
parser.add_argument()
.names({ "-W", "--hw-counters" })
.description(
"Set the hardware counters to collect (see 'timemory-avail -H')")
.action([&](parser_t& p) {
tim::settings::papi_events() = p.get<std::string>("hw-counters");
});
tim::settings::time_output() = true;
tim::settings::time_format() = "%F_%I.%M_%p";
auto err = parser.parse(args);
if(err)
{
std::cout << "Error! " << err << std::endl;
help_action(parser);
}
#else
G4Impl::consume_parameters(parser, args);
#endif
}
//---------------------------------------------------------------------------//
void G4Profiler::Finalize()
{
#if defined(GEANT4_USE_TIMEMORY)
// generally safe to call multiple times but just in case
// it is not necessary to call from worker threads, calling
// once on master will merge any threads that accumulated
// results. If a thread is destroyed, before finalize is
// called on master thread, then it will merge itself into
// the master thread before terminating. The biggest issue
// is when finalize is never called on any threads (including
// the master) so finalization happens after main exits. When
// this happens, the order that data gets deleted is very
// hard to predict so it commonly results in a segfault. Thus,
// if the user does not call this function and does not
// delete G4RunManager, a segfault is quite likely.
static thread_local bool _once = false;
if(!_once)
tim::timemory_finalize();
_once = true;
#endif
}
//---------------------------------------------------------------------------//
template <size_t Ct>
template <int Idx>
typename G4ProfilerConfig<Ct>::template PersistentSettings<Idx>&
G4ProfilerConfig<Ct>::GetPersistentFallback()
{
// G4RunManager::ConfigureProfilers() assigns defaults to these lambdas
// based on environment variables. The users should (generally) not modify
// these.
static PersistentSettings<Idx> _instance = PersistentSettings<Idx>{};
return _instance;
}
//---------------------------------------------------------------------------//
template <size_t Ct>
template <int Idx>
typename G4ProfilerConfig<Ct>::template PersistentSettings<Idx>&
G4ProfilerConfig<Ct>::GetPersistent()
{
//
// The pointers here automatically initialize on the first
// invocation on a thread and a reference is returned so they
// can be cleanly "leaked" at the application termination. Assignment
// is thread-safe and this scheme avoids having to deal with getters
// and setters. It is designed such that we can set defaults but
// the user can override them at any time.
//
// the first global instance copies from the fallback rountines, which are
// assigned defaults in G4RunManager::ConfigureProfilers() but if the user
// assigns new settings before creating G4RunManager, those defaults will
// be ignored
static auto* _instance =
new PersistentSettings<Idx>(GetPersistentFallback<Idx>());
static thread_local PersistentSettings<Idx>* _tlinstance = [=]() {
static std::mutex mtx;
std::unique_lock<std::mutex> lk(mtx);
// If this is the primary thread, just return the global instance from
// above. Modifying that instance will result in all threads created later
// to inherit those settings
static bool _first = true;
if(_first)
{ // below uses comma operator to assign to false before return
return ((_first = false), _instance);
}
// if not first, make a copy from the primary thread
return new PersistentSettings<Idx>(*_instance);
}();
return *_tlinstance;
}
// ----------------------------------------------------------------------
template <size_t Cat>
G4ProfilerConfig<Cat>::~G4ProfilerConfig()
{
delete m_bundle;
}
//----------------------------------------------------------------------------//
// primary (utilized) versions
//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::QueryHandler_t
G4ProfilerConfig<Cat>::GetQueryFunctor()
{
return QueryHandler_t{ GetPersistent<G4ProfileOp::Query>().m_functor };
}
//----------------------------------------------------------------------------//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::LabelHandler_t
G4ProfilerConfig<Cat>::GetLabelFunctor()
{
return LabelHandler_t{ GetPersistent<G4ProfileOp::Label>().m_functor };
}
//----------------------------------------------------------------------------//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::ToolHandler_t
G4ProfilerConfig<Cat>::GetToolFunctor()
{
return ToolHandler_t{ GetPersistent<G4ProfileOp::Tool>().m_functor };
}
//----------------------------------------------------------------------------//
// fallback versions
//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::QueryHandler_t
G4ProfilerConfig<Cat>::GetFallbackQueryFunctor()
{
return QueryHandler_t{
GetPersistentFallback<G4ProfileOp::Query>().m_functor
};
}
//----------------------------------------------------------------------------//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::LabelHandler_t
G4ProfilerConfig<Cat>::GetFallbackLabelFunctor()
{
return LabelHandler_t{
GetPersistentFallback<G4ProfileOp::Label>().m_functor
};
}
//----------------------------------------------------------------------------//
template <size_t Cat>
typename G4ProfilerConfig<Cat>::ToolHandler_t
G4ProfilerConfig<Cat>::GetFallbackToolFunctor()
{
return ToolHandler_t{ GetPersistentFallback<G4ProfileOp::Tool>().m_functor };
}
//---------------------------------------------------------------------------//
class G4Run;
class G4Event;
class G4Track;
class G4Step;
using G4ProfType = G4ProfileType;
using RunProfConfig = G4ProfilerConfig<G4ProfType::Run>;
using EventProfConfig = G4ProfilerConfig<G4ProfType::Event>;
using TrackProfConfig = G4ProfilerConfig<G4ProfType::Track>;
using StepProfConfig = G4ProfilerConfig<G4ProfType::Step>;
using UserProfConfig = G4ProfilerConfig<G4ProfType::User>;
//---------------------------------------------------------------------------//
// force instantiations
template class G4ProfilerConfig<G4ProfType::Run>;
template class G4ProfilerConfig<G4ProfType::Event>;
template class G4ProfilerConfig<G4ProfType::Track>;
template class G4ProfilerConfig<G4ProfType::Step>;
template class G4ProfilerConfig<G4ProfType::User>;
template G4ProfilerConfig<G4ProfType::Run>::G4ProfilerConfig(const G4Run*);
template G4ProfilerConfig<G4ProfType::Event>::G4ProfilerConfig(const G4Event*);
template G4ProfilerConfig<G4ProfType::Track>::G4ProfilerConfig(const G4Track*);
template G4ProfilerConfig<G4ProfType::Step>::G4ProfilerConfig(const G4Step*);
template G4ProfilerConfig<G4ProfileType::User>::G4ProfilerConfig(
const std::string&);
#define G4PROFILE_INSTANTIATION(TYPE) \
template TYPE::PersistentSettings<G4ProfileOp::Query>& \
TYPE::GetPersistentFallback<G4ProfileOp::Query>(); \
template TYPE::PersistentSettings<G4ProfileOp::Label>& \
TYPE::GetPersistentFallback<G4ProfileOp::Label>(); \
template TYPE::PersistentSettings<G4ProfileOp::Tool>& \
TYPE::GetPersistentFallback<G4ProfileOp::Tool>(); \
\
template TYPE::PersistentSettings<G4ProfileOp::Query>& \
TYPE::GetPersistent<G4ProfileOp::Query>(); \
template TYPE::PersistentSettings<G4ProfileOp::Label>& \
TYPE::GetPersistent<G4ProfileOp::Label>(); \
template TYPE::PersistentSettings<G4ProfileOp::Tool>& \
TYPE::GetPersistent<G4ProfileOp::Tool>();
G4PROFILE_INSTANTIATION(RunProfConfig)
G4PROFILE_INSTANTIATION(EventProfConfig)
G4PROFILE_INSTANTIATION(TrackProfConfig)
G4PROFILE_INSTANTIATION(StepProfConfig)
G4PROFILE_INSTANTIATION(UserProfConfig)
//---------------------------------------------------------------------------//
#if !defined(GEANT4_USE_TIMEMORY)
# define TIMEMORY_WEAK_PREFIX
# define TIMEMORY_WEAK_POSTFIX
#endif
//---------------------------------------------------------------------------//
extern "C"
{
// this allows the default setup to be overridden by linking
// in an custom extern C function into the application
TIMEMORY_WEAK_PREFIX
void G4ProfilerInit(void) TIMEMORY_WEAK_POSTFIX;
// this gets executed when the library gets loaded
void G4ProfilerInit(void)
{
#ifdef GEANT4_USE_TIMEMORY
// guard against re-initialization
static bool _once = false;
if(_once)
return;
_once = true;
puts(">>> G4ProfilerInit <<<");
//
// the default settings
//
// large profiles can take a very long time to plot
tim::settings::plot_output() = false;
// large profiles can take quite a bit of console space
tim::settings::cout_output() = false;
// this creates a subdirectory with the timestamp of the run
tim::settings::time_output() = false;
// see `man 3 strftime` for formatting keys
tim::settings::time_format() = "%F_%I.%M_%p";
// set the default precision for timing
tim::settings::timing_precision() = 6;
// set the minimum width for outputs
tim::settings::width() = 12;
// set dart reports (when enabled) to only print the first entry
tim::settings::dart_count() = 1;
// set dart reports (when enabled) to use the component label
// instead of the string identifer of the entry, e.g.
// >>> G4Run/0 ... peak_rss ... 50 MB would report
// 'peak_rss 50 MB' not 'G4Run/0 50 MB'
tim::settings::dart_label() = true;
// allow environment overrides of the defaults
tim::settings::parse();
#endif
}
} // extern "C"
//---------------------------------------------------------------------------//
#ifdef GEANT4_USE_TIMEMORY
namespace
{
static bool profiler_is_initialized = (G4ProfilerInit(), true);
}
#endif
//---------------------------------------------------------------------------//
@@ -243,3 +243,17 @@ G4String G4StateManager::GetStateString(const G4ApplicationState& aState) const
// --------------------------------------------------------------------
void G4StateManager::SetVerboseLevel(G4int val) { verboseLevel = val; }
// --------------------------------------------------------------------
void G4StateManager::NotifyDeletion(const G4Event* evt)
{
for(auto& d : theDependentsList)
{ d->NotifyDeletion(evt); }
}
// --------------------------------------------------------------------
void G4StateManager::NotifyDeletion(const G4Run* rn)
{
for(auto& d : theDependentsList)
{ d->NotifyDeletion(rn); }
}