-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Rivet ParticleLevelProducer and HTXS multi-threading #30888
Changes from 7 commits
4b098c7
fe60c1a
86e34d1
03bf652
7748360
ad8b62f
b053a1e
c2d8c19
313863a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,10 +33,6 @@ class HTXSRivetProducer : public edm::one::EDProducer<edm::one::WatchRuns, edm:: | |
: _hepmcCollection(consumes<HepMCProduct>(cfg.getParameter<edm::InputTag>("HepMCCollection"))), | ||
_lheRunInfo(consumes<LHERunInfoProduct, edm::InRun>(cfg.getParameter<edm::InputTag>("LHERunInfo"))) { | ||
usesResource("Rivet"); | ||
|
||
_HTXS = new Rivet::HiggsTemplateCrossSections(); | ||
|
||
_isFirstEvent = true; | ||
_prodMode = cfg.getParameter<string>("ProductionMode"); | ||
m_HiggsProdMode = HTXS::UNKNOWN; | ||
|
||
|
@@ -52,10 +48,9 @@ class HTXSRivetProducer : public edm::one::EDProducer<edm::one::WatchRuns, edm:: | |
edm::EDGetTokenT<edm::HepMCProduct> _hepmcCollection; | ||
edm::EDGetTokenT<LHERunInfoProduct> _lheRunInfo; | ||
|
||
Rivet::AnalysisHandler _analysisHandler; | ||
std::unique_ptr<Rivet::AnalysisHandler> _analysisHandler; | ||
Rivet::HiggsTemplateCrossSections* _HTXS; | ||
|
||
bool _isFirstEvent; | ||
std::string _prodMode; | ||
HTXS::HiggsProdMode m_HiggsProdMode; | ||
|
||
|
@@ -108,13 +103,14 @@ void HTXSRivetProducer::produce(edm::Event& iEvent, const edm::EventSetup&) { | |
} else if (nBs == 2 && nHs == 1 && nZs == 0) { | ||
m_HiggsProdMode = HTXS::BBH; | ||
} | ||
|
||
_HTXS->setHiggsProdMode(m_HiggsProdMode); | ||
} | ||
} | ||
|
||
if (_isFirstEvent) { | ||
_analysisHandler.addAnalysis(_HTXS); | ||
if (!_HTXS || !_HTXS->hasProjection("FS")) { | ||
delete _HTXS; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be deleted. It will be deleted when |
||
_analysisHandler = std::unique_ptr<Rivet::AnalysisHandler>(new Rivet::AnalysisHandler()); | ||
_HTXS = new Rivet::HiggsTemplateCrossSections(); | ||
_analysisHandler->addAnalysis(_HTXS); | ||
|
||
// set the production mode if not done already | ||
if (_prodMode == "GGF") | ||
|
@@ -152,8 +148,7 @@ void HTXSRivetProducer::produce(edm::Event& iEvent, const edm::EventSetup&) { | |
} | ||
|
||
// initialize rivet analysis | ||
_analysisHandler.init(*myGenEvent); | ||
_isFirstEvent = false; | ||
_analysisHandler->init(*myGenEvent); | ||
} | ||
|
||
// classify the event | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,9 +18,8 @@ using namespace Rivet; | |
|
||
ParticleLevelProducer::ParticleLevelProducer(const edm::ParameterSet& pset) | ||
: srcToken_(consumes<edm::HepMCProduct>(pset.getParameter<edm::InputTag>("src"))), | ||
rivetAnalysis_(new Rivet::RivetAnalysis(pset)) { | ||
pset_(pset) { | ||
usesResource("Rivet"); | ||
|
||
genVertex_ = reco::Particle::Point(0, 0, 0); | ||
|
||
produces<reco::GenParticleCollection>("neutrinos"); | ||
|
@@ -31,9 +30,6 @@ ParticleLevelProducer::ParticleLevelProducer(const edm::ParameterSet& pset) | |
produces<reco::GenParticleCollection>("consts"); | ||
produces<reco::GenParticleCollection>("tags"); | ||
produces<reco::METCollection>("mets"); | ||
|
||
analysisHandler_.setIgnoreBeams(true); | ||
analysisHandler_.addAnalysis(rivetAnalysis_); | ||
} | ||
|
||
void ParticleLevelProducer::addGenJet(Rivet::Jet jet, | ||
|
@@ -116,7 +112,17 @@ void ParticleLevelProducer::produce(edm::Event& event, const edm::EventSetup& ev | |
event.getByToken(srcToken_, srcHandle); | ||
|
||
const HepMC::GenEvent* genEvent = srcHandle->GetEvent(); | ||
analysisHandler_.analyze(*genEvent); | ||
|
||
if (!rivetAnalysis_ || !rivetAnalysis_->hasProjection("FS")) { | ||
delete rivetAnalysis_; | ||
rivetAnalysis_ = new Rivet::RivetAnalysis(pset_); | ||
analysisHandler_ = std::unique_ptr<Rivet::AnalysisHandler>(new Rivet::AnalysisHandler()); | ||
|
||
analysisHandler_->setIgnoreBeams(true); | ||
analysisHandler_->addAnalysis(rivetAnalysis_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the Does anything inside Or actually conversely, can it be "proven" that for a given I'm asking because we do not guarantee an instance of a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On a further thought, I suspect this approach won't work in general with TBB. The approach would probably work if each instance of the But we don't guarantee that. If two instances process the first event on the same thread, their There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Matti, I think the
Is there any way to provoke that behavior for testing? I modified this PR to re-init when the standard "FS" projection is not found. But I am not sure if that would solve the problem that you described. Cheers, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Markus,
That's good.
I don't, but to me the solution the authors outlined in https://gitlab.com/hepcedar/rivet/-/issues/84, i.e. each We don't need
With a minimal configuration of just the
Then it could happen that many or all of the
I suspect it will not solve that particular problem. Or at least I'd assume if two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Matti, I think the calls to getProjection (when a projection is applied) and hasProjection follow the same structure, see below. Best, This is the part of the code throwing the error: const Projection& ProjectionHandler::getProjection(const ProjectionApplier& parent, const string& name) const {
MSG_TRACE("Searching for child projection '" << name << "' of " << &parent);
NamedProjsMap::const_iterator nps = _namedprojs.find(&parent);
if (nps == _namedprojs.end()) {
std::ostringstream msg;
msg << "No projections registered for parent " << &parent;
throw Error(msg.str());
} called by ProjectionApplier/Analysis here: /// Get the named projection, specifying return type via a template argument.
/// @todo Add SFINAE to require that PROJ inherit from Projection
template <typename PROJ>
const PROJ& getProjection(const std::string& name) const {
const Projection& p = getProjHandler().getProjection(*this, name);
return pcast<PROJ>(p);
} The bool ProjectionHandler::hasProjection(const ProjectionApplier& parent, const string& name) const {
MSG_TRACE("Searching for child projection '" << name << "' of " << &parent);
NamedProjsMap::const_iterator nps = _namedprojs.find(&parent);
if (nps == _namedprojs.end()) return false;
NamedProjs::const_iterator np = nps->second.find(name);
return !(np == nps->second.end());
}
called by this function in ProjectionApplier/Analysis: /// Does this applier have a projection registered under the name @a name?
bool hasProjection(const std::string& name) const {
return getProjHandler().hasProjection(*this, name);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the behavior breaks already with /// Get a reference to the ProjectionHandler for this thread.
ProjectionHandler& getProjHandler() const {
return _projhandler;
} where ProjectionApplier::ProjectionApplier()
: _allowProjReg(true), _owned(false),
_projhandler(ProjectionHandler::getInstance())
{ } Therefore, if two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, and if we patch Rivet to use gettimeofday microseconds instead of the thread id? That should give as a unique ProjectionHandler for each stream.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would much rather see the "proper fix" suggested in https://gitlab.com/hepcedar/rivet/-/issues/84#note_341649903, i.e. each There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, let's see if that can be done, I hope there is no major roadblock for that. Otherwise, we may just make this a |
||
} | ||
|
||
analysisHandler_->analyze(*genEvent); | ||
|
||
// Convert into edm objects | ||
// Prompt neutrinos | ||
|
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.
It would be better if these were
std::unique_ptr
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 Chris, thank you for your suggestions but I get