Geant4 Cross Reference |
1 // 1 // 2 // MIT License 2 // MIT License 3 // Copyright (c) 2020 Jonathan R. Madsen 3 // Copyright (c) 2020 Jonathan R. Madsen 4 // Permission is hereby granted, free of charg 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentati 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, includ 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distr 7 // to use, copy, modify, merge, publish, distribute, sublicense, and 8 // copies of the Software, and to permit perso 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the followin 9 // furnished to do so, subject to the following conditions: 10 // The above copyright notice and this permiss 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the S 11 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPR 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILIT 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARIS 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALI 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 // 18 // 19 // ------------------------------------------- 19 // --------------------------------------------------------------- 20 // Tasking class implementation 20 // Tasking class implementation 21 #include "PTL/TaskRunManager.hh" << 22 21 >> 22 #include "PTL/TaskRunManager.hh" >> 23 #include "PTL/AutoLock.hh" >> 24 #include "PTL/Task.hh" >> 25 #include "PTL/TaskGroup.hh" 23 #include "PTL/TaskManager.hh" 26 #include "PTL/TaskManager.hh" 24 #include "PTL/ThreadPool.hh" 27 #include "PTL/ThreadPool.hh" >> 28 #include "PTL/Threading.hh" >> 29 #include "PTL/Utility.hh" 25 30 26 namespace PTL << 31 #include <cstdlib> 27 { << 32 #include <cstring> 28 //============================================ << 33 #include <iterator> 29 34 30 TaskRunManager::pointer& << 35 using namespace PTL; 31 TaskRunManager::GetPrivateMasterRunManager() << 32 { << 33 static pointer _instance = nullptr; << 34 return _instance; << 35 } << 36 36 37 //============================================ 37 //======================================================================================// 38 38 39 TaskRunManager::pointer& 39 TaskRunManager::pointer& 40 TaskRunManager::GetPrivateMasterRunManager(boo 40 TaskRunManager::GetPrivateMasterRunManager(bool init, bool useTBB) 41 { 41 { 42 auto& _v = GetPrivateMasterRunManager(); << 42 static pointer _instance = (init) ? new TaskRunManager(useTBB) : nullptr; 43 if(!init) << 43 return _instance; 44 return _v; << 45 if(!_v) << 46 _v = new TaskRunManager(useTBB); << 47 return _v; << 48 } 44 } 49 45 50 //============================================ 46 //======================================================================================// 51 47 52 TaskRunManager* 48 TaskRunManager* 53 TaskRunManager::GetMasterRunManager(bool useTB 49 TaskRunManager::GetMasterRunManager(bool useTBB) 54 { 50 { 55 auto& _v = GetPrivateMasterRunManager(true << 51 static pointer& _instance = GetPrivateMasterRunManager(true, useTBB); 56 return _v; << 52 return _instance; 57 } 53 } 58 54 59 //============================================ 55 //======================================================================================// 60 56 61 TaskRunManager* 57 TaskRunManager* 62 TaskRunManager::GetInstance(bool useTBB) 58 TaskRunManager::GetInstance(bool useTBB) 63 { 59 { 64 return GetMasterRunManager(useTBB); 60 return GetMasterRunManager(useTBB); 65 } 61 } 66 62 67 //============================================ 63 //======================================================================================// 68 64 69 TaskRunManager::TaskRunManager(bool useTBB) 65 TaskRunManager::TaskRunManager(bool useTBB) 70 : m_workers(std::thread::hardware_concurrency( 66 : m_workers(std::thread::hardware_concurrency()) 71 , m_use_tbb(useTBB) << 72 { 67 { 73 if(!GetPrivateMasterRunManager()) << 68 if(!GetPrivateMasterRunManager(false)) 74 GetPrivateMasterRunManager() = this; << 69 { 75 } << 70 GetPrivateMasterRunManager(false) = this; 76 << 71 } 77 //============================================ << 78 72 79 TaskRunManager::~TaskRunManager() << 73 #if defined(PTL_USE_TBB) 80 { << 74 auto _useTBB = GetEnv<bool>("PTL_FORCE_TBB", GetEnv<bool>("FORCE_TBB", useTBB)); 81 if(GetPrivateMasterRunManager() == this) << 75 if(_useTBB) 82 GetPrivateMasterRunManager() = nullptr << 76 useTBB = true; >> 77 #endif >> 78 >> 79 // handle TBB >> 80 ThreadPool::set_use_tbb(useTBB); >> 81 m_workers = GetEnv<uint64_t>("PTL_NUM_THREADS", m_workers); 83 } 82 } 84 83 85 //============================================ 84 //======================================================================================// 86 85 87 void 86 void 88 TaskRunManager::Initialize(uint64_t n) 87 TaskRunManager::Initialize(uint64_t n) 89 { 88 { 90 m_workers = n; 89 m_workers = n; 91 90 92 // create threadpool if needed + task mana 91 // create threadpool if needed + task manager 93 if(!m_thread_pool) 92 if(!m_thread_pool) 94 { 93 { 95 ThreadPool::Config cfg; << 94 if(m_verbose > 0) 96 cfg.pool_size = m_workers; << 95 std::cout << "TaskRunManager :: Creating thread pool..." << std::endl; 97 cfg.task_queue = m_task_queue; << 96 m_thread_pool = new ThreadPool(m_workers, m_task_queue); 98 cfg.use_tbb = m_use_tbb; << 97 if(m_verbose > 0) 99 m_thread_pool = new ThreadPool(cfg); << 98 std::cout << "TaskRunManager :: Creating task manager..." << std::endl; 100 m_task_manager = new TaskManager(m_thr 99 m_task_manager = new TaskManager(m_thread_pool); 101 } 100 } 102 // or resize 101 // or resize 103 else if(m_workers != m_thread_pool->size() 102 else if(m_workers != m_thread_pool->size()) 104 { 103 { >> 104 if(m_verbose > 0) >> 105 { >> 106 std::cout << "TaskRunManager :: Resizing thread pool from " >> 107 << m_thread_pool->size() << " to " << m_workers << " threads ..." >> 108 << std::endl; >> 109 } 105 m_thread_pool->resize(m_workers); 110 m_thread_pool->resize(m_workers); 106 } 111 } 107 112 >> 113 // create the joiners >> 114 if(ThreadPool::using_tbb()) >> 115 { >> 116 if(m_verbose > 0) >> 117 std::cout << "TaskRunManager :: Using TBB..." << std::endl; >> 118 } >> 119 else >> 120 { >> 121 if(m_verbose > 0) >> 122 std::cout << "TaskRunManager :: Using ThreadPool..." << std::endl; >> 123 } >> 124 108 m_is_initialized = true; 125 m_is_initialized = true; >> 126 if(m_verbose > 0) >> 127 std::cout << "TaskRunManager :: initialized..." << std::endl; 109 } 128 } 110 129 111 //============================================ 130 //======================================================================================// 112 131 113 void 132 void 114 TaskRunManager::Terminate() 133 TaskRunManager::Terminate() 115 { 134 { 116 m_is_initialized = false; 135 m_is_initialized = false; 117 if(m_thread_pool) 136 if(m_thread_pool) 118 m_thread_pool->destroy_threadpool(); 137 m_thread_pool->destroy_threadpool(); 119 delete m_task_manager; 138 delete m_task_manager; 120 delete m_thread_pool; 139 delete m_thread_pool; 121 m_task_manager = nullptr; 140 m_task_manager = nullptr; 122 m_thread_pool = nullptr; 141 m_thread_pool = nullptr; 123 } 142 } 124 143 125 //============================================ 144 //======================================================================================// 126 << 127 } // namespace PTL << 128 145