46

この記事は最終更新日から5年以上が経過しています。

投稿日

更新日

Pythonのまま高速化するNumba

Cythonは結構使ってきたのですが、どうもめんどくさいと思うことがあり(大規模になるとsetup.pyが必要になるなど)、もっと簡単にPythonを高速化するNumbaというものを知りました。llvmでJITするなんてJuliaみたいで素敵じゃないですか。以下の記事を参考に私も挑戦してみました。Numba自体を初めて目にする方はまずリンク先をご覧ください。

今のところは導入方法に関してのみです。

インストール方法

Mac 10.9 with Python2.7の場合

以下で動きました。

sudo easy_install funcsigs enum34 numba

git clone https://github.com/numba/llvmlite
cd llvmlite/
sudo python setup.py install

以下注意です。

  • llvmliteはeasy_installでも入るが、dylibが足りずに実行時エラー(なぜ?)
  • enum34の他にenumというものもeasy_install可能だが、それがあるとエラー
  • 最初にトライしたマシンと別のMac OS 10.9で試したところimport numbaでエラーが出たが、numpyを入れ直したら解決。あまり何も考えずgithubから以下のコマンドでビルドしただけ…。

    git clone https://github.com/numpy/numpy.git numpy_temp
    cd numpy_temp
    python setupegg.py bdist_egg
    sudo easy_install dist/*egg
    

Windows7 64bit Python2.7の場合

Windows7 with WinPython2.7の場合もそのうち挑戦しますが、llvmが必要だったりC++11対応が多分必要だったり64bitが難しそうだったり壁が多そうです… 苦戦すると思いきやAnaconda入れたらそれだけで通りました。Anaconda初めて使ったのですが数値計算かじる可能性があったり自分のPythonコードを高速化したい人は積極的に使って良さそうです。

使用方法と所感

ここも後ほど加筆しますが、敢えて数値計算ではない処理で試すつもりです。理由は、数値計算に対する効果は上述の先人様が既に評価済であることと、今たまたま自分は数値計算ではなく複雑なバイナリデータの読み書きプログラムなどを作っているからです。

PyInstallerで使えるように

PyInstallerを使うとPythonスクリプトをexecutableにできて他人に配布しやすくなったりしますが、numbaを使ったものは実行時に以下のエラーになります。これは、Pythonが動的にdlopenするファイルに関してPyInstallerが収集に失敗していることが原因です。

OSError: dlopen(/var/folders/qk/z4x58g2962q21q5570g2hj0c0000gn/T/_MEIRXXAjg/llvmlite/binding/libllvmlite.dylib, 6): image not found

そこでこのdylibもビルド結果に含めてやりましょう。以下の手順で問題を回避できます。なおPyInstallerはgithubのtag v2.1を使っています。

Macの場合

  1. python pyinstaller/pyinstaller.py --onefile test.py する。このときtest.specができると同時にこのtest.specを元にexeが作られるが、このexeは上記エラー状態。
  2. test.specに以下のように一行足して、libllvmlite.dylibをonefileされたexecutableの中に埋め込むように指示する。

    # -*- mode: python -*-
    a = Analysis(['test.py'],
                 pathex=['/path/to/main/script'],
                 hiddenimports=[],
                 hookspath=None,
                 runtime_hooks=None)
    
    # この下の1行が追加
    a.binaries += [("llvmlite/binding/libllvmlite.dylib", "/Library/Python/2.7/site-packages/llvmlite/binding/libllvmlite.dylib", 'BINARY')]
    
    pyz = PYZ(a.pure)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              name='test',
              debug=False,
              strip=None,
              upx=True,
              console=True )
    
  3. python pyinstaller/pyinstaller.py --clean test.specとし、修正後のtest.specで再ビルドする。

Windows Anacondaの場合

(C:¥Anacondaに環境をインストールしたと仮定します) まずAnaconda環境をPyInstallerで使おうとするとNumba関係なくpywintypesが見つからないエラーに遭遇します。が、ここに書いてあった方法でdllをPyInstallerに見つかる場所に置いて解決できました。

cd C:\Anaconda\Lib\site-packages\win32\
copy pywintypes27.dll lib\
copy pythoncom27.dll lib\

あとはMacの場合と同様にllvmlite.dllの調達方法を.specに書けばOKです。C:¥Anacondaにインストールした場合追加すべき一行は以下のようになるはずです。

a.binaries += [("llvmlite/binding/llvmlite.dll", "C:\\Anaconda\\Lib\\site-packages\\llvmlite\\binding\\llvmlite.dll", 'BINARY')]

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
ログインすると使える機能について

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
46