Author: Maciej Fijalkowski <[email protected]>
Branch: refactor-signature
Changeset: r50248:ee9bb45f0923
Date: 2011-12-07 16:33 +0200
http://bitbucket.org/pypy/pypy/changeset/ee9bb45f0923/

Log:    in-progress

diff --git a/pypy/module/micronumpy/interp_iter.py 
b/pypy/module/micronumpy/interp_iter.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -0,0 +1,196 @@
+
+from pypy.rlib import jit
+from pypy.rlib.objectmodel import instantiate
+
+# Iterators for arrays
+# --------------------
+# all those iterators with the exception of BroadcastIterator iterate over the
+# entire array in C order (the last index changes the fastest). This will
+# yield all elements. Views iterate over indices and look towards strides and
+# backstrides to find the correct position. Notably the offset between
+# x[..., i + 1] and x[..., i] will be strides[-1]. Offset between
+# x[..., k + 1, 0] and x[..., k, i_max] will be backstrides[-2] etc.
+
+# BroadcastIterator works like that, but for indexes that don't change source
+# in the original array, strides[i] == backstrides[i] == 0
+
+class BaseIterator(object):
+    def next(self, shapelen):
+        raise NotImplementedError
+
+    def done(self):
+        raise NotImplementedError
+
+    def get_offset(self):
+        raise NotImplementedError
+
+class ArrayIterator(BaseIterator):
+    def __init__(self, size):
+        self.offset = 0
+        self.size = size
+
+    def next(self, shapelen):
+        arr = instantiate(ArrayIterator)
+        arr.size = self.size
+        arr.offset = self.offset + 1
+        return arr
+
+    def done(self):
+        return self.offset >= self.size
+
+    def get_offset(self):
+        return self.offset
+
+class OneDimIterator(BaseIterator):
+    def __init__(self, start, step, stop):
+        self.offset = start
+        self.step = step
+        self.size = stop * step + start
+
+    def next(self, shapelen):
+        arr = instantiate(OneDimIterator)
+        arr.size = self.size
+        arr.step = self.step
+        arr.offset = self.offset + self.step
+        return arr
+
+    def done(self):
+        return self.offset == self.size
+
+    def get_offset(self):
+        return self.offset
+
+class ViewIterator(BaseIterator):
+    def __init__(self, arr):
+        self.indices = [0] * len(arr.shape)
+        self.offset  = arr.start
+        self.arr     = arr
+        self._done   = False
+
+    @jit.unroll_safe
+    def next(self, shapelen):
+        offset = self.offset
+        indices = [0] * shapelen
+        for i in range(shapelen):
+            indices[i] = self.indices[i]
+        done = False
+        for i in range(shapelen - 1, -1, -1):
+            if indices[i] < self.arr.shape[i] - 1:
+                indices[i] += 1
+                offset += self.arr.strides[i]
+                break
+            else:
+                indices[i] = 0
+                offset -= self.arr.backstrides[i]
+        else:
+            done = True
+        res = instantiate(ViewIterator)
+        res.offset = offset
+        res.indices = indices
+        res.arr = self.arr
+        res._done = done
+        return res
+
+    def done(self):
+        return self._done
+
+    def get_offset(self):
+        return self.offset
+
+class BroadcastIterator(BaseIterator):
+    '''Like a view iterator, but will repeatedly access values
+       for all iterations across a res_shape, folding the offset
+       using mod() arithmetic
+    '''
+    def __init__(self, arr, res_shape):
+        self.indices = [0] * len(res_shape)
+        self.offset  = arr.start
+        #strides are 0 where original shape==1
+        self.strides = []
+        self.backstrides = []
+        for i in range(len(arr.shape)):
+            if arr.shape[i] == 1:
+                self.strides.append(0)
+                self.backstrides.append(0)
+            else:
+                self.strides.append(arr.strides[i])
+                self.backstrides.append(arr.backstrides[i])
+        self.res_shape = res_shape
+        self.strides = [0] * (len(res_shape) - len(arr.shape)) + self.strides
+        self.backstrides = [0] * (len(res_shape) - len(arr.shape)) + 
self.backstrides
+        self._done = False
+
+    @jit.unroll_safe
+    def next(self, shapelen):
+        offset = self.offset
+        indices = [0] * shapelen
+        _done = False
+        for i in range(shapelen):
+            indices[i] = self.indices[i]
+        for i in range(shapelen - 1, -1, -1):
+            if indices[i] < self.res_shape[i] - 1:
+                indices[i] += 1
+                offset += self.strides[i]
+                break
+            else:
+                indices[i] = 0
+                offset -= self.backstrides[i]
+        else:
+            _done = True
+        res = instantiate(BroadcastIterator)
+        res.indices = indices
+        res.offset = offset
+        res._done = _done
+        res.strides = self.strides
+        res.backstrides = self.backstrides
+        res.res_shape = self.res_shape
+        return res
+
+    def done(self):
+        return self._done
+
+    def get_offset(self):
+        return self.offset
+
+class Call2Iterator(BaseIterator):
+    def __init__(self, left, right):
+        self.left = left
+        self.right = right
+
+    def next(self, shapelen):
+        return Call2Iterator(self.left.next(shapelen),
+                             self.right.next(shapelen))
+
+    def done(self):
+        if isinstance(self.left, ConstantIterator):
+            return self.right.done()
+        return self.left.done()
+
+    def get_offset(self):
+        if isinstance(self.left, ConstantIterator):
+            return self.right.get_offset()
+        return self.left.get_offset()
+
+class Call1Iterator(BaseIterator):
+    def __init__(self, child):
+        self.child = child
+
+    def next(self, shapelen):
+        return Call1Iterator(self.child.next(shapelen))
+
+    def done(self):
+        return self.child.done()
+
+    def get_offset(self):
+        return self.child.get_offset()
+
+class ConstantIterator(BaseIterator):
+    def next(self, shapelen):
+        return self
+
+    def done(self):
+        return False
+
+    def get_offset(self):
+        return 0
+
diff --git a/pypy/module/micronumpy/interp_numarray.py 
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -198,199 +198,6 @@
                 n_old_elems_to_use *= old_shape[oldI]
     return new_strides
 
