Geant4  9.6.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 //
28 //
29 #ifdef G4USE_TOPC
30 
31 #include "G4Timer.hh"
32 
33 #include "G4RunManager.hh"
34 
35 #include "Randomize.hh"
36 #include "G4Run.hh"
37 #include "G4RunMessenger.hh"
39 #include "G4VUserPhysicsList.hh"
40 #include "G4UserRunAction.hh"
42 #include "G4GeometryManager.hh"
43 #include "G4SDManager.hh"
45 #include "G4VPhysicalVolume.hh"
46 #include "G4ApplicationState.hh"
47 #include "G4StateManager.hh"
48 #include "G4VPersistencyManager.hh"
49 #include "G4UImanager.hh"
50 #include "G4ParticleTable.hh"
51 #include "G4ProcessTable.hh"
52 #include "G4UnitsTable.hh"
53 #include "G4VVisManager.hh"
54 
55 #include "ParRunManager.hh"
56 //include file for marshaling structures
57 #include "MarshaledG4HCofThisEvent.h"
58 
59 #include "G4ios.hh"
60 
61 #include <sstream> // Geant4 8.x and beyond
62 
63 using namespace CLHEP;
64 
65 /*
66  * The TopC call backs are implemented by using the 5 static data members to store
67  * the data and using the 3 static member functions to point to the corresponding
68  * functions of the singleton class instance.
69  */
70 G4StateManager* ParRunManager::stateManager;
71 G4int ParRunManager::n_event;
72 G4int ParRunManager::n_select;
73 G4String ParRunManager::msg;
74 ParRunManager* ParRunManager::myRunManager = 0;
75 
76 //cross-context variables
77 static long* g_Seeds;
78 
79 // TOP-C callbacks functions
80 TOPC_BUF ParRunManager::MyDoEvent( void *input_buf ) {
81  return myRunManager->DoEvent(input_buf);
82 }
83 TOPC_ACTION ParRunManager::MyCheckEventResult( void * input_buf, void *buf ) {
84  return myRunManager->CheckEventResult(input_buf, buf);
85 }
86 
87 
88 static void trace_event_input( void *input ) {
89  //G4cout << "Event " << *(G4int *)input << G4endl;
90  input = NULL; // Stop C++ from complaining about unused parameter
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  G4int i_event;
144  for( 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  G4int i_event;
154  for( 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 */