Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JetEnergyLossManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JetEnergyLossManager.cc
1 /*******************************************************************************
2  * Copyright (c) The JETSCAPE Collaboration, 2018
3  *
4  * Modular, task-based framework for simulating all aspects of heavy-ion collisions
5  *
6  * For the list of contributors see AUTHORS.
7  *
8  * Report issues at https://github.com/JETSCAPE/JETSCAPE/issues
9  *
10  * or via email to bugs.jetscape@gmail.com
11  *
12  * Distributed under the GNU General Public License 3.0 (GPLv3 or later).
13  * See COPYING for details.
14  ******************************************************************************/
15 
16 #include "JetEnergyLossManager.h"
17 #include "JetScapeLogger.h"
18 #include "JetScapeSignalManager.h"
19 #include "MakeUniqueHelper.h"
20 #include <string>
21 
22 #include <iostream>
23 #include <vector>
24 #include <thread>
25 
26 using namespace std;
27 
28 namespace Jetscape {
29 
30 JetEnergyLossManager::JetEnergyLossManager() {
31  SetId("JLossManager");
32  GetHardPartonListConnected = false;
33  VERBOSE(8);
34 }
35 
36 JetEnergyLossManager::~JetEnergyLossManager() {
37  // Check if this is all really needed with shared_ptr ...
38  JSDEBUG;
39  Clear();
40 
41  if (GetNumberOfTasks() > 0)
42  EraseTaskLast();
43 }
44 
46  JSDEBUG << "Hard Parton List ...";
47 
48  hp.clear();
49 
50  int n = GetNumberOfTasks();
51  for (int i = 1; i < n; i++)
52  EraseTaskLast();
53 
54  // Clean Up not really working with iterators (see also above!!!) Some logic not clear for me.
55  JetScapeSignalManager::Instance()->CleanUp();
56  JetScapeTask::ClearTasks();
57 
58  VERBOSE(8) << hp.size();
59 }
60 
62  JSINFO << "Initialize JetEnergyLoss Manager ...";
63 
64  if (GetNumberOfTasks() < 1) {
65  JSWARN << " : No valid Energy Loss Manager modules found ...";
66  exit(-1);
67  }
68 
69  JSINFO << "Found " << GetNumberOfTasks()
70  << " Eloss Manager Tasks/Modules Initialize them ... ";
71  JetScapeTask::InitTasks();
72 
73  JSINFO << "Connect JetEnergyLossManager Signal to Hard Process ...";
74  JetScapeSignalManager::Instance()->ConnectGetHardPartonListSignal(
75  shared_from_this());
76 
77  // Set the pointer of JetEnergyLoss for making connections to hadronization module
78  for (auto it : GetTaskList()) {
79  if (dynamic_pointer_cast<JetEnergyLoss>(it))
80 
81  JetScapeSignalManager::Instance()->SetEnergyLossPointer(
82  dynamic_pointer_cast<JetEnergyLoss>(it));
83  }
84 }
85 
86 void JetEnergyLossManager::WriteTask(weak_ptr<JetScapeWriter> w) {
87  VERBOSE(8);
88  JetScapeTask::WriteTasks(w);
89 }
90 
91 void JetEnergyLossManager::Exec() {
92  VERBOSE(1) << "Run JetEnergyLoss Manager ...";
93  JSDEBUG << "Task Id = " << this_thread::get_id();
94 
95  if (GetNumberOfTasks() < 1) {
96  JSWARN << " : No valid Energy Loss Manager modules found ...";
97  exit(-1);
98  }
99 
100  // ----------------------------------
101  // Create needed copies and connect signal/slots accordingly ...
102 
103  if (GetGetHardPartonListConnected()) {
104  GetHardPartonList(hp);
105  VERBOSE(3) << " Number of Hard Partons = " << hp.size();
106  for (int i = 1; i < hp.size(); i++) {
107  JSDEBUG << "Create the " << i
108  << " th copy because number of intital hard partons = "
109  << hp.size();
110  // Add(make_shared<JetEnergyLoss>(*dynamic_pointer_cast<JetEnergyLoss>(GetTaskAt(0))));
111  auto jloss_org = dynamic_pointer_cast<JetEnergyLoss>(GetTaskAt(0));
112  auto jloss_copy = make_shared<JetEnergyLoss>(*jloss_org);
113 
114  // if there is a liquefier attached to the jloss module
115  // also attach the liquefier to the copied jloss modules
116  // to collect hydrodynamic source terms
117  if (!weak_ptr_is_uninitialized(jloss_org->get_liquefier())) {
118  jloss_copy->add_a_liquefier(jloss_org->get_liquefier().lock());
119  }
120  Add(jloss_copy);
121  }
122  }
123 
124  VERBOSE(3) << " Found " << GetNumberOfTasks()
125  << " Eloss Manager Tasks/Modules Execute them ... ";
126  JSDEBUG << "Check and Create Signal/Slots via JetScapeSignalManager instance "
127  "if needed ...";
128 
129  CreateSignalSlots();
130 
131  // ----------------------------------
132  // Copy Shower initiating partons to JetEnergyLoss tasks ...
133 
134  if (GetGetHardPartonListConnected() && hp.size() > 0) {
135  int n = 0;
136  for (auto it : GetTaskList()) {
137  dynamic_pointer_cast<JetEnergyLoss>(it)->AddShowerInitiatingParton(
138  hp.at(n));
139  n++;
140  }
141  }
142 
143  // ----------------------------------
144  // quick and dirty here, only include after further testing (flag in init xml files ...)
145  bool multiTask = false;
146 
147  // ----------------------------------
148  //Excute JetEnergyLoss tasks and their subtasks (done via signal/slot) by hand ...
149  //needed if only JetEnergyloss tasks in parallel (otherwise could be done via JetScapeTask, then every task a new thread for example)
150  // Of course now the number of threads if plainly given by the number of initial hard partons and can exceed the allowed # of threads >1000
151  // so to really do this properly one has to think about and limit to number of CPU's * N threads or something in that directions. See a quick attempt below.
152 
153  //DEBUG:
154  //unsigned num_cpus = thread::hardware_concurrency();
155  //cout << "Num of CPU's = " << num_cpus << " threads\n";
156 
157  if (multiTask) {
158  int nTasks = GetNumberOfTasks();
159  int nCPUs = thread::hardware_concurrency();
160 
161  vector<thread> threads;
162 
163  int nMaxThreads = nCPUs * 2;
164  int n = 0;
165 
166  VERBOSE(3) << " Use multi-threading: (max) # of threads = # of CPU's "
167  << nCPUs << " (found) * 2";
168 
169  for (auto it : GetTaskList()) {
170  if (it->GetActive()) {
171  threads.push_back(thread(&JetEnergyLoss::Exec,
172  dynamic_pointer_cast<JetEnergyLoss>(it)));
173  n++;
174  }
175  if (n == nMaxThreads) {
176  //DEBUGTHREAD<<n;
177  for (auto &th : threads)
178  th.join();
179  n = 0;
180  threads.clear();
181 
182  //DEBUG:
183  //std::this_thread::sleep_for(std::chrono::milliseconds(5000));
184  }
185  }
186 
187  if (nTasks < nMaxThreads) {
188  for (auto &th : threads)
189  th.join();
190  threads.clear();
191  }
192  }
193  // ----------------------------------
194  else
195  // Standard "serial" execution for the JetEnerguLoss (+submodules) task ...
196  JetScapeTask::ExecuteTasks();
197 
198  //Add acheck if the parton shower was actually created for the Modules ....
199  VERBOSE(3) << " " << GetNumberOfTasks()
200  << " Eloss Manager Tasks/Modules finished.";
201 }
202 
203 void JetEnergyLossManager::CreateSignalSlots() {
204  for (auto it : GetTaskList()) {
205  for (auto it2 : it->GetTaskList()) {
206  if (!dynamic_pointer_cast<JetEnergyLoss>(it2)->GetJetSignalConnected()) {
207  JetScapeSignalManager::Instance()->ConnectJetSignal(
208  dynamic_pointer_cast<JetEnergyLoss>(it2));
209  }
210  if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
211  ->GetEdensitySignalConnected()) {
212  JetScapeSignalManager::Instance()->ConnectEdensitySignal(
213  dynamic_pointer_cast<JetEnergyLoss>(it2));
214  }
215  if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
216  ->GetGetHydroCellSignalConnected()) {
217  JetScapeSignalManager::Instance()->ConnectGetHydroCellSignal(
218  dynamic_pointer_cast<JetEnergyLoss>(it2));
219  }
220  if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
221  ->GetGetHydroTau0SignalConnected()) {
222  JetScapeSignalManager::Instance()->ConnectGetHydroTau0Signal(
223  dynamic_pointer_cast<JetEnergyLoss>(it2));
224  }
225 
226  // between eloss modules and eloss
227  // check the signals itself, probably best via manager in the long run ...
228  if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
229  ->GetSentInPartonsConnected()) {
230  JetScapeSignalManager::Instance()->ConnectSentInPartonsSignal(
231  dynamic_pointer_cast<JetEnergyLoss>(it),
232  dynamic_pointer_cast<JetEnergyLoss>(it2));
233  }
234  }
235  auto liq_pt = dynamic_pointer_cast<JetEnergyLoss>(it)->get_liquefier();
236  if (!weak_ptr_is_uninitialized(liq_pt) &&
237  !liq_pt.lock()->get_GetHydroCellSignalConnected()) {
238  JetScapeSignalManager::Instance()->ConnectGetHydroCellSignal(
239  liq_pt.lock());
240  }
241  }
242 
243  JetScapeSignalManager::Instance()->PrintGetHydroCellSignalMap();
244  VERBOSE(8);
245  JetScapeSignalManager::Instance()->PrintSentInPartonsSignalMap();
246 }
247 
248 } // end namespace Jetscape