diff --git a/bindings/C/adios2/adios2_c_engine.cpp b/bindings/C/adios2/adios2_c_engine.cpp index d2d0880834b4201288021e4aa8b34529d7df8e44..cbdd0ab0846e4cda143dbdb116850e22b6505aa0 100644 --- a/bindings/C/adios2/adios2_c_engine.cpp +++ b/bindings/C/adios2/adios2_c_engine.cpp @@ -156,6 +156,142 @@ void adios2_perform_puts(adios2_Engine *engine) engineCpp.PerformPuts(); } +void adios2_get_sync(adios2_Engine *engine, adios2_Variable *variable, + void *values) +{ + adios2::VariableBase *variableBase = + reinterpret_cast<adios2::VariableBase *>(variable); + const std::string type(variableBase->m_Type); + + adios2::Engine &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetSync(*dynamic_cast<adios2::Variable<T> *>(variableBase), \ + reinterpret_cast<T *>(values)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_get_sync_self(adios2_Engine *engine, adios2_Variable *variable) +{ + adios2::VariableBase *variableBase = + reinterpret_cast<adios2::VariableBase *>(variable); + const std::string type(variableBase->m_Type); + + adios2::Engine &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetSync(*dynamic_cast<adios2::Variable<T> *>(variableBase)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_get_sync_by_name(adios2_Engine *engine, const char *variable_name, + void *values) +{ + auto &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + const std::string type( + engineCpp.GetIO().InquireVariableType(variable_name)); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetSync(variable_name, reinterpret_cast<T *>(values)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_get_deferred(adios2_Engine *engine, adios2_Variable *variable, + void *values) +{ + adios2::VariableBase *variableBase = + reinterpret_cast<adios2::VariableBase *>(variable); + const std::string type(variableBase->m_Type); + + adios2::Engine &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetDeferred( \ + *dynamic_cast<adios2::Variable<T> *>(variableBase), \ + reinterpret_cast<T *>(values)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_get_deferred_self(adios2_Engine *engine, adios2_Variable *variable) +{ + adios2::VariableBase *variableBase = + reinterpret_cast<adios2::VariableBase *>(variable); + const std::string type(variableBase->m_Type); + + adios2::Engine &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetDeferred( \ + *dynamic_cast<adios2::Variable<T> *>(variableBase)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_get_deferred_by_name(adios2_Engine *engine, + const char *variable_name, void *values) +{ + auto &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + const std::string type( + engineCpp.GetIO().InquireVariableType(variable_name)); + + if (type == "compound") + { + // not supported + } +#define declare_template_instantiation(T) \ + else if (type == adios2::GetType<T>()) \ + { \ + engineCpp.GetDeferred(variable_name, reinterpret_cast<T *>(values)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation +} + +void adios2_perform_gets(adios2_Engine *engine) +{ + auto &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); + engineCpp.PerformGets(); +} + void adios2_end_step(adios2_Engine *engine) { auto &engineCpp = *reinterpret_cast<adios2::Engine *>(engine); diff --git a/bindings/C/adios2/adios2_c_engine.h b/bindings/C/adios2/adios2_c_engine.h index 178905524681968a70ede719b4dbf2bfd7f2adae..7cb9af4d891dd0b9354ba9d2d0689765228bb04e 100644 --- a/bindings/C/adios2/adios2_c_engine.h +++ b/bindings/C/adios2/adios2_c_engine.h @@ -22,6 +22,8 @@ extern "C" { */ void adios2_begin_step(adios2_Engine *engine); +//***************** PUT ***************** + /** * Put a variable in IO using a adios2_Variable handler * @param engine handler for engine executing the write @@ -33,7 +35,7 @@ void adios2_put_sync(adios2_Engine *engine, adios2_Variable *variable, void adios2_put_sync_self(adios2_Engine *engine, adios2_Variable *variable); -void adios2_put_sync_by_name(adios2_Engine *engine, const char *variableName, +void adios2_put_sync_by_name(adios2_Engine *engine, const char *variable_name, const void *values); /** @@ -48,10 +50,29 @@ void adios2_put_deferred(adios2_Engine *engine, adios2_Variable *variable, void adios2_put_deferred_self(adios2_Engine *engine, adios2_Variable *variable); void adios2_put_deferred_by_name(adios2_Engine *engine, - const char *variableName, const void *values); + const char *variable_name, const void *values); void adios2_perform_puts(adios2_Engine *engine); +//***************** GET ***************** +void adios2_get_sync(adios2_Engine *engine, adios2_Variable *variable, + void *values); + +void adios2_get_sync_self(adios2_Engine *engine, adios2_Variable *variable); + +void adios2_get_sync_by_name(adios2_Engine *engine, const char *variable_name, + void *values); + +void adios2_get_deferred(adios2_Engine *engine, adios2_Variable *variable, + void *values); + +void adios2_get_deferred_self(adios2_Engine *engine, adios2_Variable *variable); + +void adios2_get_deferred_by_name(adios2_Engine *engine, + const char *variable_name, void *values); + +void adios2_perform_gets(adios2_Engine *engine); + /** * terminates interaction with current step * @param engine handler executing IO tasks diff --git a/bindings/C/adios2/adios2_c_variable.cpp b/bindings/C/adios2/adios2_c_variable.cpp index 405a1af082996e6b288e8f7222cc751b2de2f6fe..798dd9784c191705354fe3b814397d9017d33c1a 100644 --- a/bindings/C/adios2/adios2_c_variable.cpp +++ b/bindings/C/adios2/adios2_c_variable.cpp @@ -144,7 +144,7 @@ void adios2_set_selection(adios2_Variable *variable, const size_t ndims, reinterpret_cast<adios2::VariableBase *>(variable); const adios2::Dims startV(start, start + ndims); - const adios2::Dims countV(start, start + ndims); + const adios2::Dims countV(count, count + ndims); variableBase->SetSelection({startV, countV}); variableBase->CheckDimensions("in call to adios2_set_selection"); } diff --git a/bindings/fortran/CMakeLists.txt b/bindings/fortran/CMakeLists.txt index acc3f72e6a704f1b6935cf72a52db9bd95fc84dd..58a4191a4e6f7002cd119c32037cf516e8ad9914 100644 --- a/bindings/fortran/CMakeLists.txt +++ b/bindings/fortran/CMakeLists.txt @@ -25,6 +25,8 @@ set(MODULES modules/adios2_engine_mod.f90 modules/adios2_engine_write_mod.f90 modules/adios2_engine_iwrite_mod.f90 + modules/adios2_engine_read_mod.f90 + modules/adios2_engine_iread_mod.f90 ) add_library(adios2_f ${MODULES} ${F2C}) diff --git a/bindings/fortran/f2c/adios2_f2c_engine.cpp b/bindings/fortran/f2c/adios2_f2c_engine.cpp index 67cc5cd5bdc17dab4c2ba9e1d066c24878a5bb49..3a9c8108b9547309e490f0be3ac23bac2783663a 100644 --- a/bindings/fortran/f2c/adios2_f2c_engine.cpp +++ b/bindings/fortran/f2c/adios2_f2c_engine.cpp @@ -26,6 +26,7 @@ void FC_GLOBAL(adios2_begin_step_f2c, } } +// ******** PUTS */ void FC_GLOBAL(adios2_put_sync_f2c, ADIOS2_PUT_SYNC_F2C)(adios2_Engine **engine, adios2_Variable **variable, @@ -58,6 +59,67 @@ void FC_GLOBAL(adios2_put_deferred_f2c, } } +void FC_GLOBAL(adios2_perform_puts_f2c, + ADIOS2_PERFORM_PUTS_F2C)(adios2_Engine **engine, int *ierr) +{ + *ierr = 0; + try + { + adios2_perform_puts(*engine); + } + catch (std::exception &e) + { + *ierr = 1; + } +} + +// ******** GETS */ +void FC_GLOBAL(adios2_get_sync_f2c, + ADIOS2_get_SYNC_F2C)(adios2_Engine **engine, + adios2_Variable **variable, void *values, + int *ierr) +{ + *ierr = 0; + try + { + adios2_get_sync(*engine, *variable, values); + } + catch (std::exception &e) + { + *ierr = 1; + } +} + +void FC_GLOBAL(adios2_get_deferred_f2c, + ADIOS2_get_DEFERRED_F2C)(adios2_Engine **engine, + adios2_Variable **variable, + void *values, int *ierr) +{ + *ierr = 0; + try + { + adios2_get_deferred(*engine, *variable, values); + } + catch (std::exception &e) + { + *ierr = 1; + } +} + +void FC_GLOBAL(adios2_perform_gets_f2c, + ADIOS2_PERFORM_GETS_F2C)(adios2_Engine **engine, int *ierr) +{ + *ierr = 0; + try + { + adios2_perform_gets(*engine); + } + catch (std::exception &e) + { + *ierr = 1; + } +} + void FC_GLOBAL(adios2_end_step_f2c, ADIOS2_END_STEP_F2C)(adios2_Engine **engine, int *ierr) { diff --git a/bindings/fortran/f2c/adios2_f2c_engine.h b/bindings/fortran/f2c/adios2_f2c_engine.h index 0b481dbef034698404225e199d17a6d2d683f28a..bc3ee6250f2bd94f77bd66e1199a7155e9708cf1 100644 --- a/bindings/fortran/f2c/adios2_f2c_engine.h +++ b/bindings/fortran/f2c/adios2_f2c_engine.h @@ -22,6 +22,7 @@ extern "C" { void FC_GLOBAL(adios2_begin_step_f2c, ADIOS2_BEGIN_STEP_F2C)(adios2_Engine **engine, int *ierr); +// ************** PUT void FC_GLOBAL(adios2_put_sync_f2c, ADIOS2_PUT_SYNC_F2C)(adios2_Engine **engine, adios2_Variable **variable, @@ -32,6 +33,23 @@ void FC_GLOBAL(adios2_put_deferred_f2c, adios2_Variable **variable, const void *values, int *ierr); +void FC_GLOBAL(adios2_perform_puts_f2c, + ADIOS2_PERFORM_PUTS_F2C)(adios2_Engine **engine, int *ierr); + +// ************** GET +void FC_GLOBAL(adios2_get_sync_f2c, + ADIOS2_get_SYNC_F2C)(adios2_Engine **engine, + adios2_Variable **variable, void *values, + int *ierr); + +void FC_GLOBAL(adios2_get_deferred_f2c, + ADIOS2_get_DEFERRED_F2C)(adios2_Engine **engine, + adios2_Variable **variable, + void *values, int *ierr); + +void FC_GLOBAL(adios2_perform_gets_f2c, + ADIOS2_PERFORM_GETS_F2C)(adios2_Engine **engine, int *ierr); + void FC_GLOBAL(adios2_end_step_f2c, ADIOS2_END_STEP_F2C)(adios2_Engine **engine, int *ierr); diff --git a/bindings/fortran/f2c/adios2_f2c_io.cpp b/bindings/fortran/f2c/adios2_f2c_io.cpp index 615f2e2a4fb2b1884e6aa2232d2a9d4ff617cbc9..99113da382f5979ec52c035ede19b1248ca03221 100644 --- a/bindings/fortran/f2c/adios2_f2c_io.cpp +++ b/bindings/fortran/f2c/adios2_f2c_io.cpp @@ -78,7 +78,8 @@ void FC_GLOBAL(adios2_define_variable_f2c, ADIOS2_DEFINE_VARIABLE_F2C)( const int *count, const int *constant_dims, int *ierr) { auto lf_IntToSizeT = [](const int *dimensions, const int size, - std::vector<std::size_t> &output) { + std::vector<std::size_t> &output, + const bool offset) { if (dimensions == nullptr) { @@ -86,18 +87,29 @@ void FC_GLOBAL(adios2_define_variable_f2c, ADIOS2_DEFINE_VARIABLE_F2C)( } output.resize(size); - for (unsigned int d = 0; d < size; ++d) + + if (offset) + { + for (unsigned int d = 0; d < size; ++d) + { + output[d] = dimensions[d] - 1; + } + } + else { - output[d] = dimensions[d]; + for (unsigned int d = 0; d < size; ++d) + { + output[d] = dimensions[d]; + } } }; *ierr = 0; std::vector<std::size_t> shapeV, startV, countV; - lf_IntToSizeT(shape, *ndims, shapeV); - lf_IntToSizeT(start, *ndims, startV); - lf_IntToSizeT(count, *ndims, countV); + lf_IntToSizeT(shape, *ndims, shapeV, false); + lf_IntToSizeT(start, *ndims, startV, true); + lf_IntToSizeT(count, *ndims, countV, false); try { @@ -112,6 +124,27 @@ void FC_GLOBAL(adios2_define_variable_f2c, ADIOS2_DEFINE_VARIABLE_F2C)( } } +void FC_GLOBAL(adios2_inquire_variable_f2c, + ADIOS2_INQUIRE_VARIABLE_F2C)(adios2_Variable **variable, + adios2_IO **io, + const char *variable_name, + int *ierr) +{ + *ierr = 0; + try + { + *variable = adios2_inquire_variable(*io, variable_name); + if (*variable == nullptr) + { + *ierr = 2; + } + } + catch (std::exception &e) + { + *ierr = 1; + } +} + void FC_GLOBAL(adios2_open_f2c, ADIOS2_OPEN_F2C)(adios2_Engine **engine, adios2_IO **io, const char *name, const int *open_mode, diff --git a/bindings/fortran/f2c/adios2_f2c_io.h b/bindings/fortran/f2c/adios2_f2c_io.h index 0e73994df8b3b387e18fd73e994f26dd47bf6ed1..b5aa9b364549c0536fbf49721b5921f3c2c5a2ab 100644 --- a/bindings/fortran/f2c/adios2_f2c_io.h +++ b/bindings/fortran/f2c/adios2_f2c_io.h @@ -39,6 +39,12 @@ void FC_GLOBAL(adios2_define_variable_f2c, ADIOS2_DEFINE_VARIABLE_F2C)( const int *type, const int *ndims, const int *shape, const int *start, const int *count, const int *constant_dims, int *ierr); +void FC_GLOBAL(adios2_inquire_variable_f2c, + ADIOS2_INQUIRE_VARIABLE_F2C)(adios2_Variable **variable, + adios2_IO **io, + const char *variable_name, + int *ierr); + void FC_GLOBAL(adios2_open_f2c, ADIOS2_OPEN_F2C)(adios2_Engine **engine, adios2_IO **io, const char *name, const int *open_mode, diff --git a/bindings/fortran/f2c/adios2_f2c_variable.cpp b/bindings/fortran/f2c/adios2_f2c_variable.cpp index 97d44bf7915351139016d2d919548f6b594b2bf3..799f6626ad5ada4d86bdbe452d0505e969192e69 100644 --- a/bindings/fortran/f2c/adios2_f2c_variable.cpp +++ b/bindings/fortran/f2c/adios2_f2c_variable.cpp @@ -64,6 +64,33 @@ void FC_GLOBAL(adios2_set_selection_f2c, const int *ndims, const int *start, const int *count, int *ierr) { + auto lf_IntToSizeT = [](const int *dimensions, const int size, + std::vector<std::size_t> &output, + const bool offset) { + + if (dimensions == nullptr) + { + return; + } + + output.resize(size); + + if (offset) + { + for (unsigned int d = 0; d < size; ++d) + { + output[d] = dimensions[d] - 1; + } + } + else + { + for (unsigned int d = 0; d < size; ++d) + { + output[d] = dimensions[d]; + } + } + }; + *ierr = 0; if (start == nullptr || count == nullptr) { @@ -71,8 +98,9 @@ void FC_GLOBAL(adios2_set_selection_f2c, return; } - std::vector<std::size_t> startV(start, start + *ndims); - std::vector<std::size_t> countV(count, count + *ndims); + std::vector<std::size_t> startV, countV; + lf_IntToSizeT(start, *ndims, startV, true); + lf_IntToSizeT(count, *ndims, countV, false); try { diff --git a/bindings/fortran/modules/adios2_engine_iread_mod.f90 b/bindings/fortran/modules/adios2_engine_iread_mod.f90 new file mode 100644 index 0000000000000000000000000000000000000000..44ac5b5039e961df44e5b146655cdf4f916d458a --- /dev/null +++ b/bindings/fortran/modules/adios2_engine_iread_mod.f90 @@ -0,0 +1,660 @@ +! +! Distributed under the OSI-approved Apache License, Version 2.0. See +! accompanying file Copyright.txt for details. +! +! adios2_engine_iread_mod.f90 : ADIOS2 Fortran bindings for Engine generic +! deferred READ (iread) functions +! +! Created on: Aug 22, 2017 +! Author: William F Godoy godoywf@ornl.gov +! +module adios2_engine_iread + + interface adios2_iread + + ! Single Value + module procedure adios2_iread_integer + module procedure adios2_iread_real + module procedure adios2_iread_dp + module procedure adios2_iread_complex + module procedure adios2_iread_complex_dp + module procedure adios2_iread_integer1 + module procedure adios2_iread_integer2 + module procedure adios2_iread_integer8 + + ! 1D Array + module procedure adios2_iread_integer_1d + module procedure adios2_iread_real_1d + module procedure adios2_iread_dp_1d + module procedure adios2_iread_complex_1d + module procedure adios2_iread_complex_dp_1d + module procedure adios2_iread_integer1_1d + module procedure adios2_iread_integer2_1d + module procedure adios2_iread_integer8_1d + + ! 2D Array + module procedure adios2_iread_integer_2d + module procedure adios2_iread_real_2d + module procedure adios2_iread_dp_2d + module procedure adios2_iread_complex_2d + module procedure adios2_iread_complex_dp_2d + module procedure adios2_iread_integer1_2d + module procedure adios2_iread_integer2_2d + module procedure adios2_iread_integer8_2d + + ! 3D Array + module procedure adios2_iread_integer_3d + module procedure adios2_iread_real_3d + module procedure adios2_iread_dp_3d + module procedure adios2_iread_complex_3d + module procedure adios2_iread_complex_dp_3d + module procedure adios2_iread_integer1_3d + module procedure adios2_iread_integer2_3d + module procedure adios2_iread_integer8_3d + + ! 4D Array + module procedure adios2_iread_integer_4d + module procedure adios2_iread_real_4d + module procedure adios2_iread_dp_4d + module procedure adios2_iread_complex_4d + module procedure adios2_iread_complex_dp_4d + module procedure adios2_iread_integer1_4d + module procedure adios2_iread_integer2_4d + module procedure adios2_iread_integer8_4d + + ! 5D Array + module procedure adios2_iread_integer_5d + module procedure adios2_iread_real_5d + module procedure adios2_iread_dp_5d + module procedure adios2_iread_complex_5d + module procedure adios2_iread_complex_dp_5d + module procedure adios2_iread_integer1_5d + module procedure adios2_iread_integer2_5d + module procedure adios2_iread_integer8_5d + + ! 6D Array + module procedure adios2_iread_integer_6d + module procedure adios2_iread_real_6d + module procedure adios2_iread_dp_6d + module procedure adios2_iread_complex_6d + module procedure adios2_iread_complex_dp_6d + module procedure adios2_iread_integer1_6d + module procedure adios2_iread_integer2_6d + module procedure adios2_iread_integer8_6d + + end interface + +contains + + ! Single Value + subroutine adios2_iread_integer( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + + subroutine adios2_iread_integer8( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + ! 1D Array + subroutine adios2_iread_integer_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + ! 2D Array + subroutine adios2_iread_integer_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + ! 3D Array + subroutine adios2_iread_integer_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 4D Array + subroutine adios2_iread_integer_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 5D Array + subroutine adios2_iread_integer_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 6D Array + subroutine adios2_iread_integer_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_real_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_dp_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_complex_dp_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer1_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer2_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_iread_integer8_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_deferred_f2c(engine, variable, values, ierr) + + end subroutine + +end module diff --git a/bindings/fortran/modules/adios2_engine_mod.f90 b/bindings/fortran/modules/adios2_engine_mod.f90 index 3bda71211d135e5f9722c221ac480d7fe077e0d4..9ff921673598c7718859518270b0b5f4c550c282 100644 --- a/bindings/fortran/modules/adios2_engine_mod.f90 +++ b/bindings/fortran/modules/adios2_engine_mod.f90 @@ -10,10 +10,39 @@ module adios2_engine use adios2_engine_write use adios2_engine_iwrite + use adios2_engine_read + use adios2_engine_iread implicit none contains + subroutine adios2_begin_step(engine, ierr) + integer(kind=8), intent(in) :: engine + integer, intent(out) :: ierr + + call adios2_begin_step_f2c(engine, ierr) + + end subroutine + + + subroutine adios2_perform_puts(engine, ierr) + integer(kind=8), intent(in) :: engine + integer, intent(out) :: ierr + + call adios2_perform_puts_f2c(engine, ierr) + + end subroutine + + + subroutine adios2_perform_gets(engine, ierr) + integer(kind=8), intent(in) :: engine + integer, intent(out) :: ierr + + call adios2_perform_gets_f2c(engine, ierr) + + end subroutine + + subroutine adios2_end_step(engine, ierr) integer(kind=8), intent(in) :: engine integer, intent(out) :: ierr diff --git a/bindings/fortran/modules/adios2_engine_read_mod.f90 b/bindings/fortran/modules/adios2_engine_read_mod.f90 new file mode 100644 index 0000000000000000000000000000000000000000..220937e4fd9e4a39da59bd7c9331e67ff2a83a0c --- /dev/null +++ b/bindings/fortran/modules/adios2_engine_read_mod.f90 @@ -0,0 +1,660 @@ +! +! Distributed under the OSI-approved Apache License, Version 2.0. See +! accompanying file Copyright.txt for details. +! +! adios2_engine_read_mod.f90 : ADIOS2 Fortran bindings for Engine generic +! Read functions +! +! Created on: Aug 22, 2017 +! Author: William F Godoy godoywf@ornl.gov +! +module adios2_engine_read + + interface adios2_read + + ! Single Value + module procedure adios2_read_integer + module procedure adios2_read_real + module procedure adios2_read_dp + module procedure adios2_read_complex + module procedure adios2_read_complex_dp + module procedure adios2_read_integer1 + module procedure adios2_read_integer2 + module procedure adios2_read_integer8 + + ! 1D Array + module procedure adios2_read_integer_1d + module procedure adios2_read_real_1d + module procedure adios2_read_dp_1d + module procedure adios2_read_complex_1d + module procedure adios2_read_complex_dp_1d + module procedure adios2_read_integer1_1d + module procedure adios2_read_integer2_1d + module procedure adios2_read_integer8_1d + + ! 2D Array + module procedure adios2_read_integer_2d + module procedure adios2_read_real_2d + module procedure adios2_read_dp_2d + module procedure adios2_read_complex_2d + module procedure adios2_read_complex_dp_2d + module procedure adios2_read_integer1_2d + module procedure adios2_read_integer2_2d + module procedure adios2_read_integer8_2d + + ! 3D Array + module procedure adios2_read_integer_3d + module procedure adios2_read_real_3d + module procedure adios2_read_dp_3d + module procedure adios2_read_complex_3d + module procedure adios2_read_complex_dp_3d + module procedure adios2_read_integer1_3d + module procedure adios2_read_integer2_3d + module procedure adios2_read_integer8_3d + + ! 4D Array + module procedure adios2_read_integer_4d + module procedure adios2_read_real_4d + module procedure adios2_read_dp_4d + module procedure adios2_read_complex_4d + module procedure adios2_read_complex_dp_4d + module procedure adios2_read_integer1_4d + module procedure adios2_read_integer2_4d + module procedure adios2_read_integer8_4d + + ! 5D Array + module procedure adios2_read_integer_5d + module procedure adios2_read_real_5d + module procedure adios2_read_dp_5d + module procedure adios2_read_complex_5d + module procedure adios2_read_complex_dp_5d + module procedure adios2_read_integer1_5d + module procedure adios2_read_integer2_5d + module procedure adios2_read_integer8_5d + + ! 6D Array + module procedure adios2_read_integer_6d + module procedure adios2_read_real_6d + module procedure adios2_read_dp_6d + module procedure adios2_read_complex_6d + module procedure adios2_read_complex_dp_6d + module procedure adios2_read_integer1_6d + module procedure adios2_read_integer2_6d + module procedure adios2_read_integer8_6d + + end interface + +contains + + ! Single Value + subroutine adios2_read_integer( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + + subroutine adios2_read_integer8( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + ! 1D Array + subroutine adios2_read_integer_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_1d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + ! 2D Array + subroutine adios2_read_integer_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_2d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + ! 3D Array + subroutine adios2_read_integer_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_3d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 4D Array + subroutine adios2_read_integer_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_4d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 5D Array + subroutine adios2_read_integer_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_5d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + + ! 6D Array + subroutine adios2_read_integer_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_real_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_dp_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + real(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex, dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_complex_dp_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + complex(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer1_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=1), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer2_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=2), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + + subroutine adios2_read_integer8_6d( engine, variable, values, ierr ) + integer(kind=8), intent(in):: engine + integer(kind=8), intent(in):: variable + integer(kind=8), dimension(:,:,:,:,:,:), intent(out):: values + integer, intent(out):: ierr + + call adios2_get_sync_f2c(engine, variable, values, ierr) + + end subroutine + +end module diff --git a/bindings/fortran/modules/adios2_io_mod.f90 b/bindings/fortran/modules/adios2_io_mod.f90 index a0a1169fd9714a19e9e092cde2b68be5fbdac5e7..8ac098bd8b04a6100c95ecde7c1d76005ab6fee2 100644 --- a/bindings/fortran/modules/adios2_io_mod.f90 +++ b/bindings/fortran/modules/adios2_io_mod.f90 @@ -80,4 +80,16 @@ contains end subroutine + subroutine adios2_inquire_variable(variable, io, variable_name, ierr) + integer(kind=8), intent(out) :: variable + integer(kind=8), intent(in) :: io + character*(*), intent(in) :: variable_name + integer, intent(out) :: ierr + + call adios2_inquire_variable_f2c(variable, io, & + & TRIM(ADJUSTL(variable_name))//char(0), ierr) + + end subroutine + + end module diff --git a/bindings/fortran/modules/adios2_parameters_mod.f90 b/bindings/fortran/modules/adios2_parameters_mod.f90 index 44290156424d23844046e1c0576aadfaf1f1a8cd..997ba65b56fb84c9e6a864bb654151eda0ab833b 100644 --- a/bindings/fortran/modules/adios2_parameters_mod.f90 +++ b/bindings/fortran/modules/adios2_parameters_mod.f90 @@ -35,6 +35,10 @@ module adios2_parameters logical, parameter :: adios2_constant_dims_true = .true. logical, parameter :: adios2_constant_dims_false = .false. + ! Found or not found, ierr value + integer, parameter :: adios2_found = 0 + integer, parameter :: adios2_not_found = 2 + ! Mode integer, parameter :: adios2_mode_undefined = 0 integer, parameter :: adios2_mode_write = 1 diff --git a/bindings/python/EnginePy.cpp b/bindings/python/EnginePy.cpp index a3e7b11800e13497b14894064af80282e033a6b8..3120be8a4f2445a43aa5112106494056bdc23340 100644 --- a/bindings/python/EnginePy.cpp +++ b/bindings/python/EnginePy.cpp @@ -5,7 +5,7 @@ * EnginePy.cpp * * Created on: Mar 15, 2017 - * Author: wgodoy + * Author: William F Godoy godoywf@ornl.gov */ #include "EnginePy.h" @@ -25,35 +25,12 @@ EnginePy::EnginePy(IO &io, const std::string &name, const Mode openMode, { } +void EnginePy::BeginStep() { m_Engine.BeginStep(); } + void EnginePy::PutSync(VariableBase *variable, const pybind11::array &array) { - if (variable->m_Type.empty()) // Define in IO - { - auto &io = m_Engine.GetIO(); + DefineInIO(variable, array); - if (array.is(pybind11::array())) - { - if (m_DebugMode) - { - throw std::invalid_argument( - "ERROR: passing an empty numpy array for variable " + - variable->m_Name + ", in call to PutSync"); - } - } -#define declare_type(T) \ - else if (pybind11::isinstance< \ - pybind11::array_t<T, pybind11::array::c_style>>(array)) \ - { \ - variable = &io.DefineVariable<T>(variable->m_Name, variable->m_Shape, \ - variable->m_Start, variable->m_Count, \ - variable->m_ConstantDims); \ - m_VariablesPlaceholder.erase(variable->m_Name); \ - } - ADIOS2_FOREACH_NUMPY_TYPE_1ARG(declare_type) -#undef declare_type - } - - // PutSync if (variable->m_Type == "compound") { // not supported @@ -80,10 +57,143 @@ void EnginePy::PutSync(VariableBase *variable, const pybind11::array &array) void EnginePy::PutSync(VariableBase *variable, const std::string &string) { + DefineInIO(variable, string); m_Engine.PutSync(*dynamic_cast<adios2::Variable<std::string> *>(variable), string); } +void EnginePy::PutDeferred(VariableBase *variable, const pybind11::array &array) +{ + DefineInIO(variable, array); + + if (variable->m_Type == "compound") + { + // not supported + } +#define declare_type(T) \ + else if (variable->m_Type == GetType<T>()) \ + { \ + m_Engine.PutDeferred(*dynamic_cast<adios2::Variable<T> *>(variable), \ + reinterpret_cast<const T *>(array.data())); \ + } + ADIOS2_FOREACH_NUMPY_TYPE_1ARG(declare_type) +#undef declare_type + else + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: variable " + variable->m_Name + + " numpy array type is not supported or " + "is not memory contiguous " + ", in call to PutDeferred\n"); + } + } +} + +void EnginePy::PutDeferred(VariableBase *variable, const std::string &string) +{ + DefineInIO(variable, string); + m_Engine.PutDeferred( + *dynamic_cast<adios2::Variable<std::string> *>(variable), string); +} + +void EnginePy::PerformPuts() { m_Engine.PerformPuts(); } + +void EnginePy::GetSync(VariableBase *variable, pybind11::array &array) +{ + if (variable->m_Type == "compound") + { + // not supported + } +#define declare_type(T) \ + else if (variable->m_Type == GetType<T>()) \ + { \ + m_Engine.GetSync( \ + *dynamic_cast<adios2::Variable<T> *>(variable), \ + reinterpret_cast<T *>(const_cast<void *>(array.data()))); \ + } + ADIOS2_FOREACH_NUMPY_TYPE_1ARG(declare_type) +#undef declare_type + else + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: in variable " + variable->m_Name + " of type " + + variable->m_Type + + ", numpy array type is 1) not supported, 2) a type mismatch or" + "3) is not memory contiguous " + ", in call to GetSync\n"); + } + } +} + +void EnginePy::GetSync(VariableBase *variable, std::string &string) +{ + if (variable->m_Type == GetType<std::string>()) + { + m_Engine.GetSync( + *dynamic_cast<adios2::Variable<std::string> *>(variable), string); + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: variable " + variable->m_Name + + " of type " + variable->m_Type + + " is not string, in call to GetSync"); + } + } +} + +void EnginePy::GetDeferred(VariableBase *variable, pybind11::array &array) +{ + if (variable->m_Type == "compound") + { + // not supported + } +#define declare_type(T) \ + else if (variable->m_Type == GetType<T>()) \ + { \ + m_Engine.GetDeferred( \ + *dynamic_cast<adios2::Variable<T> *>(variable), \ + reinterpret_cast<T *>(const_cast<void *>(array.data()))); \ + } + ADIOS2_FOREACH_NUMPY_TYPE_1ARG(declare_type) +#undef declare_type + else + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: in variable " + variable->m_Name + " of type " + + variable->m_Type + + ", numpy array type is 1) not supported, 2) a type mismatch or" + "3) is not memory contiguous " + ", in call to GetSync\n"); + } + } +} + +void EnginePy::GetDeferred(VariableBase *variable, std::string &string) +{ + if (variable->m_Type == GetType<std::string>()) + { + m_Engine.GetDeferred( + *dynamic_cast<adios2::Variable<std::string> *>(variable), string); + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: variable " + variable->m_Name + " of type " + + variable->m_Type + " is not string, in call to GetDeferred"); + } + } +} +void EnginePy::PerformGets() { m_Engine.PerformGets(); } + void EnginePy::EndStep() { m_Engine.EndStep(); } void EnginePy::Close(const int transportIndex) @@ -91,4 +201,46 @@ void EnginePy::Close(const int transportIndex) m_Engine.Close(transportIndex); } +// PRIVATE +void EnginePy::DefineInIO(VariableBase *variable, const pybind11::array &array) +{ + if (variable->m_Type.empty()) // Define in IO + { + auto &io = m_Engine.GetIO(); + + if (array.is(pybind11::array())) + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: passing an empty numpy array for variable " + + variable->m_Name + ", in call to Put/Get"); + } + } +#define declare_type(T) \ + else if (pybind11::isinstance< \ + pybind11::array_t<T, pybind11::array::c_style>>(array)) \ + { \ + variable = &io.DefineVariable<T>(variable->m_Name, variable->m_Shape, \ + variable->m_Start, variable->m_Count, \ + variable->m_ConstantDims); \ + m_VariablesPlaceholder.erase(variable->m_Name); \ + } + ADIOS2_FOREACH_NUMPY_TYPE_1ARG(declare_type) +#undef declare_type + } +} + +void EnginePy::DefineInIO(VariableBase *variable, const std::string &string) +{ + if (variable->m_Type.empty()) // Define in IO + { + auto &io = m_Engine.GetIO(); + variable = &io.DefineVariable<std::string>( + variable->m_Name, variable->m_Shape, variable->m_Start, + variable->m_Count, variable->m_ConstantDims); + m_VariablesPlaceholder.erase(variable->m_Name); + } +} + } // end namespace adios2 diff --git a/bindings/python/EnginePy.h b/bindings/python/EnginePy.h index e4b426345c488a559113ed1991178138999c836c..7ef45d27fdcaa1867dd651abdcba9fa4039e4ddf 100644 --- a/bindings/python/EnginePy.h +++ b/bindings/python/EnginePy.h @@ -32,9 +32,24 @@ public: ~EnginePy() = default; + void BeginStep(); + void PutSync(VariableBase *variable, const pybind11::array &array); void PutSync(VariableBase *variable, const std::string &string); + void PutDeferred(VariableBase *variable, const pybind11::array &array); + void PutDeferred(VariableBase *variable, const std::string &string); + + void PerformPuts(); + + void GetSync(VariableBase *variable, pybind11::array &array); + void GetSync(VariableBase *variable, std::string &string); + + void GetDeferred(VariableBase *variable, pybind11::array &array); + void GetDeferred(VariableBase *variable, std::string &string); + + void PerformGets(); + void EndStep(); void Close(const int transportIndex = -1); @@ -43,6 +58,9 @@ private: Engine &m_Engine; std::map<std::string, VariableBase> &m_VariablesPlaceholder; const bool m_DebugMode; + + void DefineInIO(VariableBase *variable, const pybind11::array &array); + void DefineInIO(VariableBase *variable, const std::string &string); }; } // end namespace adios2 diff --git a/bindings/python/gluePyBind11.cpp b/bindings/python/gluePyBind11.cpp index ec8b28731a4f1ed5d13c291b8fccbbe423a08ef7..374b72a11313a8289d6215a0943a4164186b28cc 100644 --- a/bindings/python/gluePyBind11.cpp +++ b/bindings/python/gluePyBind11.cpp @@ -134,7 +134,8 @@ PYBIND11_MODULE(adios2, m) .def("DeclareIO", &adios2::ADIOSPy::DeclareIO); pybind11::class_<adios2::VariableBase>(m, "Variable") - .def("SetSelection", &adios2::VariableBase::SetSelection); + .def("SetSelection", &adios2::VariableBase::SetSelection) + .def("SelectionSize", &adios2::VariableBase::SelectionSize); pybind11::class_<adios2::IOPy>(m, "IOPy") .def("SetEngine", &adios2::IOPy::SetEngine) @@ -158,12 +159,34 @@ PYBIND11_MODULE(adios2, m) adios2::IOPy::Open); pybind11::class_<adios2::EnginePy>(m, "EnginePy") + .def("BeginStep", &adios2::EnginePy::BeginStep) .def("PutSync", (void (adios2::EnginePy::*)(adios2::VariableBase *, const pybind11::array &)) & adios2::EnginePy::PutSync) .def("PutSync", (void (adios2::EnginePy::*)(adios2::VariableBase *, const std::string &)) & adios2::EnginePy::PutSync) + .def("PutDeferred", + (void (adios2::EnginePy::*)(adios2::VariableBase *, + const pybind11::array &)) & + adios2::EnginePy::PutDeferred) + .def("PutDeferred", (void (adios2::EnginePy::*)(adios2::VariableBase *, + const std::string &)) & + adios2::EnginePy::PutDeferred) + .def("PerformPuts", &adios2::EnginePy::PerformPuts) + .def("GetSync", (void (adios2::EnginePy::*)(adios2::VariableBase *, + pybind11::array &)) & + adios2::EnginePy::GetSync) + .def("GetSync", (void (adios2::EnginePy::*)(adios2::VariableBase *, + std::string &)) & + adios2::EnginePy::GetSync) + .def("GetDeferred", (void (adios2::EnginePy::*)(adios2::VariableBase *, + pybind11::array &)) & + adios2::EnginePy::GetDeferred) + .def("GetDeferred", (void (adios2::EnginePy::*)(adios2::VariableBase *, + std::string &)) & + adios2::EnginePy::GetDeferred) + .def("PerformGets", &adios2::EnginePy::PerformGets) .def("EndStep", &adios2::EnginePy::EndStep) .def("Close", &adios2::EnginePy::Close, pybind11::arg("transportIndex") = -1); diff --git a/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp b/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp index 1085571c40fb0f0b4f5b7e60a88d044bd4a47bb4..d41d039c1a49b42717022192ce3d46db0078c2bc 100644 --- a/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp +++ b/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp @@ -2,17 +2,21 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloBPReaderHeatMap.cpp : Writes a heat map in a regular 2D mesh, + * helloBPReaderHeatMap3D.cpp : Writes a heat map in a regular 3D mesh, * values grow from 0 in increments of 1 * - * temperature[gNx, Ny] + * temperature[gNx, Ny, Nz] * where: gNx = MPI_size_x * Nx * - * 0 1 2 ... Ny-1 - * Ny Ny+1 Ny+2 ... 2*Ny-1 + * k Map: + * k= Nz-1 . . . . + * k=1 . . . . + * k=0 . . . . + * 0 1 2 ... Nz-1 + * Nz Nz+1 Nz+2 ... 2*Nz-1 * ... * ... - * (gNx-1)*Ny ... gNx*Ny-1 + *(Ny-1)*Nz ... Ny*Nz-1 * * * Created on: Nov 1, 2017 @@ -73,7 +77,7 @@ int main(int argc, char *argv[]) // ************************** WRITE /*** IO class object: settings and factory of Settings: Variables, * Parameters, Transports, and Execution: Engines */ - adios2::IO &putHeatMap = adios.DeclareIO("HeatMapWriter"); + adios2::IO &putHeatMap = adios.DeclareIO("HeatMapWrite"); adios2::Variable<unsigned int> &outTemperature = putHeatMap.DefineVariable<unsigned int>( @@ -89,7 +93,7 @@ int main(int argc, char *argv[]) // ************************** READ if (rank == 0) { - adios2::IO &getHeatMap = adios.DeclareIO("HeatMapReader"); + adios2::IO &getHeatMap = adios.DeclareIO("HeatMapRead"); adios2::Engine &bpReader = getHeatMap.Open("HeatMap3D.bp", adios2::Mode::Read); @@ -107,7 +111,8 @@ int main(int argc, char *argv[]) bpReader.GetSync(*inTemperature, inTemperatures.data()); - std::cout << "Incoming temperature map:\n"; + std::cout << "Temperature map selection: "; + std::cout << "{ start = [2,2,2], count = [4,4,4] }\n"; for (auto i = 0; i < inTemperatures.size(); ++i) { diff --git a/examples/hello/bpReader/helloBPReaderHeatMap3D.f90 b/examples/hello/bpReader/helloBPReaderHeatMap3D.f90 index 1f79e7fcd3aded1d28a89878f0773915b67a2afd..89805866bb9d83d6b2079890d07fa73aec7da020 100644 --- a/examples/hello/bpReader/helloBPReaderHeatMap3D.f90 +++ b/examples/hello/bpReader/helloBPReaderHeatMap3D.f90 @@ -4,11 +4,14 @@ program helloBPReaderHeatMap3D implicit none - integer(kind=8) :: adios, io, var_temperatures, engine - integer, dimension(:,:,:), allocatable :: temperatures + integer(kind=8) :: adios + integer(kind=8) :: ioPut, var_temperatures, bpWriter + integer(kind=8) :: ioGet, var_temperaturesIn, bpReader + integer, dimension(:,:,:), allocatable :: temperatures, sel_temperatures integer, dimension(3) :: ishape, istart, icount + integer, dimension(3) :: sel_start, sel_count integer :: ierr, irank, isize, inx, iny, inz - integer :: i, j, k, iglobal, value, ilinear + integer :: i, j, k, iglobal, value, ilinear, icounter call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, irank, ierr) @@ -18,17 +21,17 @@ program helloBPReaderHeatMap3D iny = 10 inz = 10 - icount = (/ inx, iny, inz /) - istart = (/ irank * inx, 1, 1 /) - ishape = (/ isize * inx, iny, inz /) + icount = (/ inx, iny, inz /) + istart = (/ irank * inx+1, 1, 1 /) + ishape = (/ isize * inx, iny, inz /) allocate( temperatures( inx, iny, inz ) ) ! populate temperature do k=1, icount(3) do j=1, icount(2) do i=1, icount(1) - iglobal = istart(1) + i - value = k * ishape(2) * ishape(1) + j * ishape(1) + & + iglobal = istart(1) + (i-1)-1 + value = (k-1) * ishape(1) * ishape(2) + (j-1) * ishape(1) + & & iglobal temperatures(i,j,k) = value end do @@ -37,23 +40,65 @@ program helloBPReaderHeatMap3D ! Start adios2 Writer call adios2_init( adios, MPI_COMM_WORLD, adios2_debug_mode_on, ierr ) - call adios2_declare_io( io, adios, "bpFileIO", ierr ) + call adios2_declare_io( ioPut, adios, 'HeatMapWrite', ierr ) - call adios2_define_variable( var_temperatures, io, "temperatures", & + call adios2_define_variable( var_temperatures, ioPut, 'temperatures', & & adios2_type_integer, 3, ishape, istart, icount, & & adios2_constant_dims_true, ierr ) - call adios2_open( engine, io, "HeatMap3D_f.bp", adios2_mode_write, ierr ) + call adios2_open( bpWriter, ioPut, 'HeatMap3D_f.bp', & + & adios2_mode_write, ierr ) - call adios2_write( engine, var_temperatures, temperatures, ierr ) + call adios2_write( bpWriter, var_temperatures, temperatures, ierr ) - call adios2_close( engine, ierr ) + call adios2_close( bpWriter, ierr ) if( allocated(temperatures) ) deallocate(temperatures) - ! Start adios2 Reader + ! Start adios2 Reader in rank 0 + if( irank == 0 ) then + call adios2_declare_io( ioGet, adios, 'HeatMapRead', ierr ) + call adios2_open( bpReader, ioGet, 'HeatMap3D_f.bp', & + & adios2_mode_read, ierr) + + call adios2_inquire_variable( var_temperaturesIn, ioGet, & + & 'temperatures', ierr ) + + if( ierr == adios2_found ) then + + sel_start = (/ 3, 3, 3 /) + sel_count = (/ 4, 4, 4 /) + allocate( sel_temperatures( sel_count(1), sel_count(2), & + & sel_count(3) ) ) + + call adios2_set_selection( var_temperaturesIn, 3, sel_start, & + & sel_count, ierr ) + + call adios2_read( bpReader, var_temperaturesIn, sel_temperatures, & + & ierr ) + + write(*,'(A,3(I1,A),A,3(I1,A),A)') 'Temperature map selection & + & [ start = (', (sel_start(i),',',i=1,3) , ') & + & count = (', (sel_count(i),',',i=1,3) , ') ]' + + + do k=1,sel_count(3) + do j=1,sel_count(2) + do i=1,sel_count(1) + write(6,'(I4) ', advance="no") sel_temperatures(i,j,k) + end do + write(*,*) + end do + end do + + + if( allocated(sel_temperatures) ) deallocate(sel_temperatures) + + end if + + end if end program helloBPReaderHeatMap3D diff --git a/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp b/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp index 6f485e1606291cec97678a19efa80c14c5c8f8ad..6ab37a388f24beb17266d3828f77a1df4a906028 100644 --- a/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp +++ b/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp @@ -36,69 +36,109 @@ int main(int argc, char *argv[]) * recommended */ adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON); - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N"); - bpIO.SetParameters({{"Threads", "2"}}); + /// WRITE + { + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N"); + bpIO.SetParameters({{"Threads", "2"}}); - /** global array: name, { shape (total dimensions) }, { start - * (local) }, - * { count (local) }, all are constant dimensions */ - const unsigned int variablesSize = 1; - std::vector<adios2::Variable<float> *> bpFloats(variablesSize); + /** global array: name, { shape (total dimensions) }, { start + * (local) }, + * { count (local) }, all are constant dimensions */ + const unsigned int variablesSize = 1; + std::vector<adios2::Variable<float> *> bpFloats(variablesSize); - adios2::Variable<std::string> &bpString = - bpIO.DefineVariable<std::string>("bpString"); + adios2::Variable<std::string> &bpString = + bpIO.DefineVariable<std::string>("bpString"); - for (unsigned int v = 0; v < variablesSize; ++v) - { - std::string namev("bpFloats"); - if (v < 10) + for (unsigned int v = 0; v < variablesSize; ++v) { - namev += "00"; + std::string namev("bpFloats"); + if (v < 10) + { + namev += "00"; + } + else if (v < 100) + { + namev += "0"; + } + namev += std::to_string(v); + + bpFloats[v] = + &bpIO.DefineVariable<float>(namev, {size * Nx}, {rank * Nx}, + {Nx}, adios2::ConstantDims); } - else if (v < 100) + + /** global single value variable: name */ + adios2::Variable<unsigned int> &bpTimeStep = + bpIO.DefineVariable<unsigned int>("timeStep"); + + /** Engine derived class, spawned to start IO operations */ + adios2::Engine &bpWriter = + bpIO.Open("myVector.bp", adios2::Mode::Write); + + for (unsigned int timeStep = 0; timeStep < 3; ++timeStep) { - namev += "0"; + // bpWriter.BeginStep(); + if (rank == 0) // global single value, only saved by rank 0 + { + bpWriter.PutSync<unsigned int>(bpTimeStep, timeStep); + } + + // template type is optional, but recommended + for (unsigned int v = 0; v < variablesSize; ++v) + { + myFloats[0] = static_cast<float>(v + timeStep); + bpWriter.PutSync(*bpFloats[v], myFloats.data()); + } + const std::string myString( + "Hello from rank: " + std::to_string(rank) + + " and timestep: " + std::to_string(timeStep)); + + bpWriter.PutSync(bpString, myString); + + bpWriter.EndStep(); } - namev += std::to_string(v); - bpFloats[v] = &bpIO.DefineVariable<float>( - namev, {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + bpWriter.Close(); } + MPI_Barrier(MPI_COMM_WORLD); - /** global single value variable: name */ - adios2::Variable<unsigned int> &bpTimeStep = - bpIO.DefineVariable<unsigned int>("timeStep"); + { /////////////////////READ + // if (rank == 0) + // { + adios2::IO &ioReader = adios.DeclareIO("bpReader"); - /** Engine derived class, spawned to start IO operations */ - adios2::Engine &bpWriter = - bpIO.Open("myVector.bp", adios2::Mode::Write); + adios2::Engine &bpReader = + ioReader.Open("myVector.bp", adios2::Mode::Read); - for (unsigned int timeStep = 0; timeStep < 3; ++timeStep) - { - // bpWriter.BeginStep(); - if (rank == 0) // global single value, only saved by rank 0 + adios2::Variable<float> *bpFloats000 = + ioReader.InquireVariable<float>("bpFloats000"); + + if (bpFloats000 != nullptr) { - bpWriter.PutSync<unsigned int>(bpTimeStep, timeStep); + bpFloats000->SetSelection({{rank * Nx}, {Nx}}); + bpFloats000->SetStepSelection({3, 1}); + + std::vector<float> data(bpFloats000->SelectionSize()); + bpReader.GetSync(*bpFloats000, data.data()); + + std::cout << "Data timestep " << bpFloats000->m_StepsStart + << " from rank " << rank << "\n"; + for (const auto datum : data) + { + std::cout << datum << " "; + } + std::cout << "\n"; } - - // template type is optional, but recommended - for (unsigned int v = 0; v < variablesSize; ++v) + else { - myFloats[0] = static_cast<float>(v + timeStep); - bpWriter.PutSync(*bpFloats[v], myFloats.data()); + std::cout << "Variable bpFloats000 not found\n"; } - const std::string myString( - "Hello from rank: " + std::to_string(rank) + " and timestep: " + - std::to_string(timeStep)); - - bpWriter.PutSync(bpString, myString); - - bpWriter.EndStep(); + bpReader.Close(); + //} } - - bpWriter.Close(); } catch (std::invalid_argument &e) { diff --git a/source/adios2/ADIOSMacros.h b/source/adios2/ADIOSMacros.h index d95c2fab7c50a05c161641cd119e2e4435510fac..0d002d332d5702a107da96a6d8ef614193adf03c 100644 --- a/source/adios2/ADIOSMacros.h +++ b/source/adios2/ADIOSMacros.h @@ -70,6 +70,27 @@ MACRO(std::complex<double>) \ MACRO(std::complex<long double>) +#define ADIOS2_FOREACH_CHAR_TYPE_1ARG(MACRO) \ + MACRO(char) \ + MACRO(signed char) \ + MACRO(unsigned char) + +#define ADIOS2_FOREACH_NUMERIC_TYPE_1ARG(MACRO) \ + MACRO(short) \ + MACRO(unsigned short) \ + MACRO(int) \ + MACRO(unsigned int) \ + MACRO(long int) \ + MACRO(long long int) \ + MACRO(unsigned long int) \ + MACRO(unsigned long long int) \ + MACRO(float) \ + MACRO(double) \ + MACRO(long double) \ + MACRO(std::complex<float>) \ + MACRO(std::complex<double>) \ + MACRO(std::complex<long double>) + #define ADIOS2_FOREACH_ZFP_TYPE_1ARG(MACRO) \ MACRO(int32_t) \ MACRO(int64_t) \ diff --git a/source/adios2/core/ADIOS.h b/source/adios2/core/ADIOS.h index 0b00c1da889334b34e0557ee662465fcd81a1795..dc093d31f1696f68d35bfbcde6f239a4f589b59b 100644 --- a/source/adios2/core/ADIOS.h +++ b/source/adios2/core/ADIOS.h @@ -2,8 +2,7 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * ADIOS.h : ADIOS library starting point, factory class for IO and - * (polymorphic) Engines + * ADIOS.h : ADIOS library starting point, factory class for IO objects * Created on: Oct 3, 2016 * Author: William F Godoy godoywf@ornl.gov */ @@ -107,11 +106,18 @@ public: * @param name must be unique for each operator created with DefineOperator * @param type from derived class * @param parameters optional parameters - * @return + * @return reference to Operator object */ Operator &DefineOperator(const std::string name, const std::string type, const Params ¶meters = Params()); + /** + * Signature for passing Callback functions as operators + * @param name unique operator name + * @param function callable function + * @param parameters + * @return reference to Operator object + */ template <class R, class... Args> Operator &DefineOperator(const std::string name, const std::function<R(Args...)> &function, diff --git a/source/adios2/core/IO.cpp b/source/adios2/core/IO.cpp index f780868b54439aa4e510524fadab13ceb43ce985..b4b0abf4537989875dee1ecc43a1a09b8b79fb8f 100644 --- a/source/adios2/core/IO.cpp +++ b/source/adios2/core/IO.cpp @@ -173,6 +173,26 @@ std::map<std::string, Params> IO::GetAvailableVariables() noexcept if (type == "compound") { } +// TODO : enable string, add dimensions +#define declare_template_instantiation(C) \ + else if (type == GetType<C>()) \ + { \ + Variable<C> &variable = *InquireVariable<C>(name); \ + \ + const int min = static_cast<int>(variable.m_Min); \ + variablesInfo[name]["Min"] = std::to_string(min); \ + \ + const int max = static_cast<int>(variable.m_Max); \ + variablesInfo[name]["Max"] = std::to_string(max); \ + \ + variablesInfo[name]["StepsStart"] = \ + std::to_string(variable.m_AvailableStepsStart); \ + variablesInfo[name]["StepsCount"] = \ + std::to_string(variable.m_AvailableStepsCount); \ + } + ADIOS2_FOREACH_CHAR_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + #define declare_template_instantiation(T) \ else if (type == GetType<T>()) \ { \ @@ -188,10 +208,10 @@ std::map<std::string, Params> IO::GetAvailableVariables() noexcept variablesInfo[name]["StepsCount"] = \ std::to_string(variable.m_AvailableStepsCount); \ } - ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) + ADIOS2_FOREACH_NUMERIC_TYPE_1ARG(declare_template_instantiation) #undef declare_template_instantiation } - // TODO: add dimensions + return variablesInfo; } diff --git a/source/adios2/engine/bp/BPFileReader.cpp b/source/adios2/engine/bp/BPFileReader.cpp index 207505d2932e2a10414e62e048c1c45a285cc94e..6900ccd06eda7f8a30d78db3da3b290c4d30401d 100644 --- a/source/adios2/engine/bp/BPFileReader.cpp +++ b/source/adios2/engine/bp/BPFileReader.cpp @@ -8,6 +8,8 @@ * Author: William F Godoy godoywf@ornl.gov */ +#include <iostream> //TODO will go away + #include "BPFileReader.h" #include "BPFileReader.tcc" @@ -27,8 +29,9 @@ BPFileReader::BPFileReader(IO &io, const std::string &name, const Mode mode, void BPFileReader::PerformGets() { - const auto variablesSubFileInfo = + const std::map<std::string, SubFileInfoMap> variablesSubfileInfo = m_BP3Deserializer.PerformGetsVariablesSubFileInfo(m_IO); + ReadVariables(m_IO, variablesSubfileInfo); } void BPFileReader::Close(const int transportIndex) @@ -89,8 +92,7 @@ void BPFileReader::InitBuffer() fileSize); } // broadcast buffer to all ranks from zero - m_BP3Deserializer.m_Metadata.m_Buffer = - BroadcastVector(m_BP3Deserializer.m_Metadata.m_Buffer, m_MPIComm); + BroadcastVector(m_BP3Deserializer.m_Metadata.m_Buffer, m_MPIComm); // fills IO with Variables and Attributes m_BP3Deserializer.ParseMetadata(m_IO); @@ -127,13 +129,14 @@ void BPFileReader::ReadVariables( for (const auto &subFileIndexPair : variableNamePair.second) { const size_t subFileIndex = subFileIndexPair.first; - const std::string subFile( - m_BP3Deserializer.GetBPSubFileName(m_Name, subFileIndex)); if (m_SubFileManager.m_Transports.count(subFileIndex) == 0) { - m_SubFileManager.OpenFiles({subFile}, adios2::Mode::Read, - {{{"transport", "File"}}}, profile); + const std::string subFile( + m_BP3Deserializer.GetBPSubFileName(m_Name, subFileIndex)); + + m_SubFileManager.OpenFileID(subFile, subFileIndex, Mode::Read, + {{"transport", "File"}}, profile); } for (const auto &stepPair : subFileIndexPair.second) // step diff --git a/source/adios2/helper/adiosMPIFunctions.h b/source/adios2/helper/adiosMPIFunctions.h index 0e4ebe68b7905707e190bcf33e82d5cd94f7b194..81a5562f6b42d6f050acdfdc0008056b838695b4 100644 --- a/source/adios2/helper/adiosMPIFunctions.h +++ b/source/adios2/helper/adiosMPIFunctions.h @@ -25,8 +25,8 @@ template <class T> T BroadcastValue(const T &input, MPI_Comm mpiComm, const int rankSource = 0); template <class T> -std::vector<T> BroadcastVector(const std::vector<T> &input, MPI_Comm mpiComm, - const int rankSource = 0); +void BroadcastVector(std::vector<T> &vector, MPI_Comm mpiComm, + const int rankSource = 0); template <class T> T ReduceValues(const T source, MPI_Comm mpiComm, MPI_Op operation = MPI_SUM, diff --git a/source/adios2/helper/adiosMPIFunctions.tcc b/source/adios2/helper/adiosMPIFunctions.tcc index a312d13335e80ec7267475bc5342e4eda9cc01ae..6bbf28df0886e482f01915d35d57fab9ea276a1a 100644 --- a/source/adios2/helper/adiosMPIFunctions.tcc +++ b/source/adios2/helper/adiosMPIFunctions.tcc @@ -105,56 +105,29 @@ unsigned long long int ReduceValues(const unsigned long long int source, // BroadcastVector specializations template <> -std::vector<char> BroadcastVector(const std::vector<char> &input, - MPI_Comm mpiComm, const int rankSource) +void BroadcastVector(std::vector<char> &vector, MPI_Comm mpiComm, + const int rankSource) { - // First Broadcast the size, then the contents - size_t inputSize = BroadcastValue(input.size(), mpiComm, rankSource); - int rank; - MPI_Comm_rank(mpiComm, &rank); - std::vector<char> output; + int size; + MPI_Comm_size(mpiComm, &size); - if (rank == rankSource) + if (size == 1) { - MPI_Bcast(const_cast<char *>(input.data()), static_cast<int>(inputSize), - MPI_CHAR, rankSource, mpiComm); - return input; // no copy - } - else - { - output.resize(inputSize); - MPI_Bcast(output.data(), static_cast<int>(inputSize), MPI_CHAR, - rankSource, mpiComm); + return; } - return output; -} - -template <> -std::vector<size_t> BroadcastVector(const std::vector<size_t> &input, - MPI_Comm mpiComm, const int rankSource) -{ // First Broadcast the size, then the contents - size_t inputSize = BroadcastValue(input.size(), mpiComm, rankSource); + size_t inputSize = BroadcastValue(vector.size(), mpiComm, rankSource); int rank; MPI_Comm_rank(mpiComm, &rank); - std::vector<size_t> output; - if (rank == rankSource) + if (rank != rankSource) { - MPI_Bcast(const_cast<size_t *>(input.data()), - static_cast<int>(inputSize), ADIOS2_MPI_SIZE_T, rankSource, - mpiComm); - return input; // no copy in rankSource - } - else - { - output.resize(inputSize); - MPI_Bcast(output.data(), static_cast<int>(inputSize), ADIOS2_MPI_SIZE_T, - rankSource, mpiComm); + vector.resize(inputSize); } - return output; + MPI_Bcast(vector.data(), static_cast<int>(inputSize), MPI_CHAR, rankSource, + mpiComm); } // GatherArrays specializations diff --git a/source/adios2/helper/adiosMath.cpp b/source/adios2/helper/adiosMath.cpp index 5ee06cd03ec323d8c26e2273faf260409e055e5e..79c3a2bdbc5b9e7aa84d008764c95dc0bca37aba 100644 --- a/source/adios2/helper/adiosMath.cpp +++ b/source/adios2/helper/adiosMath.cpp @@ -135,10 +135,10 @@ Box<Dims> IntersectionBox(const Box<Dims> &box1, const Box<Dims> &box2) noexcept } size_t LinearIndex(const Box<Dims> &localBox, const Dims &point, - const bool isRowMajor, const bool isZeroIndex) noexcept + const bool isRowMajor) noexcept { - auto lf_RowZero = [](const Dims &count, - const Dims &normalizedPoint) -> size_t { + auto lf_RowMajor = [](const Dims &count, + const Dims &normalizedPoint) -> size_t { const size_t countSize = count.size(); size_t linearIndex = 0; @@ -154,8 +154,8 @@ size_t LinearIndex(const Box<Dims> &localBox, const Dims &point, return linearIndex; }; - auto lf_ColumnOne = [](const Dims &count, - const Dims &normalizedPoint) -> size_t { + auto lf_ColumnMajor = [](const Dims &count, + const Dims &normalizedPoint) -> size_t { const size_t countSize = count.size(); size_t linearIndex = 0; @@ -164,10 +164,10 @@ size_t LinearIndex(const Box<Dims> &localBox, const Dims &point, for (size_t p = 1; p < countSize; ++p) { - linearIndex += (normalizedPoint[countSize - p] - 1) * product; + linearIndex += (normalizedPoint[countSize - p]) * product; product /= count[countSize - p]; } - linearIndex += (normalizedPoint[0] - 1); // fastest + linearIndex += normalizedPoint[0]; // fastest return linearIndex; }; @@ -190,13 +190,13 @@ size_t LinearIndex(const Box<Dims> &localBox, const Dims &point, size_t linearIndex = MaxSizeT - 1; - if (isRowMajor && isZeroIndex) + if (isRowMajor) { - linearIndex = lf_RowZero(count, normalizedPoint); + linearIndex = lf_RowMajor(count, normalizedPoint); } - else if (!isRowMajor && !isZeroIndex) + else { - linearIndex = lf_ColumnOne(count, normalizedPoint); + linearIndex = lf_ColumnMajor(count, normalizedPoint); } return linearIndex; diff --git a/source/adios2/helper/adiosMath.h b/source/adios2/helper/adiosMath.h index d8dd481fc6498e0bfe55db8f411273caf4d71395..f5ab4bf9d2f2158606ac3a0e2123bbdcaa7d1d5d 100644 --- a/source/adios2/helper/adiosMath.h +++ b/source/adios2/helper/adiosMath.h @@ -128,7 +128,7 @@ Box<Dims> IntersectionBox(const Box<Dims> &box1, * @return linear index for contiguous memory */ size_t LinearIndex(const Box<Dims> &localBox, const Dims &point, - const bool isRowMajor, const bool isZeroIndex) noexcept; + const bool isRowMajor) noexcept; } // end namespace adios2 diff --git a/source/adios2/toolkit/format/bp3/BP3Base.h b/source/adios2/toolkit/format/bp3/BP3Base.h index a5d5d0c72d91f81df53237432972b87cffc798b0..45bf3174e62fa95f2ce23eaf8e1052ce0fd1086a 100644 --- a/source/adios2/toolkit/format/bp3/BP3Base.h +++ b/source/adios2/toolkit/format/bp3/BP3Base.h @@ -208,9 +208,7 @@ protected: const bool m_DebugMode = false; /** from host language in data information */ - bool m_IsRowMajor = true; // C, C++ defaults - /** from host language in data information */ - bool m_IsZeroIndex = true; // C, C++ + bool m_IsRowMajor = true; /** method type for file I/O */ enum IO_METHOD diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp b/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp index eae06acfce6613456a578a10ec237559ccc739cf..47f680981fb3dc73a1964f1808f15bdcc30c18e9 100644 --- a/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp +++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp @@ -117,14 +117,14 @@ void BP3Deserializer::ParsePGIndex() position = m_Minifooter.PGIndexStart; m_MetadataSet.DataPGCount = ReadValue<uint64_t>(buffer, position); - position += 10; // skipping lengths - position += 2 + ReadValue<uint16_t>(buffer, position); // skipping name + position += 10; // skipping lengths + const uint16_t nameLength = ReadValue<uint16_t>(buffer, position); + position += static_cast<size_t>(nameLength); // skipping name const char isFortran = ReadValue<char>(buffer, position); if (isFortran == 'y') { m_IsRowMajor = false; - m_IsZeroIndex = false; } } @@ -141,7 +141,7 @@ void BP3Deserializer::ParseVariablesIndex(IO &io) case (type_byte): { - DefineVariableInIO<char>(header, io, buffer, position); + DefineVariableInIO<signed char>(header, io, buffer, position); break; } diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.h b/source/adios2/toolkit/format/bp3/BP3Deserializer.h index 01f829dcbd53d30a875d831b988f9ecff5a8c50f..b81107c04ce05ef9b01775ce086b9d8c86511e5a 100644 --- a/source/adios2/toolkit/format/bp3/BP3Deserializer.h +++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.h @@ -99,7 +99,7 @@ private: * @param intersectionBox */ template <class T> - void ClipContiguousMemoryCommonRowZero( + void ClipContiguousMemoryCommonRow( Variable<T> &variable, const std::vector<char> &contiguousMemory, const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const; @@ -111,7 +111,7 @@ private: * @param intersectionBox */ template <class T> - void ClipContiguousMemoryCommonColumnOne( + void ClipContiguousMemoryCommonColumn( Variable<T> &variable, const std::vector<char> &contiguousMemory, const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const; }; diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc index 8e90253eef67ff1ceaae5495ca08caf74dd0aa9b..31600629260a90b5c282f11364499d77d28b13cc 100644 --- a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc +++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc @@ -84,10 +84,7 @@ void BP3Deserializer::DefineVariableInIO(const ElementIndexHeader &header, position = initialPosition; - size_t currentStep = 1; - - std::vector<size_t> subsetPositions; // per step - subsetPositions.reserve(1); // expecting one subset per step + size_t currentStep = 0; // Starts at 1 in bp file while (position < endPosition) { @@ -100,14 +97,6 @@ void BP3Deserializer::DefineVariableInIO(const ElementIndexHeader &header, buffer, position, static_cast<DataTypes>(header.DataType), false); - if (subsetCharacteristics.Statistics.Step > currentStep) - { - currentStep = subsetCharacteristics.Statistics.Step; - variable->m_IndexStepBlockStarts[currentStep] = subsetPositions; - ++variable->m_AvailableStepsCount; - subsetPositions.clear(); - } - if (subsetCharacteristics.Statistics.Min < variable->m_Min) { variable->m_Min = subsetCharacteristics.Statistics.Min; @@ -118,14 +107,14 @@ void BP3Deserializer::DefineVariableInIO(const ElementIndexHeader &header, variable->m_Max = subsetCharacteristics.Statistics.Max; } - subsetPositions.push_back(subsetPosition); - position = subsetPosition + subsetCharacteristics.EntryLength + 5; - - if (position == endPosition) // check if last one + if (subsetCharacteristics.Statistics.Step > currentStep) { - variable->m_IndexStepBlockStarts[currentStep] = subsetPositions; - break; + currentStep = subsetCharacteristics.Statistics.Step; + variable->m_AvailableStepsCount = + subsetCharacteristics.Statistics.Step; } + variable->m_IndexStepBlockStarts[currentStep].push_back(subsetPosition); + position = subsetPosition + subsetCharacteristics.EntryLength + 5; } } @@ -178,13 +167,13 @@ BP3Deserializer::GetSubFileInfo(const Variable<T> &variable) const info.Seeks.first = blockCharacteristics.Statistics.PayloadOffset + LinearIndex(info.BlockBox, info.IntersectionBox.first, - m_IsRowMajor, m_IsZeroIndex) * + m_IsRowMajor) * sizeof(T); info.Seeks.second = blockCharacteristics.Statistics.PayloadOffset + (LinearIndex(info.BlockBox, info.IntersectionBox.second, - m_IsRowMajor, m_IsZeroIndex) + + m_IsRowMajor) + 1) * sizeof(T); @@ -217,20 +206,20 @@ void BP3Deserializer::ClipContiguousMemoryCommon( return; } - if (m_IsRowMajor && m_IsZeroIndex) // C, C++, Python + if (m_IsRowMajor) // stored with C, C++, Python { - ClipContiguousMemoryCommonRowZero(variable, contiguousMemory, blockBox, - intersectionBox); + ClipContiguousMemoryCommonRow(variable, contiguousMemory, blockBox, + intersectionBox); } - else if (!m_IsRowMajor && !m_IsZeroIndex) // Fortran, R + else // stored with Fortran, R { - ClipContiguousMemoryCommonColumnOne(variable, contiguousMemory, - blockBox, intersectionBox); + ClipContiguousMemoryCommonColumn(variable, contiguousMemory, blockBox, + intersectionBox); } } template <class T> -void BP3Deserializer::ClipContiguousMemoryCommonRowZero( +void BP3Deserializer::ClipContiguousMemoryCommonRow( Variable<T> &variable, const std::vector<char> &contiguousMemory, const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const { @@ -247,17 +236,17 @@ void BP3Deserializer::ClipContiguousMemoryCommonRowZero( bool run = true; const size_t intersectionStart = - LinearIndex(blockBox, intersectionBox.first, true, true) * sizeof(T); + LinearIndex(blockBox, intersectionBox.first, true) * sizeof(T); while (run) { // here copy current linear memory between currentPoint and end const size_t contiguousStart = - LinearIndex(blockBox, currentPoint, true, true) * sizeof(T) - + LinearIndex(blockBox, currentPoint, true) * sizeof(T) - intersectionStart; const size_t variableStart = - LinearIndex(selectionBox, currentPoint, true, true) * sizeof(T); + LinearIndex(selectionBox, currentPoint, true) * sizeof(T); char *rawVariableData = reinterpret_cast<char *>(variable.GetData()); @@ -272,7 +261,7 @@ void BP3Deserializer::ClipContiguousMemoryCommonRowZero( while (true) { ++currentPoint[p]; - if (currentPoint[p] > end[p]) // TODO: check end condition + if (currentPoint[p] > end[p]) { if (p == 0) { @@ -294,7 +283,7 @@ void BP3Deserializer::ClipContiguousMemoryCommonRowZero( } template <class T> -void BP3Deserializer::ClipContiguousMemoryCommonColumnOne( +void BP3Deserializer::ClipContiguousMemoryCommonColumn( Variable<T> &variable, const std::vector<char> &contiguousMemory, const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const { @@ -311,17 +300,17 @@ void BP3Deserializer::ClipContiguousMemoryCommonColumnOne( bool run = true; const size_t intersectionStart = - LinearIndex(blockBox, intersectionBox.first, false, false) * sizeof(T); + LinearIndex(blockBox, intersectionBox.first, false) * sizeof(T); while (run) { // here copy current linear memory between currentPoint and end const size_t contiguousStart = - LinearIndex(blockBox, currentPoint, false, false) * sizeof(T) - + LinearIndex(blockBox, currentPoint, false) * sizeof(T) - intersectionStart; const size_t variableStart = - LinearIndex(selectionBox, currentPoint, false, false) * sizeof(T); + LinearIndex(selectionBox, currentPoint, false) * sizeof(T); char *rawVariableData = reinterpret_cast<char *>(variable.GetData()); @@ -336,7 +325,7 @@ void BP3Deserializer::ClipContiguousMemoryCommonColumnOne( while (true) { ++currentPoint[p]; - if (currentPoint[p] > end[p]) // TODO: check end condition + if (currentPoint[p] > end[p]) { if (p == dimensions - 1) { diff --git a/source/adios2/toolkit/transport/file/FileFStream.cpp b/source/adios2/toolkit/transport/file/FileFStream.cpp index e119c15967a873272dd5bda1c235ee006d20ab93..4f33cd22930067a7a57f39c67e501667f50fff90 100644 --- a/source/adios2/toolkit/transport/file/FileFStream.cpp +++ b/source/adios2/toolkit/transport/file/FileFStream.cpp @@ -34,7 +34,8 @@ void FileFStream::Open(const std::string &name, const Mode openMode) case (Mode::Write): ProfilerStart("open"); MkDir(m_Name); - m_FileStream.open(name, std::fstream::out | std::fstream::binary); + m_FileStream.open(name, std::fstream::out | std::fstream::binary | + std::fstream::trunc); ProfilerStop("open"); break; diff --git a/source/adios2/toolkit/transport/file/FilePOSIX.cpp b/source/adios2/toolkit/transport/file/FilePOSIX.cpp index 903c82992abb595fe8c6963826d43a33a076e3a1..c11b56824f89485aae66830b22912a10139f1230 100644 --- a/source/adios2/toolkit/transport/file/FilePOSIX.cpp +++ b/source/adios2/toolkit/transport/file/FilePOSIX.cpp @@ -49,7 +49,8 @@ void FilePOSIX::Open(const std::string &name, const Mode openMode) case (Mode::Write): ProfilerStart("open"); MkDir(m_Name); - m_FileDescriptor = open(m_Name.c_str(), O_WRONLY | O_CREAT, 0777); + m_FileDescriptor = + open(m_Name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0777); ProfilerStop("open"); break; diff --git a/source/adios2/toolkit/transportman/TransportMan.cpp b/source/adios2/toolkit/transportman/TransportMan.cpp index 21ed6773e81bb507543011f4b4bc9db6bf807843..4505a3b28d73fee972b689d3a3750e53bdc62542 100644 --- a/source/adios2/toolkit/transportman/TransportMan.cpp +++ b/source/adios2/toolkit/transportman/TransportMan.cpp @@ -54,12 +54,12 @@ void TransportMan::OpenFiles(const std::vector<std::string> &fileNames, } } -void TransportMan::OpenFileID(const std::string &name, const unsigned int id, - const Mode openMode, const Params ¶meters, +void TransportMan::OpenFileID(const std::string &name, const size_t id, + const Mode mode, const Params ¶meters, const bool profile) { std::shared_ptr<Transport> file = - OpenFileTransport(name, openMode, parameters, profile); + OpenFileTransport(name, mode, parameters, profile); m_Transports.insert({id, file}); } diff --git a/source/adios2/toolkit/transportman/TransportMan.h b/source/adios2/toolkit/transportman/TransportMan.h index a305236a7191576159dc55904bd9edf26ef54173..2b7f51f7269a3f8db02581966a06ac266c7c2b91 100644 --- a/source/adios2/toolkit/transportman/TransportMan.h +++ b/source/adios2/toolkit/transportman/TransportMan.h @@ -61,9 +61,16 @@ public: const std::vector<Params> ¶metersVector, const bool profile); - void OpenFileID(const std::string &name, const unsigned int id, - const Mode openMode, const Params ¶meters, - const bool profile); + /** + * Used for sub-files defined by index + * @param name + * @param id + * @param openMode + * @param parameters + * @param profile + */ + void OpenFileID(const std::string &name, const size_t id, const Mode mode, + const Params ¶meters, const bool profile); /** * Gets each transport base name from either baseName at Open or name diff --git a/source/utils/bpls2/BPLS2.cpp b/source/utils/bpls2/BPLS2.cpp index 335444646db3a139ebd28f2018ad9e588fe8e732..3efc634435dbaea05c35eada09423f5ca00b0ea1 100644 --- a/source/utils/bpls2/BPLS2.cpp +++ b/source/utils/bpls2/BPLS2.cpp @@ -238,8 +238,8 @@ void BPLS2::ProcessTransport() const for (const auto &variablePair : variablesMap) { const std::string name(variablePair.first); - const Params ¶meters = variablePair.second; - const std::string type(parameters.at("Type")); + const Params &variableParameters = variablePair.second; + const std::string type(variableParameters.at("Type")); std::cout << " "; std::cout << std::left << std::setw(maxTypeSize) << type << " "; @@ -248,8 +248,8 @@ void BPLS2::ProcessTransport() const // print min max if (m_Parameters.count("long") == 1) { - std::cout << parameters.at("Min") << " / " - << parameters.at("Max"); + std::cout << variableParameters.at("Min") << " / " + << variableParameters.at("Max"); } std::cout << "\n"; } diff --git a/testing/adios2/engine/bp/CMakeLists.txt b/testing/adios2/engine/bp/CMakeLists.txt index b70bace799f079f933093208d248d8d9009f17a8..55e8f14ea28d71667e82b61b9d4a7409be11afed 100644 --- a/testing/adios2/engine/bp/CMakeLists.txt +++ b/testing/adios2/engine/bp/CMakeLists.txt @@ -3,8 +3,16 @@ # accompanying file Copyright.txt for details. #------------------------------------------------------------------------------# -# MPI versions of the test are not properly implemented at the moment +add_executable(TestBPWriteReadADIOS2 TestBPWriteReadADIOS2.cpp) +target_link_libraries(TestBPWriteReadADIOS2 adios2 gtest gtest_main) +if(ADIOS2_HAVE_MPI) + target_link_libraries(TestBPWriteReadADIOS2 MPI::MPI_C) + set(extra_test_args EXEC_WRAPPER ${MPIEXEC_COMMAND}) +endif() + +gtest_add_tests(TARGET TestBPWriteReadADIOS2 ${extra_test_args}) + if (ADIOS2_HAVE_ADIOS1) add_executable(TestBPWriteRead TestBPWriteRead.cpp) target_link_libraries(TestBPWriteRead adios2 gtest adios1::adios) @@ -29,8 +37,6 @@ if (ADIOS2_HAVE_ADIOS1) target_link_libraries(TestBPWriteReadstdio MPI::MPI_C) target_link_libraries(TestBPWriteReadfstream MPI::MPI_C) target_link_libraries(TestBPWriteProfilingJSON MPI::MPI_C) - - set(extra_test_args EXEC_WRAPPER ${MPIEXEC_COMMAND}) endif() gtest_add_tests(TARGET TestBPWriteRead ${extra_test_args}) diff --git a/testing/adios2/engine/bp/TestBPWriteReadADIOS2.cpp b/testing/adios2/engine/bp/TestBPWriteReadADIOS2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1515c2702bb80025c6c436f99bd30ae4ff2135ef --- /dev/null +++ b/testing/adios2/engine/bp/TestBPWriteReadADIOS2.cpp @@ -0,0 +1,912 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + */ +#include <cstdint> +#include <cstring> + +#include <iostream> +#include <stdexcept> + +#include <adios2.h> + +#include <gtest/gtest.h> + +#include "../SmallTestData.h" + +class BPWriteReadTestADIOS2 : public ::testing::Test +{ +public: + BPWriteReadTestADIOS2() = default; + + SmallTestData m_TestData; +}; + +//****************************************************************************** +// 1D 1x8 test data +//****************************************************************************** + +// ADIOS2 BP write, native ADIOS1 read +TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead1D8) +{ + // Each process would write a 1x8 array and all processes would + // form a mpiSize * Nx 1D array + const std::string fname("ADIOS2BPWriteRead1D8.bp"); + + int mpiRank = 0, mpiSize = 1; + // Number of rows + const size_t Nx = 8; + + // Number of steps + const size_t NSteps = 3; + +#ifdef ADIOS2_HAVE_MPI + MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); + MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); +#endif + +// Write test data using BP + +#ifdef ADIOS2_HAVE_MPI + adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON); +#else + adios2::ADIOS adios(true); +#endif + { + adios2::IO &io = adios.DeclareIO("TestIO"); + + // Declare 1D variables (NumOfProcesses * Nx) + // The local process' part (start, count) can be defined now or later + // before Write(). + { + const adios2::Dims shape{static_cast<size_t>(Nx * mpiSize)}; + const adios2::Dims start{static_cast<size_t>(Nx * mpiRank)}; + const adios2::Dims count{Nx}; + + auto &var_iString = io.DefineVariable<std::string>("iString"); + auto &var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count); + auto &var_i16 = + io.DefineVariable<int16_t>("i16", shape, start, count); + auto &var_i32 = + io.DefineVariable<int32_t>("i32", shape, start, count); + auto &var_i64 = + io.DefineVariable<int64_t>("i64", shape, start, count); + auto &var_u8 = + io.DefineVariable<uint8_t>("u8", shape, start, count); + auto &var_u16 = + io.DefineVariable<uint16_t>("u16", shape, start, count); + auto &var_u32 = + io.DefineVariable<uint32_t>("u32", shape, start, count); + auto &var_u64 = + io.DefineVariable<uint64_t>("u64", shape, start, count); + auto &var_r32 = + io.DefineVariable<float>("r32", shape, start, count); + auto &var_r64 = + io.DefineVariable<double>("r64", shape, start, count); + } + + // Create the BP Engine + io.SetEngine("BPFileWriter"); + + io.AddTransport("file"); + + // QUESTION: It seems that BPFilterWriter cannot overwrite existing + // files + // Ex. if you tune Nx and NSteps, the test would fail. But if you clear + // the cache in + // ${adios2Build}/testing/adios2/engine/bp/ADIOS2BPWriteADIOS1Read1D8.bp.dir, + // then it works + adios2::Engine &bpWriter = io.Open(fname, adios2::Mode::Write); + + for (size_t step = 0; step < NSteps; ++step) + { + // Generate test data for each process uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, step, mpiRank, mpiSize); + + // Retrieve the variables that previously went out of scope + auto &var_iString = *io.InquireVariable<std::string>("iString"); + auto &var_i8 = *io.InquireVariable<int8_t>("i8"); + auto &var_i16 = *io.InquireVariable<int16_t>("i16"); + auto &var_i32 = *io.InquireVariable<int32_t>("i32"); + auto &var_i64 = *io.InquireVariable<int64_t>("i64"); + auto &var_u8 = *io.InquireVariable<uint8_t>("u8"); + auto &var_u16 = *io.InquireVariable<uint16_t>("u16"); + auto &var_u32 = *io.InquireVariable<uint32_t>("u32"); + auto &var_u64 = *io.InquireVariable<uint64_t>("u64"); + auto &var_r32 = *io.InquireVariable<float>("r32"); + auto &var_r64 = *io.InquireVariable<double>("r64"); + + // Make a 1D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + adios2::Box<adios2::Dims> sel({mpiRank * Nx}, {Nx}); + + EXPECT_THROW(var_iString.SetSelection(sel), std::invalid_argument); + var_i8.SetSelection(sel); + var_i16.SetSelection(sel); + var_i32.SetSelection(sel); + var_i64.SetSelection(sel); + var_u8.SetSelection(sel); + var_u16.SetSelection(sel); + var_u32.SetSelection(sel); + var_u64.SetSelection(sel); + var_r32.SetSelection(sel); + var_r64.SetSelection(sel); + + // Write each one + // fill in the variable with values from starting index to + // starting index + count + bpWriter.BeginStep(); + bpWriter.PutSync(var_iString, currentTestData.S1); + bpWriter.PutSync(var_i8, currentTestData.I8.data()); + bpWriter.PutSync(var_i16, currentTestData.I16.data()); + bpWriter.PutSync(var_i32, currentTestData.I32.data()); + bpWriter.PutSync(var_i64, currentTestData.I64.data()); + bpWriter.PutSync(var_u8, currentTestData.U8.data()); + bpWriter.PutSync(var_u16, currentTestData.U16.data()); + bpWriter.PutSync(var_u32, currentTestData.U32.data()); + bpWriter.PutSync(var_u64, currentTestData.U64.data()); + bpWriter.PutSync(var_r32, currentTestData.R32.data()); + bpWriter.PutSync(var_r64, currentTestData.R64.data()); + bpWriter.EndStep(); + } + + // Close the file + bpWriter.Close(); + } + + { + adios2::IO &io = adios.DeclareIO("ReadIO"); + + adios2::Engine &bpReader = io.Open(fname, adios2::Mode::Read); + + // auto var_iString = io.InquireVariable<std::string>("iString"); + // ASSERT_NE(var_iString, nullptr); + // ASSERT_EQ(var_iString->m_Shape.size(), 0); + // ASSERT_EQ(var_iString->m_AvailableStepsCount, NSteps); + + auto var_i8 = io.InquireVariable<int8_t>("i8"); + ASSERT_NE(var_i8, nullptr); + ASSERT_EQ(var_i8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i8->m_Shape[0], mpiSize * Nx); + + auto var_i16 = io.InquireVariable<int16_t>("i16"); + ASSERT_NE(var_i16, nullptr); + ASSERT_EQ(var_i16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i16->m_Shape[0], mpiSize * Nx); + + auto var_i32 = io.InquireVariable<int32_t>("i32"); + ASSERT_NE(var_i32, nullptr); + ASSERT_EQ(var_i32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i32->m_Shape[0], mpiSize * Nx); + + auto var_i64 = io.InquireVariable<int64_t>("i64"); + ASSERT_NE(var_i64, nullptr); + ASSERT_EQ(var_i64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i64->m_Shape[0], mpiSize * Nx); + + auto var_u8 = io.InquireVariable<uint8_t>("u8"); + ASSERT_NE(var_u8, nullptr); + ASSERT_EQ(var_u8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u8->m_Shape[0], mpiSize * Nx); + + auto var_u16 = io.InquireVariable<uint16_t>("u16"); + ASSERT_NE(var_u16, nullptr); + ASSERT_EQ(var_u16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u16->m_Shape[0], mpiSize * Nx); + + auto var_u32 = io.InquireVariable<uint32_t>("u32"); + ASSERT_NE(var_u32, nullptr); + ASSERT_EQ(var_u32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u32->m_Shape[0], mpiSize * Nx); + + auto var_u64 = io.InquireVariable<uint64_t>("u64"); + ASSERT_NE(var_u64, nullptr); + ASSERT_EQ(var_u64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u64->m_Shape[0], mpiSize * Nx); + + auto var_r32 = io.InquireVariable<float>("r32"); + ASSERT_NE(var_r32, nullptr); + ASSERT_EQ(var_r32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r32->m_Shape[0], mpiSize * Nx); + + auto var_r64 = io.InquireVariable<double>("r64"); + ASSERT_NE(var_r64, nullptr); + ASSERT_EQ(var_r64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r64->m_Shape[0], mpiSize * Nx); + + // TODO: other types + + SmallTestData testData; + std::vector<char> IString(testData.S1.size()); + std::array<int8_t, Nx> I8; + std::array<int16_t, Nx> I16; + std::array<int32_t, Nx> I32; + std::array<int64_t, Nx> I64; + std::array<uint8_t, Nx> U8; + std::array<uint16_t, Nx> U16; + std::array<uint32_t, Nx> U32; + std::array<uint64_t, Nx> U64; + std::array<float, Nx> R32; + std::array<double, Nx> R64; + + const adios2::Dims start{mpiRank * Nx}; + const adios2::Dims count{Nx}; + + const adios2::Box<adios2::Dims> sel(start, count); + + var_i8->SetSelection(sel); + var_i16->SetSelection(sel); + var_i32->SetSelection(sel); + var_i64->SetSelection(sel); + + var_u8->SetSelection(sel); + var_u16->SetSelection(sel); + var_u32->SetSelection(sel); + var_u64->SetSelection(sel); + + var_r32->SetSelection(sel); + var_r64->SetSelection(sel); + + for (size_t t = 0; t < NSteps; ++t) + { + var_i8->SetStepSelection({t + 1, 1}); + var_i16->SetStepSelection({t + 1, 1}); + var_i32->SetStepSelection({t + 1, 1}); + var_i64->SetStepSelection({t + 1, 1}); + + var_u8->SetStepSelection({t + 1, 1}); + var_u16->SetStepSelection({t + 1, 1}); + var_u32->SetStepSelection({t + 1, 1}); + var_u64->SetStepSelection({t + 1, 1}); + + var_r32->SetStepSelection({t + 1, 1}); + var_r64->SetStepSelection({t + 1, 1}); + + // Generate test data for each rank uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, t, mpiRank, mpiSize); + + bpReader.GetDeferred(*var_i8, I8.data()); + bpReader.GetDeferred(*var_i16, I16.data()); + bpReader.GetDeferred(*var_i32, I32.data()); + bpReader.GetDeferred(*var_i64, I64.data()); + + bpReader.GetDeferred(*var_u8, U8.data()); + bpReader.GetDeferred(*var_u16, U16.data()); + bpReader.GetDeferred(*var_u32, U32.data()); + bpReader.GetDeferred(*var_u64, U64.data()); + + bpReader.GetDeferred(*var_r32, R32.data()); + bpReader.GetDeferred(*var_r64, R64.data()); + + bpReader.PerformGets(); + + for (size_t i = 0; i < Nx; ++i) + { + std::stringstream ss; + ss << "t=" << t << " i=" << i << " rank=" << mpiRank; + std::string msg = ss.str(); + + EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg; + EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg; + EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg; + EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg; + EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg; + EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg; + EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg; + EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg; + EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg; + EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg; + } + } + bpReader.Close(); + } +} + +//****************************************************************************** +// 2D 2x4 test data +//****************************************************************************** + +// ADIOS2 BP write, native ADIOS1 read +TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D2x4) +{ + // Each process would write a 2x4 array and all processes would + // form a 2D 2 * (numberOfProcess*Nx) matrix where Nx is 4 here + const std::string fname("ADIOS2BPWriteRead2D2x4Test.bp"); + + int mpiRank = 0, mpiSize = 1; + // Number of rows + const std::size_t Nx = 4; + + // Number of rows + const std::size_t Ny = 2; + + // Number of steps + const std::size_t NSteps = 3; + +#ifdef ADIOS2_HAVE_MPI + MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); + MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); +#endif + +// Write test data using ADIOS2 + +#ifdef ADIOS2_HAVE_MPI + adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON); +#else + adios2::ADIOS adios(true); +#endif + { + adios2::IO &io = adios.DeclareIO("TestIO"); + + // Declare 2D variables (Ny * (NumOfProcesses * Nx)) + // The local process' part (start, count) can be defined now or later + // before Write(). + { + const adios2::Dims shape{Ny, static_cast<size_t>(Nx * mpiSize)}; + const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)}; + const adios2::Dims count{Ny, Nx}; + + auto &var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count); + auto &var_i16 = + io.DefineVariable<int16_t>("i16", shape, start, count); + auto &var_i32 = + io.DefineVariable<int32_t>("i32", shape, start, count); + auto &var_i64 = + io.DefineVariable<int64_t>("i64", shape, start, count); + auto &var_u8 = + io.DefineVariable<uint8_t>("u8", shape, start, count); + auto &var_u16 = + io.DefineVariable<uint16_t>("u16", shape, start, count); + auto &var_u32 = + io.DefineVariable<uint32_t>("u32", shape, start, count); + auto &var_u64 = + io.DefineVariable<uint64_t>("u64", shape, start, count); + auto &var_r32 = + io.DefineVariable<float>("r32", shape, start, count); + auto &var_r64 = + io.DefineVariable<double>("r64", shape, start, count); + } + + // Create the BP Engine + io.SetEngine("BPFileWriter"); + io.AddTransport("file"); + + adios2::Engine &bpWriter = io.Open(fname, adios2::Mode::Write); + + for (size_t step = 0; step < NSteps; ++step) + { + // Generate test data for each process uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, step, mpiRank, mpiSize); + + // Retrieve the variables that previously went out of scope + auto &var_i8 = *io.InquireVariable<int8_t>("i8"); + auto &var_i16 = *io.InquireVariable<int16_t>("i16"); + auto &var_i32 = *io.InquireVariable<int32_t>("i32"); + auto &var_i64 = *io.InquireVariable<int64_t>("i64"); + auto &var_u8 = *io.InquireVariable<uint8_t>("u8"); + auto &var_u16 = *io.InquireVariable<uint16_t>("u16"); + auto &var_u32 = *io.InquireVariable<uint32_t>("u32"); + auto &var_u64 = *io.InquireVariable<uint64_t>("u64"); + auto &var_r32 = *io.InquireVariable<float>("r32"); + auto &var_r64 = *io.InquireVariable<double>("r64"); + + // Make a 2D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + adios2::Box<adios2::Dims> sel( + {0, static_cast<size_t>(mpiRank * Nx)}, {Ny, Nx}); + var_i8.SetSelection(sel); + var_i16.SetSelection(sel); + var_i32.SetSelection(sel); + var_i64.SetSelection(sel); + var_u8.SetSelection(sel); + var_u16.SetSelection(sel); + var_u32.SetSelection(sel); + var_u64.SetSelection(sel); + var_r32.SetSelection(sel); + var_r64.SetSelection(sel); + + // Write each one + // fill in the variable with values from starting index to + // starting index + count + bpWriter.BeginStep(); + bpWriter.PutSync(var_i8, currentTestData.I8.data()); + bpWriter.PutSync(var_i16, currentTestData.I16.data()); + bpWriter.PutSync(var_i32, currentTestData.I32.data()); + bpWriter.PutSync(var_i64, currentTestData.I64.data()); + bpWriter.PutSync(var_u8, currentTestData.U8.data()); + bpWriter.PutSync(var_u16, currentTestData.U16.data()); + bpWriter.PutSync(var_u32, currentTestData.U32.data()); + bpWriter.PutSync(var_u64, currentTestData.U64.data()); + bpWriter.PutSync(var_r32, currentTestData.R32.data()); + bpWriter.PutSync(var_r64, currentTestData.R64.data()); + bpWriter.EndStep(); + } + + // Close the file + bpWriter.Close(); + } + + { + adios2::IO &io = adios.DeclareIO("ReadIO"); + + adios2::Engine &bpReader = io.Open(fname, adios2::Mode::Read); + + auto var_i8 = io.InquireVariable<int8_t>("i8"); + ASSERT_NE(var_i8, nullptr); + ASSERT_EQ(var_i8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i8->m_Shape[0], Ny); + ASSERT_EQ(var_i8->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i16 = io.InquireVariable<int16_t>("i16"); + ASSERT_NE(var_i16, nullptr); + ASSERT_EQ(var_i16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i16->m_Shape[0], Ny); + ASSERT_EQ(var_i16->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i32 = io.InquireVariable<int32_t>("i32"); + ASSERT_NE(var_i32, nullptr); + ASSERT_EQ(var_i32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i32->m_Shape[0], Ny); + ASSERT_EQ(var_i32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i64 = io.InquireVariable<int64_t>("i64"); + ASSERT_NE(var_i64, nullptr); + ASSERT_EQ(var_i64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i64->m_Shape[0], Ny); + ASSERT_EQ(var_i64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u8 = io.InquireVariable<uint8_t>("u8"); + ASSERT_NE(var_u8, nullptr); + ASSERT_EQ(var_u8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u8->m_Shape[0], Ny); + ASSERT_EQ(var_u8->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u16 = io.InquireVariable<uint16_t>("u16"); + ASSERT_NE(var_u16, nullptr); + ASSERT_EQ(var_u16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u16->m_Shape[0], Ny); + ASSERT_EQ(var_u16->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u32 = io.InquireVariable<uint32_t>("u32"); + ASSERT_NE(var_u32, nullptr); + ASSERT_EQ(var_u32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u32->m_Shape[0], Ny); + ASSERT_EQ(var_u32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u64 = io.InquireVariable<uint64_t>("u64"); + ASSERT_NE(var_u64, nullptr); + ASSERT_EQ(var_u64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u64->m_Shape[0], Ny); + ASSERT_EQ(var_u64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_r32 = io.InquireVariable<float>("r32"); + ASSERT_NE(var_r32, nullptr); + ASSERT_EQ(var_r32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r32->m_Shape[0], Ny); + ASSERT_EQ(var_r32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_r64 = io.InquireVariable<double>("r64"); + ASSERT_NE(var_r64, nullptr); + ASSERT_EQ(var_r64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r64->m_Shape[0], Ny); + ASSERT_EQ(var_r64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + // If the size of the array is smaller than the data + // the result is weird... double and uint64_t would get + // completely garbage data + std::array<int8_t, Nx * Ny> I8; + std::array<int16_t, Nx * Ny> I16; + std::array<int32_t, Nx * Ny> I32; + std::array<int64_t, Nx * Ny> I64; + std::array<uint8_t, Nx * Ny> U8; + std::array<uint16_t, Nx * Ny> U16; + std::array<uint32_t, Nx * Ny> U32; + std::array<uint64_t, Nx * Ny> U64; + std::array<float, Nx * Ny> R32; + std::array<double, Nx * Ny> R64; + + const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)}; + const adios2::Dims count{Ny, Nx}; + + const adios2::Box<adios2::Dims> sel(start, count); + + var_i8->SetSelection(sel); + var_i16->SetSelection(sel); + var_i32->SetSelection(sel); + var_i64->SetSelection(sel); + + var_u8->SetSelection(sel); + var_u16->SetSelection(sel); + var_u32->SetSelection(sel); + var_u64->SetSelection(sel); + + var_r32->SetSelection(sel); + var_r64->SetSelection(sel); + + for (size_t t = 0; t < NSteps; ++t) + { + var_i8->SetStepSelection({t + 1, 1}); + var_i16->SetStepSelection({t + 1, 1}); + var_i32->SetStepSelection({t + 1, 1}); + var_i64->SetStepSelection({t + 1, 1}); + + var_u8->SetStepSelection({t + 1, 1}); + var_u16->SetStepSelection({t + 1, 1}); + var_u32->SetStepSelection({t + 1, 1}); + var_u64->SetStepSelection({t + 1, 1}); + + var_r32->SetStepSelection({t + 1, 1}); + var_r64->SetStepSelection({t + 1, 1}); + + bpReader.GetDeferred(*var_i8, I8.data()); + bpReader.GetDeferred(*var_i16, I16.data()); + bpReader.GetDeferred(*var_i32, I32.data()); + bpReader.GetDeferred(*var_i64, I64.data()); + + bpReader.GetDeferred(*var_u8, U8.data()); + bpReader.GetDeferred(*var_u16, U16.data()); + bpReader.GetDeferred(*var_u32, U32.data()); + bpReader.GetDeferred(*var_u64, U64.data()); + + bpReader.GetDeferred(*var_r32, R32.data()); + bpReader.GetDeferred(*var_r64, R64.data()); + + bpReader.PerformGets(); + + // Generate test data for each rank uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, t, mpiRank, mpiSize); + + for (size_t i = 0; i < Nx * Ny; ++i) + { + std::stringstream ss; + ss << "t=" << t << " i=" << i << " rank=" << mpiRank; + std::string msg = ss.str(); + + EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg; + EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg; + EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg; + EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg; + EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg; + EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg; + EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg; + EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg; + EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg; + EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg; + } + } + bpReader.Close(); + } +} + +//****************************************************************************** +// 2D 4x2 test data +//****************************************************************************** + +TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D4x2) +{ + // Each process would write a 4x2 array and all processes would + // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here + const std::string fname("ADIOS2BPWriteRead2D4x2Test.bp"); + + int mpiRank = 0, mpiSize = 1; + // Number of rows + const std::size_t Nx = 2; + // Number of cols + const std::size_t Ny = 4; + + // Number of steps + const std::size_t NSteps = 3; + +#ifdef ADIOS2_HAVE_MPI + MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); + MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); +#endif + +// Write test data using ADIOS2 + +#ifdef ADIOS2_HAVE_MPI + adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON); +#else + adios2::ADIOS adios(true); +#endif + { + adios2::IO &io = adios.DeclareIO("TestIO"); + + // Declare 2D variables (4 * (NumberOfProcess * Nx)) + // The local process' part (start, count) can be defined now or later + // before Write(). + { + adios2::Dims shape{static_cast<unsigned int>(Ny), + static_cast<unsigned int>(mpiSize * Nx)}; + adios2::Dims start{static_cast<unsigned int>(0), + static_cast<unsigned int>(mpiRank * Nx)}; + adios2::Dims count{static_cast<unsigned int>(Ny), + static_cast<unsigned int>(Nx)}; + auto &var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count); + auto &var_i16 = + io.DefineVariable<int16_t>("i16", shape, start, count); + auto &var_i32 = + io.DefineVariable<int32_t>("i32", shape, start, count); + auto &var_i64 = + io.DefineVariable<int64_t>("i64", shape, start, count); + auto &var_u8 = + io.DefineVariable<uint8_t>("u8", shape, start, count); + auto &var_u16 = + io.DefineVariable<uint16_t>("u16", shape, start, count); + auto &var_u32 = + io.DefineVariable<uint32_t>("u32", shape, start, count); + auto &var_u64 = + io.DefineVariable<uint64_t>("u64", shape, start, count); + auto &var_r32 = + io.DefineVariable<float>("r32", shape, start, count); + auto &var_r64 = + io.DefineVariable<double>("r64", shape, start, count); + } + + // Create the BP Engine + io.SetEngine("BPFileWriter"); + + io.AddTransport("file"); + + adios2::Engine &bpWriter = io.Open(fname, adios2::Mode::Write); + + for (size_t step = 0; step < NSteps; ++step) + { + // Generate test data for each process uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, step, mpiRank, mpiSize); + + // Retrieve the variables that previously went out of scope + auto &var_i8 = *io.InquireVariable<int8_t>("i8"); + auto &var_i16 = *io.InquireVariable<int16_t>("i16"); + auto &var_i32 = *io.InquireVariable<int32_t>("i32"); + auto &var_i64 = *io.InquireVariable<int64_t>("i64"); + auto &var_u8 = *io.InquireVariable<uint8_t>("u8"); + auto &var_u16 = *io.InquireVariable<uint16_t>("u16"); + auto &var_u32 = *io.InquireVariable<uint32_t>("u32"); + auto &var_u64 = *io.InquireVariable<uint64_t>("u64"); + auto &var_r32 = *io.InquireVariable<float>("r32"); + auto &var_r64 = *io.InquireVariable<double>("r64"); + + // Make a 2D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + adios2::Box<adios2::Dims> sel( + {0, static_cast<unsigned int>(mpiRank * Nx)}, {Ny, Nx}); + var_i8.SetSelection(sel); + var_i16.SetSelection(sel); + var_i32.SetSelection(sel); + var_i64.SetSelection(sel); + var_u8.SetSelection(sel); + var_u16.SetSelection(sel); + var_u32.SetSelection(sel); + var_u64.SetSelection(sel); + var_r32.SetSelection(sel); + var_r64.SetSelection(sel); + + // Write each one + // fill in the variable with values from starting index to + // starting index + count + bpWriter.BeginStep(); + bpWriter.PutSync(var_i8, currentTestData.I8.data()); + bpWriter.PutSync(var_i16, currentTestData.I16.data()); + bpWriter.PutSync(var_i32, currentTestData.I32.data()); + bpWriter.PutSync(var_i64, currentTestData.I64.data()); + bpWriter.PutSync(var_u8, currentTestData.U8.data()); + bpWriter.PutSync(var_u16, currentTestData.U16.data()); + bpWriter.PutSync(var_u32, currentTestData.U32.data()); + bpWriter.PutSync(var_u64, currentTestData.U64.data()); + bpWriter.PutSync(var_r32, currentTestData.R32.data()); + bpWriter.PutSync(var_r64, currentTestData.R64.data()); + bpWriter.EndStep(); + } + + // Close the file + bpWriter.Close(); + } + + { + adios2::IO &io = adios.DeclareIO("ReadIO"); + + adios2::Engine &bpReader = io.Open(fname, adios2::Mode::Read); + + auto var_i8 = io.InquireVariable<int8_t>("i8"); + ASSERT_NE(var_i8, nullptr); + ASSERT_EQ(var_i8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i8->m_Shape[0], Ny); + ASSERT_EQ(var_i8->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i16 = io.InquireVariable<int16_t>("i16"); + ASSERT_NE(var_i16, nullptr); + ASSERT_EQ(var_i16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i16->m_Shape[0], Ny); + ASSERT_EQ(var_i16->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i32 = io.InquireVariable<int32_t>("i32"); + ASSERT_NE(var_i32, nullptr); + ASSERT_EQ(var_i32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i32->m_Shape[0], Ny); + ASSERT_EQ(var_i32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_i64 = io.InquireVariable<int64_t>("i64"); + ASSERT_NE(var_i64, nullptr); + ASSERT_EQ(var_i64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_i64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_i64->m_Shape[0], Ny); + ASSERT_EQ(var_i64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u8 = io.InquireVariable<uint8_t>("u8"); + ASSERT_NE(var_u8, nullptr); + ASSERT_EQ(var_u8->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u8->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u8->m_Shape[0], Ny); + ASSERT_EQ(var_u8->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u16 = io.InquireVariable<uint16_t>("u16"); + ASSERT_NE(var_u16, nullptr); + ASSERT_EQ(var_u16->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u16->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u16->m_Shape[0], Ny); + ASSERT_EQ(var_u16->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u32 = io.InquireVariable<uint32_t>("u32"); + ASSERT_NE(var_u32, nullptr); + ASSERT_EQ(var_u32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u32->m_Shape[0], Ny); + ASSERT_EQ(var_u32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_u64 = io.InquireVariable<uint64_t>("u64"); + ASSERT_NE(var_u64, nullptr); + ASSERT_EQ(var_u64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_u64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_u64->m_Shape[0], Ny); + ASSERT_EQ(var_u64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_r32 = io.InquireVariable<float>("r32"); + ASSERT_NE(var_r32, nullptr); + ASSERT_EQ(var_r32->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r32->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r32->m_Shape[0], Ny); + ASSERT_EQ(var_r32->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + auto var_r64 = io.InquireVariable<double>("r64"); + ASSERT_NE(var_r64, nullptr); + ASSERT_EQ(var_r64->m_ShapeID, adios2::ShapeID::GlobalArray); + ASSERT_EQ(var_r64->m_AvailableStepsCount, NSteps); + ASSERT_EQ(var_r64->m_Shape[0], Ny); + ASSERT_EQ(var_r64->m_Shape[1], static_cast<size_t>(mpiSize * Nx)); + + // If the size of the array is smaller than the data + // the result is weird... double and uint64_t would get + // completely garbage data + std::array<int8_t, Nx * Ny> I8; + std::array<int16_t, Nx * Ny> I16; + std::array<int32_t, Nx * Ny> I32; + std::array<int64_t, Nx * Ny> I64; + std::array<uint8_t, Nx * Ny> U8; + std::array<uint16_t, Nx * Ny> U16; + std::array<uint32_t, Nx * Ny> U32; + std::array<uint64_t, Nx * Ny> U64; + std::array<float, Nx * Ny> R32; + std::array<double, Nx * Ny> R64; + + const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)}; + const adios2::Dims count{Ny, Nx}; + + const adios2::Box<adios2::Dims> sel(start, count); + + var_i8->SetSelection(sel); + var_i16->SetSelection(sel); + var_i32->SetSelection(sel); + var_i64->SetSelection(sel); + + var_u8->SetSelection(sel); + var_u16->SetSelection(sel); + var_u32->SetSelection(sel); + var_u64->SetSelection(sel); + + var_r32->SetSelection(sel); + var_r64->SetSelection(sel); + + for (size_t t = 0; t < NSteps; ++t) + { + var_i8->SetStepSelection({t + 1, 1}); + var_i16->SetStepSelection({t + 1, 1}); + var_i32->SetStepSelection({t + 1, 1}); + var_i64->SetStepSelection({t + 1, 1}); + + var_u8->SetStepSelection({t + 1, 1}); + var_u16->SetStepSelection({t + 1, 1}); + var_u32->SetStepSelection({t + 1, 1}); + var_u64->SetStepSelection({t + 1, 1}); + + var_r32->SetStepSelection({t + 1, 1}); + var_r64->SetStepSelection({t + 1, 1}); + + bpReader.GetDeferred(*var_i8, I8.data()); + bpReader.GetDeferred(*var_i16, I16.data()); + bpReader.GetDeferred(*var_i32, I32.data()); + bpReader.GetDeferred(*var_i64, I64.data()); + + bpReader.GetDeferred(*var_u8, U8.data()); + bpReader.GetDeferred(*var_u16, U16.data()); + bpReader.GetDeferred(*var_u32, U32.data()); + bpReader.GetDeferred(*var_u64, U64.data()); + + bpReader.GetDeferred(*var_r32, R32.data()); + bpReader.GetDeferred(*var_r64, R64.data()); + + bpReader.PerformGets(); + + // Generate test data for each rank uniquely + SmallTestData currentTestData = + generateNewSmallTestData(m_TestData, t, mpiRank, mpiSize); + + for (size_t i = 0; i < Nx * Ny; ++i) + { + std::stringstream ss; + ss << "t=" << t << " i=" << i << " rank=" << mpiRank; + std::string msg = ss.str(); + + EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg; + EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg; + EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg; + EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg; + EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg; + EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg; + EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg; + EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg; + EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg; + EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg; + } + } + bpReader.Close(); + } +} + +//****************************************************************************** +// main +//****************************************************************************** + +int main(int argc, char **argv) +{ +#ifdef ADIOS2_HAVE_MPI + MPI_Init(nullptr, nullptr); +#endif + + ::testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + +#ifdef ADIOS2_HAVE_MPI + MPI_Finalize(); +#endif + + return result; +}