Branch data Line data Source code
1 : : //
2 : : // File DataTypes
3 : : // Definition of MPI types following the implementation of Boost.MPI.
4 : : //
5 : : #ifndef IPPL_MPI_DATATYPES_H
6 : : #define IPPL_MPI_DATATYPES_H
7 : :
8 : : #include <complex>
9 : : #include <cstdint>
10 : : #include <mpi.h>
11 : : #include <typeindex>
12 : : #include <typeinfo>
13 : : #include <unordered_map>
14 : :
15 : : #include "Utility/IpplException.h"
16 : :
17 : : namespace ippl {
18 : : namespace mpi {
19 : : namespace core {
20 : : static std::unordered_map<std::type_index, MPI_Datatype> type_names = {
21 : : {std::type_index(typeid(std::int8_t)), MPI_INT8_T},
22 : : {std::type_index(typeid(std::int16_t)), MPI_INT16_T},
23 : : {std::type_index(typeid(std::int32_t)), MPI_INT32_T},
24 : : {std::type_index(typeid(std::int64_t)), MPI_INT64_T},
25 : :
26 : : {std::type_index(typeid(std::uint8_t)), MPI_UINT8_T},
27 : : {std::type_index(typeid(std::uint16_t)), MPI_UINT16_T},
28 : : {std::type_index(typeid(std::uint32_t)), MPI_UINT32_T},
29 : : {std::type_index(typeid(std::uint64_t)), MPI_UINT64_T},
30 : :
31 : : {std::type_index(typeid(char)), MPI_CHAR},
32 : : {std::type_index(typeid(short)), MPI_SHORT},
33 : : {std::type_index(typeid(int)), MPI_INT},
34 : : {std::type_index(typeid(long)), MPI_LONG},
35 : : {std::type_index(typeid(long long)), MPI_LONG_LONG_INT}, // synonym: MPI_LONG_LONG
36 : :
37 : : {std::type_index(typeid(unsigned char)), MPI_UNSIGNED_CHAR},
38 : : {std::type_index(typeid(unsigned short)), MPI_UNSIGNED_SHORT},
39 : : {std::type_index(typeid(unsigned int)), MPI_UNSIGNED},
40 : : {std::type_index(typeid(unsigned long)), MPI_UNSIGNED_LONG},
41 : : {std::type_index(typeid(unsigned long long)), MPI_UNSIGNED_LONG_LONG},
42 : :
43 : : {std::type_index(typeid(float)), MPI_FLOAT},
44 : : {std::type_index(typeid(double)), MPI_DOUBLE},
45 : : {std::type_index(typeid(long double)), MPI_LONG_DOUBLE},
46 : :
47 : : {std::type_index(typeid(bool)), MPI_CXX_BOOL},
48 : :
49 : : {std::type_index(typeid(std::complex<float>)), MPI_CXX_FLOAT_COMPLEX},
50 : : {std::type_index(typeid(std::complex<double>)), MPI_CXX_DOUBLE_COMPLEX},
51 : : {std::type_index(typeid(std::complex<long double>)), MPI_CXX_LONG_DOUBLE_COMPLEX},
52 : :
53 : : {std::type_index(typeid(Kokkos::complex<double>)), MPI_CXX_FLOAT_COMPLEX},
54 : : {std::type_index(typeid(Kokkos::complex<float>)), MPI_CXX_FLOAT_COMPLEX}};
55 : : }
56 : : template <typename T>
57 : : struct vector_dim_type {
58 : : constexpr static unsigned Dim = 0;
59 : : };
60 : : template <typename T, unsigned Dim_>
61 : : struct vector_dim_type<ippl::Vector<T, Dim_>> {
62 : : constexpr static unsigned Dim = Dim_;
63 : : };
64 : : template <typename T>
65 : 430 : MPI_Datatype get_mpi_datatype(const T& /*x*/) {
66 : 430 : MPI_Datatype type = MPI_BYTE;
67 [ + - + - ]: 430 : if (core::type_names.find(std::type_index(typeid(T))) == core::type_names.end()) {
[ + - ]
68 : : if constexpr (vector_dim_type<T>::Dim > 0) {
69 : : MPI_Datatype tp;
70 [ + - + - ]: 36 : MPI_Type_contiguous(
71 : : vector_dim_type<T>::Dim,
72 : : get_mpi_datatype<typename T::value_type>(typename T::value_type{}), &tp);
73 [ + - ]: 36 : MPI_Type_commit(&tp);
74 [ + - ]: 36 : core::type_names[std::type_index(typeid(T))] = tp;
75 : : }
76 : : }
77 : : try {
78 [ + - ]: 430 : type = core::type_names.at(std::type_index(typeid(T)));
79 : 0 : } catch (...) {
80 [ - - - - : 0 : throw IpplException("ippl::mpi::get_mpi_datatype", "No such type available.");
- - ]
81 : : }
82 : 430 : return type;
83 : : }
84 : : } // namespace mpi
85 : : } // namespace ippl
86 : :
87 : : #endif
|