8#include <infiniband/verbs.h> 
   12constexpr size_t kErrorStringBufferSize = 1024;
 
   14static inline void throw_with(
const char *message) {
 
   15  throw std::runtime_error(message);
 
   18template <
class... Args>
 
   19static inline void throw_with(
const char *format, Args... args) {
 
   20  char buffer[kErrorStringBufferSize];
 
   21  ::snprintf(buffer, 
sizeof(buffer), format, args...);
 
   22  throw std::runtime_error(buffer);
 
   25static inline void check_rc(
int rc, 
const char *message) {
 
   26  if (rc != 0) [[unlikely]] {
 
   27    throw_with(
"%s: %s (rc=%d)", message, ::strerror(rc), rc);
 
   31static inline void check_wc_status(
enum ibv_wc_status status,
 
   32                                   const char *message) {
 
   33  if (status != IBV_WC_SUCCESS) [[unlikely]] {
 
   34    auto errorstr = [status]() {
 
   37        return "IBV_WC_SUCCESS";
 
   38      case IBV_WC_LOC_LEN_ERR:
 
   39        return "IBV_WC_LOC_LEN_ERR";
 
   40      case IBV_WC_LOC_QP_OP_ERR:
 
   41        return "IBV_WC_LOC_QP_OP_ERR";
 
   42      case IBV_WC_LOC_EEC_OP_ERR:
 
   43        return "IBV_WC_LOC_EEC_OP_ERR";
 
   44      case IBV_WC_LOC_PROT_ERR:
 
   45        return "IBV_WC_LOC_PROT_ERR";
 
   46      case IBV_WC_WR_FLUSH_ERR:
 
   47        return "IBV_WC_WR_FLUSH_ERR";
 
   48      case IBV_WC_MW_BIND_ERR:
 
   49        return "IBV_WC_MW_BIND_ERR";
 
   50      case IBV_WC_BAD_RESP_ERR:
 
   51        return "IBV_WC_BAD_RESP_ERR";
 
   52      case IBV_WC_LOC_ACCESS_ERR:
 
   53        return "IBV_WC_LOC_ACCESS_ERR";
 
   54      case IBV_WC_REM_INV_REQ_ERR:
 
   55        return "IBV_WC_REM_INV_REQ_ERR";
 
   56      case IBV_WC_REM_ACCESS_ERR:
 
   57        return "IBV_WC_REM_ACCESS_ERR";
 
   58      case IBV_WC_REM_OP_ERR:
 
   59        return "IBV_WC_REM_OP_ERR";
 
   60      case IBV_WC_RETRY_EXC_ERR:
 
   61        return "IBV_WC_RETRY_EXC_ERR";
 
   62      case IBV_WC_RNR_RETRY_EXC_ERR:
 
   63        return "IBV_WC_RNR_RETRY_EXC_ERR";
 
   64      case IBV_WC_LOC_RDD_VIOL_ERR:
 
   65        return "IBV_WC_LOC_RDD_VIOL_ERR";
 
   66      case IBV_WC_REM_INV_RD_REQ_ERR:
 
   67        return "IBV_WC_REM_INV_RD_REQ_ERR";
 
   68      case IBV_WC_REM_ABORT_ERR:
 
   69        return "IBV_WC_REM_ABORT_ERR";
 
   70      case IBV_WC_INV_EECN_ERR:
 
   71        return "IBV_WC_INV_EECN_ERR";
 
   72      case IBV_WC_INV_EEC_STATE_ERR:
 
   73        return "IBV_WC_INV_EEC_STATE_ERR";
 
   74      case IBV_WC_FATAL_ERR:
 
   75        return "IBV_WC_FATAL_ERR";
 
   76      case IBV_WC_RESP_TIMEOUT_ERR:
 
   77        return "IBV_WC_RESP_TIMEOUT_ERR";
 
   78      case IBV_WC_GENERAL_ERR:
 
   79        return "IBV_WC_GENERAL_ERR";
 
   81        return "IBV_WC_TM_ERR";
 
   82      case IBV_WC_TM_RNDV_INCOMPLETE:
 
   83        return "IBV_WC_TM_RNDV_INCOMPLETE";
 
   85      return "UNKNOWN_ERROR";
 
   87    throw_with(
"%s: %s (status=%d)", message, errorstr, status);
 
   90static inline void check_ptr(
void *ptr, 
const char *message) {
 
   91  if (ptr == 
nullptr) [[unlikely]] {
 
   92    throw_with(
"%s: %s (errno=%d)", message, ::strerror(errno), errno);
 
   96static inline void check_errno(
int rc, 
const char *message) {
 
   97  if (rc < 0) [[unlikely]] {
 
   98    throw_with(
"%s: %s (errno=%d)", message, ::strerror(errno), errno);