Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread Dag Sverre Seljebotn

On 02/03/2012 12:09 AM, mark florisson wrote:

On 2 February 2012 21:38, Dag Sverre Seljebotn
  wrote:

On 02/02/2012 10:16 PM, mark florisson wrote:


On 2 February 2012 12:19, Dag Sverre Seljebotn
wrote:


I just realized that

cdef int[:] a = None

raises an exception; even though I'd argue that 'a' is of the "reference"
kind of type where Cython usually allow None (i.e., "cdef MyClass b =
None"
is allowed even if type(None) is NoneType). Is this a bug or not, and is
it
possible to do something about it?

Dag Sverre
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel



Yeah I disabled that quite early. It was supposed to be working but
gave a lot of trouble in cases (segfaults, mainly). At the time I was
trying to get rid of all the segfaults and get the basic functionality
working, so I disabled it. Personally, I have never liked how things



Well, you can segfault quite easily with

cdef MyClass a = None
print a.field

so it doesn't make sense to slices different from cdef classes IMO.



can be None unchecked. I personally prefer to write

cdef foo(obj=None):
 cdef int[:] a
 if obj is None:
 obj = ...
 a = obj

Often you forget to write 'not None' when declaring the parameter (and
apparently that it only allowed for 'def' functions).

As such, I never bothered to re-enable it. However, it does support
control flow with uninitialized slices, and will raise an error if it
is uninitialized. Do we want this behaviour (e.g. for consistency)?



When in doubt, go for consistency. So +1 for that reason. I do believe that
setting stuff to None is rather vital in Python.

What I typically do is more like this:

def f(double[:] input, double[:] out=None):
if out is None:
out = np.empty_like(input)
...

Having to use another variable name is a bit of a pain. (Come on -- do you
use "a" in real code? What do you actually call "the other obj"? I sometimes
end up with "out_" and so on, but it creates smelly code quite quickly.)


No, it was just a contrived example.


It's easy to segfault with cdef classes anyway, so decent nonechecking
should be implemented at some point, and then memoryviews would use the same
mechanisms. Java has decent null-checking...



The problem with none checking is that it has to occur at every point.


Well, using control flow analysis etc. it doesn't really. E.g.,

for i in range(a.shape[0]):
print i
a[i] *= 3

can be unrolled and none-checks inserted as

print 0
if a is None: raise 
a[0] *= 3
for i in range(1, a.shape[0]):
print i
a[i] *= 3 # no need for none-check

It's very similar to what you'd want to do to pull boundschecking out of 
the loop...



With initialized slices the control flow knows when the slices are
initialized, or when they might not be (and it can raise a
compile-time or runtime error, instead of a segfault if you're lucky).
I'm fine with implementing the behaviour, I just always left it at the
bottom of my todo list.


Wasn't saying you should do it, just checking.

I'm still not sure about this. I think what I'd really like is

 a) Stop cdef classes from being None as well

 b) Sort-of deprecate cdef in favor of cast/assertion type statements 
that help the type inferences:


def f(arr):
if arr is None:
arr = ...
arr = int[:](arr) # equivalent to "cdef int[:] arr = arr", but
  # acts as statement, with a specific point
  # for the none-check
...

or even:

def f(arr):
if arr is None:
return 'foo'
else:
arr = int[:](arr) # takes effect *here*, does none-check
...
# arr still typed as int[:] here

If we can make this work well enough with control flow analysis I'd 
never cdef declare local vars again :-)


Dag
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread Dag Sverre Seljebotn

On 02/03/2012 06:53 PM, Dag Sverre Seljebotn wrote:

On 02/03/2012 12:09 AM, mark florisson wrote:

On 2 February 2012 21:38, Dag Sverre Seljebotn
 wrote:

On 02/02/2012 10:16 PM, mark florisson wrote:


On 2 February 2012 12:19, Dag Sverre Seljebotn
 wrote:


I just realized that

cdef int[:] a = None

raises an exception; even though I'd argue that 'a' is of the
"reference"
kind of type where Cython usually allow None (i.e., "cdef MyClass b =
None"
is allowed even if type(None) is NoneType). Is this a bug or not,
and is
it
possible to do something about it?

Dag Sverre
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel



Yeah I disabled that quite early. It was supposed to be working but
gave a lot of trouble in cases (segfaults, mainly). At the time I was
trying to get rid of all the segfaults and get the basic functionality
working, so I disabled it. Personally, I have never liked how things



Well, you can segfault quite easily with

cdef MyClass a = None
print a.field

so it doesn't make sense to slices different from cdef classes IMO.



can be None unchecked. I personally prefer to write

