/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWCore/Framework/src/InputSource.cc
511 строк
22 KB
Chris Jones
Remove excessive recursion from InputSource::nextitemType_
29 июн 2026, 18:44
29 июн 2026, 18:44
3f2b42e
Код
Авторство
О чём код?
/*---------------------------------------------------------------------- ----------------------------------------------------------------------*/ #include "FWCore/Framework/interface/InputSource.h" #include "DataFormats/Provenance/interface/ProcessHistory.h" #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h" #include "DataFormats/Provenance/interface/ProductRegistry.h" #include "FWCore/Framework/interface/EventPrincipal.h" #include "FWCore/Framework/interface/ExceptionHelpers.h" #include "FWCore/Framework/interface/FileBlock.h" #include "FWCore/Framework/interface/InputSourceDescription.h" #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h" #include "FWCore/Framework/interface/ProcessBlockPrincipal.h" #include "FWCore/Framework/interface/RunPrincipal.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h" #include "FWCore/ServiceRegistry/interface/StreamContext.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/Utilities/interface/processGUID.h" #include "FWCore/Utilities/interface/TimeOfDay.h" #include <cassert> #include <fstream> #include <iomanip> namespace edm { namespace { std::string const& suffix(int count) { static std::string const st("st"); static std::string const nd("nd"); static std::string const rd("rd"); static std::string const th("th"); // *0, *4 - *9 use "th". int lastDigit = count % 10; if (lastDigit >= 4 || lastDigit == 0) return th; // *11, *12, or *13 use "th". if (count % 100 - lastDigit == 10) return th; return (lastDigit == 1 ? st : (lastDigit == 2 ? nd : rd)); } } // namespace InputSource::InputSource(ParameterSet const& pset, InputSourceDescription const& desc) : actReg_(desc.actReg_), maxEvents_(desc.maxEvents_), remainingEvents_(maxEvents_), maxLumis_(desc.maxLumis_), remainingLumis_(maxLumis_), readCount_(0), maxSecondsUntilRampdown_(desc.maxSecondsUntilRampdown_), processingMode_(RunsLumisAndEvents), moduleDescription_(desc.moduleDescription_), processHistoryRegistry_(new ProcessHistoryRegistry), branchIDListHelper_(desc.branchIDListHelper_), processBlockHelper_(desc.processBlockHelper_), processGUID_(edm::processGUID().toBinary()), time_(), newRun_(true), newLumi_(true), eventCached_(false), state_(), runAuxiliary_(), lumiAuxiliary_(), statusFileName_() { if (pset.getUntrackedParameter<bool>("writeStatusFile", false)) { std::ostringstream statusfilename; statusfilename << "source_" << getpid(); statusFileName_ = statusfilename.str(); } if (maxSecondsUntilRampdown_ > 0) { processingStart_ = std::chrono::steady_clock::now(); } std::string const defaultMode("RunsLumisAndEvents"); std::string const runMode("Runs"); std::string const runLumiMode("RunsAndLumis"); // The default value provided as the second argument to the getUntrackedParameter function call // is not used when the ParameterSet has been validated and the parameters are not optional // in the description. As soon as all primary input sources and all modules with a secondary // input sources have defined descriptions, the defaults in the getUntrackedParameterSet function // calls can and should be deleted from the code. std::string processingMode = pset.getUntrackedParameter<std::string>("processingMode", defaultMode); if (processingMode == runMode) { processingMode_ = Runs; } else if (processingMode == runLumiMode) { processingMode_ = RunsAndLumis; } else if (processingMode != defaultMode) { throw Exception(errors::Configuration) << "InputSource::InputSource()\n" << "The 'processingMode' parameter for sources has an illegal value '" << processingMode << "'\n" << "Legal values are '" << defaultMode << "', '" << runLumiMode << "', or '" << runMode << "'.\n"; } } InputSource::~InputSource() noexcept(false) {} void InputSource::fillDescriptions(ConfigurationDescriptions& descriptions) { ParameterSetDescription desc; desc.setUnknown(); descriptions.addDefault(desc); } void InputSource::prevalidate(ConfigurationDescriptions&) {} static std::string const kBaseType("Source"); std::string const& InputSource::baseType() { return kBaseType; } void InputSource::fillDescription(ParameterSetDescription& desc) { std::string defaultString("RunsLumisAndEvents"); desc.addUntracked<std::string>("processingMode", defaultString) ->setComment( "'RunsLumisAndEvents': process runs, lumis, and events.\n" "'RunsAndLumis': process runs and lumis (not events).\n" "'Runs': process runs (not lumis or events)."); desc.addUntracked<bool>("writeStatusFile", false) ->setComment("Write a status file. Intended for use by workflow management."); } // This next function is to guarantee that "runs only" mode does not return events or lumis, // and that "runs and lumis only" mode does not return events. // For input sources that are not random access (e.g. you need to read through the events // to get to the lumis and runs), this is all that is involved to implement these modes. // For input sources where events or lumis can be skipped, getNextItemType() should // implement the skipping internally, so that the performance gain is realized. // If this is done for a source, the 'while' blocks in this function will never be entered // for that source. InputSource::ItemTypeInfo InputSource::nextItemType_() { ItemTypeInfo itemTypeInfo = callWithTryCatchAndPrint<ItemTypeInfo>([this]() { return getNextItemType(); }, "Calling InputSource::getNextItemType"); while (itemTypeInfo.itemType() == ItemType::IsEvent && processingMode() == RunsAndLumis) { skipEvents(1); itemTypeInfo = callWithTryCatchAndPrint<ItemTypeInfo>( [this]() { return getNextItemType(); }, "Calling InputSource::getNextItemType looking for Run or Lumi"); } while ((itemTypeInfo == ItemType::IsLumi or itemTypeInfo == ItemType::IsEvent) && processingMode() == Runs) { skipEvents(1); itemTypeInfo = callWithTryCatchAndPrint<ItemTypeInfo>([this]() { return getNextItemType(); }, "Calling InputSource::getNextItemType looking for Run"); } return itemTypeInfo; } InputSource::ItemTypeInfo InputSource::nextItemType() { ItemType oldType = state_.itemType(); if (eventLimitReached()) { // If the maximum event limit has been reached, stop. state_ = ItemTypeInfo::isStop(); } else if (lumiLimitReached()) { // If the maximum lumi limit has been reached, stop // when reaching a new file, run, or lumi. if (oldType == ItemType::IsInvalid || oldType == ItemType::IsFile || oldType == ItemType::IsRun || processingMode() != RunsLumisAndEvents) { state_ = ItemTypeInfo::isStop(); } else { ItemTypeInfo newState = nextItemType_(); if (newState == ItemType::IsEvent) { assert(processingMode() == RunsLumisAndEvents); state_ = ItemTypeInfo::isEvent(); } else { state_ = ItemTypeInfo::isStop(); } } } else { ItemTypeInfo newState = nextItemType_(); if (newState.itemType() == ItemType::IsStop) { state_ = ItemTypeInfo::isStop(); } else if (newState.itemType() == ItemType::IsSynchronize) { state_ = ItemTypeInfo::isSynchronize(); } else if (newState.itemType() == ItemType::IsFile || oldType == ItemType::IsInvalid) { state_ = ItemTypeInfo::isFile(); } else if (newState.itemType() == ItemType::IsRun || oldType == ItemType::IsFile) { runAuxiliary_ = readRunAuxiliary(); state_ = (newState.itemType() == ItemType::IsRun) ? newState : ItemTypeInfo::isRun(); } else if (newState.itemType() == ItemType::IsLumi || oldType == ItemType::IsRun) { assert(processingMode() != Runs); lumiAuxiliary_ = readLuminosityBlockAuxiliary(); state_ = (newState.itemType() == ItemType::IsLumi) ? newState : ItemTypeInfo::isLumi(); } else { assert(processingMode() == RunsLumisAndEvents); state_ = ItemTypeInfo::isEvent(); } } if (state_.itemType() == ItemType::IsStop) { lumiAuxiliary_.reset(); runAuxiliary_.reset(); } return state_; } std::shared_ptr<LuminosityBlockAuxiliary> InputSource::readLuminosityBlockAuxiliary() { return callWithTryCatchAndPrint<std::shared_ptr<LuminosityBlockAuxiliary> >( [this]() { return readLuminosityBlockAuxiliary_(); }, "Calling InputSource::readLuminosityBlockAuxiliary_"); } std::shared_ptr<RunAuxiliary> InputSource::readRunAuxiliary() { return callWithTryCatchAndPrint<std::shared_ptr<RunAuxiliary> >([this]() { return readRunAuxiliary_(); }, "Calling InputSource::readRunAuxiliary_"); } void InputSource::doBeginJob(edm::ProductRegistry const& iReg) { this->beginJob(iReg); } void InputSource::doEndJob() { endJob(); } std::pair<SharedResourcesAcquirer*, std::recursive_mutex*> InputSource::resourceSharedWithDelayedReader() { return resourceSharedWithDelayedReader_(); } std::pair<SharedResourcesAcquirer*, std::recursive_mutex*> InputSource::resourceSharedWithDelayedReader_() { return std::pair<SharedResourcesAcquirer*, std::recursive_mutex*>(nullptr, nullptr); } void InputSource::registerProducts() {} // Return a dummy file block. std::shared_ptr<FileBlock> InputSource::readFile() { assert(state_.itemType() == ItemType::IsFile); assert(!limitReached()); return callWithTryCatchAndPrint<std::shared_ptr<FileBlock> >([this]() { return readFile_(); }, "Calling InputSource::readFile_"); } void InputSource::closeFile(FileBlock* fb, bool cleaningUpAfterException) { if (fb != nullptr) fb->close(); callWithTryCatchAndPrint<void>( [this]() { closeFile_(); }, "Calling InputSource::closeFile_", cleaningUpAfterException); return; } // Return a dummy file block. // This function must be overridden for any input source that reads a file // containing Products. std::shared_ptr<FileBlock> InputSource::readFile_() { return std::make_shared<FileBlock>(); } void InputSource::readRun(RunPrincipal& runPrincipal, HistoryAppender&) { RunSourceSentry sentry(*this, runPrincipal.index()); callWithTryCatchAndPrint<void>([this, &runPrincipal]() { readRun_(runPrincipal); }, "Calling InputSource::readRun_"); } void InputSource::readAndMergeRun(RunPrincipal& rp) { RunSourceSentry sentry(*this, rp.index()); callWithTryCatchAndPrint<void>([this, &rp]() { readRun_(rp); }, "Calling InputSource::readRun_"); } void InputSource::readLuminosityBlock(LuminosityBlockPrincipal& lumiPrincipal, HistoryAppender&) { LumiSourceSentry sentry(*this, lumiPrincipal.index()); callWithTryCatchAndPrint<void>([this, &lumiPrincipal]() { readLuminosityBlock_(lumiPrincipal); }, "Calling InputSource::readLuminosityBlock_"); if (remainingLumis_ > 0) { --remainingLumis_; } } void InputSource::readAndMergeLumi(LuminosityBlockPrincipal& lbp) { LumiSourceSentry sentry(*this, lbp.index()); callWithTryCatchAndPrint<void>([this, &lbp]() { readLuminosityBlock_(lbp); }, "Calling InputSource::readLuminosityBlock_"); if (remainingLumis_ > 0) { --remainingLumis_; } } void InputSource::fillProcessBlockHelper() { fillProcessBlockHelper_(); } bool InputSource::nextProcessBlock(ProcessBlockPrincipal& processBlockPrincipal) { return nextProcessBlock_(processBlockPrincipal); } void InputSource::readProcessBlock(ProcessBlockPrincipal& processBlockPrincipal) { ProcessBlockSourceSentry sentry(*this, processBlockPrincipal.processName()); callWithTryCatchAndPrint<void>([this, &processBlockPrincipal]() { readProcessBlock_(processBlockPrincipal); }, "Calling InputSource::readProcessBlock_"); } void InputSource::fillProcessBlockHelper_() {} bool InputSource::nextProcessBlock_(ProcessBlockPrincipal&) { return false; } void InputSource::readProcessBlock_(ProcessBlockPrincipal&) {} void InputSource::readRun_(RunPrincipal& runPrincipal) { // Note: For the moment, we do not support saving and restoring the state of the // random number generator if random numbers are generated during processing of runs // (e.g. beginRun(), endRun()) runPrincipal.fillRunPrincipal(processHistoryRegistry()); } void InputSource::readLuminosityBlock_(LuminosityBlockPrincipal& lumiPrincipal) { auto history = processHistoryRegistry().getMapped(lumiPrincipal.aux().processHistoryID()); lumiPrincipal.fillLuminosityBlockPrincipal(history); } void InputSource::readEvent(EventPrincipal& ep, StreamContext& streamContext) { assert(state_.itemType() == ItemType::IsEvent); assert(!eventLimitReached()); { // block scope, in order to issue the PostSourceEvent signal before calling postRead and issueReports EventSourceSentry sentry(*this, streamContext); callWithTryCatchAndPrint<void>([this, &ep]() { readEvent_(ep); }, "Calling InputSource::readEvent_"); } if (remainingEvents_ > 0) --remainingEvents_; ++readCount_; setTimestamp(ep.time()); issueReports(ep.id(), ep.streamID()); } bool InputSource::readEvent(EventPrincipal& ep, EventID const& eventID, StreamContext& streamContext) { bool result = false; if (not limitReached()) { // the Pre/PostSourceEvent signals should be generated only if the event is actually found. // this should be taken care of by an EventSourceSentry in the implementaion of readIt() //result = callWithTryCatchAndPrint<bool>( [this,&eventID,&ep](){ return readIt(eventID, ep); }, "Calling InputSource::readIt" ); result = readIt(eventID, ep, streamContext); if (result) { if (remainingEvents_ > 0) --remainingEvents_; ++readCount_; issueReports(ep.id(), ep.streamID()); } } return result; } void InputSource::skipEvents(int offset) { callWithTryCatchAndPrint<void>([this, &offset]() { skip(offset); }, "Calling InputSource::skip"); } bool InputSource::goToEvent(EventID const& eventID) { return callWithTryCatchAndPrint<bool>([this, &eventID]() { return goToEvent_(eventID); }, "Calling InputSource::goToEvent_"); } void InputSource::rewind() { state_ = ItemTypeInfo(); remainingEvents_ = maxEvents_; setNewRun(); setNewLumi(); resetEventCached(); callWithTryCatchAndPrint<void>([this]() { rewind_(); }, "Calling InputSource::rewind_"); } void InputSource::issueReports(EventID const& eventID, StreamID streamID) { if (isFwkInfoEnabled()) { LogFwkVerbatim("FwkReport") << "Begin processing the " << readCount_ << suffix(readCount_) << " record. Run " << eventID.run() << ", Event " << eventID.event() << ", LumiSection " << eventID.luminosityBlock() << " on stream " << streamID.value() << " at " << std::setprecision(3) << TimeOfDay(); } if (!statusFileName_.empty()) { std::ofstream statusFile(statusFileName_.c_str()); statusFile << eventID << " time: " << std::setprecision(3) << TimeOfDay() << '\n'; statusFile.close(); } // At some point we may want to initiate checkpointing here } bool InputSource::readIt(EventID const&, EventPrincipal&, StreamContext&) { throw Exception(errors::LogicError) << "InputSource::readIt()\n" << "Random access is not implemented for this type of Input Source\n" << "Contact a Framework Developer\n"; } void InputSource::setRun(RunNumber_t) { throw Exception(errors::LogicError) << "InputSource::setRun()\n" << "Run number cannot be modified for this type of Input Source\n" << "Contact a Framework Developer\n"; } void InputSource::setLumi(LuminosityBlockNumber_t) { throw Exception(errors::LogicError) << "InputSource::setLumi()\n" << "Luminosity Block ID cannot be modified for this type of Input Source\n" << "Contact a Framework Developer\n"; } void InputSource::skip(int) { throw Exception(errors::LogicError) << "InputSource::skip()\n" << "Random access are not implemented for this type of Input Source\n" << "Contact a Framework Developer\n"; } bool InputSource::goToEvent_(EventID const&) { throw Exception(errors::LogicError) << "InputSource::goToEvent_()\n" << "Random access is not implemented for this type of Input Source\n" << "Contact a Framework Developer\n"; return true; } void InputSource::rewind_() { throw Exception(errors::LogicError) << "InputSource::rewind()\n" << "Random access are not implemented for this type of Input Source\n" << "Contact a Framework Developer\n"; } void InputSource::decreaseRemainingEventsBy(int iSkipped) { if (-1 == remainingEvents_) { return; } if (iSkipped < remainingEvents_) { remainingEvents_ -= iSkipped; } else { remainingEvents_ = 0; } } void InputSource::doBeginRun(RunPrincipal& rp, ProcessContext const*) {} void InputSource::doBeginLumi(LuminosityBlockPrincipal& lbp, ProcessContext const*) {} bool InputSource::randomAccess() const { return callWithTryCatchAndPrint<bool>([this]() { return randomAccess_(); }, "Calling InputSource::randomAccess_"); } ProcessingController::ForwardState InputSource::forwardState() const { return callWithTryCatchAndPrint<ProcessingController::ForwardState>([this]() { return forwardState_(); }, "Calling InputSource::forwardState_"); } ProcessingController::ReverseState InputSource::reverseState() const { return callWithTryCatchAndPrint<ProcessingController::ReverseState>([this]() { return reverseState_(); }, "Calling InputSource::reverseState__"); } void InputSource::beginJob(ProductRegistry const&) {} void InputSource::endJob() {} bool InputSource::randomAccess_() const { return false; } ProcessingController::ForwardState InputSource::forwardState_() const { return ProcessingController::kUnknownForward; } ProcessingController::ReverseState InputSource::reverseState_() const { return ProcessingController::kUnknownReverse; } ProcessHistoryID const& InputSource::reducedProcessHistoryID() const { assert(runAuxiliary()); return processHistoryRegistry_->reducedProcessHistoryID(runAuxiliary()->processHistoryID()); } RunNumber_t InputSource::run() const { assert(runAuxiliary()); return runAuxiliary()->run(); } LuminosityBlockNumber_t InputSource::luminosityBlock() const { assert(luminosityBlockAuxiliary()); return luminosityBlockAuxiliary()->luminosityBlock(); } InputSource::EventSourceSentry::EventSourceSentry(InputSource const& source, StreamContext& sc) : source_(source), sc_(sc) { source.actReg()->preSourceSignal_.emit(sc_.streamID()); } InputSource::EventSourceSentry::~EventSourceSentry() { source_.actReg()->postSourceSignal_.emit(sc_.streamID()); } InputSource::LumiSourceSentry::LumiSourceSentry(InputSource const& source, LuminosityBlockIndex index) : source_(source), index_(index) { source_.actReg()->preSourceLumiSignal_.emit(index_); } InputSource::LumiSourceSentry::~LumiSourceSentry() { source_.actReg()->postSourceLumiSignal_.emit(index_); } InputSource::RunSourceSentry::RunSourceSentry(InputSource const& source, RunIndex index) : source_(source), index_(index) { source_.actReg()->preSourceRunSignal_.emit(index_); } InputSource::RunSourceSentry::~RunSourceSentry() { source_.actReg()->postSourceRunSignal_.emit(index_); } InputSource::ProcessBlockSourceSentry::ProcessBlockSourceSentry(InputSource const& source, std::string const& processName) : source_(source), processName_(processName) { source_.actReg()->preSourceProcessBlockSignal_.emit(); } InputSource::ProcessBlockSourceSentry::~ProcessBlockSourceSentry() { source_.actReg()->postSourceProcessBlockSignal_.emit(processName_); } InputSource::FileOpenSentry::FileOpenSentry(InputSource const& source, std::string const& lfn) : post_(source.actReg()->postOpenFileSignal_), lfn_(lfn) { source.actReg()->preOpenFileSignal_.emit(lfn); } InputSource::FileOpenSentry::~FileOpenSentry() { post_.emit(lfn_); } InputSource::FileCloseSentry::FileCloseSentry(InputSource const& source, std::string const& lfn) : post_(source.actReg()->postCloseFileSignal_), lfn_(lfn) { source.actReg()->preCloseFileSignal_.emit(lfn); } InputSource::FileCloseSentry::~FileCloseSentry() { post_.emit(lfn_); } } // namespace edm