Previous Wrapper of the tables allocation |
Parent The associated python module |
Outline | Next The wrapper module source : astericshpc.cpp |
The purpose is very similar than the previous part, so let's begin :
The header is really simple :
1 2 3 4 5 6 7 8 9 10 |
#ifndef __ALLOCMATRIXWRAPPER_H__ #define __ALLOCMATRIXWRAPPER_H__ #include <Python.h> #include "structmember.h" PyObject * allocMatrix(long unsigned int nbRow, long unsigned int nbCol); PyObject * allocMatrixWrapper(PyObject *self, PyObject *args); #endif |
Let's write the source file allocMatrixWrapper.cpp.
Again and 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 7 |
#include <Python.h> #include <numpy/arrayobject.h> #include <bytearrayobject.h> #include "asterics_alloc.h" #include "allocMatrixWrapper.h" |
In this function, we get a PyCapsule. Then, we ge the associated pointer by name and finally we deallocate it :
1 2 3 4 5 6 7 |
///Free the capsule memory /** @param obj : object with contains the capsule */ void empty_freeArray(PyObject* obj){ float* ptr = (float*) PyCapsule_GetPointer(obj,"emptyMatrix"); free(ptr); } |
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 |
///Create a numpy matrix /** @param nbRow : number of rows of the matrix * @param nbCol : number of columns of the matrix * @return numpy array */ PyObject * allocMatrix(long unsigned int nbRow, long unsigned int nbCol){ //Set the size of the numpy array npy_intp attr_size[2]; attr_size[0] = nbRow; attr_size[1] = nbCol; float* mat = asterics_malloc2f(nbRow, nbCol); if(mat == NULL){ PyObject* objMat = PyArray_EMPTY(2, attr_size, NPY_FLOAT32, 0); if(objMat == NULL){ PyErr_SetString(PyExc_RuntimeError, "allocMatrix : Could not allocated memory\n"); return NULL; } return objMat; } long unsigned int pitch(getPitch(nbCol)); PyArray_Dims strides = {NULL, 0}; strides.ptr = PyDimMem_NEW(2); strides.len = 2; PyArray_Descr *descr = PyArray_DescrFromType(NPY_FLOAT32); strides.ptr[1] = (npy_intp)sizeof(float); // Last strides is equal to element size strides.ptr[0] = (pitch + nbCol) * strides.ptr[1]; PyObject* objMat = PyArray_NewFromDescr(&PyArray_Type, descr, 2, attr_size, strides.ptr, (void *)mat, NPY_ARRAY_WRITEABLE, NULL); //Desalocation stuff PyObject* memory_capsule = PyCapsule_New(mat, "emptyMatrix", empty_freeArray); if(PyArray_SetBaseObject((PyArrayObject*)objMat, memory_capsule) < 0){ PyErr_SetString(PyExc_RuntimeError, "Fail to create PyCapsule\n"); return NULL; } return objMat; } |
Once we have the desired size of the table (in number of elements), we call the allocMatrix function :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
///Allocate an aligned matrix of float with a pitch /** @param self : pointer to the parent object if it exist * @param args : arguments passed to the program * @return allocated numpy array */ PyObject * allocMatrixWrapper(PyObject *self, PyObject *args){ long unsigned int nbRow(0lu), nbCol(0lu); if(!PyArg_ParseTuple(args, "kk", &nbRow, &nbCol)){ PyErr_SetString(PyExc_RuntimeError, "allocMatrixWrapper : wrong set of arguments. Expects two arguments for the matrix size\n"); return NULL; } return allocMatrix(nbRow, nbCol); } |
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/*************************************** 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 <Python.h> #include <numpy/arrayobject.h> #include <bytearrayobject.h> #include "asterics_alloc.h" #include "allocMatrixWrapper.h" ///Free the capsule memory /** @param obj : object with contains the capsule */ void empty_freeArray(PyObject* obj){ float* ptr = (float*) PyCapsule_GetPointer(obj,"emptyMatrix"); free(ptr); } ///Create a numpy matrix /** @param nbRow : number of rows of the matrix * @param nbCol : number of columns of the matrix * @return numpy array */ PyObject * allocMatrix(long unsigned int nbRow, long unsigned int nbCol){ //Set the size of the numpy array npy_intp attr_size[2]; attr_size[0] = nbRow; attr_size[1] = nbCol; float* mat = asterics_malloc2f(nbRow, nbCol); if(mat == NULL){ PyObject* objMat = PyArray_EMPTY(2, attr_size, NPY_FLOAT32, 0); if(objMat == NULL){ PyErr_SetString(PyExc_RuntimeError, "allocMatrix : Could not allocated memory\n"); return NULL; } return objMat; } long unsigned int pitch(getPitch(nbCol)); PyArray_Dims strides = {NULL, 0}; strides.ptr = PyDimMem_NEW(2); strides.len = 2; PyArray_Descr *descr = PyArray_DescrFromType(NPY_FLOAT32); strides.ptr[1] = (npy_intp)sizeof(float); // Last strides is equal to element size strides.ptr[0] = (pitch + nbCol) * strides.ptr[1]; PyObject* objMat = PyArray_NewFromDescr(&PyArray_Type, descr, 2, attr_size, strides.ptr, (void *)mat, NPY_ARRAY_WRITEABLE, NULL); //Desalocation stuff PyObject* memory_capsule = PyCapsule_New(mat, "emptyMatrix", empty_freeArray); if(PyArray_SetBaseObject((PyArrayObject*)objMat, memory_capsule) < 0){ PyErr_SetString(PyExc_RuntimeError, "Fail to create PyCapsule\n"); return NULL; } return objMat; } ///Allocate an aligned matrix of float with a pitch /** @param self : pointer to the parent object if it exist * @param args : arguments passed to the program * @return allocated numpy array */ PyObject * allocMatrixWrapper(PyObject *self, PyObject *args){ long unsigned int nbRow(0lu), nbCol(0lu); if(!PyArg_ParseTuple(args, "kk", &nbRow, &nbCol)){ PyErr_SetString(PyExc_RuntimeError, "allocMatrixWrapper : wrong set of arguments. Expects two arguments for the matrix size\n"); return NULL; } return allocMatrix(nbRow, nbCol); } |
Previous Wrapper of the tables allocation |
Parent The associated python module |
Outline | Next The wrapper module source : astericshpc.cpp |