diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-04-18 18:00:09 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-04-18 18:00:09 +0000 |
commit | ae43872a80811507385bb4175a550d5d40d6eece (patch) | |
tree | ce0cfbdbffb6ec4b0e45d1677ed08dd320a0be16 | |
parent | 5d5d80f54e09b5bb220c3e92a5703ab3cdc53ab5 (diff) | |
download | numpy-ae43872a80811507385bb4175a550d5d40d6eece.tar.gz |
Changed error look-up to use per-thread global variable.
-rw-r--r-- | numpy/core/numeric.py | 77 | ||||
-rw-r--r-- | numpy/core/src/ufuncobject.c | 90 | ||||
-rw-r--r-- | numpy/core/src/umathmodule.c.src | 6 |
3 files changed, 101 insertions, 72 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 8bab9008b..ad19f5b99 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -374,7 +374,7 @@ def ones(shape, dtype=int_, order='C'): return a def identity(n,dtype=int_): - """identity(n) returns the identity matrix of shape n x n. + """identity(n) returns the identity 2-d array of shape n x n. """ a = array([1]+n*[0],dtype=dtype) b = empty((n,n),dtype=dtype) @@ -394,36 +394,6 @@ def allclose (a, b, rtol=1.e-5, atol=1.e-8): d = less(absolute(x-y), atol + rtol * absolute(y)) return d.ravel().all() -def _setpyvals(lst, frame, where=0): - if not isinstance(lst, list) or len(lst) != 3: - raise ValueError, "Invalid pyvalues (length 3 list needed)." - - try: - wh = where.lower()[0] - except (AttributeError, TypeError, IndexError): - wh = None - - if where==0 or wh == 'l': - frame.f_locals[UFUNC_PYVALS_NAME] = lst - elif where == 1 or wh == 'g': - frame.f_globals[UFUNC_PYVALS_NAME] = lst - elif where == 2 or wh == 'b': - frame.f_builtins[UFUNC_PYVALS_NAME] = lst - - umath.update_use_defaults() - return - -def _getpyvals(frame): - try: - return frame.f_locals[UFUNC_PYVALS_NAME] - except KeyError: - try: - return frame.f_globals[UFUNC_PYVALS_NAME] - except KeyError: - try: - return frame.f_builtins[UFUNC_PYVALS_NAME] - except KeyError: - return [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None] _errdict = {"ignore":ERR_IGNORE, "warn":ERR_WARN, @@ -436,21 +406,21 @@ for key in _errdict.keys(): del key def seterr(divide="ignore", over="ignore", under="ignore", - invalid="ignore", where=0): + invalid="ignore"): + maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) + (_errdict[over] << SHIFT_OVERFLOW ) + (_errdict[under] << SHIFT_UNDERFLOW) + (_errdict[invalid] << SHIFT_INVALID)) - frame = sys._getframe().f_back - pyvals = _getpyvals(frame) - pyvals[1] = maskvalue - _setpyvals(pyvals, frame, where) + pyvals = umath.geterrlist() + old = pyvals[:] + pyvals[1] = maskvalue + umath.seterrlist(pyvals) + return old def geterr(): - frame = sys._getframe().f_back - maskvalue = _getpyvals(frame)[1] - + maskvalue = umath.geterrlist()[1] mask = 3 res = {} val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask @@ -463,37 +433,34 @@ def geterr(): res['invalid'] = _errdict_rev[val] return res -def setbufsize(size, where=0): +def setbufsize(size): if size > 10e6: raise ValueError, "Very big buffers.. %s" % size - frame = sys._getframe().f_back - pyvals = _getpyvals(frame) + pyvals = umath.geterrlist() + old = pyvals[:] pyvals[0] = size - _setpyvals(pyvals, frame, where) + umath.seterrlist(pyvals) + return old def getbufsize(): - frame = sys._getframe().f_back - return _getpyvals(frame)[0] + return umath.geterrlist()[0] -def seterrcall(func, where=0): +def seterrcall(func): if not callable(func): raise ValueError, "Only callable can be used as callback" - frame = sys._getframe().f_back - pyvals = _getpyvals(frame) + pyvals = umath.geterrlist() + old = pyvals[:] pyvals[2] = func - _setpyvals(pyvals, frame, where) + umath.seterrlist(pyvals) + return old def geterrcall(): - frame = sys._getframe().f_back - return _getpyvals(frame)[2] + return umath.geterrlist()[2] def _setdef(): - frame = sys._getframe() defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None] - frame.f_globals[UFUNC_PYVALS_NAME] = defval - frame.f_builtins[UFUNC_PYVALS_NAME] = defval - umath.update_use_defaults() + umath.seterrlist(defval) # set the default values _setdef() diff --git a/numpy/core/src/ufuncobject.c b/numpy/core/src/ufuncobject.c index d1afb0467..ee2314ca1 100644 --- a/numpy/core/src/ufuncobject.c +++ b/numpy/core/src/ufuncobject.c @@ -698,6 +698,7 @@ select_types(PyUFuncObject *self, int *arg_types, } static int PyUFunc_USEDEFAULTS=0; +static PyObject *PyUFunc_PYVALS_NAME=NULL; /*UFUNC_API*/ static int @@ -706,22 +707,26 @@ PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject **errobj) PyObject *thedict; PyObject *ref=NULL; PyObject *retval; - static PyObject *thestring=NULL; if (!PyUFunc_USEDEFAULTS) { - if (thestring == NULL) { - thestring = PyString_InternFromString(UFUNC_PYVALS_NAME); + if (PyUFunc_PYVALS_NAME == NULL) { + PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME); } - thedict = PyEval_GetLocals(); - ref = PyDict_GetItem(thedict, thestring); - if (ref == NULL) { - thedict = PyEval_GetGlobals(); - ref = PyDict_GetItem(thedict, thestring); - } - if (ref == NULL) { + thedict = PyThreadState_GetDict(); + if (thedict == NULL) { thedict = PyEval_GetBuiltins(); - ref = PyDict_GetItem(thedict, thestring); } + ref = PyDict_GetItem(thedict, PyUFunc_PYVALS_NAME); +/* thedict = PyEval_GetLocals(); */ +/* ref = PyDict_GetItem(thedict, thestring); */ +/* if (ref == NULL) { */ +/* thedict = PyEval_GetGlobals(); */ +/* ref = PyDict_GetItem(thedict, thestring); */ +/* } */ +/* if (ref == NULL) { */ +/* thedict = PyEval_GetBuiltins(); */ +/* ref = PyDict_GetItem(thedict, thestring); */ +/* } */ } if (ref == NULL) { *errmask = UFUNC_ERR_DEFAULT; @@ -2743,26 +2748,81 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) } static PyObject * -ufunc_update_use_defaults(PyObject *dummy, PyObject *args) +ufunc_geterr(PyObject *dummy, PyObject *args) +{ + PyObject *thedict; + PyObject *res; + + if (!PyArg_ParseTuple(args, "")) return NULL; + + if (PyUFunc_PYVALS_NAME == NULL) { + PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME); + } + thedict = PyThreadState_GetDict(); + if (thedict == NULL) { + thedict = PyEval_GetBuiltins(); + } + res = PyDict_GetItem(thedict, PyUFunc_PYVALS_NAME); + if (res != NULL) { + Py_INCREF(res); + return res; + } + /* Construct list of defaults */ + res = PyList_New(3); + if (res == NULL) return NULL; + PyList_SET_ITEM(res, 0, PyInt_FromLong(PyArray_BUFSIZE)); + PyList_SET_ITEM(res, 1, PyInt_FromLong(UFUNC_ERR_DEFAULT)); + PyList_SET_ITEM(res, 2, Py_None); Py_INCREF(Py_None); + return res; +} + +static int +ufunc_update_use_defaults(void) { PyObject *errobj; int errmask, bufsize; - if (!PyArg_ParseTuple(args, "")) return NULL; - PyUFunc_USEDEFAULTS = 0; - if (PyUFunc_GetPyValues("test", &bufsize, &errmask, &errobj) < 0) return NULL; + if (PyUFunc_GetPyValues("test", &bufsize, &errmask, &errobj) < 0) return -1; if ((errmask == UFUNC_ERR_DEFAULT) && \ (bufsize == PyArray_BUFSIZE) && \ (PyTuple_GET_ITEM(errobj, 1) == Py_None)) { PyUFunc_USEDEFAULTS = 1; } + return 0; +} + +static PyObject * +ufunc_seterr(PyObject *dummy, PyObject *args) +{ + PyObject *thedict; + int res; + PyObject *val; + + if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &val)) return NULL; + if (PyList_GET_SIZE(val) < 3) { + PyErr_SetString(PyExc_ValueError, + "Error object Must be a list of length 3"); + return NULL; + } + if (PyUFunc_PYVALS_NAME == NULL) { + PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME); + } + thedict = PyThreadState_GetDict(); + if (thedict == NULL) { + thedict = PyEval_GetBuiltins(); + } + res = PyDict_SetItem(thedict, PyUFunc_PYVALS_NAME, val); + if (res < 0) return NULL; + if (ufunc_update_use_defaults() < 0) return NULL; Py_INCREF(Py_None); return Py_None; } + + static PyUFuncGenericFunction pyfunc_functions[] = {PyUFunc_On_Om}; static char diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src index b35597447..461671818 100644 --- a/numpy/core/src/umathmodule.c.src +++ b/numpy/core/src/umathmodule.c.src @@ -2262,8 +2262,10 @@ InitOtherOperators(PyObject *dictionary) { static struct PyMethodDef methods[] = { {"frompyfunc", (PyCFunction) ufunc_frompyfunc, METH_VARARGS | METH_KEYWORDS, doc_frompyfunc}, - {"update_use_defaults", (PyCFunction) ufunc_update_use_defaults, - METH_VARARGS , NULL}, + {"seterrlist", (PyCFunction) ufunc_seterr, + METH_VARARGS, NULL}, + {"geterrlist", (PyCFunction) ufunc_geterr, + METH_VARARGS, NULL}, {NULL, NULL, 0} /* sentinel */ }; |