第一原理パッケージ VASP 6.2.1 の 環境構築

#0.概要
お世話になっております. 橋本です.
表題にあります通り, VASP 6.2.1の環境設定, 及びその周辺の説明を記述いたします.
__この記事は「第一原理計算パッケージVASPの環境構築」(https://qiita.com/youkihashimoto3110/items/48ac16775d2768e1fd80 )に統合予定です.__

VASP 6.2.1の場合, コンパイルは, CPU, GPU_CUDA, GPU_oneACCの__3つ__のモードがあります. それぞれの特徴は以下の通りです.

1.CPU
・従来通りの機能. vaspの全ての機能を網羅している.

2.GPU_CUDA(the CUDA-C GPU port of VASP)
・VASP 5.4.1で登場. GPUで電子密度最適化(原子構造最適化)を計算可能になった. それ以外の最適化機能(GW法とか)は未対応. サポートは打ち切られ, 以降は以下のGPU_oneACCに置き換わる.

3.GPU_oneACC(the OpenACC GPU port of VASP)
・VASP 6.2.0で登場. GPU(とCPU)で動作し, 6.2.1時点で殆どの機能の移植を完了(GW法,ACFDT計算は移植作業中らしいです). ncclの特性上, mpiランク=取り付けられたGPUの枚数 に限定されるため, NEB法等の任意のmpiランクが必要な計算はGPU_CUDAが必要(開発中らしい).

コンパイラなのですが, CPU,GPU_CUDAモードについては従来と変わりません. 
CPUモードは「インテルコンパイラ」または「GNUコンパイラ」を使用します. 
GPU_CUDAモードは, CPUモードのコンパイラと「CUDAコンパイラ」及び, Kepler以降(K-シリーズ)のGPUです(公式より). 
※遊んだ限りだと, 1世代前のm2075やm2050でもGNUコンパイラと合わせて動きました. 倍精度ユニットの少ないGTX1080でも動きました.

GPU_oneACCモードは「NVIDIA_HPC-SDK」が必要です. むかしむかし, PGI-Fortranとかと呼ばれていたやつです. こいつにはPGIコンパイラ, CUDA, QD(ソフトウェアエミュレートの倍精度機能), NCCL(ベクトル計算とかFFTとかCUDAで高速化するやつ??)がセットになっております. 対応GPUはTesla P100, V100, A100, Quadro GP100, GV100.
※遊んでみた感じ, K80やGTX1080でも動きました.

__今回, この記事ではCPU, GPU_CUDA, GPU_oneACCの3つのモードをUbuntu 20.4 LTS上でコンパイル, 使えるようにします.__
使用するコンパイラは「インテルコンパイラ(oneAPI)」「CUDA 11.0_Update1」「NVIDIA_HPC-SDK_20.9」です.

原理的に, 「NVIDIA_HPC-SDK」を入れれば「CUDA」がついてくるので, 別途「CUDA」を入れる必要はないと思ったのですが, 「NVIDIA_HPC-SDK」と「インテルコンパイラ」との相性が悪く, 3つを使える環境にするためには, 「インテルコンパイラ」「CUDA」「NVIDIA_HPC-SDK」をそれぞれインストールする必要がありました.

#1.インテルコンパイラ(oneAPI)のインストール
※注意：何十万もするコンパイラが登録なしにかんたんに使えてしまいます. 学生は無料で有ることは確認したのですがそれ以外の開発者は存じ上げません. 気にされる方はライセンスを確認してください.

インストールの手順は公式のリファレンスから必要なものだけを抜粋したものです.
installing intel oneAPI Toolkits「https://software.intel.com/content/www/us/en/develop/articles/installing-intel-oneapi-toolkits-via-apt.html 」

まずキットをaptでインストールするキーを取得します.

```
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
```

登録します.

```
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
```

intel リポジトリを使用するためaptを構成します.

```
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
```

コンポーネントをアップグレード

```
sudo apt update
```

ベースツールキットをインストールします.
VASPで必要なC++が入ります. それ以外にもいっぱい入ります.(15GB)
__(※Ubuntu20.04の場合, ベースキットのインストールを省略することができるようです. 後述のハイパフォーマンス・コンピューターキットを入れる事で, ベースキット中の依存系が自動的にインストールされます.(研究室の後輩の実体験より.))__

```
sudo apt install intel-basekit
```

ハイパフォーマンス・コンピューターキットをインストールします.
MKLやFortran等がインストールされます.

```
sudo apt install intel-hpckit
```

以上. インテルコンパイラのインストール完了.
#2.CUDA 11.0_Update1
__※現在NVIDIA_HPC-SDK_20.9より新しいバージョンとVASP6.2.1との相性が悪いようです.(VASP側はNVIDIA_HPC-SDKが悪いと言っているようですが...)NVIDIA_HPC-SDK_20.9はCUDA 11.0を内包しており, これが動くCUDAドライバーヴァージョンでなければなりません. よって単体で導入するCUDAバージョンも11.0に揃えるというわけです.__

色々な種類のnVIDIA-GPUで色々なOS,ヴァージョンのCUDAを入れてきたCUDAインストール職人の私は経験から学びました.
「UbuntuにCUDAをインストールするときは, CUDAドライバーを入れてからCUDA単体をranファイルで入れよ！」と.
いま, GPUが「K80」, CUDAが「CUDA 11.0_Update1」の場合について説明します.

まず, CUDAドライバです.
ドライバをNVIDIAドライバダウンロードの詳細検索(過去のドライバー)「https://www.nvidia.co.jp/Download/Find.aspx?lang=jp 」からダウンロードします. CUDAバージョンを指定し, 「Linux x64 Ubuntu 20.04」のファイルをダウンロードします.
ドライバーをダウンロードできたら次はインストールです. 次のコマンドを順番に実行します.

```
sudo dpkg -i ダウンロードしたファイル
```
すると下の図のように「apt-keyを追加してください」と出る場合があるので, 言われたらそのとおりにします.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571701/95b12281-130b-1755-4d29-24af336656cc.png)
そして, ドライバを入れます.

