Open14

InfiniBand

nariaki3551nariaki3551

デバイスリストの取得

  • ibv_get_device_list: 利用可能なInfiniBandデバイスのリストを取得
  • ibv_get_device_name: 特定のInfiniBandデバイスの名前を取得
#include <iostream>
#include <infiniband/verbs.h>

int main() {
    int num_devices;
    struct ibv_device **device_list = ibv_get_device_list(&num_devices);
    for (int i = 0; i < num_devices; ++i) {
        std::cout << "Device " << i << ": "  << ibv_get_device_name(device_list[i]) << std::endl;
    }
}

https://gist.github.com/nariaki3551/147fd37383cad4c08306c4f1a043d54f

nariaki3551nariaki3551

ユーザーコンテキストの作成

        struct ibv_device *device = device_list[i];
        struct ibv_context *context = ibv_open_device(device);
nariaki3551nariaki3551

プロテクションドメインの作成

        struct ibv_context *context = ibv_open_device(device);
        struct ibv_pd *pd = ibv_alloc_pd(context);
nariaki3551nariaki3551

プロテクションドメインの中にmemory regionを作成する

    size_t length = 1024;
    void *address = malloc(length);
    int access = IBV_ACCESS_LOCAL_WRITE;
    struct ibv_mr *mr = ibv_reg_mr(pd, address, length, access);
nariaki3551nariaki3551

ユーザコンテキストの中にCompletion Queue(CQ)を作成する。

最大ceq数

    int cqe = 64; // Completion Queue Entries
    void *cq_context = nullptr;
    struct ibv_cq *cq = ibv_create_cq(
      context, cqe, cq_context,
      nullptr /* struct ibv_comp_channel */,
      0 /* comp_vector */
   );
nariaki3551nariaki3551

Queue Pair(QP)の作成

    // Queue Pair(QP)を作成
    struct ibv_qp *qp;
    struct ibv_qp_init_attr qp_init_attr = {};
    qp_init_attr.qp_context = nullptr;
    qp_init_attr.send_cq = cq;
    qp_init_attr.recv_cq = cq;
    qp_init_attr.srq = nullptr;
    qp_init_attr.cap.max_send_wr = 32; // QPが保持できる最大の送信ワークリクエスト数
    qp_init_attr.cap.max_recv_wr = 32; // QPが保持できる最大の受信ワークリクエスト数
    qp_init_attr.cap.max_send_sge = 1; // 1つの送信ワークリクエストが使用できる最大のScatter/Gatherエントリ数
    qp_init_attr.cap.max_recv_sge = 1; // 1つの受信ワークリクエストが使用できる最大のScatter/Gatherエントリ数
    qp_init_attr.qp_type = IBV_QPT_RC; // Reliable Connection
    qp_init_attr.sq_sig_all = 1; // 送信キューの完了シグナルを送信
    qp = ibv_create_qp(pd, &qp_init_attr);
nariaki3551nariaki3551
    // QPを初期化
    struct ibv_qp_attr qp_attr = {};
    qp_attr.qp_state = IBV_QPS_INIT;
    qp_attr.pkey_index = 0;
    qp_attr.port_num = 1; // 使用するポート番号
    qp_attr.qp_access_flags
      = IBV_ACCESS_LOCAL_WRITE   // ローカルメモリへの書き込み
      | IBV_ACCESS_REMOTE_WRITE  // リモートメモリへの書き込み
      | IBV_ACCESS_REMOTE_READ;  // リモートメモリからの読み込み
    ibv_modify_qp(
      qp, &qp_attr,
      IBV_QP_STATE           // QPの状態
      | IBV_QP_PKEY_INDEX    // P_Keyのインデックス
      | IBV_QP_PORT          // ポート番号
      | IBV_QP_ACCESS_FLAGS  // アクセスフラグ
   );