-# Iterators for arrays
-# --------------------
-# all those iterators with the exception of BroadcastIterator iterate over the
-# entire array in C order (the last index changes the fastest). This will
-# yield all elements. Views iterate over indices and look towards strides and
-# backstrides to find the correct position. Notably the offset between
-# x[..., i + 1] and x[..., i] will be strides[-1]. Offset between
-# x[..., k + 1, 0] and x[..., k, i_max] will be backstrides[-2] etc.
-
-# BroadcastIterator works like that, but for indexes that don't change source
-# in the original array, strides[i] == backstrides[i] == 0
-
-class BaseIterator(object):
-    def next(self, shapelen):
-        raise NotImplementedError
-
-    def done(self):
-        raise NotImplementedError
-
-    def get_offset(self):
-        raise NotImplementedError
-
-class ArrayIterator(BaseIterator):
-    def __init__(self, size):
-        self.offset = 0
-        self.size = size
-
-    def next(self, shapelen):
-        arr = instantiate(ArrayIterator)
-        arr.size = self.size
-        arr.offset = self.offset + 1
-        return arr
-
-    def done(self):
-        return self.offset >= self.size
-
-    def get_offset(self):
-        return self.offset
-
-class OneDimIterator(BaseIterator):
-    def __init__(self, start, step, stop):
-        self.offset = start
-        self.step = step
-        self.size = stop * step + start
-
-    def next(self, shapelen):
-        arr = instantiate(OneDimIterator)
-        arr.size = self.size
-        arr.step = self.step
-        arr.offset = self.offset + self.step
-        return arr
-
-    def done(self):
-        return self.offset == self.size
-
-    def get_offset(self):
-        return self.offset
-
-class ViewIterator(BaseIterator):
-    def __init__(self, arr):
-        self.indices = [0] * len(arr.shape)
-        self.offset  = arr.start
-        self.arr     = arr
-        self._done   = False
-
-    @jit.unroll_safe
-    def next(self, shapelen):
-        offset = self.offset
-        indices = [0] * shapelen
-        for i in range(shapelen):
-            indices[i] = self.indices[i]
-        done = False
-        for i in range(shapelen - 1, -1, -1):
-            if indices[i] < self.arr.shape[i] - 1:
-                indices[i] += 1
-                offset += self.arr.strides[i]
-                break
-            else:
-                indices[i] = 0
-                offset -= self.arr.backstrides[i]
-        else:
-            done = True
-        res = instantiate(ViewIterator)
-        res.offset = offset
-        res.indices = indices
-        res.arr = self.arr
-        res._done = done
-        return res
-
-    def done(self):
-        return self._done
-
-    def get_offset(self):
-        return self.offset
-
-class BroadcastIterator(BaseIterator):
-    '''Like a view iterator, but will repeatedly access values
-       for all iterations across a res_shape, folding the offset
-       using mod() arithmetic
-    '''
-    def __init__(self, arr, res_shape):
-        self.indices = [0] * len(res_shape)
-        self.offset  = arr.start
-        #strides are 0 where original shape==1
-        self.strides = []
-        self.backstrides = []
-        for i in range(len(arr.shape)):
-            if arr.shape[i] == 1:
-                self.strides.append(0)
-                self.backstrides.append(0)
-            else:
-                self.strides.append(arr.strides[i])
-                self.backstrides.append(arr.backstrides[i])
-        self.res_shape = res_shape
-        self.strides = [0] * (len(res_shape) - len(arr.shape)) + self.strides
-        self.backstrides = [0] * (len(res_shape) - len(arr.shape)) + 
self.backstrides
-        self._done = False
-
-    @jit.unroll_safe
-    def next(self, shapelen):
-        offset = self.offset
-        indices = [0] * shapelen
-        _done = False
-        for i in range(shapelen):
-            indices[i] = self.indices[i]
-        for i in range(shapelen - 1, -1, -1):
-            if indices[i] < self.res_shape[i] - 1:
-                indices[i] += 1
-                offset += self.strides[i]
-                break
-            else:
-                indices[i] = 0
-                offset -= self.backstrides[i]
-        else:
-            _done = True
-        res = instantiate(BroadcastIterator)
-        res.indices = indices
-        res.offset = offset
-        res._done = _done
-        res.strides = self.strides
-        res.backstrides = self.backstrides
-        res.res_shape = self.res_shape
-        return res
-
-    def done(self):
-        return self._done
-
-    def get_offset(self):
-        return self.offset
-
-class Call2Iterator(BaseIterator):
-    def __init__(self, left, right):
-        self.left = left
-        self.right = right
-
-    def next(self, shapelen):
-        return Call2Iterator(self.left.next(shapelen),
-                             self.right.next(shapelen))
-
-    def done(self):
-        if isinstance(self.left, ConstantIterator):
-            return self.right.done()
-        return self.left.done()
-
-    def get_offset(self):
-        if isinstance(self.left, ConstantIterator):
-            return self.right.get_offset()
-        return self.left.get_offset()
-
-class Call1Iterator(BaseIterator):
-    def __init__(self, child):
-        self.child = child
-
-    def next(self, shapelen):
-        return Call1Iterator(self.child.next(shapelen))
-
-    def done(self):
-        return self.child.done()
-
-    def get_offset(self):
-        return self.child.get_offset()
-
-class ConstantIterator(BaseIterator):
-    def next(self, shapelen):
-        return self
-
-    def done(self):
-        return False
-
-    def get_offset(self):
-        return 0
-
-
 class BaseArray(Wrappable):
     _attrs_ = ["invalidates", "signature", "shape", "strides", "backstrides",
                "start", 'order']
