10

Following up from here, I keep getting overflows. So I'm trying to raise an exception so that I know exactly what's going wrong where.

I've got something like this:

@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)

But I get this error:

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

Can't I raise exception while I'm using numba? I'm using Anaconda 2.0.1 with Numba 0.13.x and Numpy 1.8.x on a 64-bit machine.

Community
  • 1
  • 1
user961627
  • 12,379
  • 42
  • 136
  • 210
  • 4
    It does in fact look like `try..except` blocks are not supported by `numba`s bytecode compiler. You get the `NotImplementedError` from [here](https://github.com/numba/numba/blob/master/numba/bytecode.py#L231) because `SETUP_EXCEPT` is not in the [table of supported opcodes](https://github.com/numba/numba/blob/master/numba/bytecode.py#L70). – Lukas Graf Sep 13 '14 at 09:18
  • 1
    I got a response from the numba people - they set try-except blocks can't be implemented in numba. – user961627 Oct 27 '14 at 06:45
  • @user961627, please post the response you got from the numba people as an answer below to help future weary travelers :) – theannouncer Feb 16 '18 at 17:26

1 Answers1

4

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

2.6.1.1. Constructs

Numba strives to support as much of the Python language as possible, but some language features are not available inside Numba-compiled functions. The following Python language features are not currently supported:

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

The raise statement is supported in several forms:

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

so that leaves us here:

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

anything negative under about exp(-1000); really-really small will evaluate to zero without overflow

math.exp(-1000000000) "works" and is probably not your issue (although it will return 0.0, its not "really" zero)

so what would cause this to fail? well we know:

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

is silly big, much more than that... probably overflow

sure enough

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

I don't have citation but I think the effective range is like -700 to 700 which evaluate to 0 and infinity(overflow) effectively from the perspective of double floats

to handle that we window the function:

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

but that won't work either because math.exp(n) only accepts floats and your beta appears to be a list; you'll have to use numpy.exp(n) and numpy.clip() to window

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

or to raise the overflow exception:

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)
litepresence
  • 3,109
  • 1
  • 27
  • 35