[Numpy-svn] r3056 - in trunk/numpy/core: . code_generators include/numpy src
numpy-svn at scipy.org
numpy-svn at scipy.org
Thu Aug 24 04:36:56 EDT 2006
Author: oliphant
Date: 2006-08-24 03:36:48 -0500 (Thu, 24 Aug 2006)
New Revision: 3056
Modified:
trunk/numpy/core/code_generators/generate_array_api.py
trunk/numpy/core/fromnumeric.py
trunk/numpy/core/include/numpy/ndarrayobject.h
trunk/numpy/core/include/numpy/npy_interrupt.h
trunk/numpy/core/ma.py
trunk/numpy/core/numeric.py
trunk/numpy/core/src/arraymethods.c
trunk/numpy/core/src/multiarraymodule.c
Log:
Add rudimentary interrupt handliNG. Add max, min, round, abs to the numpy space.
Modified: trunk/numpy/core/code_generators/generate_array_api.py
===================================================================
--- trunk/numpy/core/code_generators/generate_array_api.py 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/code_generators/generate_array_api.py 2006-08-24 08:36:48 UTC (rev 3056)
@@ -20,6 +20,7 @@
npy_bool obval;
} PyBoolScalarObject;
+
static unsigned int PyArray_GetNDArrayCVersion (void);
static PyTypeObject PyBigArray_Type;
static PyTypeObject PyArray_Type;
Modified: trunk/numpy/core/fromnumeric.py
===================================================================
--- trunk/numpy/core/fromnumeric.py 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/fromnumeric.py 2006-08-24 08:36:48 UTC (rev 3056)
@@ -379,6 +379,8 @@
return _wrapit(a, 'max', axis, out)
return amax(axis, out)
+max = amax
+
def amin(a, axis=None, out=None):
"""Return the minimum of a along dimension axis.
"""
@@ -388,6 +390,8 @@
return _wrapit(a, 'min', axis, out)
return amin(axis, out)
+min = amin
+
def alen(a):
"""Return the length of a Python object interpreted as an array
of at least 1 dimension.
@@ -458,6 +462,8 @@
around = round_
+round = round_
+
def mean(a, axis=None, dtype=None, out=None):
"""mean(a, axis=None, dtype=None)
Return the arithmetic mean.
Modified: trunk/numpy/core/include/numpy/ndarrayobject.h
===================================================================
--- trunk/numpy/core/include/numpy/ndarrayobject.h 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/include/numpy/ndarrayobject.h 2006-08-24 08:36:48 UTC (rev 3056)
@@ -1384,6 +1384,7 @@
does not have ARR_HAS_DESCR flag set) */
} PyArrayInterface;
+
/* Includes the "function" C-API -- these are all stored in a
list of pointers --- one for each file
The two lists are concatenated into one in multiarray.
Modified: trunk/numpy/core/include/numpy/npy_interrupt.h
===================================================================
--- trunk/numpy/core/include/numpy/npy_interrupt.h 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/include/numpy/npy_interrupt.h 2006-08-24 08:36:48 UTC (rev 3056)
@@ -10,8 +10,8 @@
****Warning***************
Do not allow code that creates temporary memory or increases reference
-counts of Python objects to be interrupted unless you handle decrementing
-the reference counts and freeing any allocated memory in the clean-up code.
+counts of Python objects to be interrupted unless you handle it
+differently.
**************************
@@ -21,7 +21,7 @@
and store the old one.
- run the code to be interrupted -- if an interrupt occurs
the handler should basically just cause a return to the
- calling function for clean-up work.
+ calling function for finish work.
- restore the old signal handler
Of course, every code that allows interrupts must account for
@@ -32,74 +32,90 @@
1) platform portability (i.e. Microsoft says not to use longjmp
to return from signal handling. They have a __try and __except
extension to C instead but what about mingw?).
- 2) how to handle threads
- a) apparently whether signals are delivered to every thread of
- the process or the "invoking" thread is platform dependent.
- b) if we use global variables to save state, then how is this
- to be done in a thread-safe way.
- 3) A general-purpose facility must allow for the possibility of
- re-entrance (i.e. during execution of the code that is allowed
- to interrupt, we might call back into this very section of code
- serially).
+ 2) how to handle threads: apparently whether signals are delivered to
+ every thread of the process or the "invoking" thread is platform
+ dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance. For now, assume the
+ code will not call-back into itself.
+
Ideas:
1) Start by implementing an approach that works on platforms that
can use setjmp and longjmp functionality and does nothing
- on other platforms. Initially only catch SIGINT.
+ on other platforms.
- 2) Handle threads by storing global information in a linked-list
- with a process-id key. Then use a call-back function that longjmps
- only to the correct buffer.
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
- 3) Store a local copy of the global information and restore it on clean-up
- so that re-entrance works.
+ 3) Add a default signal_handler function to the C-API but have the rest
+ use macros.
-Interface:
+Simple Interface:
-In your C-extension. around a block of code you want to be interruptable
-NPY_SIG_TRY {
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
[code]
-}
-NPY_SIG_EXCEPT(sigval) {
-[signal return]
-}
-NPY_SIG_ELSE
-[normal return]
+NPY_SIGINT_OFF
-sigval is a local variable that will receive what
-signal was received. You can use it to perform different
-actions based on the signal received.
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects. In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
-Default actions (setting of specific Python errors)
-can be obtained with
+Interrupt handling does not work well with threads.
-NPY_SIG_TRY {
-[code]
-NPY_SIG_EXCEPT_GOTO(label)
-[normal return]
-
-label:
- [error return]
*/
/* Add signal handling macros */
#ifndef NPY_INTERRUPT_H
#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
-#ifdef NPY_NO_SIGNAL
+#ifndef sigsetjmp
-#define NPY_SIG_ON
-#define NPY_SIG_OFF
+#define SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define SIGJMP_BUF jmp_buf
#else
-#define NPY_SIG_ON
-#define NPY_SIG_OFF
+#define SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define SIGJMP_BUF sigjmp_buf
-#endif /* NPY_NO_SIGNAL */
+#endif
+SIGJMP_BUF _NPY_SIGINT_BUF;
+
+static void
+_npy_sighandler(int signum)
+{
+ PyOS_setsig(signum, SIG_IGN);
+ SIGLONGJMP(_NPY_SIGINT_BUF, signum);
+}
+
+
+# define NPY_SIGINT_ON { \
+ PyOS_sighandler_t _npy_sig_save; \
+ _npy_sig_save = PyOS_setsig(SIGINT, _npy_sighandler); \
+ if (SIGSETJMP(_NPY_SIGINT_BUF, 1) == 0) { \
+
+# define NPY_SIGINT_OFF } \
+ PyOS_setsig(SIGINT, _npy_sig_save); \
+ }
+
+#else /* NPY_NO_SIGNAL */
+
+# define NPY_SIGINT_ON
+# define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
#endif /* NPY_INTERRUPT_H */
Modified: trunk/numpy/core/ma.py
===================================================================
--- trunk/numpy/core/ma.py 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/ma.py 2006-08-24 08:36:48 UTC (rev 3056)
@@ -2144,7 +2144,6 @@
return MethodType(f, None, array)
def not_implemented(*args, **kwds):
raise NotImplementedError, "not yet implemented for numpy.ma arrays"
-array.abs = array.__abs__
array.all = _m(alltrue)
array.any = _m(sometrue)
array.argmax = _m(argmax)
Modified: trunk/numpy/core/numeric.py
===================================================================
--- trunk/numpy/core/numeric.py 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/numeric.py 2006-08-24 08:36:48 UTC (rev 3056)
@@ -95,6 +95,8 @@
extend_all(umath)
extend_all(numerictypes)
+abs = absolute
+
newaxis = None
ndarray = multiarray.ndarray
Modified: trunk/numpy/core/src/arraymethods.c
===================================================================
--- trunk/numpy/core/src/arraymethods.c 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/src/arraymethods.c 2006-08-24 08:36:48 UTC (rev 3056)
@@ -252,8 +252,6 @@
return PyArray_Min(self, axis, out);
}
-static char doc_abs[] = "a.abs() returns abs(a)";
-
static char doc_swapaxes[] = "a.swapaxes(axis1, axis2) returns new view with axes swapped.";
static PyObject *
@@ -1808,8 +1806,6 @@
METH_VARARGS|METH_KEYWORDS, doc_min},
{"ptp", (PyCFunction)array_ptp,
METH_VARARGS|METH_KEYWORDS, doc_ptp},
- {"abs", (PyCFunction)array_absolute,
- METH_VARARGS, doc_abs},
{"mean", (PyCFunction)array_mean,
METH_VARARGS|METH_KEYWORDS, doc_mean},
{"trace", (PyCFunction)array_trace,
Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c 2006-08-23 23:39:42 UTC (rev 3055)
+++ trunk/numpy/core/src/multiarraymodule.c 2006-08-24 08:36:48 UTC (rev 3056)
@@ -21,7 +21,8 @@
*/
#define _MULTIARRAYMODULE
-#include "numpy/noprefix.h"
+#define NPY_NO_PREFIX
+#include "numpy/arrayobject.h"
#define PyAO PyArrayObject
@@ -931,6 +932,10 @@
return ret;
}
+/* Why doesn't this just call the ufunc?
+ All we need to do is add it to the list of needed ufuncs.
+ */
+
/*MULTIARRAY_API
Conjugate
*/
@@ -6427,6 +6432,24 @@
+#ifndef NPY_NO_SIGNAL
+
+static PyObject *
+test_interrupt(PyObject *self)
+{
+ int a = 0;
+ NPY_SIGINT_ON
+
+ while(1) {
+ a += 1;
+ }
+
+ NPY_SIGINT_OFF
+
+ return PyInt_FromLong(a);
+}
+#endif
+
static struct PyMethodDef array_module_methods[] = {
{"_get_ndarray_c_version", (PyCFunction)array__get_ndarray_c_version,
METH_VARARGS|METH_KEYWORDS, NULL},
@@ -6481,6 +6504,10 @@
METH_VARARGS | METH_KEYWORDS, NULL},
{"compare_chararrays", (PyCFunction)compare_chararrays,
METH_VARARGS | METH_KEYWORDS, NULL},
+#ifndef NPY_NO_SIGNAL
+ {"test_interrupt", (PyCFunction)test_interrupt,
+ METH_NOARGS, NULL},
+#endif
{NULL, NULL, 0} /* sentinel */
};
@@ -6680,7 +6707,6 @@
return;
c_api = PyCObject_FromVoidPtr((void *)PyArray_API, NULL);
- if (PyErr_Occurred()) goto err;
PyDict_SetItemString(d, "_ARRAY_API", c_api);
Py_DECREF(c_api);
if (PyErr_Occurred()) goto err;
More information about the Numpy-svn
mailing list