File indexing completed on 2024-12-01 23:40:27
0001
0002
0003
0004 from FWCore.ParameterSet.Config import Service
0005 import FWCore.ParameterSet.Types as CfgTypes
0006
0007
0008 class RandomNumberServiceHelper(object):
0009 """
0010 _RandomNumberServiceHelper_
0011
0012 Helper class to hold and handle the Random number generator service.
0013
0014 Provide both user level and WM APIs.
0015
0016 Author: Dave Evans
0017 Modified: Eric Vaandering
0018 """
0019
0020 def __init__(self,randService):
0021 self._randService = randService
0022 self._lockedSeeds = []
0023
0024
0025 def __containsSeed(self,psetInstance):
0026 """
0027 _keeper_
0028
0029 True/False if the psetInstance has seeds in it
0030
0031 """
0032 if psetInstance is None:
0033 return False
0034 if not isinstance(psetInstance,CfgTypes.PSet):
0035 return False
0036 seedList = getattr(psetInstance, "initialSeedSet", None)
0037 if seedList != None:
0038 return True
0039 seedVal = getattr(psetInstance, "initialSeed", None)
0040 if seedVal != None:
0041 return True
0042 return False
0043
0044
0045 def __psetsWithSeeds(self):
0046 """
0047 _psetsWithSeeds_
0048
0049 *private method*
0050
0051 return the list of PSet instances with seeds in them
0052
0053 """
0054 svcAttrs = [getattr(self._randService, item, None)
0055 for item in self._randService.parameters_()
0056 if item not in self._lockedSeeds]
0057
0058
0059
0060 return list(filter(self.__containsSeed, svcAttrs))
0061
0062
0063 def countSeeds(self):
0064 """
0065 _countSeeds_
0066
0067 Count the number of seeds required by this service by
0068 summing up the initialSeed and initialSeedSet entries
0069 in all PSets in the service that contain those parameters.
0070
0071 """
0072 count = 0
0073
0074 for itemRef in self.__psetsWithSeeds():
0075
0076
0077
0078 seedSet = getattr(itemRef, "initialSeedSet", None)
0079 if seedSet != None:
0080 count += len( seedSet.value())
0081 continue
0082
0083
0084
0085 seedVal = getattr(itemRef, "initialSeed", None)
0086 if seedVal != None:
0087 count += 1
0088
0089
0090
0091
0092 return count
0093
0094
0095 def setNamedSeed(self, psetName, *seeds):
0096 """
0097 _setNamedSeed_
0098
0099 If a specific set of seeds is needed for a PSet in this
0100 service, they can be set by name using this method.
0101
0102 - *psetName* : Name of the pset containing the seeds
0103
0104 - *seeds* : list of seeds to be added, should be a single seed
0105 for initialSeed values.
0106
0107 """
0108 pset = getattr(self._randService, psetName, None)
0109 if pset == None:
0110 msg = "No PSet named %s belongs to this instance of the" % (
0111 psetName,)
0112 msg += "Random Seed Service"
0113 raise RuntimeError(msg)
0114
0115 seedVal = getattr(pset, "initialSeed", None)
0116 if seedVal != None:
0117 pset.initialSeed = CfgTypes.untracked(
0118 CfgTypes.uint32(seeds[0])
0119 )
0120
0121 return
0122 seedSet = getattr(pset, "initialSeedSet", None)
0123 if seedSet != None:
0124
0125
0126
0127
0128 pset.initialSeedSet = CfgTypes.untracked(
0129 CfgTypes.vuint32(*seeds))
0130 return
0131
0132
0133
0134 return
0135
0136
0137 def getNamedSeed(self, psetName):
0138 """
0139 _getNamedSeed_
0140
0141 This method returns the seeds in a PSet in this service. Returned
0142
0143 - *psetName* : Name of the pset containing the seeds
0144
0145 """
0146 pset = getattr(self._randService, psetName, None)
0147 if pset == None:
0148 msg = "No PSet named %s belongs to this instance of the" % (
0149 psetName,)
0150 msg += "Random Seed Service"
0151 raise RuntimeError(msg)
0152
0153 seedVal = getattr(pset, "initialSeed", None)
0154 if seedVal != None:
0155 return [pset.initialSeed.value()]
0156
0157 seedSet = getattr(pset, "initialSeedSet", None)
0158 if seedSet != None:
0159 return pset.initialSeedSet
0160
0161
0162 def insertSeeds(self, *seeds):
0163 """
0164 _insertSeeds_
0165
0166 Given some list of specific seeds, insert them into the
0167 service.
0168
0169 Length of seed list is required to be same as the seed count for
0170 the service.
0171
0172 Usage: WM Tools.
0173
0174 """
0175 seeds = list(seeds)
0176 if len(seeds) < self.countSeeds():
0177 msg = "Not enough seeds provided\n"
0178 msg += "Service requires %s seeds, only %s provided\n"
0179 msg += "to RandomeService.insertSeeds method\n"
0180 raise RuntimeError(msg)
0181
0182 for item in self.__psetsWithSeeds():
0183 seedSet = getattr(item, "initialSeedSet", None)
0184 if seedSet != None:
0185 numSeeds = len(seedSet.value())
0186 useSeeds = seeds[:numSeeds]
0187 seeds = seeds[numSeeds:]
0188 item.initialSeedSet = CfgTypes.untracked(
0189 CfgTypes.vuint32(*useSeeds))
0190 continue
0191 useSeed = seeds[0]
0192 seeds = seeds[1:]
0193 item.initialSeed = CfgTypes.untracked(
0194 CfgTypes.uint32(useSeed)
0195 )
0196 continue
0197 return
0198
0199
0200 def populate(self, *excludePSets):
0201 """
0202 _populate_
0203
0204 generate a bunch of seeds and stick them into this service
0205 This is the lazy user method.
0206
0207 Optional args are names of PSets to *NOT* alter seeds.
0208
0209 Eg:
0210 populate() will set all seeds
0211 populate("pset1", "pset2") will set all seeds but not those in
0212 psets named pset1 and pset2
0213
0214 """
0215
0216 import random
0217 from random import SystemRandom
0218 _inst = SystemRandom()
0219 _MAXINT = 900000000
0220
0221
0222
0223
0224 newSeeds = [ _inst.randint(1, _MAXINT)
0225 for i in range(self.countSeeds())]
0226
0227
0228 self._lockedSeeds = list(excludePSets)
0229 self.insertSeeds(*newSeeds)
0230 self._lockedSeeds = []
0231 return
0232
0233
0234 def resetSeeds(self, value):
0235 """
0236 _resetSeeds_
0237
0238 reset all seeds to given value
0239
0240 """
0241 newSeeds = [ value for i in range(self.countSeeds())]
0242 self.insertSeeds(*newSeeds)
0243 return
0244
0245
0246
0247 if __name__ == '__main__':
0248
0249
0250
0251 randSvc = Service("RandomNumberGeneratorService")
0252 randHelper = RandomNumberServiceHelper(randSvc)
0253
0254 randSvc.i1 = CfgTypes.untracked(CfgTypes.uint32(1))
0255 randSvc.t1 = CfgTypes.PSet()
0256 randSvc.t2 = CfgTypes.PSet()
0257 randSvc.t3 = CfgTypes.PSet()
0258
0259 randSvc.t1.initialSeed = CfgTypes.untracked(
0260 CfgTypes.uint32(123455678)
0261 )
0262
0263 randSvc.t2.initialSeedSet = CfgTypes.untracked(
0264 CfgTypes.vuint32(12345,234567,345677)
0265 )
0266
0267
0268 randSvc.t3.initialSeed = CfgTypes.untracked(
0269 CfgTypes.uint32(987654321)
0270 )
0271
0272 print("Inital PSet")
0273 print(randSvc)
0274
0275
0276
0277
0278
0279 print("Totally Random PSet")
0280 randHelper.populate()
0281 print(randSvc)
0282
0283
0284
0285
0286
0287 print("All seeds 9999")
0288 randHelper.resetSeeds(9999)
0289 print(randSvc)
0290
0291
0292
0293
0294 print("t1,t3 9998")
0295 randHelper.setNamedSeed("t1", 9998)
0296 randHelper.setNamedSeed("t3", 9998, 9998)
0297 print(randSvc)
0298
0299 print("t1 seed(s)",randHelper.getNamedSeed("t1"))
0300 print("t2 seed(s)",randHelper.getNamedSeed("t2"))
0301
0302
0303
0304
0305
0306 randHelper.populate("t1", "t3")
0307 print("t2 randomized")
0308 print(randSvc)