Skip to content

Commit 6d1850c

Browse files
committed
Added additional signals related to job startup
Provide signals around more of the framework startup work.
1 parent a387ab0 commit 6d1850c

File tree

3 files changed

+229
-68
lines changed

3 files changed

+229
-68
lines changed

FWCore/Framework/src/EventProcessor.cc

Lines changed: 100 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
#include "FWCore/AbstractServices/interface/RandomNumberGenerator.h"
5555
#include "FWCore/AbstractServices/interface/RootHandlers.h"
56+
#include "FWCore/AbstractServices/interface/TimingServiceBase.h"
5657

5758
#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
5859
#include "FWCore/ServiceRegistry/interface/Service.h"
@@ -109,6 +110,18 @@ namespace {
109110
private:
110111
edm::SerialTaskQueue& queue_;
111112
};
113+
114+
template <typename T>
115+
requires std::is_invocable_v<T>
116+
struct Guard {
117+
Guard(T&& signal) : final_(std::forward<T>(signal)) {}
118+
~Guard() { final_(); }
119+
T final_;
120+
};
121+
template <typename T>
122+
Guard<T> makeGuard(T&& signal) {
123+
return Guard{std::forward<T>(signal)};
124+
}
112125
} // namespace
113126

114127
namespace edm {
@@ -423,9 +436,11 @@ namespace edm {
423436
ScheduleItems items;
424437

425438
//initialize the services
439+
edm::TimingServiceBase::servicesStarting();
426440
auto& serviceSets = processDesc->getServicesPSets();
427441
ServiceToken token = items.initServices(serviceSets, *parameterSet, iToken, iLegacy);
428442
serviceToken_ = items.addTNS(*parameterSet, token);
443+
items.actReg_->postServicesConstructionSignal_();
429444

430445
//make the services available
431446
ServiceRegistry::Operate operate(serviceToken_);
@@ -440,9 +455,13 @@ namespace edm {
440455
std::shared_ptr<CommonParams> common(items.initMisc(*parameterSet));
441456

442457
// intialize the event setup provider
443-
ParameterSet const& eventSetupPset(optionsPset.getUntrackedParameterSet("eventSetup"));
444-
esp_ = espController_->makeProvider(
445-
*parameterSet, items.actReg_.get(), &eventSetupPset, maxConcurrentIOVs, dumpOptions);
458+
items.actReg_->preEventSetupModulesConstructionSignal_();
459+
{
460+
auto guard = makeGuard([&items]() { items.actReg_->postEventSetupModulesConstructionSignal_(); });
461+
ParameterSet const& eventSetupPset(optionsPset.getUntrackedParameterSet("eventSetup"));
462+
esp_ = espController_->makeProvider(
463+
*parameterSet, items.actReg_.get(), &eventSetupPset, maxConcurrentIOVs, dumpOptions);
464+
}
446465

447466
// initialize the looper, if any
448467
if (!loopers.empty()) {
@@ -497,6 +516,8 @@ namespace edm {
497516
group.wait();
498517
items.preg()->addFromInput(input_->productRegistry());
499518
{
519+
items.actReg_->preFinishScheduleSignal_();
520+
auto guard = makeGuard([&items]() { items.actReg_->postFinishScheduleSignal_(); });
500521
auto const& tns = ServiceRegistry::instance().get<service::TriggerNamesService>();
501522
schedule_ = items.finishSchedule(
502523
std::move(*madeModules), *parameterSet, tns, preallocations_, &processContext_, *processBlockHelper_);
@@ -524,44 +545,48 @@ namespace edm {
524545

525546
FDEBUG(2) << parameterSet << std::endl;
526547

527-
principalCache_.setNumberOfConcurrentPrincipals(preallocations_);
528-
for (unsigned int index = 0; index < preallocations_.numberOfStreams(); ++index) {
529-
// Reusable event principal
530-
auto ep = std::make_shared<EventPrincipal>(preg(),
548+
{
549+
actReg_->prePrincipalsCreationSignal_();
550+
auto guard = makeGuard([this]() { actReg_->postPrincipalsCreationSignal_(); });
551+
principalCache_.setNumberOfConcurrentPrincipals(preallocations_);
552+
for (unsigned int index = 0; index < preallocations_.numberOfStreams(); ++index) {
553+
// Reusable event principal
554+
auto ep = std::make_shared<EventPrincipal>(preg(),
555+
productResolversFactory::makePrimary,
556+
branchIDListHelper(),
557+
thinnedAssociationsHelper(),
558+
*processConfiguration_,
559+
historyAppender_.get(),
560+
index,
561+
&*processBlockHelper_);
562+
principalCache_.insert(std::move(ep));
563+
}
564+
565+
for (unsigned int index = 0; index < preallocations_.numberOfRuns(); ++index) {
566+
auto rp = std::make_unique<RunPrincipal>(preg(),
531567
productResolversFactory::makePrimary,
532-
branchIDListHelper(),
533-
thinnedAssociationsHelper(),
534568
*processConfiguration_,
535569
historyAppender_.get(),
536570
index,
537-
&*processBlockHelper_);
538-
principalCache_.insert(std::move(ep));
539-
}
540-
541-
for (unsigned int index = 0; index < preallocations_.numberOfRuns(); ++index) {
542-
auto rp = std::make_unique<RunPrincipal>(preg(),
543-
productResolversFactory::makePrimary,
544-
*processConfiguration_,
545-
historyAppender_.get(),
546-
index,
547-
&mergeableRunProductProcesses_);
548-
principalCache_.insert(std::move(rp));
549-
}
571+
&mergeableRunProductProcesses_);
572+
principalCache_.insert(std::move(rp));
573+
}
550574

551-
for (unsigned int index = 0; index < preallocations_.numberOfLuminosityBlocks(); ++index) {
552-
auto lp = std::make_unique<LuminosityBlockPrincipal>(
553-
preg(), productResolversFactory::makePrimary, *processConfiguration_, historyAppender_.get(), index);
554-
principalCache_.insert(std::move(lp));
555-
}
575+
for (unsigned int index = 0; index < preallocations_.numberOfLuminosityBlocks(); ++index) {
576+
auto lp = std::make_unique<LuminosityBlockPrincipal>(
577+
preg(), productResolversFactory::makePrimary, *processConfiguration_, historyAppender_.get(), index);
578+
principalCache_.insert(std::move(lp));
579+
}
556580

557-
{
558-
auto pb = std::make_unique<ProcessBlockPrincipal>(
559-
preg(), productResolversFactory::makePrimary, *processConfiguration_);
560-
principalCache_.insert(std::move(pb));
581+
{
582+
auto pb = std::make_unique<ProcessBlockPrincipal>(
583+
preg(), productResolversFactory::makePrimary, *processConfiguration_);
584+
principalCache_.insert(std::move(pb));
561585

562-
auto pbForInput = std::make_unique<ProcessBlockPrincipal>(
563-
preg(), productResolversFactory::makePrimary, *processConfiguration_);
564-
principalCache_.insertForInput(std::move(pbForInput));
586+
auto pbForInput = std::make_unique<ProcessBlockPrincipal>(
587+
preg(), productResolversFactory::makePrimary, *processConfiguration_);
588+
principalCache_.insertForInput(std::move(pbForInput));
589+
}
565590
}
566591
} catch (...) {
567592
//in case of an exception, make sure Services are available
@@ -617,43 +642,47 @@ namespace edm {
617642
schedule_->convertCurrentProcessAlias(processConfiguration_->processName());
618643

619644
PathsAndConsumesOfModules pathsAndConsumesOfModules;
620-
pathsAndConsumesOfModules.initialize(schedule_.get(), preg());
621-
622-
// Note: all these may throw
623-
checkForModuleDependencyCorrectness(pathsAndConsumesOfModules, printDependencies_);
624-
if (deleteNonConsumedUnscheduledModules_) {
625-
if (auto const unusedModules = nonConsumedUnscheduledModules(pathsAndConsumesOfModules);
626-
not unusedModules.empty()) {
627-
pathsAndConsumesOfModules.removeModules(unusedModules);
628-
629-
edm::LogInfo("DeleteModules").log([&unusedModules](auto& l) {
630-
l << "The following modules are not in any Path or EndPath, nor is their output consumed by any other "
631-
"module, "
632-
"and therefore they are deleted before the beginJob transition.";
645+
{
646+
actReg_->preScheduleConsistencyCheckSignal_();
647+
auto guard = makeGuard([this]() { actReg_->postScheduleConsistencyCheckSignal_(); });
648+
pathsAndConsumesOfModules.initialize(schedule_.get(), preg());
649+
650+
// Note: all these may throw
651+
checkForModuleDependencyCorrectness(pathsAndConsumesOfModules, printDependencies_);
652+
if (deleteNonConsumedUnscheduledModules_) {
653+
if (auto const unusedModules = nonConsumedUnscheduledModules(pathsAndConsumesOfModules);
654+
not unusedModules.empty()) {
655+
pathsAndConsumesOfModules.removeModules(unusedModules);
656+
657+
edm::LogInfo("DeleteModules").log([&unusedModules](auto& l) {
658+
l << "The following modules are not in any Path or EndPath, nor is their output consumed by any other "
659+
"module, "
660+
"and therefore they are deleted before the beginJob transition.";
661+
for (auto const& description : unusedModules) {
662+
l << "\n " << description->moduleLabel();
663+
}
664+
});
633665
for (auto const& description : unusedModules) {
634-
l << "\n " << description->moduleLabel();
666+
schedule_->deleteModule(description->moduleLabel(), actReg_.get());
635667
}
636-
});
637-
for (auto const& description : unusedModules) {
638-
schedule_->deleteModule(description->moduleLabel(), actReg_.get());
639668
}
640669
}
641-
}
642-
// Initialize after the deletion of non-consumed unscheduled
643-
// modules to avoid non-consumed non-run modules to keep the
644-
// products unnecessarily alive
645-
if (not branchesToDeleteEarly_.empty()) {
646-
auto modulesToSkip = std::move(modulesToIgnoreForDeleteEarly_);
647-
auto branchesToDeleteEarly = std::move(branchesToDeleteEarly_);
648-
auto referencesToBranches = std::move(referencesToBranches_);
649-
schedule_->initializeEarlyDelete(branchesToDeleteEarly, referencesToBranches, modulesToSkip, *preg_);
650-
}
670+
// Initialize after the deletion of non-consumed unscheduled
671+
// modules to avoid non-consumed non-run modules to keep the
672+
// products unnecessarily alive
673+
if (not branchesToDeleteEarly_.empty()) {
674+
auto modulesToSkip = std::move(modulesToIgnoreForDeleteEarly_);
675+
auto branchesToDeleteEarly = std::move(branchesToDeleteEarly_);
676+
auto referencesToBranches = std::move(referencesToBranches_);
677+
schedule_->initializeEarlyDelete(branchesToDeleteEarly, referencesToBranches, modulesToSkip, *preg_);
678+
}
651679

652-
if (preallocations_.numberOfLuminosityBlocks() > 1) {
653-
throwAboutModulesRequiringLuminosityBlockSynchronization();
654-
}
655-
if (preallocations_.numberOfRuns() > 1) {
656-
warnAboutModulesRequiringRunSynchronization();
680+
if (preallocations_.numberOfLuminosityBlocks() > 1) {
681+
throwAboutModulesRequiringLuminosityBlockSynchronization();
682+
}
683+
if (preallocations_.numberOfRuns() > 1) {
684+
warnAboutModulesRequiringRunSynchronization();
685+
}
657686
}
658687

659688
//NOTE: This implementation assumes 'Job' means one call
@@ -670,8 +699,11 @@ namespace edm {
670699
//if(looper_) {
671700
// looper_->beginOfJob(es);
672701
//}
673-
espController_->finishConfiguration();
674-
702+
{
703+
actReg_->preEventSetupConfigurationFinalizedSignal_();
704+
auto guard = makeGuard([this]() { actReg_->postEventSetupConfigurationFinalizedSignal_(); });
705+
espController_->finishConfiguration();
706+
}
675707
eventsetup::ESRecordsToProductResolverIndices esRecordsToProductResolverIndices = esp_->recordsToResolverIndices();
676708

677709
actReg_->eventSetupConfigurationSignal_(esRecordsToProductResolverIndices, processContext_);

FWCore/ServiceRegistry/interface/ActivityRegistry.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,98 @@ namespace edm {
146146
ActivityRegistry& operator=(ActivityRegistry const&) = delete; // Disallow copying and moving
147147

148148
// ---------- signals ------------------------------------
149+
using PostServicesConstruction = signalslot::Signal<void()>;
150+
/// signal is emitted after all services have been constructed
151+
PostServicesConstruction postServicesConstructionSignal_;
152+
void watchPostServicesConstruction(PostServicesConstruction::slot_type const& iSlot) {
153+
postServicesConstructionSignal_.connect(iSlot);
154+
}
155+
AR_WATCH_USING_METHOD_0(watchPostServicesConstruction)
156+
157+
using PreEventSetupModulesConstruction = signalslot::Signal<void()>;
158+
/// signal is emitted before any EventSetup modules have been constructed
159+
PreEventSetupModulesConstruction preEventSetupModulesConstructionSignal_;
160+
void watchPreEventSetupModulesConstruction(PreEventSetupModulesConstruction::slot_type const& iSlot) {
161+
preEventSetupModulesConstructionSignal_.connect(iSlot);
162+
}
163+
AR_WATCH_USING_METHOD_0(watchPreEventSetupModulesConstruction)
164+
165+
using PostEventSetupModulesConstruction = signalslot::Signal<void()>;
166+
/// signal is emitted after all EventSetup modules have been constructed
167+
PostEventSetupModulesConstruction postEventSetupModulesConstructionSignal_;
168+
void watchPostEventSetupModulesConstruction(PostEventSetupModulesConstruction::slot_type const& iSlot) {
169+
postEventSetupModulesConstructionSignal_.connect(iSlot);
170+
}
171+
AR_WATCH_USING_METHOD_0(watchPostEventSetupModulesConstruction)
172+
173+
using PreFinishSchedule = signalslot::Signal<void()>;
174+
/// signal is emitted before the call to EventSetup::finishSchedule
175+
PreFinishSchedule preFinishScheduleSignal_;
176+
void watchPreFinishSchedule(PreFinishSchedule::slot_type const& iSlot) { preFinishScheduleSignal_.connect(iSlot); }
177+
AR_WATCH_USING_METHOD_0(watchPreFinishSchedule)
178+
179+
using PostFinishSchedule = signalslot::Signal<void()>;
180+
/// signal is emitted after the call to EventSetup::finishSchedule
181+
PostFinishSchedule postFinishScheduleSignal_;
182+
void watchPostFinishSchedule(PostFinishSchedule::slot_type const& iSlot) {
183+
postFinishScheduleSignal_.connect(iSlot);
184+
}
185+
AR_WATCH_USING_METHOD_0(watchPostFinishSchedule)
186+
187+
using PrePrincipalsCreation = signalslot::Signal<void()>;
188+
/// signal is emitted before the creation of the Run, LuminosityBlock, and Event Principals
189+
PrePrincipalsCreation prePrincipalsCreationSignal_;
190+
void watchPrePrincipalsCreation(PrePrincipalsCreation::slot_type const& iSlot) {
191+
prePrincipalsCreationSignal_.connect(iSlot);
192+
}
193+
AR_WATCH_USING_METHOD_0(watchPrePrincipalsCreation)
194+
195+
using PostPrincipalsCreation = signalslot::Signal<void()>;
196+
/// signal is emitted after the creation of the Run, LuminosityBlock, and Event Principals
197+
PostPrincipalsCreation postPrincipalsCreationSignal_;
198+
void watchPostPrincipalsCreation(PostPrincipalsCreation::slot_type const& iSlot) {
199+
postPrincipalsCreationSignal_.connect(iSlot);
200+
}
201+
AR_WATCH_USING_METHOD_0(watchPostPrincipalsCreation)
202+
203+
using PreScheduleConsistencyCheck = signalslot::Signal<void()>;
204+
/// signal is emitted before the call to Schedule::consistencyCheck
205+
PreScheduleConsistencyCheck preScheduleConsistencyCheckSignal_;
206+
void watchPreScheduleConsistencyCheck(PreScheduleConsistencyCheck::slot_type const& iSlot) {
207+
preScheduleConsistencyCheckSignal_.connect(iSlot);
208+
}
209+
AR_WATCH_USING_METHOD_0(watchPreScheduleConsistencyCheck)
210+
211+
using PostScheduleConsistencyCheck = signalslot::Signal<void()>;
212+
/// signal is emitted after the call to Schedule::consistencyCheck
213+
PostScheduleConsistencyCheck postScheduleConsistencyCheckSignal_;
214+
void watchPostScheduleConsistencyCheck(PostScheduleConsistencyCheck::slot_type const& iSlot) {
215+
postScheduleConsistencyCheckSignal_.connect(iSlot);
216+
}
217+
AR_WATCH_USING_METHOD_0(watchPostScheduleConsistencyCheck)
218+
149219
typedef signalslot::Signal<void(service::SystemBounds const&)> Preallocate;
150220
///signal is emitted before beginJob
151221
Preallocate preallocateSignal_;
152222
void watchPreallocate(Preallocate::slot_type const& iSlot) { preallocateSignal_.connect(iSlot); }
153223
AR_WATCH_USING_METHOD_1(watchPreallocate)
154224

225+
using PreEventSetupConfigurationFinalized = signalslot::Signal<void()>;
226+
/// signal is emitted just before the EventSetup configuration has been finalized
227+
PreEventSetupConfigurationFinalized preEventSetupConfigurationFinalizedSignal_;
228+
void watchPreEventSetupConfigurationFinalized(PreEventSetupConfigurationFinalized::slot_type const& iSlot) {
229+
preEventSetupConfigurationFinalizedSignal_.connect(iSlot);
230+
}
231+
AR_WATCH_USING_METHOD_0(watchPreEventSetupConfigurationFinalized)
232+
233+
using PostEventSetupConfigurationFinalized = signalslot::Signal<void()>;
234+
/// signal is emitted just after the EventSetup configuration has been finalized
235+
PostEventSetupConfigurationFinalized postEventSetupConfigurationFinalizedSignal_;
236+
void watchPostEventSetupConfigurationFinalized(PostEventSetupConfigurationFinalized::slot_type const& iSlot) {
237+
postEventSetupConfigurationFinalizedSignal_.connect(iSlot);
238+
}
239+
AR_WATCH_USING_METHOD_0(watchPostEventSetupConfigurationFinalized)
240+
155241
typedef signalslot::Signal<void(eventsetup::ESRecordsToProductResolverIndices const&, ProcessContext const&)>
156242
EventSetupConfiguration;
157243
///signal is emitted before beginJob
@@ -161,6 +247,22 @@ namespace edm {
161247
}
162248
AR_WATCH_USING_METHOD_2(watchEventSetupConfiguration)
163249

250+
using PreModulesInitializationFinalized = signalslot::Signal<void()>;
251+
/// signal is emitted just before all module initialization has been finalized
252+
PreModulesInitializationFinalized preModulesInitializationFinalizedSignal_;
253+
void watchPreModulesInitializationFinalized(PreModulesInitializationFinalized::slot_type const& iSlot) {
254+
preModulesInitializationFinalizedSignal_.connect(iSlot);
255+
}
256+
AR_WATCH_USING_METHOD_0(watchPreModulesInitializationFinalized)
257+
258+
using PostModulesInitializationFinalized = signalslot::Signal<void()>;
259+
/// signal is emitted just after all module initialization has been finalized
260+
PostModulesInitializationFinalized postModulesInitializationFinalizedSignal_;
261+
void watchPostModulesInitializationFinalized(PostModulesInitializationFinalized::slot_type const& iSlot) {
262+
postModulesInitializationFinalizedSignal_.connect(iSlot);
263+
}
264+
AR_WATCH_USING_METHOD_0(watchPostModulesInitializationFinalized)
265+
164266
typedef signalslot::Signal<void(ProcessContext const&)> PreBeginJob;
165267
///signal is emitted before all modules have gotten their beginJob called
166268
PreBeginJob preBeginJobSignal_;

0 commit comments

Comments
 (0)