cython does not find appropriate overloaded constructor

278 views
Skip to first unread message

Lee Zamparo

unread,
Jul 30, 2015, 5:24:15 PM7/30/15
to cython-users

I'm trying to compile and run tests of cyrand using cython, but am running into a bizarre compile error when testing overloaded constructors. See this gist for the complete definitions of the files in question.  I'm using python: 2.7.10 (Anaconda 2.0.1) with cython: 0.22.1.


From the gist, I can compile and run example.pyx just fine, which uses the default constructor:

import numpy as np
cimport numpy as np

cimport cython

include "random.pyx"

@cython.boundscheck(False)
def example(n):

    cdef int N = n

    cdef rng r
    cdef rng_sampler[double] * rng_p = new rng_sampler[double](r)
    cdef rng_sampler[double] rng = deref(rng_p)

    cdef np.ndarray[np.double_t, ndim=1] result = np.empty(N, dtype=np.double)

    for i in range(N):
        result[i] = rng.normal(0.0, 2.0)
    print result
    return result


^ this works and runs fine. An example run produces the following output:

$ python test_example.py [ 0.47237842 3.153744849 3.6854932057 ]


Yet when I try to compile and run the test which used a constructor that takes an unsigned long as argument:

import numpy as np
cimport numpy as np

cimport cython

include "random.pyx"

@cython.boundscheck(False)
def example_seed(n, seed):

    cdef int N = n
    cdef unsigned long Seed = seed

    cdef rng r
    cdef rng_sampler[double] * rng_p = new rng_sampler[double](Seed)
    cdef rng_sampler[double] rng = deref(rng_p)

    cdef np.ndarray[np.double_t, ndim=1] result = np.empty(N, dtype=np.double)

    for i in range(N):
        result[i] = rng.normal(0.0, 2.0)
    print result
    return result

I get the following cython compiler error:

    Error compiling Cython file:
    ----------------------------------------------------------- 
    ...    
       cdef int N = n    
       cdef unsigned long Seed = seed

       cdef rng_sampler[double] * rng_p = new rng_sampler[double](Seed)
    ---------------------------------------------------------- 
    example/example_seed.pyx:15:67 Cannot assign type 'unsigned long' to 'mt19937'


I interpret this message, along with the fact that example.pyx compiles and produces a working example.so file, that cython cannot find (or manage) the rng_sampler constructor that takes an unsigned long as input.  Below is the definition of the rng_sampler cppclass: 


import numpy as np
cimport numpy as np
cimport cython

from cython.operator cimport dereference as deref

from libcpp cimport bool

cdef extern from "boost/random/mersenne_twister.hpp" namespace "boost::random" nogil:
    # random number generator
    cdef cppclass mt19937:
        #init
        mt19937() nogil
        #attributes

        #methods
        seed(unsigned long)


cdef extern from "rng_wrapper.hpp" nogil:
    # wrapper to distributions ...
    cdef cppclass rng_sampler[result_type]:
        #init
        rng_sampler(mt19937) nogil         // <- this constructor works fine in the example.pyx test
        rng_sampler(unsigned long) nogil   // <- this constructor is not found in the example_seed.pyx test
        rng_sampler()  nogil               // <- who knows about this one.
# methods (gamma and exp are using rate param) result_type normal(result_type, result_type) nogil result_type gamma(result_type, result_type) nogil result_type uniform(result_type, result_type) nogil result_type exp(result_type) nogil result_type chisq(result_type) nogil ctypedef mt19937 rng



I've not used cython before, and my cpp is middling at best. Can anyone shed light on how to fix this simple problem?


Thanks,


Lee.

slonik

unread,
Jul 31, 2015, 8:24:02 AM7/31/15
to cython-users, zam...@gmail.com

This is weird. Can you try explicit cast:

cdef rng_sampler[double] * rng_p = new rng_sampler[double](<unsigned long> 123)

--Leo

Lee Zamparo

unread,
Jul 31, 2015, 10:43:07 AM7/31/15
to cython-users, zam...@gmail.com, slon...@gmail.com
Explicitly casting the argument to unsigned long as you suggest yields the same compiler error message.  Good suggestion though, thanks.  Could this be a bug?

slonik

unread,
Aug 1, 2015, 10:53:39 AM8/1/15
to cython-users, zam...@gmail.com, slon...@gmail.com
On Friday, July 31, 2015 at 10:43:07 AM UTC-4, Lee Zamparo wrote:
Explicitly casting the argument to unsigned long as you suggest yields the same compiler error message.  Good suggestion though, thanks.  Could this be a bug?


It does *not* look as a bug to me. The following minimal example shows that cython (both 0.22.1 and git master) resolves overloaded constructors OK.  Compile with:
$ cython -o foo.cc --cplus -2 -f -v foo.pyx

### foo.pyx
cdef extern from *:
    cdef cppclass Bar:
        Bar()

    cdef cppclass Foo[T]:
        Foo()
        Foo(Bar)
        Foo(unsigned long)
        T next()

cdef Bar bar
cdef unsigned int ui= 123
cdef Foo[double] foo0
cdef Foo[double] *p_foo1= new Foo[double](bar)
cdef Foo[double] *p_foo2= new Foo[double](ui)
cdef double x= p_foo2.next()
####

 --Leo

Lee Zamparo

unread,
Aug 3, 2015, 11:44:45 AM8/3/15
to cython-users, zam...@gmail.com, slon...@gmail.com
Thanks.  I had a comment on my SO post that claims it works using cython 0.21.1.   I've downgraded to 0.21.1 and installed a different version of boost, and now it works.  Thanks for helping me track this down.
Reply all
Reply to author
Forward
0 new messages