```
sudo apt-get update
sudo apt-get install cuda-drivers
sudo reboot
```
再起動が完了したらCUDAをダウンロードしましょう. アーカイブ「https://developer.nvidia.com/cuda-toolkit-archive 」の中から対応するバージョンを選択し, CUDAをダウンロードします.
runファイルを選択することがコツ(?)です.
ファイルをダウンロードし, 以下のコマンドを実行してCuda Toolkitをインストールします.

```
sudo sh ダウンロードしたファイル
```
インストールの最中に, インストールする項目を選択する画面が登場します. このとき, CUDAのみにチェックを入れ, CUDAのみインストールしましょう.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571701/9be6459d-266b-9b43-be55-c02f938260d1.png)

以上. CUDA Tooklit のインストール完了.

#3.NVIDIA_HPC-SDK_20.9
__※現在NVIDIA_HPC-SDK_20.9より新しいバージョンとVASP6.2.1との相性が悪いようです.(VASP側はNVIDIA_HPC-SDKが悪いと言っているようですが...)__

アーカイブ「https://developer.nvidia.com/nvidia-hpc-sdk-releases 」の中から対応するバージョンを選択し, NVIDIA_HPC-SDKをダウンロード, インストールします.
NVIDIA_HPC-SDK_20.9の場合は以下のコマンドとなります.

```
wget https://developer.download.nvidia.com/hpc-sdk/20.9/nvhpc-20-9_20.9_amd64.deb
wget https://developer.download.nvidia.com/hpc-sdk/20.9/nvhpc-2020_20.9_amd64.deb
wget https://developer.download.nvidia.com/hpc-sdk/20.9/nvhpc-20-9-cuda-multi_20.9_amd64.deb
sudo apt-get install ./nvhpc-20-9_20.9_amd64.deb ./nvhpc-2020_20.9_amd64.deb ./nvhpc-20-9-cuda-multi_20.9_amd64.deb
```

