""" Parallel Library Mainly used by Computing Elements to run several jobs/pilots in parallel within a same allocation. This is an abstract class and cannot be used directly. Use cases: - multiple nodes have been allocated and have to be used: a parallel library can execute the pilot wrapper on all the nodes in parallel. - multiple cpus have been allocated and have to be used: a parallel library could dispatch several jobs on the cores available (e.g. when sites have no external connectivity). Parallel libraries implementations have to inherit from this class and override generateWrapper() and processOutput(). **Parameters** The Parallel Libraries have to be defined in a CE section via the configuration system. See the page about configuring :ref:`resourcesComputing` for where the options can be placed. WorkingDirectory: Generally defined in the ComputingElement source code depending on how they deal with the executables. Indicates where the parallel library wrapper script has to be defined and retrieved. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from DIRAC import gLogger class ParallelLibrary(object): def __init__(self, name='undefined', workingDirectory=''): """ Initialize the parallel library :param str name: name of the parallel library :param str workingDirectory: directory that should contain the executable and its inputs """ self.workingDirectory = workingDirectory self.log = gLogger.getSubLogger(name) def generateWrapper(self, executableFile): """ Associate the executable with a wrapper script, generated by the parallel library, to execute the same command in parallel on multiple nodes. Wrap it in a new executable file. :param str executableFile: name of the executable file to wrap :return str: name of the wrapper that runs the executable via the parallel library """ raise NotImplementedError("generateWrapper is not implemented") def processOutput(self, output, error, isFile=True): """ Reorder the content of the output files that is possibly not easily readable after the execution of the parallel library. If isFile is enabled, then output and error have to be filenames and are modified in-place. Else the output and error contains content of the files, and the processed content is returned. :param str output: name of the output file, or its content :param str error: name of the error file, or its content :param bool isFile: indicates if the inputs represent files or content of the files :return str: name of the files or their content depending on isFile value """ raise NotImplementedError("processOutput is not implemented")