代码之家  ›  专栏  ›  技术社区  ›  Amenhotep

使用MemoryView时,有关NPY_NO_DEPRECATED_API的Cython Numpy警告

  •  43
  • Amenhotep  · 技术社区  · 10 年前

    我正在将Cython内存视图转换为numpy数组(以便能够在纯Python代码中使用它):

    from libc.stdlib cimport realloc
    cimport numpy as np
    
    DTYPE = np.float64
    ctypedef np.float64_t DTYPE_t
    
    cpdef np.ndarray[DTYPE_t] compute(DTYPE_t[:,::1] data):
        cdef unsigned int Nchannels = data.shape[0]
        cdef unsigned int Ndata = data.shape[1]
        cdef DTYPE_t* output = NULL
        cdef DTYPE_t[::1] mv
    
        output = <DTYPE_t*>realloc(output, Ndata*sizeof(output))
        if not output:
            raise MemoryError()
        mv = <DTYPE_t[:Ndata]>output
        mv[10:Ndata-10] = 0.0
        # various calculations...
        return np.asarray(mv, dtype=DTYPE, order='C')
    

    它会编译,但编译器会发出以下警告:

    /Users/vlad/anaconda/lib/python2.7/site-packages/numpy/core/include
    /nump/npy_1_7_deprecated_api.h:15:2: warning:
    "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
    

    我在setup.py中添加了建议的指令:

    from distutils.core import setup, Extension
    from Cython.Build import cythonize
    import numpy
    
    filename = 'agents3.pyx'
    
    agents_module = Extension(
        'Agents',
        sources = [filename],
        define_macros = [('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION')],
        include_dirs = [numpy.get_include()],
    )
    
    setup (name = 'Agents',
        ext_modules = cythonize(agents_module)
    )
    

    现在它无法编译,它说:

    Vlads-MacBook-Pro:program vlad$ python setup.py build_ext --inplace
    Compiling agents3.pyx because it changed.
    Cythonizing agents3.pyx
    running build_ext
    building 'Agents' extension
    gcc -fno-strict-aliasing -I/Users/vlad/anaconda/include -arch x86_64 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -I/Users/vlad/anaconda/lib/python2.7/site-packages/numpy/core/include -I/Users/vlad/anaconda/include/python2.7 -c agents3.c -o build/temp.macosx-10.5-x86_64-2.7/agents3.o
    agents3.c:2273:52: error: use of undeclared identifier 'NPY_C_CONTIGUOUS'
        __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
                                                       ^
    agents3.c:2311:52: error: use of undeclared identifier 'NPY_F_CONTIGUOUS'
        __pyx_t_1 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
                                                       ^
    agents3.c:2474:42: error: no member named 'descr' in 'struct tagPyArrayObject'
      __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);
                               ~~~~~~~~~~~~  ^
    agents3.c:4026:27: error: no member named 'base' in 'struct tagPyArrayObject'
      Py_XDECREF(__pyx_v_arr->base);
                 ~~~~~~~~~~~  ^
    /Users/vlad/anaconda/include/python2.7/object.h:823:34: note: expanded from macro 'Py_XDECREF'
    #define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0)
                                     ^
    agents3.c:4026:27: error: no member named 'base' in 'struct tagPyArrayObject'
      Py_XDECREF(__pyx_v_arr->base);
                 ~~~~~~~~~~~  ^
    /Users/vlad/anaconda/include/python2.7/object.h:823:64: note: expanded from macro 'Py_XDECREF'
    #define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0)
                                                                   ^
    /Users/vlad/anaconda/include/python2.7/object.h:772:24: note: expanded from macro 'Py_DECREF'
            --((PyObject*)(op))->ob_refcnt != 0)            \
                           ^
    agents3.c:4026:27: error: no member named 'base' in 'struct tagPyArrayObject'
      Py_XDECREF(__pyx_v_arr->base);
                 ~~~~~~~~~~~  ^
    /Users/vlad/anaconda/include/python2.7/object.h:823:64: note: expanded from macro 'Py_XDECREF'
    #define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0)
                                                                   ^
    /Users/vlad/anaconda/include/python2.7/object.h:775:34: note: expanded from macro 'Py_DECREF'
            _Py_Dealloc((PyObject *)(op));                  \
                                     ^
    /Users/vlad/anaconda/include/python2.7/object.h:762:15: note: expanded from macro '_Py_Dealloc'
        (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))
                  ^
    /Users/vlad/anaconda/include/python2.7/object.h:115:47: note: expanded from macro 'Py_TYPE'
    #define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
                                                  ^
    agents3.c:4026:27: error: no member named 'base' in 'struct tagPyArrayObject'
      Py_XDECREF(__pyx_v_arr->base);
                 ~~~~~~~~~~~  ^
    /Users/vlad/anaconda/include/python2.7/object.h:823:64: note: expanded from macro 'Py_XDECREF'
    #define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0)
                                                                   ^
    /Users/vlad/anaconda/include/python2.7/object.h:775:34: note: expanded from macro 'Py_DECREF'
            _Py_Dealloc((PyObject *)(op));                  \
                                     ^
    /Users/vlad/anaconda/include/python2.7/object.h:762:45: note: expanded from macro '_Py_Dealloc'
        (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))
                                                ^
    agents3.c:4035:16: error: no member named 'base' in 'struct tagPyArrayObject'
      __pyx_v_arr->base = __pyx_v_baseptr;
      ~~~~~~~~~~~  ^
    agents3.c:4070:30: error: no member named 'base' in 'struct tagPyArrayObject'
      __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
                    ~~~~~~~~~~~  ^
    agents3.c:4093:44: error: no member named 'base' in 'struct tagPyArrayObject'
        __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
                                  ~~~~~~~~~~~  ^
    agents3.c:1065:37: note: expanded from macro '__Pyx_INCREF'
      #define __Pyx_INCREF(r) Py_INCREF(r)
                                        ^
    /Users/vlad/anaconda/include/python2.7/object.h:767:18: note: expanded from macro 'Py_INCREF'
        ((PyObject*)(op))->ob_refcnt++)
                     ^
    agents3.c:4094:41: error: no member named 'base' in 'struct tagPyArrayObject'
        __pyx_r = ((PyObject *)__pyx_v_arr->base);
                               ~~~~~~~~~~~  ^
    11 errors generated.
    error: command 'gcc' failed with exit status 1
    Vlads-MacBook-Pro:program vlad$ 
    

    我该怎么办?保留已弃用的API调用是否可以?它试图访问 base 但我没有这么做,这是赛顿的错。我只是将内存视图转换为numpy数组。还有其他更清洁/更安全的方法吗?

    3 回复  |  直到 10 年前
        1
  •  49
  •   Jianxun Li    9 年前

    仅供进一步参考, cython online docs 说这是因为Cython正在使用一个不推荐使用的Numpy API,而目前,这只是一个我们可以忽略的警告。

        2
  •  0
  •   Marlon    10 年前

    我也收到了同样的警告,我认为这很正常。

    对于numpy C API,如果您不喜欢此警告,则需要在C脚本前面加一行,但它所做的只是告诉编译器忽略“已弃用”的消息——这两种方式似乎都一样。

    我猜Cython编译器在生成C代码时不会放入这行代码,我认为这并不重要。

        3
  •  0
  •   Richard    6 年前

    假设希望隐藏弃用警告,则可以使用clang实现以下编译器标志: extra_compile_args=['-Wno-#warnings'] .

    对于gcc, extra_compile_args=['-Wno-cpp'] 实现了相同的效果。

    当然,这也隐藏了其他预处理器指令警告。