diff --git a/examples/heatTransfer/write/IO_ph5.cpp b/examples/heatTransfer/write/IO_ph5.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc0faa3d6977ee3f227d39ed995a5a37634f6c24 --- /dev/null +++ b/examples/heatTransfer/write/IO_ph5.cpp @@ -0,0 +1,225 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IO_ADIOS2.cpp + * + * Created on: Feb 2017 + * Author: Norbert Podhorszki + */ + +#include "IO.h" + +#include <string> +#include <stdexcept> +#include <hdf5.h> +#include <memory> +#include <ios> +#include <iostream> + +class HDF5NativeWriter +{ + +public: + HDF5NativeWriter(const std::string& fileName); + ~HDF5NativeWriter(); + + bool Advance(); + void Close(); + void CheckWriteGroup(); + + void WriteScalar(const std::string& varName, const void *data, hid_t h5Type); + void WriteSimple(const std::string& varName, int dimSize, const void *data, hid_t h5Type, const hsize_t* shape, const hsize_t* offset, const hsize_t* count); + + int m_CurrentTimeStep; + unsigned int m_TotalTimeSteps; + +private: + hid_t m_FilePropertyListId; + hid_t m_FileId; + hid_t m_GroupId; +}; + +HDF5NativeWriter::HDF5NativeWriter(const std::string& fileName) + : m_CurrentTimeStep(0), m_TotalTimeSteps(0) +{ + m_FilePropertyListId = H5Pcreate(H5P_FILE_ACCESS); + +#ifdef ADIOS2_HAVE_MPI + // read a file collectively + H5Pset_fapl_mpio(m_FilePropertyListId, MPI_COMM_WORLD, MPI_INFO_NULL); +#endif + + m_FileId = H5Fcreate(fileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, + m_FilePropertyListId); + + if (m_FileId < 0) + { + throw std::runtime_error("Unable to open " + fileName + " for reading"); + } + + std::string ts0 = "/TimeStep0"; + + m_GroupId = H5Gcreate2(m_FileId, ts0.c_str(), H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + if (m_GroupId < 0) + { + throw std::runtime_error("HDF5: Unable to create group " + ts0); + } +} + +HDF5NativeWriter::~HDF5NativeWriter() +{ + Close(); +} + +void HDF5NativeWriter::Close() +{ + if (m_FileId < 0) + return; + + hid_t s = H5Screate(H5S_SCALAR); + hid_t attr = H5Acreate(m_FileId, "NumTimeSteps", H5T_NATIVE_UINT, s, + H5P_DEFAULT, H5P_DEFAULT); + uint totalTimeSteps = m_CurrentTimeStep + 1; + + if (m_GroupId < 0) + { + totalTimeSteps = m_CurrentTimeStep; + } + H5Awrite(attr, H5T_NATIVE_UINT, &totalTimeSteps); + H5Sclose(s); + H5Aclose(attr); + + + if (m_GroupId >= 0) + { + H5Gclose(m_GroupId); + m_GroupId = -1; + } + + H5Fclose(m_FileId); + m_FileId = -1; + H5Pclose(m_FilePropertyListId); +} + +bool HDF5NativeWriter::Advance() +{ + if (m_GroupId >= 0) + { + H5Gclose(m_GroupId); + m_GroupId = -1; + } + + ++m_CurrentTimeStep; + + return true; +} + + +void HDF5NativeWriter::CheckWriteGroup() +{ + if (m_GroupId >= 0) + { + return; + } + + std::string timeStepName = "/TimeStep" + std::to_string(m_CurrentTimeStep); + m_GroupId = H5Gcreate2(m_FileId, timeStepName.c_str(), H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + if (m_GroupId < 0) + { + throw std::runtime_error("HDF5: Unable to create group " + + timeStepName); + } +} + + +void HDF5NativeWriter::WriteScalar(const std::string& varName, const void *data, hid_t h5Type) +{ + CheckWriteGroup(); + // scalar + hid_t filespaceID = H5Screate(H5S_SCALAR); + hid_t dsetID = + H5Dcreate(m_GroupId, varName.c_str(), h5Type, + filespaceID, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + herr_t status = + H5Dwrite(dsetID, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); + + H5Sclose(filespaceID); + H5Dclose(dsetID); + +} + +void HDF5NativeWriter::WriteSimple(const std::string& varName, int dimSize, const void *data, hid_t h5Type, const hsize_t* shape, const hsize_t* offset, const hsize_t* count) +{ + CheckWriteGroup(); + hid_t fileSpace = H5Screate_simple(dimSize, shape, NULL); + + hid_t dsetID = + H5Dcreate(m_GroupId, varName.c_str(), h5Type, + fileSpace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + hid_t memSpace = H5Screate_simple(dimSize, count, NULL); + + // Select hyperslab + fileSpace = H5Dget_space(dsetID); + H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset, NULL, + count, NULL); + + // Create property list for collective dataset write. + + hid_t plistID = H5Pcreate(H5P_DATASET_XFER); +#ifdef ADIOS2_HAVE_MPI + H5Pset_dxpl_mpio(plistID, H5FD_MPIO_COLLECTIVE); +#endif + herr_t status; + + status = H5Dwrite(dsetID, h5Type, memSpace, fileSpace, plistID, data); + + if (status < 0) + { + // error + std::cerr << " Write failed. " << std::endl; + } + + H5Dclose(dsetID); + H5Sclose(fileSpace); + H5Sclose(memSpace); + H5Pclose(plistID); +} + +// +// +std::shared_ptr<HDF5NativeWriter> h5writer; +//HDF5NativeWriter* h5writer; + + +IO::IO(const Settings &s, MPI_Comm comm) +{ + m_outputfilename = s.outputfile + ".h5"; + + h5writer = std::make_shared<HDF5NativeWriter>(m_outputfilename); + + if (h5writer == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS h5writer\n"); +} + +IO::~IO() +{ + h5writer->Close(); + //delete h5writer; +} + +void IO::write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm) +{ + std::vector<hsize_t> dims = {s.gndx, s.gndy}; + std::vector<hsize_t> offset = {s.offsx, s.offsy}; + std::vector<hsize_t> count = {s.ndx, s.ndy}; + + h5writer->WriteSimple("T", 2, ht.data_noghost().data(), H5T_NATIVE_DOUBLE, dims.data(), offset.data(), count.data()); + h5writer->WriteScalar("gndy", &(s.gndy), H5T_NATIVE_UINT); + + h5writer->Advance(); +}