使用 numba 时引发异常

Posted

技术标签:

【中文标题】使用 numba 时引发异常【英文标题】:Raising an exception while using numba 【发布时间】:2014-11-07 10:02:27 【问题描述】:

从here 跟进,我不断收到溢出。所以我试图提出一个例外,以便我确切地知道哪里出了问题。

我有这样的东西:

@jit
def train_function(X, y, H):
     np.seterr(over="raise", under="raise", invalid="raise")
     # do some stuff, start a double loop, and then do:
     try: 
            z[i,j] = math.exp(-beta[j,i])
     except OverflowError:
            print "Calculation failed! z[i,j] = math.exp(-beta[j,i]), j: " + str(j) + ", i: " +str(i) + ", b: " + str(beta[j,i]) + ", omb: " + str(oneminusbeta[j,i])
            raise    


class MyClass(object):
     # init and other methods
     def train(self, X, y, H):
          train_function(X, y, H)

但我收到此错误:

Traceback (most recent call last):
  File "C:\work_asaaki\code\gbc_classifier_train_7.py", line 55, in <module>
    gentlebooster.train(X_train, y_train, boosting_rounds)
  File "C:\work_asaaki\code\gentleboost_c_class_jit_v7_nolimit.py", line 297, in train
    self.g_per_round, self.g = train_function(X, y, H)  
  File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 152, in _compile_for_args
    return self.jit(sig)
  File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 143, in jit
    return self.compile(sig, **kws)
  File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 131, in compile
    flags=flags, locals=locs)
  File "C:\Anaconda\lib\site-packages\numba\compiler.py", line 103, in compile_extra
    bc = bytecode.ByteCode(func=func)
  File "C:\Anaconda\lib\site-packages\numba\bytecode.py", line 305, in __init__
    table = utils.SortedMap(ByteCodeIter(code))
  File "C:\Anaconda\lib\site-packages\numba\utils.py", line 70, in __init__
    for i, (k, v) in enumerate(sorted(seq)):
  File "C:\Anaconda\lib\site-packages\numba\bytecode.py", line 219, in next
    raise NotImplementedError(ts % tv)
NotImplementedError: offset=742 opcode=0x79 opname=SETUP_EXCEPT

我不能在吗?我在 64 位机器上使用 Anaconda 2.0.1 和 Numba 0.13.x 和 Numpy 1.8.x。

【问题讨论】:

实际上看起来try..except 块不受numbas 字节码编译器的支持。您从here 获得NotImplementedError,因为SETUP_EXCEPT 不在table of supported opcodes 中。 我收到了 numba 人的回复 - 他们设置 try-except 块无法在 numba 中实现。 @user961627,请将您从 numba 人那里得到的回复作为答案发布在下面,以帮助未来疲惫的旅行者 :) 【参考方案1】:

http://numba.pydata.org/numba-doc/dev/reference/pysupported.html

2.6.1.1。构造

Numba 力求支持尽可能多的 Python 语言,但某些语言功能在 Numba 编译的函数中不可用。目前不支持以下 Python 语言功能:

Class definition
Exception handling (try .. except, try .. finally)
Context management (the with statement)

raise 语句支持多种形式:

raise (to re-raise the current exception)
raise SomeException
raise SomeException(<arguments>)

所以我们就到这里了:

z[i,j] = math.exp(-beta[j,i])

大约 exp(-1000) 下的任何负数;非常非常小的将评估为零而不会溢出

math.exp(-1000000000) "works" 并且可能不是你的问题(虽然它会返回 0.0,但它不是“真正的”零)

那么什么会导致这个失败呢?我们知道:

print(math.exp(100))
>>>
2.6881171418161356e+43

傻大了,远不止这些……可能溢出

果然

print(math.exp(1000))
>>>
OverflowError: math range error

我没有引用,但我认为有效范围是 -700 到 700,从双浮点数的角度来看,有效地评估为 0 和无穷大(溢出)

处理我们窗口函数:

n = beta
if n > 100:
    n = 100
z = math.exp(n)

但这也行不通,因为 math.exp(n) 只接受浮点数,而您的 beta 似乎是一个列表;你必须使用 numpy.exp(n) 和 numpy.clip() 来窗口

b = numpy.array(-beta[j,i])
n = numpy.clip(b, a_max=100)
z = numpy.exp(n)

或引发溢出异常:

b = numpy.array(-beta[j,i])
n = numpy.clip(b, a_max=100)
if b != n:
    print (j,i,-beta[j,i])
    raise OverflowError
else:
    z = numpy.exp(n)

【讨论】:

以上是关于使用 numba 时引发异常的主要内容,如果未能解决你的问题,请参考以下文章

高阶函数&异常处理

使用 @Security 时引发的异常为 RuntimeException

引发异常时如何保留响应标头?

当 Python 3 中已经存在异常时引发异常

使用按顺序遍历成员函数时引发异常(堆栈溢出)的问题

使用自定义版本的 UITextField 时引发异常