Cython+Numpyメモ
いろいろと必要があってCythonとNumpyを使うことになりましたが、少し嵌ったのでメモ
数値計算にはPython+Numpyを利用していましたが、(禁忌とされる)データに対して直接forループを回さなければならないような状況に陥ったので、仕方なくCythonを導入。
CythonからNumpy.arrayにアクセスしたい時は、ナイーブな方法で行うとオーバーヘッドが大きい。
そのため、配列へのアクセスを高速に行うための仕組みがCythonにあります。
- Working with Numpy
- http://docs.cython.org/src/tutorial/numpy.html#efficient-indexing
このあたりの公式文書を参照のこと。Pythonのオブジェクトとして扱うのではなく、きちんと型と次元を指定してやって、もっとC寄りの配列を直接いじる感じ。
さて、この機能を利用するために冒頭で
import numpy as np cimport numpy as np
としてnumpyのCのヘッダを読みこんでやらないといけません。
これをコンパイルするために、ドキュメントを参照しながら適当にsetup.pyを作り、
$ python setup.py build_ext --inplace
としてコンパイルを実行すると、ありとあらゆるコンパイルエラーが出たあとに、
error: command 'gcc' failed with exit status 1
とのたもうて落ちる。cythonでCのコードを生成するのは問題なくできるので、Cをコンパイルする段での問題なのは明らかだったのですが、なかなか問題が解決できず詰まるなどしていました。。
結論から言うと簡単なことで、gccにnumpyにまつわるヘッダファイルの所在を教えてあげなければいけない、ということだったようです。
numpy用のインクルードパスはnumpy.get_numpy_include()で取得できるので、setup.pyを上手く書き換えてやって
from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext import numpy setup( name="CPWOPTcritical", cmdclass={"build_ext":build_ext}, ext_modules=[Extension("hoge",["hoge.pyx"], include_dirs=[numpy.get_numpy_include()]#ここでインクルードパスを指定 )] )
としてやれば、うまくコンパイルが通りました。
もっと早く気づいていれば…