Environment modulesのインストール

Environment modulesはスパコンやクラスタコンピュータなど大人数のユーザーが同時に利用する時にあると便利なツールです。Wisteria/BDEC-01やFlow, TSUBAME3.0などの大型計算機でも使われています。

```bash
$ module avail
------------------- /home/apps/Modules/modulefiles/compiler --------------------
gcc/8.4.0  gcc/9.3.0  gcc/10.3.0  gcc/12.2.0

--------------------- /home/apps/Modules/modulefiles/cuda ----------------------
cuda/11.1.105  cuda/11.6.112

--------------------- /home/apps/Modules/modulefiles/free ----------------------
alphafold/2.2.0     hh-suite/3.3           openbabel/3.1.1
alphafold/2.3.1     hmmer/3.3.2            openfold/1.0.0
blastplus/2.13.0    julia/1.6.7            openmpi/3.1.6_gcc10.3.0
colabfold_batch     julia/1.7.3            openmpi/4.0.5_gcc8.4.0
foldseek/3-915ef7d  julia/1.8.3            openmpi/4.1.1_gcc10.3.0
foldseek/4-645b789  mmseqs2/13-45111       Rosetta/3.13
gromacs/2021.5      mmseqs2/20220912       Scwrl/4.0.2
gromacs/2021.6      vmd/1.9.4a51
gromacs/2022.2      modeller/10.1
gromacs/2022.4      NAMD/Git-2021-01-14

---------------------- /home/apps/Modules/modulefiles/isv ----------------------
amber20  amber22  gaussian16.C01  gaussian16.C02

--------------------- /home/apps/Modules/modulefiles/tools ---------------------
bazel/3.1.0  python3.8  python3.9

------------------- /home/apps/Modules/modulefiles/linuxbrew -------------------
cd-hit  dssp  edirect  maxit  mican  python3.10  python3.11  tmalign

Key:
default-version  modulepath
```

## Introduction

スパコンやクラスタコンピュータなどの共有計算機上では、多くのユーザーが利用することのあるソフトウェアをユーザー全員がアクセス可能な領域（`/usr/local`とか）にインストールして利用してもらえば容量を圧迫せずに済ませられます。また、同じソフトウェアでも異なるバージョンのソフトウェアを使い分けたいということもあります。

ここでは共有計算機の管理者向けに、Environment modulesのインストール方法とその使い方例を示します。公式インストールガイドはここ https://modules.readthedocs.io/en/latest/INSTALL.html ソースコードはGitHub上の https://github.com/cea-hpc/modules/releases にあるので、ここから最新版をダウンロードしてくることができます。

## インストール方法
CentOSの場合は`yum install environment-modules`でインストールできます。が、最新版を使いたいという方は以下のソースコードインストール方法を試してみましょう。Ubuntu 22.04の人はまず

```bash
sudo apt -y install automake autoconf autopoint tcl-dev tk-dev
```

としてtcl, tkをインストールしておく必要があります。その後Environment Modulesのインストールを行います。

```bash
# Environment modules 5.3.1のダウンロード
wget https://github.com/cea-hpc/modules/releases/download/v5.4.0/modules-5.4.0.tar.gz
# 解凍
tar zxvf modules-5.4.0.tar.gz
cd modules-5.4.0/
# ./configure設定。prefixにはインストール先を指定する
./configure --prefix=/home/apps/Modules --modulefilesdir=/home/apps/Modules/modulefiles
# インストール。rootでない場合はsudoが必要なことがあります
make -j4 ; sudo make install
# /etc/profile.d に設定ファイルのシンボリックリンクを作成しておけばbash, csh起動時に自動的に読み込まれる（はず）。※zshの場合は読まれない
sudo ln -s /home/apps/Modules/init/profile.sh /etc/profile.d/modules.sh
sudo ln -s /home/apps/Modules/init/profile.csh /etc/profile.d/modules.csh
```

この後ログアウト＆ログインするか各種`. /home/apps/Modules/init/profile.sh`を実行してから`module avail`でenvironment moduleっぽい結果が帰ってきたら成功です。

zsh使いの方がログイン時に自動的に読み込まれるようにしたい場合は https://qiita.com/yuku_t/items/40bcc63bb8ad94f083f1 の記事などを参考に設定して、システムグローバルに適用したい場合は`/etc/zshenv`（Redhat系の場合）, `/etc/zsh/zshenv`（Ubuntuの場合）に、または個人的でよければ自身の`~/.zshrc`に`. /home/apps/Modules/init/zsh`の一行を追記しておくと良いでしょう。

## moduleコマンドの使い方

とりあえず基本的なものはいくつか覚えておきましょう。マニュアルはここ https://modules.readthedocs.io/en/latest/module.html

