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でもこの問題について触れられていました。
今のところnumbaのjitがtry-catch構文に対応する様子はなさそうなので、『try-catchを使いたい場合は@jit
を使わない』というのが唯一の対策なのでしょう。(回避策ご存知の方はコメント欄までお願いいたします。)
これまで全体像を把握しきったデータをハンドリングすることしかしてこなかったので、try-catchをあまり使ってこなかった(単にif文だけ使っていた)のだが、思わぬ落とし穴でした。
同じように困っている人のために記録として残しておきます。 ではでは。
■Qiitaにも要約が載っています。念のため。