Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
56 static G4RunManager* master_run_manager = nullptr;
57 static G4MTRunManager* mt_master_run_manager = nullptr;
58 static G4RunManagerKernel* master_run_manager_kernel = nullptr;
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 ||
72 _type == G4RunManagerType::TaskingOnly ||
73 _type == G4RunManagerType::TBBOnly)
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 {
123 case G4RunManagerType::Serial:
124 rm = new G4RunManager();
125 break;
126 case G4RunManagerType::MT:
127#if defined(G4MULTITHREADED)
128 rm = new G4MTRunManager();
129#endif
130 break;
131 case G4RunManagerType::Tasking:
132#if defined(G4MULTITHREADED)
133 rm = new G4TaskRunManager(_queue, false);
134#endif
135 break;
136 case G4RunManagerType::TBB:
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
142 case G4RunManagerType::SerialOnly:
143 break;
144 case G4RunManagerType::MTOnly:
145 break;
146 case G4RunManagerType::TaskingOnly:
147 break;
148 case G4RunManagerType::TBBOnly:
149 break;
150 case G4RunManagerType::Default:
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
161 master_run_manager = rm;
162 mt_master_run_manager = mtrm;
163 master_run_manager_kernel = rm->kernel;
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)))
207 return G4RunManagerType::Serial;
208 else if(std::regex_match(key, std::regex("^(MT).*", opts)))
209 return G4RunManagerType::MT;
210 else if(std::regex_match(key, std::regex("^(Task).*", opts)))
211 return G4RunManagerType::Tasking;
212 else if(std::regex_match(key, std::regex("^(TBB).*", opts)))
213 return G4RunManagerType::TBB;
214
215 return G4RunManagerType::Default;
216}
217
218//============================================================================//
219
221{
222 switch(_type)
223 {
224 case G4RunManagerType::Serial:
225 return "Serial";
226 case G4RunManagerType::SerialOnly:
227 return "Serial";
228 case G4RunManagerType::MT:
229 return "MT";
230 case G4RunManagerType::MTOnly:
231 return "MT";
232 case G4RunManagerType::Tasking:
233 return "Tasking";
234 case G4RunManagerType::TaskingOnly:
235 return "Tasking";
236 case G4RunManagerType::TBB:
237 return "TBB";
238 case G4RunManagerType::TBBOnly:
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
255 if(master_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
277 if(mt_master_run_manager)
278 return mt_master_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
302 if(master_run_manager_kernel)
303 return master_run_manager_kernel;
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:59
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
void G4ConsumeParameters(_Args &&...)
Definition: templates.hh:177