Metadata and Payload Exchange#
- std::unique_ptr<Buffer> rapidsmpf::communicator::default_allocate_buffer(
- BufferResource *br,
- std::size_t size,
- MetadataPayloadExchange::AllocationMode mode
The default receive buffer allocator of a
MetadataPayloadExchange.See
MetadataPayloadExchange::AllocateBufferFn. Reserves memory inADDRESSABLE_MEMORY_TYPES, in order of preference, without overbooking. If nothing fits:With
AllocationMode::MAY_FAIL, it returnsnullptr.With
AllocationMode::MUST_SUCCEED, it overbooks host memory ifallow_overbooking_by_default()ofbrallows it, and otherwise throwsstd::runtime_error, which is a fatal, unrecoverable error for the exchange.
- Parameters:
br – The buffer resource to allocate from.
size – The size of the buffer in bytes.
mode – Whether the allocation may fail.
- Throws:
std::runtime_error – If the allocation must succeed, nothing fits, and overbooking is not allowed.
- Returns:
The buffer, or
nullptrifmodeallows failing and nothing fits.
-
class MetadataPayloadExchange#
- #include <core.hpp>
Interface for exchanging serialized metadata and payload between ranks.
The
MetadataPayloadExchangeclass defines an abstract interface for transmitting messages that contain both serialized metadata and a data payload. This abstraction simplifies scenarios where metadata and payload must be exchanged together as a single logical unit.Concrete implementations, such as
TagMetadataPayloadExchange, use theCommunicatorto implement this interface. In the future, other implementations may leverage specialized features beyond the basicCommunicatorAPI to further optimize this communication pattern.The exchange only communicates with its
peers: messages can only be sent to a peer, are only received from peers, andfinish()andis_idle()only involve peers. The peers must not include the calling rank or duplicates, and the peer relation must be symmetric: if rank A has rank B as a peer, rank B has rank A as a peer. This is not checked: if rank B does not have rank A as a peer, rank A waits forever for the termination marker of rank B and never becomes idle, and messages from rank A stay unreceived on rank B, where a later exchange reusing the operation ID may receive them. Useall_remote_ranks()to communicate with every other rank.An exchange is used in three steps:
Send messages with
send(), and callprogress(),recv()andrelease_sent()regularly.Call
finish()once no more messages will be sent.Keep calling
progress(),recv()andrelease_sent()untilis_idle()returnstrue.
Only then can the exchange be destroyed and its operation ID be reused.
Receive buffers are allocated with
allocate_buffer_fn, which is called on the thread callingprogress()and must not block or spill. Implementations follow these rules:When called with
AllocationMode::MAY_FAIL, the allocator may returnnullptrto indicate that memory is not available right now. The message is kept and the allocation is retried on later calls toprogress(). A message is never dropped or delivered without its payload.If no allocation succeeds within
allocation_timeout, one pending message is forced: the allocator is called withAllocationMode::MUST_SUCCEEDand must return a buffer or throw. An exception thrown by the allocator propagates out ofprogress()and is a fatal, unrecoverable error: the exchange can’t be used afterwards. Only one message is forced per timeout. The timeout measures time without any successful allocation, not how long a single message has waited, so a message can wait longer while other allocations keep succeeding.The order in which pending allocations are retried is implementation defined.
Payloads at rest may live on disk:
When
brhas a disk resource, implementations may move the payload of a message whose receive buffer was forced by the timeout to disk before the message is delivered, so received messages may be disk-backed. The move blocksprogress()while the payload is written. Without a disk resource, the payload is delivered in the forced buffer.Only payloads in
sendable_memory_types()of their destination can be sent.
Note
This class is not thread-safe. All methods except
sendable_memory_types()must be called from the same thread.Note
All concrete implementations are expected to provide a constructor with the following signature:
DerivedMetadataPayloadExchange( std::shared_ptr<Communicator> comm, OpID op_id, std::vector<Rank> peers, MetadataPayloadExchange::AllocateBufferFn allocate_buffer_fn, Duration allocation_timeout, BufferResource* br );
Subclassed by rapidsmpf::communicator::TagMetadataPayloadExchange
Public Types
-
enum class AllocationMode : bool#
Whether a receive buffer allocation may fail.
See
AllocateBufferFn.Values:
-
enumerator MAY_FAIL#
The allocator may return
nullptrif memory is not available now.
-
enumerator MUST_SUCCEED#
The allocator must return a buffer or throw.
-
enumerator MAY_FAIL#
-
enum class AfterSend : bool#
What happens to an outgoing message once it has been sent.
Values:
-
enumerator DISCARD#
The message is discarded.
-
enumerator RETAIN#
The message is retained and returned by
release_sent().
-
enumerator DISCARD#
-
using AllocateBufferFn = std::function<std::unique_ptr<Buffer>(BufferResource*, std::size_t, AllocationMode)>#
Function allocating a receive buffer of the given size.
The exchange calls it with its own buffer resource.
With
AllocationMode::MAY_FAIL, it may returnnullptrif memory is not available right now. WithAllocationMode::MUST_SUCCEED, it must return a buffer, for example by overbooking memory, or throw if its policy does not allow forcing an allocation. Throwing is a fatal, unrecoverable error, so only throw as the very last resort.
Public Functions
- virtual std::span<MemoryType const> sendable_memory_types(
- Rank dst
Get the memory types of payloads that can be sent to a remote rank.
Callers must only send payloads in one of these memory types. The result includes at least
ADDRESSABLE_MEMORY_TYPES, is fixed at construction, and this method may be called from any thread.- Parameters:
dst – The destination rank.
- Returns:
The sendable memory types in decreasing order of preference.
-
virtual void send(std::unique_ptr<Message> message) = 0#
Send a single message to a remote rank.
Takes ownership of a ready message and manages its transmission, including metadata sending and coordination of data transfer.
The messages sent from the calling process to a destination remote rank are guaranteed to be received in the same order as they were sent. No ordering is guaranteed between messages sent to different remote ranks.
- Parameters:
message – Message ready to be sent to a remote rank.
- virtual void send(
- std::vector<std::unique_ptr<Message>> &&messages
Send messages to remote ranks.
Takes ownership of ready messages and manages their transmission, including metadata sending and coordination of data transfer.
The messages sent from the calling process to a destination remote rank are guaranteed to be received in the same order as they were sent. No ordering is guaranteed between messages sent to different remote ranks.
- Parameters:
messages – Vector of messages ready to be sent to remote ranks.
-
virtual void progress() = 0#
Progress the communication state machine.
Advances the internal state of the communication layer by processing pending operations such as receiving metadata, setting up data transfers, completing data transfers, and cleaning up completed operations. Completed messages are stored internally and can be retrieved via recv().
This method should be called periodically to make progress on communication.
-
virtual std::vector<std::unique_ptr<Message>> recv() = 0#
Receive messages from remote ranks.
The messages received by the calling process are guaranteed to be received in the same order as they were sent by the source remote rank. No ordering is guaranteed between messages received from different remote ranks.
- Returns:
Vector of completed messages ready for local processing.
-
virtual std::vector<std::unique_ptr<Message>> release_sent() = 0#
Release retained messages whose send has completed.
Returns the messages sent with
AfterSend::RETAINwhose send has completed, as detected byprogress(). A released message is unchanged: it has its peer rank, metadata and payload, which can be reused. Messages to the same destination rank are returned in the order they were sent. No ordering is guaranteed between messages sent to different ranks.- Returns:
Vector of sent messages.
-
virtual void finish() = 0#
Signal that no more messages will be sent.
After calling this method, no further calls to send() are permitted. The implementation sends protocol-level termination markers to all peers so that each receiver knows the exact number of application messages to expect. This enables safe reuse of operation IDs: once all termination markers have been received and all expected messages processed, the communication layer considers itself idle and the tag/op_id can be reused.
Calling it again has no effect.
-
virtual bool is_finished() const = 0#
Check if finish() has been called.
- Returns:
trueif finish() has been called, otherwisefalse.
-
virtual bool is_idle() const = 0#
Check if the communication layer is currently idle.
Indicates whether there are any active or pending communication operations. Before finish() is called, a return value of
truemeans no I/O operations are in progress, and no messages wait to be returned byrecv()orrelease_sent(). After finish() is called,trueadditionally requires that all peers have sent their termination markers and all expected messages have been received, meaning the op_id can safely be reused.- Returns:
trueif the communication layer is idle;falseif activity is ongoing.
-
class Message#
- #include <core.hpp>
Message class for communication.
This class contains the essential information needed for communication: data payload, metadata, and peer rank (source/destination).
Public Functions
- Message(
- Rank peer_rank,
- std::vector<std::uint8_t> &&metadata,
- std::unique_ptr<Buffer> data = nullptr,
- AfterSend after_send = AfterSend::DISCARD
Construct a new Message.
- Parameters:
peer_rank – Destination (outgoing) or source (incoming) rank.
metadata – Serialized metadata.
data – Data buffer (can be nullptr for metadata-only messages).
after_send – What happens to an outgoing message once it has been sent.
-
inline constexpr Rank peer_rank() const noexcept#
Get the destination rank for outgoing or source rank for incoming messages.
- Returns:
The rank of the destination or source.
-
inline constexpr AfterSend after_send() const noexcept#
Get what happens to an outgoing message once it has been sent.
- Returns:
Whether the message is discarded or retained for
release_sent().
- inline constexpr std::vector<std::uint8_t> const &metadata(
Get the serialized metadata for this message.
This metadata is sent first to inform the receiver about the incoming message.
- Returns:
The serialized metadata.
-
std::vector<std::uint8_t> release_metadata() noexcept#
Release ownership of the metadata.
This is typically called when transferring metadata to the communication layer.
- Returns:
Metadata with ownership transferred.
-
Buffer const *data() const#
Get the data buffer for this message.
- Returns:
The data buffer, or nullptr if no data.
-
std::unique_ptr<Buffer> release_data() noexcept#
Release ownership of the data buffer.
This is typically called when transferring a buffer to the communication layer.
- Returns:
Data buffer with ownership transferred, or nullptr if no data.
-
void set_data(std::unique_ptr<Buffer> buffer)#
Set the data buffer for this message.
This method can be used by implementations to update the data buffer.
- Parameters:
buffer – Data buffer to be set.
-
class TagMetadataPayloadExchange : public rapidsmpf::communicator::MetadataPayloadExchange#
- #include <tag.hpp>
Tag-based implementation of MetadataPayloadExchange.
This implementation provides the same communication protocol as TagMetadataPayloadExchange but works with the abstract Message.
Public Types
Public Functions
- std::shared_ptr<Communicator> comm,
- OpID op_id,
- std::vector<Rank> peers,
- AllocateBufferFn allocate_buffer_fn,
- Duration allocation_timeout,
- BufferResource *br,
- ForcedReceive forced_receive = ForcedReceive::MOVE_TO_DISK
Constructor for TagMetadataPayloadExchange.
See
MetadataPayloadExchangefor how receive buffers are allocated, how the allocation timeout forces progress, and when payloads are moved to disk.- Parameters:
comm – The communicator to use for operations.
op_id – The operation ID for tagging messages.
peers – The ranks to communicate with. See
MetadataPayloadExchange.allocate_buffer_fn – Function to allocate buffers for incoming data.
allocation_timeout – Progress timeout for receive buffer allocations.
br – Buffer resource used to move payloads to disk and whose statistics track communication operations. Must not be
nullptr.forced_receive – What happens to the payload of a message whose receive buffer was forced.
- Throws:
std::out_of_range – If a peer is not a rank of
comm.std::invalid_argument – If
peerscontains the calling rank or duplicates.
-
~TagMetadataPayloadExchange() noexcept override#
Destructor.
Logs a warning if the exchange is destroyed before
finish()has been called andis_idle()returnstrue.
-
virtual void send(std::unique_ptr<Message> message) override#
Send a single message to a remote rank.
Takes ownership of a ready message and manages its transmission, including metadata sending and coordination of data transfer.
The messages sent from the calling process to a destination remote rank are guaranteed to be received in the same order as they were sent. No ordering is guaranteed between messages sent to different remote ranks.
- Parameters:
message – Message ready to be sent to a remote rank.
- Throws:
std::invalid_argument – if the destination is not a peer or the message’s payload is not in
sendable_memory_types()of its destination.
- inline virtual std::span<MemoryType const> sendable_memory_types(
- Rank dst
Get the memory types of payloads that can be sent to a remote rank.
Callers must only send payloads in one of these memory types. The result includes at least
ADDRESSABLE_MEMORY_TYPES, is fixed at construction, and this method may be called from any thread.Returns
ADDRESSABLE_MEMORY_TYPESfor every remote rank.- Parameters:
dst – The destination rank.
- Returns:
The sendable memory types in decreasing order of preference.
- virtual void send(
- std::vector<std::unique_ptr<Message>> &&messages
Send messages to remote ranks.
Takes ownership of ready messages and manages their transmission, including metadata sending and coordination of data transfer.
The messages sent from the calling process to a destination remote rank are guaranteed to be received in the same order as they were sent. No ordering is guaranteed between messages sent to different remote ranks.
- Parameters:
messages – Vector of messages ready to be sent to remote ranks.
- Throws:
std::invalid_argument – if a destination is not a peer or a message’s payload is not in
sendable_memory_types()of its destination.
-
virtual void progress() override#
Progress the communication state machine.
Advances the internal state of the communication layer by processing pending operations such as receiving metadata, setting up data transfers, completing data transfers, and cleaning up completed operations. Completed messages are stored internally and can be retrieved via recv().
This method should be called periodically to make progress on communication.
Advances the communication state machine by:
Receiving incoming message metadata
Setting up data transfers
Handling completed data transfers
Cleaning up completed operations
Receive buffers are allocated in message order per peer. While a message from a peer waits for a buffer, later messages from that peer wait behind it.
Any exception thrown by the receive buffer allocator, for example when it is not allowed to force an allocation, propagates out of this function and is a fatal, unrecoverable error.
When a forced receive buffer is moved to disk, this call blocks until the payload is written.
-
virtual std::vector<std::unique_ptr<Message>> recv() override#
Receive messages from remote ranks.
The messages received by the calling process are guaranteed to be received in the same order as they were sent by the source remote rank. No ordering is guaranteed between messages received from different remote ranks.
- Returns:
Vector of completed messages ready for local processing.
- virtual std::vector<std::unique_ptr<Message>> release_sent(
Release retained messages whose send has completed.
Returns the messages sent with
AfterSend::RETAINwhose send has completed, as detected byprogress(). A released message is unchanged: it has its peer rank, metadata and payload, which can be reused. Messages to the same destination rank are returned in the order they were sent. No ordering is guaranteed between messages sent to different ranks.- Returns:
Vector of sent messages.
-
virtual void finish() override#
Signal that no more messages will be sent.
After calling this method, no further calls to send() are permitted. The implementation sends protocol-level termination markers to all peers so that each receiver knows the exact number of application messages to expect. This enables safe reuse of operation IDs: once all termination markers have been received and all expected messages processed, the communication layer considers itself idle and the tag/op_id can be reused.
Calling it again has no effect.
-
virtual bool is_finished() const override#
Check if finish() has been called.
- Returns:
trueif finish() has been called, otherwisefalse.
-
virtual bool is_idle() const override#
Check if the communication layer is currently idle.
Indicates whether there are any active or pending communication operations. Before finish() is called, a return value of
truemeans no I/O operations are in progress, and no messages wait to be returned byrecv()orrelease_sent(). After finish() is called,trueadditionally requires that all peers have sent their termination markers and all expected messages have been received, meaning the op_id can safely be reused.- Returns:
trueif the communication layer is idle;falseif activity is ongoing.