Skip to content

Commit 0609826

Browse files
authored
Merge branch 'develop' into mesmith75-patch-2
2 parents 0f0fb3a + ca18b5a commit 0609826

10 files changed

Lines changed: 117 additions & 195 deletions

File tree

python/Ganga/GPIDev/Lib/Tasks/ITransform.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,6 @@ def update(self):
214214
if task.transforms[trf_id].status != "completed":
215215
return 0
216216

217-
# set the start time if not already set
218-
if len(self.required_trfs) > 0 and self.units[0].start_time == 0:
219-
for unit in self.units:
220-
unit.start_time = time.time() + self.chain_delay * 60 - 1
221-
222217
# report the info for this transform
223218
unit_status = { "new":0, "hold":0, "running":0, "completed":0, "bad":0, "recreating":0 }
224219
for unit in self.units:
@@ -234,6 +229,11 @@ def update(self):
234229
# current data
235230
self.createUnits()
236231

232+
# set the start time if not already set
233+
if len(self.required_trfs) > 0 and self.units[0].start_time == 0:
234+
for unit in self.units:
235+
unit.start_time = time.time() + self.chain_delay * 60 - 1
236+
237237
# loop over units and update them ((re)submits will be called here)
238238
old_status = self.status
239239
unit_status_list = []

python/Ganga/Lib/Splitters/ArgSplitter.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
###############################################################################
66

77
import copy
8-
from Ganga.GPIDev.Adapters.ISplitter import ISplitter
8+
from Ganga.GPIDev.Adapters.ISplitter import ISplitter, SplittingError
99
from Ganga.GPIDev.Base.Proxy import stripProxy
1010
from Ganga.GPIDev.Schema import Schema, Version, SimpleItem
1111
from Ganga.GPIDev.Lib.GangaList.GangaList import GangaList
12-
1312
from Ganga.Utility.logging import getLogger
1413
logger = getLogger()
1514

@@ -19,7 +18,8 @@ class ArgSplitter(ISplitter):
1918
"""
2019
Split job by changing the args attribute of the application.
2120
22-
This splitter only applies to the applications which have args attribute (e.g. Executable, Root).
21+
This splitter only applies to the applications which have args attribute (e.g. Executable, Root), or those
22+
with extraArgs (GaudiExec). If an application has both, args takes precedence.
2323
It is a special case of the GenericSplitter.
2424
2525
This splitter allows the creation of a series of subjobs where
@@ -58,7 +58,13 @@ def split(self, job):
5858
j = self.createSubjob(job,['application'])
5959
# Add new arguments to subjob
6060
app = copy.deepcopy(job.application)
61-
app.args = arg
61+
if hasattr(app, 'args'):
62+
app.args = arg
63+
elif hasattr(app, 'extraArgs'):
64+
app.extraArgs = arg
65+
else:
66+
raise SplittingError('Application has neither args or extraArgs in its schema')
67+
6268
j.application = app
6369
logger.debug('Arguments for split job is: ' + str(arg))
6470
subjobs.append(stripProxy(j))

python/GangaAtlas/Lib/ATLASDataset/DQ2Dataset.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
###############################################################################
77
# A DQ2 dataset
88

9-
import sys, os, re, urllib, commands, imp, threading, time, fnmatch
9+
import sys, os, re, urllib, commands, imp, threading, time, fnmatch, getpass
1010

1111
from Ganga.GPIDev.Lib.Dataset import Dataset
1212
from Ganga.GPIDev.Schema import *
@@ -2023,25 +2023,27 @@ def addTask(self, cmd):
20232023
logger = getLogger()
20242024

20252025
# New for DQ2 client 2.3.0
2026-
from Ganga.GPIDev.Credentials_old import GridProxy
2027-
gridProxy = GridProxy()
2028-
if not gridProxy.isValid():
2029-
gridProxy.create()
2026+
#from Ganga.GPIDev.Credentials_old import GridProxy
2027+
#gridProxy = GridProxy()
2028+
#if not gridProxy.isValid():
2029+
# gridProxy.create()
20302030

2031-
username = gridProxy.identity(safe=True)
2031+
#username = gridProxy.identity(safe=True)
20322032
# Note: Allow missing nickname as if we can't create a proxy for some reason, we still want to start Ganga
2033-
nickname = getNickname(allowMissingNickname=True)
2034-
if nickname:
2035-
username = nickname
2036-
os.environ['RUCIO_ACCOUNT'] = username
2033+
#nickname = getNickname(allowMissingNickname=True)
2034+
#if nickname:
2035+
# username = nickname
2036+
os.environ['RUCIO_ACCOUNT'] = getpass.getuser()
20372037
logger.debug("Using RUCIO_ACCOUNT = %s " %(os.environ['RUCIO_ACCOUNT']))
20382038

20392039
# Again, if we don't have a valid proxy, don't attempt to create DQ2 object as it will just fail
2040-
if gridProxy.isValid():
2041-
from dq2.clientapi.DQ2 import DQ2
2042-
dq2=DQ2(force_backend='rucio')
2043-
else:
2044-
dq2 = None
2040+
#if gridProxy.isValid():
2041+
# from dq2.clientapi.DQ2 import DQ2
2042+
# dq2=DQ2(force_backend='rucio')
2043+
#else:
2044+
# dq2 = None
2045+
2046+
dq2 = None
20452047

20462048
from threading import Lock
20472049
dq2_lock = Lock()

python/GangaAtlas/Lib/Athena/Athena.py

Lines changed: 25 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,9 @@ class AthenaSplitterJob(ISplitter):
15341534
'numfiles_subjob' : SimpleItem(defvalue=0,sequence=0, doc="Number of files per subjob"),
15351535
'match_subjobs_files' : SimpleItem(defvalue=False,sequence=0, doc="Match the number of subjobs to the number of inputfiles"),
15361536
'split_per_dataset' : SimpleItem(defvalue=False,sequence=0, doc="Match the number of subjobs to the number of datasets"),
1537+
'events_per_subjob' : SimpleItem(defvalue=-1,sequence=0, doc='Number of Events to process per subjob. Must be used with numsubjobs.'
1538+
'The total events processed with be events_per_subjob * numsubjobs. Please'
1539+
'make sure this covers the number of events required'),
15371540
'output_loc_to_input' : SimpleItem(defvalue={}, doc='Dictionary that lists the input files that should go to a '
15381541
'particular output dir, e.g. { "/out/dir": ["/in/file1", "/in/file2"].'
15391542
'Input files must match what is given to ATLASLocalDataset }')
@@ -1554,11 +1557,12 @@ def split(self,job):
15541557
# Preparation
15551558
inputnames=[]
15561559
inputguids=[]
1557-
if job.inputdata:
1560+
if job.inputdata and (job.inputdata._name == 'ATLASLocalDataset'):
15581561

1559-
if (job.inputdata._name == 'ATLASLocalDataset'):
1560-
inputnames = []
1561-
outputnames = []
1562+
# Special case for events_per_subjob as input data is ignored
1563+
inputnames = []
1564+
outputnames = []
1565+
if self.events_per_subjob < 0:
15621566
numfiles = len(job.inputdata.get_dataset_filenames())
15631567
if self.numfiles_subjob > 0:
15641568
self.numsubjobs = int( math.ceil( numfiles / float(self.numfiles_subjob) ) )
@@ -1631,50 +1635,21 @@ def split(self,job):
16311635

16321636
for j in xrange(numfiles):
16331637
inputnames[j % self.numsubjobs].append(job.inputdata.get_dataset_filenames()[j])
1638+
else:
1639+
# for splitting on events, all data is passed to every subjob and skip events/max events
1640+
# is set appropriately
1641+
if self.numfiles_subjob > 0 or self.match_subjobs_files or self.split_per_dataset:
1642+
raise ApplicationConfigurationError("Cannot use events_per_subjob with numfiles_subjob, match_subjobs_files, split_per_dataset")
16341643

1635-
if job.inputdata._name == 'DQ2Dataset':
1636-
# Splitting per dataset
1637-
if self.split_per_dataset:
1638-
contents = job.inputdata.get_contents(overlap=False)
1639-
datasets = job.inputdata.dataset
1640-
self.numsubjobs = len(datasets)
1641-
for dataset in datasets:
1642-
content = contents[dataset]
1643-
content.sort(lambda x,y:cmp(x[1],y[1]))
1644-
inputnames.append( [ lfn for guid, lfn in content ] )
1645-
inputguids.append( [ guid for guid, lfn in content ] )
1646-
else:
1647-
# Splitting per file
1648-
content = []
1649-
input_files = []
1650-
input_guids = []
1651-
names = None
1652-
# Get list of filenames and guids
1653-
contents = job.inputdata.get_contents()
1654-
if self.match_subjobs_files:
1655-
self.numsubjobs = len(contents)
1656-
elif self.numfiles_subjob>0:
1657-
numjobs = len(contents) / int(self.numfiles_subjob)
1658-
if (len(contents) % self.numfiles_subjob)>0:
1659-
numjobs += 1
1660-
self.numsubjobs = numjobs
1661-
logger.info('Submitting %s subjobs',numjobs)
1662-
1663-
# Fill dummy values
1664-
for i in xrange(self.numsubjobs):
1665-
inputnames.append([])
1666-
inputguids.append([])
1667-
input_files = [ lfn for guid, lfn in contents ]
1668-
input_guids = [ guid for guid, lfn in contents ]
1644+
if self.numsubjobs < 1:
1645+
raise ApplicationConfigurationError("Please specify the number of subjobs if using events_per_subjob")
16691646

1670-
# Splitting
1671-
for j in xrange(len(input_files)):
1672-
inputnames[j % self.numsubjobs].append(input_files[j])
1673-
inputguids[j % self.numsubjobs].append(input_guids[j])
1647+
logger.warning("Splitting by number of events. All data will be passed to all subjobs and the total number of events to be"
1648+
"processed will be numsubjobs * events_per_subjob (%d * %d = %d in this case)" %
1649+
(self.numsubjobs, self.events_per_subjob, self.numsubjobs * self.events_per_subjob))
16741650

1675-
if job.backend._name == 'LCG' and job.backend.middleware=='GLITE' and self.numsubjobs>config['MaxJobsAthenaSplitterJobLCG']:
1676-
printout = 'Job submission failed ! AthenaSplitterJob.numsubjobs>%s - glite WMS does not like bulk jobs with more than approximately 100 subjobs - use less subjobs or use job.backend.middleware=="EDG" ' %config['MaxJobsAthenaSplitterJobLCG']
1677-
raise ApplicationConfigurationError(printout)
1651+
for j in xrange(self.numsubjobs):
1652+
inputnames.append(job.inputdata.get_dataset_filenames())
16781653

16791654
# Do the splitting
16801655
for i in range(self.numsubjobs):
@@ -1683,93 +1658,25 @@ def split(self,job):
16831658
j.inputdata=job.inputdata
16841659
if job.inputdata:
16851660
j.inputdata.names=inputnames[i]
1686-
if job.inputdata._name == 'DQ2Dataset':
1687-
j.inputdata.guids=inputguids[i]
1688-
j.inputdata.number_of_files = len(inputguids[i])
1689-
if self.split_per_dataset:
1690-
j.inputdata.dataset=job.inputdata.dataset[i]
1661+
16911662
j.outputdata=job.outputdata
16921663

16931664
# Set the output location if we have mapping
16941665
if self.output_loc_to_input and isinstance(job.outputdata, ATLASOutputDataset):
16951666
j.outputdata.location = outputnames[i]
16961667

16971668
j.application = job.application
1669+
if self.events_per_subjob > 0:
1670+
j.application.max_events = self.events_per_subjob
1671+
j.application.skip_events = self.events_per_subjob * i
1672+
16981673
j.backend=job.backend
16991674
j.inputsandbox=job.inputsandbox
17001675
j.outputsandbox=job.outputsandbox
17011676

17021677
subjobs.append(j)
17031678
return subjobs
17041679

1705-
class ATLASTier3Splitter(ISplitter):
1706-
"""Splitter for ATLASTier3Dataset"""
1707-
1708-
_name = "ATLASTier3Splitter"
1709-
_schema = Schema(Version(1,0), {
1710-
'numjobs' : SimpleItem(defvalue=0,sequence=0, doc="Number of subjobs"),
1711-
'numfiles' : SimpleItem(defvalue=0,sequence=0, doc="Number of files per subjob")
1712-
} )
1713-
1714-
_GUIPrefs = [ { 'attribute' : 'numjobs', 'widget' : 'Int' },
1715-
{ 'attribute' : 'numfiles', 'widget' : 'Int' },
1716-
]
1717-
1718-
### Splitting based on numsubjobs
1719-
def split(self,job):
1720-
from Ganga.GPIDev.Lib.Job import Job
1721-
subjobs = []
1722-
logger.debug("ATLASTier3Splitter split called")
1723-
1724-
if not job.inputdata:
1725-
raise ApplicationConfigurationError("ATLASTier3Splitter requires ATLASTier3Dataset")
1726-
if job.inputdata._name != 'ATLASTier3Dataset':
1727-
raise ApplicationConfigurationError("ATLASTier3Splitter requires ATLASTier3Dataset")
1728-
if self.numjobs and self.numfiles:
1729-
logger.warning('You specified numjobs and numfiles. Setting numjobs = 0 to continue.')
1730-
self.numjobs = 0
1731-
#raise ApplicationConfigurationError(None, "ATLASTier3Splitter: specify numjobs or numfiles, but not both.")
1732-
1733-
if job.inputdata.pfnListFile.name:
1734-
logger.info('Loading file names from %s'%job.inputdata.pfnListFile.name)
1735-
pfnListFile = open(job.inputdata.pfnListFile.name)
1736-
job.inputdata.names = [name.strip() for name in pfnListFile]
1737-
pfnListFile.close()
1738-
1739-
allnames = list(job.inputdata.names)
1740-
1741-
# default behaviour is 20 subjobs
1742-
if not self.numjobs and not self.numfiles:
1743-
self.numjobs = min(20,len(allnames))
1744-
1745-
# limit numfiles and numjobs
1746-
self.numjobs = min(self.numjobs,len(allnames))
1747-
self.numfiles = min(self.numfiles,len(allnames))
1748-
1749-
# calculate numfiles and numjobs
1750-
if self.numfiles:
1751-
(self.numjobs,r) = divmod(len(allnames),self.numfiles)
1752-
if r: self.numjobs += 1
1753-
elif self.numjobs:
1754-
(self.numfiles,r) = divmod(len(allnames),self.numjobs)
1755-
if r: self.numfiles += 1
1756-
1757-
# Do the splitting
1758-
allnames.reverse()
1759-
for i in range(self.numjobs):
1760-
j = Job()
1761-
j.inputdata=job.inputdata
1762-
j.inputdata.names=[]
1763-
while allnames and len(j.inputdata.names) < self.numfiles:
1764-
j.inputdata.names.append(allnames.pop())
1765-
j.outputdata = job.outputdata
1766-
j.application = job.application
1767-
j.backend = job.backend
1768-
j.inputsandbox = job.inputsandbox
1769-
j.outputsandbox = job.outputsandbox
1770-
subjobs.append(j)
1771-
1772-
return subjobs
17731680

17741681
from Ganga.GPIDev.Adapters.IMerger import IMerger
17751682
from commands import getstatusoutput

python/GangaAtlas/Lib/Athena/AthenaLocalRTHandler.py

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,17 @@ def prepare(self,app,appsubconfig,appmasterconfig,jobmasterconfig):
280280
# set EOS env setting
281281
environment['EOS_COMMAND_PATH'] = config['PathToEOSBinary']
282282

283+
# Max/skip event settings
284+
if app.skip_events > 0:
285+
environment['ATHENA_SKIP_EVENTS'] = str(app.skip_events)
286+
287+
if app.max_events > 0:
288+
environment['ATHENA_MAX_EVENTS'] = str(app.max_events)
289+
290+
# Flag if we're in ByteStream Data
291+
if app.atlas_run_config.has_key('input') and app.atlas_run_config['input'].has_key('inBS'):
292+
environment['USE_BYTESTREAM'] = 'True'
293+
283294
# flag for single output dir
284295
if (config['SingleDirForLocalOutput'] or config['NoSubDirsAtAllForLocalOutput']) and job._getParent():
285296
environment['SINGLE_OUTPUT_DIR'] = jid
@@ -312,21 +323,6 @@ def prepare(self,app,appsubconfig,appmasterconfig,jobmasterconfig):
312323
environment['DQ2_OUTPUT_SPACE_TOKENS']= ':'.join(configDQ2['DQ2_OUTPUT_SPACE_TOKENS'])
313324
environment['DQ2_BACKUP_OUTPUT_LOCATIONS']= ':'.join(configDQ2['DQ2_BACKUP_OUTPUT_LOCATIONS'])
314325

315-
# CN: extra condition for TNTSplitter
316-
if job._getRoot().splitter and job._getRoot().splitter._name == 'TNTJobSplitter':
317-
# set up dq2 environment
318-
datasetname = job.inputdata.dataset
319-
environment['DATASETNAME']= ':'.join(datasetname)
320-
environment['DATASETLOCATION'] = ':'.join(job.inputdata.get_locations())
321-
environment['DQ2_URL_SERVER']=configDQ2['DQ2_URL_SERVER']
322-
environment['DQ2_URL_SERVER_SSL']=configDQ2['DQ2_URL_SERVER_SSL']
323-
#environment['DATASETTYPE']=job.inputdata.type
324-
# At present, DQ2 download is the only thing that works
325-
environment['DATASETTYPE']="DQ2_DOWNLOAD"
326-
if job.inputdata.accessprotocol:
327-
environment['DQ2_LOCAL_PROTOCOL'] = job.inputdata.accessprotocol
328-
if job.inputsandbox: inputbox += job.inputsandbox
329-
330326
# Fix DATASETNAME env variable for DQ2_COPY mode
331327
if job.inputdata and job.inputdata._name in [ 'DQ2Dataset' ] and job.inputdata.type in [ 'DQ2_LOCAL', 'DQ2_COPY', 'FILE_STAGER' ]:
332328
if job.inputdata.dataset:
@@ -340,11 +336,6 @@ def prepare(self,app,appsubconfig,appmasterconfig,jobmasterconfig):
340336
raise ApplicationConfigurationError(printout )
341337

342338

343-
if job.inputdata and job.inputdata._name == 'ATLASTier3Dataset':
344-
environment['DATASETTYPE'] = 'TIER3'
345-
346-
347-
348339
# USE_POOLFILECATALOG_FAILOVER of Local/ATLASLocalDataset
349340
if job.inputdata and job.inputdata._name == 'ATLASLocalDataset':
350341
if job.inputdata.use_poolfilecatalog_failover:
@@ -407,16 +398,9 @@ def master_prepare( self, app, appconfig ):
407398
jobid = "%d" % job.id
408399

409400
# Generate output dataset name
410-
if job.outputdata:
411-
if job.outputdata._name=='DQ2OutputDataset':
412-
dq2_datasetname = job.outputdata.datasetname
413-
dq2_isGroupDS = job.outputdata.isGroupDS
414-
dq2_groupname = job.outputdata.groupname
415-
else:
416-
dq2_datasetname = ''
417-
dq2_isGroupDS = False
418-
dq2_groupname = ''
419-
self.output_datasetname, self.output_lfn = dq2outputdatasetname(dq2_datasetname, jobid, dq2_isGroupDS, dq2_groupname)
401+
dq2_datasetname = ''
402+
dq2_isGroupDS = False
403+
dq2_groupname = ''
420404

421405
# Expand Athena jobOptions
422406
if not app.option_file and not app.command_line:

python/GangaAtlas/Lib/Athena/DQ2JobSplitter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
from GangaAtlas.Lib.ATLASDataset.DQ2Dataset import *
2020
from Ganga.Utility.Config import getConfig, makeConfig, ConfigError
2121

22-
from Ganga.GPIDev.Credentials_old import GridProxy
23-
gridProxy = GridProxy()
22+
#from Ganga.GPIDev.Credentials_old import GridProxy
23+
#gridProxy = GridProxy()
2424

2525
logger = getLogger()
2626

0 commit comments

Comments
 (0)