Re: [Cython] General generator expressions

2011-01-10 Thread Vitja Makarov
2011/1/7 Stefan Behnel :
> Robert Bradshaw, 07.01.2011 19:17:
>> On Fri, Jan 7, 2011 at 4:27 AM, Vitja Makarov wrote:
>>> I've added GenerartorDefNode and GeneratorBodyDefNode now all the
>>> generators stuff is handled there.
>>
>> Yay! I'm pretty busy this weekend, but have been following your branch
>> from a distance and so reviewing this shouldn't take too long. I'm
>> thinking we should get a 0.14.1 bug fix out ASAP (e.g. once those
>> Windows and type inference bugs are in) and then 0.15 will follow with
>> generators.
>
> Absolutely. I should find some time for a review early next week, but more
> eyes are always better.
>

I've added some new things:
 - return with no value inside generator
 - nested yields (yield (yield (yield)))
 - yield inside lambda (strange thing btw), was used in test_collections
 - genexpr support, inlining is now disabled

Now I'm thinking how to enable genexpr inlining.


-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2011-01-07 Thread Stefan Behnel
Robert Bradshaw, 07.01.2011 19:17:
> On Fri, Jan 7, 2011 at 4:27 AM, Vitja Makarov wrote:
>> I've added GenerartorDefNode and GeneratorBodyDefNode now all the
>> generators stuff is handled there.
>
> Yay! I'm pretty busy this weekend, but have been following your branch
> from a distance and so reviewing this shouldn't take too long. I'm
> thinking we should get a 0.14.1 bug fix out ASAP (e.g. once those
> Windows and type inference bugs are in) and then 0.15 will follow with
> generators.

Absolutely. I should find some time for a review early next week, but more 
eyes are always better.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2011-01-07 Thread Robert Bradshaw
On Fri, Jan 7, 2011 at 4:27 AM, Vitja Makarov  wrote:
> 2010/12/31 Robert Bradshaw :
>> On Thu, Dec 30, 2010 at 10:05 AM, Stefan Behnel  wrote:
>>> Vitja Makarov, 30.12.2010 18:53:
 Why did you reverted decorators stuff?

 https://github.com/vitek/cython/commit/e0d366d9409680849e6f429992ac9724e2ad1016
>>>
>>> Because I didn't get it finished, it broke the Sage build and cython-devel
>>> should stay cleanly working before the release.
>>
>> +1
>>
>>> I added a link to the build
>>> failure log to the trac ticket but didn't even manage to come up with a
>>> suitable test case before I had to stop working on it.
>>>
>>> What I implemented so far works in most cases but there are issues with
>>> functions at the module scope. I didn't check the history but I think I
>>> recall from the code comments that Robert worked in this area (method
>>> binding) a while ago, and the comments hint at an unfinished refactoring
>>> that would help with this change.
>>
>> I'm not working on anything in the area at the moment though (or,
>> contrary to my expectations, much of anything Cython-wise... having
>> too much fun hanging out with the family :).
>>
>> - Robert
>> ___
>> Cython-dev mailing list
>> Cython-dev@codespeak.net
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>
> I've added GenerartorDefNode and GeneratorBodyDefNode now all the
> generators stuff is handled there.

Yay! I'm pretty busy this weekend, but have been following your branch
from a distance and so reviewing this shouldn't take too long. I'm
thinking we should get a 0.14.1 bug fix out ASAP (e.g. once those
Windows and type inference bugs are in) and then 0.15 will follow with
generators.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2011-01-07 Thread Vitja Makarov
2010/12/31 Robert Bradshaw :
> On Thu, Dec 30, 2010 at 10:05 AM, Stefan Behnel  wrote:
>> Vitja Makarov, 30.12.2010 18:53:
>>> Why did you reverted decorators stuff?
>>>
>>> https://github.com/vitek/cython/commit/e0d366d9409680849e6f429992ac9724e2ad1016
>>
>> Because I didn't get it finished, it broke the Sage build and cython-devel
>> should stay cleanly working before the release.
>
> +1
>
>> I added a link to the build
>> failure log to the trac ticket but didn't even manage to come up with a
>> suitable test case before I had to stop working on it.
>>
>> What I implemented so far works in most cases but there are issues with
>> functions at the module scope. I didn't check the history but I think I
>> recall from the code comments that Robert worked in this area (method
>> binding) a while ago, and the comments hint at an unfinished refactoring
>> that would help with this change.
>
> I'm not working on anything in the area at the moment though (or,
> contrary to my expectations, much of anything Cython-wise... having
> too much fun hanging out with the family :).
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

I've added GenerartorDefNode and GeneratorBodyDefNode now all the
generators stuff is handled there.

Please review.


-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-30 Thread Robert Bradshaw
On Thu, Dec 30, 2010 at 10:05 AM, Stefan Behnel  wrote:
> Vitja Makarov, 30.12.2010 18:53:
>> Why did you reverted decorators stuff?
>>
>> https://github.com/vitek/cython/commit/e0d366d9409680849e6f429992ac9724e2ad1016
>
> Because I didn't get it finished, it broke the Sage build and cython-devel
> should stay cleanly working before the release.

+1

> I added a link to the build
> failure log to the trac ticket but didn't even manage to come up with a
> suitable test case before I had to stop working on it.
>
> What I implemented so far works in most cases but there are issues with
> functions at the module scope. I didn't check the history but I think I
> recall from the code comments that Robert worked in this area (method
> binding) a while ago, and the comments hint at an unfinished refactoring
> that would help with this change.

I'm not working on anything in the area at the moment though (or,
contrary to my expectations, much of anything Cython-wise... having
too much fun hanging out with the family :).

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-30 Thread Stefan Behnel
Vitja Makarov, 30.12.2010 18:53:
> Why did you reverted decorators stuff?
>
> https://github.com/vitek/cython/commit/e0d366d9409680849e6f429992ac9724e2ad1016

Because I didn't get it finished, it broke the Sage build and cython-devel 
should stay cleanly working before the release. I added a link to the build 
failure log to the trac ticket but didn't even manage to come up with a 
suitable test case before I had to stop working on it.

What I implemented so far works in most cases but there are issues with 
functions at the module scope. I didn't check the history but I think I 
recall from the code comments that Robert worked in this area (method 
binding) a while ago, and the comments hint at an unfinished refactoring 
that would help with this change.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-30 Thread Vitja Makarov
2010/12/14 Vitja Makarov :
> 2010/12/14 Stefan Behnel :
>> Vitja Makarov, 14.12.2010 15:49:
>>> 2010/12/14 Stefan Behnel:
 Vitja Makarov, 14.12.2010 14:45:
> 2010/12/14 Stefan Behnel:
>> Stefan Behnel, 13.12.2010 06:37:
>>> Vitja Makarov, 12.12.2010 20:23:
 What do you think about GeneratorWrapperNode?
>>>
>>> It seems ok. I'll give it a deeper look ASAP.
>>
>> Actually, after looking through it, I think it's an ugly hack. It tries 
>> to
>> hide the fact that the DefNode does the wrong thing for the two faces of
>> generators, and that the current implementation does not build a separate
>> node at transform time that does the right thing instead. IMHO, two nodes
>> are needed. A CFuncDefNode (or a subtype) that writes out the generator C
>> function with the right signature and the original body, and the original
>> DefNode (with the original signature) that has its body replaced by the
>> necessary generator setup code. That's basically why the original CEP
>> proposed to split the DefNode implementation *before* going for 
>> generators.
>> Would have made this easier.
>
> Are you sure that CFuncDefNode for generator body is a good idea?
>
> Nested function and classes, lambda, generators are not supported
> inside CFuncDefNode.

 Hmm, right, that's a missing feature that could become a problem.

 Second try. Create a new subtype of DefNode that nails the signature to
 METH_O and additionally implements all the generator specific stuff,
 potentially through sensible hooks in DefNode's code generation.

>>>
>>> What is the best place to create node for generator body?
>>
>> "Create" as in "implement"? In Nodes.py.
>>
>> "Create" as in "instantiate"? Depends. The canonical answer is "in a
>> transform", but sometimes it's easier to do it inside of a node. If the
>> latter, the canonical answer would become analyse_types(). If that's too
>> late, well, back to a transform. :)
>>
>
> I think analyse_types() should be ok, and it wouldn't break things
>

Why did you reverted decorators stuff?

https://github.com/vitek/cython/commit/e0d366d9409680849e6f429992ac9724e2ad1016


-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-14 Thread Vitja Makarov
2010/12/14 Stefan Behnel :
> Vitja Makarov, 14.12.2010 15:49:
>> 2010/12/14 Stefan Behnel:
>>> Vitja Makarov, 14.12.2010 14:45:
 2010/12/14 Stefan Behnel:
> Stefan Behnel, 13.12.2010 06:37:
>> Vitja Makarov, 12.12.2010 20:23:
>>> What do you think about GeneratorWrapperNode?
>>
>> It seems ok. I'll give it a deeper look ASAP.
>
> Actually, after looking through it, I think it's an ugly hack. It tries to
> hide the fact that the DefNode does the wrong thing for the two faces of
> generators, and that the current implementation does not build a separate
> node at transform time that does the right thing instead. IMHO, two nodes
> are needed. A CFuncDefNode (or a subtype) that writes out the generator C
> function with the right signature and the original body, and the original
> DefNode (with the original signature) that has its body replaced by the
> necessary generator setup code. That's basically why the original CEP
> proposed to split the DefNode implementation *before* going for 
> generators.
> Would have made this easier.

 Are you sure that CFuncDefNode for generator body is a good idea?

 Nested function and classes, lambda, generators are not supported
 inside CFuncDefNode.
>>>
>>> Hmm, right, that's a missing feature that could become a problem.
>>>
>>> Second try. Create a new subtype of DefNode that nails the signature to
>>> METH_O and additionally implements all the generator specific stuff,
>>> potentially through sensible hooks in DefNode's code generation.
>>>
>>
>> What is the best place to create node for generator body?
>
> "Create" as in "implement"? In Nodes.py.
>
> "Create" as in "instantiate"? Depends. The canonical answer is "in a
> transform", but sometimes it's easier to do it inside of a node. If the
> latter, the canonical answer would become analyse_types(). If that's too
> late, well, back to a transform. :)
>

I think analyse_types() should be ok, and it wouldn't break things

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-14 Thread Stefan Behnel
Vitja Makarov, 14.12.2010 15:49:
> 2010/12/14 Stefan Behnel:
>> Vitja Makarov, 14.12.2010 14:45:
>>> 2010/12/14 Stefan Behnel:
 Stefan Behnel, 13.12.2010 06:37:
> Vitja Makarov, 12.12.2010 20:23:
>> What do you think about GeneratorWrapperNode?
>
> It seems ok. I'll give it a deeper look ASAP.

 Actually, after looking through it, I think it's an ugly hack. It tries to
 hide the fact that the DefNode does the wrong thing for the two faces of
 generators, and that the current implementation does not build a separate
 node at transform time that does the right thing instead. IMHO, two nodes
 are needed. A CFuncDefNode (or a subtype) that writes out the generator C
 function with the right signature and the original body, and the original
 DefNode (with the original signature) that has its body replaced by the
 necessary generator setup code. That's basically why the original CEP
 proposed to split the DefNode implementation *before* going for generators.
 Would have made this easier.
>>>
>>> Are you sure that CFuncDefNode for generator body is a good idea?
>>>
>>> Nested function and classes, lambda, generators are not supported
>>> inside CFuncDefNode.
>>
>> Hmm, right, that's a missing feature that could become a problem.
>>
>> Second try. Create a new subtype of DefNode that nails the signature to
>> METH_O and additionally implements all the generator specific stuff,
>> potentially through sensible hooks in DefNode's code generation.
>>
>
> What is the best place to create node for generator body?

"Create" as in "implement"? In Nodes.py.

"Create" as in "instantiate"? Depends. The canonical answer is "in a 
transform", but sometimes it's easier to do it inside of a node. If the 
latter, the canonical answer would become analyse_types(). If that's too 
late, well, back to a transform. :)

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-14 Thread Vitja Makarov
2010/12/14 Stefan Behnel :
> Vitja Makarov, 14.12.2010 14:45:
>> 2010/12/14 Stefan Behnel:
>>> Stefan Behnel, 13.12.2010 06:37:
 Vitja Makarov, 12.12.2010 20:23:
> What do you think about GeneratorWrapperNode?

 It seems ok. I'll give it a deeper look ASAP.
>>>
>>> Actually, after looking through it, I think it's an ugly hack. It tries to
>>> hide the fact that the DefNode does the wrong thing for the two faces of
>>> generators, and that the current implementation does not build a separate
>>> node at transform time that does the right thing instead. IMHO, two nodes
>>> are needed. A CFuncDefNode (or a subtype) that writes out the generator C
>>> function with the right signature and the original body, and the original
>>> DefNode (with the original signature) that has its body replaced by the
>>> necessary generator setup code. That's basically why the original CEP
>>> proposed to split the DefNode implementation *before* going for generators.
>>> Would have made this easier.
>>
>> Are you sure that CFuncDefNode for generator body is a good idea?
>>
>> Nested function and classes, lambda, generators are not supported
>> inside CFuncDefNode.
>
> Hmm, right, that's a missing feature that could become a problem.
>
> Second try. Create a new subtype of DefNode that nails the signature to
> METH_O and additionally implements all the generator specific stuff,
> potentially through sensible hooks in DefNode's code generation.
>

What is the best place to create node for generator body?
In analyse_...?

>
>> Btw. It would be nice to make DefNode base for GeneratorNode, all the
>> generator creation stuff could be moved into generate_function_body()
>> and make generator body childern of GeneratorNode.
>
> I'm having trouble parsing the last part of this sentence, but it seems we
> are agreeing that a subtype would be a good idea.
>

oops



-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-14 Thread Stefan Behnel
Vitja Makarov, 14.12.2010 14:45:
> 2010/12/14 Stefan Behnel:
>> Stefan Behnel, 13.12.2010 06:37:
>>> Vitja Makarov, 12.12.2010 20:23:
 What do you think about GeneratorWrapperNode?
>>>
>>> It seems ok. I'll give it a deeper look ASAP.
>>
>> Actually, after looking through it, I think it's an ugly hack. It tries to
>> hide the fact that the DefNode does the wrong thing for the two faces of
>> generators, and that the current implementation does not build a separate
>> node at transform time that does the right thing instead. IMHO, two nodes
>> are needed. A CFuncDefNode (or a subtype) that writes out the generator C
>> function with the right signature and the original body, and the original
>> DefNode (with the original signature) that has its body replaced by the
>> necessary generator setup code. That's basically why the original CEP
>> proposed to split the DefNode implementation *before* going for generators.
>> Would have made this easier.
>
> Are you sure that CFuncDefNode for generator body is a good idea?
>
> Nested function and classes, lambda, generators are not supported
> inside CFuncDefNode.

Hmm, right, that's a missing feature that could become a problem.

Second try. Create a new subtype of DefNode that nails the signature to 
METH_O and additionally implements all the generator specific stuff, 
potentially through sensible hooks in DefNode's code generation.


> Btw. It would be nice to make DefNode base for GeneratorNode, all the
> generator creation stuff could be moved into generate_function_body()
> and make generator body childern of GeneratorNode.

I'm having trouble parsing the last part of this sentence, but it seems we 
are agreeing that a subtype would be a good idea.


> I'm thinking of genexprs they are very similar to lambdas and could be
> implemented reusing lambda stuff.

Lambda is basically implemented as a little transform that creates a 
DefNode. I agree, it should be enough to just wrap generator expressions in 
a new DefNode and let the normal generator machinery do its work.

However, note that this needs to interact with the EarlyReplaceBuiltinCalls 
transform in some way, which inlines generator expressions if possible. 
Looks like it's going to be tricky to arrange the related transformations 
according to the interdependencies, e.g. to the 
AnalyseDeclarationsTransform. I guess subtyping DefNode in two levels 
(DefNode<-GeneratorNode<-GeneratorExpressionNode) could be a step to fix 
this, as the inlining transform could then be changed to properly unpack 
that node instead of the current plain expression.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-14 Thread Vitja Makarov
2010/12/14 Stefan Behnel :
> Stefan Behnel, 13.12.2010 06:37:
>> Vitja Makarov, 12.12.2010 20:23:
>>> What do you think about GeneratorWrapperNode?
>>
>> It seems ok. I'll give it a deeper look ASAP.
>
> Actually, after looking through it, I think it's an ugly hack. It tries to
> hide the fact that the DefNode does the wrong thing for the two faces of
> generators, and that the current implementation does not build a separate
> node at transform time that does the right thing instead. IMHO, two nodes
> are needed. A CFuncDefNode (or a subtype) that writes out the generator C
> function with the right signature and the original body, and the original
> DefNode (with the original signature) that has its body replaced by the
> necessary generator setup code. That's basically why the original CEP
> proposed to split the DefNode implementation *before* going for generators.
> Would have made this easier.
>

