-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative module configuration syntax #43955
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,15 @@ | ||
import FWCore.ParameterSet.Config as cms | ||
from FWCore.Modules.modules import EventContentAnalyzer, EmptySource | ||
|
||
process = cms.Process("EMPTY") | ||
|
||
process.test = cms.EDAnalyzer("EventContentAnalyzer", listPathStatus = cms.untracked.bool(True)) | ||
process.test = EventContentAnalyzer(listPathStatus = True) | ||
|
||
process.e = cms.EndPath(process.test) | ||
|
||
#process.out = cms.OutputModule("AsciiOutputModule") | ||
#process.e2 = cms.EndPath(process.out) | ||
|
||
process.source = cms.Source("EmptySource") | ||
process.source = EmptySource() | ||
|
||
process.maxEvents.input = 1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,31 @@ | ||
import FWCore.ParameterSet.Config as cms | ||
from FWCore.Framework.modules import AddIntsProducer, IntProductFilter | ||
from FWCore.Modules.modules import AsciiOutputModule | ||
from FWCore.Integration.modules import DelayedReaderThrowingSource | ||
|
||
process = cms.Process("TEST") | ||
|
||
process.source = cms.Source("DelayedReaderThrowingSource", labels = cms.untracked.vstring("test", "test2", "test3")) | ||
process.source = DelayedReaderThrowingSource( labels = ["test", "test2", "test3"]) | ||
|
||
process.getter = cms.EDProducer("AddIntsProducer", labels = cms.VInputTag(cms.InputTag("test","","INPUTTEST"))) | ||
process.onPath = cms.EDProducer("AddIntsProducer", labels = cms.VInputTag(cms.InputTag("test2", "", "INPUTTEST"), cms.InputTag("getter", "other"))) | ||
process.f1 = cms.EDFilter("IntProductFilter", label = cms.InputTag("onPath"), shouldProduce = cms.bool(True)) | ||
process.f2 = cms.EDFilter("IntProductFilter", label = cms.InputTag("onPath"), shouldProduce = cms.bool(True)) | ||
process.inFront = cms.EDFilter("IntProductFilter", label = cms.InputTag("test3")) | ||
process.getter = AddIntsProducer(labels = [("test","","INPUTTEST")]) | ||
process.onPath = AddIntsProducer(labels = [("test2", "", "INPUTTEST"), ("getter", "other")]) | ||
process.f1 = IntProductFilter( label = "onPath", shouldProduce = True) | ||
process.f2 = IntProductFilter( label = "onPath", shouldProduce = True) | ||
process.inFront = IntProductFilter( label = "test3") | ||
|
||
process.p1 = cms.Path(process.inFront+process.onPath+process.f1+process.f2) | ||
process.p3 = cms.Path(process.onPath+process.f1, cms.Task(process.getter)) | ||
|
||
process.p2 = cms.Path(process.onPath+process.f2) | ||
|
||
|
||
#process.dump = cms.EDAnalyzer("EventContentAnalyzer") | ||
#from FWCore.Modules.modules import EventContentAnalyzer import * | ||
#process.dump = EventContentAnalyzer() | ||
#process.p = cms.Path(process.dump) | ||
|
||
process.out = cms.OutputModule("AsciiOutputModule") | ||
process.out = AsciiOutputModule() | ||
process.e = cms.EndPath(process.out, cms.Task(process.getter)) | ||
|
||
process.maxEvents.input = 1 | ||
|
||
#process.add_(cms.Service("Tracer")) | ||
#from FWCore.Services.modules import Tracer | ||
#process.add_(Tracer()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import os | ||
from os.path import sep, join | ||
import importlib | ||
|
||
class _ModuleProxy (object): | ||
def __init__(self, package, name): | ||
self._package = package | ||
self._name = name | ||
self._caller = None | ||
def __call__(self,**kwargs): | ||
if not self._caller: | ||
self._caller = getattr(importlib.import_module(self._package+'.'+self._name),self._name) | ||
return self._caller(**kwargs) | ||
|
||
|
||
def _setupProxies(fullName): | ||
_cmssw_package_name='.'.join(fullName.split(sep)[-3:-1]) | ||
basename = fullName.split(sep)[-1] | ||
pathname = fullName[:-1*len(basename)] | ||
proxies = dict() | ||
for filename in ( x for x in os.listdir(pathname) if (len(x) > 3 and x[-3:] == '.py' and x != basename and ((len(x) < 6) or (x[-6:] != 'cfi.py')))): | ||
name = filename[:-3] | ||
proxies[name] = _ModuleProxy(_cmssw_package_name, name) | ||
return proxies |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,54 @@ namespace edm { | |
std::cref(baseType_), | ||
std::cref(pluginName_), | ||
std::ref(usedCfiFileNames))); | ||
if (defaultDescDefined_) { | ||
writeClassFile(defaultDesc_); | ||
} else if (descriptions_.size() == 1) { | ||
writeClassFile(descriptions_.begin()->second); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this mean if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is correct. |
||
} | ||
|
||
void ConfigurationDescriptions::writeClassFile(ParameterSetDescription const& iDesc) const { | ||
std::string pluginName = pluginName_; | ||
auto found = pluginName.find("::"); | ||
while (found != std::string::npos) { | ||
pluginName.replace(found, 2, "_"); | ||
found = pluginName.find("::"); | ||
} | ||
//Symbols that can appear in our plugin names but can't in python function names | ||
const std::string toReplace("@<>,"); | ||
found = pluginName.find_first_of(toReplace); | ||
while (found != std::string::npos) { | ||
pluginName.replace(found, 1, "_"); | ||
found = pluginName.find_first_of(toReplace, found); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC this means that a plugin with a name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is how the name would be modified. |
||
|
||
std::string fileName = pluginName + ".py"; | ||
std::ofstream outFile(fileName.c_str()); | ||
if (outFile.fail()) { | ||
edm::Exception ex(edm::errors::LogicError, "Creating class file failed.\n"); | ||
ex << "Opening a file '" << fileName << "' failed.\n"; | ||
ex << "Error code from errno " << errno << ": " << std::strerror(errno) << "\n"; | ||
|
||
ex.addContext("Executing function ConfigurationDescriptions::writeDefault"); | ||
throw ex; | ||
} | ||
outFile << "import FWCore.ParameterSet.Config as cms\n\n"; | ||
outFile << "def " << pluginName | ||
<< "(**kwargs):\n" | ||
" mod = cms." | ||
<< baseType_ << "('" << pluginName_ << "'"; | ||
|
||
bool startWithComma = true; | ||
int indentation = 4; | ||
iDesc.writeCfi(outFile, startWithComma, indentation); | ||
|
||
outFile << ")\n" | ||
" for k,v in kwargs.items():\n" | ||
" setattr(mod, k, v)\n" | ||
" return mod\n"; | ||
|
||
outFile.close(); | ||
} | ||
|
||
void ConfigurationDescriptions::writeCfiForLabel(std::pair<std::string, ParameterSetDescription> const& labelAndDesc, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,9 @@ namespace edm { | |
|
||
void ParameterDescriptionBase::writeCfi_( | ||
std::ostream& os, bool optional, bool& startWithComma, int indentation, bool& wroteSomething) const { | ||
if (label().empty() or label()[0] == '@') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change was related to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
return; | ||
} | ||
wroteSomething = true; | ||
if (startWithComma) | ||
os << ","; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something I was thinking about ages ago, when I was spending too much of my time looking after the HLT configurations, and I'm glad to see it being implemented !
Looking at the example, the main concern I have is for
InputTag
s andVInputTag
s: writing or readingI think it's very easy to get confused about
getter
andother
being two components on anInputTag
instead of two separateInputTag
s.Some other confusing exmples:
this is a
VInputTag
with only oneInputTag
?this is a
VInputTag
with twoInputTag
s ?this is a
VInputTag
with twoInputTag
s ?this is a
VInputTag
with twoInputTag
s ?this is a
VInputTag
with twoInputTag
s ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fwyzard Thanks for the feedback! All the examples are already possible since this code just reuses what is already available. The reduced syntax can already be used in
E.g.
That being said, the reduced syntax also excepts the explicit type information as well
As for some of your explicit examples, I'm curious why you ask if the following are
VInputTags
with two entries, rather than (the correct) aVInputTags
with 1 entry.or even
which does require one to understand that
(...,)
in python is just a way to express atuple
with a single entry.All the above are standard python for a container with 1 entry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two cases could be interpreted as ambiguous for understanding the type of
labels
(InputTag
vsVInputTag
) only from the assignment.The same syntax would work for
InputTag
(with module and instance labels) and for 2-elementVInputTag
The same syntax would work for
InputTag
(with module labels) and for 1-elementVInputTag
.(for reference, the sequence-syntax for assining
InputTag
was added in #29992, #29846)