[pypy-commit] pypy ufuncapi: do enough parsing, start iterator creation
mattip
noreply at buildbot.pypy.org
Fri Oct 17 15:57:47 CEST 2014
Author: mattip <matti.picus at gmail.com>
Branch: ufuncapi
Changeset: r73994:0acd1768b6b6
Date: 2014-10-16 08:27 -0500
http://bitbucket.org/pypy/pypy/changeset/0acd1768b6b6/
Log: do enough parsing, start iterator creation
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
@@ -347,6 +347,8 @@
return space.wrap(self)
def getitem(self, it, st, op_flags):
+ # TODO: push op_flags and the array onto the iterator
+ # so we can avoid creating a new W_NDimArray each iteration
if op_flags.rw == 'r':
impl = concrete.ConcreteNonWritableArrayWithBase
else:
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
@@ -160,6 +160,21 @@
af2 = ufunc(af)
assert all(af2 == af * 2)
+ def test_frompyfunc_2d_sig(self):
+ def times_2(in_array, out_array):
+ in_flat = in_array.flat
+ out_flat = out_array.flat
+ for i in range(in_array.size):
+ out_flat[i] = in_flat[i] * 2
+ from numpy import frompyfunc, dtype, arange
+ ufunc = frompyfunc([times_2], 1, 1,
+ signature='(m,m)->(m,m)',
+ dtypes=[dtype(int), dtype(int)],
+ )
+ ai = arange(18, dtype=int).reshape(2,3,3)
+ ai2 = ufunc(ai)
+ assert all(ai1 == ai * 2)
+
def test_ufunc_kwargs(self):
from numpy import ufunc, frompyfunc, arange, dtype
def adder(a, b):
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
@@ -580,8 +580,6 @@
if not self.core_enabled:
# func is going to do all the work, it must accept W_NDimArray args
arglist = space.newlist(list(inargs + outargs))
- if not isinstance(func, W_GenericUFuncCaller):
- raise oefmt(space.w_RuntimeError, "cannot do core_enabled frompyfunc")
space.call_args(func, Arguments.frompacked(space, arglist))
if len(outargs) < 2:
return outargs[0]
@@ -607,7 +605,7 @@
# into the array 'inner_dimensions[1:]'. Initialize them to
# 1, for example in the case where the operand broadcasts
# to a core dimension, it won't be visited.
- inner_dimensions = [1] * (self.core_num_dim_ix + 1)
+ inner_dimensions = [1] * (self.core_num_dim_ix + 2)
idim = 0
for i in range(self.nin):
curarg = inargs[i]
@@ -656,7 +654,7 @@
"(size %d is different from %d)", self.name, i, idim,
self.signature, op_dim_size, inner_dimensions[1 + core_dim_index])
idim += 1
- iter_shape = [-1] * (broadcast_ndim + len(outargs))
+ iter_shape = [-1] * (broadcast_ndim + (len(outargs) * num_dims))
j = broadcast_ndim
core_dim_ixs_size = 0
firstdim = broadcast_ndim
@@ -681,13 +679,13 @@
for idim in range(broadcast_ndim):
if idim >= broadcast_ndim -n:
op_axes_arrays[idim][iout] = idim - (broadcast_ndim -n)
- dim_offset = self.core_offsets[iout]
- num_dims = self.core_num_dims[iout]
- for idim in range(num_dims):
- cdi = self.core_dim_ixs[dim_offset + idim]
- iter_shape[j] = inner_dimensions[1 + cdi]
- op_axes_arrays[j][iout] = n + idim
- j += 1
+ dim_offset = self.core_offsets[iout]
+ num_dims = self.core_num_dims[iout]
+ for idim in range(num_dims):
+ cdi = self.core_dim_ixs[dim_offset + idim]
+ iter_shape[j] = inner_dimensions[1 + cdi]
+ op_axes_arrays[j][iout] = n + idim
+ j += 1
core_dim_ixs_size += self.core_num_dims[iout];
# TODO once we support obejct dtypes,
# FAIL with NotImplemented if the other object has
@@ -696,6 +694,8 @@
# TODO parse and handle subok
+ # mimic NpyIter_AdvancedNew with a nditer
+
if isinstance(func, W_GenericUFuncCaller):
pass
# xxx rdo what needs to be done to inner-loop indexing
More information about the pypy-commit
mailing list