diff options
author | cookedm <cookedm@localhost> | 2006-02-21 23:09:12 +0000 |
---|---|---|
committer | cookedm <cookedm@localhost> | 2006-02-21 23:09:12 +0000 |
commit | ede85cec1879d0d18a797749ccf7fc1853a2146e (patch) | |
tree | 450ae37baa762c4357125e428d185aedb8105ac9 /numpy/core/src | |
parent | bb23ed753f0548e79bf3371cc7c6a3ec81187bb4 (diff) | |
parent | 0aa85cabe66a188a409e51e04186a050ba6d2d79 (diff) | |
download | numpy-ede85cec1879d0d18a797749ccf7fc1853a2146e.tar.gz |
Merge trunk (r2124:2142) to power optimization branch
Diffstat (limited to 'numpy/core/src')
-rw-r--r-- | numpy/core/src/arraymethods.c | 2 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 2 | ||||
-rw-r--r-- | numpy/core/src/arraytypes.inc.src | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 18 | ||||
-rw-r--r-- | numpy/core/src/scalartypes.inc.src | 3 | ||||
-rw-r--r-- | numpy/core/src/ufuncobject.c | 128 | ||||
-rw-r--r-- | numpy/core/src/umathmodule.c.src | 1 |
7 files changed, 124 insertions, 32 deletions
diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index 4c077bbcd..fe87009e0 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -1198,7 +1198,7 @@ static char doc_sum[] = "a.sum(axis=None, dtype=None)\n\n"\ "2.0\n"\ ">>> array([0.5, 1.5]).sum(dtype=int32)\n"\ "1\n"\ - ">>> array([[0, 1], [0, 5]]).sum()\n"\ + ">>> array([[0, 1], [0, 5]]).sum(axis=0)\n"\ "array([0, 6])\n"\ ">>> array([[0, 1], [0, 5]]).sum(axis=1)\n"\ "array([1, 5])"; diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index ef9fdd6e9..ba47ffd19 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5771,7 +5771,7 @@ PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp) if (simple) { char *inptr; char *optr = out->data; - intp obytes = out->descr->elsize * outsize; + intp obytes = out->descr->elsize * mpsize; intp ncopies = outsize / mpsize; while(ncopies--) { diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src index 468728154..0fd105ab1 100644 --- a/numpy/core/src/arraytypes.inc.src +++ b/numpy/core/src/arraytypes.inc.src @@ -238,7 +238,7 @@ UNICODE_getitem(char *ip, PyArrayObject *ap) } else buffer = ip; #ifdef Py_UNICODE_WIDE - obj = PyUnicode_FromUnicode((const PyArray_UCS4 *)buffer, mysize); + obj = PyUnicode_FromUnicode((const Py_UNICODE *)buffer, mysize); #else /* create new empty unicode object of length mysize*2 */ obj = MyPyUnicode_New(mysize*2); diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index b5bc6af6a..481e5709a 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -3385,16 +3385,16 @@ _use_inherit(PyArray_Descr *type, PyObject *newobj, int *errflag) PyErr_SetString(PyExc_ValueError, "cannot base a new descriptor on an"\ " OBJECT descriptor."); - return NULL; + goto fail; } new = PyArray_DescrNew(type); - if (new == NULL) return NULL; + if (new == NULL) goto fail; if (new->elsize && new->elsize != conv->elsize) { PyErr_SetString(PyExc_ValueError, "mismatch in size of old"\ "and new data-descriptor"); - return NULL; + goto fail; } new->elsize = conv->elsize; if (conv->fields != Py_None) { @@ -3404,6 +3404,11 @@ _use_inherit(PyArray_Descr *type, PyObject *newobj, int *errflag) Py_DECREF(conv); *errflag = 0; return new; + + fail: + Py_DECREF(conv); + return NULL; + } static PyArray_Descr * @@ -3448,7 +3453,7 @@ _convert_from_tuple(PyObject *obj) else { /* interpret next item as shape (if it's a tuple) and reset the type to PyArray_VOID with - anew fields attribute. + a new fields attribute. */ PyArray_Dims shape={NULL,-1}; PyArray_Descr *newdescr; @@ -3460,7 +3465,8 @@ _convert_from_tuple(PyObject *obj) goto fail; } /* If (type, 1) was given, it is equivalent to type... */ - if (shape.len == 1 && shape.ptr[0] == 1 && PyNumber_Check(val)) { + if (shape.len == 1 && shape.ptr[0] == 1 && \ + PyNumber_Check(val)) { PyDimMem_FREE(shape.ptr); return type; } @@ -4203,7 +4209,7 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin) static char doc_fromobject[] = "array(object, dtype=None, copy=1, fortran=0, "\ "subok=0,ndmin=0)\n"\ "will return a new array formed from the given object type given.\n"\ - "Object can anything with an __array__ method, or any object\n"\ + "Object can be anything with an __array__ method, or any object\n"\ "exposing the array interface, or any (nested) sequence.\n"\ "If no type is given, then the type will be determined as the\n"\ "minimum type required to hold the objects in the sequence.\n"\ diff --git a/numpy/core/src/scalartypes.inc.src b/numpy/core/src/scalartypes.inc.src index 2f48ff041..9926cd83c 100644 --- a/numpy/core/src/scalartypes.inc.src +++ b/numpy/core/src/scalartypes.inc.src @@ -205,8 +205,9 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) if (PyArray_ISOBJECT(r)) { Py_INCREF(*((PyObject **)memptr)); } - +#ifndef Py_UNICODE_WIDE finish: +#endif if (outcode == NULL) return r; if (outcode->type_num == typecode->type_num) { diff --git a/numpy/core/src/ufuncobject.c b/numpy/core/src/ufuncobject.c index 4b6c152a5..e09b1ffd5 100644 --- a/numpy/core/src/ufuncobject.c +++ b/numpy/core/src/ufuncobject.c @@ -859,7 +859,7 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps) /* Check number of arguments */ nargs = PyTuple_Size(args); - if ((nargs != self->nin) && (nargs != self->nargs)) { + if ((nargs < self->nin) || (nargs > self->nargs)) { PyErr_SetString(PyExc_ValueError, "invalid number of arguments"); return -1; @@ -2507,8 +2507,24 @@ PyUFunc_GenericReduction(PyUFuncObject *self, PyObject *args, } -static PyObject * -_find_array_wrap(PyObject *args) +/* This function analyzes the input arguments + and determines an appropriate __array_wrap__ function to call + for the outputs. + + If an output argument is provided, then it is wrapped + with its own __array_wrap__ not with the one determined by + the input arguments. + + if the provided output argument is already an array, + the wrapping function is None (which means no wrapping will + be done --- not even PyArray_Return). + + A NULL is placed in output_wrap for outputs that + should just have PyArray_Return called. + */ + +static void +_find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout) { int nargs, i; int np = 0; @@ -2517,7 +2533,7 @@ _find_array_wrap(PyObject *args) PyObject *obj, *wrap = NULL; nargs = PyTuple_GET_SIZE(args); - for (i=0; i<nargs; i++) { + for (i=0; i<nin; i++) { obj = PyTuple_GET_ITEM(args, i); if (PyArray_CheckExact(obj) || PyBigArray_CheckExact(obj) || \ PyArray_IsAnyScalar(obj)) @@ -2537,21 +2553,71 @@ _find_array_wrap(PyObject *args) PyErr_Clear(); } } - if (np < 2) - return wrap; - wrap = wraps[0]; - maxpriority = PyArray_GetPriority(with_wrap[0], PyArray_SUBTYPE_PRIORITY); - for (i = 1; i < np; ++i) { - priority = PyArray_GetPriority(with_wrap[i], PyArray_SUBTYPE_PRIORITY); - if (priority > maxpriority) { - maxpriority = priority; - Py_DECREF(wrap); - wrap = wraps[i]; - } else { - Py_DECREF(wraps[i]); - } - } - return wrap; + if (np >= 2) { + wrap = wraps[0]; + maxpriority = PyArray_GetPriority(with_wrap[0], + PyArray_SUBTYPE_PRIORITY); + for (i = 1; i < np; ++i) { + priority = \ + PyArray_GetPriority(with_wrap[i], + PyArray_SUBTYPE_PRIORITY); + if (priority > maxpriority) { + maxpriority = priority; + Py_DECREF(wrap); + wrap = wraps[i]; + } else { + Py_DECREF(wraps[i]); + } + } + } + + /* Here wrap is the wrapping function determined from the + input arrays (could be NULL). + + For all the output arrays decide what to do. + + 1) Use the wrap function determined from the input arrays + This is the default if the output array is not + passed in. + + 2) Use the __array_wrap__ method of the output object + passed in. -- this is special cased for + exact ndarray so that no PyArray_Return is + done in that case. + */ + + for (i=0; i<nout; i++) { + int j = nin + i; + int incref=1; + output_wrap[i] = wrap; + if (j < nargs) { + obj = PyTuple_GET_ITEM(args, j); + if (obj == Py_None) + continue; + if (PyArray_CheckExact(obj) || + PyBigArray_CheckExact(obj)) { + output_wrap[i] = Py_None; + } + else { + PyObject *owrap; + owrap = PyObject_GetAttrString \ + (obj,"__array_wrap__"); + incref=0; + if (!(owrap) || !(PyCallable_Check(owrap))) { + Py_XDECREF(owrap); + owrap = wrap; + incref=1; + PyErr_Clear(); + } + output_wrap[i] = owrap; + } + } + if (incref) { + Py_XINCREF(output_wrap[i]); + } + } + + return; } static PyObject * @@ -2561,8 +2627,8 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) PyTupleObject *ret; PyArrayObject *mps[MAX_ARGS]; PyObject *retobj[MAX_ARGS]; + PyObject *wraparr[MAX_ARGS]; PyObject *res; - PyObject *wrap; int errval; /* Initialize all array objects to NULL to make cleanup easier @@ -2582,17 +2648,30 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) for(i=0; i<self->nin; i++) Py_DECREF(mps[i]); + /* Use __array_wrap__ on all outputs if present on one of the input arguments. If present for multiple inputs: use __array_wrap__ of input object with largest __array_priority__ (default = 0.0) */ - wrap = _find_array_wrap(args); + + /* Exception: we should not wrap outputs for items already + passed in as output-arguments. These items should either + be left unwrapped or wrapped by calling their own __array_wrap__ + routine. + + For each output argument, wrap will be either + NULL --- call PyArray_Return() -- default if no output arguments given + None --- array-object passed in don't call PyArray_Return + method --- the __array_wrap__ method to call. + */ + _find_array_wrap(args, wraparr, self->nin, self->nout); /* wrap outputs */ for (i=0; i<self->nout; i++) { int j=self->nin+i; + PyObject *wrap; /* check to see if any UPDATEIFCOPY flags are set which meant that a temporary output was generated */ @@ -2603,7 +2682,13 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) back into old */ mps[j] = (PyArrayObject *)old; } + wrap = wraparr[i]; if (wrap != NULL) { + if (wrap == Py_None) { + Py_DECREF(wrap); + retobj[i] = (PyObject *)mps[j]; + continue; + } res = PyObject_CallFunction(wrap, "O(OOi)", mps[j], self, args, i); if (res == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -2619,6 +2704,7 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) continue; } } + /* default behavior */ retobj[i] = PyArray_Return(mps[j]); } diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src index fd6f0ab44..896371e65 100644 --- a/numpy/core/src/umathmodule.c.src +++ b/numpy/core/src/umathmodule.c.src @@ -7,7 +7,6 @@ #include "abstract.h" #include <math.h> - /* A whole slew of basic math functions are provided originally by Konrad Hinsen. */ |