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