cdef foo(obj=None):
cdef int[:] a
if obj is None:
obj = ...
a = obj

Often you forget to write 'not None' when declaring the parameter (and
apparently that it only allowed for 'def' functions).

As such, I never bothered to re-enable it. However, it does support
control flow with uninitialized slices, and will raise an error if it
is uninitialized. Do we want this behaviour (e.g. for consistency)?



When in doubt, go for consistency. So +1 for that reason. I do
believe that
setting stuff to None is rather vital in Python.

What I typically do is more like this:

def f(double[:] input, double[:] out=None):
if out is None:
out = np.empty_like(input)
...

Having to use another variable name is a bit of a pain. (Come on --
do you
use "a" in real code? What do you actually call "the other obj"? I
sometimes
end up with "out_" and so on, but it creates smelly code quite quickly.)


No, it was just a contrived example.


It's easy to segfault with cdef classes anyway, so decent nonechecking
should be implemented at some point, and then memoryviews would use
the same
mechanisms. Java has decent null-checking...



The problem with none checking is that it has to occur at every point.


Well, using control flow analysis etc. it doesn't really. E.g.,

for i in range(a.shape[0]):
print i
a[i] *= 3

can be unrolled and none-checks inserted as

print 0
if a is None: raise 
a[0] *= 3
for i in range(1, a.shape[0]):
print i
a[i] *= 3 # no need for none-check

It's very similar to what you'd want to do to pull boundschecking out of
the loop...


With initialized slices the control flow knows when the slices are
initialized, or when they might not be (and it can raise a
compile-time or runtime error, instead of a segfault if you're lucky).
I'm fine with implementing the behaviour, I just always left it at the
bottom of my todo list.


Wasn't saying you should do it, just checking.

I'm still not sure about this. I think what I'd really like is

a) Stop cdef classes from being None as well


I'm sorry, this was out of place and hardly constructive. I beg you all 
to ignore the above sentence.


The below proposal still works for slices only though, which we can 
still define the semantics for. I rather like it. Is type-inference + 
control flow analysis powerful enough to pull this off with some minor 
changes?




b) Sort-of deprecate cdef in favor of cast/assertion type statements
that help the type inferences:

def f(arr):
if arr is None:
arr = ...
arr = int[:](arr) # equivalent to "cdef int[:] arr = arr", but
# acts as statement, with a specific point
# for the none-check
...

or even:

def f(arr):
if arr is None:
return 'foo'
else:
arr = int[:](arr) # takes effect *here*, does none-check
...
# arr still typed as int[:] here

If we can make this work well enough with control flow analysis I'd
never cdef declare local vars again :-)



Dag
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread mark florisson
On 3 February 2012 17:53, Dag Sverre Seljebotn
 wrote:
> On 02/03/2012 12:09 AM, mark florisson wrote:
>>
>> On 2 February 2012 21:38, Dag Sverre Seljebotn
>>   wrote:
>>>
>>> On 02/02/2012 10:16 PM, mark florisson wrote:


 On 2 February 2012 12:19, Dag Sverre Seljebotn
     wrote:
>
>
> I just realized that
>
> cdef int[:] a = None
>
> raises an exception; even though I'd argue that 'a' is of the
> "reference"
> kind of type where Cython usually allow None (i.e., "cdef MyClass b =
> None"
> is allowed even if type(None) is NoneType). Is this a bug or not, and
> is
> it
> possible to do something about it?
>
> Dag Sverre
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel



 Yeah I disabled that quite early. It was supposed to be working but
 gave a lot of trouble in cases (segfaults, mainly). At the time I was
 trying to get rid of all the segfaults and get the basic functionality
 working, so I disabled it. Personally, I have never liked how things
>>>
>>>
>>>
>>> Well, you can segfault quite easily with
>>>
>>> cdef MyClass a = None
>>> print a.field
>>>
>>> so it doesn't make sense to slices different from cdef classes IMO.
>>>
>>>
 can be None unchecked. I personally prefer to write

 cdef foo(obj=None):
     cdef int[:] a
     if obj is None:
         obj = ...
     a = obj

 Often you forget to write 'not None' when declaring the parameter (and
 apparently that it only allowed for 'def' functions).

 As such, I never bothered to re-enable it. However, it does support
 control flow with uninitialized slices, and will raise an error if it
 is uninitialized. Do we want this behaviour (e.g. for consistency)?
