Intel MKLの各Linuxへのインストール方法

CentOS
-------
Intel公式の Yum リポジトリからインストールします
https://software.intel.com/content/www/us/en/develop/articles/installing-intel-free-libs-and-python-yum-repo.html

```sh
yum-config-manager --add-repo https://yum.repos.intel.com/mkl/setup/intel-mkl.repo
rpm --import https://yum.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
yum install -y intel-mkl-2020.0-088
```

`/opt/intel` にインストールします。

```
ldconfig -p | grep mkl
```

ldconfigには通しません。 `/opt/intel/mkl/bin/mklvars.sh` を使わせるつもりなんでしょう。

```
$ source /opt/intel/mkl/bin/mklvars.sh intel64
$ pkg-config --libs mkl-static-lp64-iomp
Variable 'prefix' not defined in '/opt/intel/compilers_and_libraries_2020.0.166/linux/mkl/bin/pkgconfig/mkl-static-lp64-iomp.pc'
```

追加で `pkg-config` の設定をする必要があります https://software.intel.com/content/www/us/en/develop/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool.html

Debian / Ubuntu (from Intel repository)
------
Intel公式の apt リポジトリからインストールします
https://software.intel.com/content/www/us/en/develop/articles/installing-intel-free-libs-and-python-apt-repo.html

```sh
apt install -y curl gnupg
curl -sfL https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB | apt-key add -
curl -sfL https://apt.repos.intel.com/setup/intelproducts.list -o /etc/apt/sources.list.d/intelproducts.list
apt update
apt install -y intel-mkl-2020.0.088
```

`/opt/intel` にインストールする

```
$ source /opt/intel/mkl/bin/mklvars.sh intel64
$ pkg-config --libs mkl-static-lp64-iomp
Variable 'prefix' not defined in '/opt/intel/compilers_and_libraries_2020.0.166/linux/mkl/bin/pkgconfig/mkl-static-lp64-iomp.pc'
```

追加で `pkg-config` の設定をする必要があります https://software.intel.com/content/www/us/en/develop/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool.html

Debian (10 = buster)
---------
nonfree リポジトリで公式に配布しています。nonfree リポジトリを有効にするには apt の設定を追加する必要があります
https://wiki.debian.org/SourcesList

```/etc/apt/sources.list
deb http://deb.debian.org/debian buster main contrib non-free
deb-src http://deb.debian.org/debian buster main contrib non-free

deb http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb-src http://deb.debian.org/debian-security/ buster/updates main contrib non-free

deb http://deb.debian.org/debian buster-updates main contrib non-free
deb-src http://deb.debian.org/debian buster-updates main contrib non-free
```

これで `apt` で入ります

```sh
apt install -y intel-mkl
```

これで `/usr/lib/x86_64-linux-gnu/` 以下にインストールされます。
インストール時に `update-alternative` の設定をするかどうかを聞かれます

```
If you don't know what MKL is, or unwilling to set it as default, just choose the preset value or simply type Enter.                                                  
Use libmkl_rt.so as the default alternative to BLAS/LAPACK? [yes/no] yes                                                                                              
Please select the alternatives that should point to MKL. The selection applies to all available architectures, and the related
development packages will follow the same selection.
                                                                  
Typically the user may want to point both BLAS/LAPACK to MKL (libmkl_rt.so). Type Enter if you are not sure what to select.
                                 
  1. libblas.so.3  2. liblapack.so.3  3. libblas64.so.3  4. liblapack64.so.3,  5. none of the above
                                                                                                                                     
(Enter the items you want to select, separated by spaces.)                                                                           
                                                                                                                                     
Which of the these alternatives should point to MKL?         
```

この選択により `libblas.so` 等のシンボリックリンク先を MKL にすることが可能です。つまりビルド時に `-llapack -lblas` で MKL の BLAS/LAPACKを使うようになります。

```
$ ldconfig -p | grep mkl
        libmkl_vml_mc3.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_mc3.so
        libmkl_vml_mc2.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_mc2.so
        libmkl_vml_mc.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_mc.so
        libmkl_vml_def.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_def.so
        libmkl_vml_cmpt.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_cmpt.so
        libmkl_vml_avx512_mic.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_avx512_mic.so
        libmkl_vml_avx512.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_avx512.so
        libmkl_vml_avx2.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_avx2.so
        libmkl_vml_avx.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_vml_avx.so
        libmkl_tbb_thread.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_tbb_thread.so
        libmkl_sequential.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_sequential.so
        libmkl_rt.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_rt.so
        libmkl_pgi_thread.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_pgi_thread.so
        libmkl_mc3.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_mc3.so
        libmkl_mc.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_mc.so
        libmkl_intel_thread.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_intel_thread.so
        libmkl_intel_lp64.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_intel_lp64.so
        libmkl_intel_ilp64.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_intel_ilp64.so
        libmkl_gnu_thread.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_gnu_thread.so
        libmkl_gf_lp64.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_gf_lp64.so
        libmkl_gf_ilp64.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_gf_ilp64.so
        libmkl_def.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_def.so
        libmkl_core.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_core.so
        libmkl_avx512_mic.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_avx512_mic.so
        libmkl_avx512.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_avx512.so
        libmkl_avx2.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_avx2.so
        libmkl_avx.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libmkl_avx.so
```

