Skip to content
Snippets Groups Projects
HDF5ReaderP.cpp 7.54 KiB
Newer Older
guj's avatar
guj committed
/*
guj's avatar
guj committed
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
guj's avatar
guj committed
 *
guj's avatar
guj committed
 *
 *  Created on: March 20, 2017
 *      Author: Junmin
guj's avatar
guj committed
 */

#include "HDF5ReaderP.h"
guj's avatar
guj committed
#include "HDF5ReaderP.tcc"
guj's avatar
guj committed

#include "adios2/ADIOSMPI.h"

namespace adios2
guj's avatar
guj committed
HDF5ReaderP::HDF5ReaderP(IO &io, const std::string &name, const Mode openMode,
                         MPI_Comm mpiComm)
guj's avatar
guj committed
: Engine("HDF5Reader", io, name, openMode, mpiComm), m_H5File(io.m_DebugMode)
    m_EndMessage = ", in call to IO HDF5Reader Open " + m_Name + "\n";
    Init();
HDF5ReaderP::~HDF5ReaderP() { Close(); }
bool HDF5ReaderP::IsValid()
    bool isValid = false;

    if (m_OpenMode != Mode::Read)
        return isValid;
    if (m_H5File.m_FileId >= 0)
        isValid = true;
    return isValid;
void HDF5ReaderP::Init()
    if (m_OpenMode != Mode::Read)
    {
        throw std::invalid_argument(
William F Godoy's avatar
William F Godoy committed
            "ERROR: HDF5Reader only supports OpenMode::Read "
            ", in call to Open\n");
    m_H5File.Init(m_Name, m_MPIComm, false);
guj's avatar
guj committed
    int ts = m_H5File.GetNumTimeSteps();
    if (ts == 0)
guj's avatar
guj committed
        throw std::runtime_error("This h5 file is NOT written by ADIOS2");
guj's avatar
guj committed
    /*
     */
    if (!m_InStreamMode)
guj's avatar
guj committed
        m_H5File.ReadAllVariables(m_IO);
guj's avatar
guj committed
    else
guj's avatar
guj committed
        m_H5File.ReadAllVariables(m_IO);
guj's avatar
guj committed
}
guj's avatar
guj committed
template <class T>
void HDF5ReaderP::UseHDFRead(Variable<T> &variable, T *data, hid_t h5Type)
{
    int ts = 0;
    T *values = data;
    size_t variableStart = variable.m_StepsStart;
    if (!m_InStreamMode && (variableStart == 1))
    { // variableBase::m_StepsStart min=1
        variableStart = 0;
    }

guj's avatar
guj committed
    while (ts < variable.m_StepsCount)
        // m_H5File.SetTimeStep(variable.m_StepsStart + ts);
        m_H5File.SetTimeStep(variableStart + ts);
guj's avatar
guj committed

        hid_t dataSetId =
            H5Dopen(m_H5File.m_GroupId, variable.m_Name.c_str(), H5P_DEFAULT);
        if (dataSetId < 0)
        {
            return;
        }

        hid_t fileSpace = H5Dget_space(dataSetId);
        if (fileSpace < 0)
        {
            return;
        }

        size_t slabsize = 1;

        int ndims = std::max(variable.m_Shape.size(), variable.m_Count.size());
        if (0 == ndims)
        { // is scalar
            hid_t ret = H5Dread(dataSetId, h5Type, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, values);
        }
        else
        {
            hsize_t start[ndims], count[ndims], stride[ndims];

            for (int i = 0; i < ndims; i++)
            {
                count[i] = variable.m_Count[i];
                start[i] = variable.m_Start[i];
                slabsize *= count[i];
                stride[i] = 1;
            }
            hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start,
                                            stride, count, NULL);
            if (ret < 0)
                return;

            hid_t memDataSpace = H5Screate_simple(ndims, count, NULL);
            int elementsRead = 1;
            for (int i = 0; i < ndims; i++)
            {
                elementsRead *= count[i];
            }

            ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace,
                          H5P_DEFAULT, values);
            H5Sclose(memDataSpace);
        }

        H5Sclose(fileSpace);
        H5Dclose(dataSetId);

        ts++;
        values += slabsize;
    } // while
}
guj's avatar
guj committed
/*
template <class T>
void HDF5ReaderP::UseHDFRead(const std::string &variableName, T *values,
                           hid_t h5Type)
{
  int rank, size;
  MPI_Comm_rank(m_MPIComm, &rank);
  MPI_Comm_size(m_MPIComm, &size);

  hid_t dataSetId =
      H5Dopen(m_H5File.m_GroupId, variableName.c_str(), H5P_DEFAULT);

  if (dataSetId < 0)
  {
      return;
  }

  hid_t fileSpace = H5Dget_space(dataSetId);

  if (fileSpace < 0)
  {
      return;
  }
  int ndims = H5Sget_simple_extent_ndims(fileSpace);

  if (ndims == 0) { // SCALAR
    hid_t ret = H5Dread(dataSetId, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
values); return;
  }

  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};
  hsize_t start[ndims], count[ndims], stride[ndims];

  int totalElements = 1;
  for (int i = 0; i < ndims; i++)
  {
      count[i] = dims[i];
      totalElements *= dims[i];
      start[i] = 0;
      //count[i] = 0;
      stride[i] = 1;
  }

  start[0] = rank * dims[0] / size;
  count[0] = dims[0] / size;
  if (rank == size - 1)
  {
      count[0] = dims[0] - count[0] * (size - 1);
  }

  hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start, stride,
                                  count, NULL);
  if (ret < 0)
  {
      return;
  }

  hid_t memDataSpace = H5Screate_simple(ndims, count, NULL);

  int elementsRead = 1;
  for (int i = 0; i < ndims; i++)
  {
      elementsRead *= count[i];
  }

#ifdef NEVER
  //T data_array[elementsRead];

  std::vector<T> data_vector;
  data_vector.reserve(elementsRead);
  T* data_array = data_vector.data();
  ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT,
                data_array);
#else
  ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT,
values); #endif


  H5Sclose(memDataSpace);

  H5Sclose(fileSpace);
  H5Dclose(dataSetId);
guj's avatar
guj committed
*/
StepStatus HDF5ReaderP::BeginStep(StepMode mode, const float timeoutSeconds) 
{
  m_InStreamMode=true;
  int ts = m_H5File.GetNumTimeSteps();  
  if (m_StreamAt >= ts) {
    return StepStatus::EndOfStream;
  }

  return StepStatus::OK;
}