>>>
>>>
>>>
>>> When in doubt, go for consistency. So +1 for that reason. I do believe
>>> that
>>> setting stuff to None is rather vital in Python.
>>>
>>> What I typically do is more like this:
>>>
>>> def f(double[:] input, double[:] out=None):
>>>    if out is None:
>>>        out = np.empty_like(input)
>>>    ...
>>>
>>> Having to use another variable name is a bit of a pain. (Come on -- do
>>> you
>>> use "a" in real code? What do you actually call "the other obj"? I
>>> sometimes
>>> end up with "out_" and so on, but it creates smelly code quite quickly.)
>>
>>
>> No, it was just a contrived example.
>>
>>> It's easy to segfault with cdef classes anyway, so decent nonechecking
>>> should be implemented at some point, and then memoryviews would use the
>>> same
>>> mechanisms. Java has decent null-checking...
>>>
>>
>> The problem with none checking is that it has to occur at every point.
>
>
> Well, using control flow analysis etc. it doesn't really. E.g.,
>
> for i in range(a.shape[0]):
>    print i
>    a[i] *= 3
>
> can be unrolled and none-checks inserted as
>
> print 0
> if a is None: raise 
> a[0] *= 3
> for i in range(1, a.shape[0]):
>    print i
>    a[i] *= 3 # no need for none-check
>
> It's very similar to what you'd want to do to pull boundschecking out of the
> loop...
>

Oh, definitely. Both optimizations may not always be possible to do,
though. The optimization (for boundschecking) is easier for prange()
than range(), as you can immediately raise an exception as the
exceptional condition may be issued at any iteration.  What do you do
with bounds checking when some accesses are in-bound, and some are
out-of-bound? Do you immediately raise the exception? Are we fine with
aborting (like Fortran compilers do when you ask them for bounds
checking)? And how do you detect that the code doesn't already raise
an exception or break out of the loop itself to prevent the
out-of-bound access? (Unless no exceptions are propagating and no
break/return is used, but exceptions are so very common).

>> With initialized slices the control flow knows when the slices are
>> initialized, or when they might not be (and it can raise a
>> compile-time or runtime error, instead of a segfault if you're lucky).
>> I'm fine with implementing the behaviour, I just always left it at the
>> bottom of my todo list.
>
>
> Wasn't saying you should do it, just checking.
>
> I'm still not sure about this. I think what I'd really like is
>
>  a) Stop cdef classes from being None as well
>
>  b) Sort-of deprecate cdef in favor of cast/assertion type statements that
> help the type inferences:
>
> def f(arr):
>    if arr is None:
>        arr = ...
>    arr = int[:](arr) # equivalent to "cdef int[:] arr = arr", but
>                      # acts as statement, with a specific point
>                      # for the none-check
>    ...
>
> or even:
>
> def f(arr):
>    if arr is None:
>        return 'foo'
>    else:
>        arr = int[:](arr) # takes effect *here*, does none-check
>        ...
>    # arr still typed as int[:] here

Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread mark florisson
On 3 February 2012 18:06, mark florisson  wrote:
> On 3 February 2012 17:53, Dag Sverre Seljebotn
>  wrote:
>> On 02/03/2012 12:09 AM, mark florisson wrote:
>>>
>>> On 2 February 2012 21:38, Dag Sverre Seljebotn
>>>   wrote:

 On 02/02/2012 10:16 PM, mark florisson wrote:
>
>
> On 2 February 2012 12:19, Dag Sverre Seljebotn
>     wrote:
>>
>>
>> I just realized that
>>
>> cdef int[:] a = None
>>
>> raises an exception; even though I'd argue that 'a' is of the
>> "reference"
>> kind of type where Cython usually allow None (i.e., "cdef MyClass b =
>> None"
>> is allowed even if type(None) is NoneType). Is this a bug or not, and
>> is
>> it
>> possible to do something about it?
>>
>> Dag Sverre
>> ___
>> cython-devel mailing list
>> cython-devel@python.org
>> http://mail.python.org/mailman/listinfo/cython-devel
>
>
>
> Yeah I disabled that quite early. It was supposed to be working but
> gave a lot of trouble in cases (segfaults, mainly). At the time I was
> trying to get rid of all the segfaults and get the basic functionality
> working, so I disabled it. Personally, I have never liked how things



 Well, you can segfault quite easily with

 cdef MyClass a = None
 print a.field

 so it doesn't make sense to slices different from cdef classes IMO.


