Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 28 #include "G4RunManagerFactory.hh" 29 30 #include "G4EnvironmentUtils.hh" 31 #include "G4MTRunManager.hh" 32 #include "G4RunManager.hh" 33 #include "G4TaskRunManager.hh" 34 #include "G4SubEvtRunManager.hh" 35 #include "G4Threading.hh" 36 37 #include "templates.hh" 38 39 //============================================ 40 41 namespace 42 { 43 // failure message 44 static void fail(const std::string& _prefix, c 45 const std::set<std::string>& 46 { 47 G4ExceptionDescription msg; 48 msg << _prefix << ": \"" << _name << "\". " 49 << "Must be one of: "; 50 std::stringstream ss; 51 for (const auto& itr : _opts) 52 ss << ", \"" << itr << "\""; 53 msg << ss.str().substr(2); 54 auto mnum = std::string("RunManagerFactory00 55 G4Exception("G4RunManagerFactory::CreateRunM 56 } 57 58 static G4RunManager* master_run_manager = null 59 static G4MTRunManager* mt_master_run_manager = 60 static G4RunManagerKernel* master_run_manager_ 61 } // namespace 62 63 //============================================ 64 65 G4RunManager* G4RunManagerFactory::CreateRunMa 66 67 68 { 69 // If the supplied type is not ...Only, then 70 std::string rm_type = GetName(_type); 71 if (_type == G4RunManagerType::SerialOnly || 72 || _type == G4RunManagerType::TaskingOnl 73 || _type == G4RunManagerType::SubEvtOnly 74 { 75 // MUST fail if unavail in this case 76 fail_if_unavail = true; 77 } 78 else { 79 // - G4RUN_MANAGER_TYPE can be set to over 80 // - If the requested type isn't availab 81 // system default 82 // - G4FORCE_RUN_MANAGER_TYPE can be set t 83 // - A G4Exception is raised if the requ 84 rm_type = G4GetEnv<std::string>("G4RUN_MAN 85 "Overridin 86 auto force_rm = 87 G4GetEnv<std::string>("G4FORCE_RUN_MANAG 88 89 if (force_rm.length() > 0) { 90 rm_type = std::move(force_rm); 91 fail_if_unavail = true; 92 } 93 else if (rm_type.empty()) { 94 rm_type = GetDefault(); 95 } 96 } 97 98 // At this point will have a string for the 99 // NB: Comparison at present is case sensiti 100 // GetOptions) 101 auto opts = GetOptions(); 102 if (opts.find(rm_type) == opts.end()) { 103 if (fail_if_unavail) { 104 fail("Run manager type is not available" 105 } 106 else { 107 rm_type = GetDefault(); 108 } 109 } 110 111 // Construct requested RunManager given type 112 _type = GetType(rm_type); 113 G4RunManager* rm = nullptr; 114 115 switch (_type) { 116 case G4RunManagerType::Serial: 117 rm = new G4RunManager(); 118 break; 119 case G4RunManagerType::MT: 120 #if defined(G4MULTITHREADED) 121 rm = new G4MTRunManager(); 122 #endif 123 break; 124 case G4RunManagerType::Tasking: 125 #if defined(G4MULTITHREADED) 126 rm = new G4TaskRunManager(_queue, false) 127 #endif 128 break; 129 case G4RunManagerType::TBB: 130 #if defined(G4MULTITHREADED) && defined(GEANT4 131 rm = new G4TaskRunManager(_queue, true); 132 #endif 133 break; 134 case G4RunManagerType::SubEvt: 135 #if defined(G4MULTITHREADED) 136 #if defined(GEANT4_USE_TBB) 137 rm = new G4SubEvtRunManager(_queue, true 138 #else 139 rm = new G4SubEvtRunManager(_queue, fals 140 #endif 141 #endif 142 break; 143 // "Only" types are not handled since they 144 case G4RunManagerType::SerialOnly: 145 break; 146 case G4RunManagerType::MTOnly: 147 break; 148 case G4RunManagerType::TaskingOnly: 149 break; 150 case G4RunManagerType::TBBOnly: 151 break; 152 case G4RunManagerType::SubEvtOnly: 153 break; 154 case G4RunManagerType::Default: 155 break; 156 } 157 158 if (rm == nullptr) fail("Failure creating ru 159 160 auto mtrm = dynamic_cast<G4MTRunManager*>(rm 161 if (nthreads > 0 && (mtrm != nullptr)) mtrm- 162 163 master_run_manager = rm; 164 mt_master_run_manager = mtrm; 165 master_run_manager_kernel = rm->kernel; 166 167 G4ConsumeParameters(_queue); 168 return rm; 169 } 170 171 //============================================ 172 173 std::string G4RunManagerFactory::GetDefault() 174 { 175 #if defined(G4MULTITHREADED) 176 return "Tasking"; 177 #else 178 return "Serial"; 179 #endif 180 } 181 182 //============================================ 183 184 std::set<std::string> G4RunManagerFactory::Get 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 options.insert("SubEvt"); 194 #endif 195 return options; 196 }(); 197 return _instance; 198 } 199 200 //============================================ 201 202 G4RunManagerType G4RunManagerFactory::GetType( 203 { 204 // IGNORES CASE! 205 static const auto opts = std::regex::icase; 206 207 if (std::regex_match(key, std::regex("^(Seri 208 if (std::regex_match(key, std::regex("^(MT). 209 if (std::regex_match(key, std::regex("^(Task 210 if (std::regex_match(key, std::regex("^(TBB) 211 if (std::regex_match(key, std::regex("^(SubE 212 213 return G4RunManagerType::Default; 214 } 215 216 //============================================ 217 218 std::string G4RunManagerFactory::GetName(G4Run 219 { 220 switch (_type) { 221 case G4RunManagerType::Serial: 222 return "Serial"; 223 case G4RunManagerType::SerialOnly: 224 return "Serial"; 225 case G4RunManagerType::MT: 226 return "MT"; 227 case G4RunManagerType::MTOnly: 228 return "MT"; 229 case G4RunManagerType::Tasking: 230 return "Tasking"; 231 case G4RunManagerType::TaskingOnly: 232 return "Tasking"; 233 case G4RunManagerType::TBB: 234 return "TBB"; 235 case G4RunManagerType::TBBOnly: 236 return "TBB"; 237 case G4RunManagerType::SubEvt: 238 return "SubEvt"; 239 case G4RunManagerType::SubEvtOnly: 240 return "SubEvt"; 241 default: 242 break; 243 }; 244 return ""; 245 } 246 247 //============================================ 248 249 G4RunManager* G4RunManagerFactory::GetMasterRu 250 { 251 #if !defined(G4MULTITHREADED) 252 // if serial build just return G4RunManager 253 return G4RunManager::GetRunManager(); 254 #else 255 // if the application used G4RunManagerFacto 256 if (master_run_manager != nullptr) return ma 257 258 // if the application did not use G4RunManag 259 if (G4Threading::IsMultithreadedApplication( 260 auto mt_rm = GetMTMasterRunManager(); 261 if (mt_rm != nullptr) return mt_rm; 262 } 263 264 // if the application did not use G4RunManag 265 return G4RunManager::GetRunManager(); 266 #endif 267 } 268 269 //============================================ 270 271 G4MTRunManager* G4RunManagerFactory::GetMTMast 272 { 273 #if defined(G4MULTITHREADED) 274 // if the application used G4RunManagerFacto 275 if (mt_master_run_manager != nullptr) return 276 277 // if the application did not use G4RunManag 278 if (G4Threading::IsMultithreadedApplication( 279 auto task_rm = G4TaskRunManager::GetMaster 280 if (task_rm != nullptr) return task_rm; 281 return G4MTRunManager::GetMasterRunManager 282 } 283 #endif 284 285 return nullptr; 286 } 287 288 //============================================ 289 290 G4RunManagerKernel* G4RunManagerFactory::GetMa 291 { 292 #if !defined(G4MULTITHREADED) 293 // if serial build just return G4RunManager 294 return G4RunManager::GetRunManager()->kernel 295 #else 296 // if the application used G4RunManagerFacto 297 if (master_run_manager_kernel != nullptr) re 298 299 // if the application did not use G4RunManag 300 if (G4Threading::IsMultithreadedApplication( 301 auto mt_rm = GetMTMasterRunManager(); 302 if (mt_rm != nullptr) return mt_rm->kernel 303 } 304 305 // if the application did not use G4RunManag 306 return G4RunManager::GetRunManager()->kernel 307 #endif 308 } 309 310 //============================================ 311