Подсказка Anaconda зависает, когда я запускаю код с помощью «jit» декоратора numba - PullRequest
1 голос
/ 16 марта 2019

У меня есть этот код Python, который должен работать просто отлично.Я запускаю его на консоли Anaconda Spyder Ipython или на самом терминале Anaconda, потому что это единственный способ использовать библиотеку «numba» и ее декоратор «jit».

Однако, каждый из них всегда «зависает» или «зависает» почти каждый раз, когда я запускаю его.В самом коде нет ничего плохого, иначе я бы получил ошибку.

Иногда код проходит совершенно идеально, иногда он просто печатает первую строку из первой функции, а иногда код останавливается где-то посередине.

Я пытался увидеть, при каких условиях воспроизводятся те же проблемы, но я не смог ничего понять.

Мой код:

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)

Я знаю, что лучше всего опубликовать соответствующую часть вашего кода, но это такая необычная ситуация, когда код на самом деле хорош, и я подумал, что должен опубликовать все это.

Это скриншот, когдаЯ запускал код два раза подряд, очевидно, в первый раз, когда он печатал результаты, которые я хотел, просто отлично, а затем в следующий раз, когда он завис.И иногда он замирает в промежутке между ними. enter image description here

Конечно, я помещал много функций печати повсюду, когда проверял, могу ли я увидеть какой-то шаблон, но я не смог, и яубрал все эти функции печати в коде выше.Но правда в том, что этот код завис бы в середине, и не было никакой последовательности или «воспроизводимости» к нему.

Я погуглил, но не смог найти никого другого с похожей проблемой.

1 Ответ

0 голосов
/ 19 марта 2019

Вы передаете неверное значение np.random.poisson.В вашем коде result[i, j] иногда может быть отрицательным, что вызывает NaN в numba, тогда как в python он возвращает фактическое (отрицательное) значение.В python вы можете получить ValueError, но numba завершается с ошибкой по-другому, что приводит к зависанию процесса.

Вы должны решить, имеет ли это смысл для вашей конкретной проблемы, но если я добавлю,проверьте между # ****** комментариями:

@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]
                ....

в foo, затем код перестанет зависать.

В качестве общего совета по отладке, хорошо запустить код с помощью JIT-декораторовпрокомментировал, чтобы увидеть, если что-то странное происходит.

...