Как использовать catboost C API в do tnet? - PullRequest
0 голосов
/ 12 января 2020

Я пытаюсь использовать catboost C API в C#. Ниже приведен рабочий код в C:

#include <stdio.h>                                                                                                                                                                             
#include "c_api.h"                                                                                                                                                                             

int main(int argc, char** argv){                                                                                                                                                               

  float floatFeatures[3] = {96.215, 1.595655e+09, 3000};                                                                                                                                       
  char* catFeatures[0];                                                                                                                                                                        
  double result[1];                                                                                                                                                                            
  ModelCalcerHandle* modelHandle = ModelCalcerCreate();                                                                                                                                        


  // LoadFullModelFromFile is time consuming                                                                                                                                                   
  if (!LoadFullModelFromFile(modelHandle, "../../test_catboost_model.cbm")) {                                                                                                                  
    printf("LoadFullModelFromFile error message: %s\n", GetErrorString());                                                                                                                     
  }

  // CalcModelPredictionSingle is fast                                                                                                                                                                                                                                                                                                                             
  if (!CalcModelPredictionSingle(modelHandle,                                                                                                                                                  
                                 &floatFeatures, 3,                                                                                                                                            
                                 &catFeatures, 0,                                                                                                                                              
                                 &result, 1                                                                                                                                                    
                                 )) {                                                                                                                                                          
    printf("CalcModelPrediction error message: %s\n", GetErrorString());                                                                                                                       
  }

  ModelCalcerDelete(modelHandle);                                                                                                                                                              

  printf("model score is %.20f", result[0]);                                                                                                                                                   

  return 0;                                                                                                                                                                                    
}

И ниже моя попытка сделать то же самое в C# (сделать tnet core на Linux), но он не работает ... Когда я запускаю "do tnet run", просто ничего не выводится, нет сообщения об ошибке

   class Program
    {
        static void Main(string[] args)
        {
            var floatFeatures = new float[] { 96.215f, 1.595655e+09f, 3000 };
            var catFeatures = new string[0];
            var results = new double[1];

            var modelHandle = ModelCalcerCreate();
            if (!LoadFullModelFromFile(modelHandle, "{absolute path to the same model}/test_catboost_model.cbm"))
            {
                Console.WriteLine($"Load model error: {GetErrorString()}");
            }

            if (!CalcModelPredictionSingle(modelHandle, floatFeatures, 3, catFeatures, 0, out results, 1))
            {
                Console.WriteLine($"Predict error : {GetErrorString()}");
            }

            Console.WriteLine($"Model score is {results[0]}");
        }


        [DllImport("catboostmodel", EntryPoint = "ModelCalcerCreate")]
        private static extern IntPtr ModelCalcerCreate();

        [DllImport("catboostmodel", EntryPoint = "GetErrorString")]
        private static extern string GetErrorString();

        [DllImport("catboostmodel", EntryPoint = "LoadFullModelFromFile")]
        private static extern bool LoadFullModelFromFile(IntPtr modelHandle, string fileName);

        [DllImport("catboostmodel", EntryPoint = "CalcModelPredictionSingle")]
        private static extern bool CalcModelPredictionSingle(
            IntPtr modelHandle,
            float[] floatFeatures, ulong floatFeaturesSize,
            string[] catFeatures, ulong catFeaturesSize,
            out double[] result, ulong resultSize
        );
    }

Соответствующий заголовочный файл C, как показано ниже. Весь файл доступен на github .

#if defined(_WIN32) && !defined(CATBOOST_API_STATIC_LIB)
#ifdef _WINDLL
#define CATBOOST_API __declspec(dllexport)
#else                                                                                                                                                   
#define CATBOOST_API __declspec(dllimport)
#endif       
#else                                                                                                                                                                      
#define
CATBOOST_API
#endif

typedef void ModelCalcerHandle;

CATBOOST_API ModelCalcerHandle* ModelCalcerCreate();
CATBOOST_API const char* GetErrorString();
CATBOOST_API bool LoadFullModelFromFile(  
    ModelCalcerHandle* modelHandle, 
    const char* filename);
CATBOOST_API bool CalcModelPredictionSingle( 
        ModelCalcerHandle* modelHandle,
        const float* floatFeatures, size_t floatFeaturesSize,
        const char** catFeatures, size_t catFeaturesSize,
        double* result, size_t resultSize);

Любые предложения приветствуются. Спасибо!

1 Ответ

0 голосов
/ 12 января 2020

Оказывается, мне не следует использовать ключевое слово "out" перед "double [] result" в сигнатуре CalcModelPredictionSingle, что устраняет эту проблему.

Ниже работает.

   [DllImport("catboostmodel")]
    private static extern bool CalcModelPredictionSingle(
        IntPtr modelHandle,
        float[] floatFeatures, ulong floatFeaturesSize,
        string[] catFeatures, ulong catFeaturesSize,
        double[] result, ulong resultSize
    );
...