Этот код ниже лучше всего иллюстрирует мою проблему:
Вывод на консоль (обратите внимание, запуск даже первого теста занимает около 8 минут) показывает, что выделения массива 512x512x512x16-бит потребляют не больше, чем ожидалось (256 МБ для каждого), и, глядя на «сверху», процесс обычно остается суб- 600MB, как и ожидалось.
Однако при вызове векторизованной версии функции процесс расширяется до огромного размера (более 7 ГБ!). Даже самое очевидное объяснение, которое я могу придумать для объяснения этого — векторизация преобразует входные и выходные данные в число с плавающей запятой 64 внутренне — может объяснить только пару гигабайт, хотя векторизованная функция возвращает int16, а возвращаемый массив, безусловно, int16. Есть ли способ избежать этого? Я неправильно использую/понимаю аргумент векторизации otypes?
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()
Я использую те версии Python/numpy, которые актуальны в системе AMD64 Debian Squeeze (Python 2.6.6, numpy 1.4.1).