File: io.rst

package info (click to toggle)
adios2 2.10.2%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 33,764 kB
  • sloc: cpp: 175,964; ansic: 160,510; f90: 14,630; yacc: 12,668; python: 7,275; perl: 7,126; sh: 2,825; lisp: 1,106; xml: 1,049; makefile: 579; lex: 557
file content (231 lines) | stat: -rw-r--r-- 9,958 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
**
IO
**

The ``IO`` component is the connection between how applications set up their input/output options by selecting an ``Engine`` and its specific parameters, subscribing variables to data, and setting supported transport modes to a particular ``Engine``.
Think of ``IO`` as a control panel for all the user-defined parameters that applications would like to fine tune.
None of the ``IO`` operations are heavyweight until the ``Open`` function that generates an ``Engine`` is called.
Its API allows

* generation of ``Variable`` and ``Attribute`` components containing information about the data in the input output process
* setting ``Engine``-specific parameters and adding supported modes of transport
* generation of ``Engine`` objects to execute the actual IO tasks.

.. note::
   If two different engine types are needed (*e.g.* ``BPFile``, ``SST``), you must define two ``IO`` objects.
   Also, at reading always define separate IOs to avoid ``Variable`` name clashes.


.. blockdiag::

   diagram {
      default_fontsize = 17;
      default_shape = roundedbox;
      default_linecolor = blue;
      span_width = 220;

      IO -> Var_1, B, Var_N [label = "DefineVariable<T>",fontsize = 13];
      B [shape = "dots"];
      IO -> B [style = "none"];

      IO -> Att_1, C, Att_N [label = "DefineAttribute<T>",fontsize = 13];
      C [shape = "dots"];
      IO -> C [style = "none"];

      IO -> Transport_1, D, Transport_N [label = "AddTransport",fontsize = 13];
      D [shape = "dots"];
      IO -> D [style = "none"];

      IO -> Engine_1, E, Engine_N [label = "Open",fontsize = 13];
      E [shape = "dots"];
      IO -> E [style = "none"];
   }


Setting a Particular Engine and its Parameters
----------------------------------------------

Engines execute the heavy operations in ADIOS2.
Each ``IO`` may select a type of ``Engine`` through the ``SetEngine`` function.
If ``SetEngine`` is not called, then the ``BPFile`` engine is used.

.. code-block:: c++

   /** Signature */
   void adios2::IO::SetEngine( const std::string engineType );

   /** Example */
   bpIO.SetEngine("BPFile");

Each ``Engine`` allows the user to fine tune execution of buffering and output tasks via parameters passed to the ``IO`` object.
These parameters are then propagated to the ``Engine``.
For a list of parameters allowed by each engine see :ref:`Available Engines`.

.. note::

   ``adios2::Params`` is an alias to ``std::map<std::string,std::string>`` to pass parameters as key-value string pairs, which can be initialized with curly-brace initializer lists.

.. code-block:: c++

    /** Signature */
    /** Passing several parameters at once */
    void SetParameters(const adios2:Params& parameters);
    /** Passing one parameter key-value pair at a time */
    void SetParameter(const std::string key, const std::string value);

    /** Examples */
    io.SetParameters( { {"Threads", "4"},
                        {"ProfilingUnits", "Milliseconds"},
                        {"MaxBufferSize","2Gb"},
                        {"BufferGrowthFactor", "1.5" }
                        {"FlushStepsCount", "5" }
                      } );
    io.SetParameter( "Threads", "4" );


Adding Supported Transports with Parameters
-------------------------------------------

The ``AddTransport`` function allows the user to specify how data is moved through the system, *e.g.* RDMA, wide-area networks, or files.
It returns an ``unsigned int`` handler for each transport that can be used with the ``Engine::Close`` function at different times.
``AddTransport`` must provide library specific settings that the low-level system library interface allows.

.. code-block:: c++

    /** Signature */
    unsigned int AddTransport( const std::string transportType,
                               const adios2::Params& parameters );

    /** Examples */
    const unsigned int file1 = io.AddTransport( "File",
                                                { {"Library", "fstream"},
                                                  {"Name","file1.bp" }
                                                } );

    const unsigned int file2 = io.AddTransport( "File",
                                                { {"Library", "POSIX"},
                                                  {"Name","file2.bp" }
                                                } );

    const unsigned int wan = io.AddTransport( "WAN",
                                              { {"Library", "Zmq"},
                                                {"IP","127.0.0.1" },
                                                {"Port","80"}
                                              } );


Defining, Inquiring and Removing Variables and Attributes
---------------------------------------------------------