`ldconfig` で見えるようになっています

```
$ pkg-config --libs mkl-static-lp64-iomp
-Wl,--start-group /usr/lib/x86_64-linux-gnu/libmkl_intel_lp64.a /usr/lib/x86_64-linux-gnu/libmkl_intel_thread.a /usr/lib/x86_64-linux-gnu/libmkl_core.a -Wl,--end-group -liomp5 -lpthread -lm -ldl
```

`pkg-config` も認識します

Ubuntu 20.04
----------
Ubuntuはnonfree分けてないのでそのままあります

```sh
apt install -y intel-mkl
```

`/lib/x86_64-linux-gnu/` にインストールします。インストール時に `update-alternative` の設定を聞かれるのは Debianと同様です。

```
ldconfig -p | grep mkl
        libmkl_vml_mc3.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_mc3.so
        libmkl_vml_mc2.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_mc2.so
        libmkl_vml_mc.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_mc.so
        libmkl_vml_def.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_def.so
        libmkl_vml_cmpt.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_cmpt.so
        libmkl_vml_avx512_mic.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_avx512_mic.so
        libmkl_vml_avx512.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_avx512.so
        libmkl_vml_avx2.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_avx2.so
        libmkl_vml_avx.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_vml_avx.so
        libmkl_tbb_thread.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_tbb_thread.so
        libmkl_sequential.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_sequential.so
        libmkl_rt.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_rt.so
        libmkl_pgi_thread.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_pgi_thread.so
        libmkl_mc3.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_mc3.so
        libmkl_mc.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_mc.so
        libmkl_intel_thread.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_intel_thread.so
        libmkl_intel_lp64.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_intel_lp64.so
        libmkl_intel_ilp64.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_intel_ilp64.so
        libmkl_gnu_thread.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_gnu_thread.so
        libmkl_gf_lp64.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_gf_lp64.so
        libmkl_gf_ilp64.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_gf_ilp64.so
        libmkl_def.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_def.so
        libmkl_core.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_core.so
        libmkl_avx512_mic.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_avx512_mic.so
        libmkl_avx512.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_avx512.so
        libmkl_avx2.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_avx2.so
        libmkl_avx.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libmkl_avx.so
```

ldconfigはちゃんと設定されている

```
$ pkg-config --libs mkl-static-lp64-iomp
-Wl,--start-group /usr/lib/x86_64-linux-gnu/libmkl_intel_lp64.a /usr/lib/x86_64-linux-gnu/libmkl_intel_thread.a /usr/lib/x86_64-linux-gnu/libmkl_core.a -Wl,--end-group -liomp5 -lpthread -lm -ldl
```

pkg-configも設定されている

ArchLinux
--------------
なんか公式にある https://www.archlinux.jp/packages/community/x86_64/intel-mkl/

```sh
pacman -S intel-mkl intel-mkl-static
```

`/opt/intel` にインストールします

