diff --git a/src/opt/mpi/include/mpi_wrappers.cc.h b/src/opt/mpi/include/mpi_wrappers.cc.h new file mode 100644 index 0000000..5979385 --- /dev/null +++ b/src/opt/mpi/include/mpi_wrappers.cc.h @@ -0,0 +1,106 @@ +// -*- C++ -*- +/** + + @file opt/mpi/include/mpi_wrappers.cc.h + @brief MPI wrapper template implementations. + + Copyright (c) 2024 Christian Zimmermann. All rights reserved. + Mail: chizeta@f3l.de + +**/ + +#ifndef __cxz_mpi_wrappers_cc_h__ +#define __cxz_mpi_wrappers_cc_h__ + +#include "mpi_wrappers.h" + +namespace CNORXZ +{ + namespace mpi + { + + template + void BCast::bcast(T& d, SizeT root) + { + static_assert( TypeMap::exists, "no bcast implementation for given type" ); + const int ret = MPI_Bcast( reinterpret_cast(&d), 1, + TypeMap::value, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret); + return; + } + + // preliminary solutions, use cereal serialization in the future!!! + template + void BCast>::bcast(Vector& d, SizeT root) + { + SizeT size = d.size(); + const int ret = MPI_Bcast( reinterpret_cast(&size), 1, + MPI_UNSIGNED_LONG, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret); + if(size != d.size()){ + d.resize(size); + } + if constexpr( BCast::special ){ + for(auto& x: d){ + bcast(x, root); + } + } + else { + const int ret2 = MPI_Bcast( reinterpret_cast(d.data()), size, + TypeMap::value, MPI_COMM_WORLD ); + CXZ_ASSERT(ret2 == MPI_SUCCESS, "got bcast error = " << ret2); + } + } + + template + void BCast>::bcast(Arr& d, SizeT root) + { + if constexpr( BCast::special ){ + for(auto& x: d){ + bcast(x, root); + } + } + else { + const int ret = MPI_Bcast( reinterpret_cast(d.data()), N, + TypeMap::value, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret2); + } + } + + inline void BCast::bcast(String& d, SizeT root) + { + SizeT size = d.size(); + const int ret = MPI_Bcast( reinterpret_cast(&size), 1, + MPI_UNSIGNED_LONG, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret); + if(size != d.size()){ + d.resize(size); + } + const int ret = MPI_Bcast( reinterpret_cast(d.data()), size, + MPI_CHAR, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret); + } + + template + void BCast>::bcast(Tuple& d, SizeT root) + { + if constexpr( ( BCast::special or ... ) ){ + ifor<0,sizeof...(Ts)>( [&](auto i) { bcast( std::get(d), root ); }, NoF {} ); + } + else { + const int ret = MPI_Bcast( reinterpret_cast(&d), sizeof(d), + MPI_BYTE, MPI_COMM_WORLD ); + CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret); + } + } + + template + void bcast(T& d, SizeT root) + { + return BCast(d, root); + } + + } // namespace mpi +} // namespace CNORXZ + +#endif diff --git a/src/opt/mpi/include/mpi_wrappers.h b/src/opt/mpi/include/mpi_wrappers.h new file mode 100644 index 0000000..caee97b --- /dev/null +++ b/src/opt/mpi/include/mpi_wrappers.h @@ -0,0 +1,66 @@ +// -*- C++ -*- +/** + + @file opt/mpi/include/mpi_wrappers.h + @brief MPI wrapper template delarations. + + Copyright (c) 2024 Christian Zimmermann. All rights reserved. + Mail: chizeta@f3l.de + +**/ + +#ifndef __cxz_mpi_wrappers_h__ +#define __cxz_mpi_wrappers_h__ + +#include "mpi.h" +#include "cnorxz.h" +#include "typemap.h" + +namespace CNORXZ +{ + namespace mpi + { + + template + struct BCast + { + static constexpr bool special = false; + static void bcast(T& d, SizeT root); + }; + + template + struct BCast> + { + static constexpr bool special = true; + static void bcast(Vector& d, SizeT root); + }; + + template + struct BCast> + { + static constexpr bool special = true; + static void bcast(Arr& d, SizeT root); + }; + + template <> + struct BCast + { + static constexpr bool special = true; + static inline void bcast(String& d, SizeT root); + }; + + template + struct BCast> + { + static constexpr bool special = true; + static void bcast(Tuple& d, SizeT root); + }; + + template + void bcast(T& d, SizeT root); + + + } // namespace mpi +} // namespace CNORXZ + +#endif diff --git a/src/opt/mpi/include/rrange.cc.h b/src/opt/mpi/include/rrange.cc.h index e2663d4..50a815c 100644 --- a/src/opt/mpi/include/rrange.cc.h +++ b/src/opt/mpi/include/rrange.cc.h @@ -13,6 +13,7 @@ #define __cxz_mpi_rrange_cc_h__ #include "rrange.h" +#include "mpi_wrappers.h" namespace CNORXZ { diff --git a/src/opt/mpi/include/rrange.h b/src/opt/mpi/include/rrange.h index 8503ccf..03ebae3 100644 --- a/src/opt/mpi/include/rrange.h +++ b/src/opt/mpi/include/rrange.h @@ -35,7 +35,6 @@ namespace CNORXZ INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType); - // constructors!!! /** Default constructor. */ RIndex() = default; diff --git a/src/opt/mpi/include/typemap.h b/src/opt/mpi/include/typemap.h new file mode 100644 index 0000000..b0e20c9 --- /dev/null +++ b/src/opt/mpi/include/typemap.h @@ -0,0 +1,64 @@ + +#ifndef __cxz_mpi_typemap_h__ +#define __cxz_mpi_typemap_h__ + +#include "mpi.h" + +namespace CNORXZ +{ + namespace mpi + { + template + struct Typemap + { + static constexpr bool exists = false; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_INT; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_UNSIGNED; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_LONG; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_UNSIGNED_LONG; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_DOUBLE; + }; + + template <> + struct Typemap + { + static constexpr bool exists = true; + static constexpr MPI_Datatype value = MPI_FLOAT; + }; + + // further !!! + + } // namespace mpi +} // namespace CNORXZ + +#endif