I had to use a Catboost model in some programming languages, Golang and Python. The best option (for performance and compatibility) is to use an evaluation library which can be a C or C++ API. I followed the official documentation to compile the C API, but it has a lot of problems to solve so that work.
These are the problems we encountered while trying to create the evaluation library in C:
1.
error: variable has incomplete type 'ModelCalcerHandle' (aka 'void')
ModelCalcerHandle modelHandle;
c_wrapper.c:16:13: warning: incompatible pointer types passing 'float (*)[3]' to parameter of type 'const float **' [-Wincompatible-pointer-types]
&floatFeatures, 3,
^~~~~~~~~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:151:19: note: passing argument to parameter 'floatFeatures' here
const float** floatFeatures, size_t floatFeaturesSize,
^
c_wrapper.c:17:13: warning: incompatible pointer types passing 'char *(*)[4]' to parameter of type 'const char ***' [-Wincompatible-pointer-types]
&catFeatures, 4,
^~~~~~~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:152:19: note: passing argument to parameter 'catFeatures' here
const char*** catFeatures, size_t catFeaturesSize,
^
c_wrapper.c:18:13: warning: incompatible pointer types passing 'double (*)[1]' to parameter of type 'double *' [-Wincompatible-pointer-types]
&result, 1
^~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:153:13: note: passing argument to parameter 'result' here
double* result, size_t resultSize);
Solution:
- We have solved problem #1 by redefining the
modelHandle
variable as:
ModelCalcerHandle *modelHandle = ModelCalcerCreate();
After this change it was posible to compile the C program, but we got a new error:
[1] 6489 segmentation fault ./program
- The segmentation fault is related to the warnings listed in issue #2. We had to redefine the variables to solve it:
float floatFeaturesRaw[100];
const float *floatFeatures = floatFeaturesRaw;
const char *catFeaturesRaw[2] = {"1", "2"};
const char **catFeatures = catFeaturesRaw;
double resultRaw[1];
double *result = resultRaw;
and
if (!CalcModelPredictionSingle(
modelHandle,
&floatFeatures, 3,
&catFeatures, 4,
result, 1)) //We remove `&`
{
printf("CalcModelPrediction error message: %s\n", GetErrorString());
}
I'll add the complete solution, from code fixes to how to compile C code, in a comment.