Thanks, this is exactly the response I was hoping for. It would have 
been my own - my own reasoning about this idea has been:
- I found an approach to do this easily
- This should be hard
- => I'm wrong...somewhere...

and in the end I put it out for public ridicule instead of thinking more 
about which one of my assumptions are wrong.

> While I've liked your previous ideas, parse trees are not the correct
> way to do optimizations in my opinion.  This would dramatically
> increase Cython compile time by orders of magnitude for one.  If we
>   
I don't expect a full optimizing compiler. Note specifically that it 
will do *nothing* about optimizing run-time expressions:

a - b + b

will be left as-is without any change, UNLESS they are all known 
compile-time (and some code for evaluating compile-time expressions and 
marking nodes as known compile-time are already in place thanks to the 
DEF syntax).

If you think your comment still apply then just say a simple "yes it 
does" and I'll think harder about it.

An optimizing compiler tries to optimize things like the above, which is 
not what this is about.

Compilation times depends on what you use it on. I think it would be a 
manual opt-in for starters, possibly for ever, and whoever opts in (with 
@cython.inline for instance) have to eat their own cake!

The idea is that with this one can have a convenient run-time syntax for 
operator overloading, while without it the syntax for operator 
overloading I'm thinking about is a no-go (specifically talking about 
how to generate a dynamic operator overload for NumPy arrays here).

For starters I would plan to use it only for implementing NumPy array 
access in a nice way, effectively collapsing arr[i,j] through this 
overload:

  

        @cython.inline
        def __getitem__(self, index):
            cdef int bufidx = 0
            if len(index) != type(self).nd: raise ValueError("...")
            if not isinstance(index, list):
                if typeof(self).checkbounds:
                    if index < 0: raise ValueError("...")
                    ...etc...
              bufidx = index
            else:
                for subindex, dim in zip(index, range(len(index)):
                    if len(subindex) > 1: raise ValueError("slices not 
supported")
                    if typeof(self).checkbounds:
                        if subindex < 0: raise ValueError("...")
                        ...and so on...
                    bufidx += self.strides[dim] // sizeof(typeof(self).dtype) * 
subindex
            return (<cython.types.ptr(typeof(self).dtype)>self.data)[bufidx]

into

(<unsigned int*>arr.data)[i * arr.strides[0]//4 + j * arr.strides[1]//4]

for 2-D array lookup. This adds O(nm) to the compilation time where n is 
the number of NumPy array lookups and m is the number of dimensions of 
the array being looked up.

Adding memoization to this is where the smart dependency graphs needs to 
enter I guess, and that's a


-- 
Dag Sverre

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to