communicator.hpp
1 
5 #pragma once
6 
7 #include <cstdint>
8 #include <cstdlib>
9 #include <memory>
10 #include <ostream>
11 #include <stdexcept>
12 #include <string>
13 #include <unordered_map>
14 #include <utility>
15 #include <vector>
16 
17 #include <rapidsmpf/communicator/logger.hpp>
18 #include <rapidsmpf/error.hpp>
19 #include <rapidsmpf/memory/buffer.hpp>
20 #include <rapidsmpf/progress_thread.hpp>
21 
26 namespace rapidsmpf {
27 
35 using Rank = std::int32_t;
36 
45 using OpID = std::int32_t;
46 
54 using StageID = std::int32_t;
55 
84 class Tag {
85  public:
90  using StorageT = std::int32_t;
91 
93  static constexpr int stage_id_bits{3};
94 
96  static constexpr StorageT stage_id_mask{(1 << stage_id_bits) - 1};
97 
99  static constexpr int op_id_bits{20};
100 
102  static constexpr StorageT op_id_mask{
103  ((1 << (op_id_bits + stage_id_bits)) - 1) ^ stage_id_mask
104  };
105 
115  constexpr Tag(OpID const op, StageID const stage)
116  : tag_{
117  (static_cast<StorageT>(op) << stage_id_bits) | static_cast<StorageT>(stage)
118  } {
119  RAPIDSMPF_EXPECTS(
120  stage >= 0 && stage < (1 << stage_id_bits),
121  "Invalid stage value",
122  std::overflow_error
123  );
124  RAPIDSMPF_EXPECTS(
125  op >= 0 && op < (1 << op_id_bits), "Invalid OpID value", std::overflow_error
126  );
127  }
128 
133  [[nodiscard]] static constexpr std::size_t bit_length() noexcept {
134  return op_id_bits + stage_id_bits;
135  }
136 
141  [[nodiscard]] static constexpr StorageT max_value() noexcept {
142  return (1 << bit_length()) - 1;
143  }
144 
149  constexpr operator StorageT() const noexcept {
150  return tag_;
151  }
152 
157  [[nodiscard]] constexpr OpID op() const noexcept {
158  return (tag_ & op_id_mask) >> stage_id_bits;
159  }
160 
165  [[nodiscard]] constexpr StageID stage() const noexcept {
166  return tag_ & stage_id_mask;
167  }
168 
169  private:
170  StorageT const tag_;
171 };
172 
190  public:
197  class Future {
198  public:
199  Future() = default;
200  virtual ~Future() noexcept = default;
201  Future(Future&&) = default;
207  Future& operator=(Future&&) = default;
208  Future(Future const&) = delete;
209  Future& operator=(Future const&) = delete;
210  };
211 
212  protected:
213  Communicator() = default;
214 
215  public:
216  virtual ~Communicator() noexcept = default;
217 
222  [[nodiscard]] virtual Rank rank() const = 0;
223 
228  [[nodiscard]] virtual Rank nranks() const = 0;
229 
246  [[nodiscard]] virtual std::unique_ptr<Future> send(
247  std::unique_ptr<std::vector<std::uint8_t>> msg, Rank rank, Tag tag
248  ) = 0;
249 
268  [[nodiscard]] virtual std::unique_ptr<Future> send(
269  std::unique_ptr<Buffer> msg, Rank rank, Tag tag
270  ) = 0;
271 
291  [[nodiscard]] virtual std::unique_ptr<Future> recv(
292  Rank rank, Tag tag, std::unique_ptr<Buffer> recv_buffer
293  ) = 0;
294 
307  [[nodiscard]] virtual std::unique_ptr<Future> recv_sync_host_data(
308  Rank rank, Tag tag, std::unique_ptr<std::vector<std::uint8_t>> synced_buffer
309  ) = 0;
310 
320  [[nodiscard]] virtual std::pair<std::unique_ptr<std::vector<std::uint8_t>>, Rank>
321  recv_any(Tag tag) = 0;
322 
333  [[nodiscard]] virtual std::unique_ptr<std::vector<std::uint8_t>> recv_from(
334  Rank src, Tag tag
335  ) = 0;
336 
344  [[nodiscard]] virtual std::
345  pair<std::vector<std::unique_ptr<Future>>, std::vector<std::size_t>>
346  test_some(std::vector<std::unique_ptr<Future>>& future_vector) = 0;
347 
354  std::vector<std::size_t> virtual test_some(
355  std::unordered_map<std::size_t, std::unique_ptr<Communicator::Future>> const&
356  future_map
357  ) = 0;
358 
366  [[nodiscard]] virtual bool test(std::unique_ptr<Communicator::Future>& future) = 0;
367 
374  [[nodiscard]] virtual std::vector<std::unique_ptr<Buffer>> wait_all(
375  std::vector<std::unique_ptr<Communicator::Future>>&& futures
376  ) = 0;
377 
385  [[nodiscard]] virtual std::unique_ptr<Buffer> wait(
386  std::unique_ptr<Future> future
387  ) = 0;
388 
397  [[nodiscard]] std::unique_ptr<Buffer> virtual release_data(
398  std::unique_ptr<Communicator::Future> future
399  ) = 0;
400 
411  [[nodiscard]] std::
412  unique_ptr<std::vector<std::uint8_t>> virtual release_sync_host_data(
413  std::unique_ptr<Communicator::Future> future
414  ) = 0;
415 
420  [[nodiscard]] virtual std::shared_ptr<Logger> const& logger() = 0;
421 
426  [[nodiscard]] virtual std::shared_ptr<ProgressThread> const&
427  progress_thread() const = 0;
428 
433  [[nodiscard]] virtual std::string str() const = 0;
434 };
435 
437 #ifdef RAPIDSMPF_HAVE_UCXX
438 constexpr bool COMM_HAVE_UCXX = true;
439 #else
440 constexpr bool COMM_HAVE_UCXX = false;
441 #endif
442 
444 #ifdef RAPIDSMPF_HAVE_MPI
445 constexpr bool COMM_HAVE_MPI = true;
446 #else
447 constexpr bool COMM_HAVE_MPI = false;
448 #endif
449 
460 inline std::ostream& operator<<(std::ostream& os, Communicator const& obj) {
461  os << obj.str();
462  return os;
463 }
464 
465 } // namespace rapidsmpf
Buffer representing device or host memory.
Definition: buffer.hpp:47
Abstract base class for asynchronous operation within the communicator.
Future(Future const &)=delete
Not copyable.
Future & operator=(Future &&)=default
Move assignment.
Future(Future &&)=default
Movable.
Future & operator=(Future const &)=delete
Not copy-assignable.
Abstract base class for a communication mechanism between nodes.
virtual std::unique_ptr< std::vector< std::uint8_t > > recv_from(Rank src, Tag tag)=0
Receives a message from a specific rank (blocking).
virtual Rank nranks() const =0
Retrieves the total number of ranks.
virtual std::string str() const =0
Provides a string representation of the communicator.
virtual std::unique_ptr< Buffer > release_data(std::unique_ptr< Communicator::Future > future)=0
Retrieves data associated with a completed future.
virtual Rank rank() const =0
Retrieves the rank of the current node.
virtual std::shared_ptr< Logger > const & logger()=0
Retrieves the logger associated with this communicator.
virtual std::shared_ptr< ProgressThread > const & progress_thread() const =0
Retrieves the progress thread associated with this communicator.
virtual bool test(std::unique_ptr< Communicator::Future > &future)=0
Test for completion of a single future.
virtual std::unique_ptr< Future > recv_sync_host_data(Rank rank, Tag tag, std::unique_ptr< std::vector< std::uint8_t >> synced_buffer)=0
Receives a message from a specific rank to an allocated (synchronized) host buffer....
virtual std::vector< std::unique_ptr< Buffer > > wait_all(std::vector< std::unique_ptr< Communicator::Future >> &&futures)=0
Wait for completion of all futures and return their data buffers.
virtual std::pair< std::vector< std::unique_ptr< Future > >, std::vector< std::size_t > > test_some(std::vector< std::unique_ptr< Future >> &future_vector)=0
Tests for completion of multiple futures.
virtual std::unique_ptr< std::vector< std::uint8_t > > release_sync_host_data(std::unique_ptr< Communicator::Future > future)=0
Retrieves synchronized host data associated with a completed future. When the future is completed,...
virtual std::unique_ptr< Future > recv(Rank rank, Tag tag, std::unique_ptr< Buffer > recv_buffer)=0
Receives a message from a specific rank to a buffer. Use release_data to extract the data out of the ...
virtual std::unique_ptr< Buffer > wait(std::unique_ptr< Future > future)=0
Wait for a future to complete and return the data buffer.
virtual std::unique_ptr< Future > send(std::unique_ptr< std::vector< std::uint8_t >> msg, Rank rank, Tag tag)=0
Sends a host message to a specific rank.
virtual std::pair< std::unique_ptr< std::vector< std::uint8_t > >, Rank > recv_any(Tag tag)=0
Receives a message from any rank (blocking).
A logger base class for handling different levels of log messages.
Definition: logger.hpp:37
A progress thread that can execute arbitrary functions.
A tag used for identifying messages in a communication operation.
static constexpr StorageT stage_id_mask
Mask for the stage ID.
constexpr Tag(OpID const op, StageID const stage)
Constructs a tag.
constexpr OpID op() const noexcept
Extracts the operation ID from the tag.
constexpr StageID stage() const noexcept
Extracts the stage ID from the tag.
static constexpr int stage_id_bits
Number of bits for the stage ID.
static constexpr StorageT max_value() noexcept
Returns the max value of the tag.
static constexpr int op_id_bits
Number of bits for the operation ID.
static constexpr std::size_t bit_length() noexcept
Returns the max number of bits used for the tag.
std::int32_t StorageT
The physical data type to store the tag.
static constexpr StorageT op_id_mask
Mask for the operation ID.
RAPIDS Multi-Processor interfaces.
Definition: backend.hpp:14
std::int32_t Rank
The rank of a node (e.g. the rank of a MPI process), or world size (total number of ranks).
std::int32_t StageID
Identifier for a stage of a communication operation.
constexpr bool COMM_HAVE_MPI
Whether RapidsMPF was built with the MPI Communicator.
std::int32_t OpID
Operation ID defined by the user. This allows users to concurrently execute multiple operations,...
std::ostream & operator<<(std::ostream &os, Communicator const &obj)
Overloads the stream insertion operator for the Communicator class.
constexpr bool COMM_HAVE_UCXX
Whether RapidsMPF was built with the UCXX Communicator.