From 98541b51aaa984cd1ac177ce9922d1f8104cbcf1 Mon Sep 17 00:00:00 2001 From: Tim Quatmann <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 16 Jul 2019 11:53:34 +0200 Subject: [PATCH] added example python script --- examples/call_python.sh | 4 +- examples/call_python_script.py | 100 +++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 examples/call_python_script.py diff --git a/examples/call_python.sh b/examples/call_python.sh index 213ac58..279fa02 100755 --- a/examples/call_python.sh +++ b/examples/call_python.sh @@ -32,11 +32,11 @@ source $HOME/hpc-scripts/prepareEnvironmentGcc.sh ### Change Directory to your working directory (binaries, etc) -cd $HOME +cd $HOME/hpc-scripts/examples/ start=`date` echo "Starting task $SLURM_ARRAY_TASK_ID at $start" -python benchmarking.py $SLURM_ARRAY_TASK_ID ;rc=$? +python call_python_script.py $SLURM_ARRAY_TASK_ID ;rc=$? end=`date` echo "Finished task $SLURM_ARRAY_TASK_ID with exit code $rc at $end" diff --git a/examples/call_python_script.py b/examples/call_python_script.py new file mode 100644 index 0000000..ee5c6c2 --- /dev/null +++ b/examples/call_python_script.py @@ -0,0 +1,100 @@ +import os, sys, subprocess, threading, time + +class CommandExecution(object): + """ Represents the execution of a single command line argument. """ + def __init__(self): + self.timelimit = None + self.return_code = None + self.output = None + self.wall_time = None + self.proc = None + + def stop(self): + self.timelimit = True + self.proc.kill() + + def run(self, command_line_str, timelimit): + command_line_list = command_line_str.split() + command_line_list[0] = os.path.expanduser(command_line_list[0]) + self.proc = subprocess.Popen(command_line_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + start_time = time.time() + timer = threading.Timer(timelimit, self.stop) + self.timelimit = False + self.output = "" + timer.start() + try: + stdout, stderr = self.proc.communicate() + except Exception as e: + self.output = self.output + "Error when executing the command:\n{}\n".format(e) + finally: + timer.cancel() + self.wall_time = time.time() - start_time + self.return_code = self.proc.returncode + self.output = self.output + stdout.decode('utf8') + if len(stderr) > 0: + self.output = self.output + "\n" + "#"*30 + "Output to stderr" + "#"*30 + "\n" + stderr.decode('utf8') + if self.timelimit and self.wall_time <= timelimit: + print("WARN: A timelimit was triggered although the measured time is {} seconds which is still below the time limit of {} seconds".format(self.wall_time, timelimit)) + + +def execute_command_line(command_line_str, timelimit): + """ + Executes the given command line with the given time limit (in seconds). + :returns the output of the command (including the output to stderr, if present), the runtime of the command and either the return code or None (in case of a timelimit) + """ + execution = CommandExecution() + execution.run(command_line_str, timelimit) + if execution.timelimit: + return execution.output, execution.wall_time, None + else: + return execution.output, execution.wall_time, execution.return_code + + +def execute_and_log_command_line(command_line_str, timelimit, logfile): + """ + Executes the given command line with the given time limit (in seconds) and stores the output the provided logfile. + :returns a string reporting the runtime, returncode and logfile location. + """ + output, runtime, returncode = execute_command_line(command_line_str, timelimit) + header = "COMMAND: {}\nWALLTIME (seconds): {}\n".format(command_line_str, runtime) + if returncode == 0: + message = "done after {} seconds. Output saved to {}".format(runtime, logfile) + header += "\n" + elif returncode is None and runtime >= timelimit: + message = "timeout after {} seconds. Output saved to {}".format(runtime, logfile) + header += "TIMEOUT\n" + else: + message = "error after {} seconds with non-zero exit code {}. Output saved to {}".format(runtime,returncode,logfile) + header += "ERROR: {}\n".format(returncode) + output = header + "#"*30 + " LOG " + "#"*30 + "\n" + output + with open(logfile, 'w') as file: + file.write(output) + return message + +timelimit = 3600 +logdir = "/rwthfs/rz/cluster/home/tq429871/logs/" + +# contains (logfilename, command)-pairs +commands = [] +commands.append((r"eajs_P2-U3_pos-t8-c1-p0.01-e0.log", r"/home/tq429871/storm/build/bin/storm --prism /rwthfs/rz/cluster/home/tq429871/git/pure-strategies-benchmarks/scripts/../models/eajs/eajs02.prism --prop /rwthfs/rz/cluster/home/tq429871/git/pure-strategies-benchmarks/scripts/../models/eajs/eajs.props -const U=3 --multiobjective:schedrest positional -tm --exact --lpsolver gurobi --multiobjective:printres --gurobi:threads 8 --gurobi:concurrentmip 1 --multiobjective:precision 0.01 --multiobjective:maxsteps 0")) +commands.append((r"resource-gathering_G10-E5-S100_pos-t1-c1-p0.01-e24.log", r"/home/tq429871/storm/build/bin/storm --prism /rwthfs/rz/cluster/home/tq429871/git/pure-strategies-benchmarks/scripts/../models/resource-gathering/resource-gathering.prism --prop /rwthfs/rz/cluster/home/tq429871/git/pure-strategies-benchmarks/scripts/../models/resource-gathering/resource-gathering.props -const REQGOLD=10,REQGEM=5,AVSTEPS=100 --multiobjective:schedrest positional -tm --exact --lpsolver gurobi --multiobjective:printres --gurobi:threads 1 --gurobi:concurrentmip 1 --multiobjective:precision 0.01 --multiobjective:maxsteps 24")) + +if __name__ == "__main__": + print("Found {} commands.".format(len(commands))) + if len(sys.argv) != 2: + print("Invalid number of arguments. Expected 1 but got {}. Usage\npython {} <id>".format(len(sys.argv) - 1, sys.argv[0])) + exit(1) + try: + id = int(sys.argv[1]) + except ValueError: + print("Unable to convert argument '{}' to an id".format(sys.argv[1])) + exit(1) + if id < 0 or id >= len(commands): + print("id {} is out of range. Should be between 0 and {}".format(id, len(commands) - 1)) + exit(1) + + sys.stdout.write("Command {}/{} ... ".format(id, len(commands) - 1)) + sys.stdout.flush() + logfile = os.path.join(logdir, commands[id][0]) + message = execute_and_log_command_line(commands[id][1], timelimit, logfile) + print(message) -- GitLab