1

I am trying following code with python3:

import time
duration = 5

from numba import njit
@njit 
def myfn(): 
    num = 3
    starttime = time.time()
    while True: 
        print("Checking", num)
        endtime = time.time()
        if (endtime - starttime) > duration: 
            print("Time up.")
            return
        num += 2

myfn()

However, it is giving following error:

Traceback (most recent call last):
  File "/home/abcde/testing_numba", line 20, in <module>
    myfn()
  File "/home/abcde/.local/lib/python3.7/site-packages/numba/core/dispatcher.py", line 414, in _compile_for_args
    error_rewrite(e, 'typing')
  File "/home/abcde/.local/lib/python3.7/site-packages/numba/core/dispatcher.py", line 357, in error_rewrite
    raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Unknown attribute 'time' of type Module(<module 'time' (built-in)>)

File "testing_numba", line 11:
def myfn(): 
    <source elided>
        num = 3
        starttime = time.time()
 ^

During: typing of get attribute at /home/abcde/testing_numba (11)

File "testing_numba", line 11:
def myfn(): 
    <source elided>
        num = 3
        starttime = time.time()
 ^

Especially note Unknown attribute 'time' of type Module(<module 'time' (built-in)>)

Without numba, the code works fine.

How can this error be corrected?

rnso
  • 23,686
  • 25
  • 112
  • 234

2 Answers2

3

In a nutshell: As the error message suggests, Numba doesn't support this python-feature (list of supported python-features).

Normally, one would reconsider using such python-objects in nopython-numba-functions, because there is nothing to be gained speed-wise from such objects.

Alternatives are:

  • using python-mode, i.e. nb.jit(forceobj=True). The function will "work" in this case, but the speed-up gains due to the 3. point from the explanation bellow will be missing.
  • using np.objmode-content manager to turn on the python-mode only for special lines of the function.

Numba's speed up in nopython-mode comes from

  1. no need for python-interpreter: the code is compiled to python-bytecode which must run in python-vm, but to assembler which can be executed directly by the cpu.
  2. no need for dynamic dispatch: the types of variables are deduced/known at compile time, thus the meaning of operations like a+b must not be resolved at run time (dynamic dispatch) it is backed-in into the assembler already (static dispatch)
  3. no longer python objects are used (e.g. int- or float- or list-objects) but "corresponding" types in plain C like 64bit-ints or doubles.

While getting rid of 1. and 2. might get us about 2-3 times faster code (but there could be no gains at all, depending on how much overhead 1. and 2. produce), the holy grail of speeding up is the 3. point: using it has the potential of being about 100 times faster then pure python! This SO-post is an analysis of the speed-up potential for above points (but done for cython) with more details.

Obviously, in order to use C types for python objects, numba must know the correspondence between Python-object and C types.

This can be easily done for numpy-arrays like np.zeros(n, dtype=np.int32): it more or less corresponds to a pointer of type int32_t* with additional meta-information (like the length of the array).

It is possible to convert some python constructs to C types during the run time, like lists consisting only of int-objects (which are not too big), e.g.:

@nb.njit
def fun(a):
    print(a)

fun([1,2]) # works
fun([1,2,2**65]) # doesn't work, because 2**65 cannot be represented with uint64

But this obviously produces overhead during the run time and should be avoided, if possible. Instead typed lists should be used, which from memory layout are very similar to 1d-numpy-arrays.

For such a complex python-object like the time-module, there is no corresponding C type (which would provided meaningful speed-up), and thus it is not supported by numba in nopython-mode.

ead
  • 32,758
  • 6
  • 90
  • 153
2

Unfortunately, numba does not support the time module and it cannot be used in nopython mode. It will work with @jit instead of @njit, but the performance gain won't be as good.

See this answer for a potential solution and more details.

boris
  • 378
  • 1
  • 4
  • 16