void HDF5ReaderP::EndStep() {   m_StreamAt ++; m_H5File.Advance(); }

void HDF5ReaderP::PerformGets()
{
  if (!m_InStreamMode) {
    throw std::runtime_error("PerformGets() needs to follow stream read sequeuences.");
  }

#define declare_type(T)                                                        \
    for (std::string variableName : m_DeferredStack) { \
        Variable<T>* var = m_IO.InquireVariable<T>(variableName);         \
        if (var  != nullptr)					       \
	  {                                                                    \
	    var->m_StepsStart = m_StreamAt;                               \
            var->m_StepsCount = 1;				\
	    hid_t h5Type = m_H5File.GetHDF5Type<T>();                          \
	    UseHDFRead(*var, var->GetData(), h5Type);	\
	    break;						\
	  } \
    }    
ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type  


  m_DeferredStack.clear();
}
void HDF5ReaderP::Close(const int transportIndex) { m_H5File.Close(); }
guj's avatar
guj committed
#define declare_type(T)                                                        \
    void HDF5ReaderP::DoGetSync(Variable<T> &variable, T *data)                \
    {                                                                          \
        GetSyncCommon(variable, data);                                         \
    }                                                                          \
    void HDF5ReaderP::DoGetDeferred(Variable<T> &variable, T *data)            \
    {                                                                          \
        GetDeferredCommon(variable, data);                                     \
    }                                                                          \
    void HDF5ReaderP::DoGetDeferred(Variable<T> &variable, T &data)            \
    {                                                                          \
        GetDeferredCommon(variable, &data);                                    \
    }
ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type

} // end namespace adios