Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4RunManagerFactory.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27
29
30#include "G4EnvironmentUtils.hh"
31#include "G4MTRunManager.hh"
32#include "G4RunManager.hh"
33#include "G4TaskRunManager.hh"
34#include "G4Threading.hh"
35
36#include "templates.hh"
37
38//============================================================================//
39
40namespace
41{
42// failure message
43static void fail(const std::string& _prefix, const std::string& _name,
44 const std::set<std::string>& _opts, G4int _num)
45{
47 msg << _prefix << ": \"" << _name << "\". "
48 << "Must be one of: ";
49 std::stringstream ss;
50 for (const auto& itr : _opts)
51 ss << ", \"" << itr << "\"";
52 msg << ss.str().substr(2);
53 auto mnum = std::string("RunManagerFactory000") + std::to_string(_num);
54 G4Exception("G4RunManagerFactory::CreateRunManager", mnum.c_str(), FatalException, msg);
55}
56
57static G4RunManager* master_run_manager = nullptr;
58static G4MTRunManager* mt_master_run_manager = nullptr;
59static G4RunManagerKernel* master_run_manager_kernel = nullptr;
60} // namespace
61
62//============================================================================//
63
65 G4VUserTaskQueue* _queue,
66 G4bool fail_if_unavail, G4int nthreads)
67{
68 // If the supplied type is not ...Only, then allow override from environment
69 std::string rm_type = GetName(_type);
72 {
73 // MUST fail if unavail in this case
74 fail_if_unavail = true;
75 }
76 else {
77 // - G4RUN_MANAGER_TYPE can be set to override the "default"
78 // - If the requested type isn't available, then it will fall back to the
79 // system default
80 // - G4FORCE_RUN_MANAGER_TYPE can be set to force a specific type
81 // - A G4Exception is raised if the requested type is not available
82 rm_type = G4GetEnv<std::string>("G4RUN_MANAGER_TYPE", GetName(_type),
83 "Overriding G4RunManager type...");
84 auto force_rm =
85 G4GetEnv<std::string>("G4FORCE_RUN_MANAGER_TYPE", "", "Forcing G4RunManager type...");
86
87 if (force_rm.length() > 0) {
88 rm_type = force_rm;
89 fail_if_unavail = true;
90 }
91 else if (rm_type.empty()) {
92 rm_type = GetDefault();
93 }
94 }
95
96 // At this point will have a string for the RM type we can check for existence
97 // NB: Comparison at present is case sensitive (needs a comparator in
98 // GetOptions)
99 auto opts = GetOptions();
100 if (opts.find(rm_type) == opts.end()) {
101 if (fail_if_unavail) {
102 fail("Run manager type is not available", rm_type, opts, 1);
103 }
104 else {
105 rm_type = GetDefault();
106 }
107 }
108
109 // Construct requested RunManager given type
110 _type = GetType(rm_type);
111 G4RunManager* rm = nullptr;
112
113 switch (_type) {
115 rm = new G4RunManager();
116 break;
118#if defined(G4MULTITHREADED)
119 rm = new G4MTRunManager();
120#endif
121 break;
123#if defined(G4MULTITHREADED)
124 rm = new G4TaskRunManager(_queue, false);
125#endif
126 break;
128#if defined(G4MULTITHREADED) && defined(GEANT4_USE_TBB)
129 rm = new G4TaskRunManager(_queue, true);
130#endif
131 break;
132 // "Only" types are not handled since they are converted above to main type
134 break;
136 break;
138 break;
140 break;
142 break;
143 }
144
145 if (rm == nullptr) fail("Failure creating run manager", GetName(_type), GetOptions(), 2);
146
147 auto mtrm = dynamic_cast<G4MTRunManager*>(rm);
148 if (nthreads > 0 && (mtrm != nullptr)) mtrm->SetNumberOfThreads(nthreads);
149
150 master_run_manager = rm;
151 mt_master_run_manager = mtrm;
152 master_run_manager_kernel = rm->kernel;
153
154 G4ConsumeParameters(_queue);
155 return rm;
156}
157
158//============================================================================//
159
161{
162#if defined(G4MULTITHREADED)
163 return "Tasking";
164#else
165 return "Serial";
166#endif
167}
168
169//============================================================================//
170
171std::set<std::string> G4RunManagerFactory::GetOptions()
172{
173 static auto _instance = []() {
174 std::set<std::string> options = {"Serial"};
175#if defined(G4MULTITHREADED)
176 options.insert({"MT", "Tasking"});
177# if defined(GEANT4_USE_TBB)
178 options.insert("TBB");
179# endif
180#endif
181 return options;
182 }();
183 return _instance;
184}
185
186//============================================================================//
187
189{
190 // IGNORES CASE!
191 static const auto opts = std::regex::icase;
192
193 if (std::regex_match(key, std::regex("^(Serial).*", opts))) return G4RunManagerType::Serial;
194 if (std::regex_match(key, std::regex("^(MT).*", opts))) return G4RunManagerType::MT;
195 if (std::regex_match(key, std::regex("^(Task).*", opts))) return G4RunManagerType::Tasking;
196 if (std::regex_match(key, std::regex("^(TBB).*", opts))) return G4RunManagerType::TBB;
197
199}
200
201//============================================================================//
202
204{
205 switch (_type) {
207 return "Serial";
209 return "Serial";
211 return "MT";
213 return "MT";
215 return "Tasking";
217 return "Tasking";
219 return "TBB";
221 return "TBB";
222 default:
223 break;
224 };
225 return "";
226}
227
228//============================================================================//
229
231{
232#if !defined(G4MULTITHREADED)
233 // if serial build just return G4RunManager
235#else
236 // if the application used G4RunManagerFactory to create the run-manager
237 if (master_run_manager != nullptr) return master_run_manager;
238
239 // if the application did not use G4RunManagerFactory and is MT
241 auto mt_rm = GetMTMasterRunManager();
242 if (mt_rm != nullptr) return mt_rm;
243 }
244
245 // if the application did not use G4RunManagerFactory and is serial
247#endif
248}
249
250//============================================================================//
251
253{
254#if defined(G4MULTITHREADED)
255 // if the application used G4RunManagerFactory to create the run-manager
256 if (mt_master_run_manager != nullptr) return mt_master_run_manager;
257
258 // if the application did not use G4RunManagerFactory
261 if (task_rm != nullptr) return task_rm;
263 }
264#endif
265
266 return nullptr;
267}
268
269//============================================================================//
270
272{
273#if !defined(G4MULTITHREADED)
274 // if serial build just return G4RunManager
276#else
277 // if the application used G4RunManagerFactory to create the run-manager
278 if (master_run_manager_kernel != nullptr) return master_run_manager_kernel;
279
280 // if the application did not use G4RunManagerFactory and is MT
282 auto mt_rm = GetMTMasterRunManager();
283 if (mt_rm != nullptr) return mt_rm->kernel;
284 }
285
286 // if the application did not use G4RunManagerFactory and is serial
288#endif
289}
290
291//============================================================================//
_Tp G4GetEnv(const std::string &env_id, _Tp _default=_Tp())
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
void SetNumberOfThreads(G4int n) override
static G4MTRunManager * GetMasterRunManager()
static G4RunManager * CreateRunManager(G4RunManagerType _type=G4RunManagerType::Default, G4VUserTaskQueue *_queue=nullptr, G4bool fail_if_unavail=true, G4int nthreads=0)
static G4RunManager * GetMasterRunManager()
static G4MTRunManager * GetMTMasterRunManager()
static std::set< std::string > GetOptions()
static std::string GetName(G4RunManagerType)
static std::string GetDefault()
static G4RunManagerType GetType(const std::string &)
static G4RunManagerKernel * GetMasterRunManagerKernel()
G4RunManagerKernel * kernel
static G4RunManager * GetRunManager()
static G4TaskRunManager * GetMasterRunManager()
G4bool IsMultithreadedApplication()
void G4ConsumeParameters(_Args &&...)
Definition templates.hh:177