source: trunk/examples/extended/parallel/ParN04/src/ParRunManager.cc

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