Previous How to create a sgemm python module |
Parent How to create a sgemm python module |
Outline | Next The C++ module file |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/*************************************** Auteur : Pierre Aubert Mail : aubertp7@gmail.com Licence : CeCILL-C ****************************************/ #ifndef __SGEMM_WRAPPER_H__ #define __SGEMM_WRAPPER_H__ #include <Python.h> #include "structmember.h" PyObject * sgemmWrapper(PyObject *self, PyObject *args); #endif |
Now, let's write the sgemmWrapper.cpp file :
Again in this example, since we are using numpy in the module, we have to define the NO_IMPORT_ARRAY to avoid multiple definitions of the same numpy function. And we also have to specify the version of the numpy API to avoid warnings :
1 2 3 4 5 6 |
#define NO_IMPORT_ARRAY #ifndef DISABLE_COOL_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL core_ARRAY_API #endif #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION |
1 2 3 4 5 6 |
#include <iostream> #include <numpy/arrayobject.h> #include <bytearrayobject.h> #include "sgemm_intrinsics_pitch.h" #include "sgemmWrapper.h" |
Here, we parse the output table and the two input tables with 'O' which corresponds to a PyObject type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
///Get the pitch of a matrix /** @param nbCol : number of columns of the matrix * @return pitch of the matrix */ long unsigned int getPitch(long unsigned int nbCol){ long unsigned int vecSize(VECTOR_ALIGNEMENT/sizeof(float)); long unsigned int pitch(vecSize - (nbCol % vecSize)); if(pitch == vecSize){pitch = 0lu;} return pitch; } ///Do the hadamard computation /** @param self : parent of the function if it exist * @param args : arguments passed to the function * @return result of the Hadamard product */ PyObject * sgemmWrapper(PyObject *self, PyObject *args){ PyArrayObject *objMatX = NULL, *objMatY = NULL, *objMatRes = NULL; if(!PyArg_ParseTuple(args, "OOO", &objMatRes, &objMatX, &objMatY)){ PyErr_SetString(PyExc_RuntimeError, "sgemmWrapper : wrong set of arguments. Expect matRes, matX, matY\n"); return NULL; } if(PyArray_NDIM(objMatX) != 2 || PyArray_NDIM(objMatY) != 2 || PyArray_NDIM(objMatRes) != 2){ PyErr_SetString(PyExc_TypeError, "sgemmWrapper : input matrices must be a two dimension array"); return NULL; } if(PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatY)[0] || PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatRes)[0] || PyArray_DIMS(objMatX)[1] != PyArray_DIMS(objMatY)[1] || PyArray_DIMS(objMatX)[1] != PyArray_DIMS(objMatRes)[1] || PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatX)[1] || PyArray_DIMS(objMatY)[0] != PyArray_DIMS(objMatY)[1] || PyArray_DIMS(objMatRes)[0] != PyArray_DIMS(objMatRes)[1]) { PyErr_SetString(PyExc_TypeError, "sgemmWrapper : input matrices must be of the same size and square"); return NULL; } long unsigned int sizeElement(PyArray_DIMS(objMatX)[0]); const float * matX = (const float*)PyArray_DATA(objMatX); const float * matY = (const float*)PyArray_DATA(objMatY); float * matRes = (float*)PyArray_DATA(objMatRes); sgemm(matRes, matX, matY, sizeElement, getPitch(sizeElement)); Py_RETURN_NONE; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
/*************************************** Auteur : Pierre Aubert Mail : aubertp7@gmail.com Licence : CeCILL-C ****************************************/ #define NO_IMPORT_ARRAY #ifndef DISABLE_COOL_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL core_ARRAY_API #endif #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include <iostream> #include <numpy/arrayobject.h> #include <bytearrayobject.h> #include "sgemm_intrinsics_pitch.h" #include "sgemmWrapper.h" ///Get the pitch of a matrix /** @param nbCol : number of columns of the matrix * @return pitch of the matrix */ long unsigned int getPitch(long unsigned int nbCol){ long unsigned int vecSize(VECTOR_ALIGNEMENT/sizeof(float)); long unsigned int pitch(vecSize - (nbCol % vecSize)); if(pitch == vecSize){pitch = 0lu;} return pitch; } ///Do the hadamard computation /** @param self : parent of the function if it exist * @param args : arguments passed to the function * @return result of the Hadamard product */ PyObject * sgemmWrapper(PyObject *self, PyObject *args){ PyArrayObject *objMatX = NULL, *objMatY = NULL, *objMatRes = NULL; if(!PyArg_ParseTuple(args, "OOO", &objMatRes, &objMatX, &objMatY)){ PyErr_SetString(PyExc_RuntimeError, "sgemmWrapper : wrong set of arguments. Expect matRes, matX, matY\n"); return NULL; } if(PyArray_NDIM(objMatX) != 2 || PyArray_NDIM(objMatY) != 2 || PyArray_NDIM(objMatRes) != 2){ PyErr_SetString(PyExc_TypeError, "sgemmWrapper : input matrices must be a two dimension array"); return NULL; } if(PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatY)[0] || PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatRes)[0] || PyArray_DIMS(objMatX)[1] != PyArray_DIMS(objMatY)[1] || PyArray_DIMS(objMatX)[1] != PyArray_DIMS(objMatRes)[1] || PyArray_DIMS(objMatX)[0] != PyArray_DIMS(objMatX)[1] || PyArray_DIMS(objMatY)[0] != PyArray_DIMS(objMatY)[1] || PyArray_DIMS(objMatRes)[0] != PyArray_DIMS(objMatRes)[1]) { PyErr_SetString(PyExc_TypeError, "sgemmWrapper : input matrices must be of the same size and square"); return NULL; } long unsigned int sizeElement(PyArray_DIMS(objMatX)[0]); const float * matX = (const float*)PyArray_DATA(objMatX); const float * matY = (const float*)PyArray_DATA(objMatY); float * matRes = (float*)PyArray_DATA(objMatRes); sgemm(matRes, matX, matY, sizeElement, getPitch(sizeElement)); Py_RETURN_NONE; } |
Previous How to create a sgemm python module |
Parent How to create a sgemm python module |
Outline | Next The C++ module file |