¿Hay una manera de reducir la precisión de scipy / numpy para reducir el consumo de memoria?

StackOverflow https://stackoverflow.com/questions/620428

Pregunta

En mi sistema Debian / Lenny de 64 bits (4GByte RAM + partición de intercambio de 4GByte) puedo hacer con éxito:

v=array(10000*random([512,512,512]),dtype=np.int16)
f=fftn(v)

pero con f siendo un np.complex128 el consumo de memoria es sorprendente, y no puedo hacer mucho más con el resultado (por ejemplo, modular los coeficientes y luego f = ifftn (f ) ) sin un MemoryError traceback.

En lugar de instalar un poco más de RAM y / o expandir mis particiones de intercambio, hay alguna forma de controlar la precisión predeterminada " scipy / numpy; quot quot; y hacer que calcule una matriz complex64 en su lugar?

Sé que puedo reducirlo después con f = array (f, dtype = np.complex64) ; Estoy buscando que el FFT funcione con precisión de 32 bits y la mitad de la memoria.

¿Fue útil?

Solución

No parece que haya ninguna función para hacer esto en las funciones fft de scipy (consulte http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html ).

A menos que sea capaz de encontrar una biblioteca FFT de punto fijo para python, es poco probable que exista la función que desea, ya que su formato de punto flotante de hardware nativo es de 128 bits. Parece que podrías usar el método rfft para obtener solo los componentes de valor real (sin fase) de la FFT, y eso ahorraría la mitad de tu RAM.

Ejecuté lo siguiente en Python interactivo:

>>> from numpy import *
>>>  v = array(10000*random.random([512,512,512]),dtype=int16)
>>> shape(v)
(512, 512, 512)
>>> type(v[0,0,0])
<type 'numpy.int16'>

En este punto, el RSS (tamaño del conjunto residente) de python era de 265 MB.

f = fft.fft(v)

Y en este punto el RSS de python 2.3GB.

>>> type(f)
<type 'numpy.ndarray'>
>>> type(f[0,0,0]) 
<type 'numpy.complex128'>
>>> v = []

Y en este punto, el RSS se reduce a 2.0GB, ya que he liberado v.

Usando " fft.rfft (v) " para calcular valores reales solo se obtienen 1.3GB RSS. (casi la mitad, como se esperaba)

Haciendo:

>>> f = complex64(fft.fft(v))

Es el peor de los dos mundos, ya que primero calcula la versión complex88 (2.3GB) y luego la copia en la versión complex64 (1.3GB), lo que significa que el RSS máximo en mi máquina era de 3.6GB, y luego se estableció. a 1.3GB de nuevo.

Creo que si tienes 4GB de RAM, todo debería funcionar bien (como lo hace para mí). ¿Cual es el problema?

Otros consejos

Scipy 0.8 tendrá soporte de precisión simple para casi todo el código FFT (el código ya está en el troncal, por lo que puedes instalar Scipy desde SVN si necesitas la función ahora).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top