> can be None unchecked. I personally prefer to write
>
> cdef foo(obj=None):
>     cdef int[:] a
>     if obj is None:
>         obj = ...
>     a = obj
>
> Often you forget to write 'not None' when declaring the parameter (and
> apparently that it only allowed for 'def' functions).
>
> As such, I never bothered to re-enable it. However, it does support
> control flow with uninitialized slices, and will raise an error if it
> is uninitialized. Do we want this behaviour (e.g. for consistency)?



 When in doubt, go for consistency. So +1 for that reason. I do believe
 that
 setting stuff to None is rather vital in Python.

 What I typically do is more like this:

 def f(double[:] input, double[:] out=None):
    if out is None:
        out = np.empty_like(input)
    ...

 Having to use another variable name is a bit of a pain. (Come on -- do
 you
 use "a" in real code? What do you actually call "the other obj"? I
 sometimes
 end up with "out_" and so on, but it creates smelly code quite quickly.)
>>>
>>>
>>> No, it was just a contrived example.
>>>
 It's easy to segfault with cdef classes anyway, so decent nonechecking
 should be implemented at some point, and then memoryviews would use the
 same
 mechanisms. Java has decent null-checking...

>>>
>>> The problem with none checking is that it has to occur at every point.
>>
>>
>> Well, using control flow analysis etc. it doesn't really. E.g.,
>>
>> for i in range(a.shape[0]):
>>    print i
>>    a[i] *= 3
>>
>> can be unrolled and none-checks inserted as
>>
>> print 0
>> if a is None: raise 
>> a[0] *= 3
>> for i in range(1, a.shape[0]):
>>    print i
>>    a[i] *= 3 # no need for none-check
>>
>> It's very similar to what you'd want to do to pull boundschecking out of the
>> loop...
>>
>
> Oh, definitely. Both optimizations may not always be possible to do,
> though. The optimization (for boundschecking) is easier for prange()
> than range(), as you can immediately raise an exception as the
> exceptional condition may be issued at any iteration.  What do you do
> with bounds checking when some accesses are in-bound, and some are
> out-of-bound? Do you immediately raise the exception? Are we fine with
> aborting (like Fortran compilers do when you ask them for bounds
> checking)? And how do you detect that the code doesn't already raise
> an exception or break out of the loop itself to prevent the
> out-of-bound access? (Unless no exceptions are propagating and no
> break/return is used, but exceptions are so very common).
>
>>> With initialized slices the control flow knows when the slices are
>>> initialized, or when they might not be (and it can raise a
>>> compile-time or runtime error, instead of a segfault if you're lucky).
>>> I'm fine with implementing the behaviour, I just always left it at the
>>> bottom of my todo list.
>>
>>
>> Wasn't saying you should do it, just checking.
>>
>> I'm still not sure about this. I think what I'd really like is
>>
>>  a) Stop cdef classes from being None as well
>>
>>  b) Sort-of deprecate cdef in favor of cast/assertion type statements that
>> help the type inferences:
>>
>> def f(arr):
>>    if arr is None:
>>        arr = ...
>>    arr = int[:](arr) # equivalent to "cdef int[:] arr = arr", but
>>                      # acts as statement, with a specific point
>>                      # for the none-che

Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread mark florisson
On 3 February 2012 18:07, mark florisson  wrote:
> On 3 February 2012 18:06, mark florisson  wrote:
>> On 3 February 2012 17:53, Dag Sverre Seljebotn
>>  wrote:
>>> On 02/03/2012 12:09 AM, mark florisson wrote:

 On 2 February 2012 21:38, Dag Sverre Seljebotn
   wrote:
>
> On 02/02/2012 10:16 PM, mark florisson wrote:
>>
>>
>> On 2 February 2012 12:19, Dag Sverre Seljebotn
>>     wrote:
>>>
>>>
>>> I just realized that
>>>
>>> cdef int[:] a = None
>>>
>>> raises an exception; even though I'd argue that 'a' is of the
>>> "reference"
>>> kind of type where Cython usually allow None (i.e., "cdef MyClass b =
>>> None"
>>> is allowed even if type(None) is NoneType). Is this a bug or not, and
>>> is
>>> it
>>> possible to do something about it?
>>>
>>> Dag Sverre
>>> ___
>>> cython-devel mailing list
>>> cython-devel@python.org
>>> http://mail.python.org/mailman/listinfo/cython-devel
>>
>>
>>
>> Yeah I disabled that quite early. It was supposed to be working but
>> gave a lot of trouble in cases (segfaults, mainly). At the time I was
>> trying to get rid of all the segfaults and get the basic functionality
>> working, so I disabled it. Personally, I have never liked how things
>
>
>
> Well, you can segfault quite easily with
>
> cdef MyClass a = None
> print a.field
>
> so it doesn't make sense to slices different from cdef classes IMO.
>
>
>> can be None unchecked. I personally prefer to write
>>
>> cdef foo(obj=None):
>>     cdef int[:] a
>>     if obj is None:
>>         obj = ...
>>     a = obj
>>
>> Often you forget to write 'not None' when declaring the parameter (and
>> apparently that it only allowed for 'def' functions).
>>
>> As such, I never bothered to re-enable it. However, it does support
>> control flow with uninitialized slices, and will raise an error if it
>> is uninitialized. Do we want this behaviour (e.g. for consistency)?
>
>
>
> When in doubt, go for consistency. So +1 for that reason. I do believe
> that
> setting stuff to None is rather vital in Python.
>
> What I typically do is more like this:
>
> def f(double[:] input, double[:] out=None):
>    if out is None:
>        out = np.empty_like(input)
>    ...
>
> Having to use another variable name is a bit of a pain. (Come on -- do
> you
> use "a" in real code? What do you actually call "the other obj"? I
> sometimes
> end up with "out_" and so on, but it creates smelly code quite quickly.)


 No, it was just a contrived example.