Are you sure that CFuncDefNode for generator body is a good idea?

Nested function and classes, lambda, generators are not supported
inside CFuncDefNode.

Btw. It would be nice to make DefNode base for GeneratorNode, all the
generator creation stuff could be moved into generate_function_body()
and make generator body childern of GeneratorNode.

I'm thinking of genexprs they are very similar to lambdas and could be
implemented reusing lambda stuff.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Stefan Behnel
Stefan Behnel, 13.12.2010 06:37:
> Vitja Makarov, 12.12.2010 20:23:
>> What do you think about GeneratorWrapperNode?
>
> It seems ok. I'll give it a deeper look ASAP.

Actually, after looking through it, I think it's an ugly hack. It tries to 
hide the fact that the DefNode does the wrong thing for the two faces of 
generators, and that the current implementation does not build a separate 
node at transform time that does the right thing instead. IMHO, two nodes 
are needed. A CFuncDefNode (or a subtype) that writes out the generator C 
function with the right signature and the original body, and the original 
DefNode (with the original signature) that has its body replaced by the 
necessary generator setup code. That's basically why the original CEP 
proposed to split the DefNode implementation *before* going for generators. 
Would have made this easier.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Vitja Makarov
2010/12/13 Stefan Behnel :
> Vitja Makarov, 13.12.2010 13:54:
>> 2010/12/13 Stefan Behnel:
>>> Vitja Makarov, 12.12.2010 20:23:
 It seems that there is no major issues with generators, refleaks and so on.
>>>
>>> I know what the refcounting problem is now. It's a bug that has already
>>> been (mostly) fixed in Haoyu's branch. So far, we didn't have "nonlocal",
>>> so there was no way to test how closure variables behaved on assignment.
>>> Since local variables in generator functions now live in the closure and
>>> can happily get assigned to, they suffer from the same problem that
>>> nonlocal has.
>>>
>>> The place to fix this is in the assignment code in NameNode. For values in
>>> closures, it must generate a GOTREF() before DECREF-ing the lhs in the
>>> assignment and a GIVREF() after the assignment. I fixed that and also
>>> ripped out the "make refnanny happy" code sections.
>>>
>>> Doing that, I also noticed a couple of other related refnanny problems for
>>> argument handling. I didn't care to port them back to mainline since I'd
>>> expect that the current 0.14 release can live with them. Let's assume from
>>> the current state of the generators branch that 0.15 is not too far off.
>>
>> Did you already fixed this bug?
>
> Yes, and *now* it's even up on github. :)
>
> Stefan

Cool :))


-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Stefan Behnel
Vitja Makarov, 13.12.2010 13:54:
> 2010/12/13 Stefan Behnel:
>> Vitja Makarov, 12.12.2010 20:23:
>>> It seems that there is no major issues with generators, refleaks and so on.
>>
>> I know what the refcounting problem is now. It's a bug that has already
>> been (mostly) fixed in Haoyu's branch. So far, we didn't have "nonlocal",
>> so there was no way to test how closure variables behaved on assignment.
>> Since local variables in generator functions now live in the closure and
>> can happily get assigned to, they suffer from the same problem that
>> nonlocal has.
>>
>> The place to fix this is in the assignment code in NameNode. For values in
>> closures, it must generate a GOTREF() before DECREF-ing the lhs in the
>> assignment and a GIVREF() after the assignment. I fixed that and also
>> ripped out the "make refnanny happy" code sections.
>>
>> Doing that, I also noticed a couple of other related refnanny problems for
>> argument handling. I didn't care to port them back to mainline since I'd
>> expect that the current 0.14 release can live with them. Let's assume from
>> the current state of the generators branch that 0.15 is not too far off.
>
> Did you already fixed this bug?

Yes, and *now* it's even up on github. :)

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Vitja Makarov
2010/12/13 Stefan Behnel :
> Vitja Makarov, 13.12.2010 07:49:
>> 2010/12/13 Stefan Behnel:
>>> Vitja Makarov, 12.12.2010 20:23:
 I've cleaned generators stuff a little:

    * Turn YieldNodeCollector into TreeVisitor
>>>
>>> I think that's ok. It's a bit redundant with the tree traversal that
>>> happens anyway, but it also keeps the code more compact and makes it more
>>> understandable.
>>>
>>> BTW, please start using error test cases. That would easily have caught the
>>> obvious reporting bug in visit_ReturnStatNode.
>>
>> I was thinking about that. I also found that 'return' statment is
>> allowed inside generators.
>> That should raise StopIteration and close generator.
>> Don't know how to go here replace ReturnStatNode with another one
>
> You can replace it by the equivalent of "raise StopIteration" during the
> MarkClosureVisitor transform, e.g. inside of the YieldNodeCollector (which
> would then have to be a transform again). Either emit a compiler error if
> the return statement has an argument (IIRC that's the forbidden case) or
> replace the node if it has none.
>
>

That shold be much better to jump to the place where StopIteration is raised.
Couse StopIteration should not be catched here and finallize should be called.

    * Move ClosureTempAllocator to Code.py
>>>
>>> I still think that the reference should live in FunctionState so that it
>>> goes out of scope automatically. It shouldn't live longer than the function.
>>>
>>
>> Ok, I'll put reference to code.funcstate, or maybe add method to
>> funcstate set_closure_class()
>> That will create tempallocator?
>
> Hmm, not sure. What about adding an "init_generator_temps(scope)" method to
> it that creates the CTA and attaches it to the current funcstate?
>


Ok

> Stefan
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>



-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Vitja Makarov
2010/12/13 Stefan Behnel :
> Vitja Makarov, 12.12.2010 20:23:
>> It seems that there is no major issues with generators, refleaks and so on.
>
> I know what the refcounting problem is now. It's a bug that has already
> been (mostly) fixed in Haoyu's branch. So far, we didn't have "nonlocal",
> so there was no way to test how closure variables behaved on assignment.
> Since local variables in generator functions now live in the closure and
> can happily get assigned to, they suffer from the same problem that
> nonlocal has.
>
> The place to fix this is in the assignment code in NameNode. For values in
> closures, it must generate a GOTREF() before DECREF-ing the lhs in the
> assignment and a GIVREF() after the assignment. I fixed that and also
> ripped out the "make refnanny happy" code sections.
>
> Doing that, I also noticed a couple of other related refnanny problems for
> argument handling. I didn't care to port them back to mainline since I'd
> expect that the current 0.14 release can live with them. Let's assume from
> the current state of the generators branch that 0.15 is not too far off.
>
> Stefan

Did you already fixed this bug?

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Stefan Behnel
Vitja Makarov, 13.12.2010 07:49:
> 2010/12/13 Stefan Behnel:
>> Vitja Makarov, 12.12.2010 20:23:
>>> I've cleaned generators stuff a little:
>>>
>>>* Turn YieldNodeCollector into TreeVisitor
>>
>> I think that's ok. It's a bit redundant with the tree traversal that
>> happens anyway, but it also keeps the code more compact and makes it more
>> understandable.
>>
>> BTW, please start using error test cases. That would easily have caught the
>> obvious reporting bug in visit_ReturnStatNode.
>
> I was thinking about that. I also found that 'return' statment is
> allowed inside generators.
> That should raise StopIteration and close generator.
> Don't know how to go here replace ReturnStatNode with another one

You can replace it by the equivalent of "raise StopIteration" during the 
MarkClosureVisitor transform, e.g. inside of the YieldNodeCollector (which 
would then have to be a transform again). Either emit a compiler error if 
the return statement has an argument (IIRC that's the forbidden case) or 
replace the node if it has none.


>>>* Move ClosureTempAllocator to Code.py
>>
>> I still think that the reference should live in FunctionState so that it
>> goes out of scope automatically. It shouldn't live longer than the function.
>>
>
> Ok, I'll put reference to code.funcstate, or maybe add method to
> funcstate set_closure_class()
> That will create tempallocator?

Hmm, not sure. What about adding an "init_generator_temps(scope)" method to 
it that creates the CTA and attaches it to the current funcstate?

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-13 Thread Stefan Behnel
Vitja Makarov, 12.12.2010 20:23:
> It seems that there is no major issues with generators, refleaks and so on.

I know what the refcounting problem is now. It's a bug that has already 
been (mostly) fixed in Haoyu's branch. So far, we didn't have "nonlocal", 
so there was no way to test how closure variables behaved on assignment. 
Since local variables in generator functions now live in the closure and 
can happily get assigned to, they suffer from the same problem that 
nonlocal has.

The place to fix this is in the assignment code in NameNode. For values in 
closures, it must generate a GOTREF() before DECREF-ing the lhs in the 
assignment and a GIVREF() after the assignment. I fixed that and also 
ripped out the "make refnanny happy" code sections.

Doing that, I also noticed a couple of other related refnanny problems for 
argument handling. I didn't care to port them back to mainline since I'd 
expect that the current 0.14 release can live with them. Let's assume from 
the current state of the generators branch that 0.15 is not too far off.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-12 Thread Vitja Makarov
2010/12/13 Stefan Behnel :
> Vitja Makarov, 12.12.2010 20:23:
>> I've cleaned generators stuff a little:
>>
>>   * Turn YieldNodeCollector into TreeVisitor
>
> I think that's ok. It's a bit redundant with the tree traversal that
> happens anyway, but it also keeps the code more compact and makes it more
> understandable.
>
> BTW, please start using error test cases. That would easily have caught the
> obvious reporting bug in visit_ReturnStatNode.
>
>

I was thinking about that. I also found that 'return' statment is
allowed inside generators.
That should raise StopIteration and close generator.
Don't know how to go here replace ReturnStatNode with another one or
set attribute of return node:

node.return_from_generator = True?


>>   * Merge MarkClosureVisitor and MarkGeneratorVisitor
>
> That looks much better.
>
>
>>   * Rename stuff from CyGenerator to __Pyx_Generator
>
> Thanks. However, the following doesn't seem to have an effect, does it?
>
> -        entry.cname = 'CyGenerator'
> +        entry.cname = 'Generator'
>
> If that's the only place where that cname is used, I'd guess that it should
> better be dropped.
>

Sure. Obsolete code )

>
>>   * Move ClosureTempAllocator to Code.py
>
> I still think that the reference should live in FunctionState so that it
> goes out of scope automatically. It shouldn't live longer than the function.
>

Ok, I'll put reference to code.funcstate, or maybe add method to
funcstate set_closure_class()
That will create tempallocator?

>
>> It seems that there is no major issues with generators, refleaks and so on.
>
> I'm not so sure about the ref-counting yet. I'll have to think it through a
> bit more, but it currently feels a bit funny. (That doesn't mean it's
> wrong, just that I'm not sure it's the way it should be)
>
>
>> So now is time to add support for genexps and code cleanup.
>
> Absolutely. :)
>
>
>> What do you think about GeneratorWrapperNode?
>
> It seems ok. I'll give it a deeper look ASAP.
>

ok.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-12 Thread Stefan Behnel
Vitja Makarov, 12.12.2010 20:23:
> I've cleaned generators stuff a little:
>
>   * Turn YieldNodeCollector into TreeVisitor

I think that's ok. It's a bit redundant with the tree traversal that 
happens anyway, but it also keeps the code more compact and makes it more 
understandable.

BTW, please start using error test cases. That would easily have caught the 
obvious reporting bug in visit_ReturnStatNode.


>   * Merge MarkClosureVisitor and MarkGeneratorVisitor

That looks much better.


>   * Rename stuff from CyGenerator to __Pyx_Generator

Thanks. However, the following doesn't seem to have an effect, does it?

-entry.cname = 'CyGenerator'
+entry.cname = 'Generator'

If that's the only place where that cname is used, I'd guess that it should 
better be dropped.


>   * Move ClosureTempAllocator to Code.py

I still think that the reference should live in FunctionState so that it 
goes out of scope automatically. It shouldn't live longer than the function.


> It seems that there is no major issues with generators, refleaks and so on.

I'm not so sure about the ref-counting yet. I'll have to think it through a 
bit more, but it currently feels a bit funny. (That doesn't mean it's 
wrong, just that I'm not sure it's the way it should be)


> So now is time to add support for genexps and code cleanup.

Absolutely. :)


> What do you think about GeneratorWrapperNode?

It seems ok. I'll give it a deeper look ASAP.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-12 Thread Vitja Makarov
2010/12/11 Vitja Makarov :
> 2010/12/11 Stefan Behnel :
>> Vitja Makarov, 10.12.2010 09:22:
>>> 2010/12/10 Stefan Behnel:
 Stefan Behnel, 09.12.2010 10:46:
> Vitja Makarov, 08.12.2010 22:45:
>> Please review this patch. It's not yet finished, and mostly doesn't work.
>> But you can take a look at patch and generated code.
>
> I'll take a close look ASAP.
>
>>     - Temps are saved/restored/allocated inside YieldExprNode using
>> helper ClosureTempAllocator

 Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
 place for anything that generates code. It also mixes functionality that
 normally lives in Symtab.py with functionality that lives in Code.py.

>>>
>>> Yes, I know. That was placed there to give it a try (actually I'm not
>>> sure what is the best place for it). ClosureTempAllocator now is
>>> attribute of defnode and all yieldnodes, that's not clean.
>>
>> FunctionState in Code.py seems like a good place to hold a reference, at
>> least for the code generation part of it.
>>
>
> At some point we can call code.set_closure_class()
> that would create code.temp_allocator and then refer to it as
> code.temp_allocator.
> temp_allocator isn't good name here maybe closure_temps?
>
>>
>>> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?
>>
>> Why not drop it completely and generate the code in the function node
>> instead? ISTM that the only reason it's there is to drop one line of code
>> at the end of the function body. That can be done much easier.
>>
>>
>
> Sure. You've already done this, thanks!
>
>>> create_abstract_generator() is rather dirty
>>
>> I've seen worse. ;)
>>
>>
>>> I don't know how to bind C functions to CClass.
>>
>> Such as?
>>
>>
>
> e = declare()
> e.func_cname = ...
> e.signature = ...
> I think that there should be a short way
>
>>> I think that generator body could have PyObject *body(PyObject *self,
>>> PyObject *value) signature
>>> With value=Null meaning exception.
>>
>> See the CEP. ;)
>>
>
> Yeah! Forget about that, that's already done. I was looking into
> python implementation and it has `i_exc` arg.
>
>>
>>     - PyxGenerator methods are defined via declare_var
>
> Should we call that "CyGenerator" ? :)

 I actually meant to call it "CyGenerator" at the Python level, but I now
 see that it's actually a purely internal thing. That makes __Pyx_Generator
 a better choice, given that "__pyx_" is the globally reserved prefix in
 Cython code.
>>>
>>> Should rename it back ;)
>>
>> Yep.
>>
>
> __pyx_CyGenerator_(Send|Close)() <-- or lover case suffix is better,
> should look at pep7?
> class __pyx_CyGenerator
> type __pyx_CyGeneratorType
>
> is that ok?
>
>>
>>> How can I declare function entry with METH_VARGS signature?
>>> Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
>>> single METH_VARGS
>>>
>>> That's preferd for "throw" method.
>>
>> I see what you mean. It's a minor issue, though. Just ignore it for now, or
>> raise an exception if kwargs are passed in. After all, .throw() is rarely
>> used and not performance critical at all.
>>
>
> ok
>
>>> Pyregr tests works now on hudson but there is still problem with heapq
>>> don't understand is that related to generators or not
>>
>> Not sure either. It works for me in Py3 but not in Py2.7.
>
> I see you've fixed this issue. Cool.
>
>> disable generators test in Py2.4 - depends on GeneratorExit and potentially 
>> other stuff
>
> May be it's better to generate another exception (StopIteration) in
> 2.4 and control this with #ifdefs ... #endif
>
> What do you think about generate_preamble? Think it's not correct name.
>
> In GeneratorWrapper() buffer cleanup code isn't implemented when
> closure is created.
>
> What is the place for YieldCollector?
>
> About genexp: now it should be easy to implement just like lambda function
>
> --
> vitja.
>

I've cleaned generators stuff a little:

 * Turn YieldNodeCollector into TreeVisitor
 * Merge MarkClosureVisitor and MarkGeneratorVisitor
 * Rename stuff from CyGenerator to __Pyx_Generator
 * Move ClosureTempAllocator to Code.py

It seems that there is no major issues with generators, refleaks and so on.
So now is time to add support for genexps and code cleanup.

What do you think about GeneratorWrapperNode?

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/11 Stefan Behnel :
> Vitja Makarov, 10.12.2010 09:22:
>> 2010/12/10 Stefan Behnel:
>>> Stefan Behnel, 09.12.2010 10:46:
 Vitja Makarov, 08.12.2010 22:45:
> Please review this patch. It's not yet finished, and mostly doesn't work.
> But you can take a look at patch and generated code.

 I'll take a close look ASAP.

>     - Temps are saved/restored/allocated inside YieldExprNode using
> helper ClosureTempAllocator
>>>
>>> Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
>>> place for anything that generates code. It also mixes functionality that
>>> normally lives in Symtab.py with functionality that lives in Code.py.
>>>
>>
>> Yes, I know. That was placed there to give it a try (actually I'm not
>> sure what is the best place for it). ClosureTempAllocator now is
>> attribute of defnode and all yieldnodes, that's not clean.
>
> FunctionState in Code.py seems like a good place to hold a reference, at
> least for the code generation part of it.
>

At some point we can call code.set_closure_class()
that would create code.temp_allocator and then refer to it as
code.temp_allocator.
temp_allocator isn't good name here maybe closure_temps?

>
>> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?
>
> Why not drop it completely and generate the code in the function node
> instead? ISTM that the only reason it's there is to drop one line of code
> at the end of the function body. That can be done much easier.
>
>

Sure. You've already done this, thanks!

>> create_abstract_generator() is rather dirty
>
> I've seen worse. ;)
>
>
>> I don't know how to bind C functions to CClass.
>
> Such as?
>
>

e = declare()
e.func_cname = ...
e.signature = ...
I think that there should be a short way

>> I think that generator body could have PyObject *body(PyObject *self,
>> PyObject *value) signature
>> With value=Null meaning exception.
>
> See the CEP. ;)
>

Yeah! Forget about that, that's already done. I was looking into
python implementation and it has `i_exc` arg.

>
>     - PyxGenerator methods are defined via declare_var

 Should we call that "CyGenerator" ? :)
>>>
>>> I actually meant to call it "CyGenerator" at the Python level, but I now
>>> see that it's actually a purely internal thing. That makes __Pyx_Generator
>>> a better choice, given that "__pyx_" is the globally reserved prefix in
>>> Cython code.
>>
>> Should rename it back ;)
>
> Yep.
>

__pyx_CyGenerator_(Send|Close)() <-- or lover case suffix is better,
should look at pep7?
class __pyx_CyGenerator
type __pyx_CyGeneratorType

is that ok?

>
>> How can I declare function entry with METH_VARGS signature?
>> Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
>> single METH_VARGS
>>
>> That's preferd for "throw" method.
>
> I see what you mean. It's a minor issue, though. Just ignore it for now, or
> raise an exception if kwargs are passed in. After all, .throw() is rarely
> used and not performance critical at all.
>

ok

>> Pyregr tests works now on hudson but there is still problem with heapq
>> don't understand is that related to generators or not
>
> Not sure either. It works for me in Py3 but not in Py2.7.

I see you've fixed this issue. Cool.

> disable generators test in Py2.4 - depends on GeneratorExit and potentially 
> other stuff

May be it's better to generate another exception (StopIteration) in
2.4 and control this with #ifdefs ... #endif

What do you think about generate_preamble? Think it's not correct name.

In GeneratorWrapper() buffer cleanup code isn't implemented when
closure is created.

What is the place for YieldCollector?

About genexp: now it should be easy to implement just like lambda function

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Stefan Behnel
Stefan Behnel, 11.12.2010 00:46:
> Vitja Makarov, 10.12.2010 23:42:
>> Pyregr tests works now on hudson but there is still problem with heapq
>> don't understand is that related to generators or not
>
> Not sure either. It works for me in Py3 but not in Py2.7.

It seems to be generator related and it looks like there's a bug in the 
exception handling. It crashes when checking for exceptions after running 
through the heapiter() generator method. These things often point at a 
dangling reference in Python's exception state.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Stefan Behnel
Vitja Makarov, 10.12.2010 23:42:
> Pyregr tests works now on hudson but there is still problem with heapq
> don't understand is that related to generators or not

Not sure either. It works for me in Py3 but not in Py2.7.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Stefan Behnel
Vitja Makarov, 10.12.2010 09:22:
> 2010/12/10 Stefan Behnel:
>> Stefan Behnel, 09.12.2010 10:46:
>>> Vitja Makarov, 08.12.2010 22:45:
 Please review this patch. It's not yet finished, and mostly doesn't work.
 But you can take a look at patch and generated code.
>>>
>>> I'll take a close look ASAP.
>>>
 - Temps are saved/restored/allocated inside YieldExprNode using
 helper ClosureTempAllocator
>>
>> Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
>> place for anything that generates code. It also mixes functionality that
>> normally lives in Symtab.py with functionality that lives in Code.py.
>>
>
> Yes, I know. That was placed there to give it a try (actually I'm not
> sure what is the best place for it). ClosureTempAllocator now is
> attribute of defnode and all yieldnodes, that's not clean.

FunctionState in Code.py seems like a good place to hold a reference, at 
least for the code generation part of it.


> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?

Why not drop it completely and generate the code in the function node 
instead? ISTM that the only reason it's there is to drop one line of code 
at the end of the function body. That can be done much easier.


> create_abstract_generator() is rather dirty

I've seen worse. ;)


> I don't know how to bind C functions to CClass.

Such as?


> I think that generator body could have PyObject *body(PyObject *self,
> PyObject *value) signature
> With value=Null meaning exception.

See the CEP. ;)


 - PyxGenerator methods are defined via declare_var
>>>
>>> Should we call that "CyGenerator" ? :)
>>
>> I actually meant to call it "CyGenerator" at the Python level, but I now
>> see that it's actually a purely internal thing. That makes __Pyx_Generator
>> a better choice, given that "__pyx_" is the globally reserved prefix in
>> Cython code.
>
> Should rename it back ;)

Yep.


> How can I declare function entry with METH_VARGS signature?
> Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
> single METH_VARGS
>
> That's preferd for "throw" method.

I see what you mean. It's a minor issue, though. Just ignore it for now, or 
raise an exception if kwargs are passed in. After all, .throw() is rarely 
used and not performance critical at all.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Robert Bradshaw
On Fri, Dec 10, 2010 at 2:43 PM, Vitja Makarov  wrote:
> 2010/12/11 Robert Bradshaw :
>> On Fri, Dec 10, 2010 at 2:38 PM, Stefan Behnel  wrote:
>>> Vitja Makarov, 10.12.2010 22:01:
 I've pushed commit that moves exc_save_vars into temps
>>>
>>> Yes, I think that makes good sense and should simplify things a lot.
>>>
 (now it's declared with type=py_object_type and manage_refs=False)
>>>
>>> Sounds right.
>>
>> Can't their be multiple nestings of exc_save_vars (if try statements
>> are nested)?
>>
>> - Robert
>
> That should be ok, temps are allocated dynamicly. Take a look at commit 
> please.

+1, that should be fine.

(I'd actually been meaning to take a good look at your code when I had
some time and then respond with any comments, including this concern
were it was relevant, but just wanted to confirm this was considered
when I saw someone else answered.)

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/11 Robert Bradshaw :
> On Fri, Dec 10, 2010 at 2:38 PM, Stefan Behnel  wrote:
>> Vitja Makarov, 10.12.2010 22:01:
>>> I've pushed commit that moves exc_save_vars into temps
>>
>> Yes, I think that makes good sense and should simplify things a lot.
>>
>>> (now it's declared with type=py_object_type and manage_refs=False)
>>
>> Sounds right.
>
> Can't their be multiple nestings of exc_save_vars (if try statements
> are nested)?
>
> - Robert

That should be ok, temps are allocated dynamicly. Take a look at commit please.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Robert Bradshaw
On Fri, Dec 10, 2010 at 2:38 PM, Stefan Behnel  wrote:
> Vitja Makarov, 10.12.2010 22:01:
>> I've pushed commit that moves exc_save_vars into temps
>
> Yes, I think that makes good sense and should simplify things a lot.
>
>> (now it's declared with type=py_object_type and manage_refs=False)
>
> Sounds right.

Can't their be multiple nestings of exc_save_vars (if try statements
are nested)?

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/11 Stefan Behnel :
> Vitja Makarov, 10.12.2010 22:01:
>> I've pushed commit that moves exc_save_vars into temps
>
> Yes, I think that makes good sense and should simplify things a lot.
>

Here is commit for it
https://github.com/vitek/cython/commit/403fe34aa5ca0a9e512755b7d403cd9965a8d830

>
>> (now it's declared with type=py_object_type and manage_refs=False)
>
> Sounds right.
>
> Stefan

Pyregr tests works now on hudson but there is still problem with heapq
don't understand is that related to generators or not

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Stefan Behnel
Vitja Makarov, 10.12.2010 22:01:
> I've pushed commit that moves exc_save_vars into temps

Yes, I think that makes good sense and should simplify things a lot.


> (now it's declared with type=py_object_type and manage_refs=False)

Sounds right.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/10 Robert Bradshaw :
> On Fri, Dec 10, 2010 at 11:51 AM, Stefan Behnel  wrote:
>> Robert Bradshaw, 10.12.2010 20:35:
>>> On Fri, Dec 10, 2010 at 11:15 AM, Vitja Makarov wrote:
 2010/12/10 Robert Bradshaw:
> On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov wrote:
>> 2010/12/10 Stefan Behnel:
>>> I could also add Hudson jobs for it. Robert, would it be ok to add them 
>>> for
>>> all Python versions?
>
> I think that would be excessive. Lets just do 2.4,
>>>
>>> (I meant 2.3 here...)
>>
>> The 2.3 tests do not run the doctests. I have no idea why (likely a bug or
>> missing feature in the old doctest or unittest module), and I didn't care
>> much since 2.3 is long dead anyway. In any case, 2.4 is a better choice.
>
> Ah, OK, I thought it was an oversight and just went through trying to
> change it (which you probably noticed). Sure, 2.4 is fine.
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

I've pushed commit that moves exc_save_vars into temps (now it's
declared with type=py_object_type and manage_refs=False)
Is that ok? That's required for propper generator support to store
exc_save_vars somewhere.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Robert Bradshaw
On Fri, Dec 10, 2010 at 11:51 AM, Stefan Behnel  wrote:
> Robert Bradshaw, 10.12.2010 20:35:
>> On Fri, Dec 10, 2010 at 11:15 AM, Vitja Makarov wrote:
>>> 2010/12/10 Robert Bradshaw:
 On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov wrote:
> 2010/12/10 Stefan Behnel:
>> I could also add Hudson jobs for it. Robert, would it be ok to add them 
>> for
>> all Python versions?

 I think that would be excessive. Lets just do 2.4,
>>
>> (I meant 2.3 here...)
>
> The 2.3 tests do not run the doctests. I have no idea why (likely a bug or
> missing feature in the old doctest or unittest module), and I didn't care
> much since 2.3 is long dead anyway. In any case, 2.4 is a better choice.

Ah, OK, I thought it was an oversight and just went through trying to
change it (which you probably noticed). Sure, 2.4 is fine.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Stefan Behnel
Robert Bradshaw, 10.12.2010 20:35:
> On Fri, Dec 10, 2010 at 11:15 AM, Vitja Makarov wrote:
>> 2010/12/10 Robert Bradshaw:
>>> On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov wrote:
 2010/12/10 Stefan Behnel:
> I could also add Hudson jobs for it. Robert, would it be ok to add them 
> for
> all Python versions?
>>>
>>> I think that would be excessive. Lets just do 2.4,
>
> (I meant 2.3 here...)

The 2.3 tests do not run the doctests. I have no idea why (likely a bug or 
missing feature in the old doctest or unittest module), and I didn't care 
much since 2.3 is long dead anyway. In any case, 2.4 is a better choice.


>>> 2.7, and a 3.x. If
>>> there's a strange corner case that only manifests in, say, 2.5 then
>>> we'll deal with it later.
>>>
>>
>> Can you please add pyregr for 2.7 also?
>
> Sure, that makes sense as well.

Done.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Robert Bradshaw
On Fri, Dec 10, 2010 at 11:15 AM, Vitja Makarov  wrote:
> 2010/12/10 Robert Bradshaw :
>> On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov  
>> wrote:
>>> 2010/12/10 Stefan Behnel :
 Stefan Behnel, 09.12.2010 10:46:
> Vitja Makarov, 08.12.2010 22:45:
>> Please review this patch. It's not yet finished, and mostly doesn't work.
>> But you can take a look at patch and generated code.
>
> I'll take a close look ASAP.
>
>>    - Temps are saved/restored/allocated inside YieldExprNode using
>> helper ClosureTempAllocator

 Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
 place for anything that generates code. It also mixes functionality that
 normally lives in Symtab.py with functionality that lives in Code.py.

>>>
>>> Yes, I know. That was placed there to give it a try (actually I'm not
>>> sure what is the best place for it). ClosureTempAllocator now is
>>> attribute of defnode and all yieldnodes, that's not clean.
>>>
>>> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?
>>>
>>> create_abstract_generator() is rather dirty
>>>
>>> I don't know how to bind C functions to CClass.
>>>
>>> I think that generator body could have PyObject *body(PyObject *self,
>>> PyObject *value) signature
>>> With value=Null meaning exception.
>>>
 Could you give me ("scoder", or better all Cython devs) commit rights to
 your repo so that I can start refactoring the code and fix problems I find?

>>>
>>> I've added you, but I don't know how to add all devs together.
>>
>> I don't think there's a way to do that, just add whoever you want help
>> participating on this branch. My username is robertwb, and though I
>> haven't rally had time to read any code yet, I'm very interested and
>> would like to help out if I can.
>>
>
> I've added you too.

Thanks.

 I could also add Hudson jobs for it. Robert, would it be ok to add them for
 all Python versions?
>>
>> I think that would be excessive. Lets just do 2.4,

(I meant 2.3 here...)

>> 2.7, and a 3.x. If
>> there's a strange corner case that only manifests in, say, 2.5 then
>> we'll deal with it later.
>>
>
> Can you please add pyregr for 2.7 also?

Sure, that makes sense as well.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/10 Robert Bradshaw :
> On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov  
> wrote:
>> 2010/12/10 Stefan Behnel :
>>> Stefan Behnel, 09.12.2010 10:46:
 Vitja Makarov, 08.12.2010 22:45:
> Please review this patch. It's not yet finished, and mostly doesn't work.
> But you can take a look at patch and generated code.

 I'll take a close look ASAP.

>    - Temps are saved/restored/allocated inside YieldExprNode using
> helper ClosureTempAllocator
>>>
>>> Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
>>> place for anything that generates code. It also mixes functionality that
>>> normally lives in Symtab.py with functionality that lives in Code.py.
>>>
>>
>> Yes, I know. That was placed there to give it a try (actually I'm not
>> sure what is the best place for it). ClosureTempAllocator now is
>> attribute of defnode and all yieldnodes, that's not clean.
>>
>> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?
>>
>> create_abstract_generator() is rather dirty
>>
>> I don't know how to bind C functions to CClass.
>>
>> I think that generator body could have PyObject *body(PyObject *self,
>> PyObject *value) signature
>> With value=Null meaning exception.
>>
>>> Could you give me ("scoder", or better all Cython devs) commit rights to
>>> your repo so that I can start refactoring the code and fix problems I find?
>>>
>>
>> I've added you, but I don't know how to add all devs together.
>
> I don't think there's a way to do that, just add whoever you want help
> participating on this branch. My username is robertwb, and though I
> haven't rally had time to read any code yet, I'm very interested and
> would like to help out if I can.
>

I've added you too.

>>> I could also add Hudson jobs for it. Robert, would it be ok to add them for
>>> all Python versions?
>
> I think that would be excessive. Lets just do 2.4, 2.7, and a 3.x. If
> there's a strange corner case that only manifests in, say, 2.5 then
> we'll deal with it later.
>

Can you please add pyregr for 2.7 also?

>> Yeah, please that would be nice.
>>
>    - PyxGenerator methods are defined via declare_var

 Should we call that "CyGenerator" ? :)
>>>
>>> I actually meant to call it "CyGenerator" at the Python level, but I now
>>> see that it's actually a purely internal thing. That makes __Pyx_Generator
>>> a better choice, given that "__pyx_" is the globally reserved prefix in
>>> Cython code.
>>>
>>
>> Should rename it back ;)
>>
>>> Eventually, we may(!) want to reuse the superclass across modules, but I
>>> currently have no idea how that could be made to work. So it's just another
>>> thing that we don't need to worry about now.
>>>
>>
>> Okay.
>>
>> How can I declare function entry with METH_VARGS signature?
>> Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
>> single METH_VARGS
>>
>> That's preferd for "throw" method.
>
> Just let it be METH_VARGS|METH_KWARGS for now. That doesn't mean it
> can actually take arbitrary keyword arguments, just that the arguments
> that are needed can be passed in as keywords.
>

Ok

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Robert Bradshaw
On Fri, Dec 10, 2010 at 12:22 AM, Vitja Makarov  wrote:
> 2010/12/10 Stefan Behnel :
>> Stefan Behnel, 09.12.2010 10:46:
>>> Vitja Makarov, 08.12.2010 22:45:
 Please review this patch. It's not yet finished, and mostly doesn't work.
 But you can take a look at patch and generated code.
>>>
>>> I'll take a close look ASAP.
>>>
    - Temps are saved/restored/allocated inside YieldExprNode using
 helper ClosureTempAllocator
>>
>> Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
>> place for anything that generates code. It also mixes functionality that
>> normally lives in Symtab.py with functionality that lives in Code.py.
>>
>
> Yes, I know. That was placed there to give it a try (actually I'm not
> sure what is the best place for it). ClosureTempAllocator now is
> attribute of defnode and all yieldnodes, that's not clean.
>
> ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?
>
> create_abstract_generator() is rather dirty
>
> I don't know how to bind C functions to CClass.
>
> I think that generator body could have PyObject *body(PyObject *self,
> PyObject *value) signature
> With value=Null meaning exception.
>
>> Could you give me ("scoder", or better all Cython devs) commit rights to
>> your repo so that I can start refactoring the code and fix problems I find?
>>
>
> I've added you, but I don't know how to add all devs together.

I don't think there's a way to do that, just add whoever you want help
participating on this branch. My username is robertwb, and though I
haven't rally had time to read any code yet, I'm very interested and
would like to help out if I can.

>> I could also add Hudson jobs for it. Robert, would it be ok to add them for
>> all Python versions?

I think that would be excessive. Lets just do 2.4, 2.7, and a 3.x. If
there's a strange corner case that only manifests in, say, 2.5 then
we'll deal with it later.

> Yeah, please that would be nice.
>
    - PyxGenerator methods are defined via declare_var
>>>
>>> Should we call that "CyGenerator" ? :)
>>
>> I actually meant to call it "CyGenerator" at the Python level, but I now
>> see that it's actually a purely internal thing. That makes __Pyx_Generator
>> a better choice, given that "__pyx_" is the globally reserved prefix in
>> Cython code.
>>
>
> Should rename it back ;)
>
>> Eventually, we may(!) want to reuse the superclass across modules, but I
>> currently have no idea how that could be made to work. So it's just another
>> thing that we don't need to worry about now.
>>
>
> Okay.
>
> How can I declare function entry with METH_VARGS signature?
> Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
> single METH_VARGS
>
> That's preferd for "throw" method.

Just let it be METH_VARGS|METH_KWARGS for now. That doesn't mean it
can actually take arbitrary keyword arguments, just that the arguments
that are needed can be passed in as keywords.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-10 Thread Vitja Makarov
2010/12/10 Stefan Behnel :
> Stefan Behnel, 09.12.2010 10:46:
>> Vitja Makarov, 08.12.2010 22:45:
>>> Please review this patch. It's not yet finished, and mostly doesn't work.
>>> But you can take a look at patch and generated code.
>>
>> I'll take a close look ASAP.
>>
>>>    - Temps are saved/restored/allocated inside YieldExprNode using
>>> helper ClosureTempAllocator
>
> Ok, that currently lives in ParseTreeTransforms, which is totally the wrong
> place for anything that generates code. It also mixes functionality that
> normally lives in Symtab.py with functionality that lives in Code.py.
>

Yes, I know. That was placed there to give it a try (actually I'm not
sure what is the best place for it). ClosureTempAllocator now is
attribute of defnode and all yieldnodes, that's not clean.

ExprNode.StopIterationNode isn't expression should it be moved to Nodes.py?

create_abstract_generator() is rather dirty

I don't know how to bind C functions to CClass.

I think that generator body could have PyObject *body(PyObject *self,
PyObject *value) signature
With value=Null meaning exception.

> Could you give me ("scoder", or better all Cython devs) commit rights to
> your repo so that I can start refactoring the code and fix problems I find?
>

I've added you, but I don't know how to add all devs together.

> I could also add Hudson jobs for it. Robert, would it be ok to add them for
> all Python versions?
>
>

Yeah, please that would be nice.

>>>    - PyxGenerator methods are defined via declare_var
>>
>> Should we call that "CyGenerator" ? :)
>
> I actually meant to call it "CyGenerator" at the Python level, but I now
> see that it's actually a purely internal thing. That makes __Pyx_Generator
> a better choice, given that "__pyx_" is the globally reserved prefix in
> Cython code.
>

Should rename it back ;)

> Eventually, we may(!) want to reuse the superclass across modules, but I
> currently have no idea how that could be made to work. So it's just another
> thing that we don't need to worry about now.
>

Okay.

How can I declare function entry with METH_VARGS signature?
Using TypeSlots I can add METH_VARGS|METH_KWARGS entries but not
single METH_VARGS

That's preferd for "throw" method.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Stefan Behnel
Stefan Behnel, 09.12.2010 10:46:
> Vitja Makarov, 08.12.2010 22:45:
>> Please review this patch. It's not yet finished, and mostly doesn't work.
>> But you can take a look at patch and generated code.
>
> I'll take a close look ASAP.
>
>>- Temps are saved/restored/allocated inside YieldExprNode using
>> helper ClosureTempAllocator

Ok, that currently lives in ParseTreeTransforms, which is totally the wrong 
place for anything that generates code. It also mixes functionality that 
normally lives in Symtab.py with functionality that lives in Code.py.

Could you give me ("scoder", or better all Cython devs) commit rights to 
your repo so that I can start refactoring the code and fix problems I find?

I could also add Hudson jobs for it. Robert, would it be ok to add them for 
all Python versions?


>>- PyxGenerator methods are defined via declare_var
>
> Should we call that "CyGenerator" ? :)

I actually meant to call it "CyGenerator" at the Python level, but I now 
see that it's actually a purely internal thing. That makes __Pyx_Generator 
a better choice, given that "__pyx_" is the globally reserved prefix in 
Cython code.

Eventually, we may(!) want to reuse the superclass across modules, but I 
currently have no idea how that could be made to work. So it's just another 
thing that we don't need to worry about now.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Robert Bradshaw
On Thu, Dec 9, 2010 at 12:45 PM, Vitja Makarov  wrote:
> 2010/12/9 Vitja Makarov :
>> 2010/12/9 Robert Bradshaw :
>>> On Thu, Dec 9, 2010 at 2:50 AM, Vitja Makarov  
>>> wrote:
 2010/12/9 Robert Bradshaw :
> On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
>> Robert Bradshaw, 09.12.2010 11:00:
>>> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
 Vitja Makarov, 08.12.2010 22:45:
> Please review this patch. It's not yet finished, and mostly doesn't 
> work.
> But you can take a look at patch and generated code.

 *Way* cool, thanks! I'll take a close look ASAP. Please feel free to 
 send
 in a new patch when you have it. If you use hg, you can use "hg 
 bundle" to
 collect commit series. Don't know about git.

 BTW, why not set up a github branch for this?
>>>
>>> That's exactly what I was thinking. It'll make it easier to review as
>>> well, and for others to contribute without disturbing the main line.
>>
>> BTW, when this goes in, the next Cython version to release is basically
>> 1.0, right? There are some minor Python compatibility issues left, but
>> that'll be the last major feature, the way I count it.
>
> This will be the last major feature before 1.0, but I don't know that
> the first release this is in should be the 1.0 release.
>
> I also think we should set the compatibility bar a bit higher for 1.0
> as well--I want a concrete list of all the differences between Python
> X.y and Cython (for un-annotated code) and to be able to say that, if
> you don't count on the behavior in this list (e.g. identity vs
> equality for floating point literals, maybe stack frames) then you
> should be able to compile your code and have it just work, but
> hopefully faster. At the very least, until we at least attempt to make
> such a list, we won't know where we stand (the regression tests
> presumably being somewhat of a starting point, though I'd like to get
> all of them passing (unless they deal with implementation
> details...)).
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

>>   - Comprehensions are now handled by OldYieldExprNode
>
>... another one of those bad names. ;)
>
>Any reason you couldn't reuse it for both?

 Didn't yet implemented ;) GenexpNode should be replaced with DefFunc
 one that's easy but I want to fix refnanny first. Then fix refcount
 leaks.

>>   - I don't know how to make refnanny work, should refnanny context be
>> stored in closure?
>
> Good call. That's a tricky question.
>
> What about generating a GIVEREF for every Python temp you store in the
> closure, a GOTREF for everything you take back out, and finish/restart the
> refnanny context around the yield?

 Yes, that would help. But the main problem is refnanny context
 setupcontext defines local variable __pyx_refnanny, we should have one
 more macro refnanny_reinitalize_context()
>>>
>>> Yes, we'll need to split this up into two macros. This has actually
>>> bitten be before, when I was writing the profiler. Did you know that ;
>>> all by itself is considered a statement, hence one can't declare
>>> variables after it in some strict compilers?
>>>
>> BTW, why not set up a github branch for this?
>
> That's exactly what I was thinking. It'll make it easier to review as
> well, and for others to contribute without disturbing the main line.

 Should I fork cython from github?
>>>
>>> Yes, please do.
>>>
 Is github insync with hg repo?
>>>
>>> I've been manually keeping the two in sync--just pushed now.
>>>
 What is main repo now?
>>>
>>> It's a DVCS :). Some people have been developing on the git side of
>>> things, and some on the hg side of things, and I've been manually
>>> syncing the two now and then. Obviously this isn't a long term
>>> solution, and I think setting up an automated synchronization both
>>> ways would cause more confusion than benefit, so as soon as the
>>> buildbot starts looking at github I'll make the hg ones read-only.
>>> (Probably worth waiting until after the release to do this.)
>>>
 ps: I think we should hurry with 1.0 release
>>>
>>> Yes, I'd like to hurry too, and with all the stuff you're doing it
>>> should be soon :). I just think it's important to be able to say
>>> "compiles all Python code" rather than "compiles most Python code" and
>>> have a (hopefully small) concrete lits of well-delineated caveats.
>>>
>>> - Robert
>>> ___
>>> Cython-dev mailing list
>>> Cython-dev@codespeak.net
>>> http://codespeak.net/mailman/listinfo/cython-dev
>>>
>>
>> I've created github rep

Re: [Cython] General generator expressions

2010-12-09 Thread Vitja Makarov
2010/12/9 Vitja Makarov :
> 2010/12/9 Robert Bradshaw :
>> On Thu, Dec 9, 2010 at 2:50 AM, Vitja Makarov  
>> wrote:
>>> 2010/12/9 Robert Bradshaw :
 On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
> Robert Bradshaw, 09.12.2010 11:00:
>> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
>>> Vitja Makarov, 08.12.2010 22:45:
 Please review this patch. It's not yet finished, and mostly doesn't 
 work.
 But you can take a look at patch and generated code.
>>>
>>> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to 
>>> send
>>> in a new patch when you have it. If you use hg, you can use "hg bundle" 
>>> to
>>> collect commit series. Don't know about git.
>>>
>>> BTW, why not set up a github branch for this?
>>
>> That's exactly what I was thinking. It'll make it easier to review as
>> well, and for others to contribute without disturbing the main line.
>
> BTW, when this goes in, the next Cython version to release is basically
> 1.0, right? There are some minor Python compatibility issues left, but
> that'll be the last major feature, the way I count it.

 This will be the last major feature before 1.0, but I don't know that
 the first release this is in should be the 1.0 release.

 I also think we should set the compatibility bar a bit higher for 1.0
 as well--I want a concrete list of all the differences between Python
 X.y and Cython (for un-annotated code) and to be able to say that, if
 you don't count on the behavior in this list (e.g. identity vs
 equality for floating point literals, maybe stack frames) then you
 should be able to compile your code and have it just work, but
 hopefully faster. At the very least, until we at least attempt to make
 such a list, we won't know where we stand (the regression tests
 presumably being somewhat of a starting point, though I'd like to get
 all of them passing (unless they deal with implementation
 details...)).

 - Robert
 ___
 Cython-dev mailing list
 Cython-dev@codespeak.net
 http://codespeak.net/mailman/listinfo/cython-dev

>>>
>   - Comprehensions are now handled by OldYieldExprNode

... another one of those bad names. ;)

Any reason you couldn't reuse it for both?
>>>
>>> Didn't yet implemented ;) GenexpNode should be replaced with DefFunc
>>> one that's easy but I want to fix refnanny first. Then fix refcount
>>> leaks.
>>>
>   - I don't know how to make refnanny work, should refnanny context be
> stored in closure?

 Good call. That's a tricky question.

 What about generating a GIVEREF for every Python temp you store in the
 closure, a GOTREF for everything you take back out, and finish/restart the
 refnanny context around the yield?
>>>
>>> Yes, that would help. But the main problem is refnanny context
>>> setupcontext defines local variable __pyx_refnanny, we should have one
>>> more macro refnanny_reinitalize_context()
>>
>> Yes, we'll need to split this up into two macros. This has actually
>> bitten be before, when I was writing the profiler. Did you know that ;
>> all by itself is considered a statement, hence one can't declare
>> variables after it in some strict compilers?
>>
> BTW, why not set up a github branch for this?

 That's exactly what I was thinking. It'll make it easier to review as
 well, and for others to contribute without disturbing the main line.
>>>
>>> Should I fork cython from github?
>>
>> Yes, please do.
>>
>>> Is github insync with hg repo?
>>
>> I've been manually keeping the two in sync--just pushed now.
>>
>>> What is main repo now?
>>
>> It's a DVCS :). Some people have been developing on the git side of
>> things, and some on the hg side of things, and I've been manually
>> syncing the two now and then. Obviously this isn't a long term
>> solution, and I think setting up an automated synchronization both
>> ways would cause more confusion than benefit, so as soon as the
>> buildbot starts looking at github I'll make the hg ones read-only.
>> (Probably worth waiting until after the release to do this.)
>>
>>> ps: I think we should hurry with 1.0 release
>>
>> Yes, I'd like to hurry too, and with all the stuff you're doing it
>> should be soon :). I just think it's important to be able to say
>> "compiles all Python code" rather than "compiles most Python code" and
>> have a (hopefully small) concrete lits of well-delineated caveats.
>>
>> - Robert
>> ___
>> Cython-dev mailing list
>> Cython-dev@codespeak.net
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>
> I've created github repo https://github.com/vitek/cython/
>
> And changed __Pyx_Generator to __CyGenerator...
>
> --
> vitja.
>

I've fixed refnanny. Now regr are okay:

-

Re: [Cython] General generator expressions

2010-12-09 Thread Vitja Makarov
2010/12/9 Robert Bradshaw :
> On Thu, Dec 9, 2010 at 2:50 AM, Vitja Makarov  wrote:
>> 2010/12/9 Robert Bradshaw :
>>> On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
 Robert Bradshaw, 09.12.2010 11:00:
> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
>> Vitja Makarov, 08.12.2010 22:45:
>>> Please review this patch. It's not yet finished, and mostly doesn't 
>>> work.
>>> But you can take a look at patch and generated code.
>>
>> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
>> in a new patch when you have it. If you use hg, you can use "hg bundle" 
>> to
>> collect commit series. Don't know about git.
>>
>> BTW, why not set up a github branch for this?
>
> That's exactly what I was thinking. It'll make it easier to review as
> well, and for others to contribute without disturbing the main line.

 BTW, when this goes in, the next Cython version to release is basically
 1.0, right? There are some minor Python compatibility issues left, but
 that'll be the last major feature, the way I count it.
>>>
>>> This will be the last major feature before 1.0, but I don't know that
>>> the first release this is in should be the 1.0 release.
>>>
>>> I also think we should set the compatibility bar a bit higher for 1.0
>>> as well--I want a concrete list of all the differences between Python
>>> X.y and Cython (for un-annotated code) and to be able to say that, if
>>> you don't count on the behavior in this list (e.g. identity vs
>>> equality for floating point literals, maybe stack frames) then you
>>> should be able to compile your code and have it just work, but
>>> hopefully faster. At the very least, until we at least attempt to make
>>> such a list, we won't know where we stand (the regression tests
>>> presumably being somewhat of a starting point, though I'd like to get
>>> all of them passing (unless they deal with implementation
>>> details...)).
>>>
>>> - Robert
>>> ___
>>> Cython-dev mailing list
>>> Cython-dev@codespeak.net
>>> http://codespeak.net/mailman/listinfo/cython-dev
>>>
>>
   - Comprehensions are now handled by OldYieldExprNode
>>>
>>>... another one of those bad names. ;)
>>>
>>>Any reason you couldn't reuse it for both?
>>
>> Didn't yet implemented ;) GenexpNode should be replaced with DefFunc
>> one that's easy but I want to fix refnanny first. Then fix refcount
>> leaks.
>>
   - I don't know how to make refnanny work, should refnanny context be
 stored in closure?
>>>
>>> Good call. That's a tricky question.
>>>
>>> What about generating a GIVEREF for every Python temp you store in the
>>> closure, a GOTREF for everything you take back out, and finish/restart the
>>> refnanny context around the yield?
>>
>> Yes, that would help. But the main problem is refnanny context
>> setupcontext defines local variable __pyx_refnanny, we should have one
>> more macro refnanny_reinitalize_context()
>
> Yes, we'll need to split this up into two macros. This has actually
> bitten be before, when I was writing the profiler. Did you know that ;
> all by itself is considered a statement, hence one can't declare
> variables after it in some strict compilers?
>
 BTW, why not set up a github branch for this?
>>>
>>> That's exactly what I was thinking. It'll make it easier to review as
>>> well, and for others to contribute without disturbing the main line.
>>
>> Should I fork cython from github?
>
> Yes, please do.
>
>> Is github insync with hg repo?
>
> I've been manually keeping the two in sync--just pushed now.
>
>> What is main repo now?
>
> It's a DVCS :). Some people have been developing on the git side of
> things, and some on the hg side of things, and I've been manually
> syncing the two now and then. Obviously this isn't a long term
> solution, and I think setting up an automated synchronization both
> ways would cause more confusion than benefit, so as soon as the
> buildbot starts looking at github I'll make the hg ones read-only.
> (Probably worth waiting until after the release to do this.)
>
>> ps: I think we should hurry with 1.0 release
>
> Yes, I'd like to hurry too, and with all the stuff you're doing it
> should be soon :). I just think it's important to be able to say
> "compiles all Python code" rather than "compiles most Python code" and
> have a (hopefully small) concrete lits of well-delineated caveats.
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

I've created github repo https://github.com/vitek/cython/

And changed __Pyx_Generator to __CyGenerator...

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Robert Bradshaw
On Thu, Dec 9, 2010 at 2:50 AM, Vitja Makarov  wrote:
> 2010/12/9 Robert Bradshaw :
>> On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
>>> Robert Bradshaw, 09.12.2010 11:00:
 On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
> Vitja Makarov, 08.12.2010 22:45:
>> Please review this patch. It's not yet finished, and mostly doesn't work.
>> But you can take a look at patch and generated code.
>
> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
> in a new patch when you have it. If you use hg, you can use "hg bundle" to
> collect commit series. Don't know about git.
>
> BTW, why not set up a github branch for this?

 That's exactly what I was thinking. It'll make it easier to review as
 well, and for others to contribute without disturbing the main line.
>>>
>>> BTW, when this goes in, the next Cython version to release is basically
>>> 1.0, right? There are some minor Python compatibility issues left, but
>>> that'll be the last major feature, the way I count it.
>>
>> This will be the last major feature before 1.0, but I don't know that
>> the first release this is in should be the 1.0 release.
>>
>> I also think we should set the compatibility bar a bit higher for 1.0
>> as well--I want a concrete list of all the differences between Python
>> X.y and Cython (for un-annotated code) and to be able to say that, if
>> you don't count on the behavior in this list (e.g. identity vs
>> equality for floating point literals, maybe stack frames) then you
>> should be able to compile your code and have it just work, but
>> hopefully faster. At the very least, until we at least attempt to make
>> such a list, we won't know where we stand (the regression tests
>> presumably being somewhat of a starting point, though I'd like to get
>> all of them passing (unless they deal with implementation
>> details...)).
>>
>> - Robert
>> ___
>> Cython-dev mailing list
>> Cython-dev@codespeak.net
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>
>>>   - Comprehensions are now handled by OldYieldExprNode
>>
>>... another one of those bad names. ;)
>>
>>Any reason you couldn't reuse it for both?
>
> Didn't yet implemented ;) GenexpNode should be replaced with DefFunc
> one that's easy but I want to fix refnanny first. Then fix refcount
> leaks.
>
>>>   - I don't know how to make refnanny work, should refnanny context be
>>> stored in closure?
>>
>> Good call. That's a tricky question.
>>
>> What about generating a GIVEREF for every Python temp you store in the
>> closure, a GOTREF for everything you take back out, and finish/restart the
>> refnanny context around the yield?
>
> Yes, that would help. But the main problem is refnanny context
> setupcontext defines local variable __pyx_refnanny, we should have one
> more macro refnanny_reinitalize_context()

Yes, we'll need to split this up into two macros. This has actually
bitten be before, when I was writing the profiler. Did you know that ;
all by itself is considered a statement, hence one can't declare
variables after it in some strict compilers?

>>> BTW, why not set up a github branch for this?
>>
>> That's exactly what I was thinking. It'll make it easier to review as
>> well, and for others to contribute without disturbing the main line.
>
> Should I fork cython from github?

Yes, please do.

> Is github insync with hg repo?

I've been manually keeping the two in sync--just pushed now.

> What is main repo now?

It's a DVCS :). Some people have been developing on the git side of
things, and some on the hg side of things, and I've been manually
syncing the two now and then. Obviously this isn't a long term
solution, and I think setting up an automated synchronization both
ways would cause more confusion than benefit, so as soon as the
buildbot starts looking at github I'll make the hg ones read-only.
(Probably worth waiting until after the release to do this.)

> ps: I think we should hurry with 1.0 release

Yes, I'd like to hurry too, and with all the stuff you're doing it
should be soon :). I just think it's important to be able to say
"compiles all Python code" rather than "compiles most Python code" and
have a (hopefully small) concrete lits of well-delineated caveats.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Vitja Makarov
2010/12/9 Robert Bradshaw :
> On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
>> Robert Bradshaw, 09.12.2010 11:00:
>>> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
 Vitja Makarov, 08.12.2010 22:45:
> Please review this patch. It's not yet finished, and mostly doesn't work.
> But you can take a look at patch and generated code.

 *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
 in a new patch when you have it. If you use hg, you can use "hg bundle" to
 collect commit series. Don't know about git.

 BTW, why not set up a github branch for this?
>>>
>>> That's exactly what I was thinking. It'll make it easier to review as
>>> well, and for others to contribute without disturbing the main line.
>>
>> BTW, when this goes in, the next Cython version to release is basically
>> 1.0, right? There are some minor Python compatibility issues left, but
>> that'll be the last major feature, the way I count it.
>
> This will be the last major feature before 1.0, but I don't know that
> the first release this is in should be the 1.0 release.
>
> I also think we should set the compatibility bar a bit higher for 1.0
> as well--I want a concrete list of all the differences between Python
> X.y and Cython (for un-annotated code) and to be able to say that, if
> you don't count on the behavior in this list (e.g. identity vs
> equality for floating point literals, maybe stack frames) then you
> should be able to compile your code and have it just work, but
> hopefully faster. At the very least, until we at least attempt to make
> such a list, we won't know where we stand (the regression tests
> presumably being somewhat of a starting point, though I'd like to get
> all of them passing (unless they deal with implementation
> details...)).
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

>>   - Comprehensions are now handled by OldYieldExprNode
>
>... another one of those bad names. ;)
>
>Any reason you couldn't reuse it for both?

Didn't yet implemented ;) GenexpNode should be replaced with DefFunc
one that's easy but I want to fix refnanny first. Then fix refcount
leaks.

>>   - I don't know how to make refnanny work, should refnanny context be
>> stored in closure?
>
> Good call. That's a tricky question.
>
> What about generating a GIVEREF for every Python temp you store in the
> closure, a GOTREF for everything you take back out, and finish/restart the
> refnanny context around the yield?

Yes, that would help. But the main problem is refnanny context
setupcontext defines local variable __pyx_refnanny, we should have one
more macro refnanny_reinitalize_context()

>> BTW, why not set up a github branch for this?
>
> That's exactly what I was thinking. It'll make it easier to review as
> well, and for others to contribute without disturbing the main line.

Should I fork cython from github? Is github insync with hg repo? What
is main repo now?

ps: I think we should horry with 1.0 release

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Robert Bradshaw
On Thu, Dec 9, 2010 at 2:10 AM, Stefan Behnel  wrote:
> Robert Bradshaw, 09.12.2010 11:00:
>> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
>>> Vitja Makarov, 08.12.2010 22:45:
 Please review this patch. It's not yet finished, and mostly doesn't work.
 But you can take a look at patch and generated code.
>>>
>>> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
>>> in a new patch when you have it. If you use hg, you can use "hg bundle" to
>>> collect commit series. Don't know about git.
>>>
>>> BTW, why not set up a github branch for this?
>>
>> That's exactly what I was thinking. It'll make it easier to review as
>> well, and for others to contribute without disturbing the main line.
>
> BTW, when this goes in, the next Cython version to release is basically
> 1.0, right? There are some minor Python compatibility issues left, but
> that'll be the last major feature, the way I count it.

This will be the last major feature before 1.0, but I don't know that
the first release this is in should be the 1.0 release.

I also think we should set the compatibility bar a bit higher for 1.0
as well--I want a concrete list of all the differences between Python
X.y and Cython (for un-annotated code) and to be able to say that, if
you don't count on the behavior in this list (e.g. identity vs
equality for floating point literals, maybe stack frames) then you
should be able to compile your code and have it just work, but
hopefully faster. At the very least, until we at least attempt to make
such a list, we won't know where we stand (the regression tests
presumably being somewhat of a starting point, though I'd like to get
all of them passing (unless they deal with implementation
details...)).

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Stefan Behnel
Robert Bradshaw, 09.12.2010 11:00:
> On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel wrote:
>> Vitja Makarov, 08.12.2010 22:45:
>>> Please review this patch. It's not yet finished, and mostly doesn't work.
>>> But you can take a look at patch and generated code.
>>
>> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
>> in a new patch when you have it. If you use hg, you can use "hg bundle" to
>> collect commit series. Don't know about git.
>>
>> BTW, why not set up a github branch for this?
>
> That's exactly what I was thinking. It'll make it easier to review as
> well, and for others to contribute without disturbing the main line.

BTW, when this goes in, the next Cython version to release is basically 
1.0, right? There are some minor Python compatibility issues left, but 
that'll be the last major feature, the way I count it.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Robert Bradshaw
On Thu, Dec 9, 2010 at 1:46 AM, Stefan Behnel  wrote:
> Vitja Makarov, 08.12.2010 22:45:
>> Please review this patch. It's not yet finished, and mostly doesn't work.
>> But you can take a look at patch and generated code.
>
> *Way* cool, thanks! I'll take a close look ASAP. Please feel free to send
> in a new patch when you have it. If you use hg, you can use "hg bundle" to
> collect commit series. Don't know about git.
>
> BTW, why not set up a github branch for this?

That's exactly what I was thinking. It'll make it easier to review as
well, and for others to contribute without disturbing the main line.

>>   - Temps are saved/restored/allocated inside YieldExprNode using
>> helper ClosureTempAllocator
>>   - PyxGenerator methods are defined via declare_var
>
> Should we call that "CyGenerator" ? :)
>
>
>>   - Send,  __next__(), __iter__() are implemented while close(), throw() 
>> aren't
>>   - YieldExprNode doesn't handle exceptions
>
> Ok, sure, that's why close() and throw() don't work yet. I think that's
> fine for now. The first three are the most interesting ones. However,
> adding exception support shouldn't be hard at all, AFAICT, but they may
> benefit from a cdef function for the generator body in order to properly
> pass in the exception propagation trigger.
>
>
>>   - I don't know how to make refnanny work, should refnanny context be
>> stored in closure?
>
> Good call. That's a tricky question.
>
> What about generating a GIVEREF for every Python temp you store in the
> closure, a GOTREF for everything you take back out, and finish/restart the
> refnanny context around the yield?

That's what I would do as well.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-09 Thread Stefan Behnel
Vitja Makarov, 08.12.2010 22:45:
> Please review this patch. It's not yet finished, and mostly doesn't work.
> But you can take a look at patch and generated code.

*Way* cool, thanks! I'll take a close look ASAP. Please feel free to send 
in a new patch when you have it. If you use hg, you can use "hg bundle" to 
collect commit series. Don't know about git.

BTW, why not set up a github branch for this?


>   - Temps are saved/restored/allocated inside YieldExprNode using
> helper ClosureTempAllocator
>   - PyxGenerator methods are defined via declare_var

Should we call that "CyGenerator" ? :)


>   - Send,  __next__(), __iter__() are implemented while close(), throw() 
> aren't
>   - YieldExprNode doesn't handle exceptions

Ok, sure, that's why close() and throw() don't work yet. I think that's 
fine for now. The first three are the most interesting ones. However, 
adding exception support shouldn't be hard at all, AFAICT, but they may 
benefit from a cdef function for the generator body in order to properly 
pass in the exception propagation trigger.


>   - I don't know how to make refnanny work, should refnanny context be
> stored in closure?

Good call. That's a tricky question.

What about generating a GIVEREF for every Python temp you store in the 
closure, a GOTREF for everything you take back out, and finish/restart the 
refnanny context around the yield?


>   - Comprehensions are now handled by OldYieldExprNode

... another one of those bad names. ;)

Any reason you couldn't reuse it for both?

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-08 Thread Vitja Makarov
2010/12/8 Vitja Makarov :
> 2010/12/7 Vitja Makarov :
>> 2010/12/7 Vitja Makarov :
>>> 2010/12/7 Robert Bradshaw :
 First off, great to hear you're working on this. I've wanted to do it
 for a while (well, essentially ever since I got closures done), but
 don't know when I'll find the time.


 On Mon, Dec 6, 2010 at 12:56 AM, Vitja Makarov  
 wrote:

>>> def my_generator_body(closure, value, is_exception):
>>
>> Shouldn't that be a cdef function?
>
> Guess no. It has very special signature and should be used only in
> generator closure.
>
> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
> does this on first run.

 Eventually the argument parsing code should be abstracted out so that
 we don't have this restriction.

>>>       # switch case
>>>       switch (closure.resume_lable):
>>>           case 0:
>>>                  goto parse_arguments;
>>>           case 1:
>>>                  goto resume_from_yield1;
>>>       parse_arguments:
>>>       # function body here
>>
>> Ok, sure, as in the CEP.
>>
>>
>>> About temps:
>>> now temps are allocated in closure using declare_var() and it works 
>>> fine.
>>
>> I think that could seriously slow down things inside of the generator,
>> though. It means that it needs to jump through the closure indirection 
>> for
>> every little value that it keeps around temporarily, including lots of
>> intermediate C results. Also, I would expect that a lot more temps are 
>> used
>> inside of the generator body than what actually needs to be kept alive
>> during yields, so a single yield inside of a lengthy generator body could
>> have a tremendous impact on the overall runtime and closure size.
>>
>> If you only store away the live temp values before a yield, you don't 
>> even
>> need to do any reference counting for them. It's just a quick bunch of C
>> assignments on yield and resume. That's about the smallest impact you 
>> can get.
>>
>> BTW, if you change the object struct of the generator closure anyway, 
>> maybe
>> a dynamically sized PyVarObject would be a way to incorporate the temps?
>>
>>
>
> I don't understand why do you think about performance problems?
>
> It seems to me that if temps are stored in tuple (or another kind of
> object) you have to manully save/restore them, and this code will
> really slow down generator.

 -1 to storing them all in a tuple. That wouldn't handle C values very
 well, for one thing. I wouldn't use arrays though--either declare each
 temp individually or create a custom struct that has the correct slot
 for each temp. Copy to locals on enter, copy out on
 yield/exception/return.

