Создать список указателей на массив numy - PullRequest
0 голосов
/ 06 декабря 2018

Я реализую в Cython (0.29) и использую numpy (1.15.1)

cdef double *proj_points[1024]
cdef np.ndarray[double, ndim=2, mode="c"] array_ptr

for i in range(2):
    array_ptr = np.ascontiguousarray(self.projection[i] @ points, dtype=np.float)
    proj_points[i] = &array_ptr[0, 0]

В строке 1 я определяю массив указателей (в стеке).В строке 2 я определяю array_ptr, который я использую для преобразования массива numpy в указатель в стиле C на массив numpy.

Проблема:

Когда я проверяю указатели в proj_points, все они указывают на один и тот же элемент памяти последнего массива numpy (т. Е. Второй в цикле).

Текущий (неудовлетворительный) обходной путь

Если я сделаю то же самое жестко:

cdef np.ndarray[double, ndim=2, mode="c"] array_ptr0 = np.ascontiguousarray(self.projection[0] @ points, dtype=np.float)
self.proj_points[0] = &array_ptr0[0, 0]

cdef np.ndarray[double, ndim=2, mode="c"] array_ptr1 = np.ascontiguousarray(self.projection[1] @ points, dtype=np.float)
self.proj_points[1] = &array_ptr1[0, 0]

Все указатели указывают на первое значение соответствующего массива numpy.Это то, что я также хотел бы иметь в приведенном выше случае цикла, поскольку во время выполнения может быть переменное количество указателей.Как я могу сделать это?

То, что я также пробовал до сих пор:

  • cdef array_ptr внутри цикла, но это недопустимо в Cython (cdefразрешено только на первом уровне).
  • поместите деталь внутри петли в функцию и получите внутреннюю функцию cdef, но это не сработало

1 Ответ

0 голосов
/ 06 декабря 2018

Указатели на массивы не являются частью схемы подсчета ссылок Python, поэтому они не препятствуют уничтожению массива.

Поэтому, как только array_ptr переназначается в начале каждого цикла, Python уничтожаетмассив, который он использовал для хранения.Это означает, что предыдущий элемент proj_points теперь является указателем на массив, который больше не существует, и то, что вы получите, если попытаетесь прочитать его, полностью не определено.

Вам необходимо сохранить ссылку на Python длялюбой пустой массив, на который вы держите указатель.

...