Changeset 0696a3 in git for machine_learning/mlpredict.c
- Timestamp:
- Aug 7, 2019, 10:07:51 PM (5 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- 092e6882fed83e361d79576bc0aa7dc34ac19ad2
- Parents:
- 86420e9c548fd4f1645ed4114c5f79fc3488a8a6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
machine_learning/mlpredict.c
r86420e r0696a3 11 11 #include "mlpredict.h" 12 12 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 25 PyObject *_call_python_function(char *module, char *func); 26 PyObject *_call_python_function_args(char *module, char *func, PyObject *pArgs); 27 int _get_dictionary(); 28 int _get_vectors_file_list(); 29 30 /**** Static Variables ***************************************************/ 31 32 static PyObject *pDictionary = NULL; 33 static PyObject *pVectors = NULL; 34 static PyObject *pFile_list = NULL; 35 36 /**** Public Functions ***************************************************/ 14 37 15 38 /** 16 39 * 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. 18 43 * 19 44 * @return An integer: 1 if it has been intialised, 0 otherwise … … 29 54 } else { 30 55 /* python system is initialised */ 31 pValue = call_python_function(LOOKUPTABLE, IS_LOOKUP_INITIALISED);56 pValue = _call_python_function(LOOKUPTABLE, IS_LOOKUP_INITIALISED); 32 57 /* is this a boolean? */ 33 58 if (pValue != NULL && PyBool_Check(pValue)) { … … 46 71 } 47 72 } 73 74 retvalue = retvalue && pDictionary; 75 retvalue = retvalue && pVectors; 76 retvalue = retvalue && pFile_list; 48 77 return retvalue; 49 78 } … … 60 89 int ml_initialise() 61 90 { 91 int retvalue = 1; 62 92 PyObject *pValue = NULL; 63 93 … … 65 95 Py_Initialize(); 66 96 } 67 pValue = call_python_function(LOOKUPTABLE, INIT_TABLE_ON_SYSTEM);97 pValue = _call_python_function(LOOKUPTABLE, INIT_TABLE_ON_SYSTEM); 68 98 if (pValue != NULL) { 69 99 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; 75 108 } 76 109 … … 84 117 { 85 118 int retvalue = 1; 119 120 Py_XDECREF(pDictionary); 121 Py_XDECREF(pVectors); 122 Py_XDECREF(pFile_list); 123 86 124 if (Py_IsInitialized()) { 87 125 Py_Finalize(); … … 90 128 retvalue = 0; 91 129 } 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; 147 132 } 148 133 … … 166 151 int *pred_len) 167 152 { 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 */ 222 PyObject *_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 */ 240 PyObject *_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 */ 292 int _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 */ 316 int _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.