From 8f7389e982552abdaed233454a865976e788e53c Mon Sep 17 00:00:00 2001 From: guj <jgu@lbl.gov> Date: Fri, 14 Apr 2017 12:24:44 -0700 Subject: [PATCH] hdf5 basic support --- CMakeLists.txt | 2 + cmake/FindPHDF5.cmake | 59 ------- examples/hello/CMakeLists.txt | 4 + examples/hello/hdf5Writer/CMakeLists.txt | 30 ++++ examples/hello/hdf5Writer/helloHDF5Writer.cpp | 137 +++++++++++++++ .../hdf5Writer/helloHDF5Writer_nompi.cpp | 134 ++++++++++++++ include/engine/hdf5/HDF5ReaderP.h | 11 ++ include/engine/hdf5/HDF5WriterP.h | 33 ++-- source/ADIOS.cpp | 15 ++ source/CMakeLists.txt | 33 +++- source/engine/hdf5/HDF5ReaderP.cpp | 11 +- source/engine/hdf5/HDF5WriterP.cpp | 166 ++++++------------ 12 files changed, 439 insertions(+), 196 deletions(-) delete mode 100644 cmake/FindPHDF5.cmake create mode 100644 examples/hello/hdf5Writer/CMakeLists.txt create mode 100644 examples/hello/hdf5Writer/helloHDF5Writer.cpp create mode 100644 examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e267cc5b..0d70affa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ endif() option(ADIOS_USE_BZip2 "Enable support for BZip2 transforms" OFF) option(ADIOS_USE_ADIOS1 "Enable support for the ADIOS 1 engine" OFF) option(ADIOS_USE_DataMan "Enable support for the DataMan engine" OFF) +option(ADIOS_USE_PHDF5 "Enable support for hdf5" OFF) #------------------------------------------------------------------------------# # Third party libraries @@ -134,4 +135,5 @@ message(" MPI: ${ADIOS_USE_MPI}") message(" BZip2: ${ADIOS_USE_BZip2}") message(" ADIOS1: ${ADIOS_USE_ADIOS1}") message(" DataMan: ${ADIOS_USE_DataMan}") +message(" HDF5: ${ADIOS_USE_PHDF5}") message("") diff --git a/cmake/FindPHDF5.cmake b/cmake/FindPHDF5.cmake deleted file mode 100644 index e357e7279..000000000 --- a/cmake/FindPHDF5.cmake +++ /dev/null @@ -1,59 +0,0 @@ -#------------------------------------------------------------------------------# -# Distributed under the OSI-approved Apache License, Version 2.0. See -# accompanying file Copyright.txt for details. -#------------------------------------------------------------------------------# -# -# FindPHDF5 -# --------- -# - - -if(NOT PHDF5_FOUND) - if((NOT HDF5_DIR) AND (NOT (ENV{HDF5_DIR} STREQUAL ""))) - set(HDF5_DIR "$ENV{HDF5_DIR}") - endif() - - # Search for the core libraries - if(HDF5_DIR) - # If a root directory is specified, then don't look anywhere else - find_path(PHDF5_INCLUDE_DIR hdf5.h - HINTS ${HDF5_DIR}/include - NO_DEFAULT_PATHS - ) - set(_PHDF5_LIBRARY_HINT HINTS ${HDF5_DIR}/lib NO_DEFAULT_PATHS) - else() - # Otherwise use the include dir as a basis to search for the lib - find_path(PHDF5_INCLUDE_DIR hdf5.h) - if(PHDF5_INCLUDE_DIR) - get_filename_component(_PHDF5_PREFIX "${PHDF5_INCLUDE_DIR}" PATH) - set(_PHDF5_LIBRARY_HINT HINTS ${_PHDF5_PREFIX}/lib) - unset(_PHDF5_PREFIX) - endif() - endif() - find_library(PHDF5_LIBRARY hdf5 ${_PHDF5_LIBRARY_HINT}) - unset(_PHDF5_LIBRARY_HINT) - - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(PHDF5 DEFAULT_MSG PHDF5_LIBRARY PHDF5_INCLUDE_DIR) - - find_package_handle_standard_args(PHDF5 - FOUND_VAR PHDF5_FOUND - REQUIRED_VARS - PHDF5_INCLUDE_DIR - PHDF5_LIBRARY - ) - - MESSAGE(STATUS "PHDF5_FOUND: " ${PHDF5_FOUND} "HDF5_DIR: " ${HDF5_DIR} "TARGET=" ${TARGET} ) - if(PHDF5_FOUND) - set(PHDF5_INCLUDE_DIRS ${PHDF5_INCLUDE_DIR}) - set(PHDF5_LIBRARIES ${PHDF5_LIBRARY}) - if(PHDF5_FOUND AND NOT TARGET PHDF5::PHDF5) - add_library(PHDF5::PHDF5 UNKNOWN IMPORTED) - set_target_properties(PHDF5::PHDF5 PROPERTIES - IMPORTED_LOCATION "${PHDF5_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${PHDF5_INCLUDE_DIR}" - ) - endif() - endif() -endif() diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index 0cf0a5df5..73fa0f560 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -14,3 +14,7 @@ if(ADIOS_USE_DataMan) add_subdirectory(datamanReader) add_subdirectory(datamanWriter) endif() + +if(ADIOS_USE_PHDF5) + add_subdirectory(hdf5Writer) +endif() diff --git a/examples/hello/hdf5Writer/CMakeLists.txt b/examples/hello/hdf5Writer/CMakeLists.txt new file mode 100644 index 000000000..742560057 --- /dev/null +++ b/examples/hello/hdf5Writer/CMakeLists.txt @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_executable(hello_hdf5Writer_nompi helloHDF5Writer_nompi.cpp) +message(" HDF5: ${HDF5_INCLUDE_DIRS}") +include_directories(${HDF5_INCLUDE_DIRS}) +target_link_libraries(hello_hdf5Writer_nompi adios2_nompi) + +if(ADIOS_BUILD_TESTING) + add_test( + NAME Example::hello::hdf5Writer_nompi + COMMAND hello_hdf5Writer_nompi + ) +endif() + +if(ADIOS_USE_MPI) + find_package(MPI COMPONENTS C REQUIRED) + + add_executable(hello_hdf5Writer helloHDF5Writer.cpp) + target_link_libraries(hello_hdf5Writer adios2) + target_include_directories(hello_hdf5Writer PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(hello_hdf5Writer adios2 ${MPI_C_LIBRARIES}) + + if(ADIOS_BUILD_TESTING) + add_test(NAME Example::hello::hdf5Writer COMMAND hello_hdf5Writer) + endif() +endif() + diff --git a/examples/hello/hdf5Writer/helloHDF5Writer.cpp b/examples/hello/hdf5Writer/helloHDF5Writer.cpp new file mode 100644 index 000000000..8dd6260bf --- /dev/null +++ b/examples/hello/hdf5Writer/helloHDF5Writer.cpp @@ -0,0 +1,137 @@ +/* + * HDF5Writer.cpp + * + * Created on: March 20, 2017 + * Author: Junmin + */ + + + +#include <vector> +#include <iostream> + + +#include <mpi.h> + + +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + MPI_Init( &argc, &argv ); + int rank, size; + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &size ); + + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); + + + //Application variable + const std::size_t intDim1 = 4; + const std::size_t intDim2 = 3; + std::vector<int> myInts = {10,11,12,13,14,15,16,17,18,19,20,21}; + + std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::size_t Nx = myDoubles.size(); + + std::vector<std::complex<float>> myCFloats; + const std::size_t ComplexDataSize = 3; + myCFloats.reserve( ComplexDataSize ); + myCFloats.emplace_back( 1, 3 ); + myCFloats.emplace_back( 2, 2 ); + myCFloats.emplace_back( 3, 1 ); + + + std::vector<std::complex<double>> myCDoubles; + myCDoubles.reserve( ComplexDataSize ); + myCDoubles.emplace_back( 1.1, -3.3 ); + myCDoubles.emplace_back( 2.1, -2.2 ); + myCDoubles.emplace_back( 3.1, -1.1 ); + + std::vector<std::complex<long double>> myCLongDoubles; + myCLongDoubles.reserve( ComplexDataSize ); + myCLongDoubles.emplace_back( 1.11, -3.33 ); + myCLongDoubles.emplace_back( 2.11, -2.22 ); + myCLongDoubles.emplace_back( 3.11, -1.11 ); + + + std::size_t doubleVCount = Nx/size; + std::size_t complexCount = ComplexDataSize/size; + std::size_t intCountDim1 = intDim1/size; + + std::size_t doubleVOffset = rank * doubleVCount; + std::size_t complexOffset = rank * complexCount; + std::size_t intOffsetDim1 = rank * intCountDim1; + std::size_t intOffsetDim2 = 0; + + if ((size > 1) && (rank == size-1)) + { + doubleVCount = Nx - rank*(Nx/size); + complexCount = ComplexDataSize - rank * (ComplexDataSize/size); + intCountDim1 = intDim1 - rank * (intDim1/size); + } + + try + { + //Define variable and local size + auto& ioMyInts = adios.DefineVariable<int>( "myInts", {intCountDim1, intDim2}, {4,3}, {intOffsetDim1, intOffsetDim2} ); + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {doubleVCount}, {Nx}, {doubleVOffset} ); + auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {complexCount}, {3}, {complexOffset} ); + auto& ioMyCDoubles = adios.DefineVariable<std::complex<double>>( "myCDoubles", {complexCount}, {3}, {complexOffset} ); + auto& ioMyCLongDoubles = adios.DefineVariable<std::complex<long double>>( "myCLongDoubles", {complexCount}, {3}, {complexOffset} ); + + + //Define method for engine creation, it is basically straight-forward parameters + adios::Method& HDF5Settings = adios.DeclareMethod("w" ); + HDF5Settings.SetEngine("HDF5Writer"); + HDF5Settings.SetParameters( "chunck=yes", "collectiveIO=yes"); + //HDF5Settings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + + //Create engine smart pointer to HDF5 Engine due to polymorphism, + //Open returns a smart pointer to Engine containing the Derived class HDF5 + auto HDF5Writer = adios.Open( "test.bp", "w", HDF5Settings ); + + if( HDF5Writer == nullptr ) + 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( ); + + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} diff --git a/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp new file mode 100644 index 000000000..e49794eae --- /dev/null +++ b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp @@ -0,0 +1,134 @@ +/* + * HDF5Writer.cpp + * + * Created on: March 20, 2017 + * Author: Junmin + */ + + + +#include <vector> +#include <iostream> + + +//#include <mpi.h> +#include "ADIOS_MPI.h" + +#ifndef HAVE_MPI +// mpidummy has namespace adios +using namespace adios; +#endif +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + MPI_Init( &argc, &argv ); + int rank, size; + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &size ); + + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); + + + //Application variable + const std::size_t intDim1 = 4; + const std::size_t intDim2 = 3; + std::vector<int> myInts = {10,11,12,13,14,15,16,17,18,19,20,21}; + + std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::size_t Nx = myDoubles.size(); + + std::vector<std::complex<float>> myCFloats; + const std::size_t CFloatSize = 3; + myCFloats.reserve( CFloatSize ); + myCFloats.emplace_back( 1, 3 ); + myCFloats.emplace_back( 2, 2 ); + myCFloats.emplace_back( 3, 1 ); + + + std::vector<std::complex<double>> myCDoubles; + const std::size_t CDoubleSize = 3; + myCDoubles.reserve( CDoubleSize ); + myCDoubles.emplace_back( 1, 3 ); + myCDoubles.emplace_back( 2, 2 ); + myCDoubles.emplace_back( 3, 1 ); + + + std::size_t doubleVCount = Nx/size; + std::size_t floatCount = CFloatSize/size; + std::size_t intCountDim1 = intDim1/size; + + std::size_t doubleVOffset = rank * doubleVCount; + std::size_t floatOffset = rank * floatCount; + std::size_t intOffsetDim1 = rank * intCountDim1; + std::size_t intOffsetDim2 = 0; + + if ((size > 1) && (rank == size-1)) { + doubleVCount = Nx - rank*(Nx/size); + floatCount = CFloatSize - rank * (CFloatSize/size); + intCountDim1 = intDim1 - rank * (intDim1/size); + } + + try + { + //Define variable and local size + //auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx}, {Nx} ); + //auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {3}, {3} ); + //auto& ioMyInts = adios.DefineVariable<int>( "myInts", {4,3}, {4,3} ); + + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {doubleVCount}, {Nx}, {doubleVOffset} ); + auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {floatCount}, {3}, {floatOffset} ); + auto& ioMyCDoubles = adios.DefineVariable<std::complex<double>>( "myCDoubles", {floatCount}, {3}, {floatOffset} ); + auto& ioMyInts = adios.DefineVariable<int>( "myInts", {intCountDim1, intDim2}, {4,3}, {intOffsetDim1, intOffsetDim2} ); + + //Define method for engine creation, it is basically straight-forward parameters + adios::Method& HDF5Settings = adios.DeclareMethod("HDF5Writer" ); //default method type is Writer + HDF5Settings.SetParameters( "chunck=yes", "collectiveIO=yes"); + //HDF5Settings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + + //Create engine smart pointer to HDF5 Engine due to polymorphism, + //Open returns a smart pointer to Engine containing the Derived class HDF5 + auto HDF5Writer = adios.Open( "test.bp", "w", HDF5Settings ); + + if( HDF5Writer == nullptr ) + 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() ); + HDF5Writer->Write( ioMyCDoubles, myCDoubles.data() ); + HDF5Writer->Close( ); + + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} diff --git a/include/engine/hdf5/HDF5ReaderP.h b/include/engine/hdf5/HDF5ReaderP.h index 28d688208..959b08e91 100644 --- a/include/engine/hdf5/HDF5ReaderP.h +++ b/include/engine/hdf5/HDF5ReaderP.h @@ -1,3 +1,14 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * HDF5ReaderP.h + * + * Created on: March 20, 2017 + * Author: Junmin + */ + + #ifndef HDF5_READER_P_H #define HDF5_READER_P_H diff --git a/include/engine/hdf5/HDF5WriterP.h b/include/engine/hdf5/HDF5WriterP.h index 27d5e8d10..098a56c45 100644 --- a/include/engine/hdf5/HDF5WriterP.h +++ b/include/engine/hdf5/HDF5WriterP.h @@ -1,4 +1,8 @@ + /* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * * HDF5WriterP.h * * Created on: March 20, 2017 @@ -8,24 +12,23 @@ #ifndef HDF5_WRITER_P_H_ #define HDF5_WRITER_P_H_ -#include <iostream> //std::cout must be removed, only used for hello example #include <unistd.h> //sleep must be removed #include "core/Engine.h" -#include "format/BP1Writer.h" + // supported capsules #include "capsule/heap/STLVector.h" #include "ADIOS_MPI.h" -#include "hdf5.h" +#include <hdf5.h> namespace adios { - + /* typedef struct { - double _re; /*real part*/ - double _im; /*imaginary part*/ + double _re; //real part + double _im; //imaginary part } ADIOS2_Complex_Double; typedef struct { @@ -36,10 +39,10 @@ typedef struct { // using ADIOS2_Complex_Float = std::complex<float>; typedef struct { - long double _re; /*real part*/ - long double _im; /*imaginary part*/ + long double _re; //real part + long double _im; //imaginary part } ADIOS2_Complex_LongDouble; - +*/ class HDF5Writer : public Engine { public: @@ -52,12 +55,10 @@ public: * @param method * @param debugMode */ - HDF5Writer(ADIOS &adios, const std::string name, const std::string accessMode, - MPI_Comm mpiComm, const Method &method, - const bool debugMode = false, const unsigned int cores = 1); + MPI_Comm mpiComm, const Method &method); - ~HDF5Writer(); + virtual ~HDF5Writer(); void Write(Variable<char> &variable, const char *values); void Write(Variable<unsigned char> &variable, const unsigned char *values); @@ -126,9 +127,9 @@ private: hid_t DefH5T_COMPLEX_FLOAT; hid_t DefH5T_COMPLEX_LongDOUBLE; - hid_t DefH5T_filetype_COMPLEX_DOUBLE; - hid_t DefH5T_filetype_COMPLEX_FLOAT; - hid_t DefH5T_filetype_COMPLEX_LongDOUBLE; + //hid_t DefH5T_filetype_COMPLEX_DOUBLE; + //hid_t DefH5T_filetype_COMPLEX_FLOAT; + //hid_t DefH5T_filetype_COMPLEX_LongDOUBLE; template <class T> void UseHDFWrite(Variable<T> &variable, const T *values, hid_t h5type); diff --git a/source/ADIOS.cpp b/source/ADIOS.cpp index 729e6c8ee..47e3c333f 100644 --- a/source/ADIOS.cpp +++ b/source/ADIOS.cpp @@ -35,6 +35,12 @@ #include "engine/adios1/ADIOS1Writer.h" #endif +#ifdef ADIOS_HAVE_PHDF5 // external dependencies +#ifdef ADIOS_HAVE_MPI +#include "engine/hdf5/HDF5WriterP.h" +#include "engine/hdf5/HDF5ReaderP.h" +#endif +#endif namespace adios { @@ -185,6 +191,15 @@ std::shared_ptr<Engine> ADIOS::Open(const std::string &name, // method, // iomode, timeout_sec, m_DebugMode, method.m_nThreads ); } + else if (type == "HDF5Writer") // -junmin + { + #if defined(ADIOS_HAVE_PHDF5) && defined(ADIOS_HAVE_MPI) + return std::make_shared<HDF5Writer>(*this, name, accessMode, mpiComm, method); + #else + throw std::invalid_argument( "ERROR: this version didn't compile with HDF5 library, can't use HDF5\n" ); + #endif + } + else { if (m_DebugMode == true) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 2ccf94700..4c5afc475 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -25,18 +25,18 @@ foreach(adios2_target IN LISTS adios2_targets) engine/bp/BPFileReader.cpp engine/bp/BPFileWriter.cpp + + utilities/format/bp1/BP1Base.cpp + utilities/format/bp1/BP1Aggregator.cpp + utilities/format/bp1/BP1Writer.cpp + + utilities/profiling/iochrono/Timer.cpp functions/adiosFunctions.cpp transport/file/FStream.cpp transport/file/FileDescriptor.cpp transport/file/FilePointer.cpp - - utilities/format/bp1/BP1Base.cpp - utilities/format/bp1/BP1Aggregator.cpp - utilities/format/bp1/BP1Writer.cpp - - utilities/profiling/iochrono/Timer.cpp ) target_include_directories(${adios2_target} PUBLIC ${ADIOS_SOURCE_DIR}/include @@ -52,6 +52,7 @@ foreach(adios2_target IN LISTS adios2_targets) target_compile_definitions(${adios2_target} PRIVATE ADIOS_HAVE_DATAMAN) target_link_libraries(${adios2_target} PRIVATE DataMan::DataMan) endif() + if(ADIOS_USE_BZip2) find_package(BZip2 REQUIRED) @@ -81,4 +82,24 @@ if(ADIOS_USE_MPI) target_compile_definitions(adios2 PRIVATE ADIOS_HAVE_ADIOS1) target_link_libraries(adios2 PRIVATE adios1::adios) endif() + + if(ADIOS_USE_PHDF5) + find_package(HDF5 REQUIRED) + message(" HDF5 ROOT: ${HDF5_ROOT}") + message(" HDF5 include: ${HDF5_INCLUDE_DIRS} is paralle? ${HDF5_IS_PARALLEL}") + + get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(dir ${dirs}) + message(STATUS "dir='${dir}'") + endforeach() + include_directories(${HDF5_INCLUDE_DIRS}) + + target_sources(adios2 PRIVATE + engine/hdf5/HDF5ReaderP.cpp + engine/hdf5/HDF5WriterP.cpp + ) + target_compile_definitions(adios2 PRIVATE ADIOS_HAVE_PHDF5) + target_link_libraries(adios2 PRIVATE hdf5) + endif() + endif() diff --git a/source/engine/hdf5/HDF5ReaderP.cpp b/source/engine/hdf5/HDF5ReaderP.cpp index 2412944f4..3716bfea5 100644 --- a/source/engine/hdf5/HDF5ReaderP.cpp +++ b/source/engine/hdf5/HDF5ReaderP.cpp @@ -1,10 +1,15 @@ /* - * HDF5ReaderP.cpp + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. * - * Created on: Mar 23, 2017 - * Author: junmin + * HDF5WriterP.cpp + * + * Created on: March 20, 2017 + * Author: Junmin */ + + #include <iostream> //needs to go away, this is just for demo purposes #include "engine/hdf5/HDF5ReaderP.h" diff --git a/source/engine/hdf5/HDF5WriterP.cpp b/source/engine/hdf5/HDF5WriterP.cpp index 5d07fd6e7..196744ac2 100644 --- a/source/engine/hdf5/HDF5WriterP.cpp +++ b/source/engine/hdf5/HDF5WriterP.cpp @@ -1,10 +1,14 @@ /* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * * HDF5WriterP.cpp * - * Created on: Mar 23, 2017 - * Author: junmin + * Created on: March 20, 2017 + * Author: Junmin */ + #include <iostream> //needs to go away, this is just for demo purposes #ifdef ADIOS_HAVE_MPI @@ -13,59 +17,34 @@ #include "core/Support.h" #include "functions/adiosFunctions.h" //CSVToVector -// supported transports -//#include "transport/file/FD.h" // uses POSIX -//#include "transport/file/FP.h" // uses C FILE* -//#include "transport/file/FStream.h" // uses C++ fstream - namespace adios { HDF5Writer::HDF5Writer(ADIOS &adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method &method, const bool debugMode, - const unsigned int cores) - : Engine(adios, "HDF5Writer", name, accessMode, mpiComm, method, debugMode, - cores, " HDF5Writer constructor (or call to ADIOS Open).\n"), - m_Buffer(accessMode, m_RankMPI, m_DebugMode) { - DefH5T_COMPLEX_DOUBLE = - H5Tcreate(H5T_COMPOUND, sizeof(ADIOS2_Complex_Double)); - DefH5T_COMPLEX_FLOAT = H5Tcreate(H5T_COMPOUND, sizeof(ADIOS2_Complex_Float)); - DefH5T_COMPLEX_LongDOUBLE = - H5Tcreate(H5T_COMPOUND, sizeof(ADIOS2_Complex_LongDouble)); - - // compound data type for memory - H5Tinsert(DefH5T_COMPLEX_DOUBLE, "double real", - HOFFSET(ADIOS2_Complex_Double, _re), H5T_NATIVE_DOUBLE); - H5Tinsert(DefH5T_COMPLEX_DOUBLE, "double img", - HOFFSET(ADIOS2_Complex_Double, _im), H5T_NATIVE_DOUBLE); - H5Tinsert(DefH5T_COMPLEX_FLOAT, "float real", - HOFFSET(ADIOS2_Complex_Float, _re), H5T_NATIVE_FLOAT); - H5Tinsert(DefH5T_COMPLEX_FLOAT, "float img", - HOFFSET(ADIOS2_Complex_Float, _im), H5T_NATIVE_FLOAT); - H5Tinsert(DefH5T_COMPLEX_LongDOUBLE, "ldouble real", - HOFFSET(ADIOS2_Complex_LongDouble, _re), H5T_NATIVE_LDOUBLE); - H5Tinsert(DefH5T_COMPLEX_LongDOUBLE, "ldouble img", - HOFFSET(ADIOS2_Complex_LongDouble, _im), H5T_NATIVE_LDOUBLE); - - // data type for file - int ldsize = H5Tget_size(H5T_NATIVE_DOUBLE); - DefH5T_filetype_COMPLEX_DOUBLE = H5Tcreate(H5T_COMPOUND, ldsize + ldsize); - H5Tinsert(DefH5T_filetype_COMPLEX_DOUBLE, "double real", 0, H5T_IEEE_F64BE); - H5Tinsert(DefH5T_filetype_COMPLEX_DOUBLE, "double img", ldsize, - H5T_IEEE_F64BE); - - ldsize = H5Tget_size(H5T_NATIVE_FLOAT); - DefH5T_filetype_COMPLEX_FLOAT = H5Tcreate(H5T_COMPOUND, ldsize + ldsize); - H5Tinsert(DefH5T_filetype_COMPLEX_FLOAT, "float real", 0, H5T_IEEE_F32BE); - H5Tinsert(DefH5T_filetype_COMPLEX_FLOAT, "float img", ldsize, H5T_IEEE_F32BE); - - ldsize = H5Tget_size( - H5T_NATIVE_LDOUBLE); // note that sizeof(H5T_NATIVE_LDOUBLE) returned 4!! - DefH5T_filetype_COMPLEX_LongDOUBLE = H5Tcreate(H5T_COMPOUND, ldsize + ldsize); - H5Tinsert(DefH5T_filetype_COMPLEX_LongDOUBLE, "ldouble real", 0, - H5T_NATIVE_LDOUBLE); - H5Tinsert(DefH5T_filetype_COMPLEX_LongDOUBLE, "ldouble img", ldsize, - H5T_NATIVE_LDOUBLE); + const Method &method) + : Engine(adios, "HDF5Writer", name, accessMode, mpiComm, method, /*debugMode, cores,*/ + " HDF5Writer constructor (or call to ADIOS Open).\n"), + m_Buffer(accessMode, m_RankMPI, 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(); } @@ -74,20 +53,20 @@ HDF5Writer::~HDF5Writer() {} 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"); + 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; - std::cout << "::Init hdf5 parallel writer. File name:" << m_Name << std::endl; + //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 HAVE_MPI + H5Pset_fapl_mpio(_plist_id, m_MPIComm, MPI_INFO_NULL); -#endif + /* * Create a new file collectively and release property list identifier. @@ -157,17 +136,17 @@ void HDF5Writer::Write(Variable<long double> &variable, void HDF5Writer::Write(Variable<std::complex<float>> &variable, const std::complex<float> *values) { - UseHDFWrite(variable, values, DefH5T_filetype_COMPLEX_FLOAT); + UseHDFWrite(variable, values, DefH5T_COMPLEX_FLOAT); } void HDF5Writer::Write(Variable<std::complex<double>> &variable, const std::complex<double> *values) { - UseHDFWrite(variable, values, DefH5T_filetype_COMPLEX_DOUBLE); + UseHDFWrite(variable, values, DefH5T_COMPLEX_DOUBLE); } void HDF5Writer::Write(Variable<std::complex<long double>> &variable, const std::complex<long double> *values) { - UseHDFWrite(variable, values, DefH5T_filetype_COMPLEX_LongDOUBLE); + UseHDFWrite(variable, values, DefH5T_COMPLEX_LongDOUBLE); } // String version @@ -260,7 +239,7 @@ void HDF5Writer::Write(const std::string variableName, } void HDF5Writer::Close(const int transportIndex) { - std::cout << " ===> CLOSING HDF5 <===== " << std::endl; + //std::cout << " ===> CLOSING HDF5 <===== " << std::endl; // H5Dclose(_dset_id); // H5Sclose(_filespace); // H5Sclose(_memspace); @@ -277,21 +256,23 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values, variable.m_AppValues = values; m_WrittenVariables.insert(variable.m_Name); + int dimSize = variable.m_GlobalDimensions.size(); + /* std::cout << "writting : " << variable.m_Name << " dim size:" << variable.m_GlobalDimensions.size() << std::endl; - int dimSize = variable.m_GlobalDimensions.size(); for (int i = 0; i < dimSize; i++) { std::cout << " dim: " << i << ", size:" << variable.m_GlobalDimensions[i] - << " offset=" << variable.m_GlobalOffsets[i] - << " count=" << variable.m_Dimensions[i] << std::endl; + << " offset=" << variable.m_Offsets[i] + << " count=" << variable.m_LocalDimensions[i] << std::endl; } + */ std::vector<hsize_t> dimsf, count, offset; for (int i = 0; i < dimSize; i++) { dimsf.push_back(variable.m_GlobalDimensions[i]); - count.push_back(variable.m_Dimensions[i]); - offset.push_back(variable.m_GlobalOffsets[i]); + count.push_back(variable.m_LocalDimensions[i]); + offset.push_back(variable.m_Offsets[i]); } _filespace = H5Screate_simple(dimSize, dimsf.data(), NULL); @@ -308,60 +289,21 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values, count.data(), NULL); // Create property list for collective dataset write. + _plist_id = H5Pcreate(H5P_DATASET_XFER); H5Pset_dxpl_mpio(_plist_id, H5FD_MPIO_COLLECTIVE); herr_t status; - if (h5type == DefH5T_filetype_COMPLEX_FLOAT) { - /* - ADIOS2_Complex_Float v[3]; - v[0]._re = 1.1, v[0]._im = 1.2; - v[1]._re = 2.1, v[1]._im = 2.2; - v[2]._re = 3.1, v[2]._im = 3.2; - // status = H5Dwrite(_dset_id, DefH5T_COMPLEX_FLOAT, _memspace, _filespace, - // _plist_id, values); - status = H5Dwrite(_dset_id, DefH5T_COMPLEX_FLOAT, _memspace, _filespace, - _plist_id, v); - */ - } else if (h5type == DefH5T_filetype_COMPLEX_DOUBLE) { - /* - ADIOS2_Complex_Double v[3]; - v[0]._re = 1.1, v[0]._im = 1.2; - v[1]._re = 2.1, v[1]._im = 2.2; - v[2]._re = 3.1, v[2]._im = 3.2; - status = H5Dwrite(_dset_id, DefH5T_COMPLEX_DOUBLE, _memspace, _filespace, - _plist_id, v); - */ - } else if (h5type == DefH5T_filetype_COMPLEX_LongDOUBLE) { - /* - ADIOS2_Complex_LongDouble v[3]; - v[0]._re = 1.1, v[0]._im = 1.2; - v[1]._re = 2.1, v[1]._im = 2.2; - v[2]._re = 3.1, v[2]._im = 3.2; - status = H5Dwrite(_dset_id, DefH5T_COMPLEX_LongDOUBLE, _memspace, - _filespace, _plist_id, v); - */ - } else { - status = - H5Dwrite(_dset_id, h5type, _memspace, _filespace, _plist_id, values); - } + status = + H5Dwrite(_dset_id, h5type, _memspace, _filespace, _plist_id, values); if (status < 0) { // error std::cerr << " Write failed. " << std::endl; } - std::cout << " ==> User is responsible for freeing the data " << std::endl; - // free(values); - - // Close/release resources. - - // H5Dclose(_dset_id); - // H5Sclose(_filespace); - // H5Sclose(_memspace); - // H5Pclose(_plist_id); - // H5Fclose(_file_id); + //std::cout << " ==> User is responsible for freeing the data " << std::endl; H5Dclose(_dset_id); H5Sclose(_filespace); -- GitLab