source: sasview/src/sas/sascalc/calculator/c_extensions/sld2i_module.c @ 3e6829d

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249
Last change on this file since 3e6829d was 7ba6470, checked in by Paul Kienzle <pkienzle@…>, 5 years ago

remove deprecation warnings for old buffer protocol from py37 build

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/**
2  SLD2I module to perform point and I calculations
3 */
4#include <stdio.h>
5
6//#define Py_LIMITED_API 0x03020000
7#include <Python.h>
8
9#include "sld2i.h"
10
11#if PY_MAJOR_VERSION < 3
12typedef void (*PyCapsule_Destructor)(PyObject *);
13typedef void (*PyCObject_Destructor)(void *);
14#define PyCapsule_New(pointer, name, destructor) (PyCObject_FromVoidPtr(pointer, (PyCObject_Destructor)destructor))
15#define PyCapsule_GetPointer(capsule, name) (PyCObject_AsVoidPtr(capsule))
16#endif
17
18// Vector binding glue
19#if (PY_VERSION_HEX > 0x03000000) && !defined(Py_LIMITED_API)
20  // Assuming that a view into a writable vector points to a
21  // non-changing pointer for the duration of the C call, capture
22  // the view pointer and immediately free the view.
23  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \
24    Py_buffer VEC_view; \
25    int VEC_err = PyObject_GetBuffer(VEC_obj, &VEC_view, PyBUF_WRITABLE|PyBUF_FORMAT); \
26    if (VEC_err < 0 || sizeof(*VEC_buf) != VEC_view.itemsize) return NULL; \
27    VEC_buf = (typeof(VEC_buf))VEC_view.buf; \
28    VEC_len = VEC_view.len/sizeof(*VEC_buf); \
29    PyBuffer_Release(&VEC_view); \
30  } while (0)
31#else
32  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \
33    int VEC_err = PyObject_AsWriteBuffer(VEC_obj, (void **)(&VEC_buf), &VEC_len); \
34    if (VEC_err < 0) return NULL; \
35    VEC_len /= sizeof(*VEC_buf); \
36  } while (0)
37#endif
38
39/**
40 * Delete a GenI object
41 */
42void
43del_sld2i(PyObject *obj){
44#if PY_MAJOR_VERSION < 3
45        GenI* sld2i = (GenI *)obj;
46#else
47        GenI* sld2i = (GenI *)(PyCapsule_GetPointer(obj, "GenI"));
48#endif
49        PyMem_Free((void *)sld2i);
50}
51
52/**
53 * Create a GenI as a python object by supplying arrays
54 */
55PyObject * new_GenI(PyObject *self, PyObject *args) {
56        PyObject *x_val_obj;
57        PyObject *y_val_obj;
58        PyObject *z_val_obj;
59        PyObject *sldn_val_obj;
60        PyObject *mx_val_obj;
61        PyObject *my_val_obj;
62        PyObject *mz_val_obj;
63        PyObject *vol_pix_obj;
64        Py_ssize_t n_x, n_y, n_z, n_sld, n_mx, n_my, n_mz, n_vol_pix;
65        int is_avg;
66        double* x_val;
67        double* y_val;
68        double* z_val;
69        double* sldn_val;
70        double* mx_val;
71        double* my_val;
72        double* mz_val;
73        double* vol_pix;
74        double inspin;
75        double outspin;
76        double stheta;
77        PyObject *obj;
78        GenI* sld2i;
79
80        //printf("new GenI\n");
81        if (!PyArg_ParseTuple(args, "iOOOOOOOOddd", &is_avg, &x_val_obj, &y_val_obj, &z_val_obj, &sldn_val_obj, &mx_val_obj, &my_val_obj, &mz_val_obj, &vol_pix_obj, &inspin, &outspin, &stheta)) return NULL;
82        VECTOR(x_val_obj, x_val, n_x);
83        VECTOR(y_val_obj, y_val, n_y);
84        VECTOR(z_val_obj, z_val, n_z);
85        VECTOR(sldn_val_obj, sldn_val, n_sld);
86        VECTOR(mx_val_obj, mx_val, n_mx);
87        VECTOR(my_val_obj, my_val, n_my);
88        VECTOR(mz_val_obj, mz_val, n_mz);
89        VECTOR(vol_pix_obj, vol_pix, n_vol_pix);
90        sld2i = PyMem_Malloc(sizeof(GenI));
91        //printf("sldi:%p\n", sld2i);
92        if (sld2i != NULL) {
93                initGenI(sld2i,is_avg,(int)n_x,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta);
94        }
95        obj = PyCapsule_New(sld2i, "GenI", del_sld2i);
96        //printf("constructed %p\n", obj);
97        return obj;
98}
99
100/**
101 * GenI the given input (2D) according to a given object
102 */
103PyObject * genicom_inputXY(PyObject *self, PyObject *args) {
104        PyObject *gen_obj;
105        PyObject *qx_obj;
106        PyObject *qy_obj;
107        PyObject *I_out_obj;
108        Py_ssize_t n_qx, n_qy, n_out;
109        double *qx;
110        double *qy;
111        double *I_out;
112        GenI* sld2i;
113
114        //printf("in genicom_inputXY\n");
115        if (!PyArg_ParseTuple(args, "OOOO",  &gen_obj, &qx_obj, &qy_obj, &I_out_obj)) return NULL;
116        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
117        VECTOR(qx_obj, qx, n_qx);
118        VECTOR(qy_obj, qy, n_qy);
119        VECTOR(I_out_obj, I_out, n_out);
120        //printf("qx, qy, I_out: %d %d %d, %d %d %d\n", qx, qy, I_out, n_qx, n_qy, n_out);
121
122        // Sanity check
123        //if(n_q!=n_out) return Py_BuildValue("i",-1);
124
125        genicomXY(sld2i, (int)n_qx, qx, qy, I_out);
126        //printf("done calc\n");
127        //return PyCObject_FromVoidPtr(s, del_genicom);
128        return Py_BuildValue("i",1);
129}
130
131/**
132 * GenI the given 1D input according to a given object
133 */
134PyObject * genicom_input(PyObject *self, PyObject *args) {
135        PyObject *gen_obj;
136        PyObject *q_obj;
137        PyObject *I_out_obj;
138        Py_ssize_t n_q, n_out;
139        double *q;
140        double *I_out;
141        GenI *sld2i;
142
143        if (!PyArg_ParseTuple(args, "OOO",  &gen_obj, &q_obj, &I_out_obj)) return NULL;
144        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
145        VECTOR(q_obj, q, n_q);
146        VECTOR(I_out_obj, I_out, n_out);
147
148        // Sanity check
149        //if (n_q!=n_out) return Py_BuildValue("i",-1);
150
151        genicom(sld2i, (int)n_q, q, I_out);
152        return Py_BuildValue("i",1);
153}
154
155/**
156 * Define module methods
157 */
158static PyMethodDef module_methods[] = {
159        {"new_GenI", (PyCFunction)new_GenI, METH_VARARGS,
160                  "Create a new GenI object"},
161        {"genicom",(PyCFunction)genicom_input, METH_VARARGS,
162                  "genicom the given 1d input arrays"},
163        {"genicomXY",(PyCFunction)genicom_inputXY, METH_VARARGS,
164                  "genicomXY the given 2d input arrays"},
165    {NULL}
166};
167
168#define MODULE_DOC "Sld2i C Library"
169#define MODULE_NAME "_sld2i"
170#define MODULE_INIT2 init_sld2i
171#define MODULE_INIT3 PyInit__sld2i
172#define MODULE_METHODS module_methods
173
174/* ==== boilerplate python 2/3 interface bootstrap ==== */
175
176
177#if defined(WIN32) && !defined(__MINGW32__)
178    #define DLL_EXPORT __declspec(dllexport)
179#else
180    #define DLL_EXPORT
181#endif
182
183#if PY_MAJOR_VERSION >= 3
184
185  DLL_EXPORT PyMODINIT_FUNC MODULE_INIT3(void)
186  {
187    static struct PyModuleDef moduledef = {
188      PyModuleDef_HEAD_INIT,
189      MODULE_NAME,         /* m_name */
190      MODULE_DOC,          /* m_doc */
191      -1,                  /* m_size */
192      MODULE_METHODS,      /* m_methods */
193      NULL,                /* m_reload */
194      NULL,                /* m_traverse */
195      NULL,                /* m_clear */
196      NULL,                /* m_free */
197    };
198    return PyModule_Create(&moduledef);
199  }
200
201#else /* !PY_MAJOR_VERSION >= 3 */
202
203  DLL_EXPORT PyMODINIT_FUNC MODULE_INIT2(void)
204  {
205    Py_InitModule4(MODULE_NAME,
206                 MODULE_METHODS,
207                 MODULE_DOC,
208                 0,
209                 PYTHON_API_VERSION
210                 );
211  }
212
213#endif /* !PY_MAJOR_VERSION >= 3 */
Note: See TracBrowser for help on using the repository browser.