Skip to content

Commit

Permalink
Merge pull request #35630 from makortel/scheduleReplace
Browse files Browse the repository at this point in the history
Be consistent when replacing a Path/EndPath/Task in a Process that is also in a Schedule
  • Loading branch information
cmsbuild committed Oct 14, 2021
2 parents 41f1639 + 3d5ab42 commit d68bfe9
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
43 changes: 36 additions & 7 deletions FWCore/ParameterSet/python/Config.py
Expand Up @@ -504,6 +504,9 @@ def __setattr__(self,name,value):
if s is not None:
raise ValueError(msg1+"endpath "+s.label_()+msg2)

if not self.__InExtendCall and (Schedule._itemIsValid(newValue) or isinstance(newValue, Task)):
self._replaceInScheduleDirectly(name, newValue)

self._delattrFromSetattr(name)
self.__dict__[name]=newValue
if isinstance(newValue,_Labelable):
Expand Down Expand Up @@ -561,6 +564,8 @@ def __delattr__(self,name):
self._replaceInSchedule(name, None)
if isinstance(obj, _Sequenceable) or obj._isTaskComponent():
self._replaceInSequences(name, None)
if Schedule._itemIsValid(obj) or isinstance(obj, Task):
self._replaceInScheduleDirectly(name, None)
# now remove it from the process itself
try:
del self.__dict__[name]
Expand Down Expand Up @@ -1088,6 +1093,11 @@ def _replaceInSchedule(self, label, new):
old = getattr(self,label)
for task in self.schedule_()._tasks:
task.replace(old, new)
def _replaceInScheduleDirectly(self, label, new):
if self.schedule_() == None:
return
old = getattr(self,label)
self.schedule_()._replaceIfHeldDirectly(old, new)
def globalReplace(self,label,new):
""" Replace the item with label 'label' by object 'new' in the process and all sequences/paths/tasks"""
if not hasattr(self,label):
Expand Down Expand Up @@ -2339,6 +2349,16 @@ def testGlobalReplace(self):
listOfTasks[0].visit(visitor6)
self.assertTrue(visitor6.modules == set([new2]))

p.d2 = EDProducer("YourProducer")
p.schedule = Schedule(p.p, p.p2, p.e3, tasks=[p.t1])
self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
p.p = Path(p.c+s)
self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
p.e3 = EndPath(p.c)
self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
p.t1 = Task(p.d2)
self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")

def testSequence(self):
p = Process('test')
p.a = EDAnalyzer("MyAnalyzer")
Expand Down Expand Up @@ -3284,24 +3304,33 @@ def testDelete(self):
p.t1 = Task(p.g, p.h)
t2 = Task(p.g, p.h)
t3 = Task(p.g, p.h)
p.t4 = Task(p.h)
p.s = Sequence(p.d+p.e)
p.path1 = Path(p.a+p.f+p.s,t2)
p.path2 = Path(p.a)
p.endpath2 = EndPath(p.b)
p.endpath1 = EndPath(p.b+p.f)
p.schedule = Schedule(tasks=[t3])
p.schedule = Schedule(p.path2, p.endpath2, tasks=[t3, p.t4])
self.assertTrue(hasattr(p, 'f'))
self.assertTrue(hasattr(p, 'g'))
del p.e
del p.f
del p.g
self.assertFalse(hasattr(p, 'f'))
self.assertFalse(hasattr(p, 'g'))
self.assertTrue(p.t1.dumpPython() == 'cms.Task(process.h)\n')
self.assertTrue(p.s.dumpPython() == 'cms.Sequence(process.d)\n')
self.assertTrue(p.path1.dumpPython() == 'cms.Path(process.a+process.s, cms.Task(process.h))\n')
self.assertTrue(p.endpath1.dumpPython() == 'cms.EndPath(process.b)\n')
self.assertEqual(p.t1.dumpPython(), 'cms.Task(process.h)\n')
self.assertEqual(p.s.dumpPython(), 'cms.Sequence(process.d)\n')
self.assertEqual(p.path1.dumpPython(), 'cms.Path(process.a+process.s, cms.Task(process.h))\n')
self.assertEqual(p.endpath1.dumpPython(), 'cms.EndPath(process.b)\n')
del p.s
self.assertTrue(p.path1.dumpPython() == 'cms.Path(process.a+(process.d), cms.Task(process.h))\n')
self.assertTrue(p.schedule_().dumpPython() == 'cms.Schedule(tasks=[cms.Task(process.h)])\n')
self.assertEqual(p.path1.dumpPython(), 'cms.Path(process.a+(process.d), cms.Task(process.h))\n')
self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(*[ process.path2, process.endpath2 ], tasks=[cms.Task(process.h), process.t4])\n')
del p.path2
self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(*[ process.endpath2 ], tasks=[cms.Task(process.h), process.t4])\n')
del p.endpath2
self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(tasks=[cms.Task(process.h), process.t4])\n')
del p.t4
self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(tasks=[cms.Task(process.h)])\n')
def testModifier(self):
m1 = Modifier()
p = Process("test",m1)
Expand Down
20 changes: 20 additions & 0 deletions FWCore/ParameterSet/python/SequenceTypes.py
Expand Up @@ -754,6 +754,26 @@ def copy(self):
return aCopy
def _place(self,label,process):
process.setPartialSchedule_(self,label)
def _replaceIfHeldDirectly(self,original,replacement):
"""Only replaces an 'original' with 'replacement' if 'original' is directly held.
If a contained Path or Task holds 'original' it will not be replaced."""
didReplace = False
if original in self._tasks:
self._tasks.remove(original)
if replacement is not None:
self._tasks.add(replacement)
didReplace = True
indices = []
for i, e in enumerate(self):
if original == e:
indices.append(i)
for i in reversed(indices):
self.pop(i)
if replacement is not None:
self.insert(i, replacement)
didReplace = True
return didReplace

def moduleNames(self):
result = set()
visitor = NodeNameVisitor(result)
Expand Down

0 comments on commit d68bfe9

Please sign in to comment.