10 #ifndef TEUCHOS_DETAILS_MPITYPETRAITS_HPP
11 #define TEUCHOS_DETAILS_MPITYPETRAITS_HPP
17 #include "Teuchos_config.h"
19 #ifdef HAVE_TEUCHOS_MPI
42 static const bool isSpecialized =
false;
60 static const bool needsFree =
false;
78 static MPI_Datatype getType (
const T&) {
84 return MPI_DATATYPE_NULL;
96 class MpiTypeTraits<char> {
99 static const bool isSpecialized =
true;
103 static const bool needsFree =
false;
106 static MPI_Datatype getType (
const char&) {
111 static MPI_Datatype getType () {
120 class MpiTypeTraits<unsigned char> {
123 static const bool isSpecialized =
true;
127 static const bool needsFree =
false;
130 static MPI_Datatype getType (
const unsigned char&) {
131 return MPI_UNSIGNED_CHAR;
135 static MPI_Datatype getType () {
136 return MPI_UNSIGNED_CHAR;
145 class MpiTypeTraits<signed char> {
148 static const bool isSpecialized =
true;
152 static const bool needsFree =
false;
155 static MPI_Datatype getType (
const signed char&) {
156 return MPI_SIGNED_CHAR;
160 static MPI_Datatype getType () {
161 return MPI_SIGNED_CHAR;
164 #endif // MPI_VERSION >= 2
207 computeStdComplexMpiDatatype (
const std::complex<T>& z)
209 #ifdef HAVE_TEUCHOSCORE_CXX11
210 static_assert (MpiTypeTraits<T>::isSpecialized,
"This function only "
211 "works if MpiTypeTraits<T>::isSpecialized.");
212 static_assert (! MpiTypeTraits<T>::needsFree,
"This function requires "
213 "! MpiTypeTraits<T>::needsFree, since otherwise it would "
215 #endif // HAVE_TEUCHOSCORE_CXX11
219 MPI_Datatype innerDatatype = MpiTypeTraits<T>::getType (z.real ());
220 MPI_Datatype outerDatatype;
227 if (
sizeof (std::complex<T>) == 2 *
sizeof (T)) {
228 (void) MPI_Type_contiguous (2, innerDatatype, &outerDatatype);
236 MPI_Aint arrayOfDisplacements[3];
237 MPI_Datatype arrayOfTypes[3];
239 #ifdef HAVE_TEUCHOSCORE_CXX11
241 static_assert (
sizeof (MyComplex<T>) ==
sizeof (std::complex<T>),
242 "Attempt to construct a struct of the same size and layout "
243 "as std::complex<T> failed.");
244 #endif // HAVE_TEUCHOSCORE_CXX11
254 arrayOfDisplacements[0] =
reinterpret_cast<char*
>(&z2.re) - reinterpret_cast<char*>(&z2);
255 arrayOfTypes[0] = innerDatatype;
259 arrayOfDisplacements[1] =
reinterpret_cast<char*
>(&z2.im) - reinterpret_cast<char*>(&z2);
260 arrayOfTypes[1] = innerDatatype;
265 arrayOfDisplacements[2] =
sizeof (MyComplex<T>);
266 arrayOfTypes[2] = MPI_UB;
267 #endif // MPI_VERSION < 2
271 (void) MPI_Type_struct (3, blockLengths, arrayOfDisplacements,
272 arrayOfTypes, &outerDatatype);
275 (void) MPI_Type_create_struct (2, blockLengths, arrayOfDisplacements,
276 arrayOfTypes, &outerDatatype);
277 #endif // MPI_VERSION < 2
280 MPI_Type_commit (&outerDatatype);
281 return outerDatatype;
289 class MpiTypeTraits< std::complex<double> > {
292 static const bool hasMpi3 =
true;
294 static const bool hasMpi3 =
false;
295 #endif // MPI_VERSION >= 3
299 static const bool isSpecialized =
true;
303 static const bool needsFree = ! hasMpi3;
306 static MPI_Datatype getType (
const std::complex<double>& z) {
309 return MPI_C_DOUBLE_COMPLEX;
311 return MPI_DATATYPE_NULL;
312 #endif // MPI_VERSION >= 3
315 return Impl::computeStdComplexMpiDatatype<double> (z);
320 static MPI_Datatype getType () {
323 return MPI_C_DOUBLE_COMPLEX;
325 return MPI_DATATYPE_NULL;
326 #endif // MPI_VERSION >= 3
331 std::complex<double> z (3.0, 4.0);
332 return Impl::computeStdComplexMpiDatatype<double> (z);
338 class MpiTypeTraits< std::complex<float> > {
341 static const bool hasMpi3 =
true;
343 static const bool hasMpi3 =
false;
344 #endif // MPI_VERSION >= 3
348 static const bool isSpecialized =
true;
352 static const bool needsFree = ! hasMpi3;
355 static MPI_Datatype getType (
const std::complex<float>& z) {
358 return MPI_C_FLOAT_COMPLEX;
360 return MPI_DATATYPE_NULL;
361 #endif // MPI_VERSION >= 3
364 return Impl::computeStdComplexMpiDatatype<float> (z);
369 static MPI_Datatype getType () {
372 return MPI_C_FLOAT_COMPLEX;
374 return MPI_DATATYPE_NULL;
375 #endif // MPI_VERSION >= 3
380 std::complex<float> z (3.0, 4.0);
381 return Impl::computeStdComplexMpiDatatype<float> (z);
388 class MpiTypeTraits<double> {
391 static const bool isSpecialized =
true;
395 static const bool needsFree =
false;
398 static MPI_Datatype getType (
const double&) {
403 static MPI_Datatype getType () {
410 class MpiTypeTraits<float> {
413 static const bool isSpecialized =
true;
417 static const bool needsFree =
false;
420 static MPI_Datatype getType (
const float&) {
425 static MPI_Datatype getType () {
432 class MpiTypeTraits<long long> {
435 static const bool isSpecialized =
true;
439 static const bool needsFree =
false;
442 static MPI_Datatype getType (
const long long&) {
443 return MPI_LONG_LONG;
447 static MPI_Datatype getType () {
448 return MPI_LONG_LONG;
458 class MpiTypeTraits<unsigned long long> {
461 static const bool isSpecialized =
true;
465 static const bool needsFree =
false;
468 static MPI_Datatype getType (
const unsigned long long&) {
469 return MPI_UNSIGNED_LONG_LONG;
473 static MPI_Datatype getType () {
474 return MPI_UNSIGNED_LONG_LONG;
477 #endif // MPI_VERSION >= 2
481 class MpiTypeTraits<long> {
484 static const bool isSpecialized =
true;
488 static const bool needsFree =
false;
491 static MPI_Datatype getType (
const long&) {
496 static MPI_Datatype getType () {
503 class MpiTypeTraits<unsigned long> {
506 static const bool isSpecialized =
true;
510 static const bool needsFree =
false;
513 static MPI_Datatype getType (
const unsigned long&) {
514 return MPI_UNSIGNED_LONG;
518 static MPI_Datatype getType () {
519 return MPI_UNSIGNED_LONG;
525 class MpiTypeTraits<int> {
528 static const bool isSpecialized =
true;
532 static const bool needsFree =
false;
535 static MPI_Datatype getType (
const int&) {
540 static MPI_Datatype getType () {
547 class MpiTypeTraits<unsigned int> {
550 static const bool isSpecialized =
true;
554 static const bool needsFree =
false;
557 static MPI_Datatype getType (
const unsigned int&) {
562 static MPI_Datatype getType () {
569 class MpiTypeTraits<short> {
572 static const bool isSpecialized =
true;
576 static const bool needsFree =
false;
579 static MPI_Datatype getType (
const short&) {
584 static MPI_Datatype getType () {
591 class MpiTypeTraits<unsigned short> {
594 static const bool isSpecialized =
true;
598 static const bool needsFree =
false;
601 static MPI_Datatype getType (
const unsigned short&) {
602 return MPI_UNSIGNED_SHORT;
606 static MPI_Datatype getType () {
607 return MPI_UNSIGNED_SHORT;
614 #endif // HAVE_TEUCHOS_MPI
616 #endif // TEUCHOS_DETAILS_MPITYPETRAITS_HPP