コンテンツにスキップ

Spackによるソフトウェア管理

Spackとは、Lawrence Livermore National Laboratoryで開発されている高性能計算向けのソフトウェアパッケージ管理システムです。 Spackを使うことにより、同一ソフトウェアをバージョン、設定、コンパイラを様々に変えて複数ビルドし、切り替えて使うことができます。 ABCI上でSpackを使うことにより、ABCIが標準でサポートしていないソフトウェアを簡単にインストールすることができるようになります。

Note

動作確認は2023年3月31日にbashで行っており、その時の最新のバージョンである0.19.1を使用しています。

Caution

  • Spackは、独自のパッケージフォーマットでパッケージングされたHPC向けのソフトウェアを導入するためのツールであり、Linuxディストリビューションが提供するパッケージとの互換性はありません。そのためyum,aptなどのコマンドの代替として利用することはできません。

  • Spackは、Spackをインストールしたディレクトリ以下にソフトウェアをインストールします。多数のソフトウェアを導入すると多くの容量を消費しますので、使わなくなったソフトウェアはアンインストールするなどの管理をしてください。

  • 計算ノード(V)と計算ノード(A)はOSが異なるため、本ドキュメントに従ってSpackを導入する場合、一方のノードに対応する設定しか行えません。どちらの計算ノードで使用するか選択しご利用ください。本ドキュメントの例は、計算ノード(V)での結果を表示しております。

Spack環境設定

インストール

GitHubからcloneし、使用するバージョンをcheckoutすることで、Spackをインストールすることができます。

[username@es1 ~]$ git clone https://github.com/spack/spack.git
[username@es1 ~]$ cd ./spack
[username@es1 ~/spack]$ git checkout v0.19.1

以降はターミナル上で、Spackを有効化するスクリプトを読み込めば使えます。

[username@es1 ~]$ source ${HOME}/spack/share/spack/setup-env.sh

ABCI用設定

コンパイラの登録

Spackで使用するコンパイラをspack compiler findコマンドでSpackに登録します。

[username@es1 ~]$ spack compiler find
==> Added 2 new compilers to ${HOME}/.spack/linux/compilers.yaml
    gcc@8.5.0  clang@13.0.1
==> Compilers are defined in the following files:
    ${HOME}/.spack/linux/compilers.yaml

登録されたコンパイラはspack compiler listコマンドで確認できます。

GCC 8.5.0は標準のパス(/usr/bin)に入っているため、Spackが自動的に見つけます。

[username@es1 ~]$ spack compiler list
==> Available compilers
-- clang rocky8-x86_64 ------------------------------------------
clang@13.0.1

-- gcc rocky8-x86_64 --------------------------------------------
gcc@8.5.0

ABCIが提供しているGCCの設定ファイル(compilers.yaml)を配置しておりますので、以下のようにユーザ環境にコピーすることでコンパイラを利用することが可能です。

計算ノード(V)

[username@es1 ~]$ cp /apps/spack/vnode/compilers.yaml ${HOME}/.spack/linux/
[username@es1 ~]$ spack compiler list
==> Available compilers
-- gcc rocky8-x86_64 --------------------------------------------
gcc@12.2.0  gcc@8.5.0

計算ノード(A)

[username@es-a1 ~]$ cp /apps/spack/anode/compilers.yaml ${HOME}/.spack/linux/
[username@es-a1 ~]$ spack compiler list
==> Available compilers
-- gcc rhel8-x86_64 ---------------------------------------------
gcc@12.2.0  gcc@8.3.1

ABCIソフトウェアの登録

Spackはソフトウェアの依存関係を解決して、依存するソフトウェアも自動的にインストールします。 標準の設定では、CUDAなど、ABCIが既に提供しているソフトウェアも利用者ごとにインストールされます。 ディスクスペースの浪費となりますので、ABCIが提供するソフトウェアは、Spackから参照するように設定することをお勧めします。

Spackが参照するソフトウェアの設定は$HOME/.spack/linux/packages.yamlに定義します。 ABCIで提供するCUDA、cmake等の設定を記載した設定ファイル(packages.yaml)をユーザ環境にコピーすることでABCIのソフトウェアを参照することができます。

計算ノード(V)

[username@es1 ~]$ cp /apps/spack/vnode/packages.yaml ${HOME}/.spack/linux/

計算ノード(A)