以上. NVIDIA_HPC-SDKのインストール完了.

#4.VASPのインストール
VASPのインストールは単純で「ダウンロードしたアーカイブを展開」→「GPU_ACCモードのmakefile.includファイルを作成」→「make allコマンドでビルド」→「CPU,GPU_CUDAモードのmakefile.includファイルを作成」→「make allコマンドでビルド」の5手順です.
(__※なんかテストを実行しろとか言うのがあるのですがよくわかりませんでした__)

##「ダウンロードしたアーカイブを展開」
以下のコマンドでアーカイブを展開します.

```
tar -xzvf vasp.6.2.1.tar.gz
```

展開先のディレクトリに移動しインストールを続行します. 

```
cd vasp.6.2.1
```

##「makefile.includファイルを作成」
「makefile.includ」ファイルとは, 使用環境に合わせてビルドの設定を行う項目群です. 故に,コンパイラや,GPUの世代, CPUの機能等によって異なります. __ここでは2種類のmakefile.includeを作ります.__


###まず, GPU_ACCモード実行用の「makefile.includ」ファイルを作成します.
ビルドの順番はどちらでもいいのですが, 今回はこちらを先にしましょう. -
中身はただのテキストファイルなので新しく作っても良いのですが, エンコードや改行コードが異なったら事ですので, 安全な方法を取ります.
今,展開先のディレクトリは図のようになっています.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571701/d1195c3b-86f7-be30-e0a4-faea4a9e52f5.png)
この中の「arch」フォルダから,どれでも大丈夫ですので, 展開先のディレクトリへ1つコピーしてきて,名前を「makefile.includ」に変更しましょう. そのコマンドは以下のようになります.

```
cp arch/makefile.include.linux_intel makefile.includ
```
「makefile.includ」ファイルをviなどのテキストエディタで編集します.
__なお, VASPでGPUを使用されない方は以下の項目は不要です. CPUモード実行用の「makefile.include」ファイル作成のほうに移動してください.__
ここでテンプレートがありますので, ご自身の環境にあった方を引用くださいませ.変更するポイントは後ほど説明します.

