Newer
Older
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* reader.cpp
*
* Created on: Feb 13, 2017
* Author: pnorbert
*/
#include <iostream>
Podhorszki, Norbert
committed
template <class T>
T **Make2DArray(int nRows, int nCols)
{
T **ptr = new T *[nRows];
ptr[0] = new T[nRows * nCols];
for (int i = 1; i < nRows; i++)
{
ptr[i] = ptr[i - 1] + nCols;
}
return ptr;
}
template <class T>
void Delete2DArray(T **ptr)
{
delete[] ptr[0];
delete[] ptr;
}
Podhorszki, Norbert
committed
template <class T>
void Print1DArray(T *ptr, int nElems, std::string name)
{
std::cout << name << " = { ";
for (int i = 0; i < nElems; i++)
{
std::cout << ptr[i] << " ";
}
std::cout << "}\n";
}
Podhorszki, Norbert
committed
template <class T>
void Print2DArray(T **ptr, int nRows, int nCols, std::string name)
{
std::cout << name << " = { \n";
for (int step = 0; step < nRows; step++)
{
std::cout << " { ";
for (int col = 0; col < nCols; col++)
{
std::cout << ptr[step][col] << " ";
}
std::cout << "}\n";
}
std::cout << "}\n";
}
int rank = 0, nproc = 1;
#ifdef ADIOS2_HAVE_MPI
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
const bool adiosDebug = true;
adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON);
Podhorszki, Norbert
committed
// Info variables from the file
Podhorszki, Norbert
committed
// Data variables from the file
// 1. Global value, constant across processes, constant over time
unsigned int Nx;
// 2. Local value, varying across processes, constant over time
std::vector<int> ProcessID;
// 3. Global array, global dimensions, local dimensions and offsets are
// constant over time
Podhorszki, Norbert
committed
// std::vector<double> GlobalArrayFixedDims;
Podhorszki, Norbert
committed
// 4. Local array, local dimensions are
// constant over time (but different across processors here)
std::vector<float> LocalArrayFixedDims;
// 5. Global value, constant across processes, VARYING value over time
std::vector<unsigned int> Nys;
// 6. Local value, varying across processes, VARYING over time
// Read as a 2D array, time as first dimension
// 7. Global array, dimensions and offsets are VARYING over time
std::vector<double> GlobalArray;
// 8. Local array, dimensions and offsets are VARYING over time
std::vector<float> IrregularArray;
try
{
// Define method for engine creation
// 1. Get method def from config file or define new one
adios2::IO &bpReaderSettings = adios.DeclareIO("input");
if (!bpReaderSettings.InConfigFile())
{
// if not defined by user, we can change the default settings
Podhorszki, Norbert
committed
bpReaderSettings.SetEngine(
"ADIOS1Reader"); // BP is the default engine
// see only one step at a time
bpReaderSettings.SetParameters({{"OpenAsFile", "yes"}});
}
// 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"
bpReaderSettings.Open("myNumbers.bp", adios2::OpenMode::Read);
throw std::ios_base::failure(
"ERROR: failed to open ADIOS bpReader\n");
Podhorszki, Norbert
committed
/* Note: there is no global number of steps. Each variable has its
* own
adios2::Variable<int> *vNproc = bpReader->InquireVariable<int>("Nproc");
Podhorszki, Norbert
committed
Nwriters = vNproc->m_Data[0];
Podhorszki, Norbert
committed
if (rank == 0)
std::cout << "# of writers = " << Nwriters << std::endl;
Podhorszki, Norbert
committed
Podhorszki, Norbert
committed
/* There is a single value written once.
Podhorszki, Norbert
committed
// read a Global scalar which has a single value in a step
bpReader->InquireVariable<unsigned int>("NX");
Podhorszki, Norbert
committed
Nx = vNX->m_Data[0];
// bpReader->Read<unsigned int>("NX", &Nx);
Podhorszki, Norbert
committed
if (rank == 0)
std::cout << "NX = " << Nx << std::endl;
Podhorszki, Norbert
committed
/* NY */
/* We can read all into a 1D array with a step selection.
Steps are not automatically presented as an array dimension
and read does not read it as array by default.
*/
bpReader->InquireVariable<unsigned int>("NY");
Nys.resize(vNY->m_AvailableSteps); // number of steps available
// make a StepSelection to select multiple steps. Args: From, #of
// consecutive steps
// ? How do we make a selection for an arbitrary list of steps ?
vNY->SetStepSelection(0, vNY->m_AvailableSteps);
Podhorszki, Norbert
committed
bpReader->Read<unsigned int>(*vNY, Nys.data());
Podhorszki, Norbert
committed
if (rank == 0)
Print1DArray(Nys.data(), Nys.size(), "NY");
Podhorszki, Norbert
committed
/* ProcessID */
bpReader->InquireVariable<int>("ProcessID");
Podhorszki, Norbert
committed
if (vProcessID->m_Shape[0] != Nwriters)
Podhorszki, Norbert
committed
std::cout << "ERROR: Unexpected array size of ProcessID = "
<< vProcessID->m_Shape[0] << " != # of writers"
<< std::endl;
Podhorszki, Norbert
committed
ProcessID.resize(vProcessID->m_Shape[0]);
bpReader->Read<int>(*vProcessID, ProcessID.data());
Podhorszki, Norbert
committed
if (rank == 0)
Print1DArray(ProcessID.data(), ProcessID.size(), "ProcessID");
Podhorszki, Norbert
committed
// Nparts local scalar is presented as a 1D array of Nwriters
// elements.
// We can read all steps into a 2D array of nproc * Nwriters
adios2::Variable<unsigned int> *vNparts =
bpReader->InquireVariable<unsigned int>("Nparts");
Podhorszki, Norbert
committed
unsigned int **Nparts =
Make2DArray<unsigned int>(vNparts->m_AvailableSteps, Nwriters);
vNparts->SetStepSelection(0, vNparts->m_AvailableSteps);
Podhorszki, Norbert
committed
bpReader->Read<unsigned int>(*vNparts, Nparts[0]);
Podhorszki, Norbert
committed
if (rank == 0)
Print2DArray(Nparts, vNparts->m_AvailableSteps, Nwriters, "Nparts");
Podhorszki, Norbert
committed
Delete2DArray(Nparts);
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);
Podhorszki, Norbert
committed
/*
* GlobalArrayFixedDims
*/
// inquiry about a variable, whose name we know
adios2::Variable<double> *vGlobalArrayFixedDims =
bpReader->InquireVariable<double>("GlobalArrayFixedDims");
Podhorszki, Norbert
committed
if (vGlobalArrayFixedDims == nullptr)
throw std::ios_base::failure(
"ERROR: failed to find variable "
"'GlobalArrayFixedDims' in input file\n");
// ? how do we know about the type? std::string varNice->m_Type
Podhorszki, Norbert
committed
std::size_t gdim =
vGlobalArrayFixedDims->m_Shape[0]; // ?member var or member func?
std::size_t count = gdim / nproc;
std::size_t start = rank * count;
if (rank == nproc - 1)
{
Podhorszki, Norbert
committed
count = gdim - (count * (nproc - 1));
Podhorszki, Norbert
committed
if (rank == 0)
std::cout << "GlobalArrayFixedDims parallel read" << std::endl;
Podhorszki, Norbert
committed
double **GlobalArrayFixedDims =
Make2DArray<double>(vGlobalArrayFixedDims->m_AvailableSteps, count);
// Make a 1D selection to describe the local dimensions of the variable
Podhorszki, Norbert
committed
// we READ and its offsets in the global spaces
vGlobalArrayFixedDims->SetSelection({start}, {count});
Podhorszki, Norbert
committed
vGlobalArrayFixedDims->SetStepSelection(
0, vGlobalArrayFixedDims->m_AvailableSteps);
Podhorszki, Norbert
committed
bpReader->Read<double>(*vGlobalArrayFixedDims, GlobalArrayFixedDims[0]);
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);
MPI_Status status;
int token = 0;
if (rank > 0)
MPI_Recv(&token, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, &status);
Podhorszki, Norbert
committed
std::cout << "Rank " << rank << " read start = " << start
<< " count = " << count << std::endl;
Print2DArray(GlobalArrayFixedDims,
vGlobalArrayFixedDims->m_AvailableSteps, count,
"GlobalArrayFixedDims");
Podhorszki, Norbert
committed
if (rank < nproc - 1)
MPI_Send(&token, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
#endif
Delete2DArray(GlobalArrayFixedDims);
Podhorszki, Norbert
committed
/*
* LocalArrayFixedDims
*/
Podhorszki, Norbert
committed
// inquiry about a variable, whose name we know
adios2::Variable<float> *vLocalArrayFixedDims =
bpReader->InquireVariable<float>("LocalArrayFixedDims");
if (vLocalArrayFixedDims->m_Shape[0] != adios2::IrregularDim)
Podhorszki, Norbert
committed
{
throw std::ios_base::failure(
"Unexpected condition: LocalArrayFixedDims array's fast "
"dimension is supposed to be adios2::IrregularDim indicating "
"an "
Podhorszki, Norbert
committed
"Irregular array\n");
}
std::cout << "LocalArrayFixedDims is irregular. Cannot read this "
"variable yet...\n";
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);
/*
* LocalArrayFixedDimsJoined
*/
// inquiry about a variable, whose name we know
adios2::Variable<float> *vLocalArrayFixedDimsJoined =
bpReader->InquireVariable<float>("LocalArrayFixedDimsJoined");
Podhorszki, Norbert
committed
float **LocalArrayFixedDimsJoined =
Make2DArray<float>(vLocalArrayFixedDimsJoined->m_AvailableSteps,
Podhorszki, Norbert
committed
vLocalArrayFixedDimsJoined->m_Shape[0]);
// Make a 1D selection to describe the local dimensions of the variable
// we READ and its offsets in the global spaces
vLocalArrayFixedDimsJoined->SetSelection(
{0}, {vLocalArrayFixedDimsJoined->m_Shape[0]});
vLocalArrayFixedDimsJoined->SetStepSelection(
0, vLocalArrayFixedDimsJoined->m_AvailableSteps);
Podhorszki, Norbert
committed
bpReader->Read<float>(*vLocalArrayFixedDimsJoined,
LocalArrayFixedDimsJoined[0]);
if (rank == 0)
Print2DArray(LocalArrayFixedDimsJoined,
vLocalArrayFixedDimsJoined->m_AvailableSteps,
Podhorszki, Norbert
committed
vLocalArrayFixedDimsJoined->m_Shape[0],
"LocalArrayFixedDimsJoined");
Delete2DArray(LocalArrayFixedDimsJoined);
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);
Podhorszki, Norbert
committed
/*
* GlobalArray which changes size over time
*/
Podhorszki, Norbert
committed
// inquiry about a variable, whose name we know
bpReader->InquireVariable<double>("GlobalArray");
std::cout << "GlobalArray [" << vGlobalArray->m_Shape[0] << "]";
std::cout << " = Cannot read this variable yet...\n";
if (vGlobalArray->m_Shape[0] != adios2::IrregularDim)
{
throw std::ios_base::failure(
"Unexpected condition: GlobalArray array's "
"dimension is supposed to be adios2::IrregularDim indicating "
"an "
"Irregular array\n");
}
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);
// 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";
}
if (rank == 0)
{
std::cout << "Exception, STOPPING PROGRAM\n";
std::cout << e.what() << "\n";
}
Podhorszki, Norbert
committed
MPI_Barrier(MPI_COMM_WORLD);