16 struct ThreadContext {
17 std::unique_ptr<MemoryManager> memoryManager;
18 std::unique_ptr<WilsonInterface> wilsonInterface;
21 static std::mutex instanceMutex;
22 static std::map<std::thread::id, ThreadContext> threadInstances;
26 static ThreadContext& getThreadContext(
const std::string& lhaFile,
const std::string& model,
const std::vector<int>& models) {
27 auto threadId = std::this_thread::get_id();
29 std::lock_guard<std::mutex> lock(instanceMutex);
31 if (threadInstances.find(threadId) == threadInstances.end()) {
32 threadInstances[threadId] = ThreadContext{
33 std::make_unique<MemoryManager>(lhaFile, models),
34 std::make_unique<WilsonInterface>(model)
38 return threadInstances[threadId];
43 std::vector<std::thread> workers;
44 std::queue<std::function<void()>> tasks;
46 std::mutex queueMutex;
47 std::condition_variable condition;
51 explicit ThreadPool(
size_t threads) : stop(
false) {
52 for (
size_t i = 0; i < threads; ++i) {
53 workers.emplace_back([
this] {
55 std::function<void()> task;
58 std::unique_lock<std::mutex> lock(this->queueMutex);
59 this->condition.wait(lock, [
this] {
return this->stop || !this->tasks.empty(); });
61 if (this->stop && this->tasks.empty())
64 task = std::move(this->tasks.front());
74 void enqueue(std::function<
void()> task) {
76 std::lock_guard<std::mutex> lock(queueMutex);
77 tasks.emplace(std::move(task));
79 condition.notify_one();
84 std::lock_guard<std::mutex> lock(queueMutex);
87 condition.notify_all();
89 for (std::thread& worker : workers) {
90 if (worker.joinable()) {
103 void Initialize(
const std::string& lhaFile,
const std::string& model,
const std::vector<int>& models = {0}) {
104 getThreadContext(lhaFile, model, models);
108 return getThreadContext(
"",
"", {}).memoryManager.get();
112 return getThreadContext(
"",
"", {}).wilsonInterface.get();
117 const std::string& model =
"SM",
118 const std::vector<int>& models = {0},
119 size_t maxThreads = std::thread::hardware_concurrency()) {
120 ThreadPool threadPool(maxThreads);
122 for (
const auto& lhaFile : lhaFiles) {
123 threadPool.enqueue([&, lhaFile]() {
125 task(*
this, lhaFile);
132 std::lock_guard<std::mutex> lock(instanceMutex);
133 threadInstances.erase(std::this_thread::get_id());
void RunInParallel(const std::vector< std::string > &lhaFiles, std::function< void(HyperisoInterface &, const std::string &)> task, const std::string &model="SM", const std::vector< int > &models={0}, size_t maxThreads=std::thread::hardware_concurrency())