Skip to content

Commit d5f25f5

Browse files
authored
Merge pull request #49001 from Dr15Jones/additionalStartupSignals
Gather more timing information about Framework startup
2 parents 691c816 + 7229f7f commit d5f25f5

File tree

8 files changed

+265
-68
lines changed

8 files changed

+265
-68
lines changed

FWCore/AbstractServices/interface/TimingServiceBase.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,14 @@ namespace edm {
4141
virtual double getTotalCPU() const = 0;
4242

4343
static void jobStarted();
44+
static void pythonStarting();
45+
static void pythonFinished();
46+
static void servicesStarting();
4447

4548
static std::chrono::steady_clock::time_point jobStartTime();
49+
static std::chrono::steady_clock::time_point pythonStartTime();
50+
static std::chrono::steady_clock::time_point pythonEndTime();
51+
static std::chrono::steady_clock::time_point servicesStartTime();
4652
};
4753
} // namespace edm
4854

FWCore/AbstractServices/src/TimingServiceBase.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,26 @@ std::chrono::steady_clock::time_point TimingServiceBase::jobStartTime() {
2424
return s_jobStartTime;
2525
}
2626

27+
void TimingServiceBase::pythonStarting() { (void)pythonStartTime(); }
28+
void TimingServiceBase::pythonFinished() { (void)pythonEndTime(); }
29+
30+
void TimingServiceBase::servicesStarting() { (void)servicesStartTime(); }
31+
32+
std::chrono::steady_clock::time_point TimingServiceBase::pythonStartTime() {
33+
static const std::chrono::steady_clock::time_point s_pythonStartTime = std::chrono::steady_clock::now();
34+
return s_pythonStartTime;
35+
}
36+
37+
std::chrono::steady_clock::time_point TimingServiceBase::pythonEndTime() {
38+
static const std::chrono::steady_clock::time_point s_pythonEndTime = std::chrono::steady_clock::now();
39+
return s_pythonEndTime;
40+
}
41+
42+
std::chrono::steady_clock::time_point TimingServiceBase::servicesStartTime() {
43+
static const std::chrono::steady_clock::time_point s_servicesStartTime = std::chrono::steady_clock::now();
44+
return s_servicesStartTime;
45+
}
46+
2747
//
2848
// constructors and destructor
2949
//

FWCore/Framework/bin/cmsRun.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,13 @@ int main(int argc, const char* argv[]) {
189189
}
190190
std::shared_ptr<edm::ProcessDesc> processDesc;
191191
try {
192+
edm::TimingServiceBase::pythonStarting();
192193
std::unique_ptr<edm::ParameterSet> parameterSet;
193194
if (!fileName.empty())
194195
parameterSet = edm::readConfig(fileName, pythonOptValues);
195196
else
196197
edm::makeParameterSets(cmdString, parameterSet);
198+
edm::TimingServiceBase::pythonFinished();
197199
processDesc = std::make_shared<edm::ProcessDesc>(std::move(parameterSet));
198200
} catch (edm::Exception const&) {
199201
throw;

FWCore/Framework/interface/Schedule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include "FWCore/Utilities/interface/get_underlying_safe.h"
8383
#include "FWCore/Utilities/interface/propagate_const.h"
8484
#include "FWCore/Utilities/interface/Transition.h"
85+
#include "FWCore/Utilities/interface/Signal.h"
8586

8687
#include <array>
8788
#include <map>
@@ -323,6 +324,8 @@ namespace edm {
323324

324325
std::vector<std::string> const* pathNames_;
325326
std::vector<std::string> const* endPathNames_;
327+
edm::signalslot::Signal<void()> preModulesInitializationFinalizedSignal_;
328+
edm::signalslot::Signal<void()> postModulesInitializationFinalizedSignal_;
326329
bool wantSummary_;
327330
};
328331

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/Framework/src/Schedule.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ namespace edm {
237237
pathNames_(&tns.getTrigPaths()),
238238
endPathNames_(&tns.getEndPaths()),
239239
wantSummary_(tns.wantSummary()) {
240+
preModulesInitializationFinalizedSignal_.connect(std::cref(areg->preModulesInitializationFinalizedSignal_));
241+
postModulesInitializationFinalizedSignal_.connect(std::cref(areg->postModulesInitializationFinalizedSignal_));
240242
ScheduleBuilder builder(
241243
*moduleRegistry_, proc_pset, *pathNames_, *endPathNames_, prealloc, preg, *areg, processConfiguration);
242244
resultsInserter_ = std::move(builder.resultsInserter_);
@@ -900,6 +902,9 @@ namespace edm {
900902
eventsetup::ESRecordsToProductResolverIndices const& iESIndices,
901903
ProcessBlockHelperBase const& processBlockHelperBase,
902904
std::string const& iProcessName) {
905+
preModulesInitializationFinalizedSignal_();
906+
auto post = [this](void*) { postModulesInitializationFinalizedSignal_(); };
907+
std::unique_ptr<void, decltype(post)> const postGuard(this, post);
903908
finishModulesInitialization(*moduleRegistry_, iRegistry, iESIndices, processBlockHelperBase, iProcessName);
904909
globalSchedule_->beginJob(*moduleRegistry_);
905910
}

0 commit comments

Comments
 (0)