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 
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  input = NULL; // Stop C++ from complaining about unused parameter
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  G4int i_event;
146  for( 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  G4int i_event;
156  for( i_event=0; i_event<n_event; i_event++ )
157  {
158  TOPC_raw_submit_task_input(TOPC_MSG( &i_event, sizeof(G4int)));
159  if (runAborted) break;
160  }
161  }
162  TOPC_raw_end_master_slave();
163 
164  free(g_Seeds);
165 
166  if ( verboseLevel > 0 ) {
167  timer->Stop();
168  G4cout << "Run terminated." << G4endl;
169  G4cout << "Run Summary" << G4endl;
170  if ( runAborted ) {
171  G4cout << " Run Aborted." << G4endl;
172  } else {
173  G4cout << " Number of events processed : " << n_event << G4endl;
174  }
175  G4cout << " " << *timer << G4endl;
176  }
177 }
178 
179 static MarshaledG4HCofThisEvent *aMarshaledObj = NULL;
180 
181 TOPC_BUF ParRunManager::DoEvent( void *input_buf )
182 {
183  static
184  G4int i_event;
185  memcpy(&i_event, input_buf, sizeof(G4int));
186  HepRandom::setTheSeed(g_Seeds[i_event]);
187 
188  // removed for Geant4.6
189  // stateManager->SetNewState(G4State_EventProc);
190 
191  currentEvent = GenerateEvent(i_event);
192  eventManager->ProcessOneEvent(currentEvent);
193 
194  G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
195 
196  if(aMarshaledObj) delete aMarshaledObj;
197  aMarshaledObj = new MarshaledG4HCofThisEvent(HCE);
198 
199  // removed for Geant4.6
200  //stateManager->SetNewState( G4State_GeomClosed );
201  StackPreviousEvent( currentEvent );
202  currentEvent = 0;
203  return TOPC_MSG( aMarshaledObj->getBuffer(), aMarshaledObj->getBufferSize());
204 }
205 
206 
207 TOPC_ACTION ParRunManager::CheckEventResult( void * input_buf, void *output_buf )
208 {
209  G4int i_event;
210  memcpy(&i_event, input_buf, sizeof(G4int));
211 
212  // removed for Geant4.6
213  //stateManager->SetNewState(G4State_EventProc);
214  // Geant4 6.0 requires the state to be G4State_GeomClosed
215  // before calling EventManager::ProcessOneEvent(..)
216 
217  if ( !userPrimaryGeneratorAction ) {
218  G4Exception("ParRunManager::CheckEventResult", "InvalidSetup",
220  "G4VUserPrimaryGeneratorAction is not defined.");
221  }
222 
223  //This creates a trivial event in lieu of GenerateEvent(i_event);
224  currentEvent = new G4Event( i_event );
225 
226  //
227  SetUserAction( (G4UserEventAction *)0 );
228 
229  // When Geant4 4.0 sees empty event, it still calls userStackingAction.
230  // On master, only trivial events exist, so we delete userStackingAction
231  SetUserAction( (G4UserStackingAction*)0 );
232  eventManager->ProcessOneEvent( currentEvent ); // Processing the trivial event
233 
234  // Called with output_buf and no size, creates object for unmarshaling
235  // using marshalgen
236  MarshaledG4HCofThisEvent marshaledObj( output_buf );
237  G4HCofThisEvent* oldCE = currentEvent->GetHCofThisEvent();
239 
240  marshaledObj.unmarshalTo(HCE);
241  if(oldCE) delete(oldCE);
242 
243  currentEvent->SetHCofThisEvent(HCE);
244 
245  // Original UserEventAction was saved and set to NULL. Do it now on master.
246  HepRandom::setTheSeed(g_Seeds[i_event]);
247  if ( origUserEventAction )
248  origUserEventAction->BeginOfEventAction( currentEvent );
249 
250  if ( origUserEventAction )
251  origUserEventAction->EndOfEventAction( currentEvent );
252 
253  AnalyzeEvent(currentEvent);
254 
255  if (i_event<n_select) G4UImanager::GetUIpointer()->ApplyCommand(msg);
256  // Geant4 6.0 requires the state to be G4State_GeomClosed
257  stateManager->SetNewState( G4State_GeomClosed );
258  StackPreviousEvent(currentEvent);
259  currentEvent = 0;
260  return NO_ACTION;
261 }
262 
263 #endif /* G4USE_TOPC */