Cython:将单个元素分配给多维内存视图切片
Cython: Assigning single element to multidimensional memory view slice
每当我将单个值分配给多维内存视图的切片时,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]]
如期打印出来。我现在通过将文件重命名为 bug.pyx
用 Cython 编译它,将以下内容保存在同一目录的 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 内存视图的这种看似基本的用法?
我提交了 bug report and the issue has since been fixed.
每当我将单个值分配给多维内存视图的切片时,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]]
如期打印出来。我现在通过将文件重命名为 bug.pyx
用 Cython 编译它,将以下内容保存在同一目录的 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 内存视图的这种看似基本的用法?
我提交了 bug report and the issue has since been fixed.