El indicador de Anaconda se congela cuando ejecuto el código con el decorador “jit” de numba

Tengo este código de Python que debería funcionar bien. Lo estoy ejecutando en la consola Spyder Ipython de Anaconda, o en la propia terminal de Anaconda, porque esa es la única forma en que puedo usar la biblioteca “numba” y su decorador “jit”.

Sin embargo, uno siempre se “congela” o “cuelga” casi siempre que lo ejecuto. No hay nada malo con el código en sí mismo, o de lo contrario obtendré un error.

A veces, el código se ejecuta perfectamente, a veces simplemente imprime la primera línea desde la primera función y, a veces, el código se detiene en cualquier punto intermedio.

He intentado ver en qué condiciones se reproducen los mismos problemas, pero no he podido obtener ninguna información.

Mi código es:

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) 

Sé que es mejor publicar la parte de su código que sea relevante, pero esta es una situación tan inusual donde el código está realmente bien, que pensé que debería publicarlo todo.

Esta es una captura de pantalla de cuando ejecuté el código dos veces consecutivas, claramente la primera vez que imprimí las salidas que quería, y luego la próxima vez que se congeló. Y a veces se congela en el medio. introduzca la descripción de la imagen aquí

Por supuesto, puse muchas funciones de impresión por todas partes cuando estaba probando si podía ver algún patrón, pero no pude, y eliminé todas esas funciones de impresión en el código anterior. Pero la verdad es que este código se congelaría en el medio y no tenía consistencia ni “replicabilidad”.

Busqué en Google pero no pude encontrar a nadie más con un problema similar.

Related of "El indicador de Anaconda se congela cuando ejecuto el código con el decorador “jit” de numba"

Le está pasando un valor incorrecto a np.random.poisson . En su código, el result[i, j] veces puede ser negativo, lo que está causando un NaN in numba, mientras que en python devuelve un valor real (negativo). En Python puedes obtener un ValueError , pero el numba está fallando de una manera diferente que hace que el proceso se bloquee.

Debe decidir si tiene sentido para su problema en particular, pero si lo agrego, la comprobación entre los comentarios # ****** :

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

en foo , entonces el código deja de colgar.

Como una sugerencia de depuración general, es bueno ejecutar su código con los decoradores de jit comentados para ver si algo extraño está sucediendo.