```
# Precompiler options
CPP_OPTIONS= -DHOST=\"LinuxPGI\" \
             -DMPI -DMPI_BLOCK=8000 -DMPI_INPLACE -Duse_collective \
             -DscaLAPACK \
             -DCACHE_SIZE=4000 \
             -Davoidalloc \
             -Dvasp6 \
             -Duse_bse_te \
             -Dtbdyn \
             -Dfock_dblbuf \
             -D_OPENMP \
             -D_OPENACC \
             -DUSENCCL -DUSENCCLP2P

CPP        = nvfortran -Mpreprocess -Mfree -Mextend -E $(CPP_OPTIONS) $*$(FUFFIX)  > $*$(SUFFIX)

FC         = mpif90 -acc -gpu=cc35,cuda11.0 -mp
FCL        = mpif90 -acc -gpu=cc35,cuda11.0 -c++libs -mp

FREE       = -Mfree

FFLAGS     = -Mbackslash -Mlarge_arrays

OFLAG      = -fast

DEBUG      = -Mfree -O0 -traceback

# Specify your NV HPC-SDK installation, try to set NVROOT automatically
NVROOT     = /opt/nvidia/hpc_sdk/Linux_x86_64/20.9

# Use NV HPC-SDK provided BLAS and LAPACK libraries
BLAS       = -lblas
LAPACK     = -llapack

BLACS      =
SCALAPACK  = -Mscalapack

LLIBS      = $(SCALAPACK) $(LAPACK) $(BLAS)

OBJECTS    = fftmpiw.o fftmpi_map.o fftw3d.o fft3dlib.o

# Use MKL for BLAS, (sca)LAPACK, and FFTW (overwrite LLIBS and INCS)
LLIBS      = -L${MKLROOT}/lib/intel64 -lmkl_scalapack_lp64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lmkl_blacs_openmpi_lp64 -lpthread -lm -ldl
LLIBS     += -L/opt/intel/oneapi/compiler/latest/linux/compiler/lib/intel64_lin -liomp5
INCS       = -I$(MKLROOT)/include/fftw

CUDA       = -cudalib=cublas,cusolver,cufft,nccl -cuda
LLIBS      +=  $(CUDA)

# Software emulation of quadruple precsion
CPP_OPTIONS+= -Dqd_emulate
QD         ?= $(NVROOT)/compilers/extras/qd
LLIBS      += -L$(QD)/lib -lqdmod -lqd
INCS       += -I$(QD)/include/qd

# Redefine the standard list of O1 and O2 objects
SOURCE_O1  := pade_fit.o
SOURCE_O2  := pead.o

# For what used to be vasp.5.lib
CPP_LIB    = $(CPP)
FC_LIB     = nvfortran
CC_LIB     = nvc
CFLAGS_LIB = -O
FFLAGS_LIB = -O1 -Mfixed
FREE_LIB   = $(FREE)

OBJECTS_LIB= linpack_double.o getshmem.o

# For the parser library
CXX_PARS   = nvc++ --no_warnings

# Normally no need to change this
SRCDIR     = ../../src
BINDIR     = ../../bin
```
非常に多くの項目がございますが,変更する箇所はたったの3つです。上から順番に参ります.
__1つ.「-DMPI_BLOCKと-DCACHE_SIZE」__
こちらはCPUの1コアあたりのL1キャッシュのサイズと,その半分の数字を挿入します.例えば,「i9-9900X」の場合,wiki chip「https://en.wikichip.org/wiki/intel/core_i9/i9-9900x 」を参照すると32kBとわかります.
よって, ```-DMPI_BLOCK=32000```と,```-DCACHE_SIZE```にはその半分の```-DCACHE_SIZE=16000```を入力します.
ちなみに,core-iシリーズでは1コアあたりのL1キャッシュサイズは32kBです.
面倒であればデフォルトの```-DMPI_BLOCK=8000```と```-DCACHE_SIZE=4000```でも動きます.

__2つ.「FC」と「FCL」__
GPUアーキテクチャ固有のオプションです.各環境に合わせた数値を使用します.数値はCuda Toolkit Documentation「https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list 」の5.2項にあります.例えば, 「GTX 1080」はPascal世代なので,60,61,62を使用します.すなわち

```
FC         = mpif90 -acc -gpu=cc60,cc61,cc62,cuda11.0 -mp
FCL        = mpif90 -acc -gpu=cc60,cc61,cc62,cuda11.0 -c++libs -mp
```
このように「cc数字」で指定します. と, 言いたいのですが, 問題があります.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571701/379d9365-05a7-123f-10d7-74734271456e.png)
このようにエラーになってしまいます. 内容はどうやら「```-gpu=cc61```は命令に含まれてないし, ```-gpu=cc62```はLinuxじゃ使えないよ.」というものです. なのであきらめて

```
FC         = mpif90 -acc -gpu=cc60,cuda11.0 -mp
FCL        = mpif90 -acc -gpu=cc60,cuda11.0 -c++libs -mp
```
としましょう.

また,異なる世代の数値も入力可能です.

