2010-11-30 4 views
16

Fondamentalement, j'obtiens une erreur de mémoire en python lorsque j'essaie d'effectuer une opération algébrique sur une matrice numpy. La variable u, est une grande matrice de double (dans le cas contraire c'est une matrice de doubles de 288x288x156.) Je n'obtiens cette erreur que dans ce cas, mais je suis capable de le faire sur d'autres grandes matrices. Voici l'erreur 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 est la ligne de code qui échoue.

alpha est juste un double, tandis que u et r sont les grandes matrices décrites ci-dessus (les deux de la même taille).

Je ne sais pas grand-chose sur les erreurs de mémoire en particulier en Python. Toute idée/conseils pour résoudre ce problème serait très apprécié!

Merci

Répondre

39

Réécrire

p *= alpha 
u += p 

et cela utilisera beaucoup moins de mémoire. Alors que p = p*alpha alloue une toute nouvelle matrice pour le résultat de p*alpha, puis rejette le vieux p; p*= alpha fait la même chose en place.

En général, avec les grandes matrices, essayez d'utiliser l'affectation op=.

+0

Ceci est très utile, je ne le savais pas. – tylerthemiler

5

Votre matrice a 288x288x156 = 12.939.264 entrées, qui pour double pourrait venir sur 400Mo en mémoire. numpy en lançant un MemoryError à vous signifie simplement que dans la fonction que vous appelez la mémoire nécessaire pour effectuer l'opération n'était pas disponible à partir du système d'exploitation. Si vous pouvez travailler avec des matrices creuses, cela pourrait vous faire économiser beaucoup de mémoire.

+2

Mais mon ordinateur a 24 Go de RAM ... y at-il un moyen de s'assurer que plus est disponible à partir de Windows ?? Edit: la version de python que nous utilisons est 32 bits pour une raison quelconque:/Edit2: Malheureusement, les matrices creuses ne sont pas une option, car il y a des valeurs dans tous les éléments (équation de la chaleur comme problème). – tylerthemiler

+0

Merci, j'ai effacé certaines choses de la mémoire et je peux maintenant charger ceci. – tylerthemiler

+0

@tylerthemiler: Utilisez les versions 64 bits non officielles http://www.lfd.uci.edu/~gohlke/pythonlibs/ – endolith

9

Un autre conseil que j'ai trouvé pour éviter les erreurs de mémoire est de contrôler manuellement garbage collection. Lorsque les objets sont supprimés ou vont de notre portée, la mémoire utilisée pour ces variables n'est pas libérée jusqu'à ce qu'une récupération de place soit effectuée. J'ai trouvé avec une partie de mon code en utilisant de grands tableaux numpy que j'obtiens un MemoryError, mais que je peux éviter ceci si j'insère des appels à gc.collect() aux endroits appropriés.

Vous ne devriez regarder dans cette option que si l'utilisation des opérateurs de style "op =" etc. ne résout pas votre problème car ce n'est probablement pas la meilleure pratique de codage d'avoir des appels gc.collect() partout.

+0

Ouais, j'ai fini par faire ça. Merci pour la suggestion. – tylerthemiler

+0

Pourquoi MemoryError ne déclenche-t-il pas la récupération de place automatiquement? – endolith

+2

@endolith pour la même raison que vous ne pouvez pas mettre en pause et effacer la mémoire lorsque votre 'malloc()' échoue - il est trop tard _already_ a échoué. Vous pouvez ensuite revenir en arrière, GC et réessayer, mais je pense que les développeurs NumPy préfèrent que vous corrigiez votre code plutôt que de compter sur un pansement. – PythonNut