Search code examples
pythonnumba

Numba: Cannot determine the type of nested functions


I have this numba script (in a file called 'MySource.py') i'm trying to compile:

from numpy import empty_like, inf, minimum, max
from numba import pycc

cc = pycc.CC('base_model')
cc.verbose = True


@cc.export('cumMin','float64[:](float64[:])')  
def cumMin(A):
    r = empty_like(A)
    t = inf
    for i in range(len(A)):
        t = minimum(t, A[i])
        r[i] = t
    return r

# nm -C base_model.so > bingo.txt
@cc.export('da_comp','List(float64)(float64[:, :])')  
def da_comp(rolled_ndarray):

    this_series_p = rolled_ndarray[:, 0]
    this_series_v = rolled_ndarray[:, 1]    

    return [max(cumMin(this_series_p)), max(cumMin(this_series_v))]

    
if __name__ == "__main__":
    cc.compile()

In bash, I do:

 python3 MySource.py

but I get a compilation error:

    raise TypingError(msg, loc=inst.loc)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'cumMin': Cannot determine Numba type of <class 'function'>

File "MySource.py", line 24:
def da_comp(rolled_ndarray):
    <source elided>

    return [max(cumMin(this_series_p)), max(cumMin(this_series_v))]

I use numba 0.57.1 How to fix this?

#Edit: I tried splitting the functions into two files as suggested in the answer by Eric below but this doesn't solve the issue (I get the same error).


Solution

  • so I solved the problem by replacing

    @cc.export('cumMin','float64[:](float64[:])') 
    

    by:

    @numba.jit(nopython = True)
    
    import numpy
    import numba
    import numba.pycc
    
    cc = numba.pycc.CC('base_model')
    cc.verbose = True
    
    
    @numba.jit(nopython = True)
    def cumMin(A):
        r = numpy.empty(len(A))
        t = numpy.inf
        for i in range(len(A)):
            t = numpy.minimum(t, A[i])
            r[i] = t
        return r
    
    @cc.export('da_comp','List(float64)(float64[:, :])')  
    def da_comp(rolled_ndarray):
    
        this_series_p = rolled_ndarray[:, 0]
        this_series_v = rolled_ndarray[:, 1]    
    
        t1 = cumMin(this_series_p)
        t2 = cumMin(this_series_v)
    
    
        return [numpy.max(t1), numpy.max(t2)]
    
        
    if __name__ == "__main__":
        cc.compile()
    
    #python3 MySource.py