[SciPy-user] weave.inline keeps recompling my C++ code (fwd)

Curtis Cooper curtis at hindmost.LPL.Arizona.EDU
Wed Mar 30 00:03:32 CST 2005


Hi,

I'm using weave.inline to compare the performance of weave with several
other methods of doing the same calculation.  It is simply a matrix
multiplication: Z = sin(X)*cos(Y).  I have attached my program for you to
peruse.  I am in general very impressed with the usability and
performance of weave.  I have two questions, however:

1) Why does it tell me 'repairing catalog by removing key' every single
time I run this program using 'python tryweave.py'?  I thought the idea
was for scipy-weave to only have to recompile the C++ portions if the C++
source code changes.

2) How can I use the sin and cos functions with weave.blitz?  Up until
now, I have had to comment out the weave_blitz version because I can't
figure out how to add cmath support to my blitz++ expression.

FYI, my system is Debian Linux (Sarge/Testing branch).  The Python prompt
says:

Python 2.3.5 (#2, Feb
9 2005, 00:38:15) [GCC 3.3.5 (Debian 1:3.3.5-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Cheers,
Curtis
-------------- next part --------------
#!/usr/bin/env python 
import weave
import time

N_ELEM = 720
M_ELEM = 720
N_ITER = 1

#----------
def main():

    from pylab import linspace, meshgrid, pi
    from pylab import figure, imshow, hot, colorbar, show
    from numarray import ravel
   
    x = linspace(-pi, pi, N_ELEM)
    y = linspace(-pi, pi, M_ELEM)
    [XI, YI] = meshgrid(x, y)
  
    print
    print "Array Shapes: ", (N_ELEM, M_ELEM), ", # Iterations: ", N_ITER
    print "-----------------------------------------------"
    print
    start = time.clock()
    for i in xrange(N_ITER):
        Z_numarray = numarray_looping(XI, YI)
    stop = time.clock()
    dt = stop - start
    print "numarray_looping: ", dt, " [s]"
    
    start = time.clock()
    for i in xrange(N_ITER):
        Z = naive_looping(XI, YI)
    stop = time.clock()
    dt = stop - start
    print "naive_looping: ", dt, " [s]" 

    # For rest, convert to Numeric
    from Numeric import reshape, resize, size, empty, Float, asarray, array, arange, pi, exp, sin, tan, cos
    start = time.clock()
    X = empty(XI.shape, typecode = 'd')
    Y = empty(XI.shape, typecode = 'd')
    #X[:] = ravel(XI)
    #Y[:] = ravel(YI)
    #reshape(X, XI.shape)
    #reshape(Y, XI.shape)
    #print type(X), X.shape
    #X = asarray(XI, savespace = 1)
    #Y = asarray(YI, savespace = 1)
    X[:] = XI; Y[:] = YI
    stop = time.clock()
    dt = stop - start
    print "Convert to Numeric: ", dt, " [s]"
    
    start = time.clock()
    for i in xrange(N_ITER):
        Z = Numeric_looping(X, Y)
    stop = time.clock()
    dt = stop - start
    print "Numeric_looping: ", dt, " [s]"
    
    start = time.clock()
    for i in xrange(N_ITER):
        Z = weave_inline_blitz(X, Y)
    stop = time.clock()
    dt = stop - start
    print "weave_inline_blitz: ", dt, " [s]" 
    
    start = time.clock()
    for i in xrange(N_ITER):
        Z_weave_fast = weave_fast_looping(X, Y)
    stop = time.clock()
    dt = stop - start
    print "weave_fast_looping: ", dt, " [s]" 
    
    from numarray import array
    start = time.clock()
    Z_out = array(Z_weave_fast)
    stop = time.clock()
    dt = stop - start
    print "Convert back: ", dt, " [s]"
    
    #start = time.clock()
    #for i in xrange(N_ITER):
    #    Z_blitz = weave_blitz(X, Y)
    #stop = time.clock()
    #dt = stop - start
    #print "weave_blitz: ", dt, " [s]" 
        
    start = time.clock()
    for i in xrange(N_ITER):
        Z_psyco = psyco_looping(X, Y)
    stop = time.clock()
    dt = stop - start
    print "psyco_looping: ", dt, " [s]" 
    
    #figure()
    #imshow(Z_numarray, extent = [-pi, pi, -pi, pi])
    #hot()
    #colorbar()
    #figure()
    #imshow(Z_out, extent = [-pi, pi, -pi, pi])
    #hot()
    #colorbar()
    #show()


def Numeric_looping(X, Y):
    """
    Using Numeric's built-in looping abilities
    """
    #print "Numeric looping: "
    from Numeric import sin, cos, tan
    Z = sin(X)*cos(Y)
    return Z
    
def numarray_looping(X, Y):
    """
    Using Numeric's built-in looping abilities
    """
    #print "numarray looping: "
    from numarray import sin, cos, tan
    Z = sin(X)*cos(Y)
    return Z

def naive_looping(X, Y):    
    """
    Naive Python loop computation
    """
    #print "Naive looping: "
    from Numeric import arange
    from math import sin, cos, tan

    Z = X.copy()
    for i in xrange(X.shape[0]):
        for j in xrange(X.shape[1]):
            Z[i,j] = sin(X[i,j]) * cos(Y[i,j]) 

    return Z

def psyco_looping(X, Y):    
    """
    Psyco naive Python loop computation
    """
    #print "Psyco looping: "
    from Numeric import arange
    from math import sin, cos, tan
    import psyco
    psyco.bind(psyco_looping)

    psyco.full()
    Z = X.copy()
    for i in xrange(X.shape[0]):
        for j in xrange(X.shape[1]):
            Z[i,j] = sin(X[i,j]) * cos(Y[i,j]) 

    return Z

def weave_inline_blitz(X, Y):
    """
    Uses weave.inline
    """
    #print "Weave inline:"
    from Numeric import array, Float64, zeros
    from weave import converters
   
    n, m = X.shape
    Z = zeros((n, m), 'd')
    
    cpp_code = (
        """
        int i = 0, j = 0;
        for (i = 0; i < n; ++i)
            for (j = 0; j < m; ++j)
                Z(i, j) = sin(X(i, j)) * cos(Y(i, j));
        """)

    #print "Weave starting"
    weave.inline(cpp_code, ['X', 'Y', 'Z', 'n', 'm'], 
        type_converters = converters.blitz)
   
    #print "Weave returning"
    return Z

def weave_fast_looping(X, Y):
    """
    Uses weave.inline
    """
    #print "Weave inline:"
    from Numeric import array, Float64, zeros
    from weave import converters
   
    n, m = X.shape
    Z = zeros((n, m), 'd')

    # Weave module
    support_code = (
    """
        #include <iostream>
        
        template <typename T>
        class Array3D
        {
        public:

            /** Take in buffer of 3D array and store dimensions */
            Array3D(T* buffer, size_t n_rows, size_t n_cols, size_t n_depth = 1) 
                : rows(n_rows), cols(n_cols), depth(n_depth), M(buffer) {}

            const T& operator()(size_t i, size_t j, size_t k = 0) const
            {
                return M[(i*cols+j)*depth+k];
            }
            
            T& operator()(size_t i, size_t j, size_t k = 0)
            {
                return M[(i*cols+j)*depth+k];
            }

            T& operator[](size_t index) {return M[index];} 
            const T& operator[](size_t index) const {return M[index];} 

        private:
            size_t rows, cols, depth;
            T* M;
        };
       
    """)
    cpp_code = (
        """
        using namespace std;

        int rows = NX[0];
        int cols = NX[1];
        int depth = 1;
        int k = 0;
        Array3D<double> XH(X, rows, cols);
        Array3D<double> YH(Y, rows, cols);
        Array3D<double> ZH(Z, rows, cols);
        for (int i = 0; i < rows; ++i)
            for (int j = 0; j < cols; ++j)
                ZH(i, j) = sin(XH(i, j)) * cos(YH(i, j));

        // As fast as it gets; requires type_converters = converters.blitz
        //Z = sin(X) * cos(Y);
        """)

    weave.inline(cpp_code, ['X', 'Y', 'Z'], 
        support_code = support_code)
    return Z

def weave_blitz(X, Y):
    """
    Uses weave.blitz
    """
    #print "Weave inline:"
    from Numeric import array, Float64, zeros
    from weave import converters
    from math import sin, cos
   
    n, m = X.shape
    Z = zeros((n, m), 'd')
    expr = "Z = sin(X)*cos(Y)"
    
    weave.blitz(expr)
    return Z

if __name__ == '__main__':
    main()


More information about the SciPy-user mailing list