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