summaryrefslogtreecommitdiff
path: root/numpy/core/src/umathmodule.c.src
diff options
context:
space:
mode:
authorDavid Cournapeau <cournape@gmail.com>2009-04-30 08:40:50 +0000
committerDavid Cournapeau <cournape@gmail.com>2009-04-30 08:40:50 +0000
commit1f37ab2935d98654a57f139bb5ef8ee8fb0f9832 (patch)
tree4d4221e7081823d9e1945156d796e1247a6da741 /numpy/core/src/umathmodule.c.src
parent3d730002b1428cce568bcf6fcda0e0df76c5d960 (diff)
downloadnumpy-1f37ab2935d98654a57f139bb5ef8ee8fb0f9832.tar.gz
Enable separate compilation for umath module.
Diffstat (limited to 'numpy/core/src/umathmodule.c.src')
-rw-r--r--numpy/core/src/umathmodule.c.src115
1 files changed, 113 insertions, 2 deletions
diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src
index d2b4b9c8a..c8c897275 100644
--- a/numpy/core/src/umathmodule.c.src
+++ b/numpy/core/src/umathmodule.c.src
@@ -17,6 +17,8 @@
*/
#define _UMATHMODULE
+#define PY_ARRAY_UNIQUE_SYMBOL _npy_umathmodule_ARRAY_API
+
#include "Python.h"
#include "numpy/noprefix.h"
#include "numpy/ufuncobject.h"
@@ -31,11 +33,120 @@
*****************************************************************************
*/
#include "umath_funcs.inc"
-#include "umath_loops.inc"
-#include "umath_ufunc_object.inc"
+#include "umath_loops.h"
+#include "umath_ufunc_object.h"
#include "__umath_generated.c"
#include "__ufunc_api.c"
+static PyUFuncGenericFunction pyfunc_functions[] = {PyUFunc_On_Om};
+
+static char
+doc_frompyfunc[] = "frompyfunc(func, nin, nout) take an arbitrary python\n" \
+ "function that takes nin objects as input and returns\n" \
+ "nout objects and return a universal function (ufunc).\n" \
+ "This ufunc always returns PyObject arrays\n";
+
+static PyObject *
+ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUSED(kwds)) {
+ /* Keywords are ignored for now */
+
+ PyObject *function, *pyname = NULL;
+ int nin, nout, i;
+ PyUFunc_PyFuncData *fdata;
+ PyUFuncObject *self;
+ char *fname, *str;
+ Py_ssize_t fname_len = -1;
+ int offset[2];
+
+ if (!PyArg_ParseTuple(args, "Oii", &function, &nin, &nout)) {
+ return NULL;
+ }
+ if (!PyCallable_Check(function)) {
+ PyErr_SetString(PyExc_TypeError, "function must be callable");
+ return NULL;
+ }
+ self = _pya_malloc(sizeof(PyUFuncObject));
+ if (self == NULL) {
+ return NULL;
+ }
+ PyObject_Init((PyObject *)self, &PyUFunc_Type);
+
+ self->userloops = NULL;
+ self->nin = nin;
+ self->nout = nout;
+ self->nargs = nin + nout;
+ self->identity = PyUFunc_None;
+ self->functions = pyfunc_functions;
+ self->ntypes = 1;
+ self->check_return = 0;
+
+ /* generalized ufunc */
+ self->core_enabled = 0;
+ self->core_num_dim_ix = 0;
+ self->core_num_dims = NULL;
+ self->core_dim_ixs = NULL;
+ self->core_offsets = NULL;
+ self->core_signature = NULL;
+
+ pyname = PyObject_GetAttrString(function, "__name__");
+ if (pyname) {
+ (void) PyString_AsStringAndSize(pyname, &fname, &fname_len);
+ }
+ if (PyErr_Occurred()) {
+ fname = "?";
+ fname_len = 1;
+ PyErr_Clear();
+ }
+ Py_XDECREF(pyname);
+
+ /*
+ * self->ptr holds a pointer for enough memory for
+ * self->data[0] (fdata)
+ * self->data
+ * self->name
+ * self->types
+ *
+ * To be safest, all of these need their memory aligned on void * pointers
+ * Therefore, we may need to allocate extra space.
+ */
+ offset[0] = sizeof(PyUFunc_PyFuncData);
+ i = (sizeof(PyUFunc_PyFuncData) % sizeof(void *));
+ if (i) {
+ offset[0] += (sizeof(void *) - i);
+ }
+ offset[1] = self->nargs;
+ i = (self->nargs % sizeof(void *));
+ if (i) {
+ offset[1] += (sizeof(void *)-i);
+ }
+ self->ptr = _pya_malloc(offset[0] + offset[1] + sizeof(void *) +
+ (fname_len + 14));
+ if (self->ptr == NULL) {
+ return PyErr_NoMemory();
+ }
+ Py_INCREF(function);
+ self->obj = function;
+ fdata = (PyUFunc_PyFuncData *)(self->ptr);
+ fdata->nin = nin;
+ fdata->nout = nout;
+ fdata->callable = function;
+
+ self->data = (void **)(((char *)self->ptr) + offset[0]);
+ self->data[0] = (void *)fdata;
+ self->types = (char *)self->data + sizeof(void *);
+ for (i = 0; i < self->nargs; i++) {
+ self->types[i] = PyArray_OBJECT;
+ }
+ str = self->types + offset[1];
+ memcpy(str, fname, fname_len);
+ memcpy(str+fname_len, " (vectorized)", 14);
+ self->name = str;
+
+ /* Do a better job someday */
+ self->doc = "dynamic ufunc based on a python function";
+
+ return (PyObject *)self;
+}
/*
*****************************************************************************