/* * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * * HDF5ReaderP.cpp * * Created on: March 20, 2017 * Author: Junmin */ #include "HDF5ReaderP.h" #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() {} bool HDF5Reader::isValid() { if (m_AccessMode != "r" && m_AccessMode != "read") { return false; } if (_H5File._file_id >= 0) { return true; } } 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); Variable<char> v1 = m_ADIOS.DefineVariable<char>("junk1", adios::Dims{8}); char vv1[1]; ReadMe(v1, vv1, H5T_NATIVE_CHAR); Variable<unsigned char> v2 = m_ADIOS.DefineVariable<unsigned char>("junk2", adios::Dims{8}); unsigned char vv2[1]; ReadMe(v2, vv2, H5T_NATIVE_UCHAR); Variable<unsigned int> v3 = m_ADIOS.DefineVariable<unsigned int>("junk3", adios::Dims{8}); unsigned int vv3[1]; ReadMe(v3, vv3, H5T_NATIVE_UINT); Variable<int> v4 = m_ADIOS.DefineVariable<int>("junk4", adios::Dims{8}); int vv4[1]; ReadMe(v4, vv4, H5T_NATIVE_INT); Variable<float> v5 = m_ADIOS.DefineVariable<float>("junk5", adios::Dims{8}); float vv5[1]; ReadMe(v5, vv5, H5T_NATIVE_FLOAT); Variable<short> v6 = m_ADIOS.DefineVariable<short>("junk6", adios::Dims{8}); short vv6[1]; ReadMe(v6, vv6, H5T_NATIVE_SHORT); Variable<unsigned short> v7 = m_ADIOS.DefineVariable<unsigned short>("junk7", adios::Dims{8}); unsigned short vv7[1]; ReadMe(v7, vv7, H5T_NATIVE_USHORT); Variable<long> v8 = m_ADIOS.DefineVariable<long>("junk8", adios::Dims{8}); long vv8[1]; ReadMe(v8, vv8, H5T_NATIVE_LONG); Variable<unsigned long> v9 = m_ADIOS.DefineVariable<unsigned long>("junk9", adios::Dims{8}); unsigned long vv9[1]; ReadMe(v9, vv9, H5T_NATIVE_ULONG); 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); #ifdef NEVER if (_mpi_rank == 0) { std::cout << " hdf5 reading variable: " << variable.m_Name << " timestep: " << _H5File._currentTimeStep << std::endl; } #endif if (datasetID < 0) { return; } hid_t filespace = H5Dget_space(datasetID); if (filespace < 0) { return; } const int ndims = H5Sget_simple_extent_ndims(filespace); hsize_t dims[ndims]; H5Sget_simple_extent_dims(filespace, dims, NULL); //int dims_in = variable.m_GlobalDimensions.size(); variable.m_GlobalDimensions.clear(); for (int i=0; i < ndims; i++) { variable.m_GlobalDimensions.push_back(dims[i]); } std::vector<hsize_t> count, offset, stride; int elementsRead = 1; for (int i = 0; i < ndims; i++) { if (variable.m_LocalDimensions.size() == ndims) { count.push_back(variable.m_LocalDimensions[i]); elementsRead *= variable.m_LocalDimensions[i]; } else { count.push_back(variable.m_GlobalDimensions[i]); elementsRead *= variable.m_GlobalDimensions[i]; } if (variable.m_Offsets.size() == ndims) { offset.push_back(variable.m_Offsets[i]); } else { offset.push_back(0); } stride.push_back(1); } 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