Loading...
Searching...
No Matches
mpitraits.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_COMMON_PARALLEL_MPITRAITS_HH
#define DUNE_COMMON_PARALLEL_MPITRAITS_HH
#if HAVE_MPI
#include <complex>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <utility>
#include <mpi.h>
namespace Dune
{
template<typename T>
struct MPITraits
{
private:
MPITraits(){}
MPITraits(const MPITraits&){}
static MPI_Datatype datatype;
static MPI_Datatype vectortype;
public:
static inline MPI_Datatype getType()
{
if(datatype==MPI_DATATYPE_NULL) {
MPI_Type_contiguous(sizeof(T),MPI_BYTE,&datatype);
MPI_Type_commit(&datatype);
}
return datatype;
}
static constexpr bool is_intrinsic = false;
};
template<class T>
MPI_Datatype MPITraits<T>::datatype = MPI_DATATYPE_NULL;
#ifndef DOXYGEN
// A Macro for defining traits for the primitive data types
#define ComposeMPITraits(p,m) \
template<> \
struct MPITraits<p>{ \
static inline MPI_Datatype getType(){ \
return m; \
} \
static constexpr bool is_intrinsic = true; \
}
ComposeMPITraits(char, MPI_CHAR);
ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
ComposeMPITraits(short,MPI_SHORT);
ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
ComposeMPITraits(int,MPI_INT);
ComposeMPITraits(unsigned int,MPI_UNSIGNED);
ComposeMPITraits(long,MPI_LONG);
ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
ComposeMPITraits(float,MPI_FLOAT);
ComposeMPITraits(double,MPI_DOUBLE);
ComposeMPITraits(long double,MPI_LONG_DOUBLE);
ComposeMPITraits(std::complex<double>, MPI_CXX_DOUBLE_COMPLEX);
ComposeMPITraits(std::complex<long double>, MPI_CXX_LONG_DOUBLE_COMPLEX);
ComposeMPITraits(std::complex<float>, MPI_CXX_FLOAT_COMPLEX);
#undef ComposeMPITraits
template<class K, int n> class FieldVector;
template<class K, int n>
struct MPITraits<FieldVector<K,n> >
{
static MPI_Datatype datatype;
static MPI_Datatype vectortype;
static inline MPI_Datatype getType()
{
if(datatype==MPI_DATATYPE_NULL) {
MPI_Type_contiguous(n, MPITraits<K>::getType(), &vectortype);
MPI_Type_commit(&vectortype);
FieldVector<K,n> fvector;
MPI_Aint base;
MPI_Aint displ;
MPI_Get_address(&fvector, &base);
MPI_Get_address(&(fvector[0]), &displ);
displ -= base;
int length[1]={1};
MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
MPI_Type_commit(&datatype);
}
return datatype;
}
};
template<class K, int n>
MPI_Datatype MPITraits<FieldVector<K,n> >::datatype = MPI_DATATYPE_NULL;
template<class K, int n>
MPI_Datatype MPITraits<FieldVector<K,n> >::vectortype = {MPI_DATATYPE_NULL};
template<int k>
class bigunsignedint;
template<int k>
struct MPITraits<bigunsignedint<k> >
{
static MPI_Datatype datatype;
static MPI_Datatype vectortype;
static inline MPI_Datatype getType()
{
if(datatype==MPI_DATATYPE_NULL) {
MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<std::uint16_t>::getType(),
&vectortype);
//MPI_Type_commit(&vectortype);
bigunsignedint<k> data;
MPI_Aint base;
MPI_Aint displ;
MPI_Get_address(&data, &base);
MPI_Get_address(&(data.digit), &displ);
displ -= base;
int length[1]={1};
MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
MPI_Type_commit(&datatype);
}
return datatype;
}
};
}
namespace Dune
{
template<int k>
MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
template<int k>
MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
template<typename T1, typename T2>
struct MPITraits<std::pair<T1,T2 > >
{
public:
inline static MPI_Datatype getType();
private:
static MPI_Datatype type;
};
template<typename T1, typename T2>
MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
{
if(type==MPI_DATATYPE_NULL) {
int length[2] = {1, 1};
MPI_Aint disp[2];
MPI_Datatype types[2] = {MPITraits<T1>::getType(),
MPITraits<T2>::getType()};
using Pair = std::pair<T1, T2>;
static_assert(std::is_standard_layout<Pair>::value, "offsetof() is only defined for standard layout types");
disp[0] = offsetof(Pair, first);
disp[1] = offsetof(Pair, second);
MPI_Datatype tmp;
MPI_Type_create_struct(2, length, disp, types, &tmp);
MPI_Type_create_resized(tmp, 0, sizeof(Pair), &type);
MPI_Type_commit(&type);
MPI_Type_free(&tmp);
}
return type;
}
template<typename T1, typename T2>
MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
#endif // !DOXYGEN
} // namespace Dune
#endif // HAVE_MPI
#endif // DUNE_COMMON_PARALLEL_MPITRAITS_HH
Dune::type
MPI_Datatype MPITraits< ParallelLocalIndex< T > >::type
Definition plocalindex.hh:317
Dune
Dune namespace
Definition alignedallocator.hh:13
Dune::datatype
MPI_Datatype MPITraits< T >::datatype
Definition mpitraits.hh:59
Dune::MPITraits
A traits class describing the mapping of types onto MPI_Datatypes.
Definition mpitraits.hh:41
Dune::MPITraits::getType
static MPI_Datatype getType()
Definition mpitraits.hh:48
Dune::MPITraits::is_intrinsic
static constexpr bool is_intrinsic
Definition mpitraits.hh:56
Dune::bigunsignedint
Portable very large unsigned integers.
Definition bigunsignedint.hh:74
Dune::bigunsignedint::n
static constexpr int n
Definition bigunsignedint.hh:79
Dune::FieldVector
vector space out of a tensor product of fields.
Definition fvector.hh:97
Dune::type