Changeset 0696a3 in git for machine_learning/mlpredict.c


Ignore:
Timestamp:
Aug 7, 2019, 10:07:51 PM (5 years ago)
Author:
Murray Heymann <heymann.murray@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
092e6882fed83e361d79576bc0aa7dc34ac19ad2
Parents:
86420e9c548fd4f1645ed4114c5f79fc3488a8a6
Message:
Implement C prediction function
File:
1 edited

Legend:

Unmodified
Added
Removed
  • machine_learning/mlpredict.c

    r86420e r0696a3  
    1111#include "mlpredict.h"
    1212
    13 PyObject *call_python_function(char *module, char *func);
     13/* Locally defined macros */
     14#define LOOKUPTABLE "common.lookuptable"
     15#define KEYWORD_VECTOR "common.keyword_vector"
     16#define PRD_RUNNER "predictor_runner"
     17#define IS_LOOKUP_INITIALISED "is_lookup_initialised"
     18#define INIT_TABLE_ON_SYSTEM "init_table_on_system"
     19#define GET_PREDICTION "get_prediction"
     20#define READ_DICTIONARY "read_dictionary"
     21#define CREATE_TABLE "create_table"
     22
     23/**** Local Function Decleartions ****************************************/
     24
     25PyObject *_call_python_function(char *module, char *func);
     26PyObject *_call_python_function_args(char *module, char *func, PyObject *pArgs);
     27int _get_dictionary();
     28int _get_vectors_file_list();
     29
     30/**** Static Variables ***************************************************/
     31
     32static PyObject *pDictionary = NULL;
     33static PyObject *pVectors = NULL;
     34static PyObject *pFile_list = NULL;
     35
     36/**** Public Functions ***************************************************/
    1437
    1538/**
    1639 * Check whether the helpfiles have been downloaded and the relevant
    17  * vectors have been calculated and saved.
     40 * vectors have been calculated and saved. Furthermore, the local static
     41 * variables must have been set with pointers to the relevant data
     42 * structures in the python instance.
    1843 *
    1944 * @return An integer:  1 if it has been intialised, 0 otherwise
     
    2954        } else {
    3055                /* python system is initialised */
    31                 pValue = call_python_function(LOOKUPTABLE, IS_LOOKUP_INITIALISED);
     56                pValue = _call_python_function(LOOKUPTABLE, IS_LOOKUP_INITIALISED);
    3257                /* is this a boolean? */
    3358                if (pValue != NULL && PyBool_Check(pValue)) {
     
    4671                }
    4772        }
     73
     74        retvalue = retvalue && pDictionary;
     75        retvalue = retvalue && pVectors;
     76        retvalue = retvalue && pFile_list;
    4877        return retvalue;
    4978}
     
    6089int ml_initialise()
    6190{
     91        int retvalue = 1;
    6292        PyObject *pValue = NULL;
    6393
     
    6595                Py_Initialize();
    6696        }
    67         pValue = call_python_function(LOOKUPTABLE, INIT_TABLE_ON_SYSTEM);
     97        pValue = _call_python_function(LOOKUPTABLE, INIT_TABLE_ON_SYSTEM);
    6898        if (pValue != NULL) {
    6999                Py_DECREF(pValue);
    70                 return 1;
    71         } else {
    72                 return 0;
    73         }
    74 
     100        } else {
     101                retvalue = 0;
     102        }
     103
     104        retvalue = retvalue && _get_dictionary();
     105        retvalue = retvalue && _get_vectors_file_list();
     106
     107        return retvalue;
    75108}
    76109
     
    84117{
    85118        int retvalue = 1;
     119
     120        Py_XDECREF(pDictionary);
     121        Py_XDECREF(pVectors);
     122        Py_XDECREF(pFile_list);
     123
    86124        if (Py_IsInitialized()) {
    87125                Py_Finalize();
     
    90128                retvalue = 0;
    91129        }
    92         return retvalue;
    93 }
    94 
    95 
    96 
    97 /**
    98  * Local helper function to call a function that takes no arguments.
    99  * @param[in] module A string of the module name where the function is
    100  * found
    101  * @param[in] func A string giving the name of the function to call.
    102  *
    103  * @return the returned PyObject.
    104  */
    105 PyObject *call_python_function(char *module, char *func)
    106 {
    107         PyObject *pName = NULL, *pModule = NULL, *pFunc = NULL;
    108         PyObject *pValue = NULL;
    109                
    110         if (!Py_IsInitialized()) {
    111                 Py_Initialize();
    112         }
    113 
    114         /* import the module */
    115         pName = PyString_FromString(module);
    116         pModule = PyImport_Import(pName);
    117         Py_DECREF(pName);
    118 
    119         if (pModule != NULL){
    120                 /* Get the init function we want to call */
    121                 pFunc = PyObject_GetAttrString(pModule, func);
    122                 if (pFunc && PyCallable_Check(pFunc)) {
    123                         /* Callable function. Good. In this case, doesn't take any
    124                          * arguments*/
    125                         pValue = PyObject_CallObject(pFunc, NULL);
    126                         if (pValue == NULL) {
    127                                 printf("No return for function\n");
    128                                 PyErr_Print();
    129                         }
    130                 } else {
    131                         /* Somehow not executable. Clean up! */
    132                         if(PyErr_Occurred()) {
    133                                 PyErr_Print();
    134                         }
    135                         fprintf(stderr,
    136                                         "Cannot find function \"%s\"\n",
    137                                         func);
    138                 }
    139                 Py_XDECREF(pFunc);
    140                 Py_DECREF(pModule);
    141         } else {
    142                 PyErr_Print();
    143                 fprintf(stderr, "Failed to load \"%s\"\n", module);
    144         }
    145 
    146         return pValue;
     130
     131        return retvalue;
    147132}
    148133
     
    166151                                           int *pred_len)
    167152{
    168 
    169 
    170 
    171         return 1;
    172 }
    173 
    174 
     153        PyObject *pFName = NULL, *pArgs = NULL;
     154        PyObject *pValue = NULL; PyObject *pString = NULL;
     155        int retvalue = 1;
     156        int ret_string_len = 0;
     157       
     158        pFName = PyString_FromString(filename);
     159        if (!pFName) {
     160                fprintf(stderr, "This is weird\n");
     161
     162                retvalue = 0;
     163        } else {
     164                pArgs = PyTuple_New(4);
     165                if (!pArgs) {
     166                        fprintf(stderr, "This is also weird\n");
     167                        retvalue = 0;
     168                        Py_DECREF(pFName);
     169                } else {
     170                        /* pFName is handed over to the tuple, so not DECREF later */
     171                        PyTuple_SetItem(pArgs, 0, pFName);
     172                        /* Since each of the following is handed over, we need to
     173                         * increase the reference, otherwise our static variable
     174                         * pointers might be freed by the python interpreter. */
     175                        PyTuple_SetItem(pArgs, 1, pDictionary);
     176                        Py_INCREF(pDictionary);
     177                        PyTuple_SetItem(pArgs, 2, pVectors);
     178                        Py_INCREF(pVectors);
     179                        PyTuple_SetItem(pArgs, 3, pFile_list);
     180                        Py_INCREF(pFile_list);
     181                }
     182
     183        }
     184        if (pArgs) {
     185                pValue = _call_python_function_args(PRD_RUNNER,
     186                                                                                        GET_PREDICTION,
     187                                                                                        pArgs);
     188                Py_DECREF(pArgs);
     189                if (!pValue) {
     190                        retvalue = 0;
     191                } else {
     192                        pString = PyObject_Str(pValue);
     193                        strncpy(prediction_buffer,
     194                                        PyString_AsString(pString),
     195                                        buffer_size - 1);
     196                        ret_string_len = strlen(PyString_AsString(pString));
     197                        if (ret_string_len >= buffer_size - 1) {
     198                                prediction_buffer[buffer_size - 1] = '\0';
     199                                *pred_len = buffer_size - 1;
     200                        } else {
     201                                *pred_len = ret_string_len;
     202                        }
     203
     204                        Py_DECREF(pString);
     205                        Py_DECREF(pValue);
     206                }
     207        }
     208
     209        return retvalue;
     210}
     211
     212/**** Local Functions ****************************************************/
     213
     214/**
     215 * Local helper function to call a function that takes no arguments.
     216 * @param[in] module A string of the module name where the function is
     217 * found
     218 * @param[in] func A string giving the name of the function to call.
     219 *
     220 * @return the returned PyObject.
     221 */
     222PyObject *_call_python_function(char *module, char *func) {
     223        PyObject *pArgs = PyTuple_New(0);
     224        PyObject *retvalue = _call_python_function_args(module, func, pArgs);
     225
     226        Py_DECREF(pArgs);
     227        return retvalue;
     228}
     229
     230
     231/**
     232 * Local helper function to call a function that takes arguments.
     233 * @param[in] module A string of the module name where the function is
     234 * found
     235 * @param[in] func A string giving the name of the function to call.
     236 * @param[in] pArgs The arguments to be parsed to the funcion being called.
     237 *
     238 * @return the returned PyObject.
     239 */
     240PyObject *_call_python_function_args(char *module, char *func, PyObject *pArgs)
     241{
     242        PyObject *pName = NULL, *pModule = NULL, *pFunc = NULL;
     243        PyObject *pValue = NULL;
     244               
     245        if (!Py_IsInitialized()) {
     246                Py_Initialize();
     247                printf("I don't like this\n");
     248        }
     249
     250        /* import the module */
     251        pName = PyString_FromString(module);
     252        pModule = PyImport_Import(pName);
     253        Py_DECREF(pName);
     254
     255        if (pModule != NULL){
     256                /* Get the init function we want to call */
     257                pFunc = PyObject_GetAttrString(pModule, func);
     258                if (pFunc && PyCallable_Check(pFunc)) {
     259                        /* Callable function. Good. Call with the args supplied,
     260                         * assuming the arguments are correct for the function */
     261                        pValue = PyObject_CallObject(pFunc, pArgs);
     262                        if (pValue == NULL) {
     263                                printf("No return for function\n");
     264                                PyErr_Print();
     265                        }
     266                } else {
     267                        /* Somehow not executable. Clean up! */
     268                        if(PyErr_Occurred()) {
     269                                PyErr_Print();
     270                        }
     271                        fprintf(stderr,
     272                                        "Cannot find function \"%s\"\n",
     273                                        func);
     274                }
     275                Py_XDECREF(pFunc);
     276                Py_DECREF(pModule);
     277        } else {
     278                PyErr_Print();
     279                fprintf(stderr, "Failed to load \"%s\"\n", module);
     280        }
     281
     282        return pValue;
     283}
     284
     285/**
     286 * Get the PyObject of the list of keywords called dictionary and set it to
     287 * the local static variable.  If already set, simply return without any
     288 * action.
     289 *
     290 * @return 1 if successful, 0 if something goes wrong.
     291 */
     292int _get_dictionary()
     293{
     294        int retvalue = 1;
     295        PyObject *pValue = NULL;
     296
     297        if (!pDictionary) {
     298                pValue = _call_python_function(KEYWORD_VECTOR, READ_DICTIONARY);
     299                if (!pValue) {
     300                        retvalue = 0;
     301                } else {
     302                        pDictionary = pValue;
     303                }
     304        }
     305        return retvalue;
     306}
     307
     308/**
     309 * Get the PyObject of the list of vectors called corresponding to each
     310 * helper file and the list of helper files that could be in a prediction
     311 * and set it to the local static variable. If already set, simply return
     312 * without any action.
     313 *
     314 * @return 1 if successful, 0 if something goes wrong.
     315 */
     316int _get_vectors_file_list()
     317{
     318        int retvalue = 1;
     319        PyObject *pValue = NULL;
     320        PyObject *pVal1 = NULL, *pVal2 = NULL;
     321
     322        if (!pVectors || !pFile_list) {
     323                /* Ensure *both* are free */
     324                Py_XDECREF(pVectors);
     325                Py_XDECREF(pFile_list);
     326                pVectors = NULL;
     327                pFile_list = NULL;
     328                pValue = _call_python_function(LOOKUPTABLE, CREATE_TABLE);
     329                if (!pValue) {
     330                        retvalue = 0;
     331                } else {
     332                        pVal1 = PyTuple_GetItem(pValue, 0);
     333                        pVal2 = PyTuple_GetItem(pValue, 1);
     334                        /* Decreasing the reference to the tuple causes the content to
     335                         * be freed.  To prevent that (leading to a segfault), we have
     336                         * to manually increase the reference to the contents */
     337                        Py_INCREF(pVal1);
     338                        Py_INCREF(pVal2);
     339                        Py_DECREF(pValue);
     340                        pValue = NULL;
     341                        if (pVal1 && pVal2) {
     342                                pVectors = pVal1;
     343                                pFile_list = pVal2;
     344                        } else {
     345                                Py_XDECREF(pVal1);
     346                                Py_XDECREF(pVal2);
     347                                retvalue = 0;
     348                        }
     349                }
     350        }
     351       
     352        return retvalue;
     353}
Note: See TracChangeset for help on using the changeset viewer.