2010-11-30 16 views
16

Básicamente, estoy recibiendo un error de memoria en python cuando intento realizar una operación algebraica en una matriz numpy. La variable u, es una matriz grande de doble (en el caso que falla es una matriz de dobles de 288x288x156. Solo recibo este error en este gran caso, pero puedo hacerlo en otras matrices grandes, pero no tan grande). Aquí está el error de Python:Python/Numpy MemoryError

Traceback (most recent call last): 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 121, in __init__ 
    self.mainSimLoop() 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 309, in mainSimLoop 
    u = solver.solve_cg(u,b,tensors,param,fdHold,resid) # Solve the left hand si 
de of the equation Au=b with conjugate gradient method to approximate u 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\conjugate_getb.py", line 47, in solv 
e_cg 

u = u + alpha*p 

MemoryError 

u = u + alpha*p es la línea de código que falla.

alpha es solo un doble, mientras que u y r son las matrices grandes descritas anteriormente (ambas del mismo tamaño).

No sé mucho acerca de los errores de memoria, especialmente en Python. ¡Cualquier idea/sugerencia para resolver esto sería muy apreciada!

Gracias

Respuesta

39

reescritura de

p *= alpha 
u += p 

y para ello se utiliza mucha menos memoria. Mientras que p = p*alpha asigna una matriz completamente nueva para el resultado de p*alpha y luego descarta la anterior p; p*= alpha hace lo mismo en su lugar.

En general, con matrices grandes, intente utilizar la asignación op=.

+0

Esto es muy útil, no lo sabía. – tylerthemiler

5

Su matriz tiene 288x288x156 = 12.939.264 entradas, que para double podría salir a 400 MB en la memoria. numpy lanzando un MemoryError solo significa que en la función que llamó la memoria necesaria para realizar la operación no estaba disponible desde el sistema operativo.

Si puede trabajar con matrices dispersas, esto podría ahorrarle mucha memoria.

+2

Pero mi computadora tiene 24 GB de RAM ... ¿hay alguna manera de asegurarse de que haya más disponible desde Windows? Editar: la versión de Python que estamos usando es de 32 bits por alguna razón:/Edit2: Desafortunadamente, las matrices dispersas no son una opción, ya que hay valores en todos los elementos (ecuación de calor como problema). – tylerthemiler

+0

Gracias, borré algunas cosas de la memoria y ahora puedo cargar esto. – tylerthemiler

+0

@tylerthemiler: utilice las versiones no oficiales de 64 bits http://www.lfd.uci.edu/~gohlke/pythonlibs/ – endolith

9

Otro consejo que he encontrado para evitar errores de memoria es controlar manualmente garbage collection. Cuando se eliminan los objetos o van a nuestro ámbito, la memoria utilizada para estas variables no se libera hasta que se realiza una recolección de elementos no utilizados. He encontrado con algunos de mis códigos que usan matrices numpy grandes que obtengo un MemoryError, pero que puedo evitar esto si inserto llamadas a gc.collect() en lugares apropiados.

Solo debe considerar esta opción si el uso de operadores de estilo "op =", etc. no resuelve su problema, ya que probablemente no sea la mejor práctica de codificación tener llamadas gc.collect() en todas partes.

+0

Sí, terminé haciendo eso. Gracias por la sugerencia. – tylerthemiler

+0

¿Por qué MemoryError no desencadena la recolección de basura automáticamente? – endolith

+2

@endolith por la misma razón por la que no puede pausar y borrar la memoria cuando falla su 'malloc()' - es demasiado tarde _ ya ha fallado. Podrías volver a hacer doble clic, GC e intentarlo de nuevo, pero creo que los desarrolladores de NumPy prefieren que arregles tu código en vez de recurrir a una curita. – PythonNut

Cuestiones relacionadas