[pyfr] 31/88: Add support for post-actions in plugins.

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Nov 16 12:05:27 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch master
in repository pyfr.

commit 83eb21342414b0912c939987755db30d7c43ab13
Author: Freddie Witherden <freddie at witherden.org>
Date:   Sun May 1 13:31:24 2016 -0700

    Add support for post-actions in plugins.
    
    A post-action is a command (either blocking or non-blocking) to
    be invoked on the root rank after a plugin has completed.
    Support for post-actions currently exists in the writer plugin
    with the syntax being:
    
    [soln-plugin-writer]
    ...
    post-action = myprog "{mesh}" "{soln}" {t}
    post-action-mode = non-blocking
    
    which will pass the mesh file name, the just-written solution
    file name and the current simulation time to myprog.  The
    simulation will then continue execution while the plugin
    executes.  However, myprog will not be allowed to execute again
    until the current invocation has finished (and hence is myprog
    is extremely long-lived then there is the possibility of it
    blocking the the solver).
---
 pyfr/plugins/base.py   | 39 +++++++++++++++++++++++++++++++++++++++
 pyfr/plugins/writer.py |  9 ++++++++-
 pyfr/readers/native.py |  2 ++
 pyfr/writers/native.py |  3 +++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/pyfr/plugins/base.py b/pyfr/plugins/base.py
index c96d987..bb1a9c7 100644
--- a/pyfr/plugins/base.py
+++ b/pyfr/plugins/base.py
@@ -2,6 +2,11 @@
 
 from abc import ABCMeta, abstractmethod
 import os
+import shlex
+
+from pytools import prefork
+
+from pyfr.mpiutil import get_comm_rank_root
 
 
 def init_csv(cfg, cfgsect, header, *, filekey='file', headerkey='header'):
@@ -40,11 +45,45 @@ class BasePlugin(object, metaclass=ABCMeta):
         # Tolerance for time comparisons
         self.tol = 5*intg.dtmin
 
+        # Initalise our post-action (if any)
+        self.postact = None
+        self.postactaid = None
+        self.postactmode = None
+
+        if self.cfg.hasopt(cfgsect, 'post-action'):
+            self.postact = self.cfg.getpath(cfgsect, 'post-action', abs=False)
+            self.postactmode = self.cfg.get(cfgsect, 'post-action-mode')
+
+            if self.postactmode not in {'blocking', 'non-blocking'}:
+                raise ValueError('Invalid post action type')
+
         # Check that we support this particular system
         if not ('*' in self.systems or intg.system.name in self.systems):
             raise RuntimeError('System {0} not supported by plugin {1}'
                                .format(intg.system.name, self.name))
 
+    def __del__(self):
+        if self.postactaid is not None:
+            prefork.wait(self.postactaid)
+
+    def _invoke_postaction(self, **kwargs):
+        comm, rank, root = get_comm_rank_root()
+
+        # If we have a post-action and are the root rank then fire it
+        if rank == root and self.postact:
+            # First, wait for any running post-actions to complete
+            if self.postactaid is not None:
+                prefork.wait(self.postactaid)
+
+            # Prepare the command line
+            cmdline = shlex.split(self.postact.format(**kwargs))
+
+            # Invoke; either synchronously or asynchronously
+            if self.postactmode == 'blocking':
+                prefork.call(cmdline)
+            else:
+                self.postactaid = prefork.call_async(cmdline)
+
     @abstractmethod
     def __call__(self, intg):
         pass
diff --git a/pyfr/plugins/writer.py b/pyfr/plugins/writer.py
index d09d508..95e10d4 100644
--- a/pyfr/plugins/writer.py
+++ b/pyfr/plugins/writer.py
@@ -43,10 +43,17 @@ class WriterPlugin(BasePlugin):
         stats.set('data', 'prefix', 'soln')
         intg.collect_stats(stats)
 
+        # Prepare the metadata
         metadata = dict(config=self.cfg.tostr(),
                         stats=stats.tostr(),
                         mesh_uuid=intg.mesh_uuid)
 
-        self._writer.write(intg.soln, metadata, intg.tcurr)
+        # Write out the file
+        solnfname = self._writer.write(intg.soln, metadata, intg.tcurr)
 
+        # If a post-action has been registered then invoke it
+        self._invoke_postaction(mesh=intg.system.mesh.fname, soln=solnfname,
+                                t=intg.tcurr)
+
+        # Compute the next output time
         self.tout_next = intg.tcurr + self.dt_out
diff --git a/pyfr/readers/native.py b/pyfr/readers/native.py
index 9823562..4ceecf9 100644
--- a/pyfr/readers/native.py
+++ b/pyfr/readers/native.py
@@ -2,6 +2,7 @@
 
 from collections import Mapping, OrderedDict
 import re
+import os
 
 import h5py
 import numpy as np
@@ -11,6 +12,7 @@ from pyfr.util import memoize
 
 class NativeReader(Mapping):
     def __init__(self, fname):
+        self.fname = os.path.abspath(fname)
         self._file = h5py.File(fname, 'r')
 
     def __getitem__(self, aname):
diff --git a/pyfr/writers/native.py b/pyfr/writers/native.py
index b5cc49a..45741dd 100644
--- a/pyfr/writers/native.py
+++ b/pyfr/writers/native.py
@@ -93,6 +93,9 @@ class NativeWriter(object):
         # Increment the output number
         self.nout += 1
 
+        # Return the path
+        return path
+
     def _restore_nout(self):
         nout = 0
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pyfr.git



More information about the debian-science-commits mailing list