Dear G4FastSimulation or Tracking Experts,
The CMS experiment has developed and tested fast simulation models
(named GflashEMShowerModel and GflashHadronShowerModel) for the CMS calorimeter
simulation based on G4VFastSimulationModel and tuned to various test beam data
taken recently as well as geant4. However, we are experiencing a serious memory
leak from our hadronic model while testing a full chain of simulation for
aiming a large scale production. Quantitatively the amount of memory leakage
when using geant4 and GflashHadronShowerModel together is around 120 MB for
100 ttbar events while the baseline memory consumption is only 50 MB when using
the full geant4. We believe that this memory leakage comes from a possible
ill-implementation of our hadronic wrapper process even though it has
functionally worked for its own purpose of the hadronic shower
parameterization. Even though the source of the memory leakage may not be
directly from the core geant4 routines, we would like to have your suggestions
or comments on what we may try to resolve the issue.
To have more information how we use the G4WrapperProcess for our
GflashHadronWrapperProcess in conjunction with GflashHadronShowerModel,
you may refer to our latest code from the cms lxr:
http://cmslxr.fnal.gov/lxr/source/SimG4Core/GFlash/src/GflashHadronShowerModel.cc
http://cmslxr.fnal.gov/lxr/source/SimG4Core/GFlash/src/GflashHadronWrapperProcess.cc
Following is a short description of underlying logic flow of these two
routines;
1) the first time call for GflashHadronShowerModel (i.e., fParameterisation
process) is simply by-passed when testing ``GPIL for PostStep'' in
G4SteppingManager (i.e., when testing fCurrentProcess->PostStepGPIL in
G4SteppingManager2.cc)
2) GflashHadronWrapperProcess (which is now a wrapper process for the selected
process) is testing ``GPIL for PostStep'' again only for the
fParameterisation process whether dynamic conditions for
GflashHadronShowerModel::ModelTrigger is met after performing the
PostStepDoIt of the original process.
3) If GflashHadronShowerModel is selected as an ``ExclusivelyForced'' process,
then we invoke PostStepDoIt for the fParameterisation process and return
paticleChange from GflashHadronWrapperProcess.
There are redundant procedures of tracking in this logic flow, but at least the
wrapper has worked out as implemented for the rest of the parameterization
process (i.e., making hits and killing the track). Concerning to the memory
leakage issue, a relevant question is whether switching the process from the
original process (hadron inelastic interaction) to the parameterization process
during the stepping (i.e., at the particular stage of InvokePostStepDoItProcs
in G4SteppingManager).
Following lines of simplified code may be a snippet of the wrapper process, in
which whether the second ``particleChange'' below the second commented line is
legitimated or not:
G4VParticleChange* GflashHadronWrapperProcess::PostStepDoIt(
const G4Track& track, const G4Step& step) {
//1. invoke PostStepDoIt for the original process
particleChange = pRegProcess->PostStepDoIt(track, step);
for(G4int ipm = 0 ; ipm < fProcessVector->entries() ; ipm++) {
fProcess = (*fProcessVector)(ipm);
if ( fProcess->GetProcessType() == fParameterisation ) {
testGPIL = fProcess->PostStepGPIL(track,fStepLength,&fForceCondition );
if( fForceCondition == ExclusivelyForced) {
particleChange->Clear();
//2. invoke PostStepDoIt for fParameterisation process
particleChange = fProcess->PostStepDoIt(track,step);
}
}
}
return particleChange;
}
Our various tests show that invoking the second PostStepDoIt is directly
related to the memory leakage in question. We also tested alternative
implementations avoiding a possible mangle between the original process and
the parameterization process;
1) instead of the invoking the second PostStepDoIt, we substitute all
implementations of GflashHadronShowerModel::DoIt to the line in question.
In this case, the memory leak happens if we kill the track, i.e., including
following two lines which is equivalent to fastStep.KillPrimaryTrack(),
(const_cast<G4Track *> (&track))->SetTrackStatus( fStopAndKill );
(const_cast<G4Track *> (&track))->SetKineticEnergy( 0.0);
2) an implementation without the wrapper, but invoking PostStepDoIt of the
original process locally inside GflashHadronShowerModel::ModelTrigger
to access information of secondary tracks. Again, invoking the particular
call of the line,
particleChange = fProcess->PostStepDoIt(...);
is directly responsible for the memory leak.
Our question is how memories of the original process including the
particleChange are cleaned up if we discard the process and switch to
a new process. Or is the switching processes during stepping not allowed
at all?
Sorry for too much technical details, but please let us know if we did not
explain our problem clearly or did not provide enough information.
Thank you for your help or any comment.
Regards,
---Soon Yung Jun
for the calorimeter task force of CMS
|