Coffee Break Script

いわゆる息抜き。

numba ( @jit ) と try-catch は一緒に使えない

インタープリタ言語であるPythonを高速化させるための、最も手っ取り早い手段がnumbaを使うことです。

from numba import jit

@jit
def function_name(input_args):
    hoge
    hogehoge ...

    return hoge

というコードを書くと、とりあえずそれだけで多少高速化してくれるという優れもの。 どのくらい高速になるのかという検証は他のブログに譲るとして、僕のように「とりあえず動くものが書ければOK」という使い方をしている人間にとってこの@jitは高速化の”おまじない”に等しい。

ところが、このおまじないには一つ弱点がある。try-catchの例外処理が使えないのである。

たとえば、次のようなコードを動かすと…

from numba import jit

@jit
def function_name(input_args):
    hoge ...
    try:
        hoge1
    exception ERROR:
        hoge2

    return hoge

こんな感じのエラーが出ます。(最後の4行だけ抜粋)

    (前略)
  File "C:\ProgramData\Anaconda3\lib\site-packages\numba\controlflow.py", line 515, in run
    assert not inst.is_jump, inst
AssertionError: Failed at object (analyzing bytecode)
SETUP_EXCEPT(arg=XXX, lineno=XXX)

※arg=とlineno=の後のXXXには本来なら数字が入ります。

numbaのcontrolflow.pyでエラーが起きているので、try-catch節を評価して内部状態を遷移させることがそもそもできない仕様になっていると思われます。実際にstackoverflowでもこの問題について触れられていました。

stackoverflow.com

今のところnumbaのjitがtry-catch構文に対応する様子はなさそうなので、『try-catchを使いたい場合は@jitを使わない』というのが唯一の対策なのでしょう。(回避策ご存知の方はコメント欄までお願いいたします。)

これまで全体像を把握しきったデータをハンドリングすることしかしてこなかったので、try-catchをあまり使ってこなかった(単にif文だけ使っていた)のだが、思わぬ落とし穴でした。

同じように困っている人のために記録として残しておきます。 ではでは。

■Qiitaにも要約が載っています。念のため。

qiita.com