[username@es-a1 ~]$ cp /apps/spack/anode/packages.yaml ${HOME}/.spack/linux/

packages.yaml (抜粋)

packages:
  cuda:
    buildable: false
    externals:
(snip)
    - spec: cuda@11.7.1%gcc@8.5.0
      modules:
      - cuda/11.7/11.7.1
    - spec: cuda@11.7.1%gcc@12.2.0
      modules:
      - cuda/11.7/11.7.1
(snip)
  hpcx-mpi:
    externals:
    - spec: hpcx@2.11%gcc@8.5.0
      prefix: /apps/openmpi/2.11/gcc8.5.0
(snip)

このファイルを設置すると、例えば、SpackでCUDAのバージョン11.7.1のインストールを実行すると、実際にはインストールはされずに、SpackがEnvironment Modulesのcuda/11.7/11.7.1を使用するようになります。 CUDAセクションでbuildable: falseを指定することにより、Spackはここで指定しているバージョン以外のCUDAをインストールしなくなります。 ABCIが提供していないバージョンのCUDAをSpackでインストールしたい場合は、この記述を削除してください。

packages.yamlファイルの設定の詳細は公式ドキュメントを参照ください。

Spack 基本操作

Spackの基本操作についてまとめます。 詳細は公式ドキュメントを参照ください。

コンパイラ関連

Spackに登録されているコンパイラ一覧はcompiler listサブコマンドで確認できます。

[username@es1 ~]$ spack compiler list
==> Available compilers
-- gcc rhel8-x86_64 ---------------------------------------------
gcc@12.2.0  gcc@8.3.1

特定コンパイラの詳細情報を確認するには、compiler infoサブコマンドを実行します。

[username@es1 ~]$ spack compiler info gcc@8.5.0
gcc@8.5.0:
        paths:
             cc = /usr/bin/gcc
             cxx = /usr/bin/g++
             f77 = /usr/bin/gfortran
             fc = /usr/bin/gfortran
        modules  = []
        operating system  = rocky8

ソフトウェア管理関連

インストール

OpenMPIのSpack標準バージョンは、以下の通りにインストールできます。 schedulers=sgefabrics=autoの意味は導入事例を参照ください。

[username@es1 ~]$ spack install openmpi schedulers=sge fabrics=auto

バージョンを指定する場合は、@で指定します。

[username@es1 ~]$ spack install openmpi@4.1.3 schedulers=sge fabrics=auto

コンパイラを指定する場合は%で指定します。 以下の例では、コンパイラのバージョンも指定しています。

[username@es1 ~]$ spack install openmpi@4.1.3 %gcc@12.2.0 schedulers=sge fabrics=auto

アンインストール

uninstallサブコマンドで、インストール済みのソフトウェアをアンインストールできます。 インストール同様に、バージョンを指定してアンインストールできます。

[username@es1 ~]$ spack uninstall openmpi

ソフトウェアのハッシュを指定してアンインストールすることもできます。 /に続いてハッシュを指定します。 ハッシュは情報確認に示す通り、findサブコマンドで取得できます。

[username@es1 ~]$ spack uninstall /ffwtsvk

インストールした全てのソフトウェアを一括して削除するには以下の通りに実行します。

[username@es1 ~]$ spack uninstall --all

情報確認

Spackでインストールできるソフトウェア一覧は、listサブコマンドで確認できます。

[username@es1 ~]$ spack list
abinit
abyss
(snip)

キーワードを指定することで、キーワードを名前の一部に含むソフトウェアのみを表示できます。 以下ではmpiをキーワードとして指定しています。

[username@es1 ~]$ spack list mpi
compiz                          intel-oneapi-mpi  mpir               r-rmpi
cray-mpich                      mpi-bash          mpitrampoline      rempi
exempi                          mpi-serial        mpiwrapper         rkt-compiler-lib
fujitsu-mpi                     mpibind           mpix-launch-swift  spectrum-mpi
hpcx-mpi                        mpich             openmpi            spiral-package-mpi
intel-mpi                       mpifileutils      pbmpi              sst-dumpi
intel-mpi-benchmarks            mpilander         phylobayesmpi      umpire
intel-oneapi-compilers          mpileaks          pnmpi              vampirtrace
intel-oneapi-compilers-classic  mpip              py-mpi4py          wi4mpi
==> 36 packages

