Skip to content
Snippets Groups Projects
Commit c4f2931d authored by Podhorszki, Norbert's avatar Podhorszki, Norbert
Browse files

Remove standalone ADIOS2/HDF5 heat transfer codes and use the one-and-only...

Remove standalone ADIOS2/HDF5 heat transfer codes and use the one-and-only ADIOS2 version of the code with all available engines.
parent 9ab1e5bb
No related branches found
No related tags found
1 merge request!343Names of engines in Open: BPFile, DataMan, HDF5, ADIOS1. Case insensi…
#include <mpi.h>
#include "adios2.h"
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "PrintData.h"
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
if (argc < 2)
{
std::cout << "Not enough arguments: need an input file\n";
return 1;
}
const char *inputfile = argv[1];
/* World comm spans all applications started with the same aprun command
on a Cray XK6. So we have to split and create the local
'world' communicator for the reader only.
In normal start-up, the communicator will just equal the MPI_COMM_WORLD.
*/
int wrank, wnproc;
MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
MPI_Barrier(MPI_COMM_WORLD);
const unsigned int color = 2;
MPI_Comm mpiReaderComm;
MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &mpiReaderComm);
int rank, nproc;
MPI_Comm_rank(mpiReaderComm, &rank);
MPI_Comm_size(mpiReaderComm, &nproc);
try
{
adios2::ADIOS ad("adios2.xml", mpiReaderComm, adios2::DebugOFF);
// Define method for engine creation
// 1. Get method def from config file or define new one
adios2::IO &h5ReaderIO = ad.DeclareIO("input");
if (!h5ReaderIO.InConfigFile())
{
// if not defined by user, we can change the default settings
// BPFile is the default engine
// h5ReaderIO.SetEngine("ADIOS1");
h5ReaderIO.SetEngine("HDF5");
// h5ReaderIO.SetParameters({{"num_threads", "2"}});
// ISO-POSIX file is the default transport
// Passing parameters to the transport
h5ReaderIO.AddTransport("File", {{"verbose", "4"}});
}
adios2::Engine &h5Reader =
h5ReaderIO.Open(inputfile, adios2::Mode::Read, mpiReaderComm);
unsigned int gndx;
unsigned int gndy;
// h5Reader->Read<unsigned int>("gndx", &gndx);
// h5Reader->Read<unsigned int>("gndy", &gndy);
adios2::Variable<unsigned int> *vgndx =
h5ReaderIO.InquireVariable<unsigned int>("gndx");
// gndx = vgndx->GetData()[0];
adios2::Variable<unsigned int> *vgndy =
h5ReaderIO.InquireVariable<unsigned int>("gndy");
// gndy = vgndy->GetData()[0];
adios2::Variable<double> *vT = h5ReaderIO.InquireVariable<double>("T");
if ((vgndx == NULL) || (vgndy == NULL) || (vT == NULL))
{
std::cout << "Unable to find expected variables: gndx, gndy and T"
<< std::endl;
return 1;
}
h5Reader.GetSync<unsigned int>(*vgndx, gndx);
h5Reader.GetSync<unsigned int>(*vgndy, gndy);
if (rank == 0)
{
std::cout << "gndx = " << gndx << std::endl;
std::cout << "gndy = " << gndy << std::endl;
std::cout << "# of steps = " << vgndy->GetAvailableStepsCount()
<< std::endl;
}
// 1D decomposition of the columns, which is inefficient for reading!
adios2::Dims readsize({gndx, gndy / nproc});
adios2::Dims offset({0LL, rank * readsize[1]});
if (rank == nproc - 1)
{
// last process should read all the rest of columns
readsize[1] = gndy - readsize[1] * (nproc - 1);
}
std::cout << "rank " << rank << " reads " << readsize[1]
<< " columns from offset " << offset[1] << std::endl;
if (readsize[1] == 0)
{
std::cout << "Nothing to read. exiting" << std::endl;
return 0;
}
double *T = new double[vT->GetAvailableStepsCount() * readsize[0] *
readsize[1]];
// Create a 2D selection for the subset
vT->SetSelection(adios2::Box<adios2::Dims>(offset, readsize));
vT->SetStepSelection(
adios2::Box<std::size_t>(0, vT->GetAvailableStepsCount()));
h5Reader.GetSync<double>(*vT, T);
// Arrays are read by scheduling one or more of them
// and performing the reads at once
// h5Reader->ScheduleRead<double>(*vT, T);
// h5Reader->PerformReads(adios2::ReadMode::Blocking);
printData(T, readsize.data(), offset.data(), rank,
vT->GetAvailableStepsCount());
h5Reader.Close();
delete[] T;
}
catch (std::invalid_argument &e)
{
std::cout << "Invalid argument exception, STOPPING PROGRAM from rank "
<< rank << "\n";
std::cout << e.what() << "\n";
}
catch (std::ios_base::failure &e)
{
std::cout << "IO System base failure exception, STOPPING PROGRAM "
"from rank "
<< rank << "\n";
std::cout << e.what() << "\n";
}
catch (std::exception &e)
{
std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n";
std::cout << e.what() << "\n";
}
MPI_Finalize();
return 0;
}
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* IO_ph5_adios2.cpp
*
* Created on: Feb 2017
* Author: Norbert Podhorszki
*/
#include "IO.h"
#include <string>
#include <adios2.h>
adios2::ADIOS *ad = nullptr;
adios2::Engine *h5writer;
adios2::Variable<double> *varT = nullptr;
adios2::Variable<unsigned int> *varGndx = nullptr;
IO::IO(const Settings &s, MPI_Comm comm)
{
m_outputfilename = MakeFilename(s.outputfile, ".h5");
ad = new adios2::ADIOS(comm, adios2::DebugOFF);
// Define method for engine creation
// 1. Get method def from config file or define new one
adios2::IO &h5io = ad->DeclareIO("writer");
if (!h5io.InConfigFile())
{
// if not defined by user, we can change the default settings
// BPFile is the default engine
h5io.SetEngine("HDF5");
}
varGndx = &h5io.DefineVariable<unsigned int>("gndx");
h5io.DefineVariable<unsigned int>("gndy");
// define T as 2D global array
varT = &h5io.DefineVariable<double>(
"T",
// Global dimensions
{s.gndx, s.gndy},
// starting offset of the local array in the global space
{s.offsx, s.offsy},
// local size, could be defined later using SetSelection()
{s.ndx, s.ndy});
// add transform to variable
// adios2::Transform tr = adios2::transform::BZIP2( );
// varT.AddTransform( tr, "" );
// varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP
h5writer = &(h5io.Open(m_outputfilename, adios2::Mode::Write, comm));
}
IO::~IO()
{
h5writer->Close();
delete ad;
}
void IO::write(int step, const HeatTransfer &ht, const Settings &s,
MPI_Comm comm)
{
#if 1
/* This selection is redundant and not required, since we defined
* the selection already in DefineVariable(). It is here just as an example.
*/
// Make a selection to describe the local dimensions of the variable we
// write and its offsets in the global spaces. This could have been done in
// adios.DefineVariable()
// adios2::SelectionBoundingBox sel({s.offsx, s.offsy}, {s.ndx, s.ndy});
// varT->SetSelection(sel);
/* Select the area that we want to write from the data pointer we pass to
the
writer.
Think HDF5 memspace, just not hyperslabs, only a bounding box selection.
Engine will copy this bounding box from the data pointer into the output
buffer.
Size of the bounding box should match the "space" selection which was
given
above.
Default memspace is always the full selection.
*/
// adios2::SelectionBoundingBox memspace =
// adios2::SelectionBoundingBox({1, 1}, {s.ndx, s.ndy});
// varT->SetMemorySelection(memspace);
h5writer->BeginStep();
h5writer->PutSync<double>(*varT, ht.data_noghost().data());
// h5writer->Write(*varT, ht.data_noghost().data());
h5writer->PutSync<unsigned int>(*varGndx, &(s.gndx));
h5writer->PutSync("gndy", &(s.gndy));
h5writer->EndStep();
#else
h5writer->BeginStep();
h5writer->PutSync<double>(*varT, ht.data_noghost().data());
h5writer->EndStep();
#endif
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment