Dockerを用いたUnified Communication X (UCX) の動作確認

## はじめに
汎用CPUの性能向上が鈍化する中、**ある特定の問題領域に特化したアクセラレータの利用**が検討されるようになってきている。GPUはその代表的な存在であり、昨今の機械学習やAI向けに広く利用されている。より大規模な問題を解くニーズが高まっていることから、GPUを用いた分散型コンピューティングシステムも利用され始めている。
GPUの性能向上はムーアの法則を超える速度で急速に進んできた背景から、**GPUを用いた分散型コンピューティングシステムでは、ネットワークの通信速度や遅延がシステム全体のボトルネック**になると認識されている。これに対して、NVIDIAは、RDMAの技術を用いることでネットワークの高速化を達成し、GPUを用いた分散型コンピューティングシステムの性能を高めることに成功している。

上記から、**GPUに限らず、計算能力の高いアクセラレータを用いた分散型コンピューティングシステム向けのアプリを開発する際には、ネットワークの高速化も検討する必要がある**といえる。しかしながら、RDMAを含む通信プロトコルの仕様に合わせたネットワーク部の実装は、それらの専門的な知識を必要とするために敷居が高いといえる。Open UCX（以降は、UCX）は、**RDMAを含む通信プロトコル仕様の差異を吸収する抽象的なAPI**を提供することで、高速ネットワークを利用したアプリ開発を容易にするものとして注目されている。

#### 想定読者
広帯域且つ低遅延ネットワークを活用したアプリ開発に関心がある方

#### 注意事項
筆者はOpen UCXの専門家ではないため、本記事には間違いが含まれる可能性がある。
尚、以降はOpen UCXをUCXと表記する。

#### 目的
読者に以下の知識を提供すること
・UCXの概要
・Dockerを用いたUCXのインストールと環境構築の手順
・UCXに予め用意されているテストアプリを用いた動作確認の手順

## 目次
1. UCXとは
2. 環境構築
3. 動作確認

## 1. UCXとは
UCXは、**広帯域且つ低遅延ネットワーク向けに最適化された通信フレームワーク**です。
従来、高速インターフェースを活用したアプリを開発する場合、デバイス上のメモリや通信プロトコルの違いに合わせて、ネットワーク側の実装方法を改良しなければならない部分があった。
UCXは、以下の図に示すように、RDMAを含む通信プロトコルに対応したAPIを提供することでアプリ開発者がアプリの開発に専念できるようにしたものといえる。
![Screenshot from 2022-07-31 12-28-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756450/53b040e3-a708-94d2-5975-69ea0962da01.png)
参照元：https://openucx.readthedocs.io/en/master/
## 2. 環境構築
dockerコンテナを2つ用意し、それらの間でUCXを用いた通信試験を行う。
図に示すように、各コンテナはub1とub2と呼ぶこととする。

![220731_UCX_env.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756450/d12bbbff-286a-75f0-418f-5ff0130bcea7.png)


#### Version情報
dockerコンテナのOSとKernelのVersion
・OS      : Ubuntu 22.04.1 LTS
・Kernel  : 5.15.0-41-generic

UCXのVersion
・UCX     : 1.13.0
 
