source: trunk/examples/extended/parallel/ParN02/src/ParRunManager.cc @ 1346

Last change on this file since 1346 was 807, checked in by garnier, 16 years ago

update

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