以前からGPUを入手したらHPC(High Performance Computing)の勉強をしたいと思っていました。ただ、環境構築は(色々な意味で)非常に面倒くさい作業です。何とか手軽に学習環境を構築出来ないかと考えていた時に、Docker、Docker Composeを活用した環境構築を思いつきました。本記事ではCUDAやOpenCLを初めとするC言語をベースとしたHPC用ライブラリやPythonでHPCを実現するPyCUDAやPyOpenCLが実行出来るコンテナ環境を構築します。
最終目標
Dockerを用いてコンテナ上にHPC関連ライブラリの開発環境を構築します。また、ポートの開放も設定し、SSHで乗り込める用にします。これはVSCodeのRemote Development Extensionの機能を活用して、SSHでコンテナに乗り込んで開発が出来る環境を実現する為に行います。
導入するライブラリ
導入するライブラリを一覧にまとめます。このうち、OpenCLとPyCUDA、PyOpenCL以外のライブラリはNVIDIA HPC SDKに含まれている物をインストールします。
名称 | 言語 | 備考 |
---|---|---|
CUDA | C | CUDAのデフォルトバージョンCベースの独自拡張 |
CUDA | Fortran1 | NVIDIA公式のコンパイラnvfortranがリリース |
OpenCL | C | CUDAと二大巨頭と言われる並列計算ライブラリ |
PyCUDA | Python | PythonからCUDAを実行するためのラッパー |
PyOpenCL | Python | PythonからOpenCLを実行するためのラッパー |
OpenMP | C | マルチコアCPUを手軽に活用出来るライブラリ |
OpenACC | C | GPUを用いた並列計算用ライブラリ |
Docker Composeeを用いた環境構築
環境構築に使用するDockerfileとdocker-compose.ymlを以下の様に作成します。Docker Composeは本来複数のコンテナを起動し、コンテナ間でネットワークを構築する環境構築に便利なアプリケーションですが、筆者の場合Makeの様な使い方をしていることが多い様に思います。Dockerfileは一部過去の公式コンテナイメージの中身を参考に作成しました。cuDNN、PyCUDA、OpenCL、PyOpenCLはNVIDIA HPC SDKには含まれていない為、CUDA10.1版の公式コンテナイメージをベースにインストールする方法を採用しています。また、コンテナにSSHでログイン出来る様に、ログインパスワードをビルド時に引数として渡して設定出来る様にしています。
2020/9/21追記: 今回の構築では、最終的クライアント端末からリモートSSHログインを実施して開発環境として使うことを目的に環境構築を行っています。故にクライアント端末からアクセスする運用を実施しない場合はDockerfile末尾のSSHの設定部分(# Setup SSHの部分)の記載は不要です。
FROM nvidia/cuda:10.1-cudnn7-devel
ARG PASSWD
ENV CUDA_VERSION=10.1
# Upgrade OS
RUN apt update && apt upgrade -y
# Install some ruquirements
RUN apt install -y bash-completion build-essential gfortran vim wget git openssh-server python3-pip
# Install NVIDA HPC SDK
RUN wget https://developer.download.nvidia.com/hpc-sdk/nvhpc-20-7_20.7_amd64.deb \
https://developer.download.nvidia.com/hpc-sdk/nvhpc-2020_20.7_amd64.deb \
https://developer.download.nvidia.com/hpc-sdk/nvhpc-20-7-cuda-multi_20.7_amd64.deb
RUN apt install -y ./nvhpc-20-7_20.7_amd64.deb ./nvhpc-2020_20.7_amd64.deb ./nvhpc-20-7-cuda-multi_20.7_amd64.deb
# Install cuDNN
ENV CUDNN_VERSION=7.6.5.32
RUN apt install -y --no-install-recommends libcudnn7=$CUDNN_VERSION-1+cuda$CUDA_VERSION && \
apt-mark hold libcudnn7 && rm -rf /var/lib/apt/lists/*
# Install OpenCL
RUN apt update && apt install -y --no-install-recommends ocl-icd-opencl-dev && rm -rf /var/lib/apt/lists/*
RUN ln -fs /usr/bin/python3 /usr/bin/python
RUN ln -fs /usr/bin/pip3 /usr/bin/pip
ENV PATH=/usr/local/cuda-$CUDA_VERSION/bin:$PATH
ENV CPATH=/usr/local/cuda-$CUDA_VERSION/include:$CPATH
ENV LIBRARY_PATH=/usr/local/cuda-$CUDA_VERSION/lib64:$LIBRARY_PATH
# Install PyCUDA
RUN pip install pycuda
# Install PyOpenCL
RUN pip install pyopencl
# Setup SSH
RUN mkdir /var/run/sshd
# Set "root" as root's password
RUN echo 'root:'${PASSWD} | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthetication/PasswordAuthetication/' /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
version: "2.4"
services:
hpc_env:
build:
context: .
dockerfile: Dockerfile
args:
- PASSWD=${PASSWD}
runtime: nvidia
ports:
- '12345:22'
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
volumes:
- ../work:/root/work
restart: always
イメージのビルド
Dockerfileからコンテナイメージを作成します。パスワードが.bash_history
に残るのは好ましくないので、外部ファイル(auth.txt:ファイル内に設定したいパスワードを記載)から読み込んだ内容を引数渡しする様にします。コマンド操作を記載したシェルファイルを以下に示します。
#!/bin/bash
cat auth.txt | xargs -n 1 sh -c 'docker-compose build --build-arg PASSWD=$0'
ビルドの実行
シェルファイルを実行するだけです。途中の過程は省略していますが、Successfully...と最後に出力されれば成功です。途中cuDNNのセットアップでaptがエラー終了してしまうことが有りますが、何度かやり直すとビルド出来ます。(詳細な理由は不明)
$ ./build_env.sh
...
...
Successfully tagged building-hpc-env_hpc_env:latest
コンテナの起動
後はコンテナを起動するだけです。PASSWDの値が設定されていないという警告が出ていますが、ビルド時に用いる一時的な値で有る為、無視しても問題有りません。
$ docker-compose up -d
WARNING: The PASSWD variable is not set. Defaulting to a blank string.
Creating network "building-hpc-env_default" with the default driver
Creating building-hpc-env_hpc_env_1 ... done
コンテナへの接続確認
SSHで接続出来るか確認します。無事パスワードログイン出来ました。
2020/9/21追記: ここではlocalhost
で接続確認していますが、
ssh -p 12345 root@<REMOTE_IP_ADDRESS>
でも接続可能です。クライアント上のVSCodeからRemote Development Extensionを用いて接続可能です。
$ ssh -p 12345 root@localhost
root@localhost's password:
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@bd12d0a840e6:~#
おまけ1: VSCodeとの連携
詳細な構築方法は記載しませんが、VSCodeのRemote Development Extensionという拡張機能を用いると以下の様にVSCodeからHPCのお勉強が出来ます。(図はcufファイルを表示している所)
おまけ2: NVIDIA HPC SDK
NVIDIAが2020年8月にリリースしたHigh Performance Computing向けのライブラリやコンパイラまとめて開発環境として提供している物です。技術サポートは有償ですが、ライブラリやコンパイラを使用するだけなら無料で利用出来ます。従来はCUDA FortranのコンパイラはPGIコンパイラという他社製コンパイラが必要でしたが、NVIDIA製のコンパイラでCでもFortranでもCUDAが利用出来る様になります。含まれているコンパイラの一覧表を以下に示します。選り取り見取りといった所です。
# ls
addlocalrc jide-common.jar ncu nvaccelinfo nvcudainit nvprof pgaccelinfo pgf77 pgsize tools
balloontip.jar jide-dock.jar nsight-sys nvc nvdecode nvsize pgc++ pgf90 pgunzip
cuda-gdb llvmversionrc nsys nvc++ nvextract nvunzip pgcc pgf95 pgzip
cudarc localrc nv-nsight-cu-cli nvcc nvfortran nvzip pgcpuid pgfortran rcfiles
ganymed-ssh2-build251.jar makelocalrc nvaccelerror nvcpuid nvprepro pgaccelerror pgcudainit pgprepro rsyntaxtextarea.jar
まとめ
環境構築が煩雑で面倒くさいHPC向けライブラリの開発環境構築をDockerを用いることで簡単かつ手間無く出来る様にしました。HPCの専門書が数冊手元に溜まっているので勉強に活用していこうと思います。
Reference
- CUDA10.2 Dockerfile
- cuDNN Dockerfile
- OpenCL Dockerfile
- Installing PyCUDA on Ubuntu Linux
- Dockerのコンテナを起動したままにする
- NVIDIA HPC SDK
- NVIDIA HPC SDK Version 20.7 Downloads
- NVIDIA HPC SDK の HPC Compilers について
- SSHでログイン出来るコンテナの作り方(Ubuntu18対応版)
-
Fortranを業務で扱っている友人にも使って貰うのでCUDA Fortranに対応させておくことにしました。 ↩