* `module avail`
その計算機に登録されているmodule一覧を表示する

* `module load <module_name>`
moduleをロードすることで、それについてのPATHや環境変数などを追加してくれる。スペースで区切ることで同時にいくつもロード可能

* `module unload <module_name>`
moduleをアンロードすることで、それについてのPATHや環境変数などの設定を削除してくれる

* `module reload`
現在ロードされているmoduleを一度アンロードして直後にロードし直す。`reload`は`refresh`でも可。

* `module list`
現在ユーザーがロードしているmoduleの一覧を表示してくれる

* `module purge`
現在ユーザーがロードしているmoduleをすべてアンロードする

シェルスクリプト内でも利用可能です。もしシェルスクリプト内で`module`コマンドが使えないという場合は、その直前に`. /home/apps/Modules/init/sh` の行を追加し（使用しているシェルに応じて最後の`sh`部分を変更する）、module系コマンドの設定を読みこんでおけば解決します。

## modulefileの書き方例
以下に例を示します。ちなみにReedbushやTSUBAME 3.0などEnvironment modulesを導入している計算機を利用している場合、その設定ファイルはユーザーならば誰でも中身が見えるようになっているはずなので、それを参考に書くこともできます。
書き方はtcl文法に則っているようです。

### CUDA 12.1
```tcl
#%Module1.0
##
##      cuda module
##

set ver         12.1.1
set modroot     /usr/local/cuda-12.1

proc ModulesHelp { } {
        puts stderr "Sets up the paths you need to use cuda $ver."
}

prepend-path   PATH            $modroot/bin
prepend-path   CUDA_PATH       $modroot
prepend-path   LD_LIBRARY_PATH $modroot/lib64
prepend-path   C_INCLUDE_PATH  $modroot/include
prepend-path   LIBRARY_PATH    $modroot/lib64
prepend-path   MANPATH         $modroot/doc/man/
prepend-path   CUDA_TOP        $modroot
prepend-path   CUDA_HOME       $modroot
```

### Gromacs 2022.1
```tcl
#%Module

conflict gromacs
module load cuda/11.8

set base        /usr/local/package/gromacs/2022.1
set ver         2022.1
set ver2        GNU

setenv GMXBIN      $base/bin
setenv GMXDATA     $base/share/gromacs
setenv GMXLDLIB    $base/lib64
setenv GMXMAN      $base/share/man
setenv GROMACS_DIR $base

prepend-path PATH            $base/bin
prepend-path LD_LIBRARY_PATH $base/lib
prepend-path LD_LIBRARY_PATH /usr/local/lib
prepend-path LIBRARY_PATH    $base/lib64
prepend-path CPATH           $base/include/gromacs
prepend-path MANPATH         $base/share/man
prepend-path PKG_CONFIG_PATH $base/lib64/pkgconfig
```
### OpenMPI 4.1.5

```tcl
#%Module1.0
##
## OpenMPI for GCC 11.3.0 (system default)

proc ModulesHelp { } {
        puts stderr "OpenMPI 4.1.5 for GCC 11.3.0\n"
}

module-whatis   "OpenMPI 4.1.5 for GCC 11.3.0"

set arch        GNU
set pkg_root    /home/apps/openmpi/4.1.5_gcc11.3.0
set ver         4.1.5
set ver2        GCC

# module load gcc/11.3.0

setenv MPI_ROOT $pkg_root
setenv MPICC    mpicc
setenv MPICXX   mpicxx
setenv MPIFC    mpif90

prepend-path PATH            $pkg_root/bin
prepend-path LD_LIBRARY_PATH $pkg_root/lib
prepend-path LIBRARY_PATH    $pkg_root/lib
prepend-path CPATH           $pkg_root/include
prepend-path C_INCLUDE_PATH  $pkg_root/include
prepend-path CPLUS_INCLUDE_PATH  $pkg_root/include
prepend-path MANPATH         $pkg_root/share/man
```

### HH-suite 3.2
```tcl
#%Module1.0
##
## HHSuite 3.2 (system default)
proc ModulesHelp { } {
        puts stderr "HHSuite 3.2 for GCC 9.4.0\n"
}

module-whatis   "HHSuite 3.2 for GCC 9.4.0"

set arch        GNU
set pkg_root    /usr/local/package/hh-suite/3.2
set ver         3.2
set ver2        GCC

prepend-path HHLIB           $pkg_root
prepend-path PATH            $pkg_root/bin
prepend-path PATH            $pkg_root/scripts
```

## initrc (modulerc)の設定
`/home/apps/Modules/etc/initrc` (ver.4以前は`/home/apps/Modules/init/modulerc`) に`module`系コマンドを書き加えることで追加設定することができます。いわゆる`bashrc`とか`zshrc`みたいに、起動時に読み込まれる追加設定です。初期状態だとこんな内容になっています。

