Thu Jun 9 08:46:26 CEST 2011

```Author: Hakan Ardo <hakan at debian.org>
Changeset: r3625:c6fc317d3405
Date: 2011-06-09 08:47 +0200

Log:	2 dimensional convolution

diff --git a/talk/iwtc11/benchmarks/convolution/convolution.py b/talk/iwtc11/benchmarks/convolution/convolution.py
--- a/talk/iwtc11/benchmarks/convolution/convolution.py
+++ b/talk/iwtc11/benchmarks/convolution/convolution.py
@@ -17,3 +17,39 @@
for i in xrange(len(b)):
b[i] = k[4]*a[i] + k[3]*a[i+1] + k[2]*a[i+2] + k[1]*a[i+3] + k[0]*a[i+4]
return b
+
+class Array2D(object):
+    def __init__(self, w, h):
+        self.width = w
+        self.height = h
+        self.data = array('d', [0]) * (w*h)
+
+    def _idx(self, x, y):
+        if 0 <= x < self.width and 0 <= y < self.height:
+            return y*self.width + x
+        raise IndexError
+
+    def __getitem__(self, (x, y)):
+        return self.data[self._idx(x, y)]
+
+    def __setitem__(self, (x, y), val):
+        self.data[self._idx(x, y)] = val
+
+    def __cmp__(self, other):
+        return cmp(self.data, other.data)
+
+    def setup(self, data):
+        for y in xrange(self.height):
+            for x in xrange(self.width):
+                self[x, y] = data[y][x]
+        return self
+
+def conv3x3(a, k):
+    assert k.width == k.height == 3
+    b = Array2D(a.width, a.height)
+    for y in xrange(1, a.height-1):
+        for x in xrange(1, a.width-1):
+            b[x, y] = k[2,2]*a[x-1, y-1] + k[1,2]*a[x, y-1] + k[0,2]*a[x+1, y-1] + \
+                      k[2,1]*a[x-1, y]   + k[1,1]*a[x, y]   + k[0,1]*a[x+1, y]   + \
+                      k[2,0]*a[x-1, y+1] + k[1,0]*a[x, y+1] + k[0,0]*a[x+1, y+1]
+    return b
diff --git a/talk/iwtc11/benchmarks/convolution/test_convolution.py b/talk/iwtc11/benchmarks/convolution/test_convolution.py
--- a/talk/iwtc11/benchmarks/convolution/test_convolution.py
+++ b/talk/iwtc11/benchmarks/convolution/test_convolution.py
@@ -1,4 +1,4 @@
-from convolution import conv3, conv5
+from convolution import conv3, conv5, conv3x3, Array2D
from array import array

def test_conv3():
@@ -11,3 +11,18 @@
array('d', [1, 1, 2, 2, 3]))
assert b == array('d', [22, 31, 40, 49, 58])

+def test_conv3x3():
+    a = Array2D(5, 5).setup([[11, 12, 13, 14, 15],
+                             [21, 22, 23, 24, 25],
+                             [31, 32, 33, 34, 35],
+                             [41, 42, 43, 44, 45],
+                             [51, 52, 53, 54, 55]])
+    k = Array2D(3, 3).setup([[1, 2, 3],
+                             [1, 1, 2],
+                             [2, 1, 1]])
+    b = conv3x3(a, k)
+    assert b == Array2D(5, 5).setup([[0,   0,   0,   0, 0],
+                                     [0, 326, 340, 354, 0],
+                                     [0, 466, 480, 494, 0],
+                                     [0, 606, 620, 634, 0],
+                                     [0,   0,   0,   0, 0]])
diff --git a/talk/iwtc11/benchmarks/convolution/time_conv2d.py b/talk/iwtc11/benchmarks/convolution/time_conv2d.py
new file mode 100644
--- /dev/null
+++ b/talk/iwtc11/benchmarks/convolution/time_conv2d.py
@@ -0,0 +1,25 @@
+from convolution import conv3x3, Array2D
+from array import array
+import sys, time
+
+try:
+    import pypyjit
+    pypyjit.set_param(trace_limit=200000)
+except ImportError:
+    pass
+
+conv3x3(Array2D(1001, 1001), Array2D(3,3)) # Warmup
+
+a = time.time()
+for i in range(10):
+    conv3x3(Array2D(1000000, 3), Array2D(3,3))
+b = time.time()
+print 'conv3x3(3):   ', b - a
+
+a = time.time()
+for i in range(10):
+    conv3x3(Array2D(1000, 1000), Array2D(3,3))
+b = time.time()
+print 'conv3x3(1000):', b - a
+
+
```