Skip to content
Snippets Groups Projects
Commit 5b84b716 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

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.
parent ac491b1f
No related branches found
No related tags found
1 merge request!11Feature/mpi
......@@ -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");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment