Buffer concepts

A type is a data buffer if a pointer, an element count and an MPI datatype can be obtained for it, through the accessors ptr(), count() and type() (see Customization points). Variable-size operations such as alltoallv additionally need per-rank counts and displacements, through counts() and displs(). See Data buffers.

Counts and displacements are contiguous ranges of int:

template<typename T>
concept count_range
template<typename T>
concept count_range =
    std::ranges::contiguous_range<T> && std::same_as<int, std::remove_cvref_t<std::ranges::range_value_t<T>>>

A contiguous range of int — the element type used for MPI counts and displacements.

Defined in header <kamping/v2/buffer.hpp>

Single buffers

template<typename T>
concept data_buffer
template<typename T>
concept data_buffer = has_mpi_count<T> && has_mpi_ptr<T> && has_mpi_type<T>

A buffer of count() elements of MPI datatype type() at ptr().

Defined in header <kamping/v2/buffer.hpp>

template<typename T>
concept send_buffer
template<typename T>
concept send_buffer = data_buffer<T> && requires(T&& t) {
    { ptr(t) } -> std::convertible_to<void const*>;
}

A data_buffer that can be sent from: its data pointer converts to void const*.

Defined in header <kamping/v2/buffer.hpp>

template<typename T>
concept recv_buffer
template<typename T>
concept recv_buffer = data_buffer<T> && requires(T&& t) {
    { ptr(t) } -> std::convertible_to<void*>;
}

A data_buffer that can be received into: its data pointer converts to void*.

Defined in header <kamping/v2/buffer.hpp>

template<typename T>
concept send_recv_buffer
template<typename T>
concept send_recv_buffer = recv_buffer<T>

A buffer that can be used for both sending and receiving (i.e. satisfies recv_buffer).

Defined in header <kamping/v2/buffer.hpp>

Variable-size buffers

template<typename T>
concept data_buffer_v
template<typename T>
concept data_buffer_v = has_mpi_ptr<T> && has_mpi_type<T> && has_mpi_counts<T> && has_mpi_displs<T>

Variadic buffer: data + type + per-rank counts + displacements. Does NOT require a scalar count() — variadic MPI operations use the per-rank counts array directly and never need the total element count.

Defined in header <kamping/v2/buffer.hpp>

template<typename T>
concept send_buffer_v
template<typename T>
concept send_buffer_v = data_buffer_v<T> && requires(T&& t) {
    { ptr(t) } -> std::convertible_to<void const*>;
}

A data_buffer_v that can be sent from.

Defined in header <kamping/v2/buffer.hpp>

template<typename T>
concept recv_buffer_v
template<typename T>
concept recv_buffer_v = data_buffer_v<T> && requires(T&& t) {
    { ptr(t) } -> std::convertible_to<void*>;
}

A data_buffer_v that can be received into.

Defined in header <kamping/v2/buffer.hpp>

Spans

Like std::span, but for any memory and datatype, and with counts and displacements for the variable-size form.

struct mpi_span

Mutable non-owning view over a contiguous MPI buffer. Satisfies send_buffer and recv_buffer. Converts implicitly to mpi_cspan.

Defined in header <kamping/v2/buffer.hpp>

struct mpi_span_v

Mutable non-owning variadic MPI buffer view (per-rank counts + displacements). Satisfies send_buffer_v and recv_buffer_v. Converts implicitly to mpi_cspan_v.

Defined in header <kamping/v2/buffer.hpp>

struct mpi_cspan

Read-only non-owning view over a contiguous MPI buffer. Satisfies send_buffer.

Defined in header <kamping/v2/buffer.hpp>

struct mpi_cspan_v

Read-only non-owning variadic MPI buffer view (per-rank counts + displacements). Satisfies send_buffer_v. Does not carry a scalar element count.

Defined in header <kamping/v2/buffer.hpp>

Structured send buffers

A structured send buffer describes per-destination data instead of a flat sequence: a range of per-rank ranges, of (rank, message) pairs, or of (value, rank) pairs. views::flatten_v and the dstl algorithms consume them. The values they send are their payload, whose datatype is value_type() (attach one with views::with_value_type).

template<typename R>
concept nested_send_buffer
template<typename R>
concept nested_send_buffer = !already_flat_buffer<std::remove_cvref_t<R>> && std::ranges::forward_range<R>
                             && std::ranges::sized_range<R> && message<std::ranges::range_value_t<R>>

A sized range of messages, indexed by destination rank.

Defined in header <kamping/v2/views/payload.hpp>

template<typename R>
concept sparse_nested_send_buffer
template<typename R>
concept sparse_nested_send_buffer = !already_flat_buffer<std::remove_cvref_t<R>> && std::ranges::forward_range<R>
                                    && destination_buffer_pair<std::ranges::range_value_t<R>>

A range of (destination, message) pairs.

Defined in header <kamping/v2/views/payload.hpp>

template<typename R>
concept value_destination_pair_buffer
template<typename R>
concept value_destination_pair_buffer = !already_flat_buffer<std::remove_cvref_t<R>> && std::ranges::forward_range<R>
                                        && value_destination_pair<std::ranges::range_value_t<R>>

A range of (value, destination) pairs.

Defined in header <kamping/v2/views/payload.hpp>

template<typename M>
concept buffer_message
template<typename M>
concept buffer_message = requires(M const& m) {
    { ptr(m) } -> std::convertible_to<void const*>;
    count(m);
}

A message accessible in place through the buffer protocol: a pointer to its data and an element count (kamping::v2::ptr / count). Contiguous ranges qualify, as do custom buffers adapted via buffer_traits or mpi_ptr() / mpi_count() members.

Defined in header <kamping/v2/views/payload.hpp>

template<typename T>
requires detail::traits_has_value_type<std::remove_cvref_t<T>>
auto value_type(T &&t)
(1)
template<typename T>
requires (!detail::traits_has_value_type<std::remove_cvref_t<T>>) && detail::has_value_type_member<T>
auto value_type(T &&t)
(2)
template<typename T>
requires (!detail::traits_has_value_type<std::remove_cvref_t<T>>) && (!detail::has_value_type_member<T>) && detail::payload_element_is_builtin<T>
auto value_type(T&&)
(3)
Returns:
  • (1) The MPI datatype of the payload of t, obtained via value_type_traits<T>::value_type(t).

  • (2) The MPI datatype of the payload of t, obtained via t.mpi_value_type().

  • (3) The predefined MPI datatype of the payload element type of T.

Defined in header <kamping/v2/views/payload.hpp>

template<typename T>
struct value_type_traits

Non-intrusive customization point for the value-type channel, analogous to mpi::experimental::buffer_traits but scoped to the v2 layer.

Defined in header <kamping/v2/views/payload.hpp>