[pypy-commit] pypy ufuncapi: pass resolver tests, still need to use results in creating output arrays

mattip noreply at buildbot.pypy.org
Tue Dec 2 12:52:32 CET 2014


Author: mattip <matti.picus at gmail.com>
Branch: ufuncapi
Changeset: r74781:af2cb61cc4b1
Date: 2014-12-02 13:50 +0200
http://bitbucket.org/pypy/pypy/changeset/af2cb61cc4b1/

Log:	pass resolver tests, still need to use results in creating output
	arrays

diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -108,18 +108,25 @@
 
     def test_type_resolver(self, space):
         c128_dtype = get_dtype_cache(space).w_complex128dtype
+        c64_dtype = get_dtype_cache(space).w_complex64dtype
         f64_dtype = get_dtype_cache(space).w_float64dtype
+        f32_dtype = get_dtype_cache(space).w_float32dtype
         u32_dtype = get_dtype_cache(space).w_uint32dtype
         b_dtype = get_dtype_cache(space).w_booldtype
 
-        ufunc = W_UfuncGeneric(space, [None, None], 'eigenvals', None, 1, 1,
-                     [f64_dtype, c128_dtype, c128_dtype, c128_dtype],
+        ufunc = W_UfuncGeneric(space, [None, None, None], 'eigenvals', None, 1, 1,
+                     [f32_dtype, c64_dtype, 
+                      f64_dtype, c128_dtype, 
+                      c128_dtype, c128_dtype],
                      '')
-        f64 = W_NDimArray(VoidBoxStorage(0, f64_dtype))
-        c128 = W_NDimArray(VoidBoxStorage(0, c128_dtype))
-        index, dtypes = ufunc.type_resolver(space, [f64], [c128], 'd->D')
+        f32_array = W_NDimArray(VoidBoxStorage(0, f32_dtype))
+        index, dtypes = ufunc.type_resolver(space, [f32_array], [None], 'd->D')
+        #needs to cast input type, create output type
+        assert index == 1
+        assert dtypes == [f64_dtype, c128_dtype]
+        index, dtypes = ufunc.type_resolver(space, [f32_array], [None], '')
         assert index == 0
-        assert dtypes == [f64_dtype, c128_dtype]
+        assert dtypes == [f32_dtype, c64_dtype]
 
 
 class AppTestUfuncs(BaseNumpyAppTest):
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -6,7 +6,9 @@
 from rpython.rlib import jit
 from rpython.rlib.rarithmetic import LONG_BIT, maxint
 from rpython.tool.sourcetools import func_with_new_name
-from pypy.module.micronumpy import boxes, descriptor, loop, constants as NPY
+from pypy.module.micronumpy import boxes, loop, constants as NPY
+from pypy.module.micronumpy.descriptor import (get_dtype_cache,
+            variable_dtype, decode_w_dtype)
 from pypy.module.micronumpy.base import convert_to_array, W_NDimArray
 from pypy.module.micronumpy.ctors import numpify
 from pypy.module.micronumpy.nditer import W_NDIter, coalesce_iter
@@ -201,10 +203,10 @@
             if axis < 0:
                 axis += shapelen
         assert axis >= 0
-        dtype = descriptor.decode_w_dtype(space, dtype)
+        dtype = decode_w_dtype(space, dtype)
         if dtype is None:
             if self.comparison_func:
-                dtype = descriptor.get_dtype_cache(space).w_booldtype
+                dtype = get_dtype_cache(space).w_booldtype
             else:
                 dtype = find_unaryop_result_dtype(
                     space, obj.get_dtype(),
@@ -360,14 +362,14 @@
             #    raise oefmt(space.w_TypeError,
             #        "Cannot cast ufunc %s output from dtype('%s') to dtype('%s') with casting rule 'same_kind'", self.name, w_obj.get_dtype().name, res_dtype.name)
         elif self.bool_result:
-            res_dtype = descriptor.get_dtype_cache(space).w_booldtype
+            res_dtype = get_dtype_cache(space).w_booldtype
         else:
             res_dtype = calc_dtype
             if self.complex_to_float and calc_dtype.is_complex():
                 if calc_dtype.num == NPY.CFLOAT:
-                    res_dtype = descriptor.get_dtype_cache(space).w_float32dtype
+                    res_dtype = get_dtype_cache(space).w_float32dtype
                 else:
-                    res_dtype = descriptor.get_dtype_cache(space).w_float64dtype
+                    res_dtype = get_dtype_cache(space).w_float64dtype
         if w_obj.is_scalar():
             w_val = self.func(calc_dtype,
                               w_obj.get_scalar_value().convert_to(space, calc_dtype))
@@ -474,7 +476,7 @@
             out = w_out
             calc_dtype = out.get_dtype()
         if self.comparison_func:
-            res_dtype = descriptor.get_dtype_cache(space).w_booldtype
+            res_dtype = get_dtype_cache(space).w_booldtype
         else:
             res_dtype = calc_dtype
         if w_lhs.is_scalar() and w_rhs.is_scalar():
@@ -559,6 +561,7 @@
                  self.name, self.nin, len(args_w))
         for i in range(self.nin):
             inargs[i] = convert_to_array(space, args_w[i])
+            assert isinstance(inargs[i], W_NDimArray)
         outargs = [None] * self.nout
         for i in range(len(args_w)-self.nin):
             out = args_w[i+self.nin]
@@ -784,7 +787,7 @@
             if sig:
                 raise oefmt(space.w_RuntimeError,
                         "cannot specify both 'sig' and 'dtype'")
-            dtype = descriptor.decode_w_dtype(space, dtype_w)
+            dtype = decode_w_dtype(space, dtype_w)
             sig = space.newtuple([dtype])
         order = kwargs_w.pop('dtype', None)
         if not space.is_w(order, space.w_None) and not order is None:
@@ -810,32 +813,54 @@
         # linear_search_type_resolver in numpy ufunc_type_resolutions.c
         # type_tup can be '', a tuple of dtypes, or a string
         # of the form d,t -> D where the letters are dtype specs
-        inargs0 = inargs[0]
-        assert isinstance(inargs0, W_NDimArray)
         nop = len(inargs) + len(outargs)
         dtypes = []
-        if isinstance(type_tup, str):
+        if isinstance(type_tup, str) and len(type_tup) > 0:
             if len(type_tup) == 1:
                 dtypes = [get_dtype_cache(space).dtypes_by_name[type_tup]] * self.nargs
             elif len(type_tup) == self.nargs + 2:
-                for i in range(len(inargs)):
-                    dtypes.append(get_dtype_cache(space).dtype_by_name[type_tup[i]])
+                for i in range(self.nin):
+                    dtypes.append(get_dtype_cache(space).dtypes_by_name[type_tup[i]])
                 #skip the '->' in the signature
-                for i in range(len(self.nout)):
-                    dtypes.append(get_dtype_cache(space).dtype_by_name[type_tup[i+2]])
+                for i in range(self.nout):
+                    j = i + self.nin + 2
+                    dtypes.append(get_dtype_cache(space).dtypes_by_name[type_tup[j]])
             else:
-                raise oefmt(space.w_TypeError, "a type-string for %s," \
+                raise oefmt(space.w_TypeError, "a type-string for %s " \
                     "requires 1 typecode or %d typecode(s) before and %d" \
-                    " after the -> sign", self.name, self.nin, self.nout)
+                    " after the -> sign, not '%s'", self.name, self.nin, 
+                    self.nout, type_tup)
+        else:
+            # XXX does not pass translation
+            # dtypes = [i.get_dtype() for i in inargs]
+            for i in inargs:
+                if isinstance(i, W_NDimArray):
+                    dtypes.append(i.get_dtype())
+                else:
+                    dtypes.append(None)
+            for i in outargs:
+                if isinstance(i, W_NDimArray):
+                    dtypes.append(i.get_dtype())
+                else:
+                    dtypes.append(None)
+        #Find the first matchup of dtypes with self.dtypes
         for i in range(0, len(self.dtypes), self.nargs):
-            if inargs0.get_dtype() == self.dtypes[i]:
+            allok = True
+            for j in range(self.nargs):
+                if dtypes[j] is not None and dtypes[j] != self.dtypes[i+j]:
+                    allok = False
+            if allok:    
                 break
         else:
             if len(self.funcs) < 2:
                 return 0, dtypes
             raise oefmt(space.w_TypeError,
-                         'input dtype %s did not match any known dtypes',
-                                              str(inargs0.get_dtype()))
+                         'input dtype did not match any known dtypes',
+                       )
+        # Fill in empty dtypes
+        for j in range(self.nargs):
+            if dtypes[j] is None:
+                dtypes[j] = self.dtypes[i+j]
         return i / self.nargs, dtypes
 
     def alloc_outargs(self, space, index, inargs, outargs, dtypes):
