Skip to content

Commit 8ad4e57

Browse files
committed
feat: executables are extracted from inputs in ARC CEs
1 parent 0c73abc commit 8ad4e57

File tree

3 files changed

+44
-48
lines changed

3 files changed

+44
-48
lines changed

src/DIRAC/Resources/Computing/ARC6ComputingElement.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1):
144144
jobdescs = arc.JobDescriptionList()
145145

146146
# Get the job into the ARC way
147-
xrslString, diracStamp = self._writeXRSL(executableFile)
147+
xrslString, diracStamp = self._writeXRSL(executableFile, [], [])
148148
self.log.debug("XRSL string submitted : %s" % xrslString)
149149
self.log.debug("DIRAC stamp for job : %s" % diracStamp)
150150

src/DIRAC/Resources/Computing/ARCComputingElement.py

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,12 @@ def _addCEConfigDefaults(self):
167167
ComputingElement._addCEConfigDefaults(self)
168168

169169
#############################################################################
170-
def _writeXRSL(self, executableFile, inputs=None, outputs=None, executables=None):
170+
def _writeXRSL(self, executableFile, inputs, outputs):
171171
"""Create the JDL for submission
172172
173173
:param str executableFile: executable to wrap in a XRSL file
174-
:param str/list inputs: path of the dependencies to include along with the executable
175-
:param str/list outputs: path of the outputs that we want to get at the end of the execution
176-
:param str/list executables: path to inputs that should have execution mode on the remote worker node
174+
:param list inputs: path of the dependencies to include along with the executable
175+
:param list outputs: path of the outputs that we want to get at the end of the execution
177176
"""
178177
diracStamp = makeGuid()[:8]
179178
# Evaluate the number of processors to allocate
@@ -191,34 +190,25 @@ def _writeXRSL(self, executableFile, inputs=None, outputs=None, executables=None
191190
"xrslMPExtraString": self.xrslMPExtraString,
192191
}
193192

194-
# Files that would need execution rights on the remote worker node
195-
xrslExecutables = ""
196-
if executables:
197-
if not isinstance(executables, list):
198-
executables = [executables]
199-
xrslExecutables = "(executables=%s)" % " ".join(map(os.path.basename, executables))
200-
# Add them to the inputFiles
201-
if not inputs:
202-
inputs = []
203-
if not isinstance(inputs, list):
204-
inputs = [inputs]
205-
inputs += executables
206-
207193
# Dependencies that have to be embedded along with the executable
208194
xrslInputs = ""
209-
if inputs:
210-
if not isinstance(inputs, list):
211-
inputs = [inputs]
212-
for inputFile in inputs:
213-
xrslInputs += '(%s "%s")' % (os.path.basename(inputFile), inputFile)
195+
executables = []
196+
for inputFile in inputs:
197+
inputFileBaseName = os.path.basename(inputFile)
198+
if os.access(inputFile, os.X_OK):
199+
# Files that would need execution rights on the remote worker node
200+
executables.append(inputFileBaseName)
201+
xrslInputs += '(%s "%s")' % (inputFileBaseName, inputFile)
202+
203+
# Executables are added to the XRSL
204+
xrslExecutables = ""
205+
if executables:
206+
xrslExecutables = "(executables=%s)" % " ".join(executables)
214207

215208
# Output files to retrieve once the execution is complete
216209
xrslOutputs = '("%s.out" "") ("%s.err" "")' % (diracStamp, diracStamp)
217-
if outputs:
218-
if not isinstance(outputs, list):
219-
outputs = [outputs]
220-
for outputFile in outputs:
221-
xrslOutputs += '(%s "")' % (outputFile)
210+
for outputFile in outputs:
211+
xrslOutputs += '(%s "")' % (outputFile)
222212

