5 import os, sys, imp, re, pprint, string, time,shutil,copy,pickle,math
6 from optparse
import OptionParser
9 from PhysicsTools.HeppyCore.utils.batchmanager
import BatchManager
10 import PhysicsTools.HeppyCore.utils.eostools
as castortools
14 from IOMC.RandomEngine.RandomServiceHelper
import RandomNumberServiceHelper
20 script =
"""!/usr/bin/env bash
21 #PBS -l platform=LINUX,u_sps_cmsf,M=2000MB,T=2000000
28 source $HOME/.bash_profile
30 echo '***********************'
34 # coming back to submission dir do setup the env
43 cp -r $PBS_O_WORKDIR .
51 cat > sysinfo.sh <<EOF
53 echo '************** ENVIRONMENT ****************'
58 echo '************** WORKER *********************'
65 echo '************** START *********************'
69 source sysinfo.sh > sysinfo.txt
73 # copy job dir do disk
75 cp -r $jobdir $PBS_O_WORKDIR
81 '''prepare the LSF version of the batch script, to run on LSF'''
82 script =
"""#!/bin/bash
90 echo 'copying job dir to worker'
96 cd `find . -type d | grep /`
100 echo wrong exit code! removing all root files
104 echo 'sending the job directory back'
108 remoteDir = castortools.eosToLFN(remoteDir)
110 for file in *.root; do
111 newFileName=`echo $file | sed -r -e 's/\./_%s\./'`
112 fullFileName=%s/$newFileName
113 #this does cmsStage, but with retries
114 cmsStageWithFailover.py -f $file $fullFileName
115 #write the files as user readable but not writable
116 eos chmod 755 /eos/cms/$fullFileName
118 """ % (index, remoteDir)
119 script +=
'rm *.root\n'
120 script +=
'cp -rf * $LS_SUBCWD\n'
126 '''prepare a local version of the batch script, to run using nohup'''
128 script =
"""#!/bin/bash
132 echo wrong exit code! removing all root files
136 echo 'sending the job directory back'
140 remoteDir = castortools.eosToLFN(remoteDir)
142 for file in *.root; do
143 newFileName=`echo $file | sed -r -e 's/\./_%s\./'`
144 cmsStageWithFailover.py -f $file $fullFileName
145 eos chmod 755 /eos/cms/$fullFileName
147 """ % (index, remoteDir)
148 script +=
'rm *.root\n'
153 '''Exception class for this script'''
159 return str( self.
value)
163 '''Batch manager specific to cmsRun processes.'''
166 '''Prepare one job. This function is called by the base class.'''
168 process.source = fullSource.clone()
171 scriptFileName = jobDir+
'/batchScript.sh'
172 scriptFile = open(scriptFileName,
'w')
173 storeDir = self.remoteOutputDir_.replace(
'/castor/cern.ch/cms',
'')
174 mode = self.RunningMode(options.batch)
177 elif mode ==
'LOCAL':
180 os.system(
'chmod +x %s' % scriptFileName)
185 randSvc = RandomNumberServiceHelper(process.RandomNumberGeneratorService)
188 iFileMin = (value-1)*grouping
189 iFileMax = (value)*grouping
190 process.source.fileNames = fullSource.fileNames[iFileMin:iFileMax]
192 cfgFile = open(jobDir+
'/run_cfg.py',
'w')
193 cfgFile.write(
'import FWCore.ParameterSet.Config as cms\n\n')
194 cfgFile.write(
'import os,sys\n')
196 cfgFile.write(
"sys.path.append('%s')\n" % os.path.dirname(jobDir) )
197 cfgFile.write(
'from base_cfg import *\n')
198 cfgFile.write(
'process.source = ' + process.source.dumpPython() +
'\n')
200 cfgFile.write(
'process.RandomNumberGeneratorService = ' + process.RandomNumberGeneratorService.dumpPython() +
'\n')
207 file = open(
'cmsBatch.txt',
'w')
208 file.write(string.join(sys.argv) +
"\n")
211 batchManager.parser_.usage =
"""
212 %prog [options] <number of input files per job> <your_cfg.py>.
214 Submits a number of jobs taking your_cfg.py as a template. your_cfg.py can either read events from input files, or produce them with a generator. In the later case, the seeds are of course updated for each job.
216 A local output directory is created locally. This directory contains a job directory for each job, and a Logger/ directory containing information on the software you are using.
218 - the name of the output directory is created automatically.
219 - the output root files end up in the job directories.
221 Each job directory contains:
222 - the full python configuration for this job. You can run it interactively by doing:
224 - the batch script to run the job. You can submit it again by calling the batch command yourself, see the -b option.
225 - while running interactively: nohup.out, where the job stderr and stdout are redirected. To check the status of a job running interactively, do:
228 o the full nohup.out (your log) and your root files, in case you ran interactively
229 o the LSF directory, in case you ran on LSF
231 Also see fwBatch.py, which is a layer on top of cmsBatch.py adapted to the organization of our samples on the CMST3.
236 cd $CMSSW_BASE/src/CMGTools/Common/test
238 to run on your local machine:
239 cmsBatch.py 1 testCMGTools_cfg.py -b 'nohup ./batchScript.sh&'
241 to run on LSF (you must be logged on lxplus, not on your interactive machine, so that you have access to LSF)
242 cmsBatch.py 1 testCMGTools_cfg.py -b 'bsub -q 8nm < ./batchScript.sh'
244 batchManager.parser_.add_option(
"-p",
"--program", dest=
"prog",
245 help=
"program to run on your cfg file",
250 batchManager.parser_.add_option(
"-c",
"--command-args", dest=
"cmdargs",
251 help=
"command line arguments for the job",
253 batchManager.parser_.add_option(
"--notagCVS", dest=
"tagPackages",
254 default=
True,action=
"store_false",
255 help=
"tag the package on CVS (True)")
257 (options,args) = batchManager.parser_.parse_args()
258 batchManager.ParseOptions()
261 doCVSTag = options.tagPackages
264 batchManager.parser_.print_help()
270 runningMode = batchManager.RunningMode( options.batch )
271 except CmsBatchException
as err:
275 grouping = int(args[0])
277 cfgFileName = args[1]
281 pycfg_params = options.cmdargs
283 sys.argv = [cfgFileName]
285 sys.argv.extend(pycfg_params.split(
' '))
290 handle = open(cfgFileName,
'r')
291 cfo = imp.load_source("pycfg", cfgFileName, handle)
292 process = cfo.process
300 fullSource = process.source.clone()
304 process.source.fileNames
306 print 'No input file. This is a generator process.'
308 listOfValues = [i+1
for i
in range( nJobs )]
310 print "Number of files in the source:",len(process.source.fileNames),
":"
311 pprint.pprint(process.source.fileNames)
312 nFiles = len(process.source.fileNames)
313 nJobs = nFiles / grouping
314 if (nJobs!=0
and (nFiles % grouping) > 0)
or nJobs==0:
317 print "number of jobs to be created: ", nJobs
318 listOfValues = [i+1
for i
in range( nJobs )]
321 batchManager.PrepareJobs( listOfValues )
325 cfgFile = open(batchManager.outputDir_+
'/base_cfg.py',
'w')
326 cfgFile.write( process.dumpPython() +
'\n')
332 if runningMode ==
'LOCAL':
336 batchManager.SubmitJobs( waitingTime )
341 from PhysicsTools.HeppyCore.utils.logger
import logger
344 os.chdir(batchManager.outputDir_)
346 os.system(
'mkdir ' + logDir )
352 log.addFile( oldPwd +
'/' + cfgFileName )
354 if not batchManager.options_.negate:
355 if batchManager.remoteOutputDir_ !=
"":
358 log.stageOut( batchManager.remoteOutputDir_ )