@@ -880,7 +905,7 @@
         dt1, dt2 = dt2, dt1
     # Some operations promote op(bool, bool) to return int8, rather than bool
     if promote_bools and (dt1.kind == dt2.kind == NPY.GENBOOLLTR):
-        return descriptor.get_dtype_cache(space).w_int8dtype
+        return get_dtype_cache(space).w_int8dtype
 
     # Everything numeric promotes to complex
     if dt2.is_complex() or dt1.is_complex():
@@ -888,16 +913,16 @@
             dt1, dt2 = dt2, dt1
         if dt2.num == NPY.CFLOAT:
             if dt1.num == NPY.DOUBLE:
-                return descriptor.get_dtype_cache(space).w_complex128dtype
+                return get_dtype_cache(space).w_complex128dtype
             elif dt1.num == NPY.LONGDOUBLE:
-                return descriptor.get_dtype_cache(space).w_complexlongdtype
-            return descriptor.get_dtype_cache(space).w_complex64dtype
+                return get_dtype_cache(space).w_complexlongdtype
+            return get_dtype_cache(space).w_complex64dtype
         elif dt2.num == NPY.CDOUBLE:
             if dt1.num == NPY.LONGDOUBLE:
-                return descriptor.get_dtype_cache(space).w_complexlongdtype
-            return descriptor.get_dtype_cache(space).w_complex128dtype
+                return get_dtype_cache(space).w_complexlongdtype
+            return get_dtype_cache(space).w_complex128dtype
         elif dt2.num == NPY.CLONGDOUBLE:
