Skip to content
Snippets Groups Projects
HDF5WriterP.cpp 11.2 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
 * HDF5WriterP.cpp
 *
guj's avatar
guj committed
 *  Created on: March 20, 2017
 *      Author: Junmin
guj's avatar
guj committed
 */

#include "HDF5WriterP.h"
guj's avatar
guj committed

#include <iostream> //needs to go away, this is just for demo purposes
guj's avatar
guj committed

#include "adios2/core/Support.h"
#include "adios2/core/adiosFunctions.h" //CSVToVector
#include "adiso2/ADIOSMPI.h"
guj's avatar
guj committed

guj's avatar
guj committed
namespace adios
{
guj's avatar
guj committed

HDF5Writer::HDF5Writer(ADIOS &adios, const std::string name,
                       const std::string accessMode, MPI_Comm mpiComm,
guj's avatar
guj committed
                       const Method &method)
guj's avatar
guj committed
: Engine(adios, "HDF5Writer", name, accessMode, mpiComm,
         method, /*debugMode, cores,*/
         " HDF5Writer constructor (or call to ADIOS Open).\n"),
  m_Buffer(accessMode, m_RankMPI, m_DebugMode)
guj's avatar
guj committed
{
guj's avatar
guj committed
    //
    //  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);
guj's avatar
guj committed

guj's avatar
guj committed
    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);
guj's avatar
guj committed

guj's avatar
guj committed
    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);
guj's avatar
guj committed

guj's avatar
guj committed
    Init();
guj's avatar
guj committed
}

HDF5Writer::~HDF5Writer() {}

