Geant4-11
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#include "G4EnvironmentUtils.hh"
30#include "G4RunManager.hh"
31#include "G4MTRunManager.hh"
32#include "G4TaskRunManager.hh"
33#include "G4Threading.hh"
34#include "templates.hh"
35
36//============================================================================//
37
38namespace
39{
40 // failure message
41 static void fail(const std::string& _prefix, const std::string& _name,
42 const std::set<std::string>& _opts, G4int _num)
43 {
45 msg << _prefix << ": \"" << _name << "\". "
46 << "Must be one of: ";
47 std::stringstream ss;
48 for(const auto& itr : _opts)
49 ss << ", \"" << itr << "\"";
50 msg << ss.str().substr(2);
51 auto mnum = std::string("RunManagerFactory000") + std::to_string(_num);
52 G4Exception("G4RunManagerFactory::CreateRunManager", mnum.c_str(),
53 FatalException, msg);
54 }
55
59} // namespace
60
61//============================================================================//
62
64 G4VUserTaskQueue* _queue,
65 G4bool fail_if_unavail,
66 G4int nthreads)
67{
68 // If the supplied type is not ...Only, then allow override from environment
69 std::string rm_type = GetName(_type);
70 if(_type == G4RunManagerType::SerialOnly ||
71 _type == G4RunManagerType::MTOnly ||
74 {
75 // MUST fail if unavail in this case
76 fail_if_unavail = true;
77 }
78 else
79 {
80 // - G4RUN_MANAGER_TYPE can be set to override the "default"
81 // - If the requested type isn't available, then it will fall back to the
82 // system default
83 // - G4FORCE_RUN_MANAGER_TYPE can be set to force a specific type
84 // - A G4Exception is raised if the requested type is not available
85 rm_type = G4GetEnv<std::string>("G4RUN_MANAGER_TYPE", GetName(_type),
86 "Overriding G4RunManager type...");
87 auto force_rm = G4GetEnv<std::string>("G4FORCE_RUN_MANAGER_TYPE", "",
88 "Forcing G4RunManager type...");
89
90 if(force_rm.length() > 0)
91 {
92 rm_type = force_rm;
93 fail_if_unavail = true;
94 }
95 else if(rm_type.empty())
96 {
97 rm_type = GetDefault();
98 }
99 }
100
101 // At this point will have a string for the RM type we can check for existence
102 // NB: Comparison at present is case sensitive (needs a comparator in
103 // GetOptions)
104 auto opts = GetOptions();
105 if(opts.find(rm_type) == opts.end())
106 {
107 if(fail_if_unavail)
108 {
109 fail("Run manager type is not available", rm_type, opts, 1);
110 }
111 else
112 {
113 rm_type = GetDefault();
114 }
115 }
116
117 // Construct requested RunManager given type
118 _type = GetType(rm_type);
119 G4RunManager* rm = nullptr;
120
121 switch(_type)
122 {
124 rm = new G4RunManager();
125 break;
127#if defined(G4MULTITHREADED)
128 rm = new G4MTRunManager();
129#endif
130 break;
132#if defined(G4MULTITHREADED)
133 rm = new G4TaskRunManager(_queue, false);
134#endif
135 break;
137#if defined(G4MULTITHREADED) && defined(GEANT4_USE_TBB)
138 rm = new G4TaskRunManager(_queue, true);
139#endif
140 break;
141 // "Only" types are not handled since they are converted above to main type
143 break;
145 break;
147 break;
149 break;
151 break;
152 }
153
154 if(!rm)
155 fail("Failure creating run manager", GetName(_type), GetOptions(), 2);
156
157 auto mtrm = dynamic_cast<G4MTRunManager*>(rm);
158 if(nthreads > 0 && mtrm)
159 mtrm->SetNumberOfThreads(nthreads);
160
164
165 G4ConsumeParameters(_queue);
166 return rm;
167}
168
169//============================================================================//
170
172{
173#if defined(G4MULTITHREADED)
174 // For version 10.7, default is set to MT
175 // return "MT";
176 return "Tasking";
177#else
178 return "Serial";
179#endif
180}
181
182//============================================================================//
183
184std::set<std::string> G4RunManagerFactory::GetOptions()
185{
186 static auto _instance = []() {
187 std::set<std::string> options = { "Serial" };
188#if defined(G4MULTITHREADED)
189 options.insert({ "MT", "Tasking" });
190# if defined(GEANT4_USE_TBB)
191 options.insert("TBB");
192# endif
193#endif
194 return options;
195 }();
196 return _instance;
197}
198
199//============================================================================//
200
202{
203 // IGNORES CASE!
204 static const auto opts = std::regex::icase;
205
206 if(std::regex_match(key, std::regex("^(Serial).*", opts)))
208 else if(std::regex_match(key, std::regex("^(MT).*", opts)))
210 else if(std::regex_match(key, std::regex("^(Task).*", opts)))
212 else if(std::regex_match(key, std::regex("^(TBB).*", opts)))
214
216}
217
218//============================================================================//
219
221{
222 switch(_type)
223 {
225 return "Serial";
227 return "Serial";
229 return "MT";
231 return "MT";
233 return "Tasking";
235 return "Tasking";
237 return "TBB";
239 return "TBB";
240 default:
241 break;
242 };
243 return "";
244}
245
246//============================================================================//
247
249{
250#if !defined(G4MULTITHREADED)
251 // if serial build just return G4RunManager
253#else
254 // if the application used G4RunManagerFactory to create the run-manager
256 return master_run_manager;
257
258 // if the application did not use G4RunManagerFactory and is MT
260 {
261 auto mt_rm = GetMTMasterRunManager();
262 if(mt_rm)
263 return mt_rm;
264 }
265
266 // if the application did not use G4RunManagerFactory and is serial
268#endif
269}
270
271//============================================================================//
272
274{
275#if defined(G4MULTITHREADED)
276 // if the application used G4RunManagerFactory to create the run-manager
279
280 // if the application did not use G4RunManagerFactory
282 {
284 if(task_rm)
285 return task_rm;
287 }
288#endif
289
290 return nullptr;
291}
292
293//============================================================================//
294
296{
297#if !defined(G4MULTITHREADED)
298 // if serial build just return G4RunManager
300#else
301 // if the application used G4RunManagerFactory to create the run-manager
304
305 // if the application did not use G4RunManagerFactory and is MT
307 {
308 auto mt_rm = GetMTMasterRunManager();
309 if(mt_rm)
310 return mt_rm->kernel;
311 }
312
313 // if the application did not use G4RunManagerFactory and is serial
315#endif
316}
317
318//============================================================================//
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4RunManagerType
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
virtual void SetNumberOfThreads(G4int n)
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()
Definition: G4Threading.cc:130
static void fail(const std::string &_prefix, const std::string &_name, const std::set< std::string > &_opts, G4int _num)
static G4RunManagerKernel * master_run_manager_kernel
void G4ConsumeParameters(_Args &&...)
Definition: templates.hh:187