Lapackeインストールメモ
目次 |
lapackeとは
fortranで書かれている線形代数の(上位)ライブラリLAPACKを、C/C++から使うためのラッパーライブラリ。
下位のBLASはCBLASっていうC/C++用のインタフェースが定義されてたから良かったんだけど、LAPACKには無くて今まではこの部分を自分で作ってた。 ただ、これだと他の人にソースあげたりする時に面倒な事になってたので、誰か統一したインタフェースを作ってくれないかなぁと前々から思ってた。 と言う訳で、lapackeは本当に嬉しい。Intelさんありがとーっ!
・・・なんだけど、これ、lapack-3.3から本体にくっついてくるらしいので、それまでは自分でインストールする必要がある。 このページはそんなインストールに関するメモ。
インストール環境
- Ubuntu-10.10 (vmware上で動作)
- apt-get(かsynaptic)でliblapack-dev、libblas-devインストール済
(lapackは3.2.1だった)
今回は特に使わないけど、/usr/includeの下あたりにcblas.hがインストールされている事を確認。
lapackeのコンパイル
1. lapackeを取ってくる。
2. 適当に展開する。
3. make.incを編集する。(今回はmake.gnuをmake.incにコピーして少し編集した)
make.inc: (snip) LAPACKE = liblapacke.a LIBS = -llapack -lblas -lm (snip)
4. makeする。 5. トップディレクトリ(アーカイブを解凍してできたディレクトリ)にliblapack.aがあれば成功。
- コンパイルに失敗した時
エラーメッセージを読んで、問題のあるところを直す。
使ってみる
適当に作ったサンプルプログラム:
#include <stdio.h> #include <stdlib.h> /* #include <cblas.h> このプログラムでは要らない */ #include "lapacke.h" /* 行列の中身を表示する */ static void print_mat(const int m, const int n, const double *a, const int lda) { int i, j; for (i = 0; i < m; ++i) { for (j = 0; j < n; ++j) { printf("% 10.3g ", a[j*lda + i]); } printf("\n"); } printf("\n"); } /* メイン関数 */ int main() { const int n = 3; const int lda = n; double a[lda*n], ev[n]; lapack_int info; int i, j; /* 行列に値を入れる */ for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { a[lda*i + j] = (i == j || i*j != 0) ? 1 : 0; } } /* ちゃんと入ったか確認 */ printf("a:\n"); print_mat(n, n, a, lda); /* lapacke経由でdsyev(対称行列の固有値・固有ベクトルを計算する関数)を呼び出す */ info = LAPACKE_dsyev(LAPACK_COL_MAJOR, 'V', 'U', n, a, lda, ev); if (info != 0) { printf("dsyev failed. info = %d\n", info); return EXIT_FAILURE; } /* 固有ベクトル表示 */ printf("eigen vectors:\n"); print_mat(n, n, a, lda); /* 固有値表示 */ printf("eigen values:\n"); for (i = 0; i < n; ++i) { printf("% 10.3g ", ev[i]); } printf("\n"); return EXIT_SUCCESS; }
コンパイルとリンク:
$ gcc -Ipath/to/lapacke/include -c -o hode.o hode.c $ gcc -Lpath/to/lapacke hoge.o -llapacke -llapack -lblas -lm -o hoge
実行結果:
$ ./hoge a: 1 0 0 0 1 1 0 1 1 eigen vectors: 0 1 0 -0.707 0 0.707 0.707 0 0.707 eigen values: 0 1 2
・・・動いたっぽい。
注意点など
LAPACKがfortranのライブラリなので、
- column major(1列分進むと行(column)が1つ増える)にする方が良い
- 要素を1から数えるので、ピボッティング結果を返す関数(getrfとか)の値はC/C++の感覚と1ずれる(はず)
あと、使うライブラリによってはアライメント境界しばり(ex. 最初の要素が8の整数倍のアドレスで始まる)がある場合があるので、部分行列(行列の右下の3x3成分だけとか)をLAPACK/BLASの関数に入れるのは避けた方がよい。
苦労した点
サンプルプログラムで分かりやすい結果になる行列を考えるところ。
これから
行数・列数などをセットで覚えておく構造体、行列タイプに従って配列にアクセスする関数、メモリの割り当て/解放の面倒を見る関数があると便利、かも。
BoostのuBLASでもいいけど、英語面倒だし。