インストールしたソフトウェア一覧はfindサブコマンドで確認できます。

[username@es1 ~]$ spack find
==> 49 installed packages
-- linux-rocky8-skylake_avx512 / gcc@8.5.0 ----------------------------
autoconf@2.69    gdbm@1.18.1          libxml2@2.9.9  readline@8.0
(snip)

インストールしたソフトウェアのハッシュ、依存関係はfindサブコマンドに-dlオプションを指定することで確認できます。

[username@es1 ~]$ spack find -dl openmpi
-- linux-rocky8-skylake_avx512 / gcc@8.5.0 ---------------------
6pxjftg openmpi@4.1.4
ahftjey     hwloc@2.8.0
vf52amo         cuda@11.8.0
edtwt6g         libpciaccess@0.16
bt74u75         libxml2@2.10.1
qazxaa4             libiconv@1.16
jb22kvg             xz@5.2.7
pkmj6e7             zlib@1.2.13
2dq7ece         numactl@2.0.14

特定のソフトウェアの詳細情報を確認するには、infoサブコマンドを使用します。

[username@es1 ~]$ spack info openmpi
AutotoolsPackage:   openmpi

Description:
    An open source Message Passing Interface implementation. The Open MPI
    Project is an open source Message Passing Interface implementation that
(snip)

特定ソフトウェアの、インストール可能なバージョン一覧はversionsサブコマンドで確認できます。

[username@es1 ~]$ spack versions openmpi
==> Safe versions (already checksummed):
  main   4.0.4  3.1.2  2.1.6  2.0.2   1.10.1  1.8.1  1.6.4  1.5.1  1.3.3  1.2.4  1.1.1
  4.1.4  4.0.3  3.1.1  2.1.5  2.0.1   1.10.0  1.8    1.6.3  1.5    1.3.2  1.2.3  1.1
  4.1.3  4.0.2  3.1.0  2.1.4  2.0.0   1.8.8   1.7.5  1.6.2  1.4.5  1.3.1  1.2.2  1.0.2
  4.1.2  4.0.1  3.0.5  2.1.3  1.10.7  1.8.7   1.7.4  1.6.1  1.4.4  1.3    1.2.1  1.0.1
  4.1.1  4.0.0  3.0.4  2.1.2  1.10.6  1.8.6   1.7.3  1.6    1.4.3  1.2.9  1.2    1.0
  4.1.0  3.1.6  3.0.3  2.1.1  1.10.5  1.8.5   1.7.2  1.5.5  1.4.2  1.2.8  1.1.5
  4.0.7  3.1.5  3.0.2  2.1.0  1.10.4  1.8.4   1.7.1  1.5.4  1.4.1  1.2.7  1.1.4
  4.0.6  3.1.4  3.0.1  2.0.4  1.10.3  1.8.3   1.7    1.5.3  1.4    1.2.6  1.1.3
  4.0.5  3.1.3  3.0.0  2.0.3  1.10.2  1.8.2   1.6.5  1.5.2  1.3.4  1.2.5  1.1.2
==> Remote versions (not yet checksummed):
  4.1.5

ソフトウェア利用方法

Spackでインストールしたソフトウェアはspack loadコマンドで使用可能です。 ABCIが提供するモジュール同様に、ロードして使用できます。

[username@es1 ~]$ spack load xxxxx

spack loadはソフトウェアを使用するためのPATHMANPATHCPATHLD_LIBRARY_PATH等の環境変数を設定します。

不要になった場合は、spack unloadします。

[username@es1 ~]$ spack unload xxxxx

ソフトウェア環境の定義と利用

Spackにはソフトウェアパッケージを「環境」という単位でグルーピングする機能があります。 環境ごとにソフトウェアをバージョンや依存関係を変えてインストールすることができ、環境を切り替えることで一括して使用するソフトウェアを変えることができます。

まずspack env createでSpack環境を構築します。ここで別のSpack環境名を指定することで複数のSpack環境を作成することが可能です。

[username@es1 ~]$ spack env create myenv

spack env activateで作ったSpack環境を有効にします。-pをつけることで現在有効になっているSpack環境名をプロンプトに表示することができます。有効にした環境にソフトウェアをインストールしていきます。

[username@es1 ~]$ spack env activate -p myenv
[myenv] [username@es1 ~]$ spack install xxxxx

