ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParRunManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ParRunManager.cc
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 //
29 //
30 #ifdef G4USE_TOPC
31 
32 #include "G4Timer.hh"
33 
34 
35 
36 #include "G4RunManager.hh"
37 
38 #include "Randomize.hh"
39 #include "G4Run.hh"
40 #include "G4RunMessenger.hh"
42 #include "G4VUserPhysicsList.hh"
43 #include "G4UserRunAction.hh"
45 #include "G4GeometryManager.hh"
46 #include "G4SDManager.hh"
48 #include "G4VPhysicalVolume.hh"
49 #include "G4ApplicationState.hh"
50 #include "G4StateManager.hh"
51 #include "G4VPersistencyManager.hh"
52 #include "G4UImanager.hh"
53 #include "G4ParticleTable.hh"
54 #include "G4ProcessTable.hh"
55 #include "G4UnitsTable.hh"
56 #include "G4VVisManager.hh"
57 
58 #include "ParRunManager.hh"
59 //include file for marshaling structures
60 #include "MarshaledG4HCofThisEvent.h"
61 
62 #include "G4ios.hh"
63 
64 #include <sstream> // Geant4 8.x and beyond
65 
66 using namespace CLHEP;
67 
68 /*
69  * The TopC call backs are implemented by using the 5 static data members to store
70  * the data and using the 3 static member functions to point to the corresponding
71  * functions of the singleton class instance.
72  */
78 
79 //cross-context variables
80 static long* g_Seeds;
81 
82 // TOP-C callbacks functions
83 TOPC_BUF ParRunManager::MyDoEvent( void *input_buf ) {
84  return myRunManager->DoEvent(input_buf);
85 }
86 TOPC_ACTION ParRunManager::MyCheckEventResult( void * input_buf, void *buf ) {
87  return myRunManager->CheckEventResult(input_buf, buf);
88 }
89 
90 
91 static void trace_event_input( void */*input*/ ) {
92  //G4cout << "Event " << *(G4int *)input << G4endl;
93 }
94 
95 /*
96  * DoEventLoop is the most important piece in RunManager class to control the program runs,
97  * this is where we embed the TopC parallelism callbacks.
98  */
99 void ParRunManager::DoEventLoop( G4int n_event, const char* macroFile, G4int n_select )
100 {
101  TOPC_OPT_trace_input = trace_event_input;
102 
104 
105 #ifdef G4_ORIGINAL
106  cout << "ParRunManager::DoEventLoop" << endl;
107  G4RunManager::DoEventLoop(n_event, macroFile, n_select);
108  return;
109 #endif
110 
111  if(verboseLevel>0)
112  { timer->Start(); }
113 
114  G4String msg;
115  if(macroFile!=0)
116  {
117  if(n_select<0) n_select = n_event;
118  msg = "/control/execute ";
119  msg += macroFile;
120  }
121  else
122  { n_select = -1; }
123 
124 
125  // BeginOfEventAction() and EndOfEventAction() would normally be
126  // called inside G4EventManager::ProcessOneEvent() in ParRunManager::DoEvent
127  // on slave. Since this is often where hits are collected and where
128  // histogram data is first stored, must do it
129  // on master instead, to process hits. So, set user event action to NULL.
130  // Keep private copy, and execute it in CheckTaskResult().
131  // If user later does: SetUserAction( (G4UserEventAction *)NULL );
132  // we won't notice and copy it to origUserEventAction.
133  if ( eventManager->GetUserEventAction() ) {
134  origUserEventAction = eventManager->GetUserEventAction();
135  SetUserAction( (G4UserEventAction *)0 );
136  }
137 
138  // Make these variables accessible to TOP-C callback functions
139  ImportDoEventLoopLocals( stateManager, n_event, n_select, msg );
140 
141 
142  // Setup random seeds for each slave
143  g_Seeds = (long*)calloc(n_event, sizeof(long));
144 
145  for( G4int i_event=0; i_event<n_event; i_event++ )
146  {
147  g_Seeds[i_event] = (long) (100000000L * HepRandom::getTheGenerator()->flat());
148  }
149 
150  // This is where all the parallelism occurs
151  TOPC_raw_begin_master_slave(MyDoEvent, MyCheckEventResult, NULL);
152 
153  if(TOPC_is_master()){
154  for(G4int i_event=0; i_event<n_event; i_event++ )
155  {
156  TOPC_raw_submit_task_input(TOPC_MSG( &i_event, sizeof(G4int)));
157  if (runAborted) break;
158  }
159  }
160  TOPC_raw_end_master_slave();
161 
162  free(g_Seeds);
163 
164  if ( verboseLevel > 0 ) {
165  timer->Stop();
166  G4cout << "Run terminated." << G4endl;
167  G4cout << "Run Summary" << G4endl;
168  if ( runAborted ) {
169  G4cout << " Run Aborted." << G4endl;
170  } else {
171  G4cout << " Number of events processed : " << n_event << G4endl;
172  }
173  G4cout << " " << *timer << G4endl;
174  }
175 }
176 
177 static MarshaledG4HCofThisEvent *aMarshaledObj = NULL;
178 
179 TOPC_BUF ParRunManager::DoEvent( void *input_buf )
180 {
181  static
182  G4int i_event;
183  memcpy(&i_event, input_buf, sizeof(G4int));
184  HepRandom::setTheSeed(g_Seeds[i_event]);
185 
186  // removed for Geant4.6
187  // stateManager->SetNewState(G4State_EventProc);
188 
189  currentEvent = GenerateEvent(i_event);
190  eventManager->ProcessOneEvent(currentEvent);
191 
192  G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
193 
194  if(aMarshaledObj) delete aMarshaledObj;
195  aMarshaledObj = new MarshaledG4HCofThisEvent(HCE);
196 
197  // removed for Geant4.6
198  //stateManager->SetNewState( G4State_GeomClosed );
199  StackPreviousEvent( currentEvent );
200  currentEvent = 0;
201  return TOPC_MSG( aMarshaledObj->getBuffer(), aMarshaledObj->getBufferSize());
202 }
203 
204 
205 TOPC_ACTION ParRunManager::CheckEventResult( void * input_buf, void *output_buf )
206 {
207  G4int i_event;
208  memcpy(&i_event, input_buf, sizeof(G4int));
209 
210  // removed for Geant4.6
211  //stateManager->SetNewState(G4State_EventProc);
212  // Geant4 6.0 requires the state to be G4State_GeomClosed
213  // before calling EventManager::ProcessOneEvent(..)
214 
215  if ( !userPrimaryGeneratorAction ) {
216  G4Exception("ParRunManager::CheckEventResult", "InvalidSetup",
218  "G4VUserPrimaryGeneratorAction is not defined.");
219  }
220 
221  //This creates a trivial event in lieu of GenerateEvent(i_event);
222  currentEvent = new G4Event( i_event );
223 
224  //
225  SetUserAction( (G4UserEventAction *)0 );
226 
227  // When Geant4 4.0 sees empty event, it still calls userStackingAction.
228  // On master, only trivial events exist, so we delete userStackingAction
229  SetUserAction( (G4UserStackingAction*)0 );
230  eventManager->ProcessOneEvent( currentEvent ); // Processing the trivial event
231 
232  // Called with output_buf and no size, creates object for unmarshaling
233  // using marshalgen
234  MarshaledG4HCofThisEvent marshaledObj( output_buf );
235  G4HCofThisEvent* oldCE = currentEvent->GetHCofThisEvent();
237 
238  marshaledObj.unmarshalTo(HCE);
239  if(oldCE) delete(oldCE);
240 
241  currentEvent->SetHCofThisEvent(HCE);
242 
243  // Original UserEventAction was saved and set to NULL. Do it now on master.
244  HepRandom::setTheSeed(g_Seeds[i_event]);
245  if ( origUserEventAction )
246  origUserEventAction->BeginOfEventAction( currentEvent );
247 
248  if ( origUserEventAction )
249  origUserEventAction->EndOfEventAction( currentEvent );
250 
251  AnalyzeEvent(currentEvent);
252 
253  if (i_event<n_select) G4UImanager::GetUIpointer()->ApplyCommand(msg);
254  // Geant4 6.0 requires the state to be G4State_GeomClosed
255  stateManager->SetNewState( G4State_GeomClosed );
256  StackPreviousEvent(currentEvent);
257  currentEvent = 0;
258  return NO_ACTION;
259 }
260 
261 #endif /* G4USE_TOPC */