diff --git a/src/cmake/Setup3rdParty.cmake b/src/cmake/Setup3rdParty.cmake index 034981397..3641739d2 100644 --- a/src/cmake/Setup3rdParty.cmake +++ b/src/cmake/Setup3rdParty.cmake @@ -149,6 +149,19 @@ if(ADIOS_DIR) endif() endif() +################################ +# Setup ADIOS2 if available +################################ +# Search for ADIOS2. +if(ADIOS2_DIR) + include(cmake/thirdparty/SetupADIOS2.cmake) + include_directories(${ADIOS2_INCLUDE_DIRS}) + # if we don't find ADIOS2, throw a fatal error + if(NOT ADIOS2_FOUND) + message(FATAL_ERROR "ADIOS2_DIR is set, but ADIOS2 wasn't found.") + endif() +endif() + ################################ # Setup Zfp if available ################################ diff --git a/src/cmake/thirdparty/SetupADIOS2.cmake b/src/cmake/thirdparty/SetupADIOS2.cmake new file mode 100644 index 000000000..40597ee85 --- /dev/null +++ b/src/cmake/thirdparty/SetupADIOS2.cmake @@ -0,0 +1,14 @@ +# Copyright (c) Lawrence Livermore National Security, LLC and other Conduit +# Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +# other details. No copyright assignment is required to contribute to Conduit. +# +# Setup ADIOS2 +# + +MESSAGE(STATUS "Looking for ADIOS2 using ADIOS2_DIR=${ADIOS2_DIR}...") + +IF(ENABLE_MPI) + find_package(ADIOS2 REQUIRED COMPONENTS CXX MPI) +ELSE() + find_package(ADIOS2 REQUIRED COMPONENTS CXX) +ENDIF() diff --git a/src/config/ConduitConfig.cmake.in b/src/config/ConduitConfig.cmake.in index 70d1c9ecc..f41d8e130 100644 --- a/src/config/ConduitConfig.cmake.in +++ b/src/config/ConduitConfig.cmake.in @@ -35,10 +35,11 @@ if(NOT CONDUIT_FOUND) set(CONDUIT_USE_OPENMP "@ENABLE_OPENMP@") set(CONDUIT_INSTALL_PREFIX "@CONDUIT_INSTALL_PREFIX@") set(CONDUIT_PYTHON_MODULE_DIR "@CONDUIT_INSTALL_PYTHON_MODULE_DIR@") - set(CONDUIT_ZLIB_DIR "@ZLIB_DIR@") - set(CONDUIT_HDF5_DIR "@HDF5_DIR@") - set(CONDUIT_ADIOS_DIR "@ADIOS_DIR@") - set(CONDUIT_SILO_DIR "@SILO_DIR@") + set(CONDUIT_ZLIB_DIR "@ZLIB_DIR@") + set(CONDUIT_HDF5_DIR "@HDF5_DIR@") + set(CONDUIT_ADIOS_DIR "@ADIOS_DIR@") + set(CONDUIT_ADIOS2_DIR "@ADIOS2_DIR@") + set(CONDUIT_SILO_DIR "@SILO_DIR@") set(CONDUIT_METIS_DIR "@METIS_DIR@") set(CONDUIT_PARMETIS_DIR "@PARMETIS_DIR@") set(CONDUIT_ADIAK_DIR "@ADIAK_DIR@") diff --git a/src/config/conduit_config.mk.in b/src/config/conduit_config.mk.in index 25cd9812a..29b808384 100644 --- a/src/config/conduit_config.mk.in +++ b/src/config/conduit_config.mk.in @@ -28,9 +28,10 @@ CONDUIT_USE_FMT = @CONDUIT_USE_FMT@ CONDUIT_USE_CALIPER = @CONDUIT_USE_CALIPER@ CONDUIT_USE_OPENMP = @CONDUIT_USE_OPENMP@ -CONDUIT_SILO_DIR = @SILO_DIR@ -CONDUIT_ADIOS_DIR = @ADIOS_DIR@ -CONDUIT_ZFP_DIR = @ZFP_DIR@ +CONDUIT_SILO_DIR = @SILO_DIR@ +CONDUIT_ADIOS_DIR = @ADIOS_DIR@ +CONDUIT_ADIOS2_DIR = @ADIOS2_DIR@ +CONDUIT_ZFP_DIR = @ZFP_DIR@ CONDUIT_METIS_DIR = @METIS_DIR@ CONDUIT_PARMETIS_DIR = @PARMETIS_DIR@ @@ -47,10 +48,11 @@ CONDUIT_LINK_RPATH = -Wl,-rpath,$(CONDUIT_DIR)/lib # two steps are used b/c there are commas in the linker commands # which will undermine parsing of the makefile -CONDUIT_SILO_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_SILO_DIR)/lib -CONDUIT_HDF5_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_HDF5_DIR)/lib -CONDUIT_ADIOS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ADIOS_DIR)/lib -CONDUIT_ZFP_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ZFP_DIR)/lib +CONDUIT_SILO_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_SILO_DIR)/lib +CONDUIT_HDF5_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_HDF5_DIR)/lib +CONDUIT_ADIOS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ADIOS_DIR)/lib +CONDUIT_ADIOS2_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ADIOS2_DIR)/lib +CONDUIT_ZFP_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ZFP_DIR)/lib CONDUIT_METIS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_METIS_DIR)/lib CONDUIT_PARMETIS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_PARMETIS_DIR)/lib CONDUIT_CALIPER_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_CALIPER_DIR)/lib @@ -59,6 +61,7 @@ CONDUIT_ADIAK_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ADIAK_DIR)/lib CONDUIT_LINK_RPATH += $(if $(CONDUIT_SILO_DIR), $(CONDUIT_SILO_RPATH_FLAGS_VALUE)) CONDUIT_LINK_RPATH += $(if $(CONDUIT_HDF5_DIR), $(CONDUIT_HDF5_RPATH_FLAGS_VALUE)) CONDUIT_LINK_RPATH += $(if $(CONDUIT_ADIOS_DIR), $(CONDUIT_ADIOS_RPATH_FLAGS_VALUE)) +CONDUIT_LINK_RPATH += $(if $(CONDUIT_ADIOS2_DIR), $(CONDUIT_ADIOS2_RPATH_FLAGS_VALUE)) CONDUIT_LINK_RPATH += $(if $(CONDUIT_ZFP_DIR), $(CONDUIT_ZFP_RPATH_FLAGS_VALUE)) CONDUIT_LINK_RPATH += $(if $(CONDUIT_METIS_DIR), $(CONDUIT_METIS_RPATH_FLAGS_VALUE)) CONDUIT_LINK_RPATH += $(if $(CONDUIT_PARMETIS_DIR), $(CONDUIT_PARMETIS_RPATH_FLAGS_VALUE)) @@ -84,6 +87,8 @@ CONDUIT_INCLUDE_FLAGS += -I $(CONDUIT_DIR)/include CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_ADIOS_DIR),-I$(CONDUIT_ADIOS_DIR)/include) +CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_ADIOS2_DIR),-I$(CONDUIT_ADIOS2_DIR)/include) + CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_SILO_DIR),-I$(CONDUIT_SILO_DIR)/include) CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_HDF5_DIR),-I$(CONDUIT_HDF5_DIR)/include) @@ -112,6 +117,12 @@ CONDUIT_ZLIB_LIB_FLAGS = $(if $(CONDUIT_ZLIB_DIR),-L $(CONDUIT_ZLIB_DIR)/lib -l CONDUIT_ADIOS_LIB_FLAGS = $(if $(CONDUIT_ADIOS_DIR),@CONDUIT_ADIOS_NOMPI_MAKE_LIBS_STR@) CONDUIT_ADIOS_MPI_LIB_FLAGS = $(if $(CONDUIT_ADIOS_DIR),@CONDUIT_ADIOS_MPI_MAKE_LIBS_STR@) +########## +# ADIOS2 +########## +CONDUIT_ADIOS2_LIB_FLAGS = $(if $(CONDUIT_ADIOS2_DIR),@CONDUIT_ADIOS2_NOMPI_MAKE_LIBS_STR@) +CONDUIT_ADIOS2_MPI_LIB_FLAGS = $(if $(CONDUIT_ADIOS2_DIR),@CONDUIT_ADIOS2_MPI_MAKE_LIBS_STR@) + ########## # Silo ########## @@ -147,7 +158,7 @@ CONDUIT_CALIPER_LIB_FLAGS = $(if $(CONDUIT_CALIPER_DIR),-L $(CONDUIT_CALIPER_DI CONDUIT_LIB_FLAGS = -L $(CONDUIT_DIR)/lib \ -lconduit_relay \ -lconduit_blueprint \ - -lconduit $(CONDUIT_ADIOS_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_CALIPER_LIB_FLAGS) $(CONDUIT_ADIAK_LIB_FLAGS) $(CONDUIT_ZLIB_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS) $(CONDUIT_OPENMP_LINK_FLAGS) + -lconduit $(CONDUIT_ADIOS_LIB_FLAGS) $(CONDUIT_ADIOS2_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_CALIPER_LIB_FLAGS) $(CONDUIT_ADIAK_LIB_FLAGS) $(CONDUIT_ZLIB_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS) $(CONDUIT_OPENMP_LINK_FLAGS) # All conduit libs, with MPI CONDUIT_MPI_LIB_FLAGS = -L $(CONDUIT_DIR)/lib \ @@ -156,4 +167,4 @@ CONDUIT_MPI_LIB_FLAGS = -L $(CONDUIT_DIR)/lib \ -lconduit_relay \ -lconduit_blueprint_mpi \ -lconduit_blueprint \ - -lconduit $(CONDUIT_ADIOS_MPI_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_METIS_LIB_FLAGS) $(CONDUIT_PARMETIS_LIB_FLAGS) $(CONDUIT_CALIPER_LIB_FLAGS) $(CONDUIT_ZLIB_LIB_FLAGS) $(CONDUIT_ADIAK_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS) $(CONDUIT_OPENMP_LINK_FLAGS) + -lconduit $(CONDUIT_ADIOS_MPI_LIB_FLAGS) $(CONDUIT_ADIOS2_MPI_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_METIS_LIB_FLAGS) $(CONDUIT_PARMETIS_LIB_FLAGS) $(CONDUIT_CALIPER_LIB_FLAGS) $(CONDUIT_ZLIB_LIB_FLAGS) $(CONDUIT_ADIAK_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS) $(CONDUIT_OPENMP_LINK_FLAGS) diff --git a/src/libs/relay/CMakeLists.txt b/src/libs/relay/CMakeLists.txt index fc63bf2dd..023fe27f3 100644 --- a/src/libs/relay/CMakeLists.txt +++ b/src/libs/relay/CMakeLists.txt @@ -32,6 +32,14 @@ if(ADIOS_FOUND AND MPI_FOUND) SET(CONDUIT_RELAY_IO_MPI_ADIOS_ENABLED TRUE) endif() +if(ADIOS2_FOUND AND NOT MPI_FOUND) + SET(CONDUIT_RELAY_IO_ADIOS2_ENABLED TRUE) +endif() + +if(ADIOS2_FOUND AND MPI_FOUND) + SET(CONDUIT_RELAY_IO_MPI_ADIOS2_ENABLED TRUE) +endif() + if(ZFP_FOUND) SET(CONDUIT_RELAY_ZFP_ENABLED TRUE) endif() @@ -135,6 +143,13 @@ if(ADIOS_FOUND AND NOT MPI_FOUND) list(APPEND conduit_relay_sources conduit_relay_io_adios.cpp) endif() +if(ADIOS2_FOUND AND NOT MPI_FOUND) + list(APPEND conduit_relay_headers + conduit_relay_io_adios2.hpp + ) + list(APPEND conduit_relay_sources conduit_relay_io_adios2.cpp) +endif() + if(ZFP_FOUND) list(APPEND conduit_relay_headers conduit_relay_zfp.hpp) list(APPEND conduit_relay_sources conduit_relay_zfp.cpp) @@ -180,7 +195,7 @@ endif() mark_as_advanced(CONDUIT_MAKE_EXTRA_LIBS) # -# Link with silo and hdf5 and adios if these are enabled +# Link with silo, hdf5, adios, and adios2 if these are enabled # if(SILO_FOUND) list(APPEND conduit_relay_deps silo) @@ -202,6 +217,11 @@ if(ADIOS_FOUND AND NOT MPI_FOUND) list(APPEND conduit_relay_deps adios_nompi) endif() +if(ADIOS2_FOUND AND NOT MPI_FOUND) + # Link with the serial ADIOS2 libraries. + list(APPEND conduit_relay_deps adios2::cxx11) +endif() + if(ZFP_FOUND) list(APPEND conduit_relay_deps zfp) endif() @@ -401,6 +421,13 @@ if(ADIOS_FOUND) # Link with parallel versions of ADIOS list(APPEND conduit_relay_mpi_io_deps adios_mpi) endif() + +if(ADIOS2_FOUND) + list(APPEND conduit_relay_mpi_io_headers conduit_relay_mpi_io_adios2.hpp) + list(APPEND conduit_relay_mpi_io_sources conduit_relay_io_adios2.cpp) + # Link with parallel versions of ADIOS2 + list(APPEND conduit_relay_mpi_io_deps adios2::cxx11_mpi MPI::MPI_CXX) +endif() # diff --git a/src/libs/relay/conduit_relay_config.h.in b/src/libs/relay/conduit_relay_config.h.in index 060b875da..b75da0ed5 100644 --- a/src/libs/relay/conduit_relay_config.h.in +++ b/src/libs/relay/conduit_relay_config.h.in @@ -20,6 +20,10 @@ #cmakedefine CONDUIT_RELAY_IO_MPI_ADIOS_ENABLED +#cmakedefine CONDUIT_RELAY_IO_ADIOS2_ENABLED + +#cmakedefine CONDUIT_RELAY_IO_MPI_ADIOS2_ENABLED + #cmakedefine CONDUIT_RELAY_IO_HDF5_ENABLED #cmakedefine CONDUIT_RELAY_IO_H5ZZFP_ENABLED diff --git a/src/libs/relay/conduit_relay_io_adios2.cpp b/src/libs/relay/conduit_relay_io_adios2.cpp new file mode 100644 index 000000000..081c8be52 --- /dev/null +++ b/src/libs/relay/conduit_relay_io_adios2.cpp @@ -0,0 +1,372 @@ +// Copyright (c) Lawrence Livermore National Security, LLC and other Conduit +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Conduit. + +//----------------------------------------------------------------------------- +/// +/// file: conduit_relay_io_adios2.cpp +/// +//----------------------------------------------------------------------------- + +#ifdef CONDUIT_RELAY_IO_MPI_ENABLED +#include "conduit_relay_mpi_io_adios2.hpp" + +// Define argument macros that add a communicator argument. +#define CONDUIT_RELAY_COMMUNICATOR_ARG0(ARG) ARG +#define CONDUIT_RELAY_COMMUNICATOR_ARG(ARG) , ARG + +#else +#include "conduit_relay_io_adios2.hpp" + +// Define an argument macro that does not add the communicator argument. +#define CONDUIT_RELAY_COMMUNICATOR_ARG0(ARG) +#define CONDUIT_RELAY_COMMUNICATOR_ARG(ARG) + +// for non-mpi adios2 we need to define _NOMPI +#define _NOMPI + +#endif + +//----------------------------------------------------------------------------- +// standard lib includes +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +// external lib includes +//----------------------------------------------------------------------------- +#include + +//----------------------------------------------------------------------------- +// -- conduit includes -- +//----------------------------------------------------------------------------- +#include "conduit_error.hpp" +#include "conduit_utils.hpp" + +//----------------------------------------------------------------------------- +// -- begin conduit:: -- +//----------------------------------------------------------------------------- +namespace conduit { + +//----------------------------------------------------------------------------- +// -- begin conduit::relay -- +//----------------------------------------------------------------------------- +namespace relay { + +#ifdef CONDUIT_RELAY_IO_MPI_ENABLED +//----------------------------------------------------------------------------- +// -- begin conduit::relay::mpi -- +//----------------------------------------------------------------------------- +namespace mpi { +#endif + +//----------------------------------------------------------------------------- +// -- begin conduit::relay::::io -- +//----------------------------------------------------------------------------- +namespace io { + +//----------------------------------------------------------------------------- +// -- begin conduit::relay::::io::internals -- +//----------------------------------------------------------------------------- +namespace adios2_internals { + +bool is_integer(const std::string &s, int &ivalue) { + return sscanf(s.c_str(), "%d", &ivalue) == 1; +} + +//----------------------------------------------------------------------------- +bool is_positive_integer(const std::string &s, int &ivalue) { + bool ret = is_integer(s, ivalue); + return ret && ivalue >= 0; +} + +//----------------------------------------------------------------------------- +// This is the same as ADIOS's splitpath +// NOTE: Move to conduit::utils? +void splitpath(const std::string &path, std::string &filename, int &time_step, + int &domain, std::vector &subpaths, + bool prefer_time = false) { + std::vector tok; + conduit::utils::split_string(path, ':', tok); + + if (tok.empty()) + filename = path; // Would have had to be an empty string. + else if (tok.size() == 1) + filename = path; + else if (tok.size() == 2) { + filename = tok[0]; + int ivalue = 0; + if (is_integer(tok[1], ivalue)) { + if (prefer_time) { + // filename:timestep + time_step = ivalue; + } else { + // filename:domain + domain = ivalue; + } + } else { + // filename:subpaths + subpaths.push_back(tok[1]); + } + } else if (tok.size() >= 3) { + filename = tok[0]; + int ivalue1 = 0, ivalue2 = 0; + bool arg1 = is_integer(tok[1], ivalue1); + bool arg2 = is_positive_integer(tok[2], ivalue2); + if (arg1 && arg2) { + // filename:timestep:domain + time_step = ivalue1; + domain = ivalue2; + } else if (arg1 && !arg2) { + // filename:domain:subpaths + domain = ivalue1; + subpaths.push_back(tok[2]); + } else if (!arg1 && arg2) { + // filename::int + // Assume these are just numeric subpaths for now. + // We could test for tok[1] == "current" to denote time... + subpaths.push_back(tok[1]); + subpaths.push_back(tok[2]); + } else // !arg1 && !arg2 + { + // filename:subpath:subpath + subpaths.push_back(tok[1]); + subpaths.push_back(tok[2]); + } + + // Save the remaining tokens as subpaths + for (size_t i = 3; i < tok.size(); ++i) + subpaths.push_back(tok[i]); + } +} + +//----------------------------------------------------------------------------- +static std::unique_ptr adios; + +static void initialize(CONDUIT_RELAY_COMMUNICATOR_ARG0(MPI_Comm comm)) { + if (adios) + return; +#ifdef CONDUIT_RELAY_IO_MPI_ENABLED + adios = std::make_unique(comm); +#else + adios = std::make_unique(); +#endif +} + +static void finalize(CONDUIT_RELAY_COMMUNICATOR_ARG0(MPI_Comm comm)) { + if (!adios) + return; + adios.reset(); +} + +//----------------------------------------------------------------------------- +struct Options { + Options() = default; // for now + + Options(const Options &) = delete; + Options(Options &&) = delete; + Options &operator=(const Options &) = delete; + Options &operator=(Options &&) = delete; + + void set(const Node &opts) {} + void get(Node &opts) const {} +}; + +// Default I/O settings +static std::unique_ptr the_options; + +// @brief Access the ADIOS2 options, creating them first if needed. +static Options *options() { + if (!the_options) { + the_options = std::make_unique(); + } + return the_options.get(); +} + +} // namespace adios2_internals +//----------------------------------------------------------------------------- +// -- end conduit::relay::::io::adios2_internals -- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void adios2_set_options( + const Node &opts CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + adios2_internals::initialize(CONDUIT_RELAY_COMMUNICATOR_ARG0(comm)); + adios2_internals::options()->set(opts); +} + +//----------------------------------------------------------------------------- +void adios2_options(Node &opts CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + adios2_internals::initialize(CONDUIT_RELAY_COMMUNICATOR_ARG0(comm)); + adios2_internals::options()->get(opts); +} + +//----------------------------------------------------------------------------- +void adios2_initialize_library(CONDUIT_RELAY_COMMUNICATOR_ARG0(MPI_Comm comm)) { + adios2_internals::initialize(CONDUIT_RELAY_COMMUNICATOR_ARG0(comm)); +} + +//----------------------------------------------------------------------------- +void adios2_finalize_library(CONDUIT_RELAY_COMMUNICATOR_ARG0(MPI_Comm comm)) { + adios2_internals::finalize(CONDUIT_RELAY_COMMUNICATOR_ARG0(comm)); +} + +//----------------------------------------------------------------------------- +void adios2_save(const Node &node, + const std::string &path + CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + unsigned int nodehash = 0; + int nodehash_rank = 0, nodehash_size = 1; + assert(false); + // TODO adios2_internals::compute_nodehash( + // TODO node, nodehash, nodehash_rank, + // TODO nodehash_size CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); + // TODO adios2_internals::save(node, path, "w", nodehash, nodehash_rank, + // TODO nodehash_size + // CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +//----------------------------------------------------------------------------- +void adios2_save_merged(const Node &node, + const std::string &path + CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + assert(false); + // TODO // save_merged() is not allowed for streaming. + // TODO if + // (!adios2_internals::streamIsFileBased(adios2_internals::options()->read_method)) + // { + // TODO CONDUIT_ERROR("save_merged() is not allowed for streaming."); + // TODO return; + // TODO } + + unsigned int nodehash = 0; + int nodehash_rank = 0, nodehash_size = 1; + + assert(false); + // TODO // NOTE: we use "u" to update the file so the time step is not + // incremented. + // TODO adios2_internals::compute_nodehash(node, nodehash, nodehash_rank, + // TODO nodehash_size, + // TODO CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); + // TODO // TODO: read the number of domains in the file for this node hash (if + // hashing + // TODO // is present in the file) and adjust the nodehash_rank by that + // number. + // TODO adios2_internals::save(node, path, "u", nodehash, nodehash_rank, + // TODO nodehash_size, + // CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +void adios2_add_step(const Node &node, + const std::string &path + CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + // check for ":" split + std::string file_path, adios2_path; + conduit::utils::split_file_path(path, std::string(":"), file_path, + adios2_path); + + unsigned int nodehash = 0; + int nodehash_rank = 0, nodehash_size = 1; + + assert(false); + // TODO // NOTE: we use "a" to update the file to the next time step. + // TODO adios2_internals::compute_nodehash(node, nodehash, nodehash_rank, + // TODO nodehash_size, + // TODO CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); + // TODO adios2_internals::save(node, path, "a", nodehash, nodehash_rank, + // TODO nodehash_size, + // CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +//----------------------------------------------------------------------------- +void adios2_load(const std::string &path, int time_step, int domain, + Node &node CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + assert(false); + // TODO adios2_internals::adios2_load_state state; + // TODO state.time_step = time_step; // Force specific timestep/domain. + // TODO state.domain = domain; + // TODO + // TODO // Split the incoming path in case it includes other information. + // TODO // This may override the timestep and domain. + // TODO adios2_internals::splitpath(path, state.filename, state.time_step, + // TODO state.domain, state.subpaths); + // TODO + // TODO adios2_internals::load(&state, &node, + // CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +//----------------------------------------------------------------------------- +void adios2_load(const std::string &path, + Node &node CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + assert(false); + // TODO adios2_internals::adios2_load_state state; + // TODO #ifdef CONDUIT_RELAY_IO_MPI_ENABLED + // TODO // Read the rank'th domain if there is one. + // TODO MPI_Comm_rank(comm, &state.domain); + // TODO #endif + // TODO + // TODO // Split the incoming path in case it includes other information. + // TODO // This may override the timestep and domain. + // TODO adios2_internals::splitpath(path, state.filename, state.time_step, + // TODO state.domain, state.subpaths); + // TODO + // TODO adios2_internals::load(&state, &node, + // CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +//----------------------------------------------------------------------------- +int adios2_query_number_of_steps( + const std::string &path CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + assert(false); + // TODO adios2_internals::adios2_load_state state; + // TODO + // TODO // check for ":" split + // TODO std::string tmp; + // TODO conduit::utils::split_file_path(path, std::string(":"), + // state.filename, tmp); + // TODO + // TODO return adios2_internals::query_number_of_steps( + // TODO &state, CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +//----------------------------------------------------------------------------- +int adios2_query_number_of_domains( + const std::string &path CONDUIT_RELAY_COMMUNICATOR_ARG(MPI_Comm comm)) { + assert(false); + // TODO adios2_internals::adios2_load_state state; + // TODO + // TODO // Split the incoming path in case it includes other information. + // TODO // This may override the timestep and domain. + // TODO adios2_internals::splitpath(path, state.filename, state.time_step, + // TODO state.domain, state.subpaths); + // TODO + // TODO return adios2_internals::query_number_of_domains( + // TODO &state, CONDUIT_RELAY_COMMUNICATOR_ARG(comm)); +} + +} // namespace io +//----------------------------------------------------------------------------- +// -- end conduit::relay::::io -- +//----------------------------------------------------------------------------- + +#ifdef CONDUIT_RELAY_IO_MPI_ENABLED +} +//----------------------------------------------------------------------------- +// -- end conduit::relay::mpi -- +//----------------------------------------------------------------------------- +#endif + +} // namespace relay +//----------------------------------------------------------------------------- +// -- end conduit::relay -- +//----------------------------------------------------------------------------- + +} // namespace conduit +//----------------------------------------------------------------------------- +// -- end conduit:: -- +//----------------------------------------------------------------------------- diff --git a/src/libs/relay/conduit_relay_io_adios2.hpp b/src/libs/relay/conduit_relay_io_adios2.hpp new file mode 100644 index 000000000..504ed6e6c --- /dev/null +++ b/src/libs/relay/conduit_relay_io_adios2.hpp @@ -0,0 +1,133 @@ +// Copyright (c) Lawrence Livermore National Security, LLC and other Conduit +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Conduit. + +//----------------------------------------------------------------------------- +/// +/// file: conduit_relay_io_adios2.hpp +/// +//----------------------------------------------------------------------------- + +#ifndef CONDUIT_RELAY_IO_ADIOS2_HPP +#define CONDUIT_RELAY_IO_ADIOS2_HPP + +//----------------------------------------------------------------------------- +// conduit lib include +//----------------------------------------------------------------------------- +#include "conduit.hpp" +#include "conduit_relay_exports.h" +#include "conduit_relay_config.h" + +//----------------------------------------------------------------------------- +// -- begin conduit:: -- +//----------------------------------------------------------------------------- +namespace conduit +{ + +//----------------------------------------------------------------------------- +// -- begin conduit::relay -- +//----------------------------------------------------------------------------- +namespace relay +{ + +//----------------------------------------------------------------------------- +// -- begin conduit::relay::io -- +//----------------------------------------------------------------------------- +namespace io +{ + +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_initialize_library(); + +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_finalize_library(); + +//----------------------------------------------------------------------------- +/// Write node data to a given path +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_save(const Node &node, + const std::string &path); + +//----------------------------------------------------------------------------- +/// Write node data to a given path in an existing file. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_save_merged(const Node &node, + const std::string &path); + +//----------------------------------------------------------------------------- +/// Add a step of node data to an existing file. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.adios2:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_add_step(const Node &node, + const std::string &path); + +//----------------------------------------------------------------------------- +/// Read adios2 data from given path into the output node +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_load(const std::string &path, + Node &node); + +//----------------------------------------------------------------------------- +/// Read a given step and domain of adios2 data from given path into the +// output node. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_load(const std::string &path, + int step, + int domain, + Node &node); + +//----------------------------------------------------------------------------- +/// Pass a Node to set adios2 i/o options. +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_set_options(const Node &opts); + +//----------------------------------------------------------------------------- +/// Get a Node that contains adios2 i/o options. +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_options(Node &opts); + +//----------------------------------------------------------------------------- +/// Get a number of steps. +//----------------------------------------------------------------------------- +int CONDUIT_RELAY_API adios2_query_number_of_steps(const std::string &path); + +//----------------------------------------------------------------------------- +/// Get a number of domains. +//----------------------------------------------------------------------------- +int CONDUIT_RELAY_API adios2_query_number_of_domains(const std::string &path); + +} +//----------------------------------------------------------------------------- +// -- end conduit::relay::io -- +//----------------------------------------------------------------------------- + +} +//----------------------------------------------------------------------------- +// -- end conduit::relay -- +//----------------------------------------------------------------------------- + +} +//----------------------------------------------------------------------------- +// -- end conduit:: -- +//----------------------------------------------------------------------------- + +#endif diff --git a/src/libs/relay/conduit_relay_mpi_io_adios2.hpp b/src/libs/relay/conduit_relay_mpi_io_adios2.hpp new file mode 100644 index 000000000..7e429458e --- /dev/null +++ b/src/libs/relay/conduit_relay_mpi_io_adios2.hpp @@ -0,0 +1,159 @@ +// Copyright (c) Lawrence Livermore National Security, LLC and other Conduit +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Conduit. + +//----------------------------------------------------------------------------- +/// +/// file: conduit_relay_mpi_io_adios2.hpp +/// +//----------------------------------------------------------------------------- + +#ifndef CONDUIT_RELAY_MPI_IO_ADIOS2_HPP +#define CONDUIT_RELAY_MPI_IO_ADIOS2_HPP + +//----------------------------------------------------------------------------- +// external lib includes +//----------------------------------------------------------------------------- +#include + +//----------------------------------------------------------------------------- +// conduit lib include +//----------------------------------------------------------------------------- +#include "conduit.hpp" +#include "conduit_relay_exports.h" +#include "conduit_relay_config.h" + +//----------------------------------------------------------------------------- +// -- begin conduit:: -- +//----------------------------------------------------------------------------- +namespace conduit +{ + +//----------------------------------------------------------------------------- +// -- begin conduit::relay -- +//----------------------------------------------------------------------------- +namespace relay +{ + +//----------------------------------------------------------------------------- +// -- begin conduit::relay::mpi -- +//----------------------------------------------------------------------------- +namespace mpi +{ + +//----------------------------------------------------------------------------- +// -- begin conduit::relay::mpi::io -- +//----------------------------------------------------------------------------- +namespace io +{ + +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_initialize_library(MPI_Comm comm); + +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_finalize_library(MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Write node data to a given path +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_save(const Node &node, + const std::string &path, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Write node data to a given path in an existing file. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_save_merged(const Node &node, + const std::string &path, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Add a step of node data to an existing file. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.adios2:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_add_step(const Node &node, + const std::string &path, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Read adios2 data from given path into the output node +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_load(const std::string &path, + Node &node, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Read a given step and domain of adios2 data from given path into the +// output node. +/// +/// This methods supports a file system and adios2 path, joined using a ":" +/// ex: "/path/on/file/system.bp:/path/inside/adios2/file" +/// +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_load(const std::string &path, + int step, + int domain, + Node &node, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Pass a Node to set adios2 i/o options. +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_set_options(const Node &opts, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Get a Node that contains adios2 i/o options. +//----------------------------------------------------------------------------- +void CONDUIT_RELAY_API adios2_options(Node &opts, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Get a number of steps. +//----------------------------------------------------------------------------- +int CONDUIT_RELAY_API adios2_query_number_of_steps(const std::string &path, + MPI_Comm comm); + +//----------------------------------------------------------------------------- +/// Get a number of domains. +//----------------------------------------------------------------------------- +int CONDUIT_RELAY_API adios2_query_number_of_domains(const std::string &path, + MPI_Comm comm); + +} +//----------------------------------------------------------------------------- +// -- end conduit::relay::mpi::io -- +//----------------------------------------------------------------------------- + +} +//----------------------------------------------------------------------------- +// -- end conduit::relay::mpi -- +//----------------------------------------------------------------------------- + +} +//----------------------------------------------------------------------------- +// -- end conduit::relay -- +//----------------------------------------------------------------------------- + +} +//----------------------------------------------------------------------------- +// -- end conduit:: -- +//----------------------------------------------------------------------------- + + +#endif diff --git a/src/tests/relay/CMakeLists.txt b/src/tests/relay/CMakeLists.txt index 2bb21a9a3..6ac992d72 100644 --- a/src/tests/relay/CMakeLists.txt +++ b/src/tests/relay/CMakeLists.txt @@ -123,6 +123,27 @@ else() message(STATUS "ADIOS disabled: Skipping conduit_relay ADIOS tests") endif() +if(ADIOS2_FOUND) + if(NOT MPI_FOUND) + message(STATUS "ADIOS2 enabled: Adding conduit_relay ADIOS2 unit tests") + foreach(TEST ${RELAY_ADIOS2_TESTS}) + add_cpp_test(TEST ${TEST} + DEPENDS_ON conduit conduit_relay + FOLDER tests/relay) + endforeach() + else() + message(STATUS "ADIOS2 + MPI enabled: Adding conduit_relay_mpi_adios2 unit tests") + foreach(TEST ${RELAY_MPI_ADIOS2_TESTS}) + add_cpp_mpi_test(TEST ${TEST} + NUM_MPI_TASKS 2 + DEPENDS_ON conduit conduit_relay_mpi_io + FOLDER tests/relay) + endforeach() + endif() +else() + message(STATUS "ADIOS2 disabled: Skipping conduit_relay ADIOS tests") +endif() + if(MPI_FOUND) message(STATUS "MPI enabled: Adding conduit_relay_mpi unit tests") diff --git a/src/tests/relay/c/CMakeLists.txt b/src/tests/relay/c/CMakeLists.txt index cdc72b0d7..969e3f88b 100644 --- a/src/tests/relay/c/CMakeLists.txt +++ b/src/tests/relay/c/CMakeLists.txt @@ -45,3 +45,23 @@ else() endif() +if(ADIOS2_FOUND) + if(NOT MPI_FOUND) + message(STATUS "ADIOS2 enabled: Adding conduit_relay c interface ADIOS2 unit tests") + foreach(TEST ${RELAY_C_IO_ADIOS2_TESTS}) + add_cpp_test(TEST ${TEST} + DEPENDS_ON conduit conduit_relay + FOLDER tests/relay/c) + endforeach() + else() + message(STATUS "ADIOS2 + MPI enabled: Adding conduit_relay_mpi_adios2 unit tests") + foreach(TEST ${RELAY_C_MPI_IO_ADIOS2_TESTS}) + add_cpp_mpi_test(TEST ${TEST} + NUM_MPI_TASKS 2 + DEPENDS_ON conduit conduit_relay_mpi_io + FOLDER tests/relay/c) + endforeach() + endif() +else() + message(STATUS "ADIOS2 disabled: Skipping conduit_relay c interface ADIOS2 tests") +endif() diff --git a/src/tests/thirdparty/CMakeLists.txt b/src/tests/thirdparty/CMakeLists.txt index d5e501971..5f5c168df 100644 --- a/src/tests/thirdparty/CMakeLists.txt +++ b/src/tests/thirdparty/CMakeLists.txt @@ -115,6 +115,19 @@ else() message(STATUS "ADIOS disabled: Skipping related tests") endif() +if(ADIOS2_FOUND) + set(serial_adios2_deps adios2::cxx11) + if(UNIX AND NOT APPLE) + list(APPEND serial_adios2_deps dl rt ${CMAKE_THREAD_LIBS_INIT}) + endif() + message(STATUS "ADIOS2 enabled: Adding related unit tests") + add_cpp_test(TEST t_adios2_smoke + DEPENDS_ON ${serial_adios2_deps} + FOLDER tests/thirdparty) +else() + message(STATUS "ADIOS2 disabled: Skipping related tests") +endif() + if(FORTRAN_FOUND) message(STATUS "Fortran enabled: Adding related unit tests") add_fortran_test(TEST t_fortran_smoke diff --git a/src/tests/thirdparty/t_adios2_smoke.cpp b/src/tests/thirdparty/t_adios2_smoke.cpp new file mode 100644 index 000000000..bcd69fa76 --- /dev/null +++ b/src/tests/thirdparty/t_adios2_smoke.cpp @@ -0,0 +1,58 @@ +// Copyright (c) Lawrence Livermore National Security, LLC and other Conduit +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Conduit. + +//----------------------------------------------------------------------------- +/// +/// file: adios2_smoke.cpp +/// +//----------------------------------------------------------------------------- + +// Serial test only. +#define _NOMPI + +#include +#include +#include +#include "gtest/gtest.h" + +// Adapted from ADIOS2' global aggregate by color test. + +//----------------------------------------------------------------------------- +TEST(adios2_smoke, basic_use) +{ + #warning "TODO" + assert(false); + //TODO int rank = 0; + //TODO int comm = 0; + //TODO int NX = 5; + //TODO const char *filename = "adios2_smoke.bp"; + //TODO int64_t m_adios2_group; + //TODO int64_t m_adios2_file; + //TODO + //TODO int status = adios2_init_noxml(comm); + //TODO EXPECT_TRUE(status >= 0 ); + //TODO + //TODO adios2_set_max_buffer_size (10); + //TODO + //TODO status = adios2_declare_group(&m_adios2_group, "restart", "iter", adios2_stat_default); + //TODO EXPECT_TRUE(status >= 0 ); + //TODO + //TODO status = adios2_select_method(m_adios2_group, "POSIX", "", ""); + //TODO EXPECT_TRUE(status >= 0 ); + //TODO + //TODO adios2_define_var(m_adios2_group, "NX", + //TODO "", adios2_integer, + //TODO 0, 0, 0); + //TODO + //TODO status = adios2_open(&m_adios2_file, "restart", filename, "w", comm); + //TODO + //TODO status = adios2_write(m_adios2_file, "NX", (void *) &NX); + //TODO EXPECT_TRUE(status >= 0 ); + //TODO + //TODO status = adios2_close(m_adios2_file); + //TODO EXPECT_TRUE(status >= 0 ); + //TODO + //TODO status = adios2_finalize(rank); + //TODO EXPECT_TRUE(status >= 0 ); +}