From 5b84b71647aa3576c7a79fbb8b6572ee12426bd7 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Mon, 15 Oct 2018 18:23:25 +0200 Subject: [PATCH] Implement a cast mechanism that minimize number of word subdivision If T is a given type. It is decomposed into small pieces of integer words to define messages. For instance, if T size is Byte then it will be decomposed into one int8 (no decomposition just a reinterpret_cast). If T is 2Bytes -> int16, and so on. It sizeof(T) is not exactly 1,2,4 or 8, then the cast (sub)type will be the one whose size is the greatest (exact) divisor of the size of T. The CastArray<InitialType, CastType> will ensure data size consistency when transferring arrays. --- src/utils/Messenger.hpp | 70 +++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/src/utils/Messenger.hpp b/src/utils/Messenger.hpp index bb8b58d52..f1c74ffb8 100644 --- a/src/utils/Messenger.hpp +++ b/src/utils/Messenger.hpp @@ -37,47 +37,47 @@ class Messenger return MPI_Datatype(); } } -#endif PASTIS_HAS_MPI +#endif // PASTIS_HAS_MPI - struct CompositeType {}; // composite type - template <typename data_type, - int size = sizeof(data_type)> - struct data_cast - { - using type = CompositeType; - }; + private: + template <typename T, + typename Allowed = void> + struct split_cast {}; - template <typename data_type> - struct data_cast<data_type,1> - { - using type = int8_t; - static_assert(sizeof(data_type) == sizeof(type)); + template <typename T> + struct split_cast<T,std::enable_if_t<not(sizeof(T) % sizeof(int64_t))>> { + using type = int64_t; + static_assert(not(sizeof(T) % sizeof(int64_t))); }; - template <typename data_type> - struct data_cast<data_type,2> - { - using type = int16_t; - static_assert(sizeof(data_type) == sizeof(type)); + template <typename T> + struct split_cast<T,std::enable_if_t<not(sizeof(T) % sizeof(int32_t)) + and(sizeof(T) % sizeof(int64_t))>> { + using type = int32_t; + static_assert(not(sizeof(T) % sizeof(int32_t))); }; - template <typename data_type> - struct data_cast<data_type,4> - { - using type = int32_t; - static_assert(sizeof(data_type) == sizeof(type)); + template <typename T> + struct split_cast<T,std::enable_if_t<not(sizeof(T) % sizeof(int16_t)) + and(sizeof(T) % sizeof(int32_t)) + and(sizeof(T) % sizeof(int64_t))>> { + using type = int16_t; + static_assert(not(sizeof(T) % sizeof(int16_t))); }; - template <typename data_type> - struct data_cast<data_type,8> - { - using type = int64_t; - static_assert(sizeof(data_type) == sizeof(type)); + template <typename T> + struct split_cast<T,std::enable_if_t<not(sizeof(T) % sizeof(int8_t)) + and(sizeof(T) % sizeof(int16_t)) + and(sizeof(T) % sizeof(int32_t)) + and(sizeof(T) % sizeof(int64_t))>> { + using type = int8_t; + static_assert(not(sizeof(T) % sizeof(int8_t))); }; - template <typename data_type> - using data_cast_t = typename data_cast<data_type>::type; + public: + template <typename T> + using split_cast_t = typename split_cast<T>::type; }; static Messenger* m_instance; @@ -246,14 +246,8 @@ class Messenger if constexpr(std::is_arithmetic_v<DataType>) { _exchange(sent_array_list, recv_array_list); } else if constexpr(std::is_trivial_v<DataType>) { - using CastType = Helper::data_cast_t<DataType>; - - if constexpr(std::is_same_v<CastType, Helper::CompositeType>) { - static_assert(not std::is_same_v<CastType, Helper::CompositeType>, - "treatment of composite type is not yet implemented!"); - } else { - this->_exchange_through_cast<SendDataType, CastType>(sent_array_list, recv_array_list); - } + using CastType = Helper::split_cast_t<DataType>; + _exchange_through_cast<SendDataType, CastType>(sent_array_list, recv_array_list); } else { static_assert(std::is_trivial_v<RecvDataType>, "unexpected non trivial type of data"); -- GitLab