File: steps.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 (212 lines) | stat: -rw-r--r-- 6,031 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
Steps
=====

.. _sec:tutorials_basics_steps:

In the previous tutorial, we introduced the concept of operators, and briefly touched upon the concept of steps.

In this tutorial, we will explore how to write data for multiple steps, and how to read them back.

So let's dig in!

Start editing the skeleton file `ADIOS2/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cpp <https://github.com/ornladios/ADIOS2/blob/master/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cpp>`_.

1. In an MPI application first we need to always initialize MPI. We do that with the following lines:

.. code-block:: cpp

   int rank, size;
   int rank, size;
   int provided;

   // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP
   MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);

2. This application has an optional command line argument for engine being used. If
   no argument is provided, the default engine is BPFile.

.. code-block:: cpp

    const std::string engine = argv[1] ? argv[1] : "BPFile";

3. We will define the number of steps and the size of the data that we will create.

.. code-block:: cpp

    const std::string filename = engine + "StepsWriteRead.bp";
    const unsigned int nSteps = 10;
    const unsigned int Nx = 60000;

4. Now we need to create an ADIOS2 instance.

.. code-block:: cpp

   adios2::ADIOS adios(MPI_COMM_WORLD);

5. Now we will populate the writer function with the following signature:

.. code-block::

   void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname,
             const size_t Nx, unsigned int nSteps, int rank, int size)
   {
     ...
   }

6. Let's create some simulation data. We will create a 1D array of size Nx, and fill it with 0.block

.. code-block:: cpp

   std::vector<double> simData(Nx, 0.0);

7. Now we will create an IO object and set the engine type.block

.. code-block:: cpp

   adios2::IO bpIO = adios.DeclareIO("SimulationOutput");
   io.SetEngine(engine);

.. note::

   The beauty of ADIOS2 is that you write the same code for all engines. The only thing that changes is the engine name.
   The underlying engine handles all the intricacies of the engine's format, and the user enjoys the API's simplicity.

8. Now we will create a variable for the simulation data and the step.

.. code-block:: cpp

    const adios2::Dims shape{static_cast<size_t>(size * Nx)};
    const adios2::Dims start{static_cast<size_t>(rank * Nx)};
    const adios2::Dims count{Nx};
    auto bpFloats = bpIO.DefineVariable<float>("bpFloats", shape, start, count);

    auto bpStep = bpIO.DefineVariable<unsigned int>("bpStep");

9. Now we will open the file for writing.

.. code-block:: cpp

    adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write);

10. Now we will write the data for each step.

.. code-block:: cpp

   for (unsigned int step = 0; step < nSteps; ++step)
   {
       const adios2::Box<adios2::Dims> sel({0}, {Nx});
       bpFloats.SetSelection(sel);

       bpWriter.BeginStep();
       bpWriter.Put(bpFloats, simData.data());
       bpWriter.Put(bpStep, step);
       bpWriter.EndStep();

       // Update values in the simulation data
       update_array(simData, 10);
   }

11. Now we will close the file.

.. code-block:: cpp

   bpWriter.Close();

12. Now we will populate the reader function with the following signature:

.. code-block:: cpp

   void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname,
               const size_t Nx, unsigned int /*nSteps*/, int rank, int /*size*/)
   {
     ...
   }

13. Now we will create an IO object and set the engine type.

.. code-block:: cpp

   adios2::IO bpIO = adios.DeclareIO("SimulationOutput");
   io.SetEngine(engine);

14. Now we will open the file for reading.

.. code-block:: cpp

   adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read);

15. Now we will create a vector to store simData and a variable for the step.

.. code-block:: cpp

   std::vector<float> simData(Nx, 0);
   unsigned int inStep = 0;

16. Now we will read the data for each step.

.. code-block:: cpp

   for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step)
   {
       auto bpFloats = bpIO.InquireVariable<float>("bpFloats");
       if (bpFloats)
       {
           const adios2::Box<adios2::Dims> sel({{Nx * rank}, {Nx}});
           bpFloats.SetSelection(sel);
           bpReader.Get(bpFloats, simData.data());
       }
       auto bpStep = bpIO.InquireVariable<unsigned int>("bpStep");
       if (bpStep)
       {
           bpReader.Get(bpStep, &inStep);
       }

       bpReader.EndStep();
   }

17. Now we will close the file.

.. code-block:: cpp

   bpReader.Close();

18. Now we will call the writer and reader functions:

.. code-block:: cpp

   writer(adios, engine, filename, Nx, nSteps, rank, size);
   reader(adios, engine, filename, Nx, nSteps, rank, size);

19. Finally we need to finalize MPI.

.. code-block:: cpp

   MPI_Finalize();

20. The final code should look as follows (excluding try/catch and optional usage of MPI), and it was derived from the
    example `ADIOS2/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp <https://github.com/ornladios/ADIOS2/blob/master/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp>`_.

.. literalinclude:: ../../../../examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp
   :language: cpp

21. You can compile and run it as follows:

.. code-block:: bash

   cd Path-To-ADIOS2/examples/hello/bpStepsWriteRead
   mkdir build
   cd build
   cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ ..
   cmake --build .
   mpirun -np 2 ./adios2_hello_bpStepsWriteRead_mpi

22. You can check the content of the output file "BPFileStepsWriteRead.bp" using *bpls* as follows:

.. code-block:: bash

   Path-To-ADIOS2/build/bin/bpls ./BPFileStepsWriteRead.bp

     float     bpFloats  10*{120000}
     uint32_t  bpStep    10*scalar