__3つ.「NVROOT」等のコンパイラヴァージョン__
NVIDIA_HPC-SDKのヴァージョンです. 今回は20.9を使用していますので末尾が20.9ですが, それ以外のヴァージョンの場合は```/opt/nvidia/hpc_sdk/Linux_x86_64/```のディレクトリに移動し, フォルダ名を確認してください.
あわせて, ```LLIBS     += -L/opt/intel/oneapi/compiler/latest/linux/compiler/lib/intel64_lin -liomp5``にあります, ```/opt/intel/oneapi/compiler/latest/linux/compiler/lib/intel64_lin```に移動できるかも確認してください. 行けない場合はディレクトリを辿ってみてください.


###次に, CPU, GPU_CUDAモード実行用の「makefile.includ」ファイルを作成します.
今回は2回ビルドします. 2回目のビルド, すなわちCPU, GPU_CUDAモード実行用のVASPを生成するとき, 以下のように「makefile.include」を書き換えてください.
なお, VASPでGPUを使用されない方は「# GPU Stuff」以下の項目は不要です.

```
# Precompiler options
CPP_OPTIONS= -DHOST=\"LinuxIFC\"\
             -DMPI -DMPI_BLOCK=8000 -Duse_collective \
             -DscaLAPACK \
             -DCACHE_SIZE=4000 \
             -Davoidalloc \
             -Dvasp6 \
             -Duse_bse_te \
             -Dtbdyn \
             -Dfock_dblbuf

CPP        = fpp -f_com=no -free -w0  $*$(FUFFIX) $*$(SUFFIX) $(CPP_OPTIONS)

FC         = mpiifort
FCL        = mpiifort -mkl=sequential

FREE       = -free -names lowercase

FFLAGS     = -assume byterecl -w -xHOST
OFLAG      = -O3 -xAVX2
OFLAG_IN   = $(OFLAG)
DEBUG      = -O0

MKL_PATH   = $(MKLROOT)/lib/intel64
BLAS       =
LAPACK     =
BLACS      = -lmkl_blacs_intelmpi_lp64
SCALAPACK  = $(MKL_PATH)/libmkl_scalapack_lp64.a $(BLACS)

OBJECTS    = fftmpiw.o fftmpi_map.o fft3dlib.o fftw3d.o

INCS       =-I$(MKLROOT)/include/fftw

LLIBS      = $(SCALAPACK) $(LAPACK) $(BLAS)

OBJECTS_O1 += fftw3d.o fftmpi.o fftmpiw.o
OBJECTS_O2 += fft3dlib.o

# For what used to be vasp.5.lib
CPP_LIB    = $(CPP)
FC_LIB     = $(FC)
CC_LIB     = icc
CFLAGS_LIB = -O
FFLAGS_LIB = -O1
FREE_LIB   = $(FREE)

OBJECTS_LIB= linpack_double.o getshmem.o

# For the parser library
CXX_PARS   = icpc
LLIBS      += -lstdc++

# Normally no need to change this
SRCDIR     = ../../src
BINDIR     = ../../bin

#================================================
# GPU Stuff

CPP_GPU    = -DCUDA_GPU -DRPROMU_CPROJ_OVERLAP -DUSE_PINNED_MEMORY -DCUFFT_MIN=28 -UscaLAPACK -Ufock_dblbuf

OBJECTS_GPU= fftmpiw.o fftmpi_map.o fft3dlib.o fftw3d_gpu.o fftmpiw_gpu.o

CC         = icc
CXX        = icpc
CFLAGS     = -fPIC -DADD_ -Wall -qopenmp -DMAGMA_WITH_MKL -DMAGMA_SETAFFINITY -DGPUSHMEM=300 -DHAVE_CUBLAS

# Minimal requirement is CUDA >= 10.X. For "sm_80" you need CUDA >= 11.X.
CUDA_ROOT  ?= /usr/local/cuda/
NVCC       := $(CUDA_ROOT)/bin/nvcc -ccbin=icc -allow-unsupported-compiler
CUDA_LIB   := -L$(CUDA_ROOT)/lib64 -lnvToolsExt -lcudart -lcuda -lcufft -lcublas

GENCODE_ARCH    := -gencode=arch=compute_37,code=\"sm_37,compute_37\"

## For all legacy Intel MPI versions (before 2021)
#MPI_INC    = $(I_MPI_ROOT)/intel64/include/

