Nabe International | Takeru Boost >> Takeruを回せ! >>

spackを使った再現可能な環境の構築① [spack environment]

spack の概要

spackは主にスパコン向けのパッケージマネージャです。
PreBuildされたバイナリが配布されるわけではなく、SourceからBuildするための手順や依存関係の解決などがspackの主たる部分です。
それ故、x86_64系以外にも様々なCPU、コンパイラ、MPIが存在するスパコンにも対応が可能なわけです。 私達は基本的にx86_64のシステムしか扱っていませんが、以下のような点にメリットを感じていて、テストや構築の際に使っています。
  • レポジトリに無いパッケージも追加可能(簡単なものは簡単です。ただ、 Requiremientsが多いものはかなり苦労します。。。。)
  • インストール後、moduleファイルも自動生成してくれる
  • Buildしたバイナリを元にBuild Cacheサーバーが立てられる

spack を使って再現可能な環境を構築する

また、spackを使って再現性のある環境を構築する方法も以下のようなものがあります。
  1. 自身でBuildしたバイナリをBuild Cacheサーバーから配布する
  2. spack environmentを使う
  3. spack environmentからdockerコンテナを作る
このうち、今回は2のspack environmentについて、次回は3のdockerコンテナについて書いてみたいと思います。

spack environment

spack environmentとは、一言でいうとcondaの仮想環境と同様のものです。 仮想的な環境を作って分離した中に指定した複数のパッケージをインストールするといった点は同じです。 異なる点は、condaの場合は同じパッケージでも仮想環境毎に重複してインストールされる反面、spackの場合は同じバージョンの同じパッケージ(正確にはhash値が同じ)であれば再コンパイルされることなく、利用可能になるという点があります。これはパッケージ自体はglobalなspackの環境にインストールされ、spack environmentで区切られたディレクトリにはシンボリックリンクが貼られるという立て付けになっているためです。 では、さっそくspack environmentを作ってパッケージをインストールしてみたいと思います。
  • spack environmentの作成 (kankyoという名前のenvironmentを作成)
# spack env create kankyo
==> Updating view at /usr/local/spack/var/spack/environments/kankyo/.spack-env/view
==> Created environment 'kankyo' in /usr/local/spack/var/spack/environments/kankyo
  • EnvironmentのActivate
# spack env activate kankyo

# spack find              ## 新しい環境なので当然何もない
==> In environment kankyo
==> No root specs
==> 0 installed packages

# spack env status           ## 自分の今いる環境を確認
==> In environment kankyo
  • Packageのインストール
 上でも書いたようにspack environment下でインストールしたパッケージはglobalなspack環境にもインストールされ、逆にglobalなspack環境にインストールされたパッケージは再コンパイルすることなくEnvironment内で利用することができます。 パッケージのインストールについては、通常の # spack install [package] でも可能ですが、spack add を使うとまとめてインストールすることも可能です。add はそのEnvironmentにパッケージを登録するようなイメージで、add に続けて # spack install と実行すると依存関係のリストをまとめて作成し、順にインストールが始まります。
# spack add sratoolkit bowtie2 samtools         ### パッケージの登録
==> Adding sratoolkit to environment kankyo
==> Adding bowtie2 to environment kankyo
==> Adding samtools to environment kankyo
==> Updating view at /usr/local/spack/var/spack/environments/kankyo/.spack-env/view

# spack find                    ### この時点ではまだインストールされていない
==> In environment kankyo
==> Root specs
bowtie2   samtools   sratoolkit 

==> 0 installed packages

# spack install         ### addされたパッケージがまとめてインストールされる 

[インストールの確認]
# spack find
==> In environment kankyo
==> Root specs
bowtie2   samtools   sratoolkit 

==> 23 installed packages
-- linux-centos8-skylake_avx512 / gcc@8.3.1 ---------------------
bowtie2@2.3.5.1  expat@2.2.9     htslib@1.10.2     libffi@3.2.1   ncurses@6.1     python@3.7.6   sqlite@3.30.1     xz@5.2.4
bzip2@1.0.8      gdbm@1.18.1     intel-tbb@2020.1  libiconv@1.16  openssl@1.1.1d  readline@8.0   sratoolkit@2.9.6  zlib@1.2.11
curl@7.68.0      gettext@0.20.1  libbsd@0.10.0     libxml2@2.9.9  perl@5.30.1     samtools@1.10  tar@1.32


spack.yamlとspack.lock

spack environmentを作ってパッケージを追加すると、spack environmentの環境下にはspack.yaml, spack.lockといった2つのファイルが生成されます。 このファイルを利用して再現可能な環境を別のマシンの構築します。 このspackの公式チュートリアルにも書かれていますが、2つのファイルには以下の違いがあります。
  • spack.yaml : インストールされるパッケージ名、バージョン、その他細かい情報などが書かれているレシピのようなもの
  • spack.lock : spack.yaml から依存関係なども含めてconcretizeした情報が記載されているjson形式のファイル concretize は、依存関係含めてどのパッケージをどんな形でビルドするのかを決め、各パッケージにユニークなhash値を与えるspack特有のプロセスです。spack environment下に限らず $ spack find -L と実行すると下記のようにパッケージ毎にhash値が付けられていることがわかります。
-- linux-centos8-skylake_avx512 / gcc@8.3.1 ---------------------
colyrk5sxsxfw2e4kzcolckmvnezrawn bowtie2@2.3.5.1   izyg7xgbxj25j4fznxinxyok7ilzucsi ncurses@6.1
n7mfcwwlwunhzume6juysj6fpc7ioumv bzip2@1.0.8       ks24k4cv635noukrtxo2a7nt5mlfjh6i openssl@1.1.1d
heflewait7cmhv7uqinhtprw2q5rx3hw curl@7.68.0       t6cy2mxtv3zqpblypdlszhempnwewyrl perl@5.30.1
vfxu5ml3qzhrmraz3wzebo4vddocrq5d expat@2.2.9       eq5nm3d6f7guanr2odxinowvi5u2hhbx python@3.7.6
5xabiq5tcg3urhun74pr4r24xsslycyr gdbm@1.18.1       pg4766g3kc5xvmh3wpxywbeflgjd4j67 readline@8.0
hj4lbk4cvyjw3j7hqwj3ij3wuem4vv7m gettext@0.20.1    wfpqqsdvzfxkvdfjxgwgccfuba5zlcl7 samtools@1.10
oenavbpbwlyn4622kj4ow5352u537lyw htslib@1.10.2     xm2wmon64xzvfkp3w6cyp2ivusidw6q2 sqlite@3.30.1
htys56pdkrrplleu66r3ffsvmmux22rm intel-tbb@2020.1  pgmdf2xzqqml3drfan4zoytr2ykqss2d sratoolkit@2.9.6
3kya7swlqg43lj43jfwjrz6hyxf462q6 libbsd@0.10.0     2bmeylnf2lshmkpjtbjrrtpvv3nnalqy tar@1.32
5n6bpungay6pwod5zpjazja6fcwxlgk4 libffi@3.2.1      fq6iel5ao7iqr6e3v3rpyuxfgpvpptup xz@5.2.4
xztbayvikkcjof6xxpp62j3rg26cqkg2 libiconv@1.16     gqxf26r2djxsjulsmoe4akjyo5jyktt3 zlib@1.2.11
npgcvbz6jhugxogg6zafpbmarxpswh45 libxml2@2.9.9

 このhash値は、パッケージのバージョン、コンパイラ、OS、CPUの種類などの要素によりユニークに付与される値なのでこのhash値が同じであれば同じものと考えることができます。それぞれspack.yaml、もしくはspack.lockのファイルをコピーした上で以下のようにspack enviroment を作成し、同じように$ spack install を実行すると別のマシンでも同様の、もしくは同じ環境が構成できます。

$ spack env create repro_env_yaml spack.yaml            ## repro_env_yaml がspack environment の名前

$ spack env create repro_env_lock spack.lock            ## repro_env_lock がspack environment の名前
 spack.yaml はインストールしたいパッケージ名にバージョンなどのオプション情報を加えた内容が書かれているのでそれを揃えるだけでいい場合は十分です。ただ、CPUの世代やメーカー(Intel or AMD)や世代が異なると、使用する命令セットやコンパイルのオプションを自動で変更されたりするのでhash値レベルで同じものにはなりませんが、同じパッケージの組み合わせを揃えるという意味では十分です。  spack.lock に関しては、ファイルに書かれている内容は依存関係など含めてconcretizeされた情報が全て載っているのですが、この環境を別のマシンに厳密にコピーするには、同じハードウェア、OSなどであることが必要となります。CPUが異なる、あるいはOSが異なる環境にコピーした場合は、そのコピー先の環境に合わせてspack.lockが書き換えられてしまいますので厳密にはコピーされません。そうなると環境が同じでも異なっていても、spack.yaml とあまり違いがなくなってしまう気もしますが、不具合が発生した際のdebug 用途などでは有用かと思います。    今回は以上です。次回はspack environment を使ってdockerコンテナを作る方法を紹介する予定です。