ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/Splitter.py
Revision: 1.13
Committed: Tue May 26 10:23:01 2009 UTC (15 years, 11 months ago) by spiga
Content type: text/x-python
Branch: MAIN
Changes since 1.12: +28 -30 lines
Log Message:
adapting code to logging usage. (crab_logger removed)

File Contents

# User Rev Content
1 spiga 1.1 import common
2     from crab_exceptions import *
3     from crab_util import *
4     from WMCore.SiteScreening.BlackWhiteListParser import SEBlackWhiteListParser
5    
6     class JobSplitter:
7     def __init__( self, cfg_params, args ):
8     self.cfg_params = cfg_params
9 spiga 1.3 self.args=args
10 spiga 1.1 #self.maxEvents
11     # init BlackWhiteListParser
12     seWhiteList = cfg_params.get('EDG.se_white_list',[])
13     seBlackList = cfg_params.get('EDG.se_black_list',[])
14     self.blackWhiteListParser = SEBlackWhiteListParser(seWhiteList, seBlackList, common.logger)
15    
16    
17     def checkUserSettings(self):
18     ## Events per job
19     if self.cfg_params.has_key('CMSSW.events_per_job'):
20     self.eventsPerJob =int( self.cfg_params['CMSSW.events_per_job'])
21     self.selectEventsPerJob = 1
22     else:
23     self.eventsPerJob = -1
24     self.selectEventsPerJob = 0
25    
26     ## number of jobs
27     if self.cfg_params.has_key('CMSSW.number_of_jobs'):
28     self.theNumberOfJobs =int( self.cfg_params['CMSSW.number_of_jobs'])
29     self.selectNumberOfJobs = 1
30     else:
31     self.theNumberOfJobs = 0
32     self.selectNumberOfJobs = 0
33    
34     if self.cfg_params.has_key('CMSSW.total_number_of_events'):
35     self.total_number_of_events = int(self.cfg_params['CMSSW.total_number_of_events'])
36     self.selectTotalNumberEvents = 1
37     if self.selectNumberOfJobs == 1:
38     if (self.total_number_of_events != -1) and int(self.total_number_of_events) < int(self.theNumberOfJobs):
39     msg = 'Must specify at least one event per job. total_number_of_events > number_of_jobs '
40     raise CrabException(msg)
41     else:
42     self.total_number_of_events = 0
43     self.selectTotalNumberEvents = 0
44    
45    
46     ########################################################################
47     def jobSplittingByEvent( self ):
48     """
49     Perform job splitting. Jobs run over an integer number of files
50     and no more than one block.
51     ARGUMENT: blockSites: dictionary with blocks as keys and list of host sites as values
52     REQUIRES: self.selectTotalNumberEvents, self.selectEventsPerJob, self.selectNumberofJobs,
53     self.total_number_of_events, self.eventsPerJob, self.theNumberOfJobs,
54     self.maxEvents, self.filesbyblock
55 spiga 1.3 SETS: jobDestination - Site destination(s) for each job (a list of lists)
56 spiga 1.1 self.total_number_of_jobs - Total # of jobs
57     self.list_of_args - File(s) job will run on (a list of lists)
58     """
59    
60 spiga 1.3 jobDestination=[]
61 spiga 1.1 self.checkUserSettings()
62     if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
63     msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
64     raise CrabException(msg)
65    
66 spiga 1.4 blockSites = self.args['blockSites']
67     pubdata = self.args['pubdata']
68 spiga 1.3 filesbyblock=pubdata.getFiles()
69    
70     self.eventsbyblock=pubdata.getEventsPerBlock()
71     self.eventsbyfile=pubdata.getEventsPerFile()
72     self.parentFiles=pubdata.getParent()
73 spiga 1.1
74     ## get max number of events
75 spiga 1.3 self.maxEvents=pubdata.getMaxEvents()
76 spiga 1.1
77     self.useParent = int(self.cfg_params.get('CMSSW.use_parent',0))
78     noBboundary = int(self.cfg_params.get('CMSSW.no_block_boundary',0))
79    
80     # ---- Handle the possible job splitting configurations ---- #
81     if (self.selectTotalNumberEvents):
82     totalEventsRequested = self.total_number_of_events
83     if (self.selectEventsPerJob):
84     eventsPerJobRequested = self.eventsPerJob
85     if (self.selectNumberOfJobs):
86     totalEventsRequested = self.theNumberOfJobs * self.eventsPerJob
87    
88     # If user requested all the events in the dataset
89     if (totalEventsRequested == -1):
90     eventsRemaining=self.maxEvents
91     # If user requested more events than are in the dataset
92     elif (totalEventsRequested > self.maxEvents):
93     eventsRemaining = self.maxEvents
94 spiga 1.13 common.logger.info("Requested "+str(self.total_number_of_events)+ " events, but only "+str(self.maxEvents)+" events are available.")
95 spiga 1.1 # If user requested less events than are in the dataset
96     else:
97     eventsRemaining = totalEventsRequested
98    
99     # If user requested more events per job than are in the dataset
100     if (self.selectEventsPerJob and eventsPerJobRequested > self.maxEvents):
101     eventsPerJobRequested = self.maxEvents
102    
103     # For user info at end
104     totalEventCount = 0
105    
106     if (self.selectTotalNumberEvents and self.selectNumberOfJobs):
107     eventsPerJobRequested = int(eventsRemaining/self.theNumberOfJobs)
108    
109     if (self.selectNumberOfJobs):
110 spiga 1.13 common.logger.info("May not create the exact number_of_jobs requested.")
111 spiga 1.1
112     # old... to remove Daniele
113     totalNumberOfJobs = 999999999
114    
115 spiga 1.3 blocks = blockSites.keys()
116 spiga 1.1 blockCount = 0
117     # Backup variable in case self.maxEvents counted events in a non-included block
118     numBlocksInDataset = len(blocks)
119    
120     jobCount = 0
121     list_of_lists = []
122    
123     # list tracking which jobs are in which jobs belong to which block
124     jobsOfBlock = {}
125    
126     parString = ""
127     filesEventCount = 0
128    
129     # ---- Iterate over the blocks in the dataset until ---- #
130     # ---- we've met the requested total # of events ---- #
131     while ( (eventsRemaining > 0) and (blockCount < numBlocksInDataset) and (jobCount < totalNumberOfJobs)):
132     block = blocks[blockCount]
133     blockCount += 1
134     if block not in jobsOfBlock.keys() :
135     jobsOfBlock[block] = []
136    
137     if self.eventsbyblock.has_key(block) :
138     numEventsInBlock = self.eventsbyblock[block]
139 spiga 1.13 common.logger.debug('Events in Block File '+str(numEventsInBlock))
140 spiga 1.1
141 spiga 1.4 files = filesbyblock[block]
142 spiga 1.1 numFilesInBlock = len(files)
143     if (numFilesInBlock <= 0):
144     continue
145     fileCount = 0
146     if noBboundary == 0: # DD
147     # ---- New block => New job ---- #
148     parString = ""
149     # counter for number of events in files currently worked on
150     filesEventCount = 0
151     # flag if next while loop should touch new file
152     newFile = 1
153     # job event counter
154     jobSkipEventCount = 0
155    
156     # ---- Iterate over the files in the block until we've met the requested ---- #
157     # ---- total # of events or we've gone over all the files in this block ---- #
158     pString=''
159     while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
160     file = files[fileCount]
161     if self.useParent==1:
162     parent = self.parentFiles[file]
163     for f in parent :
164 spiga 1.11 pString += f + ','
165 spiga 1.13 common.logger.log(10-1, "File "+str(file)+" has the following parents: "+str(parent))
166 spiga 1.1 if newFile :
167     try:
168     numEventsInFile = self.eventsbyfile[file]
169 spiga 1.13 common.logger.log(10-1, "File "+str(file)+" has "+str(numEventsInFile)+" events")
170 spiga 1.1 # increase filesEventCount
171     filesEventCount += numEventsInFile
172     # Add file to current job
173 spiga 1.11 parString += file + ','
174 spiga 1.1 newFile = 0
175     except KeyError:
176 spiga 1.13 common.logger.info("File "+str(file)+" has unknown number of events: skipping")
177 spiga 1.1
178     eventsPerJobRequested = min(eventsPerJobRequested, eventsRemaining)
179     # if less events in file remain than eventsPerJobRequested
180     if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested):
181     if noBboundary == 1: ## DD
182     newFile = 1
183     fileCount += 1
184     else:
185     # if last file in block
186     if ( fileCount == numFilesInBlock-1 ) :
187     # end job using last file, use remaining events in block
188     # close job and touch new file
189 spiga 1.11 fullString = parString[:-1]
190 spiga 1.1 if self.useParent==1:
191 spiga 1.11 fullParentString = pString[:-1]
192 spiga 1.1 list_of_lists.append([fullString,fullParentString,str(-1),str(jobSkipEventCount)])
193     else:
194     list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
195 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
196 spiga 1.3 jobDestination.append(blockSites[block])
197 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" Destination: "+str(jobDestination[jobCount]))
198 spiga 1.1 # fill jobs of block dictionary
199     jobsOfBlock[block].append(jobCount+1)
200     # reset counter
201     jobCount = jobCount + 1
202     totalEventCount = totalEventCount + filesEventCount - jobSkipEventCount
203     eventsRemaining = eventsRemaining - filesEventCount + jobSkipEventCount
204     jobSkipEventCount = 0
205     # reset file
206     pString = ""
207     parString = ""
208     filesEventCount = 0
209     newFile = 1
210     fileCount += 1
211     else :
212     # go to next file
213     newFile = 1
214     fileCount += 1
215     # if events in file equal to eventsPerJobRequested
216     elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
217     # close job and touch new file
218 spiga 1.11 fullString = parString[:-1]
219 spiga 1.1 if self.useParent==1:
220 spiga 1.11 fullParentString = pString[:-1]
221 spiga 1.1 list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
222     else:
223     list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
224 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
225 spiga 1.3 jobDestination.append(blockSites[block])
226 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" Destination: "+str(jobDestination[jobCount]))
227 spiga 1.1 jobsOfBlock[block].append(jobCount+1)
228     # reset counter
229     jobCount = jobCount + 1
230     totalEventCount = totalEventCount + eventsPerJobRequested
231     eventsRemaining = eventsRemaining - eventsPerJobRequested
232     jobSkipEventCount = 0
233     # reset file
234     pString = ""
235     parString = ""
236     filesEventCount = 0
237     newFile = 1
238     fileCount += 1
239    
240     # if more events in file remain than eventsPerJobRequested
241     else :
242     # close job but don't touch new file
243 spiga 1.11 fullString = parString[:-1]
244 spiga 1.1 if self.useParent==1:
245 spiga 1.11 fullParentString = pString[:-1]
246 spiga 1.1 list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
247     else:
248     list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
249 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
250 spiga 1.3 jobDestination.append(blockSites[block])
251 spiga 1.13 common.logger.debug("Job "+str(jobCount+1)+" Destination: "+str(jobDestination[jobCount]))
252 spiga 1.1 jobsOfBlock[block].append(jobCount+1)
253     # increase counter
254     jobCount = jobCount + 1
255     totalEventCount = totalEventCount + eventsPerJobRequested
256     eventsRemaining = eventsRemaining - eventsPerJobRequested
257     # calculate skip events for last file
258     # use filesEventCount (contains several files), jobSkipEventCount and eventsPerJobRequest
259     jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
260     # remove all but the last file
261     filesEventCount = self.eventsbyfile[file]
262     if self.useParent==1:
263 spiga 1.11 for f in parent : pString += f + ','
264     parString = file + ','
265 spiga 1.1 pass # END if
266     pass # END while (iterate over files in the block)
267     pass # END while (iterate over blocks in the dataset)
268     self.ncjobs = self.total_number_of_jobs = jobCount
269     if (eventsRemaining > 0 and jobCount < totalNumberOfJobs ):
270 spiga 1.13 common.logger.info("Could not run on all requested events because some blocks not hosted at allowed sites.")
271     common.logger.info(str(jobCount)+" job(s) can run on "+str(totalEventCount)+" events.\n")
272 spiga 1.1
273     # skip check on block with no sites DD
274 spiga 1.5 if noBboundary == 0 : self.checkBlockNoSite(blocks,jobsOfBlock,blockSites)
275 spiga 1.1
276     # prepare dict output
277     dictOut = {}
278 spiga 1.11 dictOut['params']= ['InputFiles','MaxEvents','SkipEvents']
279     if self.useParent: dictOut['params']= ['InputFiles','ParentFiles','MaxEvents','SkipEvents']
280 spiga 1.1 dictOut['args'] = list_of_lists
281 spiga 1.3 dictOut['jobDestination'] = jobDestination
282 spiga 1.1 dictOut['njobs']=self.total_number_of_jobs
283    
284     return dictOut
285    
286     # keep trace of block with no sites to print a warning at the end
287    
288 spiga 1.5 def checkBlockNoSite(self,blocks,jobsOfBlock,blockSites):
289 spiga 1.1 # screen output
290     screenOutput = "List of jobs and available destination sites:\n\n"
291     noSiteBlock = []
292     bloskNoSite = []
293 spiga 1.10 allBlock = []
294 spiga 1.1
295     blockCounter = 0
296     for block in blocks:
297     if block in jobsOfBlock.keys() :
298     blockCounter += 1
299 spiga 1.10 allBlock.append( blockCounter )
300 spiga 1.1 screenOutput += "Block %5i: jobs %20s: sites: %s\n" % (blockCounter,spanRanges(jobsOfBlock[block]),
301 spiga 1.3 ','.join(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],[block]),[block])))
302     if len(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],[block]),[block])) == 0:
303 spiga 1.1 noSiteBlock.append( spanRanges(jobsOfBlock[block]) )
304     bloskNoSite.append( blockCounter )
305    
306 spiga 1.13 common.logger.info(screenOutput)
307 spiga 1.1 if len(noSiteBlock) > 0 and len(bloskNoSite) > 0:
308     msg = 'WARNING: No sites are hosting any part of data for block:\n '
309     virgola = ""
310     if len(bloskNoSite) > 1:
311     virgola = ","
312     for block in bloskNoSite:
313     msg += ' ' + str(block) + virgola
314     msg += '\n Related jobs:\n '
315     virgola = ""
316     if len(noSiteBlock) > 1:
317     virgola = ","
318     for range_jobs in noSiteBlock:
319     msg += str(range_jobs) + virgola
320     msg += '\n will not be submitted and this block of data can not be analyzed!\n'
321     if self.cfg_params.has_key('EDG.se_white_list'):
322     msg += 'WARNING: SE White List: '+self.cfg_params['EDG.se_white_list']+'\n'
323     msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
324     msg += 'Please check if the dataset is available at this site!)\n'
325     if self.cfg_params.has_key('EDG.ce_white_list'):
326     msg += 'WARNING: CE White List: '+self.cfg_params['EDG.ce_white_list']+'\n'
327     msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
328     msg += 'Please check if the dataset is available at this site!)\n'
329    
330 spiga 1.13 common.logger.info(msg)
331 spiga 1.1
332 spiga 1.10 if bloskNoSite == allBlock:
333     raise CrabException('No jobs created')
334    
335 spiga 1.1 return
336    
337    
338     ########################################################################
339     def jobSplittingByRun(self):
340     """
341     """
342     from sets import Set
343     from WMCore.JobSplitting.RunBased import RunBased
344     from WMCore.DataStructs.Workflow import Workflow
345     from WMCore.DataStructs.File import File
346     from WMCore.DataStructs.Fileset import Fileset
347     from WMCore.DataStructs.Subscription import Subscription
348     from WMCore.JobSplitting.SplitterFactory import SplitterFactory
349     from WMCore.DataStructs.Run import Run
350    
351     self.checkUserSettings()
352 spiga 1.4 blockSites = self.args['blockSites']
353     pubdata = self.args['pubdata']
354 spiga 1.1
355     if self.selectNumberOfJobs == 0 :
356     self.theNumberOfJobs = 9999999
357     blocks = {}
358     runList = []
359     thefiles = Fileset(name='FilesToSplit')
360 spiga 1.3 fileList = pubdata.getListFiles()
361 spiga 1.1 for f in fileList:
362     block = f['Block']['Name']
363     try:
364 spiga 1.3 f['Block']['StorageElementList'].extend(blockSites[block])
365 spiga 1.1 except:
366     continue
367     wmbsFile = File(f['LogicalFileName'])
368 spiga 1.3 [ wmbsFile['locations'].add(x) for x in blockSites[block] ]
369 spiga 1.1 wmbsFile['block'] = block
370     runNum = f['RunsList'][0]['RunNumber']
371     runList.append(runNum)
372     myRun = Run(runNumber=runNum)
373     wmbsFile.addRun( myRun )
374     thefiles.addFile(
375     wmbsFile
376     )
377    
378     work = Workflow()
379     subs = Subscription(
380     fileset = thefiles,
381     workflow = work,
382     split_algo = 'RunBased',
383     type = "Processing")
384     splitter = SplitterFactory()
385     jobfactory = splitter(subs)
386    
387     #loop over all runs
388     set = Set(runList)
389     list_of_lists = []
390     jobDestination = []
391    
392     count = 0
393     for i in list(set):
394     if count < self.theNumberOfJobs:
395     res = self.getJobInfo(jobfactory())
396     parString = ''
397     for file in res['lfns']:
398 spiga 1.11 parString += file + ','
399     fullString = parString[:-1]
400 spiga 1.1 list_of_lists.append([fullString,str(-1),str(0)])
401 spiga 1.2 #need to check single file location
402 spiga 1.1 jobDestination.append(res['locations'])
403     count +=1
404     # prepare dict output
405     dictOut = {}
406 spiga 1.11 dictOut['params']= ['InputFiles','MaxEvents','SkipEvents']
407 spiga 1.1 dictOut['args'] = list_of_lists
408     dictOut['jobDestination'] = jobDestination
409     dictOut['njobs']=count
410    
411     return dictOut
412    
413     def getJobInfo( self,jobGroup ):
414     res = {}
415     lfns = []
416     locations = []
417     tmp_check=0
418     for job in jobGroup.jobs:
419     for file in job.getFiles():
420     lfns.append(file['lfn'])
421     for loc in file['locations']:
422     if tmp_check < 1 :
423     locations.append(loc)
424 spiga 1.8 tmp_check = tmp_check + 1
425 spiga 1.1 ### qui va messo il check per la locations
426     res['lfns'] = lfns
427     res['locations'] = locations
428     return res
429    
430     ########################################################################
431     def jobSplittingNoInput(self):
432     """
433     Perform job splitting based on number of event per job
434     """
435 spiga 1.13 common.logger.debug('Splitting per events')
436 spiga 1.3 self.checkUserSettings()
437     jobDestination=[]
438 spiga 1.6 if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
439     msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
440 spiga 1.3 raise CrabException(msg)
441    
442     managedGenerators =self.args['managedGenerators']
443     generator = self.args['generator']
444     firstRun = self.cfg_params.get('CMSSW.first_run',None)
445 spiga 1.1
446     if (self.selectEventsPerJob):
447 spiga 1.13 common.logger.info('Required '+str(self.eventsPerJob)+' events per job ')
448 spiga 1.1 if (self.selectNumberOfJobs):
449 spiga 1.13 common.logger.info('Required '+str(self.theNumberOfJobs)+' jobs in total ')
450 spiga 1.1 if (self.selectTotalNumberEvents):
451 spiga 1.13 common.logger.info('Required '+str(self.total_number_of_events)+' events in total ')
452 spiga 1.1
453     if (self.total_number_of_events < 0):
454     msg='Cannot split jobs per Events with "-1" as total number of events'
455     raise CrabException(msg)
456    
457     if (self.selectEventsPerJob):
458     if (self.selectTotalNumberEvents):
459     self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
460     elif(self.selectNumberOfJobs) :
461     self.total_number_of_jobs =self.theNumberOfJobs
462     self.total_number_of_events =int(self.theNumberOfJobs*self.eventsPerJob)
463    
464     elif (self.selectNumberOfJobs) :
465     self.total_number_of_jobs = self.theNumberOfJobs
466     self.eventsPerJob = int(self.total_number_of_events/self.total_number_of_jobs)
467    
468 spiga 1.13 common.logger.debug('N jobs '+str(self.total_number_of_jobs))
469 spiga 1.1
470     # is there any remainder?
471     check = int(self.total_number_of_events) - (int(self.total_number_of_jobs)*self.eventsPerJob)
472    
473 spiga 1.13 common.logger.debug('Check '+str(check))
474 spiga 1.1
475 spiga 1.13 common.logger.info(str(self.total_number_of_jobs)+' jobs can be created, each for '+str(self.eventsPerJob)+' for a total of '+str(self.total_number_of_jobs*self.eventsPerJob)+' events')
476 spiga 1.1 if check > 0:
477 spiga 1.13 common.logger.info('Warning: asked '+str(self.total_number_of_events)+' but can do only '+str(int(self.total_number_of_jobs)*self.eventsPerJob))
478 spiga 1.1
479     # argument is seed number.$i
480     self.list_of_args = []
481     for i in range(self.total_number_of_jobs):
482     ## Since there is no input, any site is good
483 spiga 1.3 jobDestination.append([""]) #must be empty to write correctly the xml
484 spiga 1.1 args=[]
485 spiga 1.3 if (firstRun):
486 spiga 1.1 ## pythia first run
487 spiga 1.3 args.append(str(firstRun)+str(i))
488     if (generator in managedGenerators):
489     if (generator == 'comphep' and i == 0):
490 spiga 1.1 # COMPHEP is brain-dead and wants event #'s like 1,100,200,300
491     args.append('1')
492     else:
493     args.append(str(i*self.eventsPerJob))
494 spiga 1.7 args.append(str(self.eventsPerJob))
495 spiga 1.1 self.list_of_args.append(args)
496     # prepare dict output
497 spiga 1.11
498 spiga 1.1 dictOut = {}
499 spiga 1.11 dictOut['params'] = ['MaxEvents']
500     if (firstRun):
501     dictOut['params'] = ['FirstRun','MaxEvents']
502 spiga 1.12 if ( generator in managedGenerators ) : dictOut['params'] = ['FirstRun', 'FirstEvent', 'MaxEvents']
503 spiga 1.11 else:
504 spiga 1.12 if (generator in managedGenerators) : dictOut['params'] = ['FirstEvent', 'MaxEvents']
505 spiga 1.1 dictOut['args'] = self.list_of_args
506 spiga 1.3 dictOut['jobDestination'] = jobDestination
507 spiga 1.1 dictOut['njobs']=self.total_number_of_jobs
508    
509     return dictOut
510    
511    
512     def jobSplittingForScript(self):
513     """
514     Perform job splitting based on number of job
515     """
516     self.checkUserSettings()
517 spiga 1.3 if (self.selectNumberOfJobs == 0):
518 spiga 1.1 msg = 'must specify number_of_jobs.'
519     raise crabexception(msg)
520 spiga 1.3 jobDestination = []
521 spiga 1.13 common.logger.debug('Splitting per job')
522     common.logger.info('Required '+str(self.theNumberOfJobs)+' jobs in total ')
523 spiga 1.1
524     self.total_number_of_jobs = self.theNumberOfJobs
525    
526 spiga 1.13 common.logger.debug('N jobs '+str(self.total_number_of_jobs))
527 spiga 1.1
528 spiga 1.13 common.logger.info(str(self.total_number_of_jobs)+' jobs can be created')
529 spiga 1.1
530     # argument is seed number.$i
531 spiga 1.11 #self.list_of_args = []
532 spiga 1.1 for i in range(self.total_number_of_jobs):
533 spiga 1.3 jobDestination.append([""])
534 spiga 1.11 # self.list_of_args.append([str(i)])
535 spiga 1.1
536     # prepare dict output
537     dictOut = {}
538 spiga 1.11 dictOut['args'] = [] # self.list_of_args
539 spiga 1.3 dictOut['jobDestination'] = jobDestination
540 spiga 1.1 dictOut['njobs']=self.total_number_of_jobs
541     return dictOut
542    
543    
544     def jobSplittingByLumi(self):
545     """
546     """
547     return
548     def Algos(self):
549     """
550     Define key splittingType matrix
551     """
552     SplitAlogs = {
553     'EventBased' : self.jobSplittingByEvent,
554     'RunBased' : self.jobSplittingByRun,
555     'LumiBased' : self.jobSplittingByLumi,
556     'NoInput' : self.jobSplittingNoInput,
557     'ForScript' : self.jobSplittingForScript
558     }
559     return SplitAlogs
560