|
KaMPIng 0.2.1
(Near) zero-overhead MPI wrapper for C++
|
A standalone C++17 header-only library that maps C++ types to MPI datatypes and reduction operations.
kamping-types is extracted from KaMPIng and can be consumed independently — without the KaMPIng communicator layer.
Then include what you need:
| Option | Default | Description |
|---|---|---|
KAMPING_TYPES_BUILD_EXAMPLES | ON (top-level), OFF (subdirectory) | Build the example program |
KAMPING_TYPES_ENABLE_REFLECTION | OFF | Enable struct reflection via Boost.PFR for arbitrary struct types |
| Header | Contents |
|---|---|
kamping/types/builtin_types.hpp | TypeCategory, builtin_type<T>, is_builtin_type_v<T> |
kamping/types/mpi_type_traits.hpp | type_dispatcher<T>(), mpi_type_traits<T>, has_static_type_v<T> |
kamping/types/contiguous_type.hpp | contiguous_type<T,N>, byte_serialized<T> |
kamping/types/struct_type.hpp | kamping_tag, struct_type<T> |
kamping/types/scoped_datatype.hpp | ScopedDatatype — RAII commit/free wrapper |
kamping/types/kabool.hpp | kabool — bool wrapper safe for MPI containers |
kamping/types/reduce_ops.hpp | kamping::ops:: functors, mpi_operation_traits<Op,T>, ScopedOp, with_operation_functor |
kamping/types/std/)These headers register standard library types with mpi_type_traits. Include only what you need; the safe and unsafe variants for the same type are mutually exclusive.
| Header | Type | How |
|---|---|---|
kamping/types/std/utility.hpp | std::pair<F,S> | struct_type — models field layout; field types must have a static MPI type |
kamping/types/std/tuple.hpp | std::tuple<Ts...> | struct_type — models field layout; all element types must have a static MPI type |
kamping/types/std/unsafe/utility.hpp | std::pair<F,S> | byte_serialized — flat byte copy; ignores padding |
kamping/types/std/unsafe/tuple.hpp | std::tuple<Ts...> | byte_serialized — flat byte copy; ignores padding |
kamping/types/std/unsafe/trivially_copyable.hpp | any std::is_trivially_copyable<T> not already registered | byte_serialized — catch-all; excludes std::pair/std::tuple so it composes with the above |
type_dispatcher<T>() maps C++ types to type traits according to these rules:
| C++ type | Result |
|---|---|
MPI builtin (int, double, std::complex<float>, …) | builtin_type<T> — named MPI type, no commit |
| Enum | dispatches to underlying type |
T[N], std::array<T,N> | contiguous_type<T,N> — must be committed |
| Everything else | no_matching_type — specialize mpi_type_traits<T> |
Use has_static_type_v<T> to check at compile time whether a type is handled.
For std::pair and std::tuple, include the ready-made headers from kamping/types/std/:
For your own types, specialize mpi_type_traits<T> directly:
To register all trivially copyable types at once, include the catch-all:
kamping/types/reduce_ops.hpp provides a C++ functor vocabulary that maps to MPI's builtin reduction ops.
kamping::ops::)| Functor | MPI constant | Identity |
|---|---|---|
ops::max<T> | MPI_MAX | std::numeric_limits<T>::lowest() |
ops::min<T> | MPI_MIN | std::numeric_limits<T>::max() |
ops::plus<T> | MPI_SUM | 0 |
ops::multiplies<T> | MPI_PROD | 1 |
ops::logical_and<T> | MPI_LAND | true |
ops::logical_or<T> | MPI_LOR | false |
ops::logical_xor<T> | MPI_LXOR | false |
ops::bit_and<T> | MPI_BAND | ~T{0} |
ops::bit_or<T> | MPI_BOR | T{0} |
ops::bit_xor<T> | MPI_BXOR | T{0} |
All functors default to T = void, enabling deduced argument types.
mpi_operation_traits<Op, T> maps a (functor, element type) pair to its builtin MPI_Op:
is_builtin is false for functors not covered by a predefined MPI operation (e.g., std::minus<>).
ScopedOpScopedOp wraps an MPI_Op and calls MPI_Op_free on destruction only when it owns the op (user-defined ops created via MPI_Op_create). Predefined constants are wrapped non-owning.
Analogous to ScopedDatatype for MPI_Datatype.
with_operation_functorwith_operation_functor maps a runtime MPI_Op handle to its C++ functor and invokes a callable:
Unknown ops dispatch to kamping::ops::null<>{}.
User-defined operations can be tagged: