# [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
>>>

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()
```