```tcl
#%Module1.0
# This file defines the initial module command configuration, the default
# modulefiles search path and modulefiles you want to load by default for all
# users. It should contains lines of module command like 'module config conf
# val', 'module use path' and 'module load mod'
module use --append {/home/apps/Modules/modulefiles}
```

ここで、`module use --append <path>`とすると、追加でその<path>に設定されたディレクトリについても設定を読み込んでくれるようになります。例えば

```tcl
#%Module1.0
# This file defines the initial module command configuration, the default
# modulefiles search path and modulefiles you want to load by default for all
# users. It should contains lines of module command like 'module config conf
# val', 'module use path' and 'module load mod'
# module use --append {/home/apps/Modules/modulefiles}
module use --append /home/apps/Modules/modulefiles/isv
module use --append /home/apps/Modules/modulefiles/compiler
module use --append /home/apps/Modules/modulefiles/tool
module use --append /home/apps/Modules/modulefiles/free
```

とすると、これのディレクトリに置かれた設定が`module avail`コマンド実行時に分けて表示されます。

```
$ module avail
------------- /home/apps/Modules/modulefiles/isv -------------
amber22

------------- /home/apps/Modules/modulefiles/tool ------------
cuda/11.2.67  openmpi/4.1.4_gcc9.4.0  pbsutils

------------- /home/apps/Modules/modulefiles/free ------------
gromacs/2021.6  gromacs/2022.1
```

## 個人で設定したmodulefileを追加してmoduleコマンドで利用できるようにする

一見これらのmodulefilesの設定は管理者専用に思えますが、**実は一般ユーザー側からも自作したmodulefileを書いて設定しておくことで恩恵を授かることができます。** 例えば「個人的にインストールしたソフトウェアをEnvironment Modulesに登録したい」とか「（Environment Modulesが入っている）スパコン上で、研究室でライセンスを持っているソフトウェアを、その研究室の学生全員が簡単に使えるようにenvironment modulesから呼び出して使えるようにしたい」ということもあると思います。

これは以下の手順で達成することができます。まず「modulefileの書き方例」を参照して、スパコン上にインストールしたソフトウェアについてのmodulefileを書きます。例えば自前のGromacs 2022.6をスパコンのユーザーディレクトリ上にインストールし、そのmodulefilesを`/data/group1/zxxxxxr/modulefiles/gromacs/2022.6`というファイルに作成したとします。次に`module use --append /data/group1/zxxxxxr/modulefiles`とコマンドを入力すれば、以降は`module avail`からその設定が呼び出せるようになっているはずです。呼び出せることを確認したら上記`module use`コマンドを`~/.bashrc`や`~/.zshrc`などのrcファイルに追記しておくと、毎度このコマンドを入力する手間が省略されるので大変便利です。

この設定を応用すれば、スパコン上で同じユーザーグループに属する異なるユーザーアカウントから共有のソフトウェアをEnvironment Modulesを使って設定を呼び出すこともできます。同じユーザーグループのみがアクセス可能なディレクトリを作成し（`chown`とか`chgrp`のコマンドで設定可能）、使いたいソフトウェアとmodulefilesをそのディレクトリに入れればOKです。

以下はスパコン上で自作のソフトウェアを使えるようにした状態の例です。

```bash
$ module avail

------------------------------------------------- /center/local/app/x86/hpci/modulefiles --------------------------------------------------
hpci_abinit-mp/openver1rev22  hpci_frontistr/5.2            hpci_modylas/1.1.0b           hpci_phonopy/2.12.0
hpci_abinit-mp/openver2rev4   hpci_genesis/1.7.0_double_cpu hpci_mvmc/1.2.0               hpci_salmon/2.0.2
hpci_akaikkr/cpa2002v010      hpci_genesis/1.7.0_double_gpu hpci_ntchem/12.1.1            hpci_smash/3.0.0
hpci_akaikkr/cpa2002v010gpu   hpci_genesis/1.7.0_single_cpu hpci_openmx/3.9.9
hpci_alamode/1.3.0            hpci_genesis/1.7.0_single_gpu hpci_phase0/2021.01_2d
hpci_ffb/8.1                  hpci_hphi/3.5.0               hpci_phase0/2021.01_3d

---------------------------------------------------- /data/group1/zxxxxxr/modulefiles -----------------------------------------------------
amber20                 gromacs/2021.5          openmpi/3.1.6_gcc8.4.0  openmpi/4.1.4_gcc8.4.0
amber22                 gromacs/2022.1          openmpi/4.1.4_gcc10.3.0
```