### 2.1 docker imageの作成
下記のようにDockerfileを用意する。
UCXはDeveloper向けのものをインストールした。
尚、今回は使用しなかったが、デバッグ用にpingを予めインストールしている。
（DockerfileのMAINTAINERの部分は適宜修正をお願いします。）
```sh:Dockerfile
FROM ubuntu
MAINTAINER xxxx <xxx@xxx.co.jp>
SHELL ["/bin/bash", "-l", "-c"]
RUN apt-get update -y
RUN apt-get upgrade -y
RUN apt-get update \
 && apt-get install -y --no-install-recommends \
    iproute2 \
    iputils-ping \
 && apt-get -y clean \
 && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /home/ubuntu/Git/
WORKDIR /home/ubuntu/Git/
RUN apt-get update -y
RUN apt install git vim -y
RUN git clone --recursive  https://github.com/openucx/ucx.git
RUN apt-get install autoconf automake libtool -y
RUN apt install build-essential -y
RUN apt install valgrind -y
RUN mkdir install-debug
WORKDIR  ucx/
RUN ./autogen.sh
RUN ./contrib/configure-devel --prefix=$PWD/install-debug
RUN make -j4
RUN make install
```
Dockerfileがあるディレクトリにて、以下のコマンドを実行する。
```sh:
sudo docker build -t my-ub:1.0 . 
```
### 2.2 dockerコンテナの作成
作成したイメージを指定して、dockerコンテナを2つ用意する。
今回は、コンテナの名称をub1とub2としている。
```sh:
sudo docker run -it --privileged --name ub1 my-ub:1.0 /bin/bash
```
```sh:
sudo docker run -it --privileged --name ub2 my-ub:1.0 /bin/bash
```
### 3 動作確認
作成した2つのdockerコンテナ間でUCXを用いた通信の動作確認を実施する。
サーバ側をub1とし、クライアント側をub2とする。

### 3.1 サーバ側の設定
ub1にて、以下のコマンドを実行する。
```sh:ub1で実行 
cd /home/ubuntu/Git/ucx
./src/tools/perf/ucx_perftest -c 0
```
実行後には、通信確立の待受状態となる。
```sh:ub1の表示 
Waiting for connection...
```

### 3.2 クライアント側の設定
ub2にて、以下のコマンドを実行する。
尚、IPアドレスはサーバ側（ub1）のIPアドレスとして、172.17.0.2を指定した。
```sh:ub2で実行 
cd /home/ubuntu/Git/ucx
./src/tools/perf/ucx_perftest 172.17.0.2 -t tag_lat -c 1
```
実行後には、通信試験が開始され、結果が表示される。
```sh:ub2の表示 
+--------------+--------------+------------------------------+---------------------+-----------------------+
|              |              |        latency (usec)        |   bandwidth (MB/s)  |  message rate (msg/s) |
+--------------+--------------+----------+---------+---------+----------+----------+-----------+-----------+
|    Stage     | # iterations | 50.0%ile | average | overall |  average |  overall |  average  |  overall  |
+--------------+--------------+----------+---------+---------+----------+----------+-----------+-----------+
[thread 0]             92296      5.000     5.417     5.417        1.41       1.41      184588      184588
[thread 0]            184064      5.500     5.449     5.433        1.40       1.40      183535      184062
[thread 0]            274506      5.000     5.528     5.464        1.38       1.40      180883      183002
[thread 0]            362857      5.000     5.659     5.512        1.35       1.38      176702      181427
[thread 0]            454063      5.000     5.482     5.506        1.39       1.39      182412      181624
[thread 0]            543396      5.000     5.597     5.521        1.36       1.38      178666      181131
[thread 0]            635834      5.000     5.409     5.505        1.41       1.39      184875      181666
[thread 0]            727127      5.000     5.477     5.501        1.39       1.39      182585      181781
[thread 0]            819413      5.000     5.418     5.492        1.41       1.39      184571      182091
[thread 0]            911762      5.000     5.414     5.484        1.41       1.39      184696      182351
Final:               1000000      5.000     5.371     5.474        1.42       1.39      186198      182684
```
ub1の表示を確認すると、ub2との通信確立が確認できる。
```sh:ub1の表示 
Waiting for connection...
Accepted connection from 172.17.0.3:32884
+----------------------------------------------------------------------------------------------------------+
| API:          protocol layer                                                                             |
| Test:         tag match latency                                                                          |
| Data layout:  (automatic)                                                                                |
| Send memory:  host                                                                                       |
| Recv memory:  host                                                                                       |
| Message size: 8                                                                                          |
+----------------------------------------------------------------------------------------------------------+
```

## 4. まとめ
UCXの概要及び、UCXを用いた通信試験用の環境構築と動作確認の方法を紹介した。

## 参考文献
[1] Open UCX : https://openucx.readthedocs.io/en/master/
[2] UCX GitHub : https://github.com/openucx/ucx