Source code for tools.execute

# -*- coding: utf-8 -*-

'''
Created on 9 oct. 2012
@author: lafaysse
'''

import os
import subprocess
import sys
import shlex


[docs] class SystemException(Exception): """Exception for a system command""" def __init__(self, status, command, errorcode=None): self.status = status self.command = command def __str__(self): return "The following command fails with error code " + str(self.status) + ":\n" + self.command
[docs] def callSystemOrDie(commande, errorcode=None): """Method to execute a system command and kill the current program if it fails.""" status = subprocess.call(shlex.split(commande), stdout=sys.stdout, stderr=sys.stderr) if status != 0: raise SystemException(status, commande) return status
[docs] def printandcallSystemOrDie(commande, errorcode=None): """Method to print and execute a system command and kill the current program if it fails.""" print(commande) callSystemOrDie(commande, errorcode=errorcode)
[docs] def callSurfexOrDie(commande, moderun="NORMAL", nproc=1, errorcode=None): """Method to execute a SURFEX binary and kill the current program if it fails. Include the setting of MPI and OpenMP tasks, and the extension of stack memory. """ set_stack_unlimited() os.environ["OMP_NUM_THREADS"] = "1" if ("PGD" in commande or "PREP" in commande) and moderun in ["MPI", "MPIRUN"]: moderun = "MPISINGLE" if moderun in ["MPI", "MPIRUN"]: if moderun == "MPIRUN": callSystemOrDie("mpirun -np " + str(nproc) + " " + commande, errorcode=errorcode) else: if "SLURM_NODES" in list(os.environ.keys()): callSystemOrDie("srun --nodes=" + os.environ["SLURM_NNODES"] + " --ntasks=" + str(nproc) + " " + commande, errorcode=errorcode) else: callSystemOrDie("srun --ntasks=" + str(nproc) + " " + commande, errorcode=errorcode) elif moderun == "MPISINGLE": nproc = 1 callSystemOrDie("mpirun -np " + str(nproc) + " " + commande, errorcode=errorcode) else: callSystemOrDie(commande, errorcode=errorcode)
def set_stack_unlimited(): # Without the following lines, the worse segmentation faults you can ever imagine # Equivalent to bash command ulimit -s unlimited # Take care : some systems do not allow to force resource.RLIMIT_STACK at resource.RLIM_INFINITY, # so it is safer to get the system hard limit first. # Moreover, this can not be done on MacOS if sys.platform != 'darwin': import resource soft, hard = resource.getrlimit(resource.RLIMIT_STACK) # @UnusedVariable resource.setrlimit(resource.RLIMIT_STACK, (hard, hard))