# Or when you are using the Intel oneAPI compiler suite
MPI_INC    = $(I_MPI_ROOT)/include/
```

非常に多くの項目がございますが,変更する箇所はたったの3つです。上から順番に参ります.
__1つ.「-DMPI_BLOCKと-DCACHE_SIZE」__
こちらはCPUの1コアあたりのL1キャッシュのサイズと,その半分の数字を挿入します.例えば,「i9-9900X」の場合,wiki chip「https://en.wikichip.org/wiki/intel/core_i9/i9-9900x 」を参照すると32kBとわかります.
よって, ```-DMPI_BLOCK=32000```と,```-DCACHE_SIZE```にはその半分の```-DCACHE_SIZE=16000```を入力します.
ちなみに,core-iシリーズでは1コアあたりのL1キャッシュサイズは32kBです.
面倒であればデフォルトの```-DMPI_BLOCK=8000```と```-DCACHE_SIZE=4000```でも動きます.

__2つ.「OFLAG」__
かなり厄介です. 難しい場合,「OFLAG = -O2」だけでもVASPは動きます.
こちらは, CPUの機能を最大限使う最適化のオプションです. このオプションは使うCPUにも,コンパイラによっても異なります.
このオプションは必要以上にこだわる事ができますが, 大切なポイントを押さえれば最大限のパフォーマンスが得られます.
「Intelコンパイラ(Parallel Studio XE)の場合」
例えば,Intel Fortran 19ではクイック・リファレンス・ガイド「https://jp.xlsoft.com/documents/intel/compiler/19/Quick-Reference-Guide-Intel-Compilers-v19.pdf 」に示す全てのオプションを使用でき,ここから最適なものを選択します.
膨大なので, ピックアップします. 
まず「-O2」もしくは「-O3」は必須です. これは最適化の度合いを表し, 最近の2013年以降のプロセッサでは基本「-O3」を使用します.
次に「-x」と「-arch」です.これはプロセッサに最適化されたコードを生成できます.インテル製CPUの場合「-x」を,AMD製等は「-arch」を選択します. 例えば,「i9-9900X」の場合,wiki chip「https://en.wikichip.org/wiki/intel/core_i9/i9-9900x 」を参照するとAVX-512と呼ばれる高速なベクトル計算が利用できます.この機能を使用するには「-xSKYLAKE-AVX512」と,リファレンスに載っているコマンドを選択します.

__3つ.「GENCODE_ARCH」__※GPU_CUDAを利用する場合のみ
GPUアーキテクチャ固有のオプションです.各環境に合わせた数値を使用します.数値はCuda Toolkit Documentation「https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list 」の5.2項にあります.例えば, 「GTX 1080」はPascal世代なので,60,61,62を使用します.すなわち

```
GENCODE_ARCH    := -gencode=arch=compute_60,code=\"sm_60,compute_60\"\
                   -gencode=arch=compute_61,code=\"sm_61,compute_61\"\
                   -gencode=arch=compute_62,code=\"sm_62,compute_62\"\
```
と指定します.また,異なる世代の数値も入力可能です.

##「make allコマンドでビルド」
makefile.includeと同じディレクトリで, コマンド

```
make DEPS=1 -jN <target>
```
を使用することでVASPビルドを生成することができます. Nにはビルドに使用するCPUコア数が入ります. <target>には「std」「gam」「ncl」「gpu」「gpu_ncl」のいずれかが入ります. 
コンパイルファイルは「build」フォルダーに入っており,それぞれ,「std」「gam」「ncl」「gpu」「gpu_ncl」です.
たいていの研究には「std」と「gpu」で事足りると思います故,例えば4コアのCPUの場合, ```make DEPS=1 -j4 std gpu```の実行でもよろしいかと思われます.

正常にビルドが完了したら, それぞれのフォルダーの中に「vasp」という名前のファイルがございます.それがVASPの本体です.
また, 「bin」の中にもそのコピーが「vasp_std」や「vasp_gpu」とかの名前でありますので, こちらを用いたほうが便利です.

