Skip to content
Snippets Groups Projects
Commit ec2b621a authored by guj's avatar guj Committed by Atkins, Charles Vernon
Browse files

added timestep support for read/write

parent 2f9ad950
No related branches found
No related tags found
1 merge request!101Hdf5
......@@ -65,6 +65,8 @@ int main(int argc, char *argv[])
intCountDim1 = intDim1 - rank * (intDim1 / size);
}
std::cout<<" rank="<<rank<<" of "<<size<<", dim1 count: "<<intCountDim1<<", offset: "<<intOffsetDim1<<std::endl;
std::cout<<" intOffsetDim2="<<intOffsetDim2<<" "<<intDim2<<std::endl;
try
{
// Define variable and local size
......@@ -83,7 +85,7 @@ int main(int argc, char *argv[])
// Define method for engine creation, it is basically straight-forward
// parameters
adios::Method &HDF5Settings = adios.DeclareMethod("w");
adios::Method &HDF5Settings = adios.DeclareMethod("hdf5");
HDF5Settings.SetEngine("HDF5Writer");
HDF5Settings.SetParameters("chunck=yes", "collectiveIO=yes");
// HDF5Settings.AddTransport( "Mdtm", "localIP=128.0.0.0.1",
......@@ -98,20 +100,60 @@ int main(int argc, char *argv[])
throw std::ios_base::failure(
"ERROR: failed to create HDF5 I/O engine at Open\n");
HDF5Writer->Write(ioMyDoubles, myDoubles.data() +
doubleVOffset); // Base class Engine
// own the Write<T>
// that will call
// overloaded Write
// from Derived
HDF5Writer->Write(ioMyInts,
myInts.data() + (intOffsetDim1 * intDim2 * rank));
HDF5Writer->Write(ioMyCFloats, myCFloats.data() + complexOffset);
HDF5Writer->Write(ioMyCDoubles, myCDoubles.data() + complexOffset);
HDF5Writer->Write(ioMyCLongDoubles,
myCLongDoubles.data() + complexOffset);
HDF5Writer->Close();
int ts = 0;
int totalts = 2;
while (true) {
if (rank == 0) {
std::cout<<" total timesteps: "<<totalts<<" curr: "<<ts<<" th"<<std::endl;
}
HDF5Writer->Write(ioMyDoubles, myDoubles.data() +
doubleVOffset); // Base class Engine
// own the Write<T>
// that will call
// overloaded Write
// from Derived
HDF5Writer->Write(ioMyInts,
myInts.data() + (intOffsetDim1 * intDim2 ));
HDF5Writer->Write(ioMyCFloats, myCFloats.data() + complexOffset);
HDF5Writer->Write(ioMyCDoubles, myCDoubles.data() + complexOffset);
HDF5Writer->Write(ioMyCLongDoubles,
myCLongDoubles.data() + complexOffset);
ts++;
if (ts >= totalts) {
break;
}
HDF5Writer->Advance();
}
HDF5Writer->Close();
// now read out:
/*
HDF5Settings.SetEngine("HDF5Reader");
std::cout<<"... Testing a copy of test.h5, [test1.h5] , b/c engine does not decrease name count !! "<<std::endl;
auto HDF5Reader = adios.Open("test1.h5", "r", HDF5Settings);
//int findts = HDF5Reader->getNumTimeSteps();
//HDF5Reader->InquireVariableDouble("wrongMyDoubles", true);
HDF5Reader->InquireVariableDouble(ioMyDoubles.m_Name, true);
*/
/*
adios::HDF5Reader myReader(adios, "test.h5", "r", MPI_COMM_WORLD, HDF5Settings);
double values[15];
#ifndef NEVER
ts = 0;
while (ts < totalts) {
myReader.ReadMe(ioMyDoubles, values, H5T_NATIVE_DOUBLE);
myReader.Advance();
ts++;
}
#else
myReader.ReadMe(ioMyDoubles, values, H5T_NATIVE_DOUBLE);
#endif
*/
}
catch (std::invalid_argument &e)
{
......
......@@ -10,4 +10,264 @@
#include "HDF5ReaderP.h"
#include <iostream> //needs to go away, this is just for demo purposes
#include "adios2/ADIOSMPI.h"
namespace adios
{
HDF5Reader::HDF5Reader(ADIOS &adios, const std::string name,
const std::string accessMode, MPI_Comm mpiComm,
const Method &method)
: Engine(adios, "HDF5Reader", name, accessMode, mpiComm,
method,
" HDF5Reader constructor (or call to ADIOS Open).\n")
{
Init();
MPI_Comm_rank(mpiComm, &_mpi_rank);
MPI_Comm_size(mpiComm, &_mpi_size);
}
HDF5Reader::~HDF5Reader() {}
void HDF5Reader::Init()
{
if (m_AccessMode != "r" && m_AccessMode != "read")
{
throw std::invalid_argument(
"ERROR: HDF5Reader doesn't support access mode " + m_AccessMode +
", in call to ADIOS Open or HDF5Reader constructor\n");
}
_H5File.H5_Init(m_Name, m_MPIComm, false);
_H5File.GetNumTimeSteps();
}
Variable<void> * HDF5Reader::InquireVariable(const std::string &variableName,
const bool readIn )
{
std::cout<<"Not implemented: HDF5Reder::InquireVariable()"<<std::endl;
}
Variable<char> * HDF5Reader::InquireVariableChar(const std::string &variableName,
const bool readIn )
{}
Variable<unsigned char> * HDF5Reader::InquireVariableUChar(const std::string &variableName,
const bool readIn )
{}
Variable<short> * HDF5Reader::InquireVariableShort(const std::string &variableName,
const bool readIn )
{}
Variable<unsigned short> * HDF5Reader::InquireVariableUShort(const std::string &variableName,
const bool readIn)
{}
Variable<int> *HDF5Reader::InquireVariableInt(const std::string &variableName,
const bool)
{}
Variable<unsigned int> *HDF5Reader::InquireVariableUInt(const std::string &variableName,
const bool)
{}
Variable<long int> *HDF5Reader::InquireVariableLInt(const std::string &variableName,
const bool)
{}
Variable<unsigned long int> *
HDF5Reader::InquireVariableULInt(const std::string &variableName,
const bool)
{}
Variable<long long int> *
HDF5Reader::InquireVariableLLInt(const std::string &variableName,
const bool)
{}
Variable<unsigned long long int> *
HDF5Reader::InquireVariableULLInt(const std::string &variableName,
const bool)
{}
Variable<float> *HDF5Reader::InquireVariableFloat(const std::string &variableName,
const bool)
{}
Variable<double> *HDF5Reader::InquireVariableDouble(const std::string &variableName,
const bool)
{
if (_mpi_rank == 0) {
std::cout<<" ... reading var: "<<variableName<<std::endl;
}
int totalts = _H5File.GetNumTimeSteps();
if (_mpi_rank == 0) {
std::cout<<" ... I saw total timesteps: "<<totalts<<std::endl;
}
while (true) {
double values[1];
UseHDFRead(variableName, values, H5T_NATIVE_DOUBLE);
Variable<double> v = m_ADIOS.DefineVariable<double>("junk", adios::Dims{8});
ReadMe(v, values, H5T_NATIVE_DOUBLE);
if (_H5File._currentTimeStep >= totalts-1) {
break;
}
_H5File.H5_Advance(totalts);
}
}
Variable<long double> * HDF5Reader::InquireVariableLDouble(const std::string &variableName,
const bool)
{}
Variable<std::complex<float>> * HDF5Reader::InquireVariableCFloat(const std::string &variableName,
const bool)
{}
Variable<std::complex<double>> * HDF5Reader::InquireVariableCDouble(const std::string &variableName,
const bool)
{}
Variable<std::complex<long double>>* HDF5Reader::InquireVariableCLDouble(const std::string &variableName,
const bool)
{}
VariableCompound * HDF5Reader::InquireVariableCompound(const std::string &variableName,
const bool readIn)
{}
template <class T>
void HDF5Reader::ReadMe(Variable<T> variable, T *data_array, hid_t h5type)
{
hid_t datasetID = H5Dopen(_H5File._group_id, variable.m_Name.c_str(), H5P_DEFAULT);
if (_mpi_rank == 0) {
std::cout<<" hdf5 reading variable: "<<variable.m_Name<<" timestep: "<<_H5File._currentTimeStep<<std::endl;
}
if (datasetID < 0) {
return;
}
hid_t filespace = H5Dget_space(datasetID);
if (filespace < 0) {
return;
}
int ndims = variable.m_GlobalDimensions.size();
std::vector<hsize_t> count, offset, stride;
int elementsRead = 1;
for (int i = 0; i < ndims; i++)
{
count.push_back(variable.m_LocalDimensions[i]);
offset.push_back(variable.m_Offsets[i]);
stride.push_back(1);
elementsRead *= variable.m_LocalDimensions[i];
}
hid_t ret=H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset.data(), stride.data(), count.data(), NULL);
if (ret < 0) {
return;
}
hid_t mem_dataspace = H5Screate_simple (ndims, count.data(), NULL);
//T data_array[elementsRead];
ret = H5Dread(datasetID, h5type, mem_dataspace, filespace, H5P_DEFAULT, data_array);
for (int i=0; i<elementsRead; i++) {
std::cout<<"... ts "<<_H5File._currentTimeStep<<", "<<data_array[i]<<std::endl;
}
H5Sclose(mem_dataspace);
H5Sclose(filespace);
H5Dclose(datasetID);
}
template<class T>
void HDF5Reader::UseHDFRead(const std::string& variableName, T* values, hid_t h5type)
{
hid_t datasetID = H5Dopen(_H5File._group_id, variableName.c_str(), H5P_DEFAULT);
if (_mpi_rank == 0) {
std::cout<<" opened to read: "<<variableName<<std::endl;
}
if (datasetID < 0) {
return;
}
hid_t filespace = H5Dget_space(datasetID);
if (filespace < 0) {
return;
}
int ndims = H5Sget_simple_extent_ndims(filespace);
hsize_t dims[ndims];
herr_t status_n = H5Sget_simple_extent_dims(filespace, dims, NULL);
hsize_t start[ndims]={0}, count[ndims]={0}, stride[ndims]={1};
int totalElements = 1;
for (int i=0; i<ndims; i++) {
std::cout<<" ["<<i<<"] th dimension: "<<dims[i]<<std::endl;
count[i] = dims[i];
totalElements *= dims[i];
}
start[0] = _mpi_rank * dims[0]/_mpi_size;
count[0] = dims[0]/_mpi_size;
if (_mpi_rank == _mpi_size -1) {
count[0] = dims[0] - count[0]*(_mpi_size - 1);
std::cout<<" rank = "<<_mpi_rank<<", count="<<count[0]<<std::endl;
}
hid_t ret=H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, NULL);
if (ret < 0) {
return;
}
hid_t mem_dataspace = H5Screate_simple (ndims, count, NULL);
int elementsRead = 1;
for (int i=0; i<ndims; i++) {
elementsRead *= count[i];
}
T data_array[elementsRead];
ret = H5Dread(datasetID, h5type, mem_dataspace, filespace, H5P_DEFAULT, data_array);
for (int i=0; i<elementsRead; i++) {
std::cout<<"... rank "<<_mpi_rank<<" , "<<data_array[i]<<std::endl;
}
H5Sclose(mem_dataspace);
H5Sclose(filespace);
H5Dclose(datasetID);
}
void HDF5Reader::Advance(float timeout_sec)
{
int totalts = _H5File.GetNumTimeSteps();
_H5File.H5_Advance(totalts);
}
void HDF5Reader::Close(const int transportIndex)
{
_H5File.H5_Close();
}
} // end namespace adios
......@@ -11,4 +11,117 @@
#ifndef ADIOS2_ENGINE_HDF5_HDF5READERP_H_
#define ADIOS2_ENGINE_HDF5_HDF5READERP_H_
#include "HDF5Common.h"
#include "adios2/core/Engine.h"
#include "adios2/ADIOSMPICommOnly.h"
namespace adios
{
class HDF5Reader : public Engine
{
public:
/**
* Constructor for single HDF5 reader engine, reads from HDF5 format
* @param name unique name given to the engine
* @param accessMode
* @param mpiComm
* @param method
*/
HDF5Reader(ADIOS &adios, const std::string name,
const std::string accessMode, MPI_Comm mpiComm,
const Method &method);
virtual ~HDF5Reader();
Variable<void> *InquireVariable(const std::string &variableName,
const bool readIn = true);
Variable<char> *InquireVariableChar(const std::string &variableName,
const bool readIn = true);
Variable<unsigned char> *
InquireVariableUChar(const std::string &variableName,
const bool readIn = true);
Variable<short> *InquireVariableShort(const std::string &variableName,
const bool readIn = true);
Variable<unsigned short> *
InquireVariableUShort(const std::string &variableName,
const bool readIn = true);
Variable<int> *InquireVariableInt(const std::string &variableName,
const bool readIn = true);
Variable<unsigned int> *InquireVariableUInt(const std::string &variableName,
const bool readIn = true);
Variable<long int> *InquireVariableLInt(const std::string &variableName,
const bool readIn = true);
Variable<unsigned long int> *
InquireVariableULInt(const std::string &variableName,
const bool readIn = true);
Variable<long long int> *
InquireVariableLLInt(const std::string &variableName,
const bool readIn = true);
Variable<unsigned long long int> *
InquireVariableULLInt(const std::string &variableName,
const bool readIn = true);
Variable<float> *InquireVariableFloat(const std::string &variableName,
const bool readIn = true);
Variable<double> *InquireVariableDouble(const std::string &variableName,
const bool readIn = true);
Variable<long double> *
InquireVariableLDouble(const std::string &variableName,
const bool readIn = true);
Variable<std::complex<float>> *
InquireVariableCFloat(const std::string &variableName,
const bool readIn = true);
Variable<std::complex<double>> *
InquireVariableCDouble(const std::string &variableName,
const bool readIn = true);
Variable<std::complex<long double>> *
InquireVariableCLDouble(const std::string &variableName,
const bool readIn = true);
/**
* Not implemented
* @param name
* @param readIn
* @return
*/
VariableCompound *InquireVariableCompound(const std::string &variableName,
const bool readIn = true);
void Advance(float timeout_sec = 0.0);
void Close(const int transportIndex = -1);
template <class T>
void UseHDFRead(const std::string& variableName, T *values, hid_t h5type);
template <class T>
void ReadMe(Variable<T> variable, T *values, hid_t h5type);
private:
HDF5Common _H5File;
void Init();
int _mpi_rank;
int _mpi_size;
};
};
#endif /* ADIOS2_ENGINE_HDF5_HDF5READERP_H_ */
......@@ -10,8 +10,6 @@
#include "HDF5WriterP.h"
#include <iostream> //needs to go away, this is just for demo purposes
#include "adios2/ADIOSMPI.h"
#include "adios2/core/Support.h"
#include "adios2/core/adiosFunctions.h" //CSVToVector
......@@ -27,37 +25,7 @@ HDF5Writer::HDF5Writer(ADIOS &adios, const std::string name,
" HDF5Writer constructor (or call to ADIOS Open).\n"),
m_Buffer(m_DebugMode)
{
//
// 16, 4 vs: 8
// std::cout<<sizeof(std::complex<double>)<<",
// "<<sizeof(H5T_NATIVE_DOUBLE)<<" vs:
// "<<H5Tget_size(H5T_NATIVE_DOUBLE)<<std::endl;
// 8, 4 vs: 4
// std::cout<<sizeof(std::complex<float>)<<", "<<sizeof(H5T_NATIVE_FLOAT)<<"
// vs: "<<H5Tget_size(H5T_NATIVE_FLOAT)<<std::endl;
// 32, 4 vs: 16
// std::cout<<sizeof(std::complex<long double>)<<",
// "<<sizeof(H5T_NATIVE_LDOUBLE)<<" vs:
// "<<H5Tget_size(H5T_NATIVE_LDOUBLE)<<std::endl;
DefH5T_COMPLEX_FLOAT = H5Tcreate(H5T_COMPOUND, sizeof(std::complex<float>));
H5Tinsert(DefH5T_COMPLEX_FLOAT, "freal", 0, H5T_NATIVE_FLOAT);
H5Tinsert(DefH5T_COMPLEX_FLOAT, "fimg", H5Tget_size(H5T_NATIVE_FLOAT),
H5T_NATIVE_FLOAT);
DefH5T_COMPLEX_DOUBLE =
H5Tcreate(H5T_COMPOUND, sizeof(std::complex<double>));
H5Tinsert(DefH5T_COMPLEX_DOUBLE, "dreal", 0, H5T_NATIVE_DOUBLE);
H5Tinsert(DefH5T_COMPLEX_DOUBLE, "dimg", H5Tget_size(H5T_NATIVE_DOUBLE),
H5T_NATIVE_DOUBLE);
DefH5T_COMPLEX_LongDOUBLE =
H5Tcreate(H5T_COMPOUND, sizeof(std::complex<long double>));
H5Tinsert(DefH5T_COMPLEX_LongDOUBLE, "ldouble real", 0, H5T_NATIVE_LDOUBLE);
H5Tinsert(DefH5T_COMPLEX_LongDOUBLE, "ldouble img",
H5Tget_size(H5T_NATIVE_LDOUBLE), H5T_NATIVE_LDOUBLE);
Init();
Init();
}
HDF5Writer::~HDF5Writer() {}
......@@ -71,23 +39,8 @@ void HDF5Writer::Init()
"ERROR: HDF5Writer doesn't support access mode " + m_AccessMode +
", in call to ADIOS Open or HDF5Writer constructor\n");
}
// std::cout << "method: # of inputs:" << m_Method.m_Parameters.size() <<
// std::endl;
// std::cout << "::Init hdf5 parallel writer. File name:" << m_Name <<
// std::endl;
_plist_id = H5Pcreate(H5P_FILE_ACCESS);
#ifdef ADIOS2_HAVE_MPI
H5Pset_fapl_mpio(_plist_id, m_MPIComm, MPI_INFO_NULL);
#endif
/*
* Create a new file collectively and release property list identifier.
*/
_file_id = H5Fcreate(m_Name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, _plist_id);
H5Pclose(_plist_id);
_H5File.H5_Init(m_Name, m_MPIComm, true);
}
void HDF5Writer::Write(Variable<char> &variable, const char *values)
......@@ -165,19 +118,19 @@ void HDF5Writer::Write(Variable<long double> &variable,
void HDF5Writer::Write(Variable<std::complex<float>> &variable,
const std::complex<float> *values)
{
UseHDFWrite(variable, values, DefH5T_COMPLEX_FLOAT);
UseHDFWrite(variable, values, _H5File.DefH5T_COMPLEX_FLOAT);
}
void HDF5Writer::Write(Variable<std::complex<double>> &variable,
const std::complex<double> *values)
{
UseHDFWrite(variable, values, DefH5T_COMPLEX_DOUBLE);
UseHDFWrite(variable, values, _H5File.DefH5T_COMPLEX_DOUBLE);
}
void HDF5Writer::Write(Variable<std::complex<long double>> &variable,
const std::complex<long double> *values)
{
UseHDFWrite(variable, values, DefH5T_COMPLEX_LongDOUBLE);
UseHDFWrite(variable, values, _H5File.DefH5T_COMPLEX_LongDOUBLE);
}
// String version
......@@ -269,31 +222,43 @@ void HDF5Writer::Write(const std::string variableName,
const std::complex<float> *values)
{
UseHDFWrite(m_ADIOS.GetVariable<std::complex<float>>(variableName), values,
DefH5T_COMPLEX_FLOAT);
_H5File.DefH5T_COMPLEX_FLOAT);
}
void HDF5Writer::Write(const std::string variableName,
const std::complex<double> *values)
{
UseHDFWrite(m_ADIOS.GetVariable<std::complex<double>>(variableName), values,
DefH5T_COMPLEX_DOUBLE);
_H5File.DefH5T_COMPLEX_DOUBLE);
}
void HDF5Writer::Write(const std::string variableName,
const std::complex<long double> *values)
{
UseHDFWrite(m_ADIOS.GetVariable<std::complex<long double>>(variableName),
values, DefH5T_COMPLEX_LongDOUBLE);
values, _H5File.DefH5T_COMPLEX_LongDOUBLE);
}
void HDF5Writer::Advance(float timeout_sec)
{
_H5File.H5_Advance(0);
}
void HDF5Writer::Close(const int transportIndex)
{
// std::cout << " ===> CLOSING HDF5 <===== " << std::endl;
// H5Dclose(_dset_id);
// H5Sclose(_filespace);
// H5Sclose(_memspace);
// H5Pclose(_plist_id);
H5Fclose(_file_id);
/*
//void* hi = H5Iobject_verify(H5S_SCALAR, H5I_DATASPACE);
hid_t s = H5Screate(H5S_SCALAR);
//hid_t attr = H5Acreate(_H5File._group_id, "NumTimeSteps", H5T_NATIVE_UINT, s, H5P_DEFAULT, H5P_DEFAULT);
hid_t attr = H5Acreate(_H5File._file_id, "NumTimeSteps", H5T_NATIVE_UINT, s, H5P_DEFAULT, H5P_DEFAULT);
uint totalts = _H5File._currentTimeStep+1;
H5Awrite(attr,H5T_NATIVE_UINT,&totalts);
H5Sclose(s);
H5Aclose(attr);
*/
_H5File.H5_Close();
}
template <class T>
......@@ -327,13 +292,13 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values,
offset.push_back(variable.m_Offsets[i]);
}
_filespace = H5Screate_simple(dimSize, dimsf.data(), NULL);
hid_t _filespace = H5Screate_simple(dimSize, dimsf.data(), NULL);
_dset_id = H5Dcreate(_file_id, variable.m_Name.c_str(), h5type, _filespace,
hid_t _dset_id = H5Dcreate(_H5File._group_id, variable.m_Name.c_str(), h5type, _filespace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
// H5Sclose(_filespace);
_memspace = H5Screate_simple(dimSize, count.data(), NULL);
hid_t _memspace = H5Screate_simple(dimSize, count.data(), NULL);
// Select hyperslab
_filespace = H5Dget_space(_dset_id);
......@@ -342,7 +307,7 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values,
// Create property list for collective dataset write.
_plist_id = H5Pcreate(H5P_DATASET_XFER);
hid_t _plist_id = H5Pcreate(H5P_DATASET_XFER);
#ifdef ADIOS2_HAVE_MPI
H5Pset_dxpl_mpio(_plist_id, H5FD_MPIO_COLLECTIVE);
#endif
......
......@@ -12,6 +12,8 @@
#ifndef ADIOS2_ENGINE_HDF5_HDF5WRITERP_H__
#define ADIOS2_ENGINE_HDF5_HDF5WRITERP_H__
#include "HDF5Common.h"
#include "adios2/ADIOSConfig.h"
#include "adios2/ADIOSMPICommOnly.h"
#include "adios2/capsule/heap/STLVector.h"
......@@ -27,14 +29,11 @@ class HDF5Writer : public Engine
public:
/**
* Constructor for single BP capsule engine, writes in BP format into a
* single
* heap capsule
* Constructor for HDF5 writer engine, writes in hdf5 format
* @param name unique name given to the engine
* @param accessMode
* @param mpiComm
* @param method
* @param debugMode
*/
HDF5Writer(ADIOS &adios, const std::string name,
const std::string accessMode, MPI_Comm mpiComm,
......@@ -86,6 +85,8 @@ public:
void Write(const std::string variableName,
const std::complex<long double> *values);
void Advance(float timeout_sec = 0.0);
void Close(const int transportIndex = -1);
private:
......@@ -93,15 +94,21 @@ private:
capsule::STLVector m_Buffer;
void Init();
void clean();
HDF5Common _H5File;
/*
hid_t _plist_id, _file_id, _dset_id;
hid_t _memspace, _filespace;
hid_t _group_id;
hid_t DefH5T_COMPLEX_DOUBLE;
hid_t DefH5T_COMPLEX_FLOAT;
hid_t DefH5T_COMPLEX_LongDOUBLE;
int _currentTimeStep;
*/
template <class T>
void UseHDFWrite(Variable<T> &variable, const T *values, hid_t h5type);
};
......
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