Cython: Присвоение отдельного элемента многомерному фрагменту памяти - PullRequest
8 голосов
/ 02 мая 2019

Кажется, что Cython использует неправильный шаг, когда я присваиваю одно значение срезу многомерного представления памяти, за исключением случаев, когда срез находится вдоль первого измерения.Ниже приведен полный пример:

# bug.py
import numpy as np

def bug():
    #cdef int[:, ::1] a
    a = 2*np.ones((2, 2), dtype=np.intc)
    a[:, :1] = 1
    print(np.asarray(a))

Если мы запустим это в Python (например, python3 -c 'import bug; bug.bug()'), мы получим

[[1 2]
 [1 2]]

, как и ожидалось.Теперь я скомпилировал его с помощью Cython, переименовав файл в bug.pyx, сохранив следующее в Makefile в том же каталоге,

# Makefile
python = python3
python_config = $(python)-config
CC = gcc
CFLAGS  = $(shell $(python_config) --cflags) -fPIC
CFLAGS += $(shell $(python_config) --includes)
python_libdir = $(shell $(python) -c "import sysconfig; \
    print(sysconfig.get_config_var('LIBDIR'));")
LDLIBS  = -L$(python_libdir) -Wl,-rpath=$(python_libdir)
LDLIBS += $(shell $(python_config) --libs)
LDFLAGS = $(shell $(python_config) --ldflags) -shared

bug.so: bug.c; $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o bug.so bug.c
bug.c: bug.pyx; $(python) -m cython -3 $<

и запустив make.Запустив python3 -c 'import bug; bug.bug()' снова, он теперь получает скомпилированный bug.so, который снова печатает

[[1 2]
 [1 2]]

Если мы теперь раскомментируем объявление cdef, снова запустим make и python3 -c 'import bug; bug.bug()', мы получим

[[1 1]
 [2 2]]

что не так.Я не верю, что объявление int[:, ::1] неверно, так как Cython будет жаловаться.Если я заменю его на int[:, :], это сработает.Кроме того, если я назначу первое измерение a, a[:1, :] = 1, оно будет работать.

Это известная проблема, или я каким-то образом неправильно понимаю это, казалось бы, основное использование представлений памяти Cython?

1 Ответ

1 голос
/ 02 июня 2019

Я отправил отчет об ошибке , и с тех пор проблема была исправлена ​​.

...