[Cython] OpenMP thread private variable not recognized (bug report + discussion)
The attached cython program uses an extension class to represent a unit of work. The with parallel block temporarily gets the gil to allocate the object, then release the gil and performs the task with a for i in prange(...) statement. My expectation was to have w recognized as a thread private variable. with nogil, parallel(): with gil: w = Worker(n) # should be thread private with nogil: for i in prange(0,m): r += w.run() # should be reduction w = None # is this needed? Cythonize (0.20.2) works without error but produces an incorrect C file. hello.c: In function ‘__pyx_pf_5hello_run’: hello.c:2193:42: error: expected identifier before ‘)’ token hello.c: At top level: The erroneous line is: #pragma omp parallel private() reduction(+:__pyx_v_r) private(__pyx_t_5, __pyx_t_4, __pyx_t_3) firstprivate(__pyx_t_1, __pyx_t_2) private(__pyx_filename, __pyx_lineno, __pyx_clineno) shared(__pyx_parallel_why, __pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb) where you can see that the first private() clause has no argument. The variable __pyx_v_w is not declared as private either as I would expect. I believe that the problem comes from line 7720 in Cython/Compiler/Node.py if self.privates: privates = [e.cname for e in self.privates if not e.type.is_pyobject] code.put('private(%s)' % ', '.join(privates)) And I further believe that the clause "if not e.type.is_pyobject" has been added because nothing would decrements the reference count of the thread private worker object when leaving the parallel block. My quick fix would be to remove this clause and make sure that my program contains the line "w = None" before leaving the thread. But I realize that this is not sufficient for you. Note that the temporary python objects generated by the call to the Worker construction are correctly recognized as thread private and their reference count is correctly decremented when they are no longer needed. The problem here is the clash between the python scoping rules and the semantics of thread private variables. This is one of these cases where I would have liked to be able to write with nogil, parallel(): with gil: cdef w = Worker(n)# block-scoped cdef with nogil: for i in prange(0,m): r += w.run() with an understanding that the scope of the cdef variable is limited to the block where the cdef appears. But when you try this, cython tells you that cdefs are not legal there. # -*- Python -*- import numpy as np cimport numpy as np from cython.parallel import parallel, prange cdef class Worker: cdef double[::1] v def __init__(self, int n): self.v = np.random.randn(n) cdef double run(self) nogil: cdef int i cdef int n = self.v.shape[0] cdef double s = 0 for i in range(0,n): s += self.v[i] return s / n def run(int n, int m): cdef Worker w cdef double r cdef int i with nogil, parallel(): with gil: w = Worker(n) with nogil: for i in prange(0,m): r += w.run() w = None return r / m from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_module = Extension( "hello", ["hello.pyx"], extra_compile_args=['-fopenmp'], extra_link_args=['-fopenmp'], ) setup( name = 'Hello', cmdclass = {'build_ext': build_ext}, ext_modules = [ext_module], ) ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] aritmetic with arrays in Cython
On Sun, Aug 10, 2014 at 12:41 PM, Sturla Molden wrote: > Ian Henriksen > wrote: > > > Maybe I should clarify a little about why eigen is a good place to start. > > According to > href="http://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html";> > http://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html > > it > > already takes care of things like the elimination of temporary variables > > and common subexpression reduction at compile time. This should make it > > possible to compile array expressions in Cython without having to > > re-implement those sorts of optimizations. Ideally we would just have to > > map memory view operations to corresponding equivalents from eigen. It's > > not yet clear to me how to do things with arbitrary-dimensional arrays or > > broadcasting, but, given some more time, a solution may present itself. > > -Ian > > cilkplus is what you want, not Eigen. > > But if you are serious about number crunching, learn Fortran 95. > > > Sturla > > ___ > cython-devel mailing list > cython-devel@python.org > https://mail.python.org/mailman/listinfo/cython-devel > Cilk Plus would also work really nicely for this. Thanks for the suggestion. Fortran is a really great language for this sort of thing, but I don't think I'm ready to tackle the difficulties of using it as a backend for array arithmetic in Cython. It would be a really great feature to have later on though. Thanks! -Ian ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
[Cython] bug: constructor declarations not working
Hi, I want to declare and define C++ classes from Cython. Sure, I could write them in native C++, but it's just small glue code, and I prefer to let Cython handle the GIL and all the other good stuff. First, for reference, the following works (c.f. tests/run/cpp_classes_def.pyx): == cython --cplus example1.pyx cdef cppclass Foo "Foo": int _foo __init__(int foo) nogil: this._foo = foo __dealloc__() nogil: pass === This will emit a declaration for Foo and the implementations of the constructor and destructor (output is truncated to show relevant parts only): struct Foo { int _foo; Foo(int); virtual ~Foo(void); }; Foo::Foo(int __pyx_v_foo) { this->_foo = __pyx_v_foo; } Foo::~Foo(void) { } Now, I want to export the class to other cython files. The following does not work, and I think it's a bug: == example2.pxd === cdef extern cppclass Foo: int _foo __init__(int foo) __dealloc__() === == cython --cplus example2.pyx cdef cppclass Foo: __init__(int foo) nogil: this._foo = foo __dealloc__() nogil: pass === == cython --cplus example3.pyx from example2 cimport Foo cdef Foo* foo_p = new Foo(2) === This fails for example2 with an obscure error message: $ cython --cplus example2.pyx example2.pyx:3:8: undeclared name not builtin: this ...more spurious errors... For example3, Cython runs through but trying to compile shows the actual problem (which you can also see in example2 if you shift things around a bit): $ g++ -fPIC -shared -o example3.so -I /usr/include/python2.7 example3.cpp example3.cpp: In function ‘void initexample3()’: example3.cpp:775:38: error: no matching function for call to ‘Foo::Foo(int)’ __pyx_v_8example3_foo_p = new Foo(2); This is in the generated code: /*--- Type declarations ---*/ struct Foo; struct Foo { int _foo; virtual ~Foo(void); }; It's missing the constructor declaration! I traced this a bit down the Compiler/Symtab.py and found this part in CppClassScope::declare_var: 4e07fc52 (Robert Bradshaw 2012-08-21 00:46:00 -0700 2112) if name != "this" and (defining or name != ""): 4e07fc52 (Robert Bradshaw 2012-08-21 00:46:00 -0700 2113) self.var_entries.append(entry) Here defining is 0, so the declaration is skipped. I don't know Cython internals, so I am hoping someone who does can fix this easily given the above information or point me in the right direction. Thanks a lot for Cython, it's very useful! Marcus Brinkmann ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] aritmetic with arrays in Cython
Ian Henriksen schrieb am 12.08.2014 um 04:34: > On Sun, Aug 10, 2014 at 12:41 PM, Sturla Molden wrote: >> Ian Henriksen wrote: >>> Maybe I should clarify a little about why eigen is a good place to start. >>> According to >> href="http://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html";> >> http://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html >>> it >>> already takes care of things like the elimination of temporary variables >>> and common subexpression reduction at compile time. This should make it >>> possible to compile array expressions in Cython without having to >>> re-implement those sorts of optimizations. Ideally we would just have to >>> map memory view operations to corresponding equivalents from eigen. It's >>> not yet clear to me how to do things with arbitrary-dimensional arrays or >>> broadcasting, but, given some more time, a solution may present itself. >>> -Ian >> >> cilkplus is what you want, not Eigen. >> >> But if you are serious about number crunching, learn Fortran 95. > > Cilk Plus would also work really nicely for this. Thanks for the suggestion. > Fortran is a really great language for this sort of thing, but I don't > think I'm ready to tackle the difficulties of using it as a backend for > array arithmetic in Cython. It would be a really great feature to have > later on though. That clarifies a bit of the design then: The syntax support should be somewhat generic, with specialised (sets of) node implementations as backends that generate code for different libraries/compilers/languages. It's ok to start only with Eigen, though. We have working example code for it and everything else has either a much higher entry level for the implementation or a much lower general availability of the required tools. For the syntax/type support, a look at the array expressions branch might also be helpful, although I doubt that there really is all that much to do on that front. Stefan ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel