Home  >  Article  >  Backend Development  >  How to build Catboost C evaluation library API?

How to build Catboost C evaluation library API?

WBOY
WBOYforward
2024-02-06 08:15:08599browse

如何构建Catboost C评估库API?

Question content

I have to use 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 C or C API. I compiled the C API following the official documentation, but it has a lot of issues that need to be solved to work.

These are the problems we encountered when trying to create an 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:

  1. We solved issue #1 by redefining the modelhandle variable to:
modelcalcerhandle *modelhandle = modelcalcercreate();

After making this change, the c program can be compiled, but we receive a new error:

[1]    6489 segmentation fault  ./program
  1. The segmentation fault is related to the warning listed in question #2. We have to redefine the variable to fix 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 in the comments, from code fixes to how to compile the c code.


Correct answer


This is the complete solution:

  1. Clone the catboost repository:

git clone https://github.com/catboost/catboost.git

  1. Open the catboost directory from your local copy of the catboost repository.

  2. Build the evaluation library (I chose shared libraries, but you can choose which libraries you need). In my case I had to change the --target-platform parameter, I'm using mac m1 and macos ventura 13.1, clang version is 14.0.0:

./ya make -r catboost/libs/model_interface --target-platform clang14-darwin-arm64
  1. Create c file. Fixed c example code:
#include <stdio.h>
#include <c_api.h>

int main()
{
    float floatfeaturesraw[3] = {0, 89, 1};
    const float *floatfeatures = floatfeaturesraw;
    const char *catfeaturesraw[4] = {"others", "443_https", "6", "24"};
    const char **catfeatures = catfeaturesraw;
    double resultraw[4];
    double *result = resultraw;

    modelcalcerhandle *modelhandle = modelcalcercreate();
    if (!loadfullmodelfromfile(modelhandle, "catboost_model"))
    {
        printf("loadfullmodelfromfile error message: %s\n", geterrorstring());
    }
    setpredictiontype(modelhandle, 3);
    if (!calcmodelpredictionsingle(
            modelhandle,
            floatfeatures, 3,
            catfeatures, 4,
            result, 4))
    {
        printf("calcmodelprediction error message: %s\n", geterrorstring());
    }
    printf("%f\n", result[0]);
    printf("%f\n", result[1]);
    printf("%f\n", result[2]);
    printf("%f\n", result[3]);
    modelcalcerdelete(modelhandle);
}

consider:

  • I have set setpredictiontype to apt_probability
  • Our model predicts multiple categories, hence result[4].
  • We only need to predict one record at a time, so we use the calcmodelpredictionsingle method.
  1. Compile c code:
gcc -v -o program.out c_code.c -l catboostmodel -i /path/to/catboost/repo/catboost/catboost/libs/model_interface/ -l /path/to/catboost/repo/catboost/catboost/libs/model_interface/

IMPORTANT: Make sure no warning or error messages are displayed.

  1. Now you can run it:

IMPORTANT NOTE: Make sure the catboost model file is in the same path as program.out.

./program.out

The above is the detailed content of How to build Catboost C evaluation library API?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete