On Tue, Aug 25, 2009 at 9:16 PM, Kurt Smith<[email protected]> wrote:
> On Tue, Aug 25, 2009 at 4:21 PM, Fernando Perez<[email protected]> wrote:
>> Hi folks,
>>
>> On Tue, Aug 25, 2009 at 12:08 PM, Kurt Smith<[email protected]> wrote:
>>>  Weave-like support in Cython -- Fernando Perez (not at the BoF)
>>> suggested that Cython could assume the same functionality of
>>> scipy.weave (see: http://www.scipy.org/Weave), since scipy.weave is
>>> poorly documented and could use more maintenance than it is currently
>>> getting.  I'm personally very interested in this -- it seems that
>>> there is much overlap between scipy.weave and the combination of
>>> pyximport & the pure-python mode of Cython.  It seems that with a bit
>>> of work from an interested user and some guidance from yours truly, we
>>> could improve pyximport & Cython's pure-python mode to incorporate the
>>> good stuff from scipy.weave, but better ;-)  I intend to write-up a
>>> CEP with my thoughts sometime in the near future.
>>>
>>
>> Kurt, thanks for resurrecting this comment.  Indeed, weave is an
>> extremely useful piece of functionality but one that has been somewhat
>> neglected for years.  There's a lot of good in there though, and the
>> need for it is significant. It's *really* cool to do things like:
>>
>> def prod(m, v):
>>    """Matrix-vector multiply via weave/blitz++"""
>>    nrows, ncolumns = m.shape
>>    assert v.ndim==1 and ncolumns==v.shape[0],"Shape mismatch in prod"
>>
>>    res = np.zeros(nrows, float)
>>    code = r"""
>>    for (int i=0; i<nrows; i++)
>>    {
>>        for (int j=0; j<ncolumns; j++)
>>        {
>>            res(i) += m(i,j)*v(j);
>>        }
>>    }
>>    """
>>    err = inline(code,['nrows', 'ncolumns', 'res', 'm', 'v'], verbose=2,
>>                 type_converters=converters.blitz)
>>    return res
>
> Here's what I'm envisioning for the above usecase -- I admit to not
> using the pure-python mode that much, so there may be errors (and some
> of what I'm using isn't implemented yet).  But it shows how much is
> already there in Cython's pure-python mode.
>
> @cython.compile # this is new & where most of the work is required!
> @cython.locals(m=cython.float[:,::1], v=cython.float[::1])
> def prod(m, v):
>    cython.declare(
>            i=cython.int,
>            j=cython.int,
>            nrows=cython.int,
>            ncolumns=cython.int)
>    nrows = m.shape[0]; ncolumns = m.shape[1]
>    cython.declare(res=cython.float[::1])
>    res = np.zeros(nrows, np.float)
>    for i in range(nrows):
>        for j in range(ncolumns):
>            res[i] += m[i,j] * v[j]
>    return res
>
> Once the new array type / memoryview slice is merged into cython-devel
> and we get it integrated into pure-python mode, this will be close to
> working.  If you just want things fast in the function body (what
> weave gives you currently) then the above is all you need.
>
> The hard part is getting things to compile & run automatically for
> just this function (the cython.compile decorator).  This overlaps with
> pyximport a good amount, and it will take some thought as to how it
> will all work together.  Perhaps the core devs won't like so much
> going on behind the scenes -- cython is principally a utility for
> generating a C extension module, not compiling & loading the extension
> module.
>
> Weave compiles individual snippets into their own extension module,
> whereas Cython has always compiled entire modules into extension
> modules, and requires a separate compilation step (whether through the
> commandline or through pyximport).   The cython.compile decorator
> would be different, if it were to be just like weave -- it would
> compile a single function into its own extension module, without an
> explicit compilation step.  Much more is automated.
>
> This seems to be the main thing that weave offers -- fast code only
> where you want it, without the explicit compilation step.  Pyximport
> overlaps here, but pyximport still compiles an entire module, not just
> a part.
>
> So those are some of my thoughts.  They'll be in a CEP sometime soon :-)
>
>>
>> This makes interactive experimentation and the writing of
>> loop/indexing-intensive code really easy.  But by itself, weave is in
>> serious danger of bitrot, and right now Cython has the momentum and
>> concentrated effort for this problem domain.
>>
>> Everyone is extremely impressed with the amazing work you've all done,
>> and rooting for cython to continue to improve, as you are  solving a
>> number of key problems to make python a really complete platform for
>> scientific computing.  It's been lots of  fun to see cython steadily
>> attack a number of problems that have been a real issue for years.
>>
>> So if Cython absorbs/extends/integrates/develops/whatever the good
>> ideas and code from weave, so that this type of  workflow is also
>> supported, it would be great.   I am really happy to see f2py grow
>> into fwrap, and the weave machinery (or at least parts of it) seems
>> like a logical addition to the cython-based toolkit.
>>
>> One particular use case for which weave.inline was invaluable to me in
>> the past was the generation of fast looping code for various
>> dimensions.   I had to write function evaluation codes where the user
>> could supply a C expression (as a string, that would #define NDIM to
>> indicate the dimensionality of the problem).  I could then easily
>> generate a few methods for D=1..6 (the range I needed to cover) that
>> would do certain key operations very fast.  The bulk of the code used
>> numpy arrays to be dimension agnostic, but a few methods really needed
>> explicit loops and with weave, it was made completely transparent to
>> the user, all  of it being done at runtime (for us, needing gcc at
>> runtime was OK).  I mention this to give you some feedback on the use
>> cases for weave (there are others), but I hope that in the end, all of
>> this class of functionality will be available through a unified entry
>> point, and if that's cython, all the better.
>>
>
> Thanks for the encouragement, and for the examples.  I don't have time
> to absorb all this just yet, but I'll return to it.  And get other
> usecases for weave from you and others.
>
> Kurt
>
>> Thanks again to the team for your great work!
>>
>> Cheers,
>>
>> f

(A comment from a non-expert)

A more literal approach to imitating weave inline compilation, seems
already possible with cython and pyximport. To try out cython and to
reduce the time in debugging my (many) mistakes, a added the
compilation step directly to the script. This seems closer to the
usage of weave that Fernando was deswcribing and what I saw of weave
examples.

Cheers,

Josef

code = '''
import numpy as np

cimport numpy as np

__all__ = ["hist3d"]
DTYPE = ${imgtype}
DTYPE32 = ${outtype}

ctypedef ${imgtype}_t DTYPE_t
ctypedef ${outtype}_t DTYPE_t32

def hist3d(np.ndarray[DTYPE_t, ndim=3] img, int nbins):
    # a variation on code by Chris Colbert
    #if nbins are not a divisor of 256, all extra high values are added to the 
last bin
    cdef int x = img.shape[0]
    cdef int y = img.shape[1]
    #cdef int z = img.shape[2]
    #I don't know how to get the correct width
    cdef int bdist = np.max(img) / nbins #np.ceil(256 / (1.0* nbins))
    cdef int addx
    cdef int addy
    cdef int addz   
    cdef np.ndarray[DTYPE_t32, ndim=3] out = np.zeros([nbins, nbins, nbins], 
dtype=DTYPE32)
    cdef int i, j, v0, v1, v2
          
               
    for i in range(x):
        for j in range(y):
            v0 = img[i, j, 0]
            v1 = img[i, j, 1]
            v2 = img[i, j, 2]
            addx = min((v0 - (v0 % bdist)) / bdist, nbins-1)
            addy = min((v1 - (v1 % bdist)) / bdist, nbins-1)
            addz = min((v2 - (v2 % bdist)) / bdist, nbins-1)
            #print addx, addy, addz
            out[addx, addy, addz] += 1
   
    return out
'''

from string import Template
s = Template(code)
src = s.substitute({'imgtype': 'np.int', 'outtype': 'np.float64'})
open('histrgbintfl06.pyx','w').write(src)
import pyximport; pyximport.install()
import histrgbintfl06

import numpy as np
factors = np.random.randint(256,size=(480, 630, 3))
h = histrgbintfl06.hist3d(factors, 4)#.astype(np.uint8))
print h[:,:,0]
h = histrgbintfl06.hist3d(factors, 5)
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to