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 resultI 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 rngI'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.
cdef rng_sampler[double] * rng_p = new rng_sampler[double](<unsigned long> 123) 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?