forked from cms-sw/cmssw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRandomServiceHelper.py
308 lines (230 loc) · 7.88 KB
/
RandomServiceHelper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#!/usr/bin/env python
from FWCore.ParameterSet.Config import Service
import FWCore.ParameterSet.Types as CfgTypes
class RandomNumberServiceHelper(object):
"""
_RandomNumberServiceHelper_
Helper class to hold and handle the Random number generator service.
Provide both user level and WM APIs.
Author: Dave Evans
Modified: Eric Vaandering
"""
def __init__(self,randService):
self._randService = randService
self._lockedSeeds = []
def __containsSeed(self,psetInstance):
"""
_keeper_
True/False if the psetInstance has seeds in it
"""
if psetInstance is None:
return False
if not isinstance(psetInstance,CfgTypes.PSet):
return False
seedList = getattr(psetInstance, "initialSeedSet", None)
if seedList != None:
return True
seedVal = getattr(psetInstance, "initialSeed", None)
if seedVal != None:
return True
return False
def __psetsWithSeeds(self):
"""
_psetsWithSeeds_
*private method*
return the list of PSet instances with seeds in them
"""
svcAttrs = [getattr(self._randService, item, None)
for item in self._randService.parameters_()
if item not in self._lockedSeeds]
#print svcAttrs
return list(filter(self.__containsSeed, svcAttrs))
def countSeeds(self):
"""
_countSeeds_
Count the number of seeds required by this service by
summing up the initialSeed and initialSeedSet entries
in all PSets in the service that contain those parameters.
"""
count = 0
for itemRef in self.__psetsWithSeeds():
# //
# // PSet has list of seeds
#//
seedSet = getattr(itemRef, "initialSeedSet", None)
if seedSet != None:
count += len( seedSet.value())
continue
# //
# // PSet has single seed
#//
seedVal = getattr(itemRef, "initialSeed", None)
if seedVal != None:
count += 1
# //
# // PSet has no recognisable seed, therfore do nothing
#// with it
return count
def setNamedSeed(self, psetName, *seeds):
"""
_setNamedSeed_
If a specific set of seeds is needed for a PSet in this
service, they can be set by name using this method.
- *psetName* : Name of the pset containing the seeds
- *seeds* : list of seeds to be added, should be a single seed
for initialSeed values.
"""
pset = getattr(self._randService, psetName, None)
if pset == None:
msg = "No PSet named %s belongs to this instance of the" % (
psetName,)
msg += "Random Seed Service"
raise RuntimeError(msg)
seedVal = getattr(pset, "initialSeed", None)
if seedVal != None:
pset.initialSeed = CfgTypes.untracked(
CfgTypes.uint32(seeds[0])
)
return
seedSet = getattr(pset, "initialSeedSet", None)
if seedSet != None:
# //
# // Do we want to check the number of seeds??
#//
#if len(seeds) != len( seedSet.value()): pass
pset.initialSeedSet = CfgTypes.untracked(
CfgTypes.vuint32(*seeds))
return
# //
# // No seeds for that PSet
#// Error throw?
return
def getNamedSeed(self, psetName):
"""
_getNamedSeed_
This method returns the seeds in a PSet in this service. Returned
- *psetName* : Name of the pset containing the seeds
"""
pset = getattr(self._randService, psetName, None)
if pset == None:
msg = "No PSet named %s belongs to this instance of the" % (
psetName,)
msg += "Random Seed Service"
raise RuntimeError(msg)
seedVal = getattr(pset, "initialSeed", None)
if seedVal != None:
return [pset.initialSeed.value()]
seedSet = getattr(pset, "initialSeedSet", None)
if seedSet != None:
return pset.initialSeedSet
def insertSeeds(self, *seeds):
"""
_insertSeeds_
Given some list of specific seeds, insert them into the
service.
Length of seed list is required to be same as the seed count for
the service.
Usage: WM Tools.
"""
seeds = list(seeds)
if len(seeds) < self.countSeeds():
msg = "Not enough seeds provided\n"
msg += "Service requires %s seeds, only %s provided\n"
msg += "to RandomeService.insertSeeds method\n"
raise RuntimeError(msg)
for item in self.__psetsWithSeeds():
seedSet = getattr(item, "initialSeedSet", None)
if seedSet != None:
numSeeds = len(seedSet.value())
useSeeds = seeds[:numSeeds]
seeds = seeds[numSeeds:]
item.initialSeedSet = CfgTypes.untracked(
CfgTypes.vuint32(*useSeeds))
continue
useSeed = seeds[0]
seeds = seeds[1:]
item.initialSeed = CfgTypes.untracked(
CfgTypes.uint32(useSeed)
)
continue
return
def populate(self, *excludePSets):
"""
_populate_
generate a bunch of seeds and stick them into this service
This is the lazy user method.
Optional args are names of PSets to *NOT* alter seeds.
Eg:
populate() will set all seeds
populate("pset1", "pset2") will set all seeds but not those in
psets named pset1 and pset2
"""
import random
from random import SystemRandom
_inst = SystemRandom()
_MAXINT = 900000000
# //
# // count seeds and create the required number of seeds
#//
newSeeds = [ _inst.randint(1, _MAXINT)
for i in range(self.countSeeds())]
self._lockedSeeds = list(excludePSets)
self.insertSeeds(*newSeeds)
self._lockedSeeds = []
return
def resetSeeds(self, value):
"""
_resetSeeds_
reset all seeds to given value
"""
newSeeds = [ value for i in range(self.countSeeds())]
self.insertSeeds(*newSeeds)
return
if __name__ == '__main__':
# //
# // Setup a test service and populate it
#//
randSvc = Service("RandomNumberGeneratorService")
randHelper = RandomNumberServiceHelper(randSvc)
randSvc.i1 = CfgTypes.untracked(CfgTypes.uint32(1))
randSvc.t1 = CfgTypes.PSet()
randSvc.t2 = CfgTypes.PSet()
randSvc.t3 = CfgTypes.PSet()
randSvc.t1.initialSeed = CfgTypes.untracked(
CfgTypes.uint32(123455678)
)
randSvc.t2.initialSeedSet = CfgTypes.untracked(
CfgTypes.vuint32(12345,234567,345677)
)
randSvc.t3.initialSeed = CfgTypes.untracked(
CfgTypes.uint32(987654321)
)
print("Inital PSet")
print(randSvc)
# //
# // Autofill seeds
#//
print("Totally Random PSet")
randHelper.populate()
print(randSvc)
# //
# // Set all seeds with reset method
#//
print("All seeds 9999")
randHelper.resetSeeds(9999)
print(randSvc)
# //
# // test setting named seeds
#//
print("t1,t3 9998")
randHelper.setNamedSeed("t1", 9998)
randHelper.setNamedSeed("t3", 9998, 9998)
print(randSvc)
print("t1 seed(s)",randHelper.getNamedSeed("t1"))
print("t2 seed(s)",randHelper.getNamedSeed("t2"))
# //
# // Autofill seeds with exclusion list
#//
randHelper.populate("t1", "t3")
print("t2 randomized")
print(randSvc)