> It's easy to segfault with cdef classes anyway, so decent nonechecking
> should be implemented at some point, and then memoryviews would use the
> same
> mechanisms. Java has decent null-checking...
>

 The problem with none checking is that it has to occur at every point.
>>>
>>>
>>> Well, using control flow analysis etc. it doesn't really. E.g.,
>>>
>>> for i in range(a.shape[0]):
>>>    print i
>>>    a[i] *= 3
>>>
>>> can be unrolled and none-checks inserted as
>>>
>>> print 0
>>> if a is None: raise 
>>> a[0] *= 3
>>> for i in range(1, a.shape[0]):
>>>    print i
>>>    a[i] *= 3 # no need for none-check
>>>
>>> It's very similar to what you'd want to do to pull boundschecking out of the
>>> loop...
>>>
>>
>> Oh, definitely. Both optimizations may not always be possible to do,
>> though. The optimization (for boundschecking) is easier for prange()
>> than range(), as you can immediately raise an exception as the
>> exceptional condition may be issued at any iteration.  What do you do
>> with bounds checking when some accesses are in-bound, and some are
>> out-of-bound? Do you immediately raise the exception? Are we fine with
>> aborting (like Fortran compilers do when you ask them for bounds
>> checking)? And how do you detect that the code doesn't already raise
>> an exception or break out of the loop itself to prevent the
>> out-of-bound access? (Unless no exceptions are propagating and no
>> break/return is used, but exceptions are so very common).
>>
 With initialized slices the control flow knows when the slices are
 initialized, or when they might not be (and it can raise a
 compile-time or runtime error, instead of a segfault if you're lucky).
 I'm fine with implementing the behaviour, I just always left it at the
 bottom of my todo list.
>>>
>>>
>>> Wasn't saying you should do it, just checking.
>>>
>>> I'm still not sure about this. I think what I'd really like is
>>>
>>>  a) Stop cdef classes from being None as well
>>>
>>>  b) Sort-of deprecate cdef in favor of cast/assertion type statements that
>>> help the type inferences:
>>>
>>> def f(arr):
>>>    if arr is None:
>>

Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread Dag Sverre Seljebotn

On 02/03/2012 07:07 PM, mark florisson wrote:

On 3 February 2012 18:06, mark florisson  wrote:

On 3 February 2012 17:53, Dag Sverre Seljebotn
  wrote:

On 02/03/2012 12:09 AM, mark florisson wrote:


On 2 February 2012 21:38, Dag Sverre Seljebotn
wrote:


On 02/02/2012 10:16 PM, mark florisson wrote:



On 2 February 2012 12:19, Dag Sverre Seljebotn
  wrote:



I just realized that

cdef int[:] a = None

raises an exception; even though I'd argue that 'a' is of the
"reference"
kind of type where Cython usually allow None (i.e., "cdef MyClass b =
None"
is allowed even if type(None) is NoneType). Is this a bug or not, and
is
it
possible to do something about it?

Dag Sverre
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel




Yeah I disabled that quite early. It was supposed to be working but
gave a lot of trouble in cases (segfaults, mainly). At the time I was
trying to get rid of all the segfaults and get the basic functionality
working, so I disabled it. Personally, I have never liked how things




Well, you can segfault quite easily with

cdef MyClass a = None
print a.field

so it doesn't make sense to slices different from cdef classes IMO.



can be None unchecked. I personally prefer to write

cdef foo(obj=None):
 cdef int[:] a
 if obj is None:
 obj = ...
 a = obj

Often you forget to write 'not None' when declaring the parameter (and
apparently that it only allowed for 'def' functions).

