Program Listing for File Helpers.hpp

Return to documentation for file (BackendLibfabric/Helpers.hpp)

#ifndef NETIO3BACKEND_BACKENDLIBFABRIC_HELPERS_HPP
#define NETIO3BACKEND_BACKENDLIBFABRIC_HELPERS_HPP

#include <rdma/fabric.h>
#include <rdma/fi_eq.h>
#include <rdma/fi_endpoint.h>

#include "netio3-backend/Netio3Backend.hpp"
#include "netio3-backend/Issues.hpp"

namespace netio3::libfabric {
  struct CqCmFds {
    int cq_fd;
    int cm_fd;
  };

  struct FiInfoDeleter {
    void operator()(fi_info* info) const
    {
      if (info != nullptr) {
        fi_freeinfo(info);
      }
    }
  };

  template<typename T>
  concept HasFidConcept = requires(T obj) {
    {
      obj.fid
    };
  };

  template<HasFidConcept T>
  class FiCloseDeleter
  {
  public:
    explicit FiCloseDeleter(EndPointAddress address = {}, std::string message = "") :
      m_address{std::move(address)}, m_message{std::move(message)}
    {}

    void operator()(T* obj) const
    {
      if (obj != nullptr) {
        const auto ret = fi_close(&obj->fid);
        if (ret != FI_SUCCESS) {
          ers::error(FailedCloseEndpoint(
            ERS_HERE,
            m_address.address(),
            m_address.port(),
            std::format("{}, error {} - {}", m_message, ret, fi_strerror(-ret))));
        }
      }
    }

  private:
    EndPointAddress m_address;
    std::string m_message;
  };

  using FiInfoUniquePtr = std::unique_ptr<fi_info, FiInfoDeleter>;
  template<HasFidConcept T>
  using FiCloseUniquePtr = std::unique_ptr<T, FiCloseDeleter<T>>;

  class FiInfoWrapper
  {
  public:
    FiInfoWrapper() : m_info{fi_allocinfo()} {}

    [[nodiscard]] fi_info* get() const { return m_info.get(); }

  private:
    FiInfoUniquePtr m_info{nullptr};
  };

  static constexpr std::size_t MAX_CQ_EVENTS = 10;
  static constexpr int MAX_CQ_ENTRIES = 4096;

  struct Endpoint {
    FiInfoUniquePtr fi{nullptr};
    FiCloseUniquePtr<fid_cq> rcq{nullptr};
    FiCloseUniquePtr<fid_cq> cq{nullptr};
    FiCloseUniquePtr<fid_eq> eq{nullptr};
    FiCloseUniquePtr<fid_ep> ep{nullptr};
    int eqfd{-1};
    int cqfd{-1};
    std::size_t cq_size{MAX_CQ_EVENTS};
  };

  [[nodiscard]] std::string get_provider(NetworkMode mode);

  [[nodiscard]] EndPointAddress peer_address(fid_ep* ep);

}  // namespace netio3::libfabric

#endif  // NETIO3BACKEND_BACKENDLIBFABRIC_HELPERS_HPP