spack env deactivateでSpack環境を無効にします。別の環境を使う場合、その環境をspack env activateします。

[myenv] [username@es1 ~]$ spack env deactivate
[username@es1 ~]$

spack env listで作成済みのSpack環境の一覧を表示することが可能です。

[username@es1 ~]$ spack env list
==> 2 environments
    myenv
    another_env

利用事例

CUDA-aware OpenMPI

インストール方法

CUDA 11.8.0を使用するOpenMPI 4.1.4をインストールする場合の例です。 GPUを搭載する計算ノード上で作業を行います。

[username@g0001 ~]$ spack install cuda@11.8.0
[username@g0001 ~]$ spack install openmpi@4.1.4 +cuda schedulers=sge fabrics=auto ^cuda@11.8.0
[username@g0001 ~]$ spack find --paths openmpi@4.1.4
==> 1 installed package
-- linux-rocky8-skylake_avx512 / gcc@8.5.0 ----------------------------
openmpi@4.1.4  ${SPACK_ROOT}/opt/spack/linux-rocky8-skylake_avx512/gcc-8.5.0/openmpi-4.1.4-4mmghhfuk5n7my7g3ko2zwzlo4wmoc5v
[username@g0001 ~]$ echo "btl_openib_warn_default_gid_prefix = 0" >> ${SPACK_ROOT}/opt/spack/linux-centos7-haswell/gcc-8.5.0/openmpi-4.1.4-4mmghhfuk5n7my7g3ko2zwzlo4wmoc5v/etc/openmpi-mca-params.conf

1行目では、ABCIが提供するCUDAを使用するよう、CUDAのバージョン11.8.0をインストールします。 2行目では、インストール済みソフトウェアの構成と同様の設定で、OpenMPIをインストールしています。 インストールオプションの意味は以下の通りです。

  • +cuda: CUDAを有効にしてビルドします。
  • schedulers=sge: MPIプロセスを起動する手段を指定しています。ABCIではSGE互換のAGEを使っているため、sgeを指定します。
  • fabrics=auto: 通信ライブラリを選択します。この例では自動判別としています。
  • ^cuda@11.8.0: 使用するCUDAを指定します。^は依存するソフトウェアを指定するときに使います。

4行目では実行時の警告を消すため、設定ファイルを編集しています(任意)。 そのため、3行目でOpenMPIがインストールされたパスを確認しています。

Spackでは、同一ソフトウェアを異なる設定で複数インストールし、管理することができます。 ここでは、CUDA 11.7.1を使用するOpenMPI 4.1.3を追加インストールします。

[username@g0001 ~]$ spack install cuda@11.7.1
[username@g0001 ~]$ spack install openmpi@4.1.3 +cuda schedulers=sge fabrics=auto ^cuda@11.7.1

使い方

「CUDA 11.8.0を使用するOpenMPI 4.1.4」を使う場合の利用方法を説明します。

spack load実行時にOpenMPIのバージョン並びにCUDAの依存関係を指定することで、特定のバージョンを利用することが可能です。

[username@es1 ~]$ spack load openmpi@4.1.4 ^cuda@11.8.0

計算ノード上でプログラムをコンパイルする場合は、SpackでインストールしたOpenMPIを呼び出してからMPIを起動します。

[username@g0001 ~]$ source ${HOME}/spack/share/spack/setup-env.sh
[username@g0001 ~]$ spack load openmpi@4.1.4 ^cuda@11.8.0
[username@g0001 ~]$ mpicc ...

ジョブスクリプトでは、以下のように使用します。

#!/bin/bash
#$-l rt_F=2
#$-j y
#$-cwd

source ${HOME}/spack/share/spack/setup-env.sh
spack load openmpi@4.1.4 ^cuda@11.8.0

NUM_NODES=${NHOSTS}
NUM_GPUS_PER_NODE=4
NUM_PROCS=$(expr ${NUM_NODES} \* ${NUM_GPUS_PER_NODE})
MPIOPTS="-n ${NUM_PROCS} -map-by ppr:${NUM_GPUS_PER_NODE}:node -x PATH -x LD_LIBRARY_PATH"
mpiexec ${MPIOPTS} YOUR_PROGRAM

不要になった場合は、バージョン並びに依存関係を指定してアンインストールします。

[username@es1 ~]$ spack uninstall openmpi@4.1.4 ^cuda@11.8.0

