File: valuesWrite.cpp

package info (click to toggle)
adios2 2.10.2%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • 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 (170 lines) | stat: -rw-r--r-- 5,589 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
/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * Write single values to a file. There are four different cases:
 * 1. Global constant - same on all processes, constant over time
 * 2. Global value - same on all processes, may change over time
 * 3. Local constants - different across processes, constant over time
 * 4. Local value - different across processes, may change over time
 *
 * Constants are not handled separately from time-varying values in ADIOS.
 * Simply write them only in the first step.
 *
 * Writing a global value from multiple processes does not hurt but it is
 * useless.
 *
 * Created on: Jun 2, 2017
 *      Author: pnorbert
 */

#include <iostream>
#include <string>
#include <vector>

#include <adios2.h>
#if ADIOS2_USE_MPI
#include <mpi.h>
#endif

int main(int argc, char *argv[])
{
    int rank = 0, nproc = 1;
#if ADIOS2_USE_MPI
    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, &nproc);
#endif
    const int NSTEPS = 5;

    // generate different random numbers on each process,
    // but always the same sequence at each run
    srand(rank * 32767);

#if ADIOS2_USE_MPI
    adios2::ADIOS adios(MPI_COMM_WORLD);
#else
    adios2::ADIOS adios;
#endif

    // Application variables for output
    // 1. Global value, constant across processes, constant over time
    // This is 'nproc'

    // 2. Global value, constant across processes, varying value over time
    // This is 'step'

    // 3. Local value, varying across processes, constant over time
    // It will appear in reading as a 1D array of nproc elements.
    // This is 'rank'

    // 4. Local value, varying across processes, varying over time
    unsigned int Nparts; // random size per process, 5..10 each

    try
    {
        // Get io settings from the config file or
        // create one with default settings here
        adios2::IO io = adios.DeclareIO("Output");
        io.SetEngine("BPFile");
        io.SetParameters({{"verbose", "4"}});
        /*
         * Define variables
         */
        // 1. Global constant, same value across processes, constant over time
        adios2::Variable<int> varNproc = io.DefineVariable<int>("Nproc");
        (void)varNproc; // For the sake of the example we create an unused
                        // variable

        // 2. Global value, same value across processes, varying value over time
        adios2::Variable<int> varStep = io.DefineVariable<int>("Step");
        adios2::Variable<std::string> varGlobalString =
            io.DefineVariable<std::string>("GlobalString");

        // 3. Local value, varying across processes, constant over time
        adios2::Variable<int> varProcessID =
            io.DefineVariable<int>("ProcessID", {adios2::LocalValueDim});

        // 4. Local value, varying across processes, varying over time
        adios2::Variable<unsigned int> varNparts =
            io.DefineVariable<unsigned int>("Nparts", {adios2::LocalValueDim});

        // Open file. "w" means we overwrite any existing file on disk,
        // but Advance() will append steps to the same file.
        adios2::Engine writer = io.Open("values.bp", adios2::Mode::Write);

        for (int step = 0; step < NSTEPS; step++)
        {
            writer.BeginStep();

            // random size per process, 5..10 each
            Nparts = rand() % 6 + 5;

            // 1. and 2. Writing a global value from only one process
            if (rank == 0)
            {
                // 1. Writing a global constant value only once
                if (step == 0)
                {
                    adios2::Variable<int> varNproc = io.InquireVariable<int>("Nproc");
                    writer.Put<int>(varNproc, nproc);
                }
                writer.Put<int>(varStep, step);

                std::string str = "This is step " + std::to_string(step);
                // str will go out of scope before EndStep(), so we must use
                // Sync mode in Put()
                writer.Put<std::string>(varGlobalString, str, adios2::Mode::Sync);
            }

            // 3. and 4. Writing a local value on every process. Will be shown
            // at reading as a 1D array
            if (step == 0)
            {
                writer.Put<int>(varProcessID, rank);
            }
            writer.Put<unsigned int>(varNparts, Nparts);

            // Indicate we are done for this step.
            // Disk I/O will be performed during this call unless
            // time aggregation postpones all of that to some later step
            writer.EndStep();
        }

        // Called once: indicate that we are done with this output for the run
        writer.Close();
    }
    catch (std::invalid_argument &e)
    {
        if (rank == 0)
        {
            std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::ios_base::failure &e)
    {
        if (rank == 0)
        {
            std::cout << "System exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::exception &e)
    {
        if (rank == 0)
        {
            std::cout << "Exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }

#if ADIOS2_USE_MPI
    MPI_Finalize();
#endif

    return 0;
}