summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattip <matti.picus@gmail.com>2018-10-10 11:19:33 +0300
committermattip <matti.picus@gmail.com>2018-10-11 17:18:02 +0300
commit7ef2b3ab61907958b879b34c8e790fcca302f004 (patch)
tree2f79c57ce54807809a7b899999233f1c41a6f0c8
parentb0308d1a65935fc1df7411875598890b16983d62 (diff)
downloadnumpy-7ef2b3ab61907958b879b34c8e790fcca302f004.tar.gz
MAINT: formatting, remove version, rework flags
-rw-r--r--doc/source/reference/c-api.generalized-ufuncs.rst17
-rw-r--r--doc/source/reference/c-api.types-and-structures.rst20
-rw-r--r--numpy/core/include/numpy/ufuncobject.h10
-rw-r--r--numpy/core/src/umath/_umath_tests.c.src26
-rw-r--r--numpy/core/src/umath/ufunc_object.c25
-rw-r--r--numpy/core/tests/test_ufunc.py20
6 files changed, 53 insertions, 65 deletions
diff --git a/doc/source/reference/c-api.generalized-ufuncs.rst b/doc/source/reference/c-api.generalized-ufuncs.rst
index dce198013..b59f077ad 100644
--- a/doc/source/reference/c-api.generalized-ufuncs.rst
+++ b/doc/source/reference/c-api.generalized-ufuncs.rst
@@ -149,11 +149,13 @@ Notes:
Here are some examples of signatures:
+-------------+----------------------------+-----------------------------------+
-| add | ``(),()->()`` | |
+| name | signature | common usage |
++=============+============================+===================================+
+| add | ``(),()->()`` | binary ufunc |
+-------------+----------------------------+-----------------------------------+
-| sum1d | ``(i)->()`` | |
+| sum1d | ``(i)->()`` | reduction |
+-------------+----------------------------+-----------------------------------+
-| inner1d | ``(i),(i)->()`` | |
+| inner1d | ``(i),(i)->()`` | vector-vector multiplication |
+-------------+----------------------------+-----------------------------------+
| matmat | ``(m,n),(n,p)->(m,p)`` | matrix multiplication |
+-------------+----------------------------+-----------------------------------+
@@ -167,10 +169,15 @@ Here are some examples of signatures:
| | | outer over the second to last, |
| | | and loop/broadcast over the rest. |
+-------------+----------------------------+-----------------------------------+
-| cross1d | ``(3),(3)->(3)`` | cross product where the last |
-| | | dimension must be 3 |
+| cross1d | ``(3),(3)->(3)`` | cross product where the last |
+| | | dimension is frozen and must be 3 |
+-------------+----------------------------+-----------------------------------+
+.. _frozen:
+
+The last is an instance of freezing a core dimension and can be used to
+improve ufunc performance
+
C-API for implementing Elementary Functions
-------------------------------------------
diff --git a/doc/source/reference/c-api.types-and-structures.rst b/doc/source/reference/c-api.types-and-structures.rst
index 51818142a..0766f5a3f 100644
--- a/doc/source/reference/c-api.types-and-structures.rst
+++ b/doc/source/reference/c-api.types-and-structures.rst
@@ -734,8 +734,8 @@ PyUFunc_Type
npy_uint32 *op_flags;
npy_uint32 *iter_flags;
/* new in API version 0x0000000D */
- npy_intp *core_dim_sizes;
- npy_intp *core_dim_flags;
+ npy_intp *core_dim_sizes;
+ npy_intp *core_dim_flags;
} PyUFuncObject;
@@ -796,11 +796,9 @@ PyUFunc_Type
specifies how many different 1-d loops (of the builtin data
types) are available.
- .. c:member:: int PyUFuncObject.version
+ .. c:member:: int PyUFuncObject.reserved1
- The ``NPY_API_VERSION`` used during the call to
- :c:func:`PyUFunc_FromFuncAndDataAndSignature`. If less than
- 0x0000000D, ``core_dim_sizes`` and ``core_dim_flags`` will be ignored.
+ Unused.
.. c:member:: char *PyUFuncObject.name
@@ -901,15 +899,15 @@ PyUFunc_Type
.. c:member:: npy_intp *PyUFuncObject.core_dim_sizes
For each distinct core dimension, the possible
- "frozen" size (``-1`` if not frozen)
+ :ref:`frozen <frozen>` size (``-1`` if not frozen)
.. c:member:: npy_uint32 *PyUFuncObject.core_dim_flags
- For each distinct core dimension, a set of flags ``OR`` ed together:
+ For each distinct core dimension, a set of ``UFUNC_CORE_DIM*`` flags
- - :c:data:`UFUNC_CORE_CAN_IGNORE` if the dim name ends in ``?``
- - :c:data:`UFUNC_CORE_DIM_SIZE_UNSET` if the dim size will be
- determined by the operands (not frozen)
+ - :c:data:`UFUNC_CORE_DIM_CAN_IGNORE` if the dim name ends in ``?``
+ - :c:data:`UFUNC_CORE_DIM_SIZE_INFERRED` if the dim size will be
+ determined from the operands and not from a :ref:`frozen <frozen>` signature
PyArrayIter_Type
----------------
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index e24da04af..4786e73d7 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -130,8 +130,8 @@ typedef struct _tagPyUFuncObject {
/* The number of elements in 'functions' and 'data' */
int ntypes;
- /* Used to be unused field 'check_return', repurposed in 1.16 */
- const int version;
+ /* Used to be unused field 'check_return' */
+ int reserved1;
/* The name of the ufunc */
const char *name;
@@ -219,9 +219,7 @@ typedef struct _tagPyUFuncObject {
npy_intp *core_dim_sizes;
/*
- * for each distinct core dimension, a set of flags OR'd together
- * e.g., UFUNC_CORE_DIM_CAN_IGNORE if signature has ?
- * UFUNC_CORE_DIM_SIZE_UNSET for non-frozen dimensions.
+ * for each distinct core dimension, a set of UFUNC_CORE_DIM* flags
*/
npy_uint32 *core_dim_flags;
@@ -232,7 +230,7 @@ typedef struct _tagPyUFuncObject {
#include "arrayobject.h"
/* Generalized ufunc; 0x0001 reserved for possible use as CORE_ENABLED */
/* the core dimension's size will be determined by the operands. */
-#define UFUNC_CORE_DIM_SIZE_UNSET 0x0002
+#define UFUNC_CORE_DIM_SIZE_INFERRED 0x0002
/* the core dimension may be absent */
#define UFUNC_CORE_DIM_CAN_IGNORE 0x0004
/* flags inferred during execution */
diff --git a/numpy/core/src/umath/_umath_tests.c.src b/numpy/core/src/umath/_umath_tests.c.src
index f0347cef8..8cb74f177 100644
--- a/numpy/core/src/umath/_umath_tests.c.src
+++ b/numpy/core/src/umath/_umath_tests.c.src
@@ -335,29 +335,29 @@ defdict = {
Ufunc(2, 1, None_,
r'''inner on the last dimension and broadcast on the rest \n"
" \"(i),(i)->()\" \n''',
- TD('ld'),
- ),
+ TD('ld'),
+ ),
'innerwt' :
Ufunc(3, 1, None_,
- r'''inner1d with a weight argument \n"
- " \"(i),(i),(i)->()\" \n''',
- TD('ld'),
- ),
+ r'''inner1d with a weight argument \n"
+ " \"(i),(i),(i)->()\" \n''',
+ TD('ld'),
+ ),
}
*/
static PyUFuncGenericFunction inner1d_functions[] = { LONG_inner1d, DOUBLE_inner1d };
-static void * inner1d_data[] = { (void *)NULL, (void *)NULL };
+static void *inner1d_data[] = { (void *)NULL, (void *)NULL };
static char inner1d_signatures[] = { NPY_LONG, NPY_LONG, NPY_LONG, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
static PyUFuncGenericFunction innerwt_functions[] = { LONG_innerwt, DOUBLE_innerwt };
-static void * innerwt_data[] = { (void *)NULL, (void *)NULL };
+static void *innerwt_data[] = { (void *)NULL, (void *)NULL };
static char innerwt_signatures[] = { NPY_LONG, NPY_LONG, NPY_LONG, NPY_LONG, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
static PyUFuncGenericFunction matrix_multiply_functions[] = { LONG_matrix_multiply, FLOAT_matrix_multiply, DOUBLE_matrix_multiply };
static void *matrix_multiply_data[] = { (void *)NULL, (void *)NULL, (void *)NULL };
static char matrix_multiply_signatures[] = { NPY_LONG, NPY_LONG, NPY_LONG, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
static PyUFuncGenericFunction cross1d_functions[] = { LONG_cross1d, DOUBLE_cross1d };
-static void * cross1d_data[] = { (void *)NULL, (void *)NULL };
+static void *cross1d_data[] = { (void *)NULL, (void *)NULL };
static char cross1d_signatures[] = { NPY_LONG, NPY_LONG, NPY_LONG, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
static PyUFuncGenericFunction euclidean_pdist_functions[] =
{ FLOAT_euclidean_pdist, DOUBLE_euclidean_pdist };
@@ -366,7 +366,7 @@ static char euclidean_pdist_signatures[] = { NPY_FLOAT, NPY_FLOAT,
NPY_DOUBLE, NPY_DOUBLE };
static PyUFuncGenericFunction cumsum_functions[] = { LONG_cumsum, DOUBLE_cumsum };
-static void * cumsum_data[] = { (void *)NULL, (void *)NULL };
+static void *cumsum_data[] = { (void *)NULL, (void *)NULL };
static char cumsum_signatures[] = { NPY_LONG, NPY_LONG, NPY_DOUBLE, NPY_DOUBLE };
@@ -527,7 +527,7 @@ UMath_Tests_test_signature(PyObject *NPY_UNUSED(dummy), PyObject *args)
goto fail;
}
for (i = 0; i < core_num_ixs; i++) {
- PyObject * val = PyLong_FromLong(f->core_dim_ixs[i]);
+ PyObject *val = PyLong_FromLong(f->core_dim_ixs[i]);
PyTuple_SET_ITEM(core_dim_ixs, i, val);
}
}
@@ -541,7 +541,7 @@ UMath_Tests_test_signature(PyObject *NPY_UNUSED(dummy), PyObject *args)
goto fail;
}
for (i = 0; i < f->core_num_dim_ix; i++) {
- PyObject * val = PyLong_FromLong(f->core_dim_flags[i]);
+ PyObject *val = PyLong_FromLong(f->core_dim_flags[i]);
PyTuple_SET_ITEM(core_dim_flags, i, val);
}
}
@@ -555,7 +555,7 @@ UMath_Tests_test_signature(PyObject *NPY_UNUSED(dummy), PyObject *args)
goto fail;
}
for (i = 0; i < f->core_num_dim_ix; i++) {
- PyObject * val = PyLong_FromLong(f->core_dim_sizes[i]);
+ PyObject *val = PyLong_FromLong(f->core_dim_sizes[i]);
PyTuple_SET_ITEM(core_dim_sizes, i, val);
}
}
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index c3e1c62a8..5d477d479 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -652,7 +652,7 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
var_names[ix] = signature + i;
ufunc->core_dim_sizes[ix] = frozen_size;
if (frozen_size < 0) {
- ufunc->core_dim_flags[ix] |= UFUNC_CORE_DIM_SIZE_UNSET;
+ ufunc->core_dim_flags[ix] |= UFUNC_CORE_DIM_SIZE_INFERRED;
}
if (can_ignore) {
ufunc->core_dim_flags[ix] |= UFUNC_CORE_DIM_CAN_IGNORE;
@@ -2353,7 +2353,7 @@ _parse_axis_arg(PyUFuncObject *ufunc, int core_num_dims[], PyObject *axis,
* an output argument that were not specified in an input argument,
* and whose size could not be inferred from a passed in output
* argument, would have their size set to 1.
- * * Core dimensions may be fixed, new in ufunc->version 1 (NumPy 1.16)
+ * * Core dimensions may be fixed, new in NumPy 1.16
*/
static int
_get_coredim_sizes(PyUFuncObject *ufunc, PyArrayObject **op,
@@ -2492,23 +2492,9 @@ _initialize_variable_parts(PyUFuncObject *ufunc,
for (i = 0; i < ufunc->nargs; i++) {
op_core_num_dims[i] = ufunc->core_num_dims[i];
}
- if (ufunc->version >= 0x0000d) {
- for (i = 0; i < ufunc->core_num_dim_ix; i++) {
- core_dim_sizes[i] = ufunc->core_dim_sizes[i];
- core_dim_flags[i] = ufunc->core_dim_flags[i];
- }
- }
- else if (ufunc->version == 0) {
- for (i = 0; i < ufunc->core_num_dim_ix; i++) {
- core_dim_sizes[i] = -1;
- core_dim_flags[i] = UFUNC_CORE_DIM_SIZE_UNSET;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "'%s': unrecognized version number %d or corrupted data.",
- ufunc_get_name_cstr(ufunc), ufunc->version);
- return -1;
+ for (i = 0; i < ufunc->core_num_dim_ix; i++) {
+ core_dim_sizes[i] = ufunc->core_dim_sizes[i];
+ core_dim_flags[i] = ufunc->core_dim_flags[i];
}
return 0;
}
@@ -4868,7 +4854,6 @@ PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void **data,
return NULL;
}
memset(ufunc, 0, sizeof(PyUFuncObject));
- *((int*)&ufunc->version) = NPY_API_VERSION;
PyObject_Init((PyObject *)ufunc, &PyUFunc_Type);
ufunc->nin = nin;
diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py
index c0cca9e56..fbb6cfcd5 100644
--- a/numpy/core/tests/test_ufunc.py
+++ b/numpy/core/tests/test_ufunc.py
@@ -287,7 +287,7 @@ class TestUfunc(object):
pass
# from include/numpy/ufuncobject.h
- size_unset = 2
+ size_inferred = 2
can_ignore = 4
def test_signature0(self):
# the arguments to test_signature are: nin, nout, core_signature
@@ -296,7 +296,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (1, 1, 0))
assert_equal(ixs, (0, 0))
- assert_equal(flags, (self.size_unset,))
+ assert_equal(flags, (self.size_inferred,))
assert_equal(sizes, (-1,))
def test_signature1(self):
@@ -316,7 +316,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (2, 1, 1))
assert_equal(ixs, (0, 1, 2, 3))
- assert_equal(flags, (self.size_unset,)*4)
+ assert_equal(flags, (self.size_inferred,)*4)
assert_equal(sizes, (-1, -1, -1, -1))
def test_signature3(self):
@@ -325,7 +325,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (2, 1, 2))
assert_equal(ixs, (0, 1, 2, 1, 3))
- assert_equal(flags, (self.size_unset,)*4)
+ assert_equal(flags, (self.size_inferred,)*4)
assert_equal(sizes, (-1, -1, -1, -1))
def test_signature4(self):
@@ -335,7 +335,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (2, 2, 2))
assert_equal(ixs, (0, 1, 1, 2, 0, 2))
- assert_equal(flags, (self.size_unset,)*3)
+ assert_equal(flags, (self.size_inferred,)*3)
assert_equal(sizes, (-1, -1, -1))
def test_signature5(self):
@@ -345,9 +345,9 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (2, 2, 2))
assert_equal(ixs, (0, 1, 1, 2, 0, 2))
- assert_equal(flags, (self.size_unset | self.can_ignore,
- self.size_unset,
- self.size_unset | self.can_ignore))
+ assert_equal(flags, (self.size_inferred | self.can_ignore,
+ self.size_inferred,
+ self.size_inferred | self.can_ignore))
assert_equal(sizes, (-1, -1, -1))
def test_signature6(self):
@@ -365,7 +365,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (1, 2, 1, 1))
assert_equal(ixs, (0, 0, 0, 1, 2))
- assert_equal(flags, (0, self.size_unset, 0))
+ assert_equal(flags, (0, self.size_inferred, 0))
assert_equal(sizes, (3, -1, 9))
def test_signature8(self):
@@ -374,7 +374,7 @@ class TestUfunc(object):
assert_equal(enabled, 1)
assert_equal(num_dims, (1, 2, 1, 1))
assert_equal(ixs, (0, 0, 0, 1, 2))
- assert_equal(flags, (self.can_ignore, self.size_unset, 0))
+ assert_equal(flags, (self.can_ignore, self.size_inferred, 0))
assert_equal(sizes, (3, -1, 9))
def test_signature_failure0(self):