I have a Cython extension class that wraps the N_Vector type [1] from the 
Sundials solver suite for differential equations. (Thanks to Dag Sverre 
Seljebotn for guidance [2].) However, I have problems using the class outside 
of the module where it was defined (cynvector.pyx).

The following couple of trivial operations work when included at the end of 
cynvector.pyx:

cdef CythonNVector v = CythonNVector(2) # allocates empty N_Vector of length 2
cdef N_Vector p = v.nvector # alias to an attribute of the CythonNVector

(I've learned that both v and p need to have their type specified by 
"cdef ...", otherwise they default to generic Python objects and the "nvector" 
attribute isn't recognized.)

However, the same statements fail if I move them to another file, say 
test_cynvector.pyx:

from sundials cimport * # sundials.pxd contains type declaration for N_Vector
from cynvector import *
cdef CythonNVector v = CythonNVector(2) # allocates empty N_Vector of length 2
cdef N_Vector p = v.nvector # alias to an attribute of the CythonNVector

fails with:

cdef CythonNVector v = CythonNVector(2)
    ^
'CythonNVector' is not a type identifier

Why isn't type CythonNVector recognized outside of cynvector.pyx? A similar 
error results if I try "from cynvector cimport CythonNVector"; then I get "Name 
'CythonNVector' not declared in module 'cynvector'".


Thanks in advance for any help.

[1] https://computation.llnl.gov/casc/sundials/documentation/cv_guide/node7.html
[2] http://article.gmane.org/gmane.comp.python.cython.devel/6556


Here is the essence of cynvector.pyx, based on [2]:

== cynvector.pyx ==
cimport numpy as np
from sundials cimport * # sundials.pxd declares N_Vector and friends

cdef extern from "pyarray_set_base.h":
    void PyArray_Set_BASE(np.ndarray arr, object obj)

cdef extern from "numpy/arrayobject.h":
    void import_array()
    object PyArray_SimpleNewFromData(int nd, np.npy_intp* dims, 
        int typenum, void* data)

import_array()

cdef class CythonNVector:
    cdef N_Vector nvector
    def __init__(self, length):
        self.nvector = N_VNew_Serial(length)

    def __dealloc__(self):
        N_VDestroy_Serial(self.nvector)

    cpdef toarray(self):
        cdef np.npy_intp* shape =  <np.npy_intp *>(
            &(<N_VectorContent_Serial>(self.nvector).content).length)
        assert sizeof(realtype) == sizeof(double)
        cdef np.ndarray result = PyArray_SimpleNewFromData(1, shape, 
            np.NPY_DOUBLE, 
            <void*>((<N_VectorContent_Serial>(self.nvector).content).data))
        PyArray_Set_BASE(result, self)
        return result

# Testing: These statements do work at the end of cynvector.pyx.
cdef CythonNVector v = CythonNVector(2)
cdef N_Vector p = v.nvector


_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to