Newer
Older
/*
* reader.cpp
*
* Created on: Feb 13, 2017
* Author: pnorbert
*/
#include <iostream>
#include "ADIOS_CPP.h"
int rank, nproc;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
const bool adiosDebug = true;
adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug);
// Application variable
std::vector<double> NiceArray;
std::vector<float> RaggedArray;
int Nparts;
int Nwriters;
int Nsteps;
try
{
// Define method for engine creation
// 1. Get method def from config file or define new one
adios::Method &bpReaderSettings = adios.GetMethod("input");
if (bpReaderSettings.undeclared())
// if not defined by user, we can change the default settings
bpReaderSettings.SetEngine("BP"); // BP is the default engine
// By default we see all steps available in a file, so the next line is
// not needed
bpReaderSettings.SetParameters("Stepping", false);
}
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
// Create engine smart pointer due to polymorphism,
// Default behavior
// auto bpReader = adios.Open( "myNumbers.bp", "r" );
// this would just open with a default transport, which is "BP"
auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings);
// All the above is same as default use:
// auto bpReader = adios.Open( "myNumbers.bp", "r");
if (bpReader == nullptr)
throw std::ios_base::failure("ERROR: failed to open ADIOS bpReader\n");
/* Note: there is no global number of steps. Each variable has its own
* number of steps */
/* NX */
/* There is a single value for each step. We can read all into a 1D array
* with a step selection.
* We can also just conveniently get the first with a simple read statement.
* Steps are not automatically presented as an array dimension and read does
* not read it as array.
*/
unsigned int Nx;
bpReader->Read<unsigned int>(
"NX", &Nx); // read a Global scalar which has a single value in a step
std::shared_ptr<adios::Variable<void>> varNx =
bpReader.InquiryVariable("Nx");
std::vector<int> Nxs(varNx->nsteps()); // number of steps available
// make a StepSelection to select multiple steps. Args: From, #of
// consecutive steps
std::unique_ptr<adios::StepSelection> stepsNx =
adios.StepSelection(0, varNx->nsteps());
// ? How do we make a selection for an arbitrary list of steps ?
varNX.SetStepSelection(stepsNx);
bpReader->Read<unsigned int>(varNx, Nxs.data());
auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs));
auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs));
if (*itmin != *itmax)
{
throw std::ios_base::failure("ERROR: NX is not the same at all steps!\n");
}
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
/* nproc */
bpReader->Read<int>("nproc", &Nwriters); // also a global scalar
/* Nparts */
// Nparts local scalar is presented as a 1D array of Nwriters elements.
// We can read all steps into a 2D array of nproc * Nwriters
std::shared_ptr<adios::Variable<void>> varNparts =
bpReader.InquiryVariable("Nparts");
std::vector<int> partsV(Nproc * Nwriters);
varNparts->SetStepSelection(adios.StepSelection(0, varNparts->nsteps()));
bpReader->Read<int>(
varNparts,
partsV.data()); // missing spatial selection = whole array at each step
/* Nice */
// inquiry about a variable, whose name we know
std::shared_ptr<adios::Variable<void>> varNice =
bpReader.InquiryVariable("Nice");
if (varNice == nullptr)
throw std::ios_base::failure(
"ERROR: failed to find variable 'myDoubles' in input file\n");
// ? how do we know about the type? std::string varNice->m_Type
unsigned long long int gdim =
varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func?
unsigned long long int ldim = gdim / nproc;
unsigned long long int offs = rank * ldim;
if (rank == nproc - 1)
{
ldim = gdim - (ldim * gdim);
}
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
NiceArray.reserve(ldim);
// Make a 1D selection to describe the local dimensions of the variable we
// READ and
// its offsets in the global spaces
std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox(
{ldim}, {offs}); // local dims and offsets; both as list
bpReader->Read<double>("Nice", bbsel,
NiceArray.data()); // Base class Engine own the
// Read<T> that will call
// overloaded Read from Derived
/* Ragged */
// inquiry about a variable, whose name we know
std::shared_ptr<adios::Variable<void>> varRagged =
bpReader.InquiryVariable("Ragged");
if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION)
{
throw std::ios_base::failure(
"Unexpected condition: Ragged array's fast dimension "
"is supposed to be VARYING_DIMENSION\n");
}
// We have here varRagged->sum_nblocks, nsteps, nblocks[], global
if (rank < varRagged->nblocks[0]) // same as rank < Nwriters in this example
{
// get per-writer size information
varRagged->InquiryBlocks();
// now we have the dimensions per block
unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0];
RaggedArray.resize(ldim);
std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock(rank);
bpReader->Read<float>("Ragged", wbsel, RaggedArray.data());
// We can use bounding box selection as well
std::unique_ptr<adios::Selection> rbbsel =
adios.SelectionBoundingBox({1, ldim}, {rank, 0});
bpReader->Read<float>("Ragged", rbbsel, RaggedArray.data());
/* Extra help to process Ragged */
int maxRaggedDim =
varRagged->GetMaxGlobalDimensions(1); // contains the largest
std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(
1); // contains all individual sizes in that dimension
// Close file/stream
bpReader->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";