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