As such, I never bothered to re-enable it. However, it does support
control flow with uninitialized slices, and will raise an error if it
is uninitialized. Do we want this behaviour (e.g. for consistency)?




When in doubt, go for consistency. So +1 for that reason. I do believe
that
setting stuff to None is rather vital in Python.

What I typically do is more like this:

def f(double[:] input, double[:] out=None):
if out is None:
out = np.empty_like(input)
...

Having to use another variable name is a bit of a pain. (Come on -- do
you
use "a" in real code? What do you actually call "the other obj"? I
sometimes
end up with "out_" and so on, but it creates smelly code quite quickly.)



No, it was just a contrived example.


It's easy to segfault with cdef classes anyway, so decent nonechecking
should be implemented at some point, and then memoryviews would use the
same
mechanisms. Java has decent null-checking...



The problem with none checking is that it has to occur at every point.



Well, using control flow analysis etc. it doesn't really. E.g.,

for i in range(a.shape[0]):
print i
a[i] *= 3

can be unrolled and none-checks inserted as

print 0
if a is None: raise 
a[0] *= 3
for i in range(1, a.shape[0]):
print i
a[i] *= 3 # no need for none-check

It's very similar to what you'd want to do to pull boundschecking out of the
loop...



Oh, definitely. Both optimizations may not always be possible to do,
though. The optimization (for boundschecking) is easier for prange()
than range(), as you can immediately raise an exception as the
exceptional condition may be issued at any iteration.  What do you do
with bounds checking when some accesses are in-bound, and some are
out-of-bound? Do you immediately raise the exception? Are we fine with
aborting (like Fortran compilers do when you ask them for bounds
checking)? And how do you detect that the code doesn't already raise
an exception or break out of the loop itself to prevent the
out-of-bound access? (Unless no exceptions are propagating and no
break/return is used, but exceptions are so very common).


With initialized slices the control flow knows when the slices are
initialized, or when they might not be (and it can raise a
compile-time or runtime error, instead of a segfault if you're lucky).
I'm fine with implementing the behaviour, I just always left it at the
bottom of my todo list.



Wasn't saying you should do it, just checking.

I'm still not sure about this. I think what I'd really like is

  a) Stop cdef classes from being None as well

  b) Sort-of deprecate cdef in favor of cast/assertion type statements that
help the type inferences:

def f(arr):
if arr is None:
arr = ...
arr = int[:](arr) # equivalent to "cdef int[:] arr = arr", but
  # acts as statement, with a specific point
  # for the none-check
...

or even:

def f(arr):
if arr is None:
return 'foo'
else:
arr = int[:](arr) # takes effect *here*, does none-check
...
# arr still typed as int[:] here

If we can make this work well enough with control flow analysis I'd never
cdef declare local vars again :-)


Hm, what about the following?

def f(arr):
if arr is None:
return 'foo'

cdef int[:] arr # arr may not be None


The above would work in general, until the declaration is lexically
encountered, the object is typed

Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread mark florisson
On 3 February 2012 18:15, Dag Sverre Seljebotn
 wrote:
> On 02/03/2012 07:07 PM, mark florisson wrote:
>>
>> On 3 February 2012 18:06, mark florisson
>>  wrote:
>>>
>>> On 3 February 2012 17:53, Dag Sverre Seljebotn
>>>   wrote:

 On 02/03/2012 12:09 AM, mark florisson wrote:
>
>
> On 2 February 2012 21:38, Dag Sverre Seljebotn
>     wrote:
>>
>>
>> On 02/02/2012 10:16 PM, mark florisson wrote:
>>>
>>>
>>>
>>> On 2 February 2012 12:19, Dag Sverre Seljebotn
>>>       wrote:



 I just realized that

 cdef int[:] a = None

 raises an exception; even though I'd argue that 'a' is of the
 "reference"
 kind of type where Cython usually allow None (i.e., "cdef MyClass b
 =
 None"
 is allowed even if type(None) is NoneType). Is this a bug or not,
 and
 is
 it
 possible to do something about it?

 Dag Sverre
 ___
 cython-devel mailing list
 cython-devel@python.org
 http://mail.python.org/mailman/listinfo/cython-devel
