From 86608c6770cf08c138a2bdab5855072f64be09ef Mon Sep 17 00:00:00 2001 From: joshua Date: Sat, 30 Dec 2023 23:54:31 -0500 Subject: initial commit --- .../PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c | 408 +++++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 Drivers/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c (limited to 'Drivers/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c') diff --git a/Drivers/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c b/Drivers/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c new file mode 100644 index 0000000..f024982 --- /dev/null +++ b/Drivers/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c @@ -0,0 +1,408 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Python Wrapper + * Title: cmsismodule.c + * Description: C code for the CMSIS-DSP Python wrapper + * + * $Date: 25. March 2019 + * $Revision: V0.0.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define NPY_NO_DEPRECATED_API NPY_1_15_API_VERSION + +#ifdef WIN +#pragma warning( disable : 4013 ) +#pragma warning( disable : 4244 ) +#endif + +#include +#define MAX(A,B) (A) < (B) ? (B) : (A) + +#define CAT1(A,B) A##B +#define CAT(A,B) CAT1(A,B) + + +#ifdef CMSISDSP +#include "arm_math.h" +#define MODNAME "cmsisdsp" +#define MODINITNAME cmsisdsp +#endif + +#include +#include + +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#endif + +struct module_state { + PyObject *error; +}; + +#if PY_MAJOR_VERSION >= 3 +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) +#else +#define GETSTATE(m) (&_state) +static struct module_state _state; +#endif + +static PyObject * +error_out(PyObject *m) { + struct module_state *st = GETSTATE(m); + PyErr_SetString(st->error, "something bad happened"); + return NULL; +} + +#define MLTYPE(name,thenewfunc,deallocfunc,initfunc,methods)\ +static PyTypeObject ml_##name##Type = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + .tp_name=MODNAME".##name", \ + .tp_basicsize = sizeof(ml_##name##Object), \ + .tp_itemsize = 0, \ + .tp_dealloc = (destructor)deallocfunc, \ + .tp_flags = Py_TPFLAGS_DEFAULT, \ + .tp_doc = #name, \ + .tp_init = (initproc)initfunc, \ + .tp_new = (newfunc)thenewfunc, \ + .tp_methods = methods \ + }; + + +#define MEMCPY(DST,SRC,NB,FORMAT) \ +for(memCpyIndex = 0; memCpyIndex < (NB) ; memCpyIndex++)\ +{ \ + (DST)[memCpyIndex] = (FORMAT)(SRC)[memCpyIndex]; \ +} + +#define GETFIELD(NAME,FIELD,FORMAT) \ +static PyObject * \ +Method_##NAME##_##FIELD(ml_##NAME##Object *self, PyObject *ignored)\ +{ \ + return(Py_BuildValue(FORMAT,self->instance->FIELD)); \ +} + +#define GETFIELDARRAY(NAME,FIELD,FORMAT) \ +static PyObject * \ +Method_##NAME##_##FIELD(ml_##NAME##Object *self, PyObject *ignored)\ +{ \ + return(specific_##NAME##_##FIELD(self->instance)); \ +} + +#define INITARRAYFIELD(FIELD,FORMAT,SRCFORMAT,DSTFORMAT) \ + if (FIELD) \ + { \ + PyArray_Descr *desct=PyArray_DescrFromType(FORMAT); \ + PyArrayObject *FIELD##c = (PyArrayObject *)PyArray_FromAny(FIELD,desct,\ + 1,0,NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED | NPY_ARRAY_FORCECAST, \ + NULL); \ + if (FIELD##c) \ + { \ + uint32_t memCpyIndex; \ + SRCFORMAT *f=(SRCFORMAT*)PyArray_DATA(FIELD##c); \ + uint32_t n = PyArray_SIZE(FIELD##c); \ + self->instance->FIELD =PyMem_Malloc(sizeof(DSTFORMAT)*n); \ + MEMCPY(self->instance->FIELD ,f,n,DSTFORMAT); \ + Py_DECREF(FIELD##c); \ + } \ + } +#define GETCARRAY(PYVAR,CVAR,FORMAT,SRCFORMAT,DSTFORMAT) \ + if (PYVAR) \ + { \ + PyArray_Descr *desct=PyArray_DescrFromType(FORMAT); \ + PyArrayObject *PYVAR##c = (PyArrayObject *)PyArray_FromAny(PYVAR,desct,\ + 1,0,NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED | NPY_ARRAY_FORCECAST, \ + NULL); \ + if (PYVAR##c) \ + { \ + uint32_t memCpyIndex; \ + SRCFORMAT *f=(SRCFORMAT*)PyArray_DATA(PYVAR##c); \ + uint32_t n = PyArray_SIZE(PYVAR##c); \ + CVAR =PyMem_Malloc(sizeof(DSTFORMAT)*n); \ + MEMCPY(CVAR ,f,n,DSTFORMAT); \ + Py_DECREF(PYVAR##c); \ + } \ + } + +#define GETARGUMENT(FIELD,FORMAT,SRCFORMAT,DSTFORMAT) \ + uint32_t arraySize##FIELD=0; \ + if (FIELD) \ + { \ + PyArray_Descr *desct=PyArray_DescrFromType(FORMAT); \ + PyArrayObject *FIELD##c = (PyArrayObject *)PyArray_FromAny(FIELD,desct, \ + 1,0,NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED | NPY_ARRAY_FORCECAST, \ + NULL); \ + if (FIELD##c) \ + { \ + uint32_t memCpyIndex; \ + SRCFORMAT *f=(SRCFORMAT*)PyArray_DATA(FIELD##c); \ + arraySize##FIELD = PyArray_SIZE(FIELD##c); \ + FIELD##_converted =PyMem_Malloc(sizeof(DSTFORMAT)*arraySize##FIELD);\ + MEMCPY(FIELD##_converted ,f,arraySize##FIELD,DSTFORMAT); \ + Py_DECREF(FIELD##c); \ + } \ + } + +#define FREEARGUMENT(FIELD) \ + PyMem_Free(FIELD) + +#ifdef IS_PY3K +#define ADDTYPE(name) \ + if (PyType_Ready(&ml_##name##Type) < 0) \ + return; \ + \ + Py_INCREF(&ml_##name##Type); \ + PyModule_AddObject(module, #name, (PyObject *)&ml_##name##Type); +#else +#define ADDTYPE(name) \ + if (PyType_Ready(&ml_##name##Type) < 0) \ + return; \ + \ + Py_INCREF(&ml_##name##Type); \ + PyModule_AddObject(module, #name, (PyObject *)&ml_##name##Type); +#endif + +#define FLOATARRAY2(OBJ,NB1,NB2,DATA) \ + npy_intp dims[2]; \ + dims[0]=NB1; \ + dims[1]=NB2; \ + const int ND=2; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, DATA); + +#define FLOATARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, DATA); + +#define FLOAT64ARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_DOUBLE, DATA); + +#define UINT32ARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_UINT32, DATA); + +#define INT32ARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_INT32, DATA); + +#define INT16ARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_INT16, DATA); + +#define INT8ARRAY1(OBJ,NB1,DATA) \ + npy_intp dims[1]; \ + dims[0]=NB1; \ + const int ND=1; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_BYTE, DATA); + + +#define MATRIXFROMNUMPY(EXT,TYP,SRCTYPE,NUMPYTYPE) \ +arm_matrix_instance_##EXT *EXT##MatrixFromNumpy(PyObject *o) \ +{ \ + arm_matrix_instance_##EXT *s; \ + \ + s=PyMem_Malloc(sizeof(arm_matrix_instance_##EXT)); \ + s->pData=NULL; \ + s->numRows=0; \ + s->numCols=0; \ + \ + PyArray_Descr *desct=PyArray_DescrFromType(NUMPYTYPE); \ + PyArrayObject *cdata = (PyArrayObject *)PyArray_FromAny(o,desct, \ + 1,0,NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED | NPY_ARRAY_FORCECAST, \ + NULL); \ + if (cdata) \ + { \ + uint32_t memCpyIndex; \ + SRCTYPE *f=(SRCTYPE*)PyArray_DATA(cdata); \ + s->numRows=PyArray_DIM(cdata,0); \ + s->numCols=PyArray_DIM(cdata,1); \ + uint32_t nb = PyArray_SIZE(cdata); \ + s->pData = PyMem_Malloc(sizeof(TYP)*nb); \ + MEMCPY(s->pData ,f,nb,TYP); \ + Py_DECREF(cdata); \ + } \ + \ + \ + return(s); \ + \ +} + +MATRIXFROMNUMPY(f32,float32_t,double,NPY_DOUBLE); +MATRIXFROMNUMPY(f64,float64_t,double,NPY_DOUBLE); +MATRIXFROMNUMPY(q31,q31_t,int32_t,NPY_INT32); +MATRIXFROMNUMPY(q15,q15_t,int16_t,NPY_INT16); + +#define CREATEMATRIX(EXT,TYP) \ +arm_matrix_instance_##EXT *create##EXT##Matrix(uint32_t r,uint32_t c)\ +{ \ + arm_matrix_instance_##EXT *s; \ + \ + s=PyMem_Malloc(sizeof(arm_matrix_instance_##EXT)); \ + s->pData=PyMem_Malloc(sizeof(TYP)*r*c); \ + s->numRows=r; \ + s->numCols=c; \ + return(s); \ +} + +CREATEMATRIX(f32,float32_t); +CREATEMATRIX(f64,float64_t); +CREATEMATRIX(q31,q31_t); +CREATEMATRIX(q15,q15_t); + +#define NUMPYARRAYFROMMATRIX(EXT,NUMPYTYPE_FROMC) \ +PyObject *NumpyArrayFrom##EXT##Matrix(arm_matrix_instance_##EXT *mat) \ +{ \ + npy_intp dims[2]; \ + dims[0]=mat->numRows; \ + dims[1]=mat->numCols; \ + const int ND=2; \ + PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NUMPYTYPE_FROMC, mat->pData);\ + return(OBJ); \ +} + +NUMPYARRAYFROMMATRIX(f32,NPY_FLOAT); +NUMPYARRAYFROMMATRIX(f64,NPY_DOUBLE); +NUMPYARRAYFROMMATRIX(q31,NPY_INT32); +NUMPYARRAYFROMMATRIX(q15,NPY_INT16); + +//#include "specific.h" +#include "cmsismodule.h" + +#if 0 +static PyObject *cmsisml_test(PyObject *obj, PyObject *args) +{ + ml_arm_svm_linear_instance_f32Object *self=NULL; + PyObject *svm, *vector=NULL; + + if (!PyArg_ParseTuple(args, "OO", &svm,&vector)) + return NULL; + + self=(ml_arm_svm_linear_instance_f32Object*)svm; + if (self) + { + if (self->instance) + { + int result; + float32_t *input=NULL; + GETCARRAY(vector,input,NPY_DOUBLE,double,float32_t); + + arm_svm_linear_predict_f32(self->instance,input,&result); + /* + printf("Dual\n"); + for(int i = 0 ; i < self->instance->nbOfSupportVectors ; i++) + { + printf("%f\n",self->instance->dualCoefficients[i]); + } + printf("Vectors\n"); + int k=0; + for(int i = 0 ; i < self->instance->nbOfSupportVectors ; i++) + { + printf("Vector %d\n",i); + for(int j = 0 ; j < self->instance->vectorDimension ; j++) + { + printf("%f\n",self->instance->supportVectors[k]); + k++; + } + } + printf("Classes\n"); + for(int i = 0 ; i < 2 ; i++) + { + printf("%d\n",self->instance->classes[i]); + } + printf("Intercept %f\n",self->instance->intercept); +*/ + PyMem_Free(input); + return(Py_BuildValue("i",result)); + } + } + return(Py_BuildValue("i",-1)); +} +#endif + +#ifdef IS_PY3K +static int cmsisml_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int cmsisml_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + MODNAME, + NULL, + sizeof(struct module_state), + CMSISMLMethods, + NULL, + cmsisml_traverse, + cmsisml_clear, + NULL +}; + +#define INITERROR return NULL + +PyMODINIT_FUNC +CAT(PyInit_,MODINITNAME)(void) + + +#else +#define INITERROR return + +void CAT(init,MODINITNAME)(void) +#endif +{ + import_array(); + + #ifdef IS_PY3K + PyObject *module = PyModule_Create(&moduledef); + #else + PyObject *module = Py_InitModule(MODNAME, CMSISMLMethods); + #endif + + if (module == NULL) + INITERROR; + struct module_state *st = GETSTATE(module); + + st->error = PyErr_NewException(MODNAME".Error", NULL, NULL); + if (st->error == NULL) { + Py_DECREF(module); + INITERROR; + } + + + typeRegistration(module); + + #ifdef IS_PY3K + return module; + #endif +} \ No newline at end of file -- cgit v1.2.3