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 960 : MPI_Datatype get_mpi_datatype(const T& /*x*/) {
66 960 : MPI_Datatype type = MPI_BYTE;
67 960 : 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 24 : MPI_Type_contiguous(
71 : vector_dim_type<T>::Dim,
72 : get_mpi_datatype<typename T::value_type>(typename T::value_type{}), &tp);
73 24 : MPI_Type_commit(&tp);
74 24 : core::type_names[std::type_index(typeid(T))] = tp;
75 : }
76 : }
77 : try {
78 960 : 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 960 : return type;
83 : }
84 : } // namespace mpi
85 : } // namespace ippl
86 :
87 : #endif
|