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