Есть ли способ уменьшить точность scipy / numpy, чтобы уменьшить потребление памяти?
-
05-07-2019 - |
Вопрос
В моей 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-битной точностью и половиной памяти.
Решение
Не похоже, что есть какая-либо функция, делающая это в функциях 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 ГБ ОЗУ, все должно работать нормально (как и у меня). В чем проблема? Р>
Другие советы
Scipy 0.8 будет поддерживать одинарную точность почти для всего кода fft (код уже находится в стволе, поэтому вы можете установить scipy из svn, если вам нужна эта функция сейчас).