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

Last change on this file since 1191 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
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.