Der folgende Code veranschaulicht mein Problem am besten:
Die Ausgabe auf der Konsole (NB, es dauert ~8 Minuten, um sogar den ersten Test auszuführen) zeigt, dass die 512x512x512x16-Bit-Array-Zuweisungen nicht mehr als erwartet verbrauchen (256 MByte für jeden), und wenn man sich "oben" ansieht, bleibt der Prozess im Allgemeinen wie erwartet unter 600 MByte.
ただし während die vektorisierte Version der Funktion aufgerufen wird, erweitert sich der Prozess zu enorm Größe (über 7 GByte!). Selbst die naheliegendste Erklärung, die mir dafür einfällt - dass vectorize die Ein- und Ausgaben intern in float64 konvertiert - könnte nur ein paar Gigabyte erklären, obwohl die vektorisierte Funktion eine int16 zurückgibt und das zurückgegebene Array sicherlich eine int16 ist. Gibt es eine Möglichkeit, dies zu vermeiden? Benutze/verstehe ich das otypes-Argument von vectorize falsch?
import numpy as np
import subprocess
def logmem():
subprocess.call('cat /proc/meminfo | grep MemFree',shell=True)
def fn(x):
return np.int16(x*x)
def test_plain(v):
print "Explicit looping:"
logmem()
r=np.zeros(v.shape,dtype=np.int16)
for z in xrange(v.shape[0]):
for y in xrange(v.shape[1]):
for x in xrange(v.shape[2]):
r[z,y,x]=fn(x)
print type(r[0,0,0])
logmem()
return r
vecfn=np.vectorize(fn,otypes=[np.int16])
def test_vectorize(v):
print "Vectorize:"
logmem()
r=vecfn(v)
print type(r[0,0,0])
logmem()
return r
logmem()
s=(512,512,512)
v=np.ones(s,dtype=np.int16)
logmem()
test_plain(v)
test_vectorize(v)
v=None
logmem()
Ich verwende die jeweils aktuellen Versionen von Python/numpy auf einem amd64 Debian Squeeze System (Python 2.6.6, numpy 1.4.1).