[Cython] OpenMP thread private variable not recognized (bug report + discussion)

2014-08-11 Thread Leon Bottou

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

2014-08-11 Thread Ian Henriksen
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

2014-08-11 Thread Marcus Brinkmann

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

2014-08-11 Thread Stefan Behnel
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