Cython MemoryError

В cdef, где я выделяю массив numpy для своих результатов, я получаю следующую ошибку.

---> 56     cdef np.ndarray[DTYPE_t, ndim=2] alignpmf = np.zeros([bin_len, out_len*bin_len],dtype=float)
MemoryError: 

Соответствующий код:

from __future__ import division
import numpy as np
cimport numpy as np
cimport cython
DTYPE = np.int
DTYPE_f = np.float
ctypedef np.float_t DTYPE_t
ctypedef np.int_t DTYPE_i

...

@cython.boundscheck(False)
@cython.wraparound(False)
def full_pmfs(np.ndarray[DTYPE_i, ndim=2] align, np.ndarray[DTYPE_i, ndim=1] bins):

    assert align.dtype == DTYPE
    assert bins.dtype == DTYPE
    cdef int loop_ind_i, loop_ind_j, inner_count, inner_count_start, inner_count_stop
    cdef int bin_len = bins.shape[0]
    cdef int i_start_ind, i_stop_ind
    cdef int seqs = align.shape[0]
    cdef int residues = align.shape[1]
    cdef int size = residues * bin_len
    cdef int out_len = residues**2 - residues // 2)
    cdef np.ndarray[DTYPE_t, ndim=2] alignpmf = np.zeros([bin_len,
    out_len*bin_len],dtype=float)
    ...

Есть какие-нибудь подсказки о том, что вызывает ошибку? Если я напишу тот же код на python, я не получу ошибки памяти. Когда я запускаю чистый код numpy или cython, он почти не потребляет мой баран (12 ГБ на этом поле). Для справки, bin_len может быть около 20, а out_len может быть 80 000.

Pyx компилируется с помощью python setup.py build_ext --inplace:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy

ext_modules = [Extension("mi", ["mi.pyx"])]

setup(
    name = 'MI calcs',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules,
    include_dirs = [numpy.get_include(),],
    )

person Jessica Collins    schedule 01.03.2012    source источник
comment
Вы уверены, что bin_len и out_len - это те значения, которые вы думаете? Может быть, перед этим вставьте оператор печати?   -  person tillsten    schedule 04.06.2012


Ответы (1)


Я не смог восстановить ошибку - после удаления завершающего символа ")" в вашем коде (при вычислении остатков // 2) и вызова его следующим образом:

from numpy import *
import mi
if __name__ == '__main__':
    a = ones((20,300),mi.DTYPE)
    b = ones(20,mi.DTYPE)
    mi.full_pmfs(a,b) # gives you bin_len = 20 and out_len = 89850 

У меня это отлично работает.

Как именно вы вызываете функцию? Кроме того, по моему опыту, иногда сообщения об ошибках Cython могут быть немного неуместными, может быть, это утверждение после?

person flinz    schedule 04.06.2012