Подтвердить что ты не робот

Буферные объявления Cython для участников объекта

Я хочу иметь объект Cython cdef с членом NumPy и иметь возможность использовать быстрый доступ к буферам. В идеале я бы сделал что-то вроде:

import numpy as np
cimport numpy as np

cdef class Model:
  cdef np.ndarray[np.int_t, ndim=1] A

  def sum(self):
    cdef int i, s=0, N=len(self.A)
    for 0 <= i < N:
      s += self.A[i]
    return s

  def __init__(self):
    self.A = np.arange(1000)

К сожалению, Cython не может скомпилировать это с ошибкой Buffer types only allowed as function local variables.

Обходной путь, который я использую, заключается в объявлении атрибутов буфера новой локальной переменной, назначенной члену объекта:

cdef class Model:
  cdef np.ndarray A

  def sum(self):
    cdef int i, s=0, N=len(self.A)
    cdef np.ndarray[np.int_t, ndim=1] A = self.A
    for 0 <= i < N:
      s += A[i]
    return s

Это становится очень раздражающим, если вы хотите, чтобы несколько методов обращались к тем же структурам данных, что кажется довольно распространенным случаем использования, no?

Есть ли лучшее решение, которое не требует повторного объявления типов внутри каждого метода?

4b9b3361

Ответ 1

Существует возможность работы с фрагментами памяти или массивами cython http://docs.cython.org/src/userguide/memoryviews.html

import numpy as np
cimport numpy as np

  cdef class Model:

    cdef int [:] A

    def sum(self):

        for 0 <= i < N:
            s += self.A[i]
        return s

    def __init__(self):
        self.A = np.arange(1000)

Ответ 2

Решение, которое вы используете в настоящее время, я использую, т.е. создаю локальную копию в этой функции. Это не изящно, но я не думаю, что вы делаете огромный удар производительности (или, по крайней мере, в моем случае, я много работаю над этим методом, поэтому это не делает заметной разницы). Я также создал C-массив в методе __cinit__, а затем заполнил его данными в __init__ (убедитесь, что вы правильно используете __dealloc__ для очистки). Вы теряете некоторые функции массива numpy, но вы все равно можете использовать его, как и для c-массива.

Вы также можете проверить обсуждение в этом более старом письме в списке cython:

http://codespeak.net/pipermail/cython-dev/2009-April/005214.html