> On the other hand when all temps are declared in closure you just have
> to say "closure->pyx_temp_v1"
>
> Do you think that closure-> will be much slower then stack operations?

 Yes, the performance difference can be dramatic. This is one of the
 reasons good numpy support is tricky to get right--the compiler can
 optimize stuff on the stack like crazy, but the same can't be said of
 indirect references. I'm fine with sticking all temps in the closure
 for now if that gets us up and running faster, and optimizing things
 later.

>>> I'm not sure about manage_ref flag I guess that temps with
>>> manage_ref=False shouldn't be allocated on closure (am I right?)
>>
>> "manage_ref=False" (for a Python object value) just means that the
>> reference is either borrowed or will be stolen at some point. I'm not 
>> sure
>> that stealing the reference may not happen *after* a yield, but I guess
>> that would produce other problems if the reference isn't kept alive in
>> another way. Nothing to worry about now, carefully crafted tests will
>> eventually catch that.
>>
>> In any case, all live temps (Python refs, borrowed refs and C values) may
>> be needed after the yield, so they must *all* end up in the closure.

 And of course we need to make all live reference are properly
 deallocated when the closure is GC'd as well.

 - Robert
 ___
 Cython-dev mailing list
 Cython-dev@codespeak.net
 http://codespeak.net/mailman/listinfo/cython-dev

>>>
>>> YieldExprNode can check what temps are currently used and
>>> save/restore, and declare them on demand in closure.
>>> Sounds not bad too. This is not a problem.
>>>
>>> I created now I create AbstractGeneratorClass and make it base for closure.
>>> I  want to bind tp_iter directly to my C functions, I found this way,
>>> but it's a little bit trickey...
>>>
>>> entry = klass.declare_var('__iter__', PyrexTypes.py_object_type, pos,
>>> visib

Re: [Cython] General generator expressions

2010-12-08 Thread Vitja Makarov
2010/12/7 Vitja Makarov :
> 2010/12/7 Vitja Makarov :
>> 2010/12/7 Robert Bradshaw :
>>> First off, great to hear you're working on this. I've wanted to do it
>>> for a while (well, essentially ever since I got closures done), but
>>> don't know when I'll find the time.
>>>
>>>
>>> On Mon, Dec 6, 2010 at 12:56 AM, Vitja Makarov  
>>> wrote:
>>>
>> def my_generator_body(closure, value, is_exception):
>
> Shouldn't that be a cdef function?

 Guess no. It has very special signature and should be used only in
 generator closure.

 It can't be cdef as cdef doesn't parse (args, kwargs) and generator
 does this on first run.
>>>
>>> Eventually the argument parsing code should be abstracted out so that
>>> we don't have this restriction.
>>>
>>       # switch case
>>       switch (closure.resume_lable):
>>           case 0:
>>                  goto parse_arguments;
>>           case 1:
>>                  goto resume_from_yield1;
>>       parse_arguments:
>>       # function body here
>
> Ok, sure, as in the CEP.
>
>
>> About temps:
>> now temps are allocated in closure using declare_var() and it works fine.
>
> I think that could seriously slow down things inside of the generator,
> though. It means that it needs to jump through the closure indirection for
> every little value that it keeps around temporarily, including lots of
> intermediate C results. Also, I would expect that a lot more temps are 
> used
> inside of the generator body than what actually needs to be kept alive
> during yields, so a single yield inside of a lengthy generator body could
> have a tremendous impact on the overall runtime and closure size.
>
> If you only store away the live temp values before a yield, you don't even
> need to do any reference counting for them. It's just a quick bunch of C
> assignments on yield and resume. That's about the smallest impact you can 
> get.
>
> BTW, if you change the object struct of the generator closure anyway, 
> maybe
> a dynamically sized PyVarObject would be a way to incorporate the temps?
>
>

 I don't understand why do you think about performance problems?

 It seems to me that if temps are stored in tuple (or another kind of
 object) you have to manully save/restore them, and this code will
 really slow down generator.
>>>
>>> -1 to storing them all in a tuple. That wouldn't handle C values very
>>> well, for one thing. I wouldn't use arrays though--either declare each
>>> temp individually or create a custom struct that has the correct slot
>>> for each temp. Copy to locals on enter, copy out on
>>> yield/exception/return.
>>>
 On the other hand when all temps are declared in closure you just have
 to say "closure->pyx_temp_v1"

 Do you think that closure-> will be much slower then stack operations?
>>>
>>> Yes, the performance difference can be dramatic. This is one of the
>>> reasons good numpy support is tricky to get right--the compiler can
>>> optimize stuff on the stack like crazy, but the same can't be said of
>>> indirect references. I'm fine with sticking all temps in the closure
>>> for now if that gets us up and running faster, and optimizing things
>>> later.
>>>
>> I'm not sure about manage_ref flag I guess that temps with
>> manage_ref=False shouldn't be allocated on closure (am I right?)
>
> "manage_ref=False" (for a Python object value) just means that the
> reference is either borrowed or will be stolen at some point. I'm not sure
> that stealing the reference may not happen *after* a yield, but I guess
> that would produce other problems if the reference isn't kept alive in
> another way. Nothing to worry about now, carefully crafted tests will
> eventually catch that.
>
> In any case, all live temps (Python refs, borrowed refs and C values) may
> be needed after the yield, so they must *all* end up in the closure.
>>>
>>> And of course we need to make all live reference are properly
>>> deallocated when the closure is GC'd as well.
>>>
>>> - Robert
>>> ___
>>> Cython-dev mailing list
>>> Cython-dev@codespeak.net
>>> http://codespeak.net/mailman/listinfo/cython-dev
>>>
>>
>> YieldExprNode can check what temps are currently used and
>> save/restore, and declare them on demand in closure.
>> Sounds not bad too. This is not a problem.
>>
>> I created now I create AbstractGeneratorClass and make it base for closure.
>> I  want to bind tp_iter directly to my C functions, I found this way,
>> but it's a little bit trickey...
>>
>> entry = klass.declare_var('__iter__', PyrexTypes.py_object_type, pos,
>> visibility='extern')
>> entry.func_cname = 'PyObject_SelfIter'
>>
>>
>> I'm now stuck with generator body and function that returns genertor:
>>
>> DefNode should be translated into

Re: [Cython] General generator expressions

2010-12-06 Thread Vitja Makarov
2010/12/7 Vitja Makarov :
> 2010/12/7 Robert Bradshaw :
>> First off, great to hear you're working on this. I've wanted to do it
>> for a while (well, essentially ever since I got closures done), but
>> don't know when I'll find the time.
>>
>>
>> On Mon, Dec 6, 2010 at 12:56 AM, Vitja Makarov  
>> wrote:
>>
> def my_generator_body(closure, value, is_exception):

 Shouldn't that be a cdef function?
>>>
>>> Guess no. It has very special signature and should be used only in
>>> generator closure.
>>>
>>> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
>>> does this on first run.
>>
>> Eventually the argument parsing code should be abstracted out so that
>> we don't have this restriction.
>>
>       # switch case
>       switch (closure.resume_lable):
>           case 0:
>                  goto parse_arguments;
>           case 1:
>                  goto resume_from_yield1;
>       parse_arguments:
>       # function body here

 Ok, sure, as in the CEP.


> About temps:
> now temps are allocated in closure using declare_var() and it works fine.

 I think that could seriously slow down things inside of the generator,
 though. It means that it needs to jump through the closure indirection for
 every little value that it keeps around temporarily, including lots of
 intermediate C results. Also, I would expect that a lot more temps are used
 inside of the generator body than what actually needs to be kept alive
 during yields, so a single yield inside of a lengthy generator body could
 have a tremendous impact on the overall runtime and closure size.

 If you only store away the live temp values before a yield, you don't even
 need to do any reference counting for them. It's just a quick bunch of C
 assignments on yield and resume. That's about the smallest impact you can 
 get.

 BTW, if you change the object struct of the generator closure anyway, maybe
 a dynamically sized PyVarObject would be a way to incorporate the temps?


>>>
>>> I don't understand why do you think about performance problems?
>>>
>>> It seems to me that if temps are stored in tuple (or another kind of
>>> object) you have to manully save/restore them, and this code will
>>> really slow down generator.
>>
>> -1 to storing them all in a tuple. That wouldn't handle C values very
>> well, for one thing. I wouldn't use arrays though--either declare each
>> temp individually or create a custom struct that has the correct slot
>> for each temp. Copy to locals on enter, copy out on
>> yield/exception/return.
>>
>>> On the other hand when all temps are declared in closure you just have
>>> to say "closure->pyx_temp_v1"
>>>
>>> Do you think that closure-> will be much slower then stack operations?
>>
>> Yes, the performance difference can be dramatic. This is one of the
>> reasons good numpy support is tricky to get right--the compiler can
>> optimize stuff on the stack like crazy, but the same can't be said of
>> indirect references. I'm fine with sticking all temps in the closure
>> for now if that gets us up and running faster, and optimizing things
>> later.
>>
> I'm not sure about manage_ref flag I guess that temps with
> manage_ref=False shouldn't be allocated on closure (am I right?)

 "manage_ref=False" (for a Python object value) just means that the
 reference is either borrowed or will be stolen at some point. I'm not sure
 that stealing the reference may not happen *after* a yield, but I guess
 that would produce other problems if the reference isn't kept alive in
 another way. Nothing to worry about now, carefully crafted tests will
 eventually catch that.

 In any case, all live temps (Python refs, borrowed refs and C values) may
 be needed after the yield, so they must *all* end up in the closure.
>>
>> And of course we need to make all live reference are properly
>> deallocated when the closure is GC'd as well.
>>
>> - Robert
>> ___
>> Cython-dev mailing list
>> Cython-dev@codespeak.net
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>
> YieldExprNode can check what temps are currently used and
> save/restore, and declare them on demand in closure.
> Sounds not bad too. This is not a problem.
>
> I created now I create AbstractGeneratorClass and make it base for closure.
> I  want to bind tp_iter directly to my C functions, I found this way,
> but it's a little bit trickey...
>
> entry = klass.declare_var('__iter__', PyrexTypes.py_object_type, pos,
> visibility='extern')
> entry.func_cname = 'PyObject_SelfIter'
>
>
> I'm now stuck with generator body and function that returns genertor:
>
> DefNode should be translated into generator body:
>
> first I wanted to make it PyObject (*)(PyObject *closure, PyObject
> *value, int is_exception)
> But it seems to be hard now. And I'm think

Re: [Cython] General generator expressions

2010-12-06 Thread Vitja Makarov
2010/12/7 Robert Bradshaw :
> First off, great to hear you're working on this. I've wanted to do it
> for a while (well, essentially ever since I got closures done), but
> don't know when I'll find the time.
>
>
> On Mon, Dec 6, 2010 at 12:56 AM, Vitja Makarov  
> wrote:
>
 def my_generator_body(closure, value, is_exception):
>>>
>>> Shouldn't that be a cdef function?
>>
>> Guess no. It has very special signature and should be used only in
>> generator closure.
>>
>> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
>> does this on first run.
>
> Eventually the argument parsing code should be abstracted out so that
> we don't have this restriction.
>
       # switch case
       switch (closure.resume_lable):
           case 0:
                  goto parse_arguments;
           case 1:
                  goto resume_from_yield1;
       parse_arguments:
       # function body here
>>>
>>> Ok, sure, as in the CEP.
>>>
>>>
 About temps:
 now temps are allocated in closure using declare_var() and it works fine.
>>>
>>> I think that could seriously slow down things inside of the generator,
>>> though. It means that it needs to jump through the closure indirection for
>>> every little value that it keeps around temporarily, including lots of
>>> intermediate C results. Also, I would expect that a lot more temps are used
>>> inside of the generator body than what actually needs to be kept alive
>>> during yields, so a single yield inside of a lengthy generator body could
>>> have a tremendous impact on the overall runtime and closure size.
>>>
>>> If you only store away the live temp values before a yield, you don't even
>>> need to do any reference counting for them. It's just a quick bunch of C
>>> assignments on yield and resume. That's about the smallest impact you can 
>>> get.
>>>
>>> BTW, if you change the object struct of the generator closure anyway, maybe
>>> a dynamically sized PyVarObject would be a way to incorporate the temps?
>>>
>>>
>>
>> I don't understand why do you think about performance problems?
>>
>> It seems to me that if temps are stored in tuple (or another kind of
>> object) you have to manully save/restore them, and this code will
>> really slow down generator.
>
> -1 to storing them all in a tuple. That wouldn't handle C values very
> well, for one thing. I wouldn't use arrays though--either declare each
> temp individually or create a custom struct that has the correct slot
> for each temp. Copy to locals on enter, copy out on
> yield/exception/return.
>
>> On the other hand when all temps are declared in closure you just have
>> to say "closure->pyx_temp_v1"
>>
>> Do you think that closure-> will be much slower then stack operations?
>
> Yes, the performance difference can be dramatic. This is one of the
> reasons good numpy support is tricky to get right--the compiler can
> optimize stuff on the stack like crazy, but the same can't be said of
> indirect references. I'm fine with sticking all temps in the closure
> for now if that gets us up and running faster, and optimizing things
> later.
>
 I'm not sure about manage_ref flag I guess that temps with
 manage_ref=False shouldn't be allocated on closure (am I right?)
>>>
>>> "manage_ref=False" (for a Python object value) just means that the
>>> reference is either borrowed or will be stolen at some point. I'm not sure
>>> that stealing the reference may not happen *after* a yield, but I guess
>>> that would produce other problems if the reference isn't kept alive in
>>> another way. Nothing to worry about now, carefully crafted tests will
>>> eventually catch that.
>>>
>>> In any case, all live temps (Python refs, borrowed refs and C values) may
>>> be needed after the yield, so they must *all* end up in the closure.
>
> And of course we need to make all live reference are properly
> deallocated when the closure is GC'd as well.
>
> - Robert
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

YieldExprNode can check what temps are currently used and
save/restore, and declare them on demand in closure.
Sounds not bad too. This is not a problem.

I created now I create AbstractGeneratorClass and make it base for closure.
I  want to bind tp_iter directly to my C functions, I found this way,
but it's a little bit trickey...

entry = klass.declare_var('__iter__', PyrexTypes.py_object_type, pos,
visibility='extern')
entry.func_cname = 'PyObject_SelfIter'


I'm now stuck with generator body and function that returns genertor:

DefNode should be translated into generator body:

first I wanted to make it PyObject (*)(PyObject *closure, PyObject
*value, int is_exception)
But it seems to be hard now. And I'm thinking to put value and
is_exception into AbstractGenerator class. And let generator body
C-function accept original PyFunction arguments (PyObject *args,
PyObject *k

Re: [Cython] General generator expressions

2010-12-06 Thread Robert Bradshaw
First off, great to hear you're working on this. I've wanted to do it
for a while (well, essentially ever since I got closures done), but
don't know when I'll find the time.


On Mon, Dec 6, 2010 at 12:56 AM, Vitja Makarov  wrote:

>>> def my_generator_body(closure, value, is_exception):
>>
>> Shouldn't that be a cdef function?
>
> Guess no. It has very special signature and should be used only in
> generator closure.
>
> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
> does this on first run.

Eventually the argument parsing code should be abstracted out so that
we don't have this restriction.

>>>       # switch case
>>>       switch (closure.resume_lable):
>>>           case 0:
>>>                  goto parse_arguments;
>>>           case 1:
>>>                  goto resume_from_yield1;
>>>       parse_arguments:
>>>       # function body here
>>
>> Ok, sure, as in the CEP.
>>
>>
>>> About temps:
>>> now temps are allocated in closure using declare_var() and it works fine.
>>
>> I think that could seriously slow down things inside of the generator,
>> though. It means that it needs to jump through the closure indirection for
>> every little value that it keeps around temporarily, including lots of
>> intermediate C results. Also, I would expect that a lot more temps are used
>> inside of the generator body than what actually needs to be kept alive
>> during yields, so a single yield inside of a lengthy generator body could
>> have a tremendous impact on the overall runtime and closure size.
>>
>> If you only store away the live temp values before a yield, you don't even
>> need to do any reference counting for them. It's just a quick bunch of C
>> assignments on yield and resume. That's about the smallest impact you can 
>> get.
>>
>> BTW, if you change the object struct of the generator closure anyway, maybe
>> a dynamically sized PyVarObject would be a way to incorporate the temps?
>>
>>
>
> I don't understand why do you think about performance problems?
>
> It seems to me that if temps are stored in tuple (or another kind of
> object) you have to manully save/restore them, and this code will
> really slow down generator.

-1 to storing them all in a tuple. That wouldn't handle C values very
well, for one thing. I wouldn't use arrays though--either declare each
temp individually or create a custom struct that has the correct slot
for each temp. Copy to locals on enter, copy out on
yield/exception/return.

> On the other hand when all temps are declared in closure you just have
> to say "closure->pyx_temp_v1"
>
> Do you think that closure-> will be much slower then stack operations?

Yes, the performance difference can be dramatic. This is one of the
reasons good numpy support is tricky to get right--the compiler can
optimize stuff on the stack like crazy, but the same can't be said of
indirect references. I'm fine with sticking all temps in the closure
for now if that gets us up and running faster, and optimizing things
later.

>>> I'm not sure about manage_ref flag I guess that temps with
>>> manage_ref=False shouldn't be allocated on closure (am I right?)
>>
>> "manage_ref=False" (for a Python object value) just means that the
>> reference is either borrowed or will be stolen at some point. I'm not sure
>> that stealing the reference may not happen *after* a yield, but I guess
>> that would produce other problems if the reference isn't kept alive in
>> another way. Nothing to worry about now, carefully crafted tests will
>> eventually catch that.
>>
>> In any case, all live temps (Python refs, borrowed refs and C values) may
>> be needed after the yield, so they must *all* end up in the closure.

And of course we need to make all live reference are properly
deallocated when the closure is GC'd as well.

- Robert
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-06 Thread Stefan Behnel
Stefan Behnel, 06.12.2010 11:35:
> I think it would be best to generate the straight assignment code from
> within of the YieldExprNode:
>
>   closure->place_for_int_temp[0] = __pyx_t_2
>   closure->place_for_int_temp[1] = __pyx_t_5
>   closure->place_for_object_temp[0] = __pyx_t_9
>   return result
>   resume:
>   __pyx_t_2 = closure->place_for_int_temp[0]
>   ...
>
> For starters, I wouldn't mind if the closure fields were all "size_t" and
> the assignments just did an ugly cast on the RHS. Might be easier than
> properly allocating separate arrays of correctly sized fields.

... although, of course, not every C value fits into size_t, either. There 
may be structs being passed around by value, for example. Tricky...

Hmm, maybe it's really ok to start with temps in the closure for now, just 
like we accepted that closures were huge until they were cut down to what 
was actually needed. I think the feature is more important than the 
optimisations around it.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-06 Thread Dag Sverre Seljebotn
On 12/06/2010 11:35 AM, Stefan Behnel wrote:
> Vitja Makarov, 06.12.2010 10:56:
>
>> 2010/12/6 Stefan Behnel:
>>  
>>> Vitja Makarov, 06.12.2010 09:56:
>>>
 2010/12/6 Stefan Behnel:
  
> Vitja Makarov, 05.12.2010 20:12:
>
>> About temps:
>> now temps are allocated in closure using declare_var() and it works fine.
>>  
> I think that could seriously slow down things inside of the generator,
> though. It means that it needs to jump through the closure indirection for
> every little value that it keeps around temporarily, including lots of
> intermediate C results. Also, I would expect that a lot more temps are 
> used
> inside of the generator body than what actually needs to be kept alive
> during yields, so a single yield inside of a lengthy generator body could
> have a tremendous impact on the overall runtime and closure size.
>
> If you only store away the live temp values before a yield, you don't even
> need to do any reference counting for them. It's just a quick bunch of C
> assignments on yield and resume. That's about the smallest impact you can 
> get.
>
> BTW, if you change the object struct of the generator closure anyway, 
> maybe
> a dynamically sized PyVarObject would be a way to incorporate the temps?
>
 I don't understand why do you think about performance problems?

 It seems to me that if temps are stored in tuple (or another kind of
 object) you have to manully save/restore them, and this code will
 really slow down generator.
  
>>> But it only has to be done when suspending/resuming, not every time a temp
>>> is used. Given that there is quite some overhead involved in executing a
>>> yield/resume cycle, it doesn't matter if we add a couple of fast C
>>> assignments to that.
>>>
>>>
 On the other hand when all temps are declared in closure you just have
 to say "closure->pyx_temp_v1"

 Do you think that closure-> will be much slower then stack operations?
  
>>> Yes, *much* slower. Temps are not meant to live on the stack. Most of the
>>> time, they will just live in a CPU register, especially on x86_64 and other
>>> architectures with plenty of registers. When you put them into the closure,
>>> the C compiler must assume that it's an external operation when accessing
>>> them and can't know that the next time it reads the variable it still has
>>> the same value that it just wrote. That's kills tons of possible C
>>> optimisations.
>>>
>> Hmm. It is not really necessery to check each for value each time,
>> it's not defined as volatile.
>>  
> My knowledge of C is admittedly limited. Why should the C compiler be
> allowed to assume that a value stored somewhere in a foreign memory
> location doesn't change its value between separate store and read operations?
>

Unless you call another function, the C compiler will know just from the 
actions of the executing thread. (You can't use a variable/struct field 
to e.g. communicate between threads...unless perhaps if you mark it 
volatile, but one should use locking instead).

But, of course, the closure may well call other functions in libraries 
where the C compiler has no access. So I believe Stefan is right. It 
corresponds to providing hints to the compiler that "no external code 
will modify this memory".

Dag Sverre
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-06 Thread Stefan Behnel
Vitja Makarov, 06.12.2010 10:56:
> 2010/12/6 Stefan Behnel:
>> Vitja Makarov, 06.12.2010 09:56:
>>> 2010/12/6 Stefan Behnel:
 Vitja Makarov, 05.12.2010 20:12:
> About temps:
> now temps are allocated in closure using declare_var() and it works fine.

 I think that could seriously slow down things inside of the generator,
 though. It means that it needs to jump through the closure indirection for
 every little value that it keeps around temporarily, including lots of
 intermediate C results. Also, I would expect that a lot more temps are used
 inside of the generator body than what actually needs to be kept alive
 during yields, so a single yield inside of a lengthy generator body could
 have a tremendous impact on the overall runtime and closure size.

 If you only store away the live temp values before a yield, you don't even
 need to do any reference counting for them. It's just a quick bunch of C
 assignments on yield and resume. That's about the smallest impact you can 
 get.

 BTW, if you change the object struct of the generator closure anyway, maybe
 a dynamically sized PyVarObject would be a way to incorporate the temps?
>>>
>>> I don't understand why do you think about performance problems?
>>>
>>> It seems to me that if temps are stored in tuple (or another kind of
>>> object) you have to manully save/restore them, and this code will
>>> really slow down generator.
>>
>> But it only has to be done when suspending/resuming, not every time a temp
>> is used. Given that there is quite some overhead involved in executing a
>> yield/resume cycle, it doesn't matter if we add a couple of fast C
>> assignments to that.
>>
>>> On the other hand when all temps are declared in closure you just have
>>> to say "closure->pyx_temp_v1"
>>>
>>> Do you think that closure->will be much slower then stack operations?
>>
>> Yes, *much* slower. Temps are not meant to live on the stack. Most of the
>> time, they will just live in a CPU register, especially on x86_64 and other
>> architectures with plenty of registers. When you put them into the closure,
>> the C compiler must assume that it's an external operation when accessing
>> them and can't know that the next time it reads the variable it still has
>> the same value that it just wrote. That's kills tons of possible C
>> optimisations.
>
> Hmm. It is not really necessery to check each for value each time,
> it's not defined as volatile.

My knowledge of C is admittedly limited. Why should the C compiler be 
allowed to assume that a value stored somewhere in a foreign memory 
location doesn't change its value between separate store and read operations?


> Compiler will try to put it in registers and write back when reqired.

The difference is, when it's not in the closure, the function body (or 
current C scope) owns it, so the C compiler doesn't have to generate code 
to write it anywhere in the first place. Most temps are really just there 
for convenience when generating the C code, not because there really is 
something to store away. The C compiler is expected to drop almost all of them.


> Btw it's better to try both ways and choose the fastest one.

I know, predicting performance is hard at best, but in this case, it's 
clear enough to me that letting all temps live in the closure suffers from 
two serious drawbacks: space *and* time.


> How should save/restore code look like?
>
> PyObject *all_temps[NUMBER_OF_PYOBJECT_TEMPS];
>
> // save
> memcpy(closure->all_temps, all_temps, sizeof(all_temps));?
>
> Or:
>
> for (int i=0; i<  NUMBER_OF_PYOBJECT_TEMPS; i++) {
> if (all_temps[i]) {
>   // this will create tuple (n, all_temps[i]) and add it to
> closure->temps_tuple
>   add_temp_to_closure(closure, i, all_temps[i]);
> }
> }
>
> How should it handle native C types?

The CEP has some comments on this.

I think it would be best to generate the straight assignment code from 
within of the YieldExprNode:

 closure->place_for_int_temp[0] = __pyx_t_2
 closure->place_for_int_temp[1] = __pyx_t_5
 closure->place_for_object_temp[0] = __pyx_t_9
 return result
 resume:
 __pyx_t_2 = closure->place_for_int_temp[0]
 ...

For starters, I wouldn't mind if the closure fields were all "size_t" and 
the assignments just did an ugly cast on the RHS. Might be easier than 
properly allocating separate arrays of correctly sized fields.

BTW, I just noticed that this won't work with exception handling yet. In 
try-except and try-finally statements, we keep the current exception state 
in block local variables, those would have to get stored away as well. 
However, the problem is that this can be in nested block scopes, so the 
outer variables may not even be available to the C code. Another thing to 
deal with once this works...

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman

Re: [Cython] General generator expressions

2010-12-06 Thread Vitja Makarov
2010/12/6 Stefan Behnel :
> Vitja Makarov, 06.12.2010 09:56:
>> 2010/12/6 Stefan Behnel:
>>> Vitja Makarov, 05.12.2010 20:12:
 def my_generator(self, args, kwargs):
      closure  = my_generator_closure_new()
      closure.is_running = 0
      closure.resume_label  = 0
      closure.args = args
      closure.kwargs = kwargs
      closure.outer_scope = self
      closure.generator_body = my_generator_body
      return closure

 generator body:

 def my_generator_body(closure, value, is_exception):
>>>
>>> Shouldn't that be a cdef function?
>>
>> Guess no. It has very special signature and should be used only in
>> generator closure.
>>
>> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
>> does this on first run.
>
> Generators, yes. Generator expressions, no. I've written in the CEP that it
> would be nice to start with splitting the way Python functions work. I
> don't ask you to do this (certainly makes a nice optimisation when the
> functionality itself is done), but it would easily enable a cdef function
> here, which would hugely reduce the burden when advancing a generator.
>

