Ubuntu 20.04 LTS の Intel oneAPI で NetCDF-4 のインストール

**2023年11月5日：** 若干の更新と追記をしました．

Windows 10 **WSL2** の **Ubuntu 20.04LTS** において，オープンソース海洋流動モデル等で必要となる **NetCDF-4** を [**Intel oneAPI**](https://www.isus.jp/products/oneapi/oneapi-news-and-updates/) を用いてビルド・インストールする方法の簡単な備忘録です．スパコン（九州大学 ITO で検証）でも同様にインストール可能とするため，**ローカルインストール** とします．ソースコードのダウンロードは wget で行いましたが，うまく行かない場合は手動でダウンロードしましょう．
**Intel oneAPI** は [**apt でインストール**](https://estuarine.jp/2023/04/oneapi-ubuntu-22-04/) 可能です．
**備考：** NetCDF-CはGNU版のパッケージでインストールし，NetCDF-FortranはIntel oneAPIでビルドする圧倒的に簡単な方法は [こちら](https://estuarine.jp/2020/05/ubuntu-intel-netcdf/) で紹介しています（多分，この方法で十分です）．

## **~/.bashrc** の環境変数の設定

Intel oneAPI が利用できることを前提とします．コンパイラの環境変数を以下の通り **~/.bashrc** に設定し，Miniconda（Anaconda）がインストールされている場合はそれを無効にしておきます（Miniconda が **.bashrc** に追記した部分をコメントアウトします）．

```bash
# Intel oneAPI
export OPTIM="-O3"
export CC=icc
export CXX=icpc
export CFLAGS=${OPTIM}
export CXXFLAGS=${OPTIM}
export F77=ifort
export FC=ifort
export F90=ifort
export FFLAGS=${OPTIM}
export CPP="icc -E"
export CXXCPP="icpc -E"
```

## [CUnit](http://cunit.sourceforge.net/) のインストール
[こちら](https://blog.cleverelephant.ca/2014/12/building-cunit-from-source.html) と [こちら](https://qiita.com/from_chc/items/db771bef1e83fc00783a) を参考にしました．以下の インストール用のスクリプト **build_cunit.sh** をホームディレクトリ以下の適当なディレクトリ（ここでは `~/Downloads/` とし，以降も同様です）に作成します．インストール先は `~/local/` 以下としました（以降も同様です）．

```bash
#!/bin/bash
# build_cunit.sh
version_cunit="2.1-2"
wget http://downloads.sourceforge.net/project/cunit/CUnit/${version_cunit}/CUnit-${version_cunit}-src.tar.bz2
tar xf CUnit-${version_cunit}-src.tar.bz2
cd CUnit-${version_cunit}
./configure --prefix=${HOME}/local/CUnit/${version_cunit}
make
make install
```

`~/Downloads/` でこのスクリプトに実行権限を付与して（`chmod a+x build_cunit.sh`）実行します．

```bash
./build_cunit.sh
```

以下を `~/.bashrc` に追記し，再ログインします．

```bash
# CUnit
export LD_LIBRARY_PATH="${HOME}/local/CUnit/2.1-2/lib:$LD_LIBRARY_PATH"
```

## [UDUNITS](https://www.unidata.ucar.edu/software/udunits/) のインストール

あらかじめ以下をインストールします．この部分はroot権限が必要です．

```bash
sudo apt update
sudo apt install libexpat1
sudo apt install libexpat1-dev
sudo apt install libcunit1 libcunit1-doc libcunit1-dev
```

以下のスクリプトを同様に作成し，実行します．

```bash
#!/bin/bash
# build_udunits.sh
version_udunits="2.2.28" 
wget https://artifacts.unidata.ucar.edu/repository/downloads-udunits/udunits-${version_udunits}.tar.gz
tar xf udunits-${version_udunits}.tar.gz
cd udunits-${version_udunits}
./configure --prefix="${HOME}/local/udunits/${version_udunits}"
make
make check
make install
make clean
```

以下を `~/.bashrc` に追記し，再ログインします．バージョン番号に注意してください．

```bash
# UDUNITS
export UDUNITS2_XML_PATH="${HOME}/local/udunits/2.2.28/share/udunits/udunits2.xml"
export PATH="${HOME}/local/udunits/2.2.28/bin:$PATH"
```

## [SZIP](https://support.hdfgroup.org/doc_resource/SZIP/) のインストール

以下のスクリプトを同様に作成し，実行します．**SZIP** は **HDF5** のビルドで必要です．

```bash
#!/bin/bash
# build_szip.sh
version_szip="2.1.1"
wget https://support.hdfgroup.org/ftp/lib-external/szip/${version_szip}/src/szip-${version_szip}.tar.gz
tar xf szip-${version_szip}.tar.gz
cd szip-${version_szip}
./configure --prefix=${HOME}/local/szip/${version_szip}
make
make check
make install
```

## [zlib](https://zlib.net/) のインストール

以下のスクリプトを同様に作成し，実行します．**zlib** は **HDF5** のビルドで必要です．

```bash
#!/bin/bash
# build_zlib.sh for building zlib using Intel compiler
version_zlib="1.2.11"
wget https://zlib.net/zlib-${version_zlib}.tar.gz
tar xf zlib-${version_zlib}.tar.gz
cd zlib-${version_zlib}
./configure --prefix=${HOME}/local/zlib/${version_zlib}
make
make install
```

## [HDF5](https://www.hdfgroup.org/downloads/hdf5/source-code/) のインストール

ここは大変時間がかかります．手動で [**こちら**](https://www.hdfgroup.org/downloads/hdf5/source-code/#) から **hdf5-1.12.0.tar.gz** をダウンロードし（wgetは失敗しました），以下のスクリプトを同様に作成し，実行します．上でインストールした **zlib** と **szlib** のライブラリを指定する必要があり，それぞれのバージョン番号に注意します．
ソースコードのダウンロードは Windows で行い，Ubuntu でそれをコピーできます．Windows の Cドライブは，Ubuntu の `/mnt/c/` にマウントされています．
[こちら](http://wiki.opentelemac.org/doku.php?id=installation_linux_hdf5)を参考にしました．インストール方法を説明したファイルが `hdf5-1.12.0/release_docs/` にあります．`make check` でエラーが出たので，`--enable-parallel` は止めました．また，`--with-default-api-version=v18` を付与しないとNetCDF-4-C のビルドでエラーとなりました．

```bash
#!/bin/bash
# build_hdf5.sh
version_hdf5="1.12.0"
version_zlib="1.2.11"
version_szip="2.1.1"
tar xf hdf5-${version_hdf5}.tar.gz
cd hdf5-${version_hdf5}
./configure --prefix=${HOME}/local/hdf5/${version_hdf5} --with-zlib=${HOME}/local/zlib/${version_zlib}/include,${HOME}/local/zlib/${version_zlib}/lib --with-szlib=${HOME}/local/szip/${version_szip}/lib --enable-hl --enable-fortran --with-default-api-version=v18 
make
## make checkは非常に時間がかかり，途中で止まったように見えることが何度もあります．
make check
make install
make check-install
```

## [Curl](https://curl.se/) のインストール

**OPeNDAP** で必要です．以下のスクリプトを同様に作成し，実行します．

```bash
#!/bin/bash
# build_curl.sh for building Curl using Intel compiler
version_curl="7.76.1"
wget https://curl.se/download/curl-${version_curl}.tar.gz
tar xf curl-${version_curl}.tar.gz
cd curl-${version_curl}/
export OPTIM="-O3 -mcmodel=large -fPIC"
# testに失敗し，いろいろ試した結果，-mcmodel=large が不可欠でした
# このオプションが必要な理由は不明です
export CC=icc
export CXX=icpc
export CPP="icc -E -mcmodel=large"
export CXXCPP="icpc -E -mcmodel=large"
export CFLAGS="${OPTIM}"
export CXXFLAGS="${OPTIM}"
./configure --prefix=${HOME}/local/curl/${version_curl}
make
# テストは途中で止まる等うまくいかな場合があり，対処法不明で実害もなかったので飛ばしてよいでしょう
# make test
make install
```

`make test` で **Failed** が現れるかもしれませんが，実害はないようでした．ファイアウォールの警告のポップアップウィンドウが現れる場合は許可します．スパコン ITO では Failed が多発しましたが，セキュリティ上の制約によるものかもしれません．

## [NetCDF-4](https://www.unidata.ucar.edu/downloads/netcdf/) のインストール

C版とFortran版が分かれていますので，両者をインストールします．

### C版のNetCDF-4

以下のスクリプトを同様に作成し，実行します．2021年4月29日時点で最新版は **netcdf-c-4.8.0** でした．hdf5，zlib，curlのライブラリの設定ではバージョン番号の整合性に注意します．

```bash
#!/bin/bash
# build_netcdf-c.sh
version_netcdf4="4.8.0"
version_hdf5="1.12.0"
version_zlib="1.2.11"
version_curl="7.76.1"
wget https://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-c-${version_netcdf4}.tar.gz
tar xf netcdf-c-${version_netcdf4}.tar.gz
cd netcdf-c-${version_netcdf4}/
export LDFLAGS="-L${HOME}/local/hdf5/${version_hdf5}/lib -L${HOME}/local/zlib/${version_zlib}/lib -L${HOME}/local/curl/${version_curl}/lib"
export CPPFLAGS="-I${HOME}/local/hdf5/${version_hdf5}/include -I${HOME}/local/zlib/${version_zlib}/include ${LDFLAGS} -I${HOME}/local/curl/${version_curl}/include"
export OPTIM="-O3 -mcmodel=large -fPIC ${LDFLAGS}"
#
export CC=icc
export CXX=icpc
export CPP="icc -E -mcmodel=large"
export CXXCPP="icpc -E -mcmodel=large"
#
export CFLAGS="${OPTIM}"
export CXXFLAGS="${OPTIM}"
# dapをenableとするか，選択
./configure --prefix=${HOME}/local/netcdf4-intel/${version_netcdf4} --enable-large-file-tests --with-pic
# ./configure --prefix=${HOME}/local/netcdf4-intel/${version_netcdf4}-disable-dap --disable-dap --enable-large-file-tests --with-pic
make
make check
make install
```

### Fortran版の NetCDF-4

以下のスクリプトを同様に作成し，実行します．2021年4月29日時点で最新版は **netcdf-fortran-4.5.3** でした．上でインストールしたC版のNetCDF-4のディレクトリを **LD_LIBRARY_PATH** に指定する必要があります（以下のスクリプト参照）．

```bash
#!/bin/bash
# build_netcdf-fortran.sh
version_netcdf4_fortran="4.5.3"
version_netcdf4="4.8.0"
wget https://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-fortran-${version_netcdf4_fortran}.tar.gz
tar xf netcdf-fortran-${version_netcdf4_fortran}.tar.gz
cd netcdf-fortran-${version_netcdf4_fortran}
export NCDIR="${HOME}/local/netcdf4-intel/${version_netcdf4}"
export LD_LIBRARY_PATH="${NCDIR}/lib:${LD_LIBRARY_PATH}"
export NFDIR="${HOME}/local/netcdf4-intel-fortran/${version_netcdf4_fortran}"
export CPPFLAGS="-I${NCDIR}/include"
export LDFLAGS="-L${NCDIR}/lib"
export OPTIM="-O3 -mcmodel=large -fPIC ${LDFLAGS}"
export CC=icc
#export CXX=icpc
export FC=ifort
export F77=ifort
export F90=ifort
export CPP="icc -E -mcmodel=large"
export CXXCPP="icpc -E -mcmodel=large"
export CPPFLAGS="-DNDEBUG -DpgiFortran ${LDFLAGS} $CPPFLAGS"
export CFLAGS="${OPTIM}"
#export CXXFLAGS="${OPTIM}"
export FCFLAGS="${OPTIM}"
export F77FLAGS="${OPTIM}"
export F90FLAGS="${OPTIM}"
./configure --prefix=${NFDIR} --enable-large-file-tests --with-pic
make
make check
make install
```

### 環境変数の設定

`~/.bashrc` に以下の環境変数を追記し，再ログインします．バージョン番号の整合性に注意します．

```bash
export PATH="${HOME}/local/netcdf4-intel/4.8.0/bin:$PATH"
export PATH="${HOME}/local/netcdf4-intel-fortran/4.5.3/bin:$PATH"
export LD_LIBRARY_PATH="${HOME}/local/netcdf4-intel/4.8.0/lib:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH="${HOME}/local/netcdf4-intel-fortran/4.5.3/lib:$LD_LIBRARY_PATH"
```

## [NCVIEW](http://cirrus.ucsd.edu/ncview/) のインストール（GUIはMobaXterm）

NCVIEW は NetCDFファイルビュワーです．X-Windowが必要なため，ターミナルとして [**MobaXterm**](https://mobaxterm.mobatek.net/) **version 21.1** の利用を前提とします．version 20.6 と設定が異なるようでした．
**xorg-dev** をインストールします．

```bash
sudo apt install xorg-dev
```


以下のスクリプトを同様に作成し，実行します．UDUNITS ライブラリの指定が必要です．

```bash
#!/bin/bash
# build_ncview.sh for building NCVIEW using Intel compiler
wget https://fossies.org/linux/misc/ncview-2.1.8.tar.gz
tar xf ncview-2.1.8.tar.gz
cd ncview-2.1.8/
export OPTIM="-O3 -mcmodel=large -fPIC ${LDFLAGS}"
export CC=icc
export CXX=icpc
export CPP="icc -E -mcmodel=large"
export CXXCPP="icpc -E -mcmodel=large"
export CFLAGS="${OPTIM}"
export CXXFLAGS="${OPTIM}"
./configure --prefix=${HOME}/local/ncview-intel/2.1.8 --with-udunits2_incdir=${HOME}/local/udunits/2.2.28/include --with-udunits2_libdir=${HOME}/local/udunits/2.2.28/lib
make
make check
make install
```

`~/.bashrc` に以下を追記し，再ログインします．

```bash
export PATH="${HOME}/local/ncview-intel/2.1.8/bin:$PATH"
```

さらに，[**MobaXterm**](https://mobaxterm.mobatek.net/) の **Settings** ボタンの **Configuration** の **X11 タブ** の X11 settings にある，**X11 remote access** のプルダウンで **full** を選択します．これをしておかないと，ターミナルを立ち上げる度にポップアップが現れ，接続の許可を求められます．

### MobeXterm の補足
環境変数 **DISPLAY** の設定が必要になる場合が多いようですが，私のところで3台のPCを設定したところ，どういうわけか，1台は[こちらの記事](https://qiita.com/vega77/items/f00323e8ce64bfa1fdd6)と同じ現象で，DISPLAY を以下のように設定するとGUIが立ち上がりませんでした．3台の違いはMobaXtermのバージョンで，version 20.6 では以下の DISPLAY の設定が必要でした．一方，version 21.1 では DISPLAY の設定が不要でした．よく分からないのは，version 21.1 では DISPLAY の設定をして GUI が立ち上がる場合と立ち上がらない場合があることでした．さらに，**立ち上がる場合は以下の DISPLAY の設定をした方が高速に NCVIEW が立ち上がりました**．
ipconfig で IPアドレスを調べたところ，version 21.1 で以下の設定では立ち上がらなかったマシンでは Windowsの IP アドレスを DISPLAY に設定するとうまく行きました．version 21.1 で DISPLAY を明示的に設定しない状態では localhost:0.0 が自動設定されていました．[Changelog](https://mobaxterm.mobatek.net/download-home-edition.html) を見ると，version 21 で WSL 対応が進んでいるようですので，仕様変更があったものと思われます．
結論としては，問題なければ以下の設定をしておくのがよさそうです．

`~/.bashrc` に環境変数 DISPLAY を追記します．ただし，GUIが立ち上がらない場合は以下の追記をコメントアウトしてみましょう． 

```bash
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
# WSL-1 の場合は以下です
# export DISPLAY=localhost:0.0
```

### 参考資料
- [WSL2でGUIアプリを起動（Qiita）](https://qiita.com/vega77/items/f00323e8ce64bfa1fdd6)