From f043f013d6f8bbe285794758b4344c2541149e14 Mon Sep 17 00:00:00 2001 From: Daniel Brown <ddb@star.sr.bham.ac.uk> Date: Fri, 24 Jul 2015 19:04:25 +0100 Subject: [PATCH] adding in parakat object to run multiple kat objects at once using ipython cluster feature. --- pykat/finesse.py | 15 ++++++-- pykat/parallel.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 pykat/parallel.py diff --git a/pykat/finesse.py b/pykat/finesse.py index e582425..760c072 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -1107,7 +1107,7 @@ class kat(object): except pkex.BasePyKatException as ex: print (ex) - def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False): + def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False, rethrowExceptions=False): """ Runs the current simulation setup that has been built thus far. It returns a katRun or katRun2D object which is populated with the various @@ -1124,6 +1124,8 @@ class kat(object): that Finesse performs, the keys are the node names and the values are the x and y beam parameters. If no tracing is done a None is returned. + + rethrowExceptions - if true exceptions will be thrown again rather than being excepted and calling sys.exit() """ start = datetime.datetime.now() @@ -1423,9 +1425,16 @@ class kat(object): except KeyboardInterrupt as ex: print("Keyboard interrupt caught, stopped simulation.") except pkex.FinesseRunError as ex: - pkex.PrintError("Error from Finesse:", ex) + if rethrowExceptions: + raise ex + else: + pkex.PrintError("Error from Finesse:", ex) + except pkex.BasePyKatException as ex: - pkex.PrintError("Error from pykat:", ex) + if rethrowExceptions: + raise ex + else: + pkex.PrintError("Error from pykat:", ex) finally: if self.verbose: print ("") if self.verbose: print ("Finished in " + str(datetime.datetime.now()-start)) diff --git a/pykat/parallel.py b/pykat/parallel.py new file mode 100644 index 0000000..5fec9a5 --- /dev/null +++ b/pykat/parallel.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Jan 27 09:56:53 2013 + +PyKat - Python interface and wrapper for FINESSE +Copyright (C) 2013 Daniel David Brown + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Contact at ddb@star.sr.bham.ac.uk + +@author: Daniel Brown +""" + +from IPython.parallel import Client +import sys +import os + +def _run(commands, pwd): + import os + os.chdir(pwd) + + import pykat + + kat = pykat.finesse.kat() + kat.parseCommands(commands) + out = kat.run(rethrowExceptions=True) + + return out + +class parakat(object): + """ + Uses the ipython clustering for running kat objects in parallel. + + To use this you must have started an ipython cluster on your computer. + From a new terminal use the command: + + ipcluster start -n 4 + + This will start a cluster with 4 workers. + + To run a kat object use: + + pk = parakat() + pk.run(kat1) + pk.run(kat2) + pk.run(kat3) + + outs = pk.getResults() + + The list 'outs' will contain the katRun object you'd normal get if you + had just called, kat1.run(), etc. The results list is matched to order + in which you run the kats. + + If you need to stop long running kat processes the chances are you will + also need to kill the ipython cluster process, as sometimes they carry + on running. + """ + + def __init__(self): + self._rc = Client() + self._lview = self._rc.load_balanced_view() + self._lview.block = False + self._results = [] + + def run(self, kat): + print(kat) + self._results.append(self._lview.apply_async(_run, "".join(kat.generateKatScript()), os.getcwd())) + print(self._results) + + def getResults(self): + out = [] + + self._lview.wait(self._results) + + for done in self._results: + out.append(done.get()) + + return out -- GitLab