scipy / numpyの精度を下げてメモリ消費を減らす方法はありますか?
-
05-07-2019 - |
質問
64ビットDebian / Lennyシステム(4GバイトRAM + 4Gバイトスワップパーティション)では、次のことができます。
v=array(10000*random([512,512,512]),dtype=np.int16)
f=fftn(v)
しかし、fが np.complex128
の場合、メモリの消費は衝撃的であり、結果をさらに処理することはできません(たとえば、係数を変調してから f = ifftn(f )
) MemoryError
トレースバックなし。
RAMをインストールしたり、スワップパーティションを拡張したりする代わりに、scipy / numpyの「デフォルトの精度」を制御する方法があります。代わりにcomplex64配列を計算しますか?
後で f = array(f、dtype = np.complex64)
で減らすことができることを知っています。私は実際にFFTを32ビット精度で半分のメモリで動作させるようにしています。
解決
scipyのfft関数でこれを行う関数はないようです( http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html )。
Python用の固定小数点FFTライブラリが見つからない限り、ネイティブハードウェアの浮動小数点形式は128ビットなので、必要な関数が存在する可能性は低いです。 rfftメソッドを使用して、FFTの実際の値のコンポーネント(位相なし)だけを取得できるように見えます。これにより、RAMの半分を節約できます。
対話型pythonで次を実行しました:
>>> 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'>
この時点で、pythonのRSS(Resident Set Size)は265MBでした。
f = fft.fft(v)
この時点で、Python 2.3GBのRSS。
>>> type(f)
<type 'numpy.ndarray'>
>>> type(f[0,0,0])
<type 'numpy.complex128'>
>>> v = []
そして、この時点でRSSは2.0GBになります。vを解放しました。
&quot; fft.rfft(v)&quot;の使用実数値のみを計算すると、1.3GB RSSになります。 (予想どおり、ほぼ半分)
実行:
>>> f = complex64(fft.fft(v))
最初にcomplex128バージョン(2.3GB)を計算し、それをcomplex64バージョン(1.3GB)にコピーします。つまり、私のマシンのピークRSSは3.6GBであり、その後落ち着きます。再び1.3GBに。
4GBのRAMがあれば、これはすべてうまくいくはずです(私にとってはそうです)。問題は何ですか?
他のヒント
Scipy 0.8は、ほぼすべてのfftコードを単精度でサポートします(コードはすでにトランクにあるため、機能が必要な場合はsvnからscipyをインストールできます)。