[pypy-commit] pypy numpy-refactor: record dtypes

fijal noreply at buildbot.pypy.org
Fri Sep 7 18:33:37 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-refactor
Changeset: r57225:6d3bcbe5016a
Date: 2012-09-07 18:31 +0200
http://bitbucket.org/pypy/pypy/changeset/6d3bcbe5016a/

Log:	record dtypes

diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -259,7 +259,7 @@
     def _prepare_slice_args(self, space, w_idx):
         if space.isinstance_w(w_idx, space.w_str):
             idx = space.str_w(w_idx)
-            dtype = self.find_dtype()
+            dtype = self.dtype
             if not dtype.is_record_type() or idx not in dtype.fields:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "field named %s not defined" % idx))
@@ -369,7 +369,7 @@
         return SliceArray(0, strides, backstrides, new_shape, self)
 
 class SliceArray(BaseConcreteArray):
-    def __init__(self, start, strides, backstrides, shape, parent):
+    def __init__(self, start, strides, backstrides, shape, parent, dtype=None):
         self.strides = strides
         self.backstrides = backstrides
         self.shape = shape
@@ -378,7 +378,9 @@
         self.parent = parent
         self.storage = parent.storage
         self.order = parent.order
-        self.dtype = parent.dtype
+        if dtype is None:
+            dtype = parent.dtype
+        self.dtype = dtype
         self.size = support.product(shape) * self.dtype.itemtype.get_element_size()
         self.start = start
 
diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/arrayimpl/voidbox.py
@@ -0,0 +1,10 @@
+
+from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation
+from pypy.rlib.rawstorage import free_raw_storage, alloc_raw_storage
+
+class VoidBoxStorage(BaseArrayImplementation):
+    def __init__(self, size):
+        self.storage = alloc_raw_storage(size)
+
+    def __del__(self):
+        free_raw_storage(self.storage)
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -20,10 +20,11 @@
         return W_NDimArray(impl)
 
     @classmethod
-    def new_slice(cls, offset, strides, backstrides, shape, parent):
+    def new_slice(cls, offset, strides, backstrides, shape, parent, dtype=None):
         from pypy.module.micronumpy.arrayimpl import concrete
 
-        impl = concrete.SliceArray(offset, strides, backstrides, shape, parent)
+        impl = concrete.SliceArray(offset, strides, backstrides, shape, parent,
+                                   dtype)
         return W_NDimArray(impl)
 
     @classmethod
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -57,12 +57,11 @@
         self.name = name
 
     def apply(self, arr):
-        arr = arr.get_concrete()
         ofs, subdtype = arr.dtype.fields[self.name]
         # strides backstrides are identical, ofs only changes start
-        return W_NDimArray.new_slice(arr.start + ofs, arr.strides[:],
-                                     arr.backstrides[:],
-                                     arr.shape[:], arr, subdtype)
+        return W_NDimArray.new_slice(arr.start + ofs, arr.strides,
+                                     arr.backstrides,
+                                     arr.shape, arr, subdtype)
 
 class Chunks(BaseChunk):
     def __init__(self, l):
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -2184,8 +2184,8 @@
     def test_views(self):
         from _numpypy import array
         a = array([(1, 2), (3, 4)], dtype=[('x', int), ('y', float)])
-        raises(ValueError, 'array([1])["x"]')
-        raises(ValueError, 'a["z"]')
+        raises((IndexError, ValueError), 'array([1])["x"]')
+        raises((IndexError, ValueError), 'a["z"]')
         assert a['x'][1] == 3
         assert a['y'][1] == 4
         a['x'][0] = 15
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -4,6 +4,7 @@
 
 from pypy.interpreter.error import OperationError
 from pypy.module.micronumpy import interp_boxes
+from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage
 from pypy.objspace.std.floatobject import float2string
 from pypy.rlib import rfloat, clibffi
 from pypy.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
@@ -942,16 +943,14 @@
             raise OperationError(space.w_ValueError, space.wrap(
                 "wrong length"))
         items_w = space.fixedview(w_item)
-        # XXX optimize it out one day, but for now we just allocate an
-        #     array
-        arr = create_array([1], dtype)
+        arr = VoidBoxStorage(self.size)
         for i in range(len(items_w)):
             subdtype = dtype.fields[dtype.fieldnames[i]][1]
             ofs, itemtype = self.offsets_and_fields[i]
             w_item = items_w[i]
             w_box = itemtype.coerce(space, subdtype, w_item)
             itemtype.store(arr, 0, ofs, w_box)
-        return interp_boxes.W_VoidBox(arr, 0, arr.dtype)
+        return interp_boxes.W_VoidBox(arr, 0, dtype)
 
     @jit.unroll_safe
     def store(self, arr, i, ofs, box):


More information about the pypy-commit mailing list