有没有办法降低 scipy/numpy 精度以减少内存消耗?
在我的 64 位 Debian/Lenny 系统(4GByte RAM + 4GByte 交换分区)上,我可以成功执行以下操作:
v=array(10000*random([512,512,512]),dtype=np.int16)
f=fftn(v)
但是 f 是 np.complex128
,内存消耗令人震惊,我无能为力更详细地了解结果(例如,调制系数,然后 f=ifftn(f)
),而无需 MemoryError
回溯。
是否有某种方法可以控制 scipy/numpy“默认精度”并让它计算复杂的 64 数组,而不是安装更多 RAM 和/或扩展交换分区?
我知道我可以用 f=array(f,dtype=np.complex64)
; 来减少它 我希望它能够以 32 位精度和一半的内存实际执行 FFT 工作。
On my 64-bit Debian/Lenny system (4GByte RAM + 4GByte swap partition) I can successfully do:
v=array(10000*random([512,512,512]),dtype=np.int16)
f=fftn(v)
but with f being a np.complex128
the memory consumption is shocking, and I can't do much more with the result (e.g modulate the coefficients and then f=ifftn(f)
) without a MemoryError
traceback.
Rather than installing some more RAM and/or expanding my swap partitions, is there some way of controlling the scipy/numpy "default precision" and have it compute a complex64 array instead ?
I know I can just reduce it afterwards with f=array(f,dtype=np.complex64)
; I'm looking to have it actually do the FFT work in 32-bit precision and half the memory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
scipy 的 fft 函数中似乎没有任何函数可以执行此操作(请参阅 http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html)。
除非您能够找到适用于 python 的定点 FFT 库,否则您想要的函数不太可能存在,因为您的本机硬件浮点格式是 128 位。 看起来您确实可以使用 rfft 方法来获取 FFT 的实值分量(无相位),这将节省一半的 RAM。
我在交互式 python 中运行了以下命令:
此时 python 的 RSS(驻留集大小)为 265MB。
而此时python的RSS为2.3GB。
此时,RSS 下降到 2.0GB,因为我已经释放了 v。
使用“fft.rfft(v)”计算实值仅产生 1.3GB RSS。 (几乎一半,如预期)
做法:
是两全其美,因为它首先计算complex128版本(2.3GB),然后将其复制到complex64版本(1.3GB),这意味着我的机器上的峰值RSS是3.6GB ,然后又稳定到1.3GB。
我认为如果你有 4GB RAM,这一切应该都可以正常工作(就像对我来说一样)。 有什么问题吗?
It doesn't look like there's any function to do this in scipy's fft functions ( see http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html ).
Unless you're able to find a fixed point FFT library for python, it's unlikely that the function you want exists, since your native hardware floating point format is 128 bits. It does look like you could use the rfft method to get just the real-valued components (no phase) of the FFT, and that would save half your RAM.
I ran the following in interactive python:
At this point the RSS (Resident Set Size) of python was 265MB.
And at this point the RSS of python 2.3GB.
And at this point the RSS goes down to 2.0GB, since I've free'd up v.
Using "fft.rfft(v)" to compute real-values only results in a 1.3GB RSS. (almost half, as expected)
Doing:
Is the worst of both worlds, since it first computes the complex128 version (2.3GB) and then copies that into the complex64 version (1.3GB) which means the peak RSS on my machine was 3.6GB, and then it settled down to 1.3GB again.
I think that if you've got 4GB RAM, this should all work just fine (as it does for me). What's the issue?
Scipy 0.8将为几乎所有的fft代码提供单精度支持(代码已经在主干中,因此如果您现在需要该功能,可以从svn安装scipy)。
Scipy 0.8 will have single precision support for almost all the fft code (The code is already in the trunk, so you can install scipy from svn if you need the feature now).