The Anaconda prompt freezes when I run code with numba's “jit” decorator

拥有回忆 提交于 2019-12-20 04:16:02

问题


I have this python code that should run just fine. I'm running it on Anaconda's Spyder Ipython console, or on the Anaconda terminal itself, because that is the only way I can use the "numba" library and its "jit" decorator.

However, either one always "freezes" or "hangs" just about whenever I run it. There is nothing wrong with the code itself, or else I'd get an error.

Sometimes, the code runs all the way through perfectly fine, sometimes it just prints the first line from the first function, and sometimes the code stops anywhere in the middle.

I've tried seeing under which conditions the same problems reproduce, but I haven't been able to get any insights.

My code is:

import time
import numpy as np
import random
from numba import vectorize, cuda, jit, njit, prange, float64, float32, int64
from numba.numpy_support import from_dtype
import numba

@jit(nopython = True)
def make_array(number_of_rows, row_size, starting_size):
    q = np.zeros((number_of_rows,row_size))
    q[:,0]=starting_size
    return(q)

q = make_array(5,5,5)

@jit(nopython = True)
def row_size(array):
    return(array.shape[1])
@jit(nopython = True)
def number_of_rows(array):
    return(array.shape[0])

@jit(nopython = True)
def foo(array):

    result = np.zeros(array.size).reshape(1,array.shape[1])
    result[:] = array[:]
    shedding_row = np.zeros(array.size).reshape(1,array.shape[1])
    birth_row = np.zeros(array.size).reshape(1,array.shape[1])
    for i in range((array.shape[0])):
        for j in range((array.shape[1])-1):
            if  result[i,j] !=0:
                shedding = (np.random.poisson( (result[i,j])**.2, 1))[0]
                birth = (np.random.poisson( (3), 1))[0]
                birth = 0
                result[i,j+1] = result[i,j] - shedding + birth
                shedding_row[i,j+1] = shedding
                birth_row[i,j+1] = birth
            if result[i,j] == 0:
                result[i,j] = result[i,j]
    return(result, shedding_row)


@jit(nopython = True)    
def foo_two(array):

    result = np.zeros(array.size).reshape(array.shape[0],array.shape[1])
    result_two = np.zeros(array.size).reshape(array.shape[0],array.shape[1])       
    i = 0

    while i != (result.shape[0]):

        fill_in_row=  0*np.arange(1 * result.shape[1]).reshape(1, result.shape[1])
        fill_in_row[0] = array[i]
        result[i], shedding_row = foo(fill_in_row)
        result_two[i] = shedding_row
        i+=1            
    return(result, result_two)

@jit(nopython = True)
def foo_three(array):
    array_sum = np.sum(array, axis = 0)
    array_sum = array_sum.reshape(1,array_sum.size)
    result = np.zeros(array_sum.size).reshape(1,array_sum.size)

    for i in range((result.shape[0])):
        for j in range((result.shape[1])):

            shed_death_param = .2
            shed_metastasis_param = .3
            combined_number = (int(array_sum[i,j])) *    (shed_death_param+shed_metastasis_param)
            for q in range(int(combined_number)):
                random_number = random.randint(1, 7)
                if random_number == 5:
                    result[i,j]+=1
            number_to_add = (int(array_sum[i,j])) - (int(combined_number))
            if j < row_size(array_sum) - 1:
                (array_sum[i,j+1]) += number_to_add
    return(result)


@jit(nopython = True)
def foo_four(array):
    result = np.zeros(array.size).reshape(1,array.size)
    for i in range((result.shape[0])):
        for j in range((result.shape[1])):
            if int(array[i,j])!= 0:
                for q in range(int(array[i,j])):
                     addition = np.zeros((1,result.shape[1]))
                     addition[0][j] = 1
                     result = np.concatenate((result, addition), axis=0)
    if result.shape[0]!=1:
        result = result[1:]
    return(result)


def the_process(array):

    array, master_shedding_array = (foo_two(array))
    master_metastasis_array = foo_three(master_shedding_array)
    new_array = (foo_four(master_metastasis_array))
    print("new_array is\n", new_array)
    return(array,new_array)

def the_bigger_process(array):
    big_array = make_array(1,row_size(array),0)
    big_metastasis_array = make_array(1,row_size(array),0)
    counter =0
    i = 0

    while counter < row_size(array)-1:
        print("We begin, before the_process is called")
        updated_array,metastasis_array = the_process(array)
        big_array = np.concatenate((big_array, updated_array), axis=0)      
        if sum( metastasis_array[0] ) != 0:
            big_metastasis_array = np.concatenate((big_metastasis_array, metastasis_array), axis=0)        
        i+=1           
        third_big_metastasis_array = big_metastasis_array[np.where(big_metastasis_array[:,i] == 1)]        
        array = third_big_metastasis_array
        counter+=1

    big_array = big_array[1:]
    big_metastasis_array = big_metastasis_array[1:]
    return(big_array,big_metastasis_array)   

something, big_metastasis_array = the_bigger_process(q)
print("something is\n",something)
print("big_metastasis_array is\n",big_metastasis_array)

I know it's best to just post the part of your code that's relevant, but this such an unusual situation where the code is actually fine, that I thought I should post all of it.

This is a screenshot of when I ran the code two consecutive times, clearly the first time it printed the outputs I wanted just fine, and then the next time it froze. And sometimes it freezes in between.

Of course I put many print functions all over when I was testing if I could see some pattern, but I couldn't, and I took out all those print functions in the code above. But the truth is, this code would freeze in the middle, and there was no consistency or "replicability" to it.

I've googled around but couldn't find anyone else with a similar issue.


回答1:


You are passing a bad value to np.random.poisson. In your code result[i, j] can sometimes be negative, which is causing an NaN in numba, whereas in python it return an actual (negative) value. In python you might get a ValueError, but numba is failing in a different way that causes the process to hang.

You have to decide whether it makes sense for your particular problem, but if I add, the check between the # ****** comments:

@jit(nopython=True)
def foo(array):
    result = np.zeros(array.size).reshape(1, array.shape[1])
    result[:] = array[:]
    shedding_row = np.zeros(array.size).reshape(1, array.shape[1])
    birth_row = np.zeros(array.size).reshape(1, array.shape[1])
    for i in range((array.shape[0])):
        for j in range((array.shape[1]) - 1):
            if result[i, j] != 0:

                # ******
                if result[i, j] < 0:
                    continue
                # ******
                shedding = (np.random.poisson( (result[i, j])**.2, 1))[0]
                birth = (np.random.poisson((3), 1))[0]
                ....

in foo, then the code stops hanging.

As a general debugging tip, it's good to run your code with the jit decorators commented out to see if anything strange is happening.



来源:https://stackoverflow.com/questions/55191444/the-anaconda-prompt-freezes-when-i-run-code-with-numbas-jit-decorator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!