-            return descriptor.get_dtype_cache(space).w_complexlongdtype
+            return get_dtype_cache(space).w_complexlongdtype
         else:
             raise OperationError(space.w_TypeError, space.wrap("Unsupported types"))
 
@@ -912,11 +937,11 @@
     # Everything promotes to float, and bool promotes to everything.
     if dt2.kind == NPY.FLOATINGLTR or dt1.kind == NPY.GENBOOLLTR:
         if dt2.num == NPY.HALF and dt1.itemtype.get_element_size() == 2:
-            return descriptor.get_dtype_cache(space).w_float32dtype
+            return get_dtype_cache(space).w_float32dtype
         if dt2.num == NPY.HALF and dt1.itemtype.get_element_size() >= 4:
-            return descriptor.get_dtype_cache(space).w_float64dtype
+            return get_dtype_cache(space).w_float64dtype
         if dt2.num == NPY.FLOAT and dt1.itemtype.get_element_size() >= 4:
-            return descriptor.get_dtype_cache(space).w_float64dtype
+            return get_dtype_cache(space).w_float64dtype
         return dt2
 
     # for now this means mixing signed and unsigned
@@ -942,7 +967,7 @@
     else:
         # increase to the next signed type
         dtypenum = dt2.num + 1
-    newdtype = descriptor.get_dtype_cache(space).dtypes_by_num[dtypenum]
+    newdtype = get_dtype_cache(space).dtypes_by_num[dtypenum]
 
     if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size() or
             newdtype.kind == NPY.FLOATINGLTR):
@@ -951,7 +976,7 @@
         # we only promoted to long on 32-bit or to longlong on 64-bit
         # this is really for dealing with the Long and Ulong dtypes
         dtypenum += 2
-        return descriptor.get_dtype_cache(space).dtypes_by_num[dtypenum]
+        return get_dtype_cache(space).dtypes_by_num[dtypenum]
 
 
 @jit.unroll_safe
@@ -960,21 +985,21 @@
     if promote_to_largest:
         if dt.kind == NPY.GENBOOLLTR or dt.kind == NPY.SIGNEDLTR:
             if dt.elsize * 8 < LONG_BIT:
-                return descriptor.get_dtype_cache(space).w_longdtype
+                return get_dtype_cache(space).w_longdtype
         elif dt.kind == NPY.UNSIGNEDLTR:
             if dt.elsize * 8 < LONG_BIT:
-                return descriptor.get_dtype_cache(space).w_ulongdtype
+                return get_dtype_cache(space).w_ulongdtype
         else:
             assert dt.kind == NPY.FLOATINGLTR or dt.kind == NPY.COMPLEXLTR
         return dt
     if promote_bools and (dt.kind == NPY.GENBOOLLTR):
