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;
}
|