```
$ cat /etc/ld.so.conf.d/intel-mkl.conf 
/opt/intel/mkl/lib/intel64
/opt/intel/mkl/lib/intel64_lin
$ ldconfig -p | grep mkl
        libmkl_vml_mc3.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_mc3.so
        libmkl_vml_mc2.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_mc2.so
        libmkl_vml_mc.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_mc.so
        libmkl_vml_def.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_def.so
        libmkl_vml_cmpt.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_cmpt.so
        libmkl_vml_avx512_mic.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_avx512_mic.so
        libmkl_vml_avx512.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_avx512.so
        libmkl_vml_avx2.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_avx2.so
        libmkl_vml_avx.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_vml_avx.so
        libmkl_tbb_thread.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_tbb_thread.so
        libmkl_sequential.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_sequential.so
        libmkl_scalapack_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_scalapack_lp64.so
        libmkl_scalapack_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_scalapack_ilp64.so
        libmkl_rt.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_rt.so
        libmkl_pgi_thread.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_pgi_thread.so
        libmkl_mc3.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_mc3.so
        libmkl_mc.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_mc.so
        libmkl_intel_thread.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_intel_thread.so
        libmkl_intel_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_intel_lp64.so
        libmkl_intel_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_intel_ilp64.so
        libmkl_gnu_thread.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_gnu_thread.so
        libmkl_gf_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_gf_lp64.so
        libmkl_gf_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_gf_ilp64.so
        libmkl_def.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_def.so
        libmkl_core.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_core.so
        libmkl_cdft_core.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_cdft_core.so
        libmkl_blacs_sgimpt_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_sgimpt_lp64.so
        libmkl_blacs_sgimpt_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_sgimpt_ilp64.so
        libmkl_blacs_openmpi_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_openmpi_lp64.so
        libmkl_blacs_openmpi_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_openmpi_ilp64.so
        libmkl_blacs_intelmpi_lp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.so
        libmkl_blacs_intelmpi_ilp64.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_blacs_intelmpi_ilp64.so
        libmkl_avx512_mic.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_avx512_mic.so
        libmkl_avx512.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_avx512.so
        libmkl_avx2.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_avx2.so
        libmkl_avx.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libmkl_avx.so
        libiomp5_db.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libiomp5_db.so
        libiomp5.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libiomp5.so
        libiompstubs5.so (libc6,x86-64) => /opt/intel/mkl/lib/intel64/libiompstubs5.so
```

ldconfigもちゃんと設定されてる

```
$ pkg-config --libs mkl-static-lp64-iomp
-Wl,--start-group /opt/intel/mkl/lib/intel64/libmkl_intel_lp64.a /opt/intel/mkl/lib/intel64/libmkl_intel_thread.a /opt/intel/mkl/lib/intel64/libmkl_core.a -Wl,--end-group -L/opt/intel/mkl/lib/intel64 -liomp5 -lpthread -lm -ldl 
```

pkg-configもちゃんと設定されている

Other Linux
-------------------

自動化の為に非対話的に行うためのスクリプトです

```silent.cfg
# Patterns used to check silent configuration file
#
# anythingpat - any string
# filepat     - the file location pattern (/file/location/to/license.lic)
# lspat       - the license server address pattern (0123@hostname)
# snpat       - the serial number pattern (ABCD-01234567)
# comppat     - the component abbreviation (intel-component-0123.4-567__arch), use installer command line option to get it

# Accept EULA, valid values are: {accept, decline}
ACCEPT_EULA=accept

# Optional error behavior, valid values are: {yes, no}
CONTINUE_WITH_OPTIONAL_ERROR=yes

# Install location, valid values are: {/opt/intel, filepat}
PSET_INSTALL_DIR=/opt/intel

# Continue with overwrite of existing installation directory, valid values are: {yes, no}
CONTINUE_WITH_INSTALLDIR_OVERWRITE=yes

# List of components to install (use semicolon to separate the components), valid values are: {ALL, DEFAULTS, comppat}
COMPONENTS=DEFAULTS

# Installation mode, valid values are: {install, repair, uninstall}
PSET_MODE=install

# Path to the cluster description file, valid values are: {filepat}
#CLUSTER_INSTALL_MACHINES_FILE=filepat

# Perform validation of digital signatures of RPM files, valid values are: {yes, no}
SIGNING_ENABLED=yes

# Select target architecture of your applications, valid values are: {IA32, INTEL64, ALL}
ARCH_SELECTED=INTEL64
```

```intel-mkl.conf
/opt/intel/mkl/lib/intel64
/opt/intel/mkl/lib/intel64_lin
```

```sh
curl -sfLO http://registrationcenter-download.intel.com/akdlm/irc_nas/tec/16533/l_mkl_2020.1.217.tgz  # termoshttの認証で取得したURLです
tar xf l_mkl_2020.1.217.tgz
cd l_mkl_2020.1.217
./install.sh -s ../silent.cfg
cd -

# Setup linker to find shared library
mv intel-mkl.conf /etc/ld.so.conf.d/
ldconfig

# Setup pkg-config
export PKG_CONFIG_PATH=/opt/intel/mkl/bin/pkgconfig  # これは /etc/profile あたりにおくほうがよさげ
sed -i "s/MKLROOT/prefix/g" ${PKG_CONFIG_PATH}/*.pc
```

まとめ
---------

- Intel配布のものは追加の設定が必要
    - 基本的に `/opt/intel` にインストールする
- 各ディストリビューションで配布されているものは適切に設定がなされている
    - ただしインストール先は各ディストリビューション毎の方式に則っているのでバラバラ