diff --git a/bindings/CXX11/CMakeLists.txt b/bindings/CXX11/CMakeLists.txt index 7815a5f335..cea73ef8c7 100644 --- a/bindings/CXX11/CMakeLists.txt +++ b/bindings/CXX11/CMakeLists.txt @@ -89,6 +89,7 @@ install( adios2/cxx11/Operator.h adios2/cxx11/Query.h adios2/cxx11/Types.h + adios2/cxx11/kokkos_interop.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/adios2/cxx11 COMPONENT adios2_cxx11-development ) diff --git a/bindings/CXX11/adios2/cxx11/Engine.h b/bindings/CXX11/adios2/cxx11/Engine.h index 166679c799..efda5a8cf9 100644 --- a/bindings/CXX11/adios2/cxx11/Engine.h +++ b/bindings/CXX11/adios2/cxx11/Engine.h @@ -21,6 +21,38 @@ namespace adios2 { +namespace detail +{ + +template +using void_t = void; + +} // end namespace detail + +template +struct ndarray_traits : std::false_type +{ +}; + +template +struct ndarray_traits< + C, detail::void_t().data()), + decltype(std::declval().size()), + // don't match std::vector since it's handled separately + typename std::enable_if>::type>>> +: std::true_type +{ + using value_type = typename C::value_type; + using pointer = typename C::pointer; + using size_type = typename C::size_type; + static constexpr auto memory_space = adios2::MemorySpace::Detect; + + static pointer data(C &c) { return c.data(); } + static size_type size(C &c) { return c.size(); } +}; + /// \cond EXCLUDE_FROM_DOXYGEN // forward declare class IO; // friend @@ -146,6 +178,31 @@ class Engine void Put(VariableNT &variable, const void *data, const Mode launch = Mode::Deferred); + /** + * Put data associated with a container-like thing, e.g., a Kokkos::View + * @param variable contains variable metadata information + * @param ndarray user data that is multi-dimensional array-like + * @param launch mode policy + */ + template ::value && + std::is_same::value_type>::type, + T>::value>::type> + void Put(Variable variable, const C &ndarray, + const Mode launch = Mode::Deferred) + { + auto mem_space = ndarray_traits::memory_space; + if (mem_space != adios2::MemorySpace::Detect) + { + variable.SetMemorySpace(mem_space); + } + Put(variable, + const_cast(ndarray_traits::data(ndarray)), + launch); + } + /** * Put data associated with a Variable in the Engine * Overloaded version that accepts a variable name string. @@ -232,6 +289,30 @@ class Engine void Get(VariableNT &variable, void *data, const Mode launch = Mode::Deferred); + /** + * Get data associated with a Variable from the Engine + * @param variable contains variable metadata information + * @param ndarray user data that is multi-dimensional array-like + * @param launch mode policy + * @exception std::invalid_argument for invalid variable or nullptr data + */ + template ::value && + std::is_same::value_type>::type, + T>::value>::type> + void Get(Variable variable, C &ndarray, + const Mode launch = Mode::Deferred) + { + auto mem_space = ndarray_traits::memory_space; + if (mem_space != adios2::MemorySpace::Detect) + { + variable.SetMemorySpace(mem_space); + } + Get(variable, ndarray_traits::data(ndarray), launch); + } + /** * Get data associated with a Variable from the Engine. Overloaded version * to get variable by name. diff --git a/bindings/CXX11/adios2/cxx11/kokkos_interop.h b/bindings/CXX11/adios2/cxx11/kokkos_interop.h new file mode 100644 index 0000000000..d5df683825 --- /dev/null +++ b/bindings/CXX11/adios2/cxx11/kokkos_interop.h @@ -0,0 +1,52 @@ + +#ifndef ADIOS2_BINDINGS_CXX11_CXX11_KOKKOS_INTEROP_H_ +#define ADIOS2_BINDINGS_CXX11_CXX11_KOKKOS_INTEROP_H_ + +#include +#include + +namespace adios2 +{ + +namespace detail +{ + +template +struct memspace_kokkos_to_adios2; + +template <> +struct memspace_kokkos_to_adios2 +{ + static constexpr adios2::MemorySpace value = adios2::MemorySpace::Host; +}; + +#ifdef KOKKOS_ENABLE_CUDA + +template <> +struct memspace_kokkos_to_adios2 +{ + static constexpr adios2::MemorySpace space = adios2::MemorySpace::CUDA; +}; + +#endif + +} // namespace detail + +template +struct ndarray_traits::value>::type> +: std::true_type +{ + using value_type = typename T::value_type; + using size_type = typename T::size_type; + using pointer = typename T::pointer_type; + static constexpr auto memory_space = + detail::memspace_kokkos_to_adios2::value; + + static pointer data(const T &c) { return c.data(); } + static size_type size(const T &c) { return c.size(); } +}; + +} // namespace adios2 + +#endif