SENSEI
A frame work for generic in situ analytics
PythonAnalysis.h
1 #ifndef sensei_PythonAnalysis_h
2 #define sensei_PythonAnalysis_h
3 
4 #include "senseiConfig.h"
5 #include "AnalysisAdaptor.h"
6 #include <mpi.h>
7 
8 namespace sensei
9 {
10 class DataAdaptor;
11 
12 /** Loads and executes a Python script impementing the sensei::AnalysisAdaptor
13  * API. The script should define the following functions:
14  *
15  * ```python
16  * def Initialize():
17  * """ Initialization code here """
18  * return
19  *
20  * def Execute(dataAdaptor):
21  * """ Use sensei::DataAdaptor API to process data here """
22  * return
23  *
24  * def Finalize():
25  * """ Finalization code here """
26  * return
27  * ```
28  *
29  * "Initialize" and "Finalize" are optional, while "Execute" is required. The script
30  * is specified at run time either as a module or a file. If a module is
31  * specified (see SetScriptModule) the provided module is imported through
32  * Python's built in import mechanism. This means that it must be in a
33  * directory in the `PYTHONPATH`. If a file is specified (see SetScriptFile)
34  * the file is read on rank 0 and broadcast to other ranks. Use either the
35  * module or the file approach, but not both.
36  *
37  * The active MPI communicator is made available to the script through the
38  * global variable `comm`.
39  *
40  * To fine tune run time behavior we provide "initialization source". The
41  * initialization source (see SetInitializeSource) is provided in a string and
42  * will be executed prior to your script functions. This lets you set global
43  * variables that can modify the scripts run time behavior.
44  *
45  * The compiled artifacts of this class and the sensei Python module must be
46  * findable in both the `PYTHONPATH` and the `LD_LIBRARY_PATH`
47  * (`DYLD_LIBRARY_PATH` on Mac OS)
48  *
49  * The user provided Execute function returns one of four possible things:
50  *
51  * 1. None. Success is assumed in this case, and processing continues.
52  * 2. An integer status code where 0 indicates to stop in situ processing and
53  * non-zero indicates to continue in situ processing.
54  * 3. A data adaptor instance. The data adaptor instance can be used to access
55  * the results of the operation. Success is assumed in this case and processing
56  * continues.
57  * 4. A tuple containing an integer status code (see 2 above for description of
58  * status codes) and a data adaptor instance through which results of the
59  * operation may be accessed.
60  *
61  * At any point the user provided code may raise an exception if an error
62  * occurred. This will be caught and preoprted. An error code will be returned
63  * to the simulation indicating to halt in situ processing.
64  *
65  * The user provided Execute function should call DataAdaptor::ReleaseData when
66  * processing is completed to ensure all resources are released.
67  */
68 class SENSEI_EXPORT PythonAnalysis : public AnalysisAdaptor
69 {
70 public:
71  /// Creates a new instance of the PythonAnalysis
72  static PythonAnalysis* New();
73 
74  senseiTypeMacro(PythonAnalysis, AnalysisAdaptor);
75 
76  /** Set the file to load the Python source code from rank 0 reads and
77  * broadcasts to all.
78  */
79  void SetScriptFile(const std::string &fileName);
80 
81  /** Set a module to import Python source code from. Makes use of Python's
82  * import mechanism to load your script. Your script must be in the
83  * `PYTHONPATH`.
84  */
85  void SetScriptModule(const std::string &moduleName);
86 
87  /** Set a string containing Python source code that will be executed during
88  * initialization. This can be used for instance to set global variables
89  * controlling execution. This source will be executed after loading or
90  * importing the script (see SetScriptFile and SetScriptModule) and
91  * before the script's functions.
92  */
93  void SetInitializeSource(const std::string &source);
94 
95  /** Initialize the interpreter. One must set file name or module name before
96  * initialization.
97  */
98  int Initialize();
99 
100  /// Invoke in situ processing by calling the user provided Python function.
101  bool Execute(DataAdaptor* data, DataAdaptor**) override;
102 
103  /// Shut down and clean up the embedded interpreter.
104  int Finalize() override;
105 
106 protected:
107  PythonAnalysis();
108  ~PythonAnalysis();
109 
110  PythonAnalysis(const PythonAnalysis&) = delete;
111  void operator=(const PythonAnalysis&) = delete;
112 
113 private:
114  struct InternalsType;
115  InternalsType *Internals;
116 };
117 
118 }
119 #endif
int Initialize(MPI_Comm comm, const std::string &fileName, InTransitDataAdaptor *&dataAdaptor)
Creates a sensei::ConfigurableAnalysis adaptor and sensei::InTransitDataAdaptor based on a SENSEI XML...
The base class for data consumers.
Definition: AnalysisAdaptor.h:24
SENSEI.
Definition: ADIOS2AnalysisAdaptor.h:27
Loads and executes a Python script impementing the sensei::AnalysisAdaptor API.
Definition: PythonAnalysis.h:68
Base class that defines the interface for fetching data from a simulation.
Definition: DataAdaptor.h:25