@@ -1327,6 +1134,7 @@
     )
     arr = W_NDimArray(size, shape[:], dtype=dtype, order=order)
     shapelen = len(shape)
+    iters = arr.signature.create_iterator()
     arr_iter = arr.start_iter(arr.shape)
     for i in range(len(elems_w)):
         w_elem = elems_w[i]
diff --git a/pypy/module/micronumpy/signature.py 
b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -1,5 +1,7 @@
 from pypy.rlib.objectmodel import r_dict, compute_identity_hash, compute_hash
 from pypy.rlib.rarithmetic import intmask
+from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
+     BroadcastIterator, OneDimIterator
 
 
 # def components_eq(lhs, rhs):
@@ -35,6 +37,9 @@
     def hash(self):
         return compute_hash(self)
 
+    def create_iter(self, array, cache):
+        raise NotImplementedError
+
 class ViewSignature(Signature):
     def __init__(self, child):
         self.child = child
@@ -50,10 +55,16 @@
     def debug_repr(self):
         return 'Slice(%s)' % self.child.debug_repr()
 
+    def create_iter(self, array, cache):
+        xxxx
+
 class ArraySignature(Signature):
     def debug_repr(self):
         return 'Array'
 
+    def create_iter(self, array, cache):
+        xxx
+
 class ScalarSignature(Signature):
     def debug_repr(self):
         return 'Scalar'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to