MKLの使い方


Intel oneAPIを導入後、Math Kernel Library (MKL)と呼ばれるライブラリ群の使用が可能になる。ここでは、その使い方を説明する。ライブラリ群には、

  • Blas (Basic Linear Algebra Subprograms)
  • Lapack (Linear Algebra PACKage)
  • Scalapack (Scalable Linear Algebra PACKage、Lapackの分散メモリ型並列計算版)
  • sparse solver routine (疎行列の連立一次方程式を解くためのルーチン)

などなど、いろいろなライブラリが入っている。


1.行いたい処理を実現する、関数の名前を特定する

ネットで調べると、次のような資料を見つけることができると思う。

  • Intel® oneAPI Math Kernel Library LAPACK Examples
  • Developer Reference for Intel® oneAPI Math Kernel Library for C
  • Developer Reference for Intel® oneAPI Math Kernel Library for Fortran
  • インテル®数値演算ライブラリ リファレンス・マニュアル

これらの資料やネット(日本nagのページが良い, https://www.nag-j.co.jp/)から、目的の関数の名前を同定する。なおルーチンには命名規則があることが多い。たとえばLapackであれば、「インテル®数値演算ライブラリ リファレンス・マニュアル」のp181に載っているので、見てみること。

2.関数の使い方を調べる

名前を特定したら、使い方を調べる。MKLはサンプルコードを用意している。

examplesの場所はintel oneapiのバージョンによって若干の差があるので注意すること。tarを使い、tgzファイルを解凍し、いろいろなexampleを見てみよう。例えば、examples_core_c.tgzを解凍してみる。

sudo tar -xzvf examples_core_c.tgz

と打つと、解凍でき”c”というフォルダができる。その中身は次のようである。

blasやlapackなどさまざまなライブラリが入っている。それぞれのライブラリでどんなことができるのかは、調べてほしい。ここではlapackを見てみる。

このように、サンプルコードがたくさん置かれている。連立一次方程式を解きたい場合、DGESVという関数(「インテル®数値演算ライブラリ リファレンス・マニュアル」のp341)を使えばよいが、このディレクトリ内のdgesv.cというファイルを見てみることで、その使い方がわかる。

3.サンプルコードをもとに、テストのプログラムを書いてみる

dgesv.cを用いたテストプログラム

4.コンパイル&実行

インテルのリンクアドバイザーを使うと、リンカの仕方や、コンパイルオプションなど、示してくれる。ただ、それなりにコンパイルに関する知識が必要で、つかいこなすのは難しい。

そこで、以下のMakefileを利用することを推奨。おそらく、だいたいのMKLをつかったプログラムはコンパイルできるはずである。

Makefileの例

CC = icx

#昔は、場所を指定していたが、いまはつかっていない
#一応、コメントアウトで残しておく
#Intelのリンクアドバイザーをみると、場所を指定する書き方なんだけど...
#MKLのインストール場所によって適宜書き換え
#MKLRoot         = #/opt/intel/compilers_and_libraries/linux/mkl
#LIBRoot         = #/opt/intel/compilers_and_libraries/linux/mkl/lib
#
## C --> compile
#MKL_FCFLAGS     = -I  $(MKLRoot)/include/ 
## L -->link
#MKL_FLFLAGS     =  -L  $(MKLRoot)/lib/intel64 -#lmkl_intel_lp64 -lmkl_intel_thread\
#         -lmkl_core -L $(LIBRoot)/intel64 -liomp5 -lpthread #-lm -ldl

MKL_FCFLAGS     = 
MKL_FLFLAGS     =   -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl

#openMPの利用方法はよくわかってない リンクアドバイザーを頼りにした方がよい
#FCFLAGS = $(MKL_FCFLAGS) -m64 -qopenmp
FCFLAGS = $(MKL_FCFLAGS) -m64
FLFLAGS	= $(MKL_FLFLAGS)

##今回、main.cとsolver.cがあるので、main.oとsolver.oを書いている
##ここは適宜変更する。
RK2D_PLA      = main.o \
	solver.o

AllObj          = $(RK2D_PLA) 

##TEST_PROGRAMという実行ファイルが生成される
all: $(AllObj)
	$(CC) $(AllObj) $(FLFLAGS) -o TEST_PROGRAM 

##Makefileと同じディレクトリにC言語のファイルを配置する
##AというフォルダのなかにC言語のファイルがある場合は、「%.o:A/%.c」のように書く
%.o:%.c
	$(CC) $(FCFLAGS) -c $< $(VERBOSE)

補足1.サンプルコードがない場合がある

固有値の数を指定して、一般化固有値問題を解きたい場合を考える。「一般化固有値問題 nag」のように調べると、次のような検索結果を得る。

nagのページを閲覧すると、関数名が特定でき、目的の関数名は「DSYGVX」であるとわかる。nagはサンプルコートを載せており、非常に有用であるが、Fortranで書かれている。

次にexamplesのディレクトリからdsygvxのサンプルコード探すが、残念ながら存在しない。ただ、すべての固有値を算出する実対称固有値解析dsyevのサンプルコードであるdsyev.cは存在する。

なので、dsyev.cを参考にdsygvxの使い方を推察する。

  • nagのページで、fotranで書かれたdsyevとdsygvxのサンプルコードを見くらべて、どこが違うか分析する。
  • 「Developer Reference for Intel® oneAPI Math Kernel Library for C」のdsyevとdsygvxの説明を見比べて、どこが違うか分析する。

上記のような分析をおこなえば、サンプルコードがなくとも関数の使い方がわかると思う。DGESVを使ったテストプログラム はこちら

補足2.Lapackの関数にはLAPACKE_****と****のように2種類の関数がある。

例えばLAPACKE_dgesvとdgesvのように。Lapackの関数の多くは、もともとfortran77で書かれたものらしい。dgesvのようにLAPACKE_をつけずに用いた場合、C言語からfortran77で書かれた関数を呼ぶことになるそうだ。一方、LAPACKE_****はC言語で扱いやすいように書き直したものらしい。LAPACKE_をつけるかつけないかで、引数が変わるので注意すること。LAPACKE_をつけずに関数を使う場合は、fortranのマニュアルを参考にした方が良い。(というかCのマニュアルにはLAPACKE_****の使い方しか載っていない)

参考にしたサイト

補足3.疎行列の連立一次方程式のソルバについて

多くの数値解析で必要となる、疎行列の連立一次方程式のソルバも、MKLを利用すればかなり高速に解ける。ただ、疎行列格納形式についての知識が必要で、それについては割愛する。

examplesのディレクトリにいき、「c」(examples_core_c.tgzを解凍するとできる)の中に、「sparse_directsolvers」というディレクトリがある。そのなかに、いろいろな直接法ベースのソルバのサンプルコードがある。たとえば、dss_sym.cであれば対称行列用のソルバで、dss_unsym.cであれば非対称行列用のソルバである。また、pardisoというものもあり、これはopenMP(共有メモリ型の並列計算)に対応した直接法ベースのソルバだったと思う。

また、examples_cluster_c.tgzを解凍すると「c_mpi」ができ、このなかには分散メモリ型の並列計算に対応した関数のサンプルコードがのっている。このなかの「cluster_sparse_solver」には、分散メモリ型並列計算対応の直接法ベースのソルバがある。

ここでは、直接法ベースのものを紹介したが、反復法ベースのものもサンプルコードがあるので、必要な人は参考にするとよい。

,

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です