Author: Matti Picus <[email protected]>
Branch: str-dtype-improvement
Changeset: r62391:aaadf6eca9d9
Date: 2013-03-17 13:45 -0700
http://bitbucket.org/pypy/pypy/changeset/aaadf6eca9d9/
Log: implement convert_from for str arrays only
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
@@ -47,13 +47,10 @@
if impl.is_scalar():
self.fill(impl.get_scalar_value())
return
- if self.dtype.is_str_or_unicode():
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "concatenate(%s) not implemented yet" % self.dtype))
shape = shape_agreement(space, self.get_shape(), arr)
if impl.storage == self.storage:
- impl = impl.copy()
- loop.setslice(shape, self, impl)
+ impl = impl.copy(space)
+ loop.setslice(space, shape, self, impl)
def get_size(self):
return self.size // self.dtype.itemtype.get_element_size()
@@ -244,12 +241,12 @@
return SliceArray(self.start, strides,
backstrides, shape, self, orig_array)
- def copy(self):
+ def copy(self, space):
strides, backstrides = support.calc_strides(self.get_shape(),
self.dtype,
self.order)
impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides,
backstrides)
- return loop.setslice(self.get_shape(), impl, self)
+ return loop.setslice(space, self.get_shape(), impl, self)
def create_axis_iter(self, shape, dim, cum):
return iter.AxisIterator(self, shape, dim, cum)
@@ -284,7 +281,7 @@
raise OperationError(space.w_NotImplementedError, space.wrap(
"astype(%s) not implemented yet" % self.dtype))
else:
- loop.setslice(new_arr.get_shape(), new_arr.implementation, self)
+ loop.setslice(space, new_arr.get_shape(), new_arr.implementation,
self)
return new_arr
class ConcreteArrayNotOwning(BaseConcreteArray):
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py
b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -47,7 +47,7 @@
def set_scalar_value(self, w_val):
self.value = w_val.convert_to(self.dtype)
- def copy(self):
+ def copy(self, space):
scalar = Scalar(self.dtype)
scalar.value = self.value
return scalar
diff --git a/pypy/module/micronumpy/interp_dtype.py
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -71,6 +71,8 @@
def box_complex(self, real, imag):
return self.itemtype.box_complex(real, imag)
+ def convert_from(self, space, box):
+ return self.itemtype.convert_from(space, self, box)
def coerce(self, space, w_item):
return self.itemtype.coerce(space, self, w_item)
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
@@ -252,7 +252,7 @@
return self.implementation.get_scalar_value()
def descr_copy(self, space):
- return W_NDimArray(self.implementation.copy())
+ return W_NDimArray(self.implementation.copy(space))
def descr_get_real(self, space):
return W_NDimArray(self.implementation.get_real(self))
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -65,26 +65,32 @@
obj_iter.next()
return out
-setslice_driver = jit.JitDriver(name='numpy_setslice',
+setslice_driver1 = jit.JitDriver(name='numpy_setslice1',
greens = ['shapelen', 'dtype'],
- reds = ['target', 'source', 'target_iter',
- 'source_iter'])
+ reds = 'auto')
+setslice_driver2 = jit.JitDriver(name='numpy_setslice2',
+ greens = ['shapelen', 'dtype'],
+ reds = 'auto')
-def setslice(shape, target, source):
+def setslice(space, shape, target, source):
# note that unlike everything else, target and source here are
# array implementations, not arrays
target_iter = target.create_iter(shape)
source_iter = source.create_iter(shape)
dtype = target.dtype
shapelen = len(shape)
- while not target_iter.done():
- setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype,
- target=target, source=source,
- target_iter=target_iter,
- source_iter=source_iter)
- target_iter.setitem(source_iter.getitem().convert_to(dtype))
- target_iter.next()
- source_iter.next()
+ if dtype.is_str_or_unicode():
+ while not target_iter.done():
+ setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype)
+ target_iter.setitem(dtype.convert_from(space,
source_iter.getitem()))
+ target_iter.next()
+ source_iter.next()
+ else:
+ while not target_iter.done():
+ setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype)
+ target_iter.setitem(source_iter.getitem().convert_to(dtype))
+ target_iter.next()
+ source_iter.next()
return target
reduce_driver = jit.JitDriver(name='numpy_reduce',
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
@@ -1480,13 +1480,10 @@
a = (a + a)[::2]
b = concatenate((a[:3], a[-3:]))
assert (b == [2, 6, 10, 2, 6, 10]).all()
- try:
- a = concatenate((array([1]), array(['abc'])))
- assert a.dtype == 'S3'
- a = concatenate((array([]), array(['abc'])))
- assert a[0] == 'abc'
- except NotImplementedError:
- skip('cannot concatenate numeric with string')
+ a = concatenate((array([1]), array(['abc'])))
+ assert str(a.dtype) == '|S3'
+ a = concatenate((array([]), array(['abc'])))
+ assert a[0] == 'abc'
def test_record_concatenate(self):
# only an exact match can succeed
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
@@ -1627,6 +1627,7 @@
def get_size(self):
return self.size
+
class StringType(BaseType, BaseStringType):
T = lltype.Char
@@ -1642,7 +1643,7 @@
@jit.unroll_safe
def store(self, arr, i, offset, box):
assert isinstance(box, interp_boxes.W_StringBox)
- for k in range(min(self.size, box.arr.size-offset)):
+ for k in range(min(self.size - i, box.arr.size-offset)):
arr.storage[k + i] = box.arr.storage[k + offset]
def read(self, arr, i, offset, dtype=None):
@@ -1675,6 +1676,20 @@
def to_builtin_type(self, space, box):
return space.wrap(self.to_str(box))
+ def convert_from(self, space, mydtype, box):
+ if box.get_dtype(space).is_str_or_unicode():
+ arg = box.get_dtype(space).itemtype.to_str(box)
+ else:
+ w_arg = box.descr_str(space)
+ arg = space.str_w(space.str(w_arg))
+ arr = VoidBoxStorage(self.size, mydtype)
+ i = 0
+ for i in range(min(len(arg), self.size)):
+ arr.storage[i] = arg[i]
+ for j in range(i + 1, self.size):
+ arr.storage[j] = '\x00'
+ return interp_boxes.W_StringBox(arr, 0, arr.dtype)
+
class VoidType(BaseType, BaseStringType):
T = lltype.Char
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit