/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWCore/Framework/interface/GlobalSchedule.h
219 строк
9 KB
Chris Jones
Various code improvements
13 июл 2025, 16:59
13 июл 2025, 16:59
0733ea5
Код
Авторство
О чём код?
#ifndef FWCore_Framework_GlobalSchedule_h #define FWCore_Framework_GlobalSchedule_h #include "DataFormats/Provenance/interface/ModuleDescription.h" #include "FWCore/Common/interface/FWCoreCommonFwd.h" #include "FWCore/Framework/interface/ExceptionActions.h" #include "FWCore/Framework/interface/ExceptionHelpers.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h" #include "FWCore/Framework/interface/OccurrenceTraits.h" #include "FWCore/Framework/interface/ProcessBlockPrincipal.h" #include "FWCore/Framework/interface/RunPrincipal.h" #include "FWCore/Framework/interface/WorkerManager.h" #include "FWCore/Framework/interface/maker/Worker.h" #include "FWCore/MessageLogger/interface/ExceptionMessages.h" #include "FWCore/ServiceRegistry/interface/GlobalContext.h" #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h" #include "FWCore/ServiceRegistry/interface/ServiceRegistryfwd.h" #include "FWCore/ServiceRegistry/interface/ServiceToken.h" #include "FWCore/Utilities/interface/Algorithms.h" #include "FWCore/Utilities/interface/BranchType.h" #include "FWCore/Utilities/interface/ConvertException.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/Utilities/interface/StreamID.h" #include "FWCore/Utilities/interface/propagate_const.h" #include "FWCore/Concurrency/interface/WaitingTaskHolder.h" #include "FWCore/Utilities/interface/thread_safety_macros.h" #include <exception> #include <map> #include <memory> #include <set> #include <string> #include <vector> #include <sstream> #include "boost/range/adaptor/reversed.hpp" namespace edm { class ExceptionCollector; class PreallocationConfiguration; class ModuleRegistry; class TriggerResultInserter; class PathStatusInserter; class EndPathStatusInserter; namespace maker { class ModuleHolder; } class GlobalSchedule { public: using vstring = std::vector<std::string>; using AllWorkers = std::vector<Worker*>; using WorkerPtr = std::shared_ptr<Worker>; using Wokers = std::vector<Worker*>; GlobalSchedule(std::shared_ptr<TriggerResultInserter> inserter, std::vector<edm::propagate_const<std::shared_ptr<PathStatusInserter>>>& pathStatusInserters, std::vector<edm::propagate_const<std::shared_ptr<EndPathStatusInserter>>>& endPathStatusInserters, std::shared_ptr<ModuleRegistry> modReg, std::vector<edm::ModuleDescription const*> const& modulesToUse, PreallocationConfiguration const& prealloc, ExceptionToActionTable const& actions, std::shared_ptr<ActivityRegistry> areg, ProcessContext const* processContext); GlobalSchedule(GlobalSchedule const&) = delete; template <typename T> void processOneGlobalAsync(WaitingTaskHolder holder, typename T::TransitionInfoType&, ServiceToken const& token, bool cleaningUpAfterException = false); void beginJob(ModuleRegistry&); void endJob(ExceptionCollector& collector, ModuleRegistry&); /// Return a vector allowing const access to all the /// ModuleDescriptions for this GlobalSchedule. /// *** N.B. *** Ownership of the ModuleDescriptions is *not* /// *** passed to the caller. Do not call delete on these /// *** pointers! std::vector<ModuleDescription const*> getAllModuleDescriptions() const; /// Return whether each output module has reached its maximum count. bool terminate() const; /// clone the type of module with label iLabel but configure with iPSet. void replaceModule(maker::ModuleHolder* iMod, std::string const& iLabel); /// Delete the module with label iLabel void deleteModule(std::string const& iLabel); /// returns the collection of pointers to workers AllWorkers const& allWorkers() const { return workerManagers_[0].allWorkers(); } private: /// returns the action table ExceptionToActionTable const& actionTable() const { return workerManagers_[0].actionTable(); } template <typename T> void preScheduleSignal(GlobalContext const*, ServiceToken const&); template <typename T> void postScheduleSignal(GlobalContext const*, ServiceWeakToken const&, std::exception_ptr&); void handleException(GlobalContext const*, ServiceWeakToken const&, bool cleaningUpAfterException, std::exception_ptr&); std::vector<WorkerManager> workerManagers_; std::vector<unsigned int> beginJobFailedForModule_; std::shared_ptr<ActivityRegistry> actReg_; // We do not use propagate_const because the registry itself is mutable. std::vector<edm::propagate_const<WorkerPtr>> extraWorkers_; ProcessContext const* processContext_; // The next 3 variables use the same naming convention, even though we have no intention // to ever have concurrent ProcessBlocks. They are all related to the number of // WorkerManagers needed for global transitions. unsigned int numberOfConcurrentLumis_; unsigned int numberOfConcurrentRuns_; static constexpr unsigned int numberOfConcurrentProcessBlocks_ = 1; }; template <typename T> void GlobalSchedule::processOneGlobalAsync(WaitingTaskHolder iHolder, typename T::TransitionInfoType& transitionInfo, ServiceToken const& token, bool cleaningUpAfterException) { auto const& principal = transitionInfo.principal(); // Caught exception is propagated via WaitingTaskHolder CMS_SA_ALLOW try { //need the doneTask to own the memory auto globalContext = std::make_shared<GlobalContext>(T::makeGlobalContext(principal, processContext_)); ServiceWeakToken weakToken = token; auto doneTask = make_waiting_task( [this, iHolder, cleaningUpAfterException, globalContext, weakToken](std::exception_ptr const* iPtr) mutable { std::exception_ptr excpt; if (iPtr) { excpt = *iPtr; // add context information to the exception and print message handleException(globalContext.get(), weakToken, cleaningUpAfterException, excpt); } postScheduleSignal<T>(globalContext.get(), weakToken, excpt); iHolder.doneWaiting(excpt); }); //make sure the task doesn't get run until all workers have beens started WaitingTaskHolder holdForLoop(*iHolder.group(), doneTask); CMS_SA_ALLOW try { preScheduleSignal<T>(globalContext.get(), token); unsigned int managerIndex = principal.index(); if constexpr (T::branchType_ == InRun) { managerIndex += numberOfConcurrentLumis_; } else if constexpr (T::branchType_ == InProcess) { managerIndex += (numberOfConcurrentLumis_ + numberOfConcurrentRuns_); } WorkerManager& workerManager = workerManagers_[managerIndex]; workerManager.resetAll(); ParentContext parentContext(globalContext.get()); // make sure the ProductResolvers know about their // workers to allow proper data dependency handling workerManager.setupResolvers(transitionInfo.principal()); auto& aw = workerManager.allWorkers(); for (Worker* worker : boost::adaptors::reverse(aw)) { worker->doWorkAsync<T>( holdForLoop, transitionInfo, token, StreamID::invalidStreamID(), parentContext, globalContext.get()); } } catch (...) { holdForLoop.doneWaiting(std::current_exception()); } } catch (...) { iHolder.doneWaiting(std::current_exception()); } } template <typename T> void GlobalSchedule::preScheduleSignal(GlobalContext const* globalContext, ServiceToken const& token) { if (actReg_) { try { ServiceRegistry::Operate op(token); convertException::wrap([this, globalContext]() { T::preScheduleSignal(actReg_.get(), globalContext); }); } catch (cms::Exception& ex) { exceptionContext(ex, *globalContext, "Handling pre signal, likely in a service function"); throw; } } } template <typename T> void GlobalSchedule::postScheduleSignal(GlobalContext const* globalContext, ServiceWeakToken const& weakToken, std::exception_ptr& excpt) { if (actReg_) { try { convertException::wrap([this, &weakToken, globalContext]() { ServiceRegistry::Operate op(weakToken.lock()); T::postScheduleSignal(actReg_.get(), globalContext); }); } catch (cms::Exception& ex) { if (not excpt) { exceptionContext(ex, *globalContext, "Handling post signal, likely in a service function"); excpt = std::current_exception(); } } } } } // namespace edm #endif