2009-03-06 14 views
7

मेरी 64-बिट Debian/लेनी प्रणाली पर (4GByte रैम + 4GByte स्वैप विभाजन) मैं सफलतापूर्वक कर सकते हैं:स्मृति खपत को कम करने के लिए scipy/numpy परिशुद्धता को कम करने का कोई तरीका है?

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

लेकिन च के साथ किया जा रहा है एक np.complex128 स्मृति खपत चौंकाने वाला है, और मैं ज्यादा कुछ नहीं कर सकते हैं परिणाम के साथ और अधिक (उदाहरण के लिए गुणांक को संशोधित करें और फिर f=ifftn(f)) MemoryError ट्रेसबैक के बिना।

कुछ और रैम और/या मेरे स्वैप विभाजन को विस्तारित करने के बजाय, क्या scipy/numpy "डिफ़ॉल्ट परिशुद्धता" को नियंत्रित करने का कोई तरीका है और इसके बजाय यह एक जटिल 64 सरणी की गणना करता है?

मुझे पता है कि मैं इसे बाद में f=array(f,dtype=np.complex64) के साथ कम कर सकता हूं; मैं वास्तव में 32-बिट परिशुद्धता और आधा स्मृति में एफएफटी काम करना चाहता हूं।

उत्तर

5

ऐसा लगता है कि scipy के fft कार्यों में ऐसा करने के लिए कोई फ़ंक्शन नहीं है (http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html देखें)।

जब तक आप पाइथन के लिए एक निश्चित बिंदु एफएफटी लाइब्रेरी नहीं ढूंढ पा रहे हैं, तो यह संभावना नहीं है कि आप जिस फ़ंक्शन को चाहते हैं, वह मौजूद है, क्योंकि आपका मूल हार्डवेयर फ़्लोटिंग पॉइंट प्रारूप 128 बिट्स है। ऐसा लगता है कि आप एफएफटी के वास्तविक मूल्यवान घटकों (कोई चरण) प्राप्त करने के लिए आरएफटी विधि का उपयोग नहीं कर सकते हैं, और यह आपकी आधा रैम बचाएगा।

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

इस बिंदु आरएसएस (निवासी सेट आकार) अजगर की 265MB था:

मैं इंटरैक्टिव अजगर में निम्नलिखित भाग गया।

f = fft.fft(v) 

और इस बिंदु पर अजगर 2.3 जीबी आरएसएस।

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

और इस बिंदु आरएसएस 2.0GB करने के लिए नीचे चला जाता है, के बाद से मैं वी अप free'd गए हैं पर।

का उपयोग करना "fft.rfft (v)" वास्तविक मूल्यों की गणना करने के लिए केवल परिणाम एक 1.3 जीबी आरएसएस। (लगभग आधे, उम्मीद के रूप में)

कर:

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

दोनों दुनिया का सबसे बुरा है, क्योंकि यह पहले complex128 संस्करण (2.3GB) की गणना करता है और उसके बाद प्रतियां कि complex64 संस्करण में (1.3GB) जिसका मतलब है कि मेरी मशीन पर शीर्ष आरएसएस 3.6 जीबी था, और फिर यह फिर से 1.3 जीबी तक बस गया।

मुझे लगता है कि अगर आपके पास 4 जीबी रैम है, तो यह सब ठीक काम करेगा (जैसा कि यह मेरे लिए करता है)। मुद्दा क्या है?

+1

rfftn कार्यों के सूचक के लिए धन्यवाद; हाँ वे अच्छी तरह से काम करते हैं। एफ = आरएफटीएन (वी), एफ = सरणी (एफ, dtype = np.complex64) के लिए पीक उपयोग, एफ = irfftn (एफ) उलटा में 6224MByte है। (इंटरमीडिएट कास्ट जटिल 64 के बिना यह 7754 एमबीटीई का उपयोग करता है ... थोड़ा कसकर)। – timday

+0

क्या आपका उत्पादन सरणी आकार वास्तव में 512^3 से अधिक है? मुझे यकीन नहीं है कि आप 4x रैम उपयोग की तरह कुछ क्यों देख रहे हैं जो मैं ऊपर अपने उदाहरण कोड में देखता हूं ... – slacy

+0

कृपया उस बिट को संशोधित करें जहां आप कहते हैं 'एकल-परिशुद्धता मौजूद नहीं है क्योंकि आपके मूल हार्डवेयर 128-बिट' हैं- मूल हार्डवेयर 64 बिट्स से 128 बिट्स नहीं है, और एफएफटीडब्ल्यू दोनों का समर्थन करने में बहुत लचीला है। जैसा कि डेविड का जवाब इंगित करता है, 'scipy.fftpack.rfft' इसका समर्थन करता है: 'scipy.fftpack.rfft (v.astype (np.float32))। Dtype' रिटर्न' float32'। दुर्भाग्य से, 2015 में भी, Sumy के पीछे बेवकूफ समर्थन है: https://github.com/numpy/numpy/issues/6012 –

4

Scipy 0.8 में लगभग सभी एफएफटी कोड के लिए एकल सटीक समर्थन होगा (कोड पहले से ही ट्रंक में है, इसलिए यदि आप अब सुविधा की आवश्यकता है तो आप svn से scipy इंस्टॉल कर सकते हैं)।

संबंधित मुद्दे