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 "Issues.hpp"
#include "netio3-backend/Netio3Backend.hpp"
#include "netio3-backend/Issues.hpp"

namespace netio3::libfabric {
  struct CqCmFds {
    int cq_fd{};
    int rcq_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 FiCloseEndpointDeleter
  {
  public:
    explicit FiCloseEndpointDeleter(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(FailedCloseActiveEndpoint(
            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;
  };

  template<HasFidConcept T>
  class FiCloseDeleter
  {
  public:
    explicit FiCloseDeleter(std::string message = "") :
      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(LibFabricError(
            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 FiCloseEndpointUniquePtr = std::unique_ptr<T, FiCloseEndpointDeleter<T>>;
  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 int LIBFABRIC_MAJOR_VERSION = 2;
  static constexpr int LIBFABRIC_MINOR_VERSION = 2;

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

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

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

  [[nodiscard]] int get_address_format(const EndPointAddress& address);

  [[nodiscard]] fi_ep_type get_ep_type(NetworkMode mode);

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

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

  [[nodiscard]] fi_info* get_fi_info(const EndPointAddress& address,
                                     NetworkMode mode,
                                     std::uint64_t info_flags);

    [[nodiscard]] EndpointCapabilities get_endpoint_capabilities(
      const ConnectionParameters& connection_params);
}  // namespace netio3::libfabric

#endif  // NETIO3BACKEND_BACKENDLIBFABRIC_HELPERS_HPP