LAPACKE_dsyevd

LAPACKE_dsyevd()がメモリが足りないと怒る。ググっても情報がない。なぜだろうか。LAPACKE_dsyevd_work()を叩いてみるか。

LAPACKE_dsyevd()のコードを見てみると、lworklapack_int型になってるけど、これは実質int型(lapacke.hのなかで、#define lapack_int intとなっている)。つまり、現行のx86-64システムだと32bitのsigned integerだから、lworkがあまりに大きいとoverflowする。

これを踏まえて、lworkをlong型にしLAPACKE_dsyevd()を真似てLAPACKE_dsyevd_work()を直接呼んでみたら、期待通り動いた。安全かどうかわからないけれど。

以上はOpenBLASでの話。MKL2015ではコケた。

Intel MKL ERROR: Parameter 8 was incorrect on entry to DSTEDC.
Intel MKL ERROR: Parameter 12 was incorrect on entry to DORMTR.

バグかな。最新版を試す必要がありそう。

valgrind

なぜだか結局mallocから逃げられない。その順当な結果としてメモリリークしてしまう。自動でチェックできるようにtravis-CIの中でvalgrindを走らせたい。valgrindはconda-forgeに入っているので、それをインストールすればよい。しかし、システムのgccを使うとvalgrindが動かない(libcのコンフリクトかな)ので、コンパイラもcondaでインストールする。実マシン上ではこれで問題なくvalgrindが動く。一方、travis-CI上ではコンパイラのインストールの途中でcondaのパッケージが取れずにコケてしまうので一時休止。

ところで、valgrindの出力のInvalid read/writeがよくわからない。例えば以下のページに書いてあるような場合は明白だ。

可変長配列を関数に渡した時に、invalid read/writeが起こるが、配列と同じ形のメモリをmallocで確保した場合はinvalid read/writeが起こらない。なぜかわからない。