-        return descriptor.get_dtype_cache(space).w_int8dtype
+        return get_dtype_cache(space).w_int8dtype
     if promote_to_float:
         if dt.kind == NPY.FLOATINGLTR or dt.kind == NPY.COMPLEXLTR:
             return dt
         if dt.num >= NPY.INT:
-            return descriptor.get_dtype_cache(space).w_float64dtype
-        for bytes, dtype in descriptor.get_dtype_cache(space).float_dtypes_by_num_bytes:
+            return get_dtype_cache(space).w_float64dtype
+        for bytes, dtype in get_dtype_cache(space).float_dtypes_by_num_bytes:
             if (dtype.kind == NPY.FLOATINGLTR and
                     dtype.itemtype.get_element_size() >
                     dt.itemtype.get_element_size()):
@@ -983,12 +1008,12 @@
 
 
 def find_dtype_for_scalar(space, w_obj, current_guess=None):
-    bool_dtype = descriptor.get_dtype_cache(space).w_booldtype
-    long_dtype = descriptor.get_dtype_cache(space).w_longdtype
-    int64_dtype = descriptor.get_dtype_cache(space).w_int64dtype
-    uint64_dtype = descriptor.get_dtype_cache(space).w_uint64dtype
-    complex_dtype = descriptor.get_dtype_cache(space).w_complex128dtype
-    float_dtype = descriptor.get_dtype_cache(space).w_float64dtype
+    bool_dtype = get_dtype_cache(space).w_booldtype
+    long_dtype = get_dtype_cache(space).w_longdtype
+    int64_dtype = get_dtype_cache(space).w_int64dtype
+    uint64_dtype = get_dtype_cache(space).w_uint64dtype
+    complex_dtype = get_dtype_cache(space).w_complex128dtype
+    float_dtype = get_dtype_cache(space).w_float64dtype
     if isinstance(w_obj, boxes.W_GenericBox):
         dtype = w_obj.get_dtype(space)
         return find_binop_result_dtype(space, dtype, current_guess)
@@ -1012,11 +1037,11 @@
         return complex_dtype
     elif space.isinstance_w(w_obj, space.w_str):
         if current_guess is None:
-            return descriptor.variable_dtype(space,
+            return variable_dtype(space,
                                                'S%d' % space.len_w(w_obj))
         elif current_guess.num == NPY.STRING:
             if current_guess.elsize < space.len_w(w_obj):
-                return descriptor.variable_dtype(space,
+                return variable_dtype(space,
                                                    'S%d' % space.len_w(w_obj))
         return current_guess
     raise oefmt(space.w_NotImplementedError,
@@ -1033,7 +1058,7 @@
             raise oefmt(space.w_NotImplementedError,
                         "%s not implemented for %s",
                         ufunc_name, dtype.get_name())
-    dtype_cache = descriptor.get_dtype_cache(space)
+    dtype_cache = get_dtype_cache(space)
     if nin == 1:
         def impl(res_dtype, value):
             res = get_op(res_dtype)(value)
@@ -1162,7 +1187,7 @@
         identity = extra_kwargs.get("identity")
         if identity is not None:
             identity = \
-                descriptor.get_dtype_cache(space).w_longdtype.box(identity)
+                get_dtype_cache(space).w_longdtype.box(identity)
         extra_kwargs["identity"] = identity
 
         func = ufunc_dtype_caller(space, ufunc_name, op_name, nin,
@@ -1264,7 +1289,7 @@
             else:
                 dtypes = [None]*len(_dtypes)
                 for i in range(len(dtypes)):
-                    dtypes[i] = descriptor.decode_w_dtype(space, _dtypes[i])
+                    dtypes[i] = decode_w_dtype(space, _dtypes[i])
     else:
         raise oefmt(space.w_ValueError,
             'dtypes must be None or a list of dtypes')
@@ -1273,7 +1298,7 @@
         identity =  None
     elif space.isinstance_w(w_identity, space.w_int):
         identity = \
-            descriptor.get_dtype_cache(space).w_longdtype.box(space.int_w(w_identity))
+            get_dtype_cache(space).w_longdtype.box(space.int_w(w_identity))
     else:
         raise oefmt(space.w_ValueError,
             'identity must be None or an int')


More information about the pypy-commit mailing list