From a150b2f047f4c680694bd256cccb3757e31bd544 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Keck <jean-baptiste.keck@imag.fr>
Date: Sun, 25 Feb 2018 17:52:52 +0100
Subject: [PATCH] added visu_rank

---
 examples/analytic/analytic.py           | 39 +++++++++++++++++--------
 hysop/core/graph/computational_graph.py |  6 +++-
 2 files changed, 32 insertions(+), 13 deletions(-)
 mode change 100644 => 100755 examples/analytic/analytic.py

diff --git a/examples/analytic/analytic.py b/examples/analytic/analytic.py
old mode 100644
new mode 100755
index 0349e33a1..f52a59927
--- a/examples/analytic/analytic.py
+++ b/examples/analytic/analytic.py
@@ -1,6 +1,8 @@
+#!/usr/bin/env python2
 
 def run(impl, dim, npts, nb_iter, 
-            dump_freq, stdout, stderr):
+            dump_freq, stdout, stderr, 
+            override_cache, visu_rank):
 
     import hysop
     hysop.redirect_stderr(stderr)
@@ -12,6 +14,7 @@ def run(impl, dim, npts, nb_iter,
     from hysop.constants import Implementation
     from hysop.operators import AnalyticField
     
+    # check input arguments
     assert dim in (2,3), dim
     assert (npts>0), npts
     assert (nb_iter>0), nb_iter
@@ -25,6 +28,7 @@ def run(impl, dim, npts, nb_iter,
         msg='Unknown implementation \'{}\'.'.format(impl)
         raise ValueError(msg)
     
+    # define domain and variables
     npts += 1 # domain periodicity
     d3d=(npts,)*dim
     box = Box(length=(2*np.pi,)*dim)
@@ -32,10 +36,13 @@ def run(impl, dim, npts, nb_iter,
     t      = ScalarParameter('t', dtype=np.float32)
     scalar = Field(domain=box, name='S0', nb_components=1, dtype=np.float32)
     
+    # analytic initialization method depends on chosen implementation
     if (impl is Implementation.PYTHON):
         # With the python implementation we can directly use a python method
         # (using numpy arrays). Here each field component is stored in the
-        # tuple 'data'.
+        # tuple 'data'. Coordinates will be passed as a tuple as a second 
+        # argument. Finally extra arguments (here t) are passed last.
+        # Note that t is a ScalarParameter, so we evaluate it to get its value.
         def compute_scalar(data, coords, t):
             data[0][...] = (1.0/(1.0+0.1*t()))
             for x in coords:
@@ -43,7 +50,8 @@ def run(impl, dim, npts, nb_iter,
     elif (impl is Implementation.OPENCL_CODEGEN):
         # With the opencl codegen implementation we use a symbolic expression
         # generated using sympy. OpenCL code will be automatically generated.
-        # For multiple components, multiple expressions should be given in a tuple.
+        # For a vector field, multiple expressions should be given as a tuple.
+        # Here xs and ts are the symbolic variables representing coordinates and time.
         xs = box.frame.coords
         ts = t.s
         compute_scalar = 1/(1+0.1*ts)
@@ -60,12 +68,16 @@ def run(impl, dim, npts, nb_iter,
 
     # write output field at given frequency
     analytic.dump_outputs(fields=scalar, frequency=dump_freq, filename='F')
-    
+   
+    # create the problem we want to solve and insert our operator
     problem = Problem()
     problem.insert(analytic)
-    
     problem.build()
-    #problem.display()
+
+    # if a visu_rank was provided, display the graph on the given rank
+    problem.display(visu_rank)
+
+    # create a simulation and solve it
     simu = Simulation(start=0.0, end=2*np.pi, nb_iter=nb_iter, t=t)
     problem.solve(simu)
     problem.finalize()
@@ -97,16 +109,18 @@ if __name__=='__main__':
     parser.add_argument('--npts',  help='Number of points in each discretization (default=64).', type=int, default=64, dest='npts') 
     parser.add_argument('--niter', help='Number of iterations (default=100).', type=int, default=100, dest='niter') 
     parser.add_argument('--dump-freq',   help='HDF5 output frequency in terms of iterations (default=10).', type=int, default=10, dest='dump_freq') 
-    parser.add_argument('--dump-dir',  help='HySoP output directory (default \'{}\').'.format(default_dump_dir), type=str, default=default_dump_dir, dest='dump_dir') 
-    parser.add_argument('--cache-dir', help='Specify an alternative HySoP caching directory.', type=str, default=None, dest='cache_dir') 
+    parser.add_argument('--dump-dir',  help='HySoP output directory (default \'{}\'). Overrides HYSOP_DUMP_DIR.'.format(default_dump_dir), type=str, default=default_dump_dir, dest='dump_dir') 
+    parser.add_argument('--cache-dir', help='Specify an alternative HySoP caching directory. Overrides HYSOP_CACHE_DIR.', type=str, default=None, dest='cache_dir') 
+    parser.add_argument('--override-cache', help='Ignore cached data.', action='store_true', default=False, dest='override_cache')
+    parser.add_argument('--visu-rank', help='Specify a rank were the graphical outputs will occur. By default there are no graphical outputs.', type=int, default=None, dest='visu_rank')
     parser.add_argument('--cl-platform-id', type=int, default=None, required=False, help='OpenCL platform id for the OpenCL implementation.', dest='cl_pid')
     parser.add_argument('--cl-device-id', type=int, default=None, required=False, help='OpenCL device id for the OpenCL implementation.', dest='cl_did')
     msg='All {rank} and {size} occurences are replaced by the MPI rank and MPI communicator size. {dpath} is replaced by default output path.'
     parser.add_argument('-stdout', '--std-out', type=str, default=None, required=False, help='Redirect stdout to this file after hysop has been initialized. '+msg, dest='stdout') 
     parser.add_argument('-stderr', '--std-err', type=str, default=None, required=False, help='Redirect stderr to this file after hysop has been initialized. '+msg, dest='stderr')
-    parser.add_argument('-V', '--verbose', help='Enable verbosity.', action='store_true', default=False, dest='verbose')
-    parser.add_argument('-D', '--debug',   help='Enable debugging informations.', action='store_true', default=False, dest='debug')
-    parser.add_argument('-P', '--profile', help='Enable profiling informations.', action='store_true', default=False, dest='profile')
+    parser.add_argument('-V', '--verbose', help='Enable verbosity. Overrides HYSOP_VERBOSE.', action='store_true', default=False, dest='verbose')
+    parser.add_argument('-D', '--debug',   help='Enable debugging informations. Overrides HYSOP_DEBUG.', action='store_true', default=False, dest='debug')
+    parser.add_argument('-P', '--profile', help='Enable profiling informations. Overrides HYSOP_PROFILE.', action='store_true', default=False, dest='profile')
 
     args = parser.parse_args()
 
@@ -124,4 +138,5 @@ if __name__=='__main__':
     set_env('CACHE_DIR', args.cache_dir)
     
     run(impl=impl, dim=dim, npts=npts, nb_iter=nb_iter, dump_freq=dump_freq,
-            stdout=args.stdout, stderr=args.stderr)
+            stdout=args.stdout, stderr=args.stderr, 
+            override_cache=args.override_cache, visu_rank=args.visu_rank)
diff --git a/hysop/core/graph/computational_graph.py b/hysop/core/graph/computational_graph.py
index bb6fb153d..a864a4392 100644
--- a/hysop/core/graph/computational_graph.py
+++ b/hysop/core/graph/computational_graph.py
@@ -337,10 +337,14 @@ class ComputationalGraph(ComputationalGraphNode):
 
     @debug
     @graph_built
-    def display(self, vertex_font_size=10, edge_font_size=16):
+    def display(self, visu_rank=0, vertex_font_size=10, edge_font_size=16):
         """
         Display the reduced computational graph.
         """
+        from hysop import main_rank
+        if (visu_rank is None) or (main_rank != visu_rank):
+            return
+
         graph          = self.reduced_graph
         edge_text      = graph.edge_properties['var_names']
         vertex_text    = graph.vertex_properties['op_pnames']
-- 
GitLab