CUDA-aware MVAPICH2

CUDA-aware MVAPICH2を使用する場合は、以下を参考にSpackでインストールしてください。

GPUを搭載する計算ノード上で作業を行います。 上述したCUDA-aware OpenMPIに、使用するCUDAをインストールしたのちに、CUDAオプション(+cuda)、通信ライブラリ(fabrics=mrail)、およびCUDAの依存関係(^cuda@11.8.0)を指定してMVAPICH2をインストールします。

[username@g0001 ~]$ spack install cuda@11.8.0
[username@g0001 ~]$ spack install mvapich2@2.3.7 +cuda fabrics=mrail ^cuda@11.8.0

使い方もCUDA-aware OpenMPIと同様に、インストールしたMVAPICH2をロードして使います。 以下にジョブスクリプト例を示します。

#!/bin/bash
#$-l rt_F=2
#$-j y
#$-cwd

source ${HOME}/spack/share/spack/setup-env.sh
spack load mvapich2@2.3.7 ^cuda@11.8.0

NUM_NODES=${NHOSTS}
NUM_GPUS_PER_NODE=4
NUM_PROCS=$(expr ${NUM_NODES} \* ${NUM_GPUS_PER_NODE})
MPIE_ARGS="-genv MV2_USE_CUDA=1"
MPIOPTS="${MPIE_ARGS} -np ${NUM_PROCS} -ppn ${NUM_GPUS_PER_NODE}"

mpiexec ${MPIOPTS} YOUR_PROGRAM

MPIFileUtils

MPIFileUtilsは、MPIを用いたファイル転送ツールです。 複数のライブラリに依存するため、マニュアルでインストールするのは面倒ですが、Spackを用いると簡単にインストールできます。

以下の例では、OpenMPI 4.1.4を使用して、MPIFileUtilsをインストールします。 該当するOpenMPIをインストールした後で(1行目)、それへの依存を指定してMPIFileUtilsをインストールします(2行目)。

[username@es1 ~]$ spack install openmpi@4.1.4
[username@es1 ~]$ spack install mpifileutils ^openmpi@4.1.4

使うときには、MPIFileUtilsのモジュールをロードします。 MPIFileUtilsのモジュールをロードすると、dbcastなどのプログラムへのパスがセットされます。 以下にジョブスクリプト例を示します。

#!/bin/bash
#$-l rt_F=2
#$-j y
#$-cwd

source ${HOME}/spack/share/spack/setup-env.sh
spack load mpifileutils@0.11.1 ^openmpi@4.1.4

NPPN=5
NMPIPROC=$(( $NHOSTS * $NPPN ))
SRC_FILE=name_of_file
DST_FILE=name_of_file

mpiexec -n ${NMPIPROC} -map-by ppr:${NPPN}:node dbcast $SRC_FILE $DST_FILE

ソフトウェア環境からのSingularityイメージの作成手順

ソフトウェア環境の定義と利用で作成した環境を用いてSingularityのイメージを作成することが可能です。 ここではmyenvという名前のSpack環境を用いてCUDA-awareのOpenMPIをインストールし、Singularityイメージを作成する例を示します。

[username@es1 ~]$ spack env create myenv
[username@es1 ~]$ spack activate -p myenv
[myenv] [username@es1 ~]$ spack install openmpi +cuda schedulers=sge fabrics=auto
[username@es1 ~]$ cp -p ${HOME}/spack/var/spack/environments/myenv/spack.yaml .
[username@es1 ~]$ vi spack.yaml

spack.yamlは以下にように編集します。

# This is a Spack Environment file.
#
# It describes a set of packages to be installed, along with
# configuration settings.
spack:
  # add package specs to the `specs` list
  specs: [openmpi +cuda fabrics=auto schedulers=sge]
  view: true                       # <- この行は削除

  container:                       # <- 追加
    images:                        # <- 追加
      build: spack/centos7:0.19.1  # <- 追加
      final: spack/centos7:0.19.1  # <- 追加
    format: singularity            # <- 追加
    strip: false                   # <- 追加

spack containerizeを用いて、spack.yamlファイルからSingularityレシピファイル(myenv.def)を作成します。

[username@es1 ~]$ spack containerize > myenv.def

SigularityレシピファイルからSingularityイメージを作成する方法については、Singularityイメージファイルの作成(build)をご参照ください。