1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Python Wrapper
3 * Title: cmsismodule.h
4 * Description: C code for the CMSIS-DSP Python wrapper
5 *
6 * $Date: 27 April 2021
7 * $Revision: V1.0
8 *
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29 #define MODNAME "cmsisdsp_bayes"
30 #define MODINITNAME cmsisdsp_bayes
31
32 #include "cmsisdsp_module.h"
33
34
35
36 NUMPYVECTORFROMBUFFER(f32,float32_t,NPY_FLOAT);
37
38
39
40 typedef struct {
41 PyObject_HEAD
42 arm_gaussian_naive_bayes_instance_f32 *instance;
43 } dsp_arm_gaussian_naive_bayes_instance_f32Object;
44
45
46 static void
arm_gaussian_naive_bayes_instance_f32_dealloc(dsp_arm_gaussian_naive_bayes_instance_f32Object * self)47 arm_gaussian_naive_bayes_instance_f32_dealloc(dsp_arm_gaussian_naive_bayes_instance_f32Object* self)
48 {
49 //printf("Dealloc called\n");
50 if (self->instance)
51 {
52
53 if (self->instance->theta)
54 {
55 PyMem_Free((float32_t*)self->instance->theta);
56 }
57
58 if (self->instance->sigma)
59 {
60 PyMem_Free((float32_t*)self->instance->sigma);
61 }
62
63 if (self->instance->classPriors)
64 {
65 PyMem_Free((float32_t*)self->instance->classPriors);
66 }
67
68 PyMem_Free(self->instance);
69 }
70
71 Py_TYPE(self)->tp_free((PyObject*)self);
72 }
73
74
75 static PyObject *
arm_gaussian_naive_bayes_instance_f32_new(PyTypeObject * type,PyObject * args,PyObject * kwds)76 arm_gaussian_naive_bayes_instance_f32_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
77 {
78 dsp_arm_gaussian_naive_bayes_instance_f32Object *self;
79 //printf("New called\n");
80
81 self = (dsp_arm_gaussian_naive_bayes_instance_f32Object *)type->tp_alloc(type, 0);
82 //printf("alloc called\n");
83
84 if (self != NULL) {
85
86 self->instance = PyMem_Malloc(sizeof(arm_gaussian_naive_bayes_instance_f32));
87 self->instance->theta=NULL;
88 self->instance->sigma=NULL;
89 self->instance->classPriors=NULL;
90
91 }
92
93
94 return (PyObject *)self;
95 }
96
97 static int
arm_gaussian_naive_bayes_instance_f32_init(dsp_arm_gaussian_naive_bayes_instance_f32Object * self,PyObject * args,PyObject * kwds)98 arm_gaussian_naive_bayes_instance_f32_init(dsp_arm_gaussian_naive_bayes_instance_f32Object *self, PyObject *args, PyObject *kwds)
99 {
100
101 PyObject *theta=NULL;
102 PyObject *sigma=NULL;
103 PyObject *classPriors=NULL;
104
105 char *kwlist[] = {
106 "vectorDimension",
107 "numberOfClasses",
108 "theta",
109 "sigma",
110 "classPriors",
111 "epsilon",NULL
112 };
113
114 if (PyArg_ParseTupleAndKeywords(args, kwds, "|iiOOOf", kwlist,
115 &self->instance->vectorDimension
116 ,&self->instance->numberOfClasses
117 ,&theta
118 ,&sigma
119 ,&classPriors
120 ,&self->instance->epsilon
121 ))
122 {
123
124 INITARRAYFIELD(theta,NPY_DOUBLE,double,float32_t);
125 INITARRAYFIELD(sigma,NPY_DOUBLE,double,float32_t);
126 INITARRAYFIELD(classPriors,NPY_DOUBLE,double,float32_t);
127 }
128 return 0;
129 }
130
131 GETFIELD(arm_gaussian_naive_bayes_instance_f32,vectorDimension,"i");
132 GETFIELD(arm_gaussian_naive_bayes_instance_f32,numberOfClasses,"i");
133 GETFIELD(arm_gaussian_naive_bayes_instance_f32,epsilon,"f");
134
135
136 static PyMethodDef arm_gaussian_naive_bayes_instance_f32_methods[] = {
137
138 {"vectorDimension", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
139 {"numberOfClasses", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_numberOfClasses,METH_NOARGS,"numberOfClasses"},
140 {"epsilon", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_epsilon,METH_NOARGS,"epsilon"},
141
142 {NULL} /* Sentinel */
143 };
144
145
146 DSPType(arm_gaussian_naive_bayes_instance_f32,arm_gaussian_naive_bayes_instance_f32_new,arm_gaussian_naive_bayes_instance_f32_dealloc,arm_gaussian_naive_bayes_instance_f32_init,arm_gaussian_naive_bayes_instance_f32_methods);
147
148
149
150
typeRegistration(PyObject * module)151 void typeRegistration(PyObject *module) {
152
153
154
155 ADDTYPE(arm_gaussian_naive_bayes_instance_f32);
156
157
158 }
159
160
161 static PyObject *
cmsis_arm_gaussian_naive_bayes_predict_f32(PyObject * obj,PyObject * args)162 cmsis_arm_gaussian_naive_bayes_predict_f32(PyObject *obj, PyObject *args)
163 {
164
165 PyObject *S=NULL; // input
166 PyObject *pSrc=NULL; // input
167 float32_t *pSrc_converted=NULL; // input
168 float32_t *pDst=NULL; // output
169 uint32_t nbClasses; // input
170
171 if (PyArg_ParseTuple(args,"OO",&S,&pSrc))
172 {
173
174 dsp_arm_gaussian_naive_bayes_instance_f32Object *selfS = (dsp_arm_gaussian_naive_bayes_instance_f32Object *)S;
175 GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
176
177 nbClasses=selfS->instance->numberOfClasses;
178
179
180 pDst=PyMem_Malloc(sizeof(float32_t)*nbClasses);
181 float32_t *temp=PyMem_Malloc(sizeof(float32_t)*nbClasses);
182
183
184 uint32_t res=arm_gaussian_naive_bayes_predict_f32(selfS->instance,pSrc_converted,pDst,temp);
185 FLOATARRAY1(pDstOBJ,nbClasses,pDst);
186
187 PyObject *pythonResult = Py_BuildValue("Ok",pDstOBJ,res);
188
189 FREEARGUMENT(pSrc_converted);
190 PyMem_Free(temp);
191 Py_DECREF(pDstOBJ);
192 return(pythonResult);
193
194 }
195 return(NULL);
196 }
197
198
199
200 static PyMethodDef CMSISDSPMethods[] = {
201
202
203
204 {"arm_gaussian_naive_bayes_predict_f32", cmsis_arm_gaussian_naive_bayes_predict_f32, METH_VARARGS,""},
205
206
207
208 {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
209 {NULL, NULL, 0, NULL} /* Sentinel */
210 };
211
212 #ifdef IS_PY3K
cmsisdsp_traverse(PyObject * m,visitproc visit,void * arg)213 static int cmsisdsp_traverse(PyObject *m, visitproc visit, void *arg) {
214 Py_VISIT(GETSTATE(m)->error);
215 return 0;
216 }
217
cmsisdsp_clear(PyObject * m)218 static int cmsisdsp_clear(PyObject *m) {
219 Py_CLEAR(GETSTATE(m)->error);
220 return 0;
221 }
222
223
224 static struct PyModuleDef moduledef = {
225 PyModuleDef_HEAD_INIT,
226 MODNAME,
227 NULL,
228 sizeof(struct module_state),
229 CMSISDSPMethods,
230 NULL,
231 cmsisdsp_traverse,
232 cmsisdsp_clear,
233 NULL
234 };
235
236 #define INITERROR return NULL
237
238 PyMODINIT_FUNC
CAT(PyInit_,MODINITNAME)239 CAT(PyInit_,MODINITNAME)(void)
240
241
242 #else
243 #define INITERROR return
244
245 void CAT(init,MODINITNAME)(void)
246 #endif
247 {
248 import_array();
249
250 #ifdef IS_PY3K
251 PyObject *module = PyModule_Create(&moduledef);
252 #else
253 PyObject *module = Py_InitModule(MODNAME, CMSISDSPMethods);
254 #endif
255
256 if (module == NULL)
257 INITERROR;
258 struct module_state *st = GETSTATE(module);
259
260 st->error = PyErr_NewException(MODNAME".Error", NULL, NULL);
261 if (st->error == NULL) {
262 Py_DECREF(module);
263 INITERROR;
264 }
265
266
267 typeRegistration(module);
268
269 #ifdef IS_PY3K
270 return module;
271 #endif
272 }