2013年2月24日日曜日

EPD(フルパッケージ版)におけるCythonの使い方

概要

EPDのフルパッケージ版にはCythonが含まれている。
CythonはPythonのコードをCコードに変換してくれるパッケージ。
ループ構造や条件分岐などで特に処理の遅いPythonコードをCythonでCに変換しコンパイルすることで処理の高速化が可能となったりするらしい。

とりあえず関数などをCythonでコンパイルすると良いらしい。これにより生成される実行ファイルをPython側で使うことでPythonで作った関数よりも高速に動作させることが可能となる。
もっとも、NumpyやScipyなどのパッケージは処理を計算ライブラリに投げることで高速化を実現しており、CPU資源をかなり使い切っているためCythonの恩恵は少ないはず。
別途記事を作るかもしれないが、行列-行列計算などではほとんどといっていいほど違いは出ない(今のところ時間計測をPythonで行なっているため、アプリケーションの実行時間で比べれば、また違った結果が見えるかもしれないが)。
Cythonのイメージのようなもの
とにかく、条件によっては性能が100倍以上に上昇する場合もあるので、覚えておいて損はないと思う。
EPDの場合、なんにも考えなくとも、パス等が通っているため楽に使うことができる。
ただ、Windows 7 64bitの場合、デフォルトでは32bitの実行ファイルが生成されてしまう。
これを64bitにするためにかなり調べてググったのでメモとしてまとめておく。

使い方

はじめに、C言語化したいPythonの関数を.pyx形式で作成する。
ここで、Cythonを使うためにいくつかのコードを関数に追加する必要がある。
高速化の恩恵を受けられるかどうかにも関わってくるらしいので覚えておきたい。
Pyxのコードは、例えば次のようになる。

#行列のべき乗計算
import numpy as np
cimport numpy as np
cimport cython
DOUBLE = np.float64
INT = np.int64
ctypedef np.float64_t DOUBLE_t
ctypedef np.int64_t INT_t
def MyMatPow(np.ndarray[DOUBLE_t,ndim=2] a, INT_t n):
    cdef int i
    cdef np.ndarray[DOUBLE_t,ndim=2] tempa = a
    for i in xrange(n-1):
        tempa = np.dot(tempa, a)
    return tempa
こんなかんじでソースを作っておく。

Windows 7の場合のコンパイル方法(多分XPとかでも同じ)を以下に記す。

コンパイル@32bit

EPDだと何も考えずにそのままコンパイルできる。
と言っても、いろいろめんどくさいので、setup.pyというファイルをPYXソースと同一のディレクトリに配置しておく。setup.pyの中身はこんな感じで動くと思う。

'''$ python setup.py build_ext --inplace'''
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [Extension("出力ファイルの名前(ex: example)", ["PYXソースの名前(ex: example.pyx)"], language="c", include_dirs=[np.get_include()])]
)

とりあえずコマンドライン上でPYXソースのあるディレクトリ上に移動して、
python setup.py build_ext --inplace
と打てばコンパイルしたファイルが生成される。ここで出力ファイルの名前とPYXソースの名前は合わせておく。例えば、example.pyxという名前のソースを作った場合、出力ファイルの名前にはexampleと書く。
後は、同一ディレクトリにpythonソースを置き、
import example
とかいう風にしてやれば、example.pyxの中身の関数を使うことができる。

コンパイル @64bit

64bitでコンパイルする場合、windwosだとVisual Studioと言うか、 Windows SDK C/C++ compilerが必要になる。
とりあえず、本家に記載のあった通り、Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1辺りをインストールしておく。
とりあえず、C:\Program Files\Microsoft SDKs\Windows\v7.0というフォルダができていれば良い。
次に、
バッチファイルでも作って、

CD /d C:\Program Files\Microsoft SDKs\Windows\v7.0
set DISTUTILS_USE_SDK=1
C:\Windows\System32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\Setenv.cmd" /x64 /release
と書き、実行すると、文字が緑色のコマンドラインが出てくる。
そうしたら、コマンドライン上でPYXソースのあるディレクトリに移動して、
python setup.py build_ext --inplace
と打つと64bitの実行ライブラリが生成される。
Python上での使い方は32bitの場合と変わらない。


0 件のコメント:

コメントを投稿