New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GBRForest implementation added in RecoJets/JetProducers PileupJetIdAl… #15907
Conversation
@cmsbuild please test |
The tests are being triggered in jenkins. |
A new Pull Request was created by @romeof for CMSSW_8_1_X. It involves the following packages: RecoJets/JetProducers @cvuosalo, @slava77, @davidlange6 can you please review it and eventually sign? Thanks. cms-bot commands are list here #13028 |
adding @lgray since he knows on the egamma GBR forst that we started from |
@cmsbuild please test |
The tests are being triggered in jenkins. |
} | ||
tmpTMVAReader.AddSpectator( *it, variables_[ tmvaNames_[*it] ].first ); | ||
} | ||
reco::details::loadTMVAWeights(&tmpTMVAReader, tmvaMethod_.c_str(), tmvaEtaWeights_.at(v).c_str() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to wrap this call in a std::unique_ptrTMVA::IMethod, otherwise it will leak memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like in this line:
mIMethod = std::unique_ptr<TMVA::IMethod>( reco::details::loadTMVAWeights(mReader.get(), mMethod.c_str(), weightFile.c_str()) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exactly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Lindsey,
I have implemented std::unique_ptrTMVA::IMethod syntax. I can see it from
https://github.com/romeof/cmssw/blob/PileupJetID_GBRForest/RecoJets/JetProducers/src/PileupJetIdAlgo.cc
Is this ok?
tmpTMVAReader.AddSpectator( *it, variables_[ tmvaNames_[*it] ].first ); | ||
} | ||
reco::details::loadTMVAWeights(&tmpTMVAReader, tmvaMethod_.c_str(), tmvaEtaWeights_.at(v).c_str() ); | ||
etaReader_.push_back(std::unique_ptr<const GBRForest> ( new GBRForest( dynamic_cast<TMVA::MethodBDT*>( tmpTMVAReader.FindMVA(tmvaMethod_.c_str()) ) ) ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise, here and below it would be a good idea (if possible) to move all of this into a cache that is common across threads like I do for the EGM code. This would reduce the number of times you have to read in the configuration file and thus improve CMSSW startup time in multithreaded mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lgray could you point us to the relevant line in the EGM code that make this cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is an example of a cache: https://github.com/cms-sw/cmssw/blob/CMSSW_8_1_X/RecoParticleFlow/PFTracking/interface/ConvBremHeavyObjectCache.h
here is an example of using it: https://github.com/cms-sw/cmssw/blob/CMSSW_8_1_X/RecoParticleFlow/PFTracking/interface/PFElecTkProducer.h#L48-L61
Here's the relevant TWiki: https://twiki.cern.ch/twiki/bin/view/CMSPublic/FWMultithreadedFrameworkStreamModuleInterface#edm_GlobalCacheT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Lindsey,
do you have another example that may be more clear (to me)?
So far, I have used as a reference
https://github.com/cms-sw/cmssw/blob/CMSSW_7_6_X/RecoEgamma/ElectronIdentification/plugins/ElectronMVAEstimatorRun2Spring15NonTrig.cc#L151
but the new code seems more complicated (to me).
I would be glad if there is an implementation similar to what you mention in a file related to
https://github.com/cms-sw/cmssw/blob/CMSSW_7_6_X/RecoEgamma/ElectronIdentification/plugins/ElectronMVAEstimatorRun2Spring15NonTrig.cc#L151
If so, I can try to implement it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, so what I am thinking about is more along the lines of this:
https://github.com/cms-sw/cmssw/blob/CMSSW_8_1_X/RecoEgamma/EgammaTools/interface/MVAValueMapProducer.h
Which uses:
https://github.com/cms-sw/cmssw/blob/CMSSW_8_1_X/RecoEgamma/EgammaTools/interface/MVAObjectCache.h
As a global cache and then finally that global cache stores pointers to the MVAs which derive from the base class here:
https://github.com/cms-sw/cmssw/blob/CMSSW_8_1_X/RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romeof: What is being done about using a global cache for this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to study this syntax before. It is completely new to me and I am not a guru of programming :-( This may take sometime, not sure how much yet.
@lgray: For me to understand, could you comment further on what you mean by "This would reduce the number of times you have to read in the configuration file"? It assumes that there are different MVA configurations or it is for the same MVA configuration for different events? By "thread" do you mean a call to an MVA configuration? Thanks and sorry for naive questions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, since the producer that holds this algorithm is edm::stream it gets replicated for each thread (by thread I mean a thread on a processor) for CMSSW. Therefore if you run with four threads you have to build this algorithm four times. As it is implemented presently that means reading the MVA file and created four instances of the MVA which can blow up memory and start up time.
Using the global cache solves this problem permanently by only ever needing to build the MVAs once and sharing the MVAs among the threads.
@@ -37,6 +37,8 @@ class PileupJetIdAlgo { | |||
float jec, const reco::Vertex *, const reco::VertexCollection &, double rho); | |||
|
|||
void set(const PileupJetIdentifier &); | |||
std::unique_ptr<const GBRForest> getMVA(std::vector<std::string>, const std::string &); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first parameter should actually be a const reference (I forgot to say so in my original coment) to avoid copying overhead:
std::unique_ptr<const GBRForest> getMVA(const std::vector<std::string> &, const std::string &);
Same for getMVAvars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi cvuosalo,
thanks for your last suggestions, which I implemented in the code.
If it is ok now, I will try to get a look at the global cache implementation.
Pull request #15907 was updated. @cmsbuild, @cvuosalo, @slava77, @davidlange6 can you please check and sign again. |
@cmsbuild please test |
The tests are being triggered in jenkins. |
+1 Changing from TMVA to GBRForest in PileupJetIdAlgo. There should be no change in monitored quantities. The code changes are satisfactory, and Jenkins tests against baseline CMSSW_8_1_X_2016-09-27-1100 show no significant differences, as expected. A test of workflow 136.731_RunSinglePh2016B with 200 events against baseline CMSSW_8_1_X_2016-09-18-0000 also shows no significant differences. Memory usage shows no significant change, for either one or four threads:
|
This pull request is fully signed and it will be integrated in one of the next CMSSW_8_1_X IBs (tests are also fine). This pull request requires discussion in the ORP meeting before it's merged. @slava77, @davidlange6, @smuzaffar |
@cvuosalo Did you happen to also look at the processing time with multiple threads? It would be interesting to know if this change can indeed speed up MiniAOD production. |
You'll need to look at the time spent before the first event. That's the On Tue, Sep 27, 2016 at 4:06 PM, ahinzmann notifications@github.com wrote:
|
On 9/27/16 1:59 PM, Carl Vuosalo wrote:
IIRC, we should see a decrease by using GBR. both 1-thread and 4-thread tests show decrease in RSS: 1-thread down by 65MB
|
@ahinzmann: My measurements don't show any performance improvement, but I'm not sure of the correct technique to specifically measure the improvement provided by using GBRForest. |
+1 |
igprof memory profiling shows some improvement. Checking MEM_LIVE between baseline CMSSW_8_1_X_2016-09-18-0000 and this PR shows the MVA-reading memory usage for PileUpJetIdAlgo goes from rank 426 and 1.41% of total memory down to rank 1395 and 0.21%. |
GBRForest implementation has been added in the PileupJetIdAlgo class of the package RecoJets/JetProducers. This method is used to book the reader for the mva pileup jet id discriminator.