[pypy-commit] pypy ufuncapi: almost complete program flow, refactoring needed

mattip noreply at buildbot.pypy.org
Mon Nov 17 22:06:55 CET 2014


Author: mattip <matti.picus at gmail.com>
Branch: ufuncapi
Changeset: r74565:250491ca11a1
Date: 2014-11-17 23:05 +0200
http://bitbucket.org/pypy/pypy/changeset/250491ca11a1/

Log:	almost complete program flow, refactoring needed

diff --git a/pypy/module/micronumpy/nditer.py b/pypy/module/micronumpy/nditer.py
--- a/pypy/module/micronumpy/nditer.py
+++ b/pypy/module/micronumpy/nditer.py
@@ -289,7 +289,7 @@
 class W_NDIter(W_Root):
     _immutable_fields_ = ['ndim', ]
     def __init__(self, space, w_seq, w_flags, w_op_flags, w_op_dtypes,
-                 w_casting, w_op_axes, w_itershape, w_buffersize, order):
+                 w_casting, w_op_axes, w_itershape, buffersize=0, order='K'):
         from pypy.module.micronumpy.ufuncs import find_binop_result_dtype
         
         self.order = order
@@ -578,14 +578,14 @@
 @unwrap_spec(w_flags=WrappedDefault(None), w_op_flags=WrappedDefault(None),
              w_op_dtypes=WrappedDefault(None), order=str,
              w_casting=WrappedDefault(None), w_op_axes=WrappedDefault(None),
-             w_itershape=WrappedDefault(None), w_buffersize=WrappedDefault(None))
-def descr__new__(space, w_subtype, w_seq, w_flags, w_op_flags, w_op_dtypes,
-                 w_casting, w_op_axes, w_itershape, w_buffersize, order='K'):
+             w_itershape=WrappedDefault(None), buffersize=int)
+def descr_new_nditer(space, w_subtype, w_seq, w_flags, w_op_flags, w_op_dtypes,
+                 w_casting, w_op_axes, w_itershape, buffersize=0, order='K'):
     return W_NDIter(space, w_seq, w_flags, w_op_flags, w_op_dtypes, w_casting, w_op_axes,
-                    w_itershape, w_buffersize, order)
+                    w_itershape, buffersize, order)
 
 W_NDIter.typedef = TypeDef('numpy.nditer',
-    __new__ = interp2app(descr__new__),
+    __new__ = interp2app(descr_new_nditer),
 
     __iter__ = interp2app(W_NDIter.descr_iter),
     __getitem__ = interp2app(W_NDIter.descr_getitem),
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -112,7 +112,7 @@
             if var_name not in var_names:
                 var_names[var_name] = ufunc.core_num_dim_ix
                 ufunc.core_num_dim_ix += 1
-            ufunc.core_dim_ixs[cur_core_dim] = var_names[var_name]
+            ufunc.core_dim_ixs.append(var_names[var_name])
             cur_core_dim += 1
             nd += 1
             i = next_comma
@@ -144,7 +144,6 @@
     if cur_arg != ufunc.nargs:
         raise oefmt(space.w_ValueError, '%s at %d in "%s"',
             "incomplete signature: not all arguments found", i, signature)
-    ufunc.core_dim_ixs = ufunc.core_dim_ixs[:cur_core_dim]
     if cur_core_dim == 0:
-        ufunc.core_enabled = 0
+        ufunc.core_enabled = False
     return 0 # for historical reasons, any failures will raise
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
@@ -542,10 +542,10 @@
         #These will be filled in by _parse_signature
         self.core_enabled = True    # False for scalar ufunc, True for generalized ufunc
         self.stack_inputs = stack_inputs
-        self.core_num_dim_ix = 0 # number of distinct dimention names in signature
+        self.core_num_dim_ix = 0 # number of distinct dimension names in signature
         self.core_num_dims = [0] * self.nargs  # number of core dimensions of each nargs
         self.core_offsets = [0] * self.nargs
-        self.core_dim_ixs = [0] * len(signature)
+        self.core_dim_ixs = [] # indices into unique shapes for each arg
 
     def reduce(self, space, w_obj, w_axis, keepdims=False, out=None, dtype=None,
                cumulative=False):
@@ -559,8 +559,8 @@
                  self.name, self.nin, len(args_w))
         for i in range(self.nin):
             inargs[i] = convert_to_array(space, args_w[i])
-        outargs = [None] * min(self.nout, len(args_w)-self.nin)
-        for i in range(len(outargs)):
+        outargs = [None] * self.nout
+        for i in range(len(args_w)-self.nin):
             out = args_w[i+self.nin]
             if space.is_w(out, space.w_None) or out is None:
                 continue
@@ -698,19 +698,35 @@
 
         # TODO parse and handle subok
         # TODO handle flags, op_flags
-        flags = ['external_loop']
-        op_flags = None
+        w_flags = space.w_None #space.newlist([space.wrap('external_loop')])
+        w_op_flags = space.w_None
+        w_op_dtypes = space.w_None
+        w_casting = space.w_None
+        w_itershape = space.newlist([space.wrap(i) for i in iter_shape]) 
+        w_op_axes = space.w_None
 
         # mimic NpyIter_AdvancedNew with a nditer
 
         if self.stack_inputs:
             inargs = inargs + outargs
-            it = W_NDIter(space, space.newlist(inargs + outargs),
-                            flags=flags, op_flags=op_flags)
-            for args in it:
-                space.call_args(func, Arguments.frompacked(space, args))
+            nd_it = W_NDIter(space, space.newlist(inargs + outargs), w_flags,
+                          w_op_flags, w_op_dtypes, w_casting, w_op_axes,
+                          w_itershape)
+            # XXX coalesce each iterators, according to inner_dimensions
+            while not nd_it.done:
+                for it, st in nd_it.iters:
+                    if not it.done(st):
+                        break
+                else:
+                    nd_it.done = True
+                    break
+                args = []
+                for i, (it, st) in enumerate(nd_it.iters):
+                    args.append(nd_it.getitem(it, st))
+                    nd_it.iters[i] = (it, it.next(st))
+                space.call_args(func, Arguments.frompacked(space, space.newlist(args)))
             if len(outargs) > 1:
-                return outargs
+                return space.newtuple([convert_to_array(space, o) for o in outargs])
             return outargs[0]
         inargs0 = inargs[0]
         assert isinstance(inargs0, W_NDimArray)
@@ -1147,9 +1163,9 @@
     name: str, default=''
     doc: str, default=''
     stack_inputs*: boolean, whether the function is of the form
-            out = func(*in)     False
+            out = func(*in)  False
             or
-            func(*in_out)       True
+            func(*in_out)    True (forces use of a nditer with 'external_loop')
 
     only one of out_dtype or signature may be specified
 
@@ -1218,6 +1234,9 @@
     if len(signature) == 0:
         # cpython compatability, func is of the form (i),(i)->(i)
         signature = ','.join(['(i)'] * nin) + '->' + ','.join(['(i)'] * nout)
+    else:
+        #stack_inputs = True
+        pass
 
     w_ret = W_UfuncGeneric(space, func, name, identity, nin, nout, dtypes,
                            signature, match_dtypes=match_dtypes,


More information about the pypy-commit mailing list