>>>
>>>
>>>
>>>
>>> Yeah I disabled that quite early. It was supposed to be working but
>>> gave a lot of trouble in cases (segfaults, mainly). At the time I was
>>> trying to get rid of all the segfaults and get the basic
>>> functionality
>>> working, so I disabled it. Personally, I have never liked how things
>>
>>
>>
>>
>> Well, you can segfault quite easily with
>>
>> cdef MyClass a = None
>> print a.field
>>
>> so it doesn't make sense to slices different from cdef classes IMO.
>>
>>
>>> can be None unchecked. I personally prefer to write
>>>
>>> cdef foo(obj=None):
>>>     cdef int[:] a
>>>     if obj is None:
>>>         obj = ...
>>>     a = obj
>>>
>>> Often you forget to write 'not None' when declaring the parameter
>>> (and
>>> apparently that it only allowed for 'def' functions).
>>>
>>> As such, I never bothered to re-enable it. However, it does support
>>> control flow with uninitialized slices, and will raise an error if it
>>> is uninitialized. Do we want this behaviour (e.g. for consistency)?
>>
>>
>>
>>
>> When in doubt, go for consistency. So +1 for that reason. I do believe
>> that
>> setting stuff to None is rather vital in Python.
>>
>> What I typically do is more like this:
>>
>> def f(double[:] input, double[:] out=None):
>>    if out is None:
>>        out = np.empty_like(input)
>>    ...
>>
>> Having to use another variable name is a bit of a pain. (Come on -- do
>> you
>> use "a" in real code? What do you actually call "the other obj"? I
>> sometimes
>> end up with "out_" and so on, but it creates smelly code quite
>> quickly.)
>
>
>
> No, it was just a contrived example.
>
>> It's easy to segfault with cdef classes anyway, so decent nonechecking
>> should be implemented at some point, and then memoryviews would use
>> the
>> same
>> mechanisms. Java has decent null-checking...
>>
>
> The problem with none checking is that it has to occur at every point.



 Well, using control flow analysis etc. it doesn't really. E.g.,

 for i in range(a.shape[0]):
    print i
    a[i] *= 3

 can be unrolled and none-checks inserted as

 print 0
 if a is None: raise 
 a[0] *= 3
 for i in range(1, a.shape[0]):
    print i
    a[i] *= 3 # no need for none-check

 It's very similar to what you'd want to do to pull boundschecking out of
 the
 loop...

