18
22

More than 3 years have passed since last update.

Docker Composeを用いたHPC学習環境の構築(C, Python, Fortran)

Last updated at Posted at 2020-09-20

以前から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の部分)の記載は不要です。

Dockerfile
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"]
docker-compose.yml
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:ファイル内に設定したいパスワードを記載)から読み込んだ内容を引数渡しする様にします。コマンド操作を記載したシェルファイルを以下に示します。

build_env.sh
#!/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ファイルを表示している所)

hpcenv

おまけ2: NVIDIA HPC SDK

NVIDIAが2020年8月にリリースしたHigh Performance Computing向けのライブラリやコンパイラまとめて開発環境として提供している物です。技術サポートは有償ですが、ライブラリやコンパイラを使用するだけなら無料で利用出来ます。従来はCUDA FortranのコンパイラはPGIコンパイラという他社製コンパイラが必要でしたが、NVIDIA製のコンパイラでCでもFortranでもCUDAが利用出来る様になります。含まれているコンパイラの一覧表を以下に示します。選り取り見取りといった所です。

hpcsdk

/opt/nvidia/hpc_sdk/Linux_x86_64/20.7/compilers/binの中は選り取り見取りな様子
# 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


  1. Fortranを業務で扱っている友人にも使って貰うのでCUDA Fortranに対応させておくことにしました。 

18
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
22