1
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
2

3
#include "Python.h"
4
#include "math.h"
5
#include "numpy/ndarraytypes.h"
6
#include "numpy/ufuncobject.h"
7
#include "numpy/npy_3kcompat.h"
8

9

10
/*
11
 * struct_ufunc_test.c
12
 * This is the C code for creating your own
13
 * NumPy ufunc for a structured array dtype.
14
 *
15
 * Details explaining the Python-C API can be found under
16
 * 'Extending and Embedding' and 'Python/C API' at
17
 * docs.python.org .
18
 */
19

20 1
static void add_uint64_triplet(char **args,
21
                               npy_intp const *dimensions,
22
                               npy_intp const* steps,
23
                               void* data)
24
{
25
    npy_intp i;
26 1
    npy_intp is1=steps[0];
27 1
    npy_intp is2=steps[1];
28 1
    npy_intp os=steps[2];
29 1
    npy_intp n=dimensions[0];
30
    npy_uint64 *x, *y, *z;
31

32 1
    char *i1=args[0];
33 1
    char *i2=args[1];
34 1
    char *op=args[2];
35

36 1
    for (i = 0; i < n; i++) {
37

38 1
        x = (npy_uint64*)i1;
39 1
        y = (npy_uint64*)i2;
40 1
        z = (npy_uint64*)op;
41

42 1
        z[0] = x[0] + y[0];
43 1
        z[1] = x[1] + y[1];
44 1
        z[2] = x[2] + y[2];
45

46 1
        i1 += is1;
47 1
        i2 += is2;
48 1
        op += os;
49
    }
50 1
}
51

52
static PyObject*
53 1
register_fail(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
54
{
55
    PyObject *add_triplet;
56
    PyObject *dtype_dict;
57
    PyArray_Descr *dtype;
58
    PyArray_Descr *dtypes[3];
59
    int retval;
60

61 1
    add_triplet = PyUFunc_FromFuncAndData(NULL, NULL, NULL, 0, 2, 1,
62
                                    PyUFunc_None, "add_triplet",
63
                                    "add_triplet_docstring", 0);
64

65 1
    dtype_dict = Py_BuildValue("[(s, s), (s, s), (s, s)]",
66
                               "f0", "u8", "f1", "u8", "f2", "u8");
67 1
    PyArray_DescrConverter(dtype_dict, &dtype);
68 1
    Py_DECREF(dtype_dict);
69

70 1
    dtypes[0] = dtype;
71 1
    dtypes[1] = dtype;
72 1
    dtypes[2] = dtype;
73

74 1
    retval = PyUFunc_RegisterLoopForDescr((PyUFuncObject *)add_triplet,
75
                                dtype,
76
                                &add_uint64_triplet,
77
                                dtypes,
78
                                NULL);
79

80 1
    if (retval < 0) {
81 0
        Py_DECREF(add_triplet);
82 0
        Py_DECREF(dtype);
83
        return NULL;
84
    }
85 1
    retval = PyUFunc_RegisterLoopForDescr((PyUFuncObject *)add_triplet,
86
                                dtype,
87
                                &add_uint64_triplet,
88
                                dtypes,
89
                                NULL);
90 1
    Py_DECREF(add_triplet);
91 1
    Py_DECREF(dtype);
92 1
    if (retval < 0) {
93
        return NULL;
94
    }
95 0
    Py_RETURN_NONE;
96
}
97

98
static PyMethodDef StructUfuncTestMethods[] = {
99
    {"register_fail",
100
        register_fail,
101
        METH_NOARGS, NULL},
102
    {NULL, NULL, 0, NULL}
103
};
104

105
static struct PyModuleDef moduledef = {
106
    PyModuleDef_HEAD_INIT,
107
    "_struct_ufunc_tests",
108
    NULL,
109
    -1,
110
    StructUfuncTestMethods,
111
    NULL,
112
    NULL,
113
    NULL,
114
    NULL
115
};
116

117 1
PyMODINIT_FUNC PyInit__struct_ufunc_tests(void)
118
{
119
    PyObject *m, *add_triplet, *d;
120
    PyObject *dtype_dict;
121
    PyArray_Descr *dtype;
122
    PyArray_Descr *dtypes[3];
123

124 1
    m = PyModule_Create(&moduledef);
125

126 1
    if (m == NULL) {
127
        return NULL;
128
    }
129

130 1
    import_array();
131 1
    import_umath();
132

133 1
    add_triplet = PyUFunc_FromFuncAndData(NULL, NULL, NULL, 0, 2, 1,
134
                                    PyUFunc_None, "add_triplet",
135
                                    "add_triplet_docstring", 0);
136

137 1
    dtype_dict = Py_BuildValue("[(s, s), (s, s), (s, s)]",
138
                               "f0", "u8", "f1", "u8", "f2", "u8");
139 1
    PyArray_DescrConverter(dtype_dict, &dtype);
140 1
    Py_DECREF(dtype_dict);
141

142 1
    dtypes[0] = dtype;
143 1
    dtypes[1] = dtype;
144 1
    dtypes[2] = dtype;
145

146 1
    PyUFunc_RegisterLoopForDescr((PyUFuncObject *)add_triplet,
147
                                dtype,
148
                                &add_uint64_triplet,
149
                                dtypes,
150
                                NULL);
151

152 1
    Py_DECREF(dtype);
153 1
    d = PyModule_GetDict(m);
154

155 1
    PyDict_SetItemString(d, "add_triplet", add_triplet);
156 1
    Py_DECREF(add_triplet);
157
    return m;
158
}

Read our documentation on viewing source code .

Loading