>>>
>>> Oh, definitely. Both optimizations may not always be possible to do,
>>> though. The optimization (for boundschecking) is easier for prange()
>>> than range(), as you can immediately raise an exception as the
>>> exceptional condition may be issued at any iteration.  What do you do
>>> with bounds checking when some accesses are in-bound, and some are
>>> out-of-bound? Do you immediately raise the exception? Are we fine with
>>> aborting (like Fortran compilers do when you ask them for bounds
>>> checking)? And how do you detect that the code doesn't already raise
>>> an exception or break out of the loop itself to prevent the
>>> out-of-bound access? (Unless no exceptions are propagating and no
>>> break/return is used, but exceptions are so very common).
>>>
> With initialized slices the control flow knows when the slices are
> initialized, or when they might not be (and it can raise a
> compile-time or runtime error, instead of a segfault if you're lucky).
> I'm fine with implementing the behaviour, I just always left it at the
> bottom of my todo list.




Re: [Cython] Bug in Cython producing incorrect C code

2012-02-03 Thread Vitja Makarov
2012/1/26 mark florisson :
> On 26 January 2012 19:27, Stefan Behnel  wrote:
>> mark florisson, 26.01.2012 20:15:
>>> On 26 January 2012 18:53, Stefan Behnel wrote:
 mark florisson, 26.01.2012 16:20:
> I think this problem can trivially be solved by creating a ProxyNode
> that should never be replaced by any transform, but it's argument may
> be replaced. So you wrap self.rhs in a ProxyNode and use that to
> create your CloneNodes.

 I can't see what a ProxyNode would do that a CloneNode shouldn't do anyway.
>>>
>>> It wouldn't be a replacement, merely an addition (an extra indirection).
>>
>> What I was trying to say was that a ProxyNode would always be required by a
>> CloneNode, but I don't see where a ProxyNode would be needed outside of a
>> CloneNode. So it seems rather redundant and I don't know if we need a
>> separate node for it.
>
> Yes it would be needed only for that, but I think the only real
> alternative is to not use CloneNode at all, i.e. make the
> transformation Dag mentioned, where you create new rhs (NameNode?)
> references to the temporary result.
>

Now it seems to be the only case when we got problem like this. It
means that clones may be safely created at very late stage.
So transforming CascadeAssignment into SingleAssignments doesn't solve
generic problem.

I tried to implement conditional inlining the same problem may happen
there (ConditionalCallNode owns arguments and replaces
SimpleCallNode's args with clones). Splitting analyse_expressions()
would help. On the other hand moving this optimization after
OptimizeBuiltinCalls() would help too.

-- 
vitja.
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] memoryview slices can't be None?

2012-02-03 Thread mark florisson
On 3 February 2012 18:06, mark florisson  wrote:
> On 3 February 2012 17:53, Dag Sverre Seljebotn
>  wrote:
>> On 02/03/2012 12:09 AM, mark florisson wrote:
>>>
>>> On 2 February 2012 21:38, Dag Sverre Seljebotn
>>>   wrote:

 On 02/02/2012 10:16 PM, mark florisson wrote:
>
>
> On 2 February 2012 12:19, Dag Sverre Seljebotn
>     wrote:
>>
>>
>> I just realized that
>>
>> cdef int[:] a = None
>>
>> raises an exception; even though I'd argue that 'a' is of the
>> "reference"
>> kind of type where Cython usually allow None (i.e., "cdef MyClass b =
>> None"
>> is allowed even if type(None) is NoneType). Is this a bug or not, and
>> is
>> it
>> possible to do something about it?
>>
>> Dag Sverre
>> ___
>> cython-devel mailing list
>> cython-devel@python.org
>> http://mail.python.org/mailman/listinfo/cython-devel
>
>
>
> Yeah I disabled that quite early. It was supposed to be working but
> gave a lot of trouble in cases (segfaults, mainly). At the time I was
> trying to get rid of all the segfaults and get the basic functionality
> working, so I disabled it. Personally, I have never liked how things



 Well, you can segfault quite easily with

 cdef MyClass a = None
 print a.field

 so it doesn't make sense to slices different from cdef classes IMO.


> can be None unchecked. I personally prefer to write
>
> cdef foo(obj=None):
>     cdef int[:] a
>     if obj is None:
>         obj = ...
>     a = obj
>
> Often you forget to write 'not None' when declaring the parameter (and
> apparently that it only allowed for 'def' functions).
>
> As such, I never bothered to re-enable it. However, it does support
> control flow with uninitialized slices, and will raise an error if it
> is uninitialized. Do we want this behaviour (e.g. for consistency)?



 When in doubt, go for consistency. So +1 for that reason. I do believe
 that
 setting stuff to None is rather vital in Python.

 What I typically do is more like this:

 def f(double[:] input, double[:] out=None):
    if out is None:
        out = np.empty_like(input)
    ...

 Having to use another variable name is a bit of a pain. (Come on -- do
 you
 use "a" in real code? What do you actually call "the other obj"? I
 sometimes
 end up with "out_" and so on, but it creates smelly code quite quickly.)
>>>
>>>
>>> No, it was just a contrived example.
>>>
 It's easy to segfault with cdef classes anyway, so decent nonechecking
 should be implemented at some point, and then memoryviews would use the
 same
 mechanisms. Java has decent null-checking...

>>>
>>> The problem with none checking is that it has to occur at every point.
>>
>>
>> Well, using control flow analysis etc. it doesn't really. E.g.,
>>
>> for i in range(a.shape[0]):
>>    print i
>>    a[i] *= 3
>>
>> can be unrolled and none-checks inserted as
>>
>> print 0
>> if a is None: raise 
>> a[0] *= 3
>> for i in range(1, a.shape[0]):
>>    print i
>>    a[i] *= 3 # no need for none-check
>>
>> It's very similar to what you'd want to do to pull boundschecking out of the
>> loop...
>>
>
> Oh, definitely. Both optimizations may not always be possible to do,
> though. The optimization (for boundschecking) is easier for prange()
> than range(), as you can immediately raise an exception as the
> exceptional condition may be issued at any iteration.  What do you do
> with bounds checking when some accesses are in-bound, and some are
> out-of-bound? Do you immediately raise the exception? Are we fine with
> aborting (like Fortran compilers do when you ask them for bounds
> checking)? And how do you detect that the code doesn't already raise
> an exception or break out of the loop itself to prevent the
> out-of-bound access? (Unless no exceptions are propagating and no
> break/return is used, but exceptions are so very common).

I enabled bound checking in nogil contexts:
https://github.com/markflorisson88/cython/commit/73c6b0ea8e7e1c243e87b3966ade834b02664a4f
. It's not optimized yet, but at least it doesn't force users to use
boundscheck(False), it just hints that it would be faster to disable
the bounds checking.

When we actually start optimizing these things (e.g. moving it outside
loops etc), it might also be useful to consider inlining functions at
the Cython level (otherwise optimizations cannot escape the function).

>>> With initialized slices the control flow knows when the slices are
>>> initialized, or when they might not be (and it can raise a
>>> compile-time or runtime error, instead of a segfault if you're lucky).
>>> I'm fine with implementing the behaviour, I just always left it at the
>>> bottom of my todo list.
>>
>>
>> Wasn't say