Yeah. Splitting would be nice. But I don't know yet how to do it the best way.
So it could wait a little.

>
 About temps:
 now temps are allocated in closure using declare_var() and it works fine.
>>>
>>> I think that could seriously slow down things inside of the generator,
>>> though. It means that it needs to jump through the closure indirection for
>>> every little value that it keeps around temporarily, including lots of
>>> intermediate C results. Also, I would expect that a lot more temps are used
>>> inside of the generator body than what actually needs to be kept alive
>>> during yields, so a single yield inside of a lengthy generator body could
>>> have a tremendous impact on the overall runtime and closure size.
>>>
>>> If you only store away the live temp values before a yield, you don't even
>>> need to do any reference counting for them. It's just a quick bunch of C
>>> assignments on yield and resume. That's about the smallest impact you can 
>>> get.
>>>
>>> BTW, if you change the object struct of the generator closure anyway, maybe
>>> a dynamically sized PyVarObject would be a way to incorporate the temps?
>>
>> I don't understand why do you think about performance problems?
>>
>> It seems to me that if temps are stored in tuple (or another kind of
>> object) you have to manully save/restore them, and this code will
>> really slow down generator.
>
> But it only has to be done when suspending/resuming, not every time a temp
> is used. Given that there is quite some overhead involved in executing a
> yield/resume cycle, it doesn't matter if we add a couple of fast C
> assignments to that.
>
>
>> On the other hand when all temps are declared in closure you just have
>> to say "closure->pyx_temp_v1"
>>
>> Do you think that closure->  will be much slower then stack operations?
>
> Yes, *much* slower. Temps are not meant to live on the stack. Most of the
> time, they will just live in a CPU register, especially on x86_64 and other
> architectures with plenty of registers. When you put them into the closure,
> the C compiler must assume that it's an external operation when accessing
> them and can't know that the next time it reads the variable it still has
> the same value that it just wrote. That's kills tons of possible C
> optimisations.
>
>

Hmm. It is not really necessery to check each for value each time,
it's not defined as volatile.
Compiler will try to put it in registers and write back when reqired.

Btw it's better to try both ways and choose the fastest one.

How should save/restore code look like?

PyObject *all_temps[NUMBER_OF_PYOBJECT_TEMPS];

// save
memcpy(closure->all_temps, all_temps, sizeof(all_temps));?

Or:

for (int i=0; i < NUMBER_OF_PYOBJECT_TEMPS; i++) {
   if (all_temps[i]) {
 // this will create tuple (n, all_temps[i]) and add it to
closure->temps_tuple
 add_temp_to_closure(closure, i, all_temps[i]);
   }
}

How should it  handle native C types?

 struct closure {
       /* abstract_generator */
       PY_OBJECT_HEAD
       /* generator internal vars */
       PyObject *(*body)(struct closure *, PyObject *, int);
       int resume_label;
       
       /* Closure stuff */
 } ;

 and generator utility function will work like this:

 PyObject *abstract_generator_next(PyObject *self, PyObject *args)
 {
       struct abstract_generator *generator = (struct abstract_generator *) 
 self;
       PyObject *retval;
       // check running
       retval =  generator->body(self, None, 0);
       // unlock running
       return retval;
 }

 But this way should be much better, don't know if that is possible btw.

 struct closure {
       struct abstract_generator generator;
       /* closure stuff he

Re: [Cython] General generator expressions

2010-12-06 Thread Stefan Behnel
Vitja Makarov, 06.12.2010 09:56:
> 2010/12/6 Stefan Behnel:
>> Vitja Makarov, 05.12.2010 20:12:
>>> def my_generator(self, args, kwargs):
>>>  closure  = my_generator_closure_new()
>>>  closure.is_running = 0
>>>  closure.resume_label  = 0
>>>  closure.args = args
>>>  closure.kwargs = kwargs
>>>  closure.outer_scope = self
>>>  closure.generator_body = my_generator_body
>>>  return closure
>>>
>>> generator body:
>>>
>>> def my_generator_body(closure, value, is_exception):
>>
>> Shouldn't that be a cdef function?
>
> Guess no. It has very special signature and should be used only in
> generator closure.
>
> It can't be cdef as cdef doesn't parse (args, kwargs) and generator
> does this on first run.

Generators, yes. Generator expressions, no. I've written in the CEP that it 
would be nice to start with splitting the way Python functions work. I 
don't ask you to do this (certainly makes a nice optimisation when the 
functionality itself is done), but it would easily enable a cdef function 
here, which would hugely reduce the burden when advancing a generator.


>>> About temps:
>>> now temps are allocated in closure using declare_var() and it works fine.
>>
>> I think that could seriously slow down things inside of the generator,
>> though. It means that it needs to jump through the closure indirection for
>> every little value that it keeps around temporarily, including lots of
>> intermediate C results. Also, I would expect that a lot more temps are used
>> inside of the generator body than what actually needs to be kept alive
>> during yields, so a single yield inside of a lengthy generator body could
>> have a tremendous impact on the overall runtime and closure size.
>>
>> If you only store away the live temp values before a yield, you don't even
>> need to do any reference counting for them. It's just a quick bunch of C
>> assignments on yield and resume. That's about the smallest impact you can 
>> get.
>>
>> BTW, if you change the object struct of the generator closure anyway, maybe
>> a dynamically sized PyVarObject would be a way to incorporate the temps?
>
> I don't understand why do you think about performance problems?
>
> It seems to me that if temps are stored in tuple (or another kind of
> object) you have to manully save/restore them, and this code will
> really slow down generator.

But it only has to be done when suspending/resuming, not every time a temp 
is used. Given that there is quite some overhead involved in executing a 
yield/resume cycle, it doesn't matter if we add a couple of fast C 
assignments to that.


> On the other hand when all temps are declared in closure you just have
> to say "closure->pyx_temp_v1"
>
> Do you think that closure->  will be much slower then stack operations?

Yes, *much* slower. Temps are not meant to live on the stack. Most of the 
time, they will just live in a CPU register, especially on x86_64 and other 
architectures with plenty of registers. When you put them into the closure, 
the C compiler must assume that it's an external operation when accessing 
them and can't know that the next time it reads the variable it still has 
the same value that it just wrote. That's kills tons of possible C 
optimisations.


>>> struct closure {
>>>   /* abstract_generator */
>>>   PY_OBJECT_HEAD
>>>   /* generator internal vars */
>>>   PyObject *(*body)(struct closure *, PyObject *, int);
>>>   int resume_label;
>>>   
>>>   /* Closure stuff */
>>> } ;
>>>
>>> and generator utility function will work like this:
>>>
>>> PyObject *abstract_generator_next(PyObject *self, PyObject *args)
>>> {
>>>   struct abstract_generator *generator = (struct abstract_generator *) 
>>> self;
>>>   PyObject *retval;
>>>   // check running
>>>   retval =  generator->body(self, None, 0);
>>>   // unlock running
>>>   return retval;
>>> }
>>>
>>> But this way should be much better, don't know if that is possible btw.
>>>
>>> struct closure {
>>>   struct abstract_generator generator;
>>>   /* closure stuff here */
>>>   ...
>>> } ;
>>
>> That's called inheritance in Cython. Just declare a subtype of the specific
>> closure class.
>
> That's not inheritance exactly I don't want to call all cython&
> python stuff for base class (why not btw?)

