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

Last change on this file since 1350 was 807, checked in by garnier, 17 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.