guj's avatar
guj committed
void HDF5Writer::Init()
{
    if (m_AccessMode != "w" && m_AccessMode != "write" && m_AccessMode != "a" &&
        m_AccessMode != "append")
    {
        throw std::invalid_argument(
            "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;
guj's avatar
guj committed

guj's avatar
guj committed
    // std::cout << "::Init hdf5 parallel writer. File name:" << m_Name <<
    // std::endl;
guj's avatar
guj committed

guj's avatar
guj committed
    _plist_id = H5Pcreate(H5P_FILE_ACCESS);
guj's avatar
guj committed

#ifdef ADIOS2_HAVE_MPI
guj's avatar
guj committed
    H5Pset_fapl_mpio(_plist_id, m_MPIComm, MPI_INFO_NULL);
guj's avatar
guj committed

guj's avatar
guj committed
    /*
     * 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);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<char> &variable, const char *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_CHAR);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<unsigned char> &variable,
guj's avatar
guj committed
                       const unsigned char *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_UCHAR);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<short> &variable, const short *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_SHORT);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<unsigned short> &variable,
guj's avatar
guj committed
                       const unsigned short *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_USHORT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<int> &variable, const int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_INT);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<unsigned int> &variable,
guj's avatar
guj committed
                       const unsigned int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_UINT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<long int> &variable, const long int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_LONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<unsigned long int> &variable,
guj's avatar
guj committed
                       const unsigned long int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_ULONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<long long int> &variable,
guj's avatar
guj committed
                       const long long int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_LLONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<unsigned long long int> &variable,
guj's avatar
guj committed
                       const unsigned long long int *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_ULLONG);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<float> &variable, const float *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_FLOAT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(Variable<double> &variable, const double *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_DOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<long double> &variable,
guj's avatar
guj committed
                       const long double *values)
{
    UseHDFWrite(variable, values, H5T_NATIVE_LDOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<std::complex<float>> &variable,
guj's avatar
guj committed
                       const std::complex<float> *values)
{
    UseHDFWrite(variable, values, DefH5T_COMPLEX_FLOAT);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<std::complex<double>> &variable,
guj's avatar
guj committed
                       const std::complex<double> *values)
{
    UseHDFWrite(variable, values, DefH5T_COMPLEX_DOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(Variable<std::complex<long double>> &variable,
guj's avatar
guj committed
                       const std::complex<long double> *values)
{
    UseHDFWrite(variable, values, DefH5T_COMPLEX_LongDOUBLE);
guj's avatar
guj committed
}

// String version
guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const char *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<char>(variableName), values,
                H5T_NATIVE_CHAR);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const unsigned char *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<unsigned char>(variableName), values,
                H5T_NATIVE_UCHAR);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const short *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<short>(variableName), values,
                H5T_NATIVE_SHORT);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const unsigned short *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<unsigned short>(variableName), values,
                H5T_NATIVE_USHORT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<int>(variableName), values, H5T_NATIVE_INT);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const unsigned int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<unsigned int>(variableName), values,
                H5T_NATIVE_UINT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const long int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<long int>(variableName), values,
                H5T_NATIVE_LONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const unsigned long int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<unsigned long int>(variableName), values,
                H5T_NATIVE_ULONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const long long int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<long long int>(variableName), values,
                H5T_NATIVE_LLONG);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const unsigned long long int *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<unsigned long long int>(variableName),
                values, H5T_NATIVE_ULLONG);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const float *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<float>(variableName), values,
                H5T_NATIVE_FLOAT);
guj's avatar
guj committed
}

guj's avatar
guj committed
void HDF5Writer::Write(const std::string variableName, const double *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<double>(variableName), values,
                H5T_NATIVE_DOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const long double *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<long double>(variableName), values,
                H5T_NATIVE_LDOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const std::complex<float> *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<std::complex<float>>(variableName), values,
                DefH5T_COMPLEX_FLOAT);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const std::complex<double> *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<std::complex<double>>(variableName), values,
                DefH5T_COMPLEX_DOUBLE);
guj's avatar
guj committed
}

void HDF5Writer::Write(const std::string variableName,
guj's avatar
guj committed
                       const std::complex<long double> *values)
{
    UseHDFWrite(m_ADIOS.GetVariable<std::complex<long double>>(variableName),
                values, DefH5T_COMPLEX_LongDOUBLE);
guj's avatar
guj committed
}

guj's avatar
guj committed
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);
guj's avatar
guj committed
}

template <class T>
void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values,
guj's avatar
guj committed
                             hid_t h5type)
{
    // here comes your magic at Writing now variable.m_UserValues has the data
    // passed by the user
    // set variable
    variable.m_AppValues = values;
    m_WrittenVariables.insert(variable.m_Name);
guj's avatar
guj committed

guj's avatar
guj committed
    int dimSize = variable.m_GlobalDimensions.size();
    /*
    std::cout << "writting : " << variable.m_Name
              << " dim size:" << variable.m_GlobalDimensions.size() <<
    std::endl;
guj's avatar
guj committed

guj's avatar
guj committed
    for (int i = 0; i < dimSize; i++) {
      std::cout << " dim: " << i << ", size:" << variable.m_GlobalDimensions[i]
                << " offset=" << variable.m_Offsets[i]
                << " count=" << variable.m_LocalDimensions[i] << std::endl;
    }
    */
    std::vector<hsize_t> dimsf, count, offset;
guj's avatar
guj committed

guj's avatar
guj committed
    for (int i = 0; i < dimSize; i++)
    {
        dimsf.push_back(variable.m_GlobalDimensions[i]);
        count.push_back(variable.m_LocalDimensions[i]);
        offset.push_back(variable.m_Offsets[i]);
    }
guj's avatar
guj committed

guj's avatar
guj committed
    _filespace = H5Screate_simple(dimSize, dimsf.data(), NULL);
guj's avatar
guj committed

guj's avatar
guj committed
    _dset_id = H5Dcreate(_file_id, variable.m_Name.c_str(), h5type, _filespace,
                         H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    // H5Sclose(_filespace);
guj's avatar
guj committed

guj's avatar
guj committed
    _memspace = H5Screate_simple(dimSize, count.data(), NULL);
guj's avatar
guj committed

guj's avatar
guj committed
    // Select hyperslab
    _filespace = H5Dget_space(_dset_id);
    H5Sselect_hyperslab(_filespace, H5S_SELECT_SET, offset.data(), NULL,
                        count.data(), NULL);
guj's avatar
guj committed

guj's avatar
guj committed
    //  Create property list for collective dataset write.
guj's avatar
guj committed

guj's avatar
guj committed
    _plist_id = H5Pcreate(H5P_DATASET_XFER);
guj's avatar
guj committed
    H5Pset_dxpl_mpio(_plist_id, H5FD_MPIO_COLLECTIVE);
guj's avatar
guj committed
    herr_t status;
guj's avatar
guj committed

guj's avatar
guj committed
    status =
        H5Dwrite(_dset_id, h5type, _memspace, _filespace, _plist_id, values);
guj's avatar
guj committed

guj's avatar
guj committed
    if (status < 0)
    {
        // error
        std::cerr << " Write failed. " << std::endl;
    }
guj's avatar
guj committed

guj's avatar
guj committed
    // std::cout << " ==> User is responsible for freeing the data " <<
    // std::endl;
guj's avatar
guj committed

guj's avatar
guj committed
    H5Dclose(_dset_id);
    H5Sclose(_filespace);
    H5Sclose(_memspace);
    H5Pclose(_plist_id);
guj's avatar
guj committed
}

} // end namespace adios