Есть ли способ уменьшить точность scipy / numpy, чтобы уменьшить потребление памяти? - PullRequest
7 голосов
/ 07 марта 2009

На моей 64-битной системе Debian / Lenny (4 Гбайт ОЗУ + раздел подкачки 4 Гбайт) я могу успешно выполнить:

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

, но с f, равным np.complex128, потребление памяти шокирует, и я не могу сделать намного больше с результатом (например, модулировать коэффициенты и затем f=ifftn(f)) без MemoryError трассировки.

Вместо того, чтобы устанавливать больше оперативной памяти и / или расширять разделы подкачки, есть ли какой-нибудь способ управления scipy / numpy «точностью по умолчанию» и вместо этого он вычисляет массив complex64?

Я знаю, что потом могу просто уменьшить его с помощью f=array(f,dtype=np.complex64); Я хочу, чтобы он действительно выполнял FFT-работу с 32-битной точностью и половиной памяти.

Ответы [ 2 ]

5 голосов
/ 07 марта 2009

Не похоже, что есть какая-либо функция для этого в функциях fft Сципи (см. http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html).

Если вы не можете найти библиотеку FFT с фиксированной запятой для python, маловероятно, что нужная функция существует, поскольку ваш собственный аппаратный формат с плавающей запятой имеет 128 бит. Похоже, вы могли бы использовать метод rfft, чтобы получить только компоненты с реальной стоимостью (без фазы) БПФ, и это сэкономило бы половину вашей оперативной памяти.

Я запустил следующее в интерактивном питоне:

>>> 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'>

На данный момент RSS (размер резидентного набора) python составлял 265 МБ.

f = fft.fft(v)

И на данный момент RSS-версия Python 2.3GB.

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

И на этом этапе RSS уменьшается до 2,0 ГБ, так как я освободил v.

Использование «fft.rfft (v)» для вычисления реальных значений приводит к получению 1,3 ГБ RSS. (почти половина, как и ожидалось)

Делать:

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

Это худший из двух миров, поскольку сначала он вычисляет версию complex128 (2,3 ГБ), а затем копирует ее в версию complex64 (1,3 ГБ), что означает, что пиковое значение RSS на моей машине составляло 3,6 ГБ, а затем установилось до 1,3 ГБ снова.

Я думаю, что если у вас 4 ГБ ОЗУ, все должно работать нормально (как и у меня). В чем проблема?

4 голосов
/ 21 марта 2009

Scipy 0.8 будет поддерживать одинарную точность практически для всего кода FFT (код уже находится в транке, поэтому вы можете установить scipy из svn, если вам нужна эта функция сейчас).

...