The template functions ``DefineVariable<T>`` allows subscribing to data into ADIOS2 by returning a reference to a ``Variable`` class object whose scope is the same as the ``IO`` object that created it.
The user must provide a unique name, the dimensions: MPI global: shape, MPI local: start and offset, optionally a flag indicating that dimensions are known to be constant, and a data pointer if defined in the application.
Note: data is not passed at this stage.
This is done by the ``Engine`` functions ``Put`` and ``Get`` for Variables.
See the :ref:`Variable` section for supported types and shapes.

.. tip::
   ``adios2::Dims`` is an alias to ``std::vector<std::size_t>``, while ``adios2::ConstantDims`` is an alias to bool ``true``. Use them for code clarity.

.. code-block:: c++

    /** Signature */
    adios2::Variable<T>
        DefineVariable<T>(const std::string name,
                          const adios2::Dims &shape = {}, // Shape of global object
                          const adios2::Dims &start = {}, // Where to begin writing
                          const adios2::Dims &count = {}, // Where to end writing
                          const bool constantDims = false);

    /** Example */
    /** global array of floats with constant dimensions */
    adios2::Variable<float> varFloats =
        io.DefineVariable<float>("bpFloats",
                                 {size * Nx},
                                 {rank * Nx},
                                 {Nx},
                                 adios2::ConstantDims);

Attributes are extra-information associated with the current ``IO`` object.
The function ``DefineAttribute<T>`` allows for defining single value and array attributes.
Keep in mind that Attributes apply to all Engines created by the ``IO`` object and, unlike Variables which are passed to each ``Engine`` explicitly, their definition contains their actual data.

.. code-block:: c++

    /** Signatures */

    /** Single value */
    adios2::Attribute<T> DefineAttribute(const std::string &name,
                                  const T &value);

    /** Arrays */
    adios2::Attribute<T> DefineAttribute(const std::string &name,
                                  const T *array,
                                  const size_t elements);

In situations in which a variable and attribute has been previously defined:
1) a variable/attribute reference goes out of scope, or 2) when reading from an incoming stream, the ``IO`` can inquire about the status of variables and attributes.
If the inquired variable/attribute is not found, then the overloaded ``bool()`` operator of returns ``false``.

.. code-block:: c++

    /** Signature */
    adios2::Variable<T> InquireVariable<T>(const std::string &name) noexcept;
    adios2::Attribute<T> InquireAttribute<T>(const std::string &name) noexcept;

    /** Example */
    adios2::Variable<float> varPressure = io.InquireVariable<float>("pressure");
    if( varPressure ) // it exists
    {
      ...
    }


.. note::
   ``adios2::Variable`` overloads ``operator bool()`` so that we can check for invalid states (e.g. variables haven't arrived in a stream, weren't previously defined, or weren't written in a file).

.. caution::

   Since ``InquireVariable`` and ``InquireAttribute`` are template functions, both the name and type must match the data you are looking for.


Opening an Engine
-----------------

The ``IO::Open`` function creates a new derived object of the abstract ``Engine`` class and returns a reference handler to the user.
A particular ``Engine`` type is set to the current ``IO`` component with the ``IO::SetEngine`` function.
Engine polymorphism is handled internally by the ``IO`` class, which allows subclassing future derived ``Engine`` types without changing the basic API.

``Engine`` objects are created in various modes.
The available modes are ``adios2::Mode::Read``, ``adios2::Mode::ReadRandomAccess``, ``adios2::Mode::Write``, ``adios2::Mode::Append``, ``adios2::Mode::Sync``, ``adios2::Mode::Deferred``, and ``adios2::Mode::Undefined``.


.. code-block:: c++

    /** Signatures */
    /** Provide a new MPI communicator other than from ADIOS->IO->Engine */
    adios2::Engine adios2::IO::Open(const std::string &name,
                                    const adios2::Mode mode,
                                    MPI_Comm mpiComm );

    /** Reuse the MPI communicator from ADIOS->IO->Engine \n or non-MPI serial mode */
    adios2::Engine adios2::IO::Open(const std::string &name,
                                    const adios2::Mode mode);


    /** Examples */

    /** Engine derived class, spawned to start Write operations */
    adios2::Engine bpWriter = io.Open("myVector.bp", adios2::Mode::Write);

    /** Engine derived class, spawned to start Read operations on rank 0 */
    if( rank == 0 )
    {
        adios2::Engine bpReader = io.Open("myVector.bp",
                                           adios2::Mode::Read,
                                           MPI_COMM_SELF);
    }

.. caution::

   Always pass ``MPI_COMM_SELF`` if an ``Engine`` lives in only one MPI process.
   ``Open`` and ``Close`` are collective operations.