From ec2b621a15de4fa0d250b55dec94d45725852c8d Mon Sep 17 00:00:00 2001
From: guj <jgu@lbl.gov>
Date: Tue, 2 May 2017 16:09:38 -0400
Subject: [PATCH] added timestep support for read/write

---
 examples/hello/hdf5Writer/helloHDF5Writer.cpp |  72 ++++-
 source/adios2/engine/hdf5/HDF5ReaderP.cpp     | 262 +++++++++++++++++-
 source/adios2/engine/hdf5/HDF5ReaderP.h       | 113 ++++++++
 source/adios2/engine/hdf5/HDF5WriterP.cpp     |  95 ++-----
 source/adios2/engine/hdf5/HDF5WriterP.h       |  19 +-
 5 files changed, 474 insertions(+), 87 deletions(-)

diff --git a/examples/hello/hdf5Writer/helloHDF5Writer.cpp b/examples/hello/hdf5Writer/helloHDF5Writer.cpp
index ecfe1b940..f7ffea4e1 100644
--- a/examples/hello/hdf5Writer/helloHDF5Writer.cpp
+++ b/examples/hello/hdf5Writer/helloHDF5Writer.cpp
@@ -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)
     {
diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.cpp b/source/adios2/engine/hdf5/HDF5ReaderP.cpp
index 782135c00..9aa7f7b76 100644
--- a/source/adios2/engine/hdf5/HDF5ReaderP.cpp
+++ b/source/adios2/engine/hdf5/HDF5ReaderP.cpp
@@ -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
diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.h b/source/adios2/engine/hdf5/HDF5ReaderP.h
index 42e4dab6b..5298be8f6 100644
--- a/source/adios2/engine/hdf5/HDF5ReaderP.h
+++ b/source/adios2/engine/hdf5/HDF5ReaderP.h
@@ -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_ */
diff --git a/source/adios2/engine/hdf5/HDF5WriterP.cpp b/source/adios2/engine/hdf5/HDF5WriterP.cpp
index bb01c6301..befa9e1a9 100644
--- a/source/adios2/engine/hdf5/HDF5WriterP.cpp
+++ b/source/adios2/engine/hdf5/HDF5WriterP.cpp
@@ -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
diff --git a/source/adios2/engine/hdf5/HDF5WriterP.h b/source/adios2/engine/hdf5/HDF5WriterP.h
index cca6b53ee..6dd5c6972 100644
--- a/source/adios2/engine/hdf5/HDF5WriterP.h
+++ b/source/adios2/engine/hdf5/HDF5WriterP.h
@@ -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);
 };
-- 
GitLab