Right, why not? Closures are instantiated by calling tp_new() directly, so 
even the overhead of creating them as a subtype is pretty low. Plus, it 
only has to be done once when instantiating the generator, not every time 
it advances. So I consider it totally negligible over the overall lifetime.


> Just want to have some fields (now I think that is_running and body is
> enough) on top of closure stuff, and I don't want to declare things
> twice.

Then inheritance is your friend. It will create a vtable, though, if you 
use methods.


>>> I add MarkGenerator visitor, that sets is_generator flag on DefNode
>>> and checks for returns/yields.

Re: [Cython] General generator expressions

2010-12-06 Thread Vitja Makarov
2010/12/6 Stefan Behnel :
> Vitja Makarov, 05.12.2010 20:12:
>> I've started woring on generators on friday.
>
> Cool. This sounds like a larger code change, though. Try not to submit it
> as a single patch as that would likely be hard to review. Instead, put up a
> repo somewhere that others can look at, or submit bundles (as hg calls
> them) of separate commits.
>
>

Ok, I'll try :)


>> Now it can generate some code, but it doesn't work yet, what is done:
>>   - switch() for resuming and argument parsing
>>   - yield stuff
>>   - closure temp allocation
>>
>> I'm going to put all the generator stuff into closure
>>
>> Generator function:
>>
>> Creates closure with all temps, args, variables, and all the internal stuff:
>> Also closure have all the required generator methods __iter__(),
>> __nextiter__() and so on.
>
> Ok, why not.
>
>
>> def my_generator(self, args, kwargs):
>>     closure  = my_generator_closure_new()
>>     closure.is_running = 0
>>     closure.resume_label  = 0
>>     closure.args = args
>>     closure.kwargs = kwargs
>>     closure.outer_scope = self
>>     closure.generator_body = my_generator_body
>>     return closure
>>
>> generator body:
>>
>> def my_generator_body(closure, value, is_exception):
>
> Shouldn't that be a cdef function?

Guess no. It has very special signature and should be used only in
generator closure.

It can't be cdef as cdef doesn't parse (args, kwargs) and generator
does this on first run.

>
>
>>       # switch case
>>       switch (closure.resume_lable):
>>           case 0:
>>                  goto parse_arguments;
>>           case 1:
>>                  goto resume_from_yield1;
>>       parse_arguments:
>>       # function body here
>
> Ok, sure, as in the CEP.
>
>
>> About temps:
>> now temps are allocated in closure using declare_var() and it works fine.
>
> I think that could seriously slow down things inside of the generator,
> though. It means that it needs to jump through the closure indirection for
> every little value that it keeps around temporarily, including lots of
> intermediate C results. Also, I would expect that a lot more temps are used
> inside of the generator body than what actually needs to be kept alive
> during yields, so a single yield inside of a lengthy generator body could
> have a tremendous impact on the overall runtime and closure size.
>
> If you only store away the live temp values before a yield, you don't even
> need to do any reference counting for them. It's just a quick bunch of C
> assignments on yield and resume. That's about the smallest impact you can get.
>
> BTW, if you change the object struct of the generator closure anyway, maybe
> a dynamically sized PyVarObject would be a way to incorporate the temps?
>
>

I don't understand why do you think about performance problems?

It seems to me that if temps are stored in tuple (or another kind of
object) you have to manully save/restore them, and this code will
really slow down generator.

On the other hand when all temps are declared in closure you just have
to say "closure->pyx_temp_v1"

Do you think that closure-> will be much slower then stack operations?

>> I'm not sure about manage_ref flag I guess that temps with
>> manage_ref=False shouldn't be allocated on closure (am I right?)
>
> "manage_ref=False" (for a Python object value) just means that the
> reference is either borrowed or will be stolen at some point. I'm not sure
> that stealing the reference may not happen *after* a yield, but I guess
> that would produce other problems if the reference isn't kept alive in
> another way. Nothing to worry about now, carefully crafted tests will
> eventually catch that.
>
> In any case, all live temps (Python refs, borrowed refs and C values) may
> be needed after the yield, so they must *all* end up in the closure.
>
>
>> TODO:
>>   - create C function that returns closure
>>   - generator utility code
>
> At least for generator expressions, the latter wouldn't be needed for now.
>
>
>> I have problem with closures and generators.
>>
>> Now I want to implement closure structure this way:
>> struct abstract_generator {
>>      PY_OBJECT_HEAD
>>      /* generator internal vars */
>>      PyObject *(*body)(struct closure *, PyObject *, int);
>>      int resume_label;
>> }
>
> I hope you're not trying to do it manually at that level, are you?
> Declaring the fields on the closure class should just work.
>

No, I declare things using scope_class.declare_var ;)

>
>> struct closure {
>>      /* abstract_generator */
>>      PY_OBJECT_HEAD
>>      /* generator internal vars */
>>      PyObject *(*body)(struct closure *, PyObject *, int);
>>      int resume_label;
>>      
>>      /* Closure stuff */
>> } ;
>>
>> and generator utility function will work like this:
>>
>> PyObject *abstract_generator_next(PyObject *self, PyObject *args)
>> {
>>      struct abstract_generator *generator = (struct abstract_generator *) 
>> self;
>>      PyObject *retval;
>>      // che

Re: [Cython] General generator expressions

2010-12-05 Thread Stefan Behnel
Stefan Behnel, 06.12.2010 08:33:
> Vitja Makarov, 05.12.2010 20:12:
>> I have problem with closures and generators.
>>
>> Now I want to implement closure structure this way:
>> struct abstract_generator {
>>   PY_OBJECT_HEAD
>>   /* generator internal vars */
>>   PyObject *(*body)(struct closure *, PyObject *, int);
>>   int resume_label;
>> }
>
> I hope you're not trying to do it manually at that level, are you?
> Declaring the fields on the closure class should just work.
>
>
>> struct closure {
>>   /* abstract_generator */
>>   PY_OBJECT_HEAD
>>   /* generator internal vars */
>>   PyObject *(*body)(struct closure *, PyObject *, int);
>>   int resume_label;
>>   
>>   /* Closure stuff */
>> } ;
>>
>> and generator utility function will work like this:
>>
>> PyObject *abstract_generator_next(PyObject *self, PyObject *args)
>> {
>>   struct abstract_generator *generator = (struct abstract_generator *) 
>> self;
>>   PyObject *retval;
>>   // check running
>>   retval =  generator->body(self, None, 0);
>>   // unlock running
>>   return retval;
>> }
>>
>> But this way should be much better, don't know if that is possible btw.
>>
>> struct closure {
>>   struct abstract_generator generator;
>>   /* closure stuff here */
>>   ...
>> } ;
>
> That's called inheritance in Cython. Just declare a subtype of the specific
> closure class.

Erm, sorry, the other way round. Yes, I think it's a good idea to let the 
closure class inherit from the abstract generator.

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-05 Thread Stefan Behnel
Vitja Makarov, 05.12.2010 20:12:
> I've started woring on generators on friday.

Cool. This sounds like a larger code change, though. Try not to submit it 
as a single patch as that would likely be hard to review. Instead, put up a 
repo somewhere that others can look at, or submit bundles (as hg calls 
them) of separate commits.


> Now it can generate some code, but it doesn't work yet, what is done:
>   - switch() for resuming and argument parsing
>   - yield stuff
>   - closure temp allocation
>
> I'm going to put all the generator stuff into closure
>
> Generator function:
>
> Creates closure with all temps, args, variables, and all the internal stuff:
> Also closure have all the required generator methods __iter__(),
> __nextiter__() and so on.

Ok, why not.


> def my_generator(self, args, kwargs):
> closure  = my_generator_closure_new()
> closure.is_running = 0
> closure.resume_label  = 0
> closure.args = args
> closure.kwargs = kwargs
> closure.outer_scope = self
> closure.generator_body = my_generator_body
> return closure
>
> generator body:
>
> def my_generator_body(closure, value, is_exception):

Shouldn't that be a cdef function?


>   # switch case
>   switch (closure.resume_lable):
>   case 0:
>  goto parse_arguments;
>   case 1:
>  goto resume_from_yield1;
>   parse_arguments:
>   # function body here

Ok, sure, as in the CEP.


> About temps:
> now temps are allocated in closure using declare_var() and it works fine.

I think that could seriously slow down things inside of the generator, 
though. It means that it needs to jump through the closure indirection for 
every little value that it keeps around temporarily, including lots of 
intermediate C results. Also, I would expect that a lot more temps are used 
inside of the generator body than what actually needs to be kept alive 
during yields, so a single yield inside of a lengthy generator body could 
have a tremendous impact on the overall runtime and closure size.

If you only store away the live temp values before a yield, you don't even 
need to do any reference counting for them. It's just a quick bunch of C 
assignments on yield and resume. That's about the smallest impact you can get.

BTW, if you change the object struct of the generator closure anyway, maybe 
a dynamically sized PyVarObject would be a way to incorporate the temps?


> I'm not sure about manage_ref flag I guess that temps with
> manage_ref=False shouldn't be allocated on closure (am I right?)

"manage_ref=False" (for a Python object value) just means that the 
reference is either borrowed or will be stolen at some point. I'm not sure 
that stealing the reference may not happen *after* a yield, but I guess 
that would produce other problems if the reference isn't kept alive in 
another way. Nothing to worry about now, carefully crafted tests will 
eventually catch that.

In any case, all live temps (Python refs, borrowed refs and C values) may 
be needed after the yield, so they must *all* end up in the closure.


> TODO:
>   - create C function that returns closure
>   - generator utility code

At least for generator expressions, the latter wouldn't be needed for now.


> I have problem with closures and generators.
>
> Now I want to implement closure structure this way:
> struct abstract_generator {
>  PY_OBJECT_HEAD
>  /* generator internal vars */
>  PyObject *(*body)(struct closure *, PyObject *, int);
>  int resume_label;
> }

I hope you're not trying to do it manually at that level, are you? 
Declaring the fields on the closure class should just work.


> struct closure {
>  /* abstract_generator */
>  PY_OBJECT_HEAD
>  /* generator internal vars */
>  PyObject *(*body)(struct closure *, PyObject *, int);
>  int resume_label;
>  
>  /* Closure stuff */
> } ;
>
> and generator utility function will work like this:
>
> PyObject *abstract_generator_next(PyObject *self, PyObject *args)
> {
>  struct abstract_generator *generator = (struct abstract_generator *) 
> self;
>  PyObject *retval;
>  // check running
>  retval =  generator->body(self, None, 0);
>  // unlock running
>  return retval;
> }
>
> But this way should be much better, don't know if that is possible btw.
>
> struct closure {
>  struct abstract_generator generator;
>  /* closure stuff here */
>  ...
> } ;

That's called inheritance in Cython. Just declare a subtype of the specific 
closure class.


> I add MarkGenerator visitor, that sets is_generator flag on DefNode
> and checks for returns/yields.

Why do you need a new class here? Can't the MarkClosureVisitor handle this? 
It's not like transform runs over the whole AST come for free...

Stefan
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev


Re: [Cython] General generator expressions

2010-12-05 Thread Vitja Makarov
2010/12/5 Stefan Behnel :
> Hi,
>
> I just noticed that Vitja's closure refactoring brought us closer to
> supporting generator expressions (before supporting generators and
> coroutines). Here's what's missing:
>
> 1) transform a GeneratorExpressionNode into a DefNode or a subclass
> (obviously excluding inlined generator expressions)
>
> 2) generate the resume code at the start of the function body
>
> 3) store temps in closures. For simplicity, this can be done with a tuple
> (which supports NULL values to a certain extent). That way, we do not need
> to declare each temp separately as a closure field. The remaining tricky
> bit is then to figure out the maximum number of temps that are alive at a
> YieldExprNode (ok, that's actually easy) and to pass that number on to the
> closure class that needs to allocate a sufficiently large tuple.
>
> That doesn't sound too hard.
>
> The generators CEP has the details for each step.
>
> http://wiki.cython.org/enhancements/generators
>
> Going for generator expressions before implementing generators has the
> advantage that it gives us most of the infrastructure without requiring the
> additional steps of passing initial arguments into the generator and
> implementing the complete coroutine protocol (the yield nodes cannot return
> values, for example).
>
> Anyone with a little time to spare?
>
> Stefan
> ___
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
>

Hi!

I've started woring on generators on friday.

Now it can generate some code, but it doesn't work yet, what is done:
 - switch() for resuming and argument parsing
 - yield stuff
 - closure temp allocation

I'm going to put all the generator stuff into closure

Generator function:

Creates closure with all temps, args, variables, and all the internal stuff:
Also closure have all the required generator methods __iter__(),
__nextiter__() and so on.

def my_generator(self, args, kwargs):
   closure  = my_generator_closure_new()
   closure.is_running = 0
   closure.resume_label  = 0
   closure.args = args
   closure.kwargs = kwargs
   closure.outer_scope = self
   closure.generator_body = my_generator_body
   return closure

generator body:

def my_generator_body(closure, value, is_exception):
 # switch case
 switch (closure.resume_lable):
 case 0:
goto parse_arguments;
 case 1:
goto resume_from_yield1;
 parse_arguments:
 # function body here

About temps:

now temps are allocated in closure using declare_var() and it works fine.
I'm not sure about manage_ref flag I guess that temps with
manage_ref=False shouldn't be allocated on closure (am I right?)

I'm not sure that tuple should be better for temps.

TODO:
 - create C function that returns closure
 - generator utility code

I have problem with closures and generators.

Now I want to implement closure structure this way:
struct abstract_generator {
PY_OBJECT_HEAD
/* generator internal vars */
PyObject *(*body)(struct closure *, PyObject *, int);
int resume_label;
}

struct closure {
/* abstract_generator */
PY_OBJECT_HEAD
/* generator internal vars */
PyObject *(*body)(struct closure *, PyObject *, int);
int resume_label;

/* Closure stuff */
} ;

and generator utility function will work like this:

PyObject *abstract_generator_next(PyObject *self, PyObject *args)
{
struct abstract_generator *generator = (struct abstract_generator *) self;
PyObject *retval;
// check running
retval =  generator->body(self, None, 0);
// unlock running
return retval;
}

But this way should be much better, don't know if that is possible btw.

struct closure {
struct abstract_generator generator;
/* closure stuff here */
...
} ;

I add MarkGenerator visitor, that sets is_generator flag on DefNode
and checks for returns/yields.
Then CreateClosureClasses will create correct closure class for generator.

-- 
vitja.
___
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev