Skip to content

Commit

Permalink
Merge pull request #39391 from makortel/moduleTypeResolverEventSetup
Browse files Browse the repository at this point in the history
Extend alternative module type loading to EventSetup
  • Loading branch information
cmsbuild authored Sep 15, 2022
2 parents 03a7fe5 + 8e92ec6 commit bf366b7
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 108 deletions.
24 changes: 8 additions & 16 deletions FWCore/Framework/interface/ComponentFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
#include "FWCore/PluginManager/interface/PluginFactory.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Framework/interface/ComponentMaker.h"
#include "FWCore/Framework/interface/resolveMaker.h"
#include "FWCore/Utilities/interface/ConvertException.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/Utilities/interface/thread_safety_macros.h"

// forward declarations
namespace edm {
class ModuleTypeResolverBase;

namespace eventsetup {
class EventSetupProvider;
class EventSetupsController;
Expand All @@ -46,37 +49,26 @@ namespace edm {
//~ComponentFactory();

typedef ComponentMakerBase<T> Maker;
typedef std::map<std::string, std::shared_ptr<Maker> > MakerMap;
typedef std::map<std::string, std::shared_ptr<Maker>> MakerMap;
typedef typename T::base_type base_type;
// ---------- const member functions ---------------------
std::shared_ptr<base_type> addTo(EventSetupsController& esController,
EventSetupProvider& iProvider,
edm::ParameterSet const& iConfiguration,
ModuleTypeResolverBase const* resolver,
bool replaceExisting = false) const {
std::string modtype = iConfiguration.template getParameter<std::string>("@module_type");
//cerr << "Factory: module_type = " << modtype << endl;
typename MakerMap::iterator it = makers_.find(modtype);

if (it == makers_.end()) {
std::shared_ptr<Maker> wm(edmplugin::PluginFactory<ComponentMakerBase<T>*()>::get()->create(modtype));

if (wm.get() == nullptr) {
Exception::throwThis(errors::Configuration,
"UnknownModule",
T::name().c_str(),
" of type ",
modtype.c_str(),
" has not been registered.\n"
"Perhaps your module type is misspelled or is not a "
"framework plugin.\n"
"Try running EdmPluginDump to obtain a list of "
"available Plugins.");
}
std::shared_ptr<Maker> wm(
detail::resolveMaker<edmplugin::PluginFactory<ComponentMakerBase<T>*()>>(modtype, resolver));

//cerr << "Factory: created the worker" << endl;

std::pair<typename MakerMap::iterator, bool> ret =
makers_.insert(std::pair<std::string, std::shared_ptr<Maker> >(modtype, wm));
makers_.insert(std::pair<std::string, std::shared_ptr<Maker>>(modtype, wm));

if (ret.second == false) {
Exception::throwThis(errors::Configuration, "Maker Factory map insert failed");
Expand Down
2 changes: 2 additions & 0 deletions FWCore/Framework/interface/EventSetupProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace edm {
class EventSetupImpl;
class EventSetupRecordIntervalFinder;
class IOVSyncValue;
class ModuleTypeResolverBase;
class ParameterSet;

namespace eventsetup {
Expand Down Expand Up @@ -89,6 +90,7 @@ namespace edm {
void forceCacheClear();

void checkESProducerSharing(
ModuleTypeResolverBase const* resolver,
EventSetupProvider& precedingESProvider,
std::set<ParameterSetIDHolder>& sharingCheckDone,
std::map<EventSetupRecordKey, std::vector<ComponentDescription const*>>& referencedESProducers,
Expand Down
4 changes: 4 additions & 0 deletions FWCore/Framework/interface/EventSetupsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace edm {
class EventSetupRecordIntervalFinder;
class ParameterSet;
class IOVSyncValue;
class ModuleTypeResolverBase;
class WaitingTaskHolder;
class WaitingTaskList;

Expand Down Expand Up @@ -79,6 +80,7 @@ namespace edm {
class EventSetupsController {
public:
EventSetupsController();
explicit EventSetupsController(ModuleTypeResolverBase const* resolver);

EventSetupsController(EventSetupsController const&) = delete;
EventSetupsController const& operator=(EventSetupsController const&) = delete;
Expand Down Expand Up @@ -183,6 +185,8 @@ namespace edm {
std::multimap<ParameterSetID, ESProducerInfo> esproducers_;
std::multimap<ParameterSetID, ESSourceInfo> essources_;

ModuleTypeResolverBase const* typeResolver_ = nullptr;

bool hasNonconcurrentFinder_ = false;
bool mustFinishConfiguration_ = true;
};
Expand Down
40 changes: 40 additions & 0 deletions FWCore/Framework/interface/resolveMaker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef FWCore_Framework_interface_resolveMaker_h
#define FWCore_Framework_interface_resolveMaker_h

#include "FWCore/Framework/interface/ModuleTypeResolverBase.h"
#include "FWCore/Utilities/interface/Exception.h"

#include <memory>
#include <string>

namespace edm::detail {
void annotateResolverMakerExceptionAndRethrow(cms::Exception& except,
std::string const& modtype,
ModuleTypeResolverBase const* resolver);

template <typename TFactory>
auto resolveMaker(std::string const& moduleType, ModuleTypeResolverBase const* resolver) {
if (resolver) {
auto index = resolver->kInitialIndex;
auto newType = moduleType;
do {
auto [ttype, tindex] = resolver->resolveType(std::move(newType), index);
newType = std::move(ttype);
index = tindex;
auto m = TFactory::get()->tryToCreate(newType);
if (m) {
return m;
}
} while (index != resolver->kLastIndex);
try {
//failed to find a plugin
return TFactory::get()->create(moduleType);
} catch (cms::Exception& iExcept) {
detail::annotateResolverMakerExceptionAndRethrow(iExcept, moduleType, resolver);
}
}
return TFactory::get()->create(moduleType);
}
} // namespace edm::detail

#endif
3 changes: 2 additions & 1 deletion FWCore/Framework/src/EventProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ namespace edm {
ParameterSet* providerPSet = params.getPSetForUpdate(looperName);
validateLooper(*providerPSet);
providerPSet->registerIt();
vLooper = eventsetup::LooperFactory::get()->addTo(esController, cp, *providerPSet);
// Unlikely we would ever need the ModuleTypeResolver in Looper
vLooper = eventsetup::LooperFactory::get()->addTo(esController, cp, *providerPSet, nullptr);
}
return vLooper;
}
Expand Down
3 changes: 2 additions & 1 deletion FWCore/Framework/src/EventSetupProvider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ namespace edm {
}

void EventSetupProvider::checkESProducerSharing(
ModuleTypeResolverBase const* resolver,
EventSetupProvider& precedingESProvider,
std::set<ParameterSetIDHolder>& sharingCheckDone,
std::map<EventSetupRecordKey, std::vector<ComponentDescription const*>>& referencedESProducers,
Expand Down Expand Up @@ -530,7 +531,7 @@ namespace edm {
} else {
if (esController.isLastMatch(psetID, subProcessIndex_, precedingESProvider.subProcessIndex_)) {
ParameterSet const& pset = *esController.getESProducerPSet(psetID, subProcessIndex_);
ModuleFactory::get()->addTo(esController, *this, pset, true);
ModuleFactory::get()->addTo(esController, *this, pset, resolver, true);
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions FWCore/Framework/src/EventSetupProviderMaker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ namespace edm {
}

// ---------------------------------------------------------------
void fillEventSetupProvider(EventSetupsController& esController, EventSetupProvider& cp, ParameterSet& params) {
void fillEventSetupProvider(ModuleTypeResolverBase const* resolver,
EventSetupsController& esController,
EventSetupProvider& cp,
ParameterSet& params) {
std::vector<std::string> providers = params.getParameter<std::vector<std::string> >("@all_esmodules");

for (std::vector<std::string>::iterator itName = providers.begin(), itNameEnd = providers.end();
Expand All @@ -100,7 +103,7 @@ namespace edm {
ParameterSet* providerPSet = params.getPSetForUpdate(*itName);
validateEventSetupParameters(*providerPSet);
providerPSet->registerIt();
ModuleFactory::get()->addTo(esController, cp, *providerPSet);
ModuleFactory::get()->addTo(esController, cp, *providerPSet, resolver);
}

std::vector<std::string> sources = params.getParameter<std::vector<std::string> >("@all_essources");
Expand All @@ -110,7 +113,7 @@ namespace edm {
ParameterSet* providerPSet = params.getPSetForUpdate(*itName);
validateEventSetupParameters(*providerPSet);
providerPSet->registerIt();
SourceFactory::get()->addTo(esController, cp, *providerPSet);
SourceFactory::get()->addTo(esController, cp, *providerPSet, resolver);
}
}

Expand Down
6 changes: 5 additions & 1 deletion FWCore/Framework/src/EventSetupProviderMaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// forward declarations
namespace edm {
class ActivityRegistry;
class ModuleTypeResolverBase;
class ParameterSet;
namespace eventsetup {
class EventSetupProvider;
Expand All @@ -16,7 +17,10 @@ namespace edm {
unsigned subProcessIndex,
ActivityRegistry*);

void fillEventSetupProvider(EventSetupsController& esController, EventSetupProvider& cp, ParameterSet& params);
void fillEventSetupProvider(ModuleTypeResolverBase const* resolver,
EventSetupsController& esController,
EventSetupProvider& cp,
ParameterSet& params);

void validateEventSetupParameters(ParameterSet& pset);
} // namespace eventsetup
Expand Down
7 changes: 5 additions & 2 deletions FWCore/Framework/src/EventSetupsController.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace edm {
namespace eventsetup {

EventSetupsController::EventSetupsController() {}
EventSetupsController::EventSetupsController(ModuleTypeResolverBase const* resolver) : typeResolver_(resolver) {}

void EventSetupsController::endIOVsAsync(edm::WaitingTaskHolder iEndTask) {
for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
Expand All @@ -54,7 +55,7 @@ namespace edm {
// Construct the ESProducers and ESSources
// shared_ptrs to them are temporarily stored in this
// EventSetupsController and in the EventSetupProvider
fillEventSetupProvider(*this, *returnValue, iPSet);
fillEventSetupProvider(typeResolver_, *this, *returnValue, iPSet);

numberOfConcurrentIOVs_.readConfigurationParameters(eventSetupPset, maxConcurrentIOVs, dumpOptions);

Expand Down Expand Up @@ -381,7 +382,9 @@ namespace edm {
// preceding process will be the top level process and the others
// SubProcess's)
for (auto precedingESProvider = providers_.begin(); precedingESProvider != esProvider; ++precedingESProvider) {
(*esProvider)->checkESProducerSharing(**precedingESProvider, sharingCheckDone, referencedESProducers, *this);
(*esProvider)
->checkESProducerSharing(
typeResolver_, **precedingESProvider, sharingCheckDone, referencedESProducers, *this);
}

(*esProvider)->resetRecordToProxyPointers();
Expand Down
55 changes: 2 additions & 53 deletions FWCore/Framework/src/Factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "FWCore/Framework/src/Factory.h"
#include "FWCore/Framework/interface/maker/MakerPluginFactory.h"
#include "FWCore/Framework/interface/ModuleTypeResolverBase.h"
#include "FWCore/Framework/interface/resolveMaker.h"
#include "FWCore/Utilities/interface/DebugMacros.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/Algorithms.h"
Expand All @@ -24,65 +25,13 @@ namespace edm {

Factory const* Factory::get() { return &singleInstance_; }

static void annotateExceptionAndRethrow(cms::Exception& except,
const MakeModuleParams& p,
std::string const& modtype,
ModuleTypeResolverBase const* resolver) {
if (not resolver) {
throw except;
}
//if needed, create list of alternative types that were tried
std::string alternativeTypes;
auto index = resolver->kInitialIndex;
auto newType = modtype;
int tries = 0;
do {
++tries;
if (not alternativeTypes.empty()) {
alternativeTypes.append(", ");
}
auto [ttype, tindex] = resolver->resolveType(std::move(newType), index);
newType = std::move(ttype);
index = tindex;
alternativeTypes.append(newType);
} while (index != resolver->kLastIndex);
if (tries == 1 and alternativeTypes == modtype) {
throw except;
}
alternativeTypes.insert(0, "These alternative types were tried: ");
except.addAdditionalInfo(alternativeTypes);
throw except;
}

Maker* Factory::findMaker(const MakeModuleParams& p, ModuleTypeResolverBase const* resolver) const {
std::string modtype = p.pset_->getParameter<std::string>("@module_type");
FDEBUG(1) << "Factory: module_type = " << modtype << std::endl;
MakerMap::iterator it = makers_.find(modtype);

if (it == makers_.end()) {
auto make = [](auto resolver, const auto& modtype, auto const& p) {
if (resolver) {
auto index = resolver->kInitialIndex;
auto newType = modtype;
do {
auto [ttype, tindex] = resolver->resolveType(std::move(newType), index);
newType = std::move(ttype);
index = tindex;
auto m = MakerPluginFactory::get()->tryToCreate(newType);
if (m) {
return m;
}
} while (index != resolver->kLastIndex);
try {
//failed to find a plugin
return MakerPluginFactory::get()->create(modtype);
} catch (cms::Exception& iExcept) {
annotateExceptionAndRethrow(iExcept, p, modtype, resolver);
}
}
return MakerPluginFactory::get()->create(modtype);
};
std::unique_ptr<Maker> wm = make(resolver, modtype, p);
std::unique_ptr<Maker> wm = detail::resolveMaker<MakerPluginFactory>(modtype, resolver);
FDEBUG(1) << "Factory: created worker of type " << modtype << std::endl;

std::pair<MakerMap::iterator, bool> ret = makers_.insert(std::pair<std::string, Maker*>(modtype, wm.get()));
Expand Down
32 changes: 32 additions & 0 deletions FWCore/Framework/src/resolverMaker.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "FWCore/Framework/interface/resolveMaker.h"

namespace edm::detail {
void annotateResolverMakerExceptionAndRethrow(cms::Exception& except,
std::string const& modtype,
ModuleTypeResolverBase const* resolver) {
if (not resolver) {
throw except;
}
//if needed, create list of alternative types that were tried
std::string alternativeTypes;
auto index = resolver->kInitialIndex;
auto newType = modtype;
int tries = 0;
do {
++tries;
if (not alternativeTypes.empty()) {
alternativeTypes.append(", ");
}
auto [ttype, tindex] = resolver->resolveType(std::move(newType), index);
newType = std::move(ttype);
index = tindex;
alternativeTypes.append(newType);
} while (index != resolver->kLastIndex);
if (tries == 1 and alternativeTypes == modtype) {
throw except;
}
alternativeTypes.insert(0, "These alternative types were tried: ");
except.addAdditionalInfo(alternativeTypes);
throw except;
}
} // namespace edm::detail
38 changes: 38 additions & 0 deletions FWCore/Framework/test/TestTypeResolvers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef FWCore_Framework_test_TestTypeResolvers_h
#define FWCore_Framework_test_TestTypeResolvers_h

#include "FWCore/Framework/interface/ModuleTypeResolverBase.h"

#include <string>
#include <utility>

namespace edm::test {
class SimpleTestTypeResolver : public edm::ModuleTypeResolverBase {
public:
SimpleTestTypeResolver() = default;
std::pair<std::string, int> resolveType(std::string basename, int index) const final {
return {basename, kLastIndex};
}
};

class ComplexTestTypeResolver : public edm::ModuleTypeResolverBase {
public:
ComplexTestTypeResolver() = default;
std::pair<std::string, int> resolveType(std::string basename, int index) const final {
constexpr auto kGeneric = "generic::";
constexpr auto kOther = "edm::test::other::";
constexpr auto kCPU = "edm::test::cpu::";
if (index != kInitialIndex and index != kLastIndex) {
basename.replace(basename.find(kOther), strlen(kOther), kCPU);
return {basename, kLastIndex};
}
if (index == kInitialIndex and basename.find(kGeneric) != std::string::npos) {
basename.replace(basename.find(kGeneric), strlen(kGeneric), kOther);
return {basename, kInitialIndex + 1};
}
return {basename, kLastIndex};
}
};
} // namespace edm::test

#endif
Loading

0 comments on commit bf366b7

Please sign in to comment.