Using MPI With Custom Types
Note
If your custom type is serializable you can safely ignore this page and your custom type will work correctly with ParallelZone. However, ParallelZone may not perform as efficiently as possible. To learn how to use ParallelZone more efficiently with custom types read on.
For better or for worse MPI was designed for functional programming. This means its support for object-oriented programming is lacking out of the box. Arguably the best way for ParallelZone to support arbitrary objects is by doing all MPI operations on binary data. For an arbitrary C++ object this can always be done by serializing/deserializing the object; however, depending on the type of the object, and the properties of that type, there may be more efficient ways to convert the object to/from binary.
Since C++ lacks reflection, ParallelZone relies on several type traits to determine the properties of a particular type. These type traits are already defined for standard types (types built in to the C++ language and those in the standard library) and for types defined by ParallelZone. For all other types ParallelZone will fall back to the safety of serialization/deserialization unless told otherwise. This page explains the various type traits used by ParallelZone. Users of ParallelZone should register their custom types with these traits to get the most out of ParallelZone.
NeedsSerialized
The NeedsSerialized
template class is used to determine if a type T
needs to be serialized in order to be used by ParallelZone. By default
NeedsSerialized
is true for all T
. To make NeedsSerialized
false
for a particular type NeedsSerialized
needs to be specialized for that
type. For a type T
this is as simple as:
namespace parallelzone::mpi_helpers {
template<>
struct NeedsSerialized<T> : std::false_type {};
ParallelZone already defines specializations for:
std::vector<T>
(for trivially copyableT
only)BinaryBuffer
BinaryView
ConstBinaryView
Note
There are additional STL classes which should be covered, but are presently not coded up yet. Feel free to make a PR adding them.
Other Traits That Impact MPI Behavior
ParallelZone uses several other type traits under the hood, but generally speaking users can safely ignore them. We list them here only for very advanced usage of ParallelZone.
MPIDataType
This type trait is used by ParallelZone to map a C++ type to its corresponding
MPI data type enumeration. For example this trait will map char
to
MPI_CHAR
, double
to MPI_DOUBLE
, etc. Since MPI’s data types are
only defined for primitive data types we have already exhaustively registered
the primitive C++ data type with it’s corresponding MPI data type.
In some cases, users may have a user-defined type which is actually an MPI data
type (or can be implicitly converted to one). One common scenario is when using
enums or strong types. In these cases, users should specialize the
MPIDataType
class for their type.
MPIOp
This type trait maps C++ functors to the corresponding MPI operation. For
example this type trait will map std::plus
to MPI_SUM
and
std::multiplies
to MPI_PROD
. Since there is a small set of known MPI
operations we have taken the liberty of defining the instantiating the
MPIOp
template class for these operations and users will typically not need
to worry about such mappings.
In some cases users may have user-defined functors which map to MPI operations.
In those cases they may choose to specialize MPIOp
for their functor.