19 #ifndef TIMPI_STANDARD_TYPE_H 20 #define TIMPI_STANDARD_TYPE_H 24 #include "timpi/timpi_config.h" 33 #endif // TIMPI_HAVE_MPI 36 #ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION 37 # include <boost/multiprecision/float128.hpp> 48 #include <type_traits> 49 #include <unordered_map> 50 #include <unordered_set> 82 template <
typename T,
typename Enable>
100 template <
typename T>
107 template <
typename T,
typename A>
114 template <
typename T,
typename A>
121 template <
typename K,
typename T,
typename C,
typename A>
128 template <
typename K,
typename T,
typename C,
typename A>
135 template <
typename T,
typename C,
typename A>
142 template <
typename T,
typename C,
typename A>
149 template <
typename K,
typename T,
typename C,
typename A>
156 template <
typename K,
typename T,
typename C,
typename A>
163 template <
typename T,
typename C,
typename A>
170 template <
typename T,
typename C,
typename A>
180 template <
typename T>
193 template <
typename T,
typename A>
194 StandardType<typename InnermostType<T>::type>
197 const T * inner_example = (example && !example->empty()) ? &(*example)[0] :
nullptr;
206 #ifdef TIMPI_HAVE_MPI 208 #define TIMPI_STANDARD_TYPE(cxxtype,mpitype) \ 210 class StandardType<cxxtype> : public DataType \ 214 StandardType(const cxxtype * = nullptr) : DataType(mpitype) {} \ 216 static const bool is_fixed_type = true; \ 221 #define TIMPI_STANDARD_TYPE(cxxtype,mpitype) \ 223 class StandardType<cxxtype> : public DataType \ 227 StandardType(const cxxtype * = nullptr) : DataType() {} \ 229 static const bool is_fixed_type = true; \ 249 #ifdef TIMPI_HAVE_MPI 259 _type(uncommitted_type) {
260 MPI_Type_commit (&uncommitted_type);
264 MPI_Type_free(&
_type);
273 # ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION 280 static data_type static_type = MPI_DATATYPE_NULL;
281 if (static_type == MPI_DATATYPE_NULL)
283 timpi_call_mpi(MPI_Type_contiguous(2, MPI_DOUBLE, &static_type));
285 (std::make_unique<ManageType>(static_type));
287 _datatype = static_type;
296 _datatype = t._datatype;
304 # ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION 312 template<
typename T1,
typename T2>
314 typename std::enable_if<
315 StandardType<typename std::remove_const<T1>::type>::is_fixed_type &&
316 StandardType<T2>::is_fixed_type>::type> :
public DataType 323 #ifdef TIMPI_HAVE_MPI 324 static data_type static_type = MPI_DATATYPE_NULL;
325 if (static_type == MPI_DATATYPE_NULL)
328 static const std::pair<T1, T2> p;
335 d1(
const_cast<typename std::remove_const<T1>::type *
> 340 int blocklengths[] = {1,1};
341 MPI_Aint displs[2], start;
344 (MPI_Get_address (
const_cast<std::pair<T1,T2> *
>(example),
347 (MPI_Get_address (const_cast<T1*>(&example->first),
350 (MPI_Get_address (const_cast<T2*>(&example->second),
356 MPI_Datatype tmptype;
358 (MPI_Type_create_struct (2, blocklengths, displs, types,
361 (MPI_Type_commit (&tmptype));
365 (MPI_Type_create_resized (tmptype, 0,
366 sizeof(std::pair<T1,T2>),
369 (MPI_Type_free (&tmptype));
372 (std::make_unique<ManageType>(static_type));
374 _datatype = static_type;
377 #endif // TIMPI_HAVE_MPI 388 _datatype = t._datatype;
397 template<
typename T, std::
size_t N>
399 typename std::enable_if<
400 StandardType<T>::is_fixed_type>::type> :
public DataType 407 #ifdef TIMPI_HAVE_MPI 408 static data_type static_type = MPI_DATATYPE_NULL;
409 if (static_type == MPI_DATATYPE_NULL)
412 std::array<T, N> * ex;
413 std::unique_ptr<std::array<T, N>> temp;
415 ex =
const_cast<std::array<T, N> *
>(example);
418 temp.reset(
new std::array<T, N>());
422 static_assert(N > 0,
"Zero-length std::array is not supported by TIMPI");
426 MPI_Aint displs, start;
427 MPI_Datatype tmptype, type = T_type;
430 (MPI_Get_address (ex, &start));
432 (MPI_Get_address (&((*ex)[0]), &displs));
439 (MPI_Type_create_struct (1, &blocklength, &displs, &type,
442 (MPI_Type_commit (&tmptype));
446 (MPI_Type_create_resized (tmptype, 0,
sizeof(std::array<T,N>),
450 (MPI_Type_free (&tmptype));
453 (std::make_unique<ManageType>(static_type));
455 _datatype = static_type;
456 #else // #ifdef TIMPI_HAVE_MPI 469 _datatype = t._datatype;
480 template<std::
size_t n_minus_i>
483 template<
typename... Types>
484 static void build(std::vector<std::unique_ptr<DataType>> & out_vec,
485 const std::tuple<Types...> & example);
491 template<
typename... Types>
492 static void build(std::vector<std::unique_ptr<DataType>> & ,
493 const std::tuple<Types...> & ) {}
496 template<std::
size_t n_minus_i>
497 template<
typename... Types>
499 (std::vector<std::unique_ptr<DataType>> & out_vec,
500 const std::tuple<Types...> & example)
503 std::tuple_element<
sizeof...(Types)-n_minus_i, std::tuple<Types...>>::type
508 (&std::get<
sizeof...(Types)-n_minus_i>(example)));
514 template<std::
size_t n_minus_i>
517 template <
typename OutArray,
class... Types>
518 static void fill(OutArray & out,
519 const std::tuple<Types...> & example);
525 template <
typename OutArray,
typename... Types>
527 const std::tuple<Types...> & ) {}
531 template<std::
size_t n_minus_i>
532 template<
typename OutArray,
typename... Types>
535 const std::tuple<Types...> & example)
539 (&std::get<
sizeof...(Types)-n_minus_i>(example),
540 &out_vec[
sizeof...(Types)-n_minus_i]));
546 template <
typename Head,
typename... Tail>
553 template <
typename Head>
559 template<
typename... Types>
561 typename std::enable_if<
562 CheckAllFixedTypes<Types...>::is_fixed_type>::type> :
public DataType 569 #ifdef TIMPI_HAVE_MPI 570 static data_type static_type = MPI_DATATYPE_NULL;
571 if (static_type == MPI_DATATYPE_NULL)
574 static const std::tuple<Types...> t;
581 (MPI_Get_address (example, &start));
583 const std::size_t tuplesize =
sizeof...(Types);
585 std::vector<std::unique_ptr<DataType>> subtypes;
588 std::array<MPI_Aint,
sizeof...(Types)> displs;
591 std::array<MPI_Datatype,
sizeof...(Types)> types;
592 std::array<int,
sizeof...(Types)> blocklengths;
594 for (std::size_t i = 0; i != tuplesize; ++i)
602 MPI_Datatype tmptype;
604 (MPI_Type_create_struct (tuplesize, blocklengths.data(), displs.data(), types.data(),
607 (MPI_Type_commit (&tmptype));
611 (MPI_Type_create_resized (tmptype, 0,
612 sizeof(std::tuple<Types...>),
615 (MPI_Type_free (&tmptype));
618 (std::make_unique<ManageType>(static_type));
620 _datatype = static_type;
621 #else // #ifdef TIMPI_HAVE_MPI 623 #endif // TIMPI_HAVE_MPI 634 _datatype = t._datatype;
657 #endif // TIMPI_STANDARD_TYPE_H InnermostType< T >::type type
ManageType(data_type uncommitted_type)
InnermostType< T >::type type
MPI_Datatype data_type
Data types for communication.
InnermostType< std::pair< const K, T > >::type type
StandardType(const std::complex< T > *=nullptr)
StandardType & operator=(StandardType &t)
static void build(std::vector< std::unique_ptr< DataType >> &, const std::tuple< Types... > &)
InnermostType< T >::type type
StandardType(const StandardType< TIMPI_DEFAULT_SCALAR_TYPE > &t)
Encapsulates the MPI_Datatype.
InnermostType< T >::type type
Templated class to provide the appropriate MPI datatype for use with built-in C types or simple C++ c...
StandardType(const T *example=nullptr)
StandardType< T > build_standard_type(const T *example=nullptr)
virtual ~ManageType() override
static void build(std::vector< std::unique_ptr< DataType >> &out_vec, const std::tuple< Types... > &example)
StandardType & operator=(StandardType &t)
static const bool is_fixed_type
StandardType(const std::tuple< Types... > *example=nullptr)
static void fill(OutArray &out, const std::tuple< Types... > &example)
StandardType(const StandardType< std::array< T, N >> &t)
StandardType<T>'s which do not define a way to MPI_Type T should inherit from this class...
InnermostType< T >::type type
InnermostType< std::pair< const K, T > >::type type
StandardType & operator=(StandardType &t)
static void fill(OutArray &, const std::tuple< Types... > &)
The SemiPermanent "class" is basically just a place for a destructor vtable.
InnermostType< std::pair< const K, T > >::type type
static const bool is_fixed_type
static void add(std::unique_ptr< SemiPermanent > obj)
void timpi_ignore(const Args &...)
StandardType(const TIMPI_DEFAULT_SCALAR_TYPE *=nullptr)
StandardType(const StandardType< std::pair< T1, T2 >> &t)
StandardType(const std::array< T, N > *example=nullptr)
InnermostType< std::pair< const K, T > >::type type
StandardType(const std::pair< T1, T2 > *example=nullptr)
InnermostType< T >::type type
StandardType(const StandardType< std::tuple< Types... >> &t)
StandardType & operator=(StandardType &t)
TIMPI_STANDARD_TYPE(char, MPI_CHAR)