Program Listing for File Sender.cpp

Return to documentation for file (BackendLibfabric/Sender.cpp)

#include "Sender.hpp"

netio3::NetioStatus netio3::libfabric::Sender::send_data(const std::span<const iovec> data,
                                                         const std::span<fid_mr*> mrs,
                                                         std::uint64_t key,
                                                         fi_addr_t addr) const
{
  ZoneScoped;
  if (data.size() != mrs.size()) {
    ers::error(FailedSend(ERS_HERE,
                          m_endpoint.get().get_address().address(),
                          m_endpoint.get().get_address().port(),
                          "Failed sending message because of mismatched data and memory regions."));
    return NetioStatus::FAILED;
  }
  std::vector<void*> descs{};
  descs.reserve(mrs.size());
  std::transform(
    mrs.begin(), mrs.end(), std::back_inserter(descs), [](auto* mr) { return fi_mr_desc(mr); });
  fi_msg msg{};
  msg.msg_iov = data.data(); /* scatter-gather array */
  msg.desc = descs.data();
  msg.iov_count = data.size();
  msg.addr = addr;
  msg.context = reinterpret_cast<void*>(key);
  msg.data = 0;

  if (m_endpoint.get().get_endpoint().ep == nullptr ||
      m_endpoint.get().get_endpoint().ep->msg == nullptr) {
    ers::error(FailedSend(ERS_HERE,
                          m_endpoint.get().get_address().address(),
                          m_endpoint.get().get_address().port(),
                          "Failed sending message because of null message or null endpoint."));
    return NetioStatus::FAILED;
  }

  ERS_DEBUG(2, std::format("sending iov message with key {}", msg.context));
  const uint64_t flags = FI_INJECT_COMPLETE;  // | FI_INJECT;
  const auto ret = fi_sendmsg(m_endpoint.get().get_endpoint().ep.get(), &msg, flags);
  if (ret == -FI_EAGAIN) {
    ERS_DEBUG(1, "Send failed with result: EAGAIN");
    return NetioStatus::NO_RESOURCES;
  }
  ERS_DEBUG(1, std::format("Send completed with result: {}", ret));
  if (ret != 0) {
    ers::error(FailedSend(ERS_HERE,
                          m_endpoint.get().get_address().address(),
                          m_endpoint.get().get_address().port(),
                          std::format("Failed to send message error (IOV count 1, key {}) - {}",
                                      key,
                                      fi_strerror(-ret))));
    return NetioStatus::FAILED;
  }
  return NetioStatus::OK;
}