223213
xrsl = """
224214
&(executable="%(executable)s")
@@ -247,6 +237,13 @@ def _writeXRSL(self, executableFile, inputs=None, outputs=None, executables=None
247237
def _bundlePreamble(self, executableFile):
248238
"""Bundle the preamble with the executable file"""
249239
wrapperContent = "%s\n./%s" % (self.preamble, executableFile)
240+
241+
# We need to make sure the executable file can be executed by the wrapper
242+
# By adding the execution mode to the file, the file will be processed as an "executable" in the XRSL
243+
# This is done in _writeXRSL()
244+
if not os.access(executableFile, os.X_OK):
245+
os.chmod(executableFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH)
246+
250247
return writeScript(wrapperContent, os.getcwd())
251248

252249
#############################################################################
@@ -299,13 +296,14 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
299296
return result
300297
self.usercfg.ProxyPath(os.environ["X509_USER_PROXY"])
301298

302-
self.log.verbose("Executable file path: %s" % executableFile)
303-
if not os.access(executableFile, 5):
304-
os.chmod(executableFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH)
299+
if not inputs:
300+
inputs = []
301+
if not outputs:
302+
outputs = []
305303

306-
executables = None
304+
self.log.verbose("Executable file path: %s" % executableFile)
307305
if self.preamble:
308-
executables = [executableFile]
306+
inputs.append(executableFile)
309307
executableFile = self._bundlePreamble(executableFile)
310308

311309
batchIDList = []
@@ -325,7 +323,7 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
325323
# The basic job description
326324
jobdescs = arc.JobDescriptionList()
327325
# Get the job into the ARC way
328-
xrslString, diracStamp = self._writeXRSL(executableFile, inputs, outputs, executables)
326+
xrslString, diracStamp = self._writeXRSL(executableFile, inputs, outputs)
329327
self.log.debug("XRSL string submitted : %s" % xrslString)
330328
self.log.debug("DIRAC stamp for job : %s" % diracStamp)
331329
# The arc bindings don't accept unicode objects in Python 2 so xrslString must be explicitly cast

src/DIRAC/Resources/Computing/AREXComputingElement.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,12 @@ def _getDelegationID(self, arcJobID):
304304

305305
#############################################################################
306306

307-
def _getArcJobID(self, executableFile, inputs, outputs, executables, delegation):
307+
def _getArcJobID(self, executableFile, inputs, outputs, delegation):
308308
"""Get an ARC JobID endpoint to upload executables and inputs.
309309
310310
:param str executableFile: executable to submit
311311
:param list inputs: list of input files
312312
:param list outputs: list of expected output files
313-
:param list executables: list of secondary executables (will be uploaded with the executable mode)
314313
:param str delegation: delegation ID
315314
316315
:return: tuple containing a job ID and a stamp
@@ -320,7 +319,7 @@ def _getArcJobID(self, executableFile, inputs, outputs, executables, delegation)
320319
query = self._urlJoin("jobs")
321320

322321
# Get the job into the ARC way
323-
xrslString, diracStamp = self._writeXRSL(executableFile, inputs, outputs, executables)
322+
xrslString, diracStamp = self._writeXRSL(executableFile, inputs, outputs)
324323
xrslString += delegation
325324
self.log.debug("XRSL string submitted", "is %s" % xrslString)
326325
self.log.debug("DIRAC stamp for job", "is %s" % diracStamp)
@@ -344,21 +343,16 @@ def _getArcJobID(self, executableFile, inputs, outputs, executables, delegation)
344343
arcJobID = responseJob["id"]
345344
return S_OK((arcJobID, diracStamp))
346345

347-
def _uploadJobDependencies(self, arcJobID, executableFile, inputs, executables):
346+
def _uploadJobDependencies(self, arcJobID, executableFile, inputs):
348347
"""Upload job dependencies so that the job can start.
349348
This includes the executables and the inputs.
350349
351350
:param str arcJobID: ARC job ID
352351
:param str executableFile: executable file
353352
:param list inputs: inputs required by the executable file
354-
:param list executables: executables require by the executable file
355353
"""
356354
filesToSubmit = [executableFile]
357-
filesToSubmit += executables
358-
if inputs:
359-
if not isinstance(inputs, list):
360-
inputs = [inputs]
361-
filesToSubmit += inputs
355+
filesToSubmit += inputs
362356

363357
for fileToSubmit in filesToSubmit:
364358
queryExecutable = self._urlJoin(os.path.join("jobs", arcJobID, "session", os.path.basename(fileToSubmit)))
@@ -397,10 +391,14 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
397391
else:
398392
delegation = "\n(delegationid=%s)" % result["Value"]
399393

394+
if not inputs:
395+
inputs = []
396+
if not outputs:
397+
outputs = []
398+
400399
# If there is a preamble, then we bundle it in an executable file
401-
executables = []
402400
if self.preamble:
403-
executables = [executableFile]
401+
inputs.append(executableFile)
404402
executableFile = self._bundlePreamble(executableFile)
405403

406404
# Submit multiple jobs sequentially.
@@ -410,14 +408,14 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
410408
batchIDList = []
411409
stampDict = {}
412410
for _ in range(numberOfJobs):
413-
result = self._getArcJobID(executableFile, inputs, outputs, executables, delegation)
411+
result = self._getArcJobID(executableFile, inputs, outputs, delegation)
414412
if not result["OK"]:
415413
break
416414
arcJobID, diracStamp = result["Value"]
417415

418416
# At this point, only the XRSL job has been submitted to AREX services
419417
# Here we also upload the executable, other executable files and inputs.
420-
result = self._uploadJobDependencies(arcJobID, executableFile, inputs, executables)
418+
result = self._uploadJobDependencies(arcJobID, executableFile, inputs)
421419
if not result["OK"]:
422420
break
423421

0 commit comments

Comments
 (0)