今回は2回ビルドします. 1回目のビルドでGPU_ACCモード実行用が, 2回目でCPUとGPU_CUDAモード実行用がそれぞれ出力されます.
__1回目のビルド__
上述のGPU_ACCモード用の「makefile.include」を使用します.
また, コンパイラとして「NVIDIA_HPC-SDK」の全機能と, 「インテルコンパイラ(oneAPI)」の「コンパイラ」と「MKL」が必要です.
これらを使うため, パスを通します. 
「NVIDIA_HPC-SDK」は

```
NVARCH=`uname -s`_`uname -m`; export NVARCH
NVCOMPILERS=/opt/nvidia/hpc_sdk; export NVCOMPILERS
MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/20.9/compilers/man; export MANPATH
PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/bin:$PATH; export PATH
export PATH=$NVCOMPILERS/$NVARCH/20.9/comm_libs/mpi/bin:$PATH
export MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/20.9/comm_libs/mpi/man
export LD_LIBRARY_PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/extras/qd/lib/:$LD_LIBRARY_PATH
```
です. 「20.9」とあるところはヴァージョンです. インストールされた「NVIDIA_HPC-SDK」のヴァージョンに従ってください.
「インテルコンパイラ(oneAPI)」の「コンパイラ」と「MKL」は

```
source /opt/intel/oneapi/mkl/2021.3.0/env/vars.sh
source /opt/intel/oneapi/compiler/2021.3.0/env/vars.sh
```
です. 「2021.3.0」はヴァージョンです. そのディレクトリに移動し, 自身のヴァージョンを確認してください.__ここでoneAPIの全機能を有効にしないでください. PATHはコンパイラとMKLのみです.__
そして, VASPをビルドします. 例えば, 4コアでGPU_ACCモードのVASPの「std」「gam」「ncl」をビルドするには

```
make DEPS=1 -j4 all
```
と入力します.

__2回目のビルド__
上述のCPU, GPU_GPUモード用の「makefile.include」を使用します.
また, コンパイラとして「CUDAコンパイラ」の全機能と, 「インテルコンパイラ(oneAPI)」の全機能が必要です.
これらを使うため, パスを通します. 
「CUDAコンパイラ」は

```
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
```
「インテルコンパイラ(oneAPI)」は

```
source /opt/intel/oneapi/setvars.sh
```
です.
そして, VASPをビルドします.
__ビルドの際, GPU_ACCモードの生成ファイル, ディレクトリをリネームしておきましょう. 「std」「gam」「ncl」は名前がかぶります.__
例えば, 4コアでCPU, GPU_GPUモードのVASPの「std」「gam」「ncl」「gpu」「gpu_ncl」をビルドするには

```
make DEPS=1 -j4 all gpu gpu_ncl
```
と入力します.

#4.インストール後の起動確認
大きな系で計算する際にスタックメモリが足りないと言われる可能性がありますので, 上限を開放します.以下のコマンドを実行してください.

```
ulimit -sunlimited
```
また、毎回実行するのが面倒であれば, 「.bashrc」の末尾に追記しておきましょう.
##・VASP.6.2.1の場合
H2O-VASP「https://www.vasp.at/wiki/index.php/H2O 」を使用します.ファイルをダウンロードし,展開しておいてください.
###GPU_ACCモードの実行
生成時と同様にPATHを通します.「NVIDIA_HPC-SDK」の全機能と, 「インテルコンパイラ(oneAPI)」の「コンパイラ」と「MKL」が必要です.
「NVIDIA_HPC-SDK」は

```
NVARCH=`uname -s`_`uname -m`; export NVARCH
NVCOMPILERS=/opt/nvidia/hpc_sdk; export NVCOMPILERS
MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/20.9/compilers/man; export MANPATH
PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/bin:$PATH; export PATH
export PATH=$NVCOMPILERS/$NVARCH/20.9/comm_libs/mpi/bin:$PATH
export MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/20.9/comm_libs/mpi/man
export LD_LIBRARY_PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$NVCOMPILERS/$NVARCH/20.9/compilers/extras/qd/lib/:$LD_LIBRARY_PATH
```
「インテルコンパイラ(oneAPI)」の「コンパイラ」と「MKL」は

```
source /opt/intel/oneapi/mkl/2021.3.0/env/vars.sh
source /opt/intel/oneapi/compiler/2021.3.0/env/vars.sh
```

展開したH2OのフォルダにビルドしたVASP本体をコピーします.例えばcpuで実行する時は,

```
cp /VASPのインストールディレクトリ/vasp.5.4.4/build/std/vasp /H2Oのフォルダ/vasp
```
となります. H2Oのフォルダへ移動し,以下のコマンドを実行します.

```
./vasp
```
計算が実行できたら, 並列化計算も実施してみましょう. __並列数はGPUボード(GPUユニット)の枚数です.__ 例えば4枚K40のボードを積んでいたら

```
mpirun -np 4 ./vasp
```
※4枚のK80ボードの場合, K80には1ボードに2つのGPUユニットがあるので, ```mpirun -np 8 ./vasp```となります.

###CPU, GPU_CUDAモードの実行
生成時と同様にPATHを通します.
「CUDAコンパイラ」は

```
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
```
「インテルコンパイラ(oneAPI)」は

```
source /opt/intel/oneapi/setvars.sh
```
CPUモードでの実行時, 並列化ノード数の上限はCPUの物理コア数です. 論理コア数を足すと, むしろ遅くなります(ですが動きます.). 例えば4コアの場合は,

```
mpirun -np 4 ./vasp
```
GPU_CUDAモードでの実行時, INCARファイル内のタグに成約があります. NCOREは1に(もしくは記述なしに), ALGOはNORMAL, FAST, VERYFASTのいずれかに限定されます. 
並列化ノード数は5以上のとき, "NCOREが指定されていない"とか警告が出ますが実行可能です. GPUのメモリ限界が, 並列化ノード数の限界値です. 大抵の場合, 並列化ノード数はGPUボードの枚数にすればいいです. 例えば4枚K40のボードを積んでいたら

```
mpirun -np 4 ./vasp
```
となります.

###いちいちPATH通すのは面倒です.
はい. 面倒です. 私は, NVIDIA_HPC-SDKとインテルコンパイラ, MKLのPATHをbashrcに書き込み, 自動でGPU_ACCモードのPATHを通しています.
CPU, GPU_CUDAモードが使いたくなったら, oneAPIのPATHだけを通します.

__そもそも, なんでこんな面倒なことになっているか説明します.__
インテルコンパイラ, MKL, インテルMPIは非常に優れたコンパイラライブラリです. インテルMPIはインテルCPUのコアを適切に専有してくれ, MKLは優れた線形変換アルゴリズム, FFTのライブラリを提供してくれます. これを使わない手はありません. 

しかし, 新しいGPU_ACCはNVIDIA_HPC-SDKに含まれるopenACCという, インテルMPIやopenMPよりも広い抽象度で並列化が可能になる機能を要求しているのです. 残念ながら, intel oneAPIにopenACCは含まれていません. (ってかなんだよ. 小文字+大文字略称の組み合わせ流行ってるの？oneAPIとかopenACCとかややこしいのだが.)

よって, GPU_ACCを使うためにはインテルMPIの機能を無効にしなければならず, CPU, GPU_CUDAモードを使用するときにはACC機能を無効にし, インテルMPIの機能を有効にしなければなりません.
コンパイルのときには, 確かに上のように, NVIDIA_HPC-SDKを読み込まない(無効にする)処理が必要なのですが, なぜか, コンパイル後の使用時には, あとからインテルMPIの機能を有効にすればインテルMPIの機能を自動的に選択してくれるようになります.

#6.参考記事
VASP Wiki 「https://www.vasp.at/wiki/index.php/The_VASP_Manual」
Intel Vasp build「https://software.intel.com/content/www/us/en/develop/articles/building-vasp-with-intel-mkl-and-intel-compilers.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ISNMain+%28Intel+Developer+Zone+Articles+Feed%29 」
Cuda VASP 「https://www.nvidia.com/en-us/data-center/gpu-accelerated-applications/vasp/ 」