コンテンツにスキップ

CUDA-Q

ここでは、CUDA-Qのコンテナを利用して、複数GPU,複数ノードでのシミュレーションを実行する手順を説明します。 コンテナとしては、NVIDIA CUDA Quantum にあるコンテナイメージ を使用しています。

CUDA-Qコンテナの準備

前提

  • grpnameはご自身のシステムHグループ名に置き換えてください
  • サンプルプログラムはインタラクティブノードと各計算ノードで参照できるよう、ホーム領域またはグループ領域に保存してください

導入方法

CUDA-Q のコンテナイメージをダウンロードして、Singularity 用のコンテナを作成する手順です。 最初に、以下の様な、Singularity コンテナを作成するためのDefinition ファイルを用意します。

[username@qes01] % cd CUDA-Q
[username@qes01]~/CUDA-Q % cat cudaQ.def
Bootstrap: docker
From: nvcr.io/nvidia/nightly/cuda-quantum:cu12-0.11.0
Stage:final

%post
    # set timezone
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

    apt update
    apt-get -y upgrade

    chmod 777 /home/cudaq
    apt install -y python3-venv python3-pip

    #
    # added to run ORNL workshop
    pip install qutip --upgrade
    pip install scipy --upgrade

    # Cleanup
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives

%runscript
    bash

このファイルを使用して、コンテナイメージを作成します。

[username@qes01 ~]~/CUDA-Q$ qsub -I -W group_list=grpname -l rt_QG=1 -l walltime=1:00:00
[username@qh001 ~]~/CUDA-Q$ singularity build --fakeroot cudaQ.sif cudaQ.def
.
.
.
INFO:    Adding runscript
INFO:    Creating SIF file...
INFO:    Build complete: cudaQ.sif
[username@qh001 ~]~/CUDA-Q$ 

サンプルプログラムの準備

CUDA-Q のコンテナの中には、あらかじめ、いくつかのサンプルプログラムが用意されています。それを、あらかじめコピーしておき、実行してみます。

[username@qes01 ~]~/CUDA-Q$ qsub -I -W group_list=grpname -l rt_QG=1 -l walltime=1:00:00
[username@qh001 ~]~/CUDA-Q$ singularity run --nv cudaQ.sif
Singularity> cp -r /home/cudaq/ .

CUDA-Qコンテナの実行

インタラクティブジョブとして実行

[username@qes01 ~]$ qsub -W group_list=grpname -l rt_QG=1,walltime=1:00:00
[username@qh001 ~]$ singularity run --nv cudaQ.sif
Singularity> python3 cudaq/examples/python/dynamics/heisenberg_model.py 
Singularity> ls -1 cudaq/examples/python/dynamics/hei*.png
heisenberg_model.png

バッチジョブとして実行(1ノード, 1GPU)

次のジョブスクリプトを run.sh ファイルとして保存します。

#!/bin/sh

#PBS -W group_list=grpname
#PBS -l rt_QG=1
#PBS -l walltime=00:30:00
#PBS -j oe

export QDIR=${HOME}/CUDA-Q
export SIF=${HOME}/CUDA-Q/cudaQ.sif

cd $QDIR
singularity exec --nv ${SIF} python3 ${QDIR}/cudaq/examples/python/dynamics/heisenberg_model.py

バッチジョブ実行のため、ジョブスクリプト run.sh をqsubコマンドでバッチジョブとして投入します。

[username@qes01 ~]$ qsub run.sh
12345.qjcm

ジョブが終了すると、実行したPython スクリプトのあるディレクトリに、以下のファイルが作成されます。

[username@qes01 ~]$ cd cudaq/examples/python/dynamics
[username@qes01 ~]$ ls -1 hei*.png
heisenberg_model.png

バッチジョブとして実行(1ノード, 4GPU)

次のジョブスクリプトを run.sh ファイルとして保存します。

#!/bin/sh

#PBS -W group_list=grpname
#PBS -l rt_QF=1:mpiprocs=4
#PBS -l walltime=00:30:00
#PBS -j oe

module load openmpi/4.1.7
export MPIOPTS="-np 4 --map-by ppr:4:node "
export PMIX_MCA_gds=^ds12
export QDIR=${HOME}/CUDA-Q
export SIF=${HOME}/CUDA-Q/cudaQ.sif

cd $QDIR
mpirun $MPIOPTS singularity exec --nv ${SIF} python3 ${QDIR}/cudaq/examples/python/dynamics/heisenberg_model.py

このジョブスクリプトについて簡単に説明します。

  1. #PBS -l rt_QF=1:mpiprocs=4 リソースタイプQF(ノードあたり4GPU,ノード占有)を1ノード、最大 4個までのMPI プロセスをPBSに要求します。このバッチジョブ内では、mpiで起動できるプロセスは、4に制限されます。
  2. MPIOPTS="-np 4 --map-by ppr:4:node " mpirun を実行するときに、MPIプロセスを合計4、ノードあたり4プロセスを起動します。
  3. export PMIX_MCA_gds=^ds12 ジョブを実行後に出てくるエラーメッセージが出ないようにするため、環境変数を設定します。(エラーが出ても、ジョブ自体は、実行されています)

バッチジョブ実行のため、ジョブスクリプト run.sh をqsubコマンドでバッチジョブとして投入します。

[username@qes01 ~]$ qsub run.sh
12345.qjcm

ジョブが終了すると、実行したPython スクリプトのあるディレクトリに、以下のファイルが作成されます。

[username@qes01 ~]$ cd cudaq/examples/python/dynamics
[username@qes01 ~]$ ls -1 hei*.png
heisenberg_model.png

バッチジョブとして実行(複数ノード、複数GPU)

CUDA-Q のコンテナイメージは、複数ノードでの利用可能な様に、openmpi (4.1.x) に対応しています。以下の様なジョブスクリプトを使用することで、簡単に利用可能です。

次のジョブスクリプトを run.sh ファイルとして保存します。

#!/bin/sh

#PBS -W group_list=grpname
#PBS -l rt_QF=2:mpiprocs=8
#PBS -l walltime=00:30:00
#PBS -j oe

module load openmpi/4.1.7

export MPIOPTS="-np 8 --map-by ppr:4:node"
##export MPIENVS="--env OPAL_PREFIX=/usr/local/openmpi --env PMIX_INSTALL_PREFIX=/usr/local/pmix"
echo "MPI option is :" $MPIOPTS
echo "MPIENV     is :" $MPIENVS

export export PMIX_MCA_gds=^ds12
export QDIR=${HOME}/CUDA-Q
export SIF=${QDIR}/cudaQ.sif

cd ${QDIR}/cudaq/examples/python/dynamics/mgmn/
MPIRUN=`which mpirun`

$MPIRUN -v $MPIOPTS singularity exec --nv $MPIENVS ${SIF} python3 multi_gpu.py

このジョブスクリプトについて簡単に説明します。

  1. #PBS -l rt_QF=2:mpiprocs=8 リソースタイプQF(ノードあたり4GPU,ノード占有)で2ノード、合計 2x4=8 のMPI プロセスをPBSに要求します。このバッチジョブ内では、mpiで起動できるプロセスは、8に制限されます。
  2. MPIOPTS="-np 8 --map-by ppr:4:node " mpirun を実行するときに、MPIプロセスを合計8、ノードあたり4プロセスを起動します。
  3. export PMIX_MCA_gds=^ds12 ジョブを実行後に出てくるエラーメッセージが出ないようにするため、環境変数を設定します。(エラーが出ても、ジョブ自体は、実行されています)

バッチジョブ実行のため、ジョブスクリプト run.sh をqsubコマンドでバッチジョブとして投入します。

[username@qes01 ~]$ qsub run.sh
12345.qjcm

ジョブが終了すると、ジョブを実行したディレクトリに、以下のファイルが作成されます。

[username@qes01 ~]$ ls -1 
.
heisenberg_model-interactive-nompi.png
.
.