Numpy: Durées d'exécution extrêmement longues dans numpy.fft.fft (Trac # 1266)

Créé le 19 oct. 2012  ·  19Commentaires  ·  Source: numpy/numpy

_Billet original http://projects.scipy.org/numpy/ticket/1266 le 19/10/2009 par l'utilisateur trac koehler, attribué à unknown._

Bien que la documentation de numpy.fft.fft indique que:
"C'est plus efficace pour une puissance de na de deux. Cela stocke également un cache de mémoire de travail pour différentes tailles de fft, donc vous pourriez théoriquement rencontrer des problèmes de mémoire si vous appelez cela trop de fois avec trop de n différents." , Je pense qu'il peut être important de signaler cette bizarrerie dans le runtime fft.
En fonction de la longueur du tableau, le runtime fft varie vraiment de façon extrême:

[ipython shell, from numpy import *]
In [1]: %time fft.fft(zeros(119516))
CPU times: user 22.83 s, sys: 0.39 s, total: 23.23 s
Wall time: 23.53 s

In [3]: %time fft.fft(zeros(119517))
CPU times: user 36.33 s, sys: 0.08 s, total: 36.40 s
Wall time: 36.51 s

In [5]: %time fft.fft(zeros(119518))
CPU times: user 4.88 s, sys: 0.08 s, total: 4.96 s
Wall time: 5.02 s

In [7]: %time fft.fft(zeros(119519))
CPU times: user 0.45 s, sys: 0.00 s, total: 0.45 s
Wall time: 0.45 s

In [9]: %time fft.fft(zeros(119515))
CPU times: user 0.07 s, sys: 0.00 s, total: 0.08 s
Wall time: 0.08 s

In [11]: %time fft.fft(zeros(119514))
CPU times: user 15.84 s, sys: 0.06 s, total: 15.90 s
Wall time: 15.95 s

In [13]: %time fft.fft(zeros(119513))
CPU times: user 272.75 s, sys: 1.03 s, total: 273.78 s
Wall time: 275.63 s
00 - Bug numpy.fft

Commentaire le plus utile

Cela devrait être corrigé dans numpy 1.17.

Tous les 19 commentaires

_ @ endolith rédigé le 2009-11-20_

En relation: # 1177 http://projects.scipy.org/scipy/ticket/949

_ @ rgommers rédigé le 2011-03-01_

_ @ rgommers rédigé le 2011-03-01_

David C. a implémenté la transformation Bluestein si vous en avez besoin: https://github.com/cournape/numpy/tree/bluestein

Espérons que bientôt atterrir dans le coffre Numpy.

Jalon changé en Unscheduled par @mwiebe le

dans ce pr un remplissage aux petits nombres premiers est proposé
https://github.com/scipy/scipy/pull/3144
avoir la fonction pour obtenir une meilleure taille de remplissage pourrait être un utilitaire utile dans numpys fftpack

Oui, au lieu de m = 2 ** nextpow2(2 * n - 1) il sera plus rapide d'utiliser quelque chose comme la fonction next_regular

J'ai également rencontré ce problème en utilisant la fonction detect_equilibration de pymbar qui appelle à plusieurs reprises np.fft et np.ifft via la fonction d'autocorrélation de statsmodels sur de nombreux tableaux de plus en plus courts. J'ai découvert le profilage du code, ce qui m'a finalement conduit à ce fil. La seule solution à ce jour est d'appeler explicitement

 np.fft.fftpack._fft_cache.clear()

pour vous assurer que la mémoire requise n'augmente pas dangereusement. Cela ne semble cependant pas être la solution idéale. Ce serait bien d'avoir soit un kwarg tel que "memsafe = True" et / ou une fonction pour vider manuellement le cache sans se référer explicitement à la variable globale.

@juliantaylor Padding n'est pas applicable aux FFT simples, n'est-ce pas? Juste à la convolution / corrélation?

@rgommers L'algorithme Bluestein accélère la FFT pour les tailles principales, comme cela est fait dans https://github.com/scipy/scipy/issues/4288 , mais nécessite un pré-calcul de chirps complexes, et est plus efficace lorsque vous conservez le gazouillez en mémoire et réutilisez-le à plusieurs reprises sur des morceaux de données. Donc je ne suis pas sûr que cela soit bon pour numpy et peut-être simplement reporter à scipy.fftpack.czt pour cette application?

Quoi qu'il en soit, je pense que cela peut être fermé comme un double de https://github.com/numpy/numpy/issues/1177 ? À moins que quelque chose d'autre comme l'algorithme de Rader soit meilleur que celui de Bluestein?

et le problème de

@endolith c'était il y a longtemps :) mais oui, maintenant que je la regarde à nouveau, cela semble être un problème différent. Le problème que j'ai signalé pourrait cependant toujours être pertinent et j'ai dû implémenter la solution de contournement que j'ai suggérée dans pymbar pour que cela fonctionne.

Pour info, j'ai rencontré quelqu'un lors d'une conférence audio qui m'a montré cet exemple. Il est facile à reproduire et extrême.

%time np.fft.fft( np.random.randn(100000) )
Wall time: 16 ms
Out[16]: 
array([ 196.58599022  +0.j        ,  -88.38483360 +89.2507627j ,
       -166.72250316+339.27161306j, ...,   12.22959535 -64.01621313j,
       -166.72250316-339.27161306j,  -88.38483360 -89.2507627j ])

%time np.fft.fft( np.random.randn(100003) )
Wall time: 1min 42s
Out[17]: 
array([  13.36160617  +0.j        , -314.86472577-340.44686425j,
       -258.36716707-170.43805382j, ...,  -21.18014704+441.3618185j ,
       -258.36716707+170.43805382j, -314.86472577+340.44686425j])

fft de longueur 1e6: 16 MILLIsecondes

fft de longueur 1e6 + 3: 1 MINUTE et 42 SECONDES

Fonctionnalité, pas un bug. FFTPACK n'est "rapide" que lorsque les facteurs de taille sont un produit des nombres 2, 3, 4, 5. Il y a eu un désir de longue date d'utiliser un algorithme plus rapide pour les grandes tailles principales, mais il n'a pas été implémenté. Notez que 100003 est premier.

Je n'appellerais pas cela une "fonctionnalité", mais c'est normal et non un bug. :)

https://github.com/scipy/scipy/issues/4288 a l'algorithme de Bluestein, mais il nécessite un pré-calcul d'un chirp complexe, il faudrait donc faire des tests pour voir à quelles tailles principales cela vaut la peine.

Intéressant. La principale chose que je sais, c'est que l'implémentation fft par défaut pour Julia et Matlab n'a pas ce comportement. Je suis curieux de savoir ce que fait l'implémentation Julia pour éviter ce comportement.

Julia et Matlab appellent FFTW, ce que nous ne pouvons pas faire à cause de sa licence.

Notez qu'il existe des liaisons Python pour FFTW; pyFFTW semble plutôt actuel. Si la vitesse FFT est un problème, c'est probablement la voie à suivre. FFTPACK était une bonne implémentation pour son époque, mais le code et le matériel ont évolué.

@charris J'apprécie vraiment les informations et c'est dommage, mais cela a du sens en ce qui concerne la licence.

Cela devrait être corrigé dans numpy 1.17.

merci @mreineck , fermeture

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

inducer picture inducer  ·  3Commentaires

qualiaa picture qualiaa  ·  3Commentaires

kevinzhai80 picture kevinzhai80  ·  4Commentaires

perezpaya picture perezpaya  ·  4Commentaires

navytux picture navytux  ·  4Commentaires