LCOV - code coverage report
Current view: top level - nntrainer/models - model_loader.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 70.3 % 229 161
Test Date: 2025-12-14 20:38:17 Functions: 83.3 % 18 15

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : /**
       3              :  * Copyright (C) 2020 Parichay Kapoor <pk.kapoor@samsung.com>
       4              :  *
       5              :  * @file  model_loader.cpp
       6              :  * @date  5 August 2020
       7              :  * @brief This is model loader class for the Neural Network
       8              :  * @see   https://github.com/nnstreamer/nntrainer
       9              :  * @author  Jijoong Moon <jijoong.moon@samsung.com>
      10              :  * @author  Parichay Kapoor <pk.kapoor@samsung.com>
      11              :  * @bug   No known bugs except for NYI items
      12              :  *
      13              :  */
      14              : #include <sstream>
      15              : 
      16              : #include <adam.h>
      17              : #include <databuffer_factory.h>
      18              : #include <filesystem>
      19              : #include <ini_interpreter.h>
      20              : #include <model_loader.h>
      21              : #include <neuralnet.h>
      22              : #include <nntrainer_error.h>
      23              : #include <nntrainer_log.h>
      24              : #include <optimizer_wrapped.h>
      25              : #include <time_dist.h>
      26              : #include <util_func.h>
      27              : 
      28              : #if defined(ENABLE_NNSTREAMER_BACKBONE)
      29              : #include <nnstreamer_layer.h>
      30              : #endif
      31              : 
      32              : #if defined(ENABLE_TFLITE_BACKBONE)
      33              : #include <tflite_layer.h>
      34              : #endif
      35              : 
      36              : #ifdef ENABLE_ONNX_INTERPRETER
      37              : #include <onnx_interpreter.h>
      38              : #endif
      39              : 
      40              : #define NN_INI_RETURN_STATUS()                                                 \
      41              :   do {                                                                         \
      42              :     if (status != ML_ERROR_NONE) {                                             \
      43              :       iniparser_freedict(ini);                                                 \
      44              :       return status;                                                           \
      45              :     }                                                                          \
      46              :   } while (0)
      47              : 
      48              : namespace nntrainer {
      49              : 
      50          554 : int ModelLoader::loadLearningRateSchedulerConfigIni(
      51              :   dictionary *ini, std::shared_ptr<ml::train::Optimizer> &optimizer) {
      52              :   int status = ML_ERROR_NONE;
      53              : 
      54          554 :   if (iniparser_find_entry(ini, "LearningRateScheduler") == 0) {
      55              :     return ML_ERROR_NONE;
      56              :   }
      57              : 
      58              :   /** Default to adam optimizer */
      59              :   const char *lrs_type =
      60            5 :     iniparser_getstring(ini, "LearningRateScheduler:Type", "unknown");
      61              :   std::vector<std::string> properties =
      62           10 :     parseProperties(ini, "LearningRateScheduler", {"type"});
      63              : 
      64              :   try {
      65              :     auto lrs =
      66           10 :       ct_engine->createLearningRateSchedulerObject(lrs_type, properties);
      67              :     auto opt_wrapped = std::static_pointer_cast<OptimizerWrapped>(optimizer);
      68           10 :     opt_wrapped->setLearningRateScheduler(std::move(lrs));
      69            0 :   } catch (std::exception &e) {
      70            0 :     ml_loge("%s %s", typeid(e).name(), e.what());
      71              :     return ML_ERROR_INVALID_PARAMETER;
      72            0 :   } catch (...) {
      73            0 :     ml_loge("Creating the optimizer failed");
      74              :     return ML_ERROR_INVALID_PARAMETER;
      75            0 :   }
      76              : 
      77            5 :   return status;
      78            5 : }
      79              : 
      80          593 : int ModelLoader::loadOptimizerConfigIni(dictionary *ini, NeuralNetwork &model) {
      81              :   int status = ML_ERROR_NONE;
      82              : 
      83          593 :   if (iniparser_find_entry(ini, "Optimizer") == 0) {
      84           27 :     if (!model.opt) {
      85            6 :       ml_logw("there is no [Optimizer] section in given ini file."
      86              :               "This model can only be used for inference.");
      87              :     }
      88           27 :     return ML_ERROR_NONE;
      89              :   }
      90              : 
      91              :   /** Optimizer already set with deprecated method */
      92          566 :   if (model.opt) {
      93            0 :     ml_loge("Error: optimizers specified twice.");
      94            0 :     return ML_ERROR_INVALID_PARAMETER;
      95              :   }
      96              : 
      97              :   /** Default to adam optimizer */
      98          566 :   const char *opt_type = iniparser_getstring(ini, "Optimizer:Type", "adam");
      99              :   std::vector<std::string> properties =
     100         1132 :     parseProperties(ini, "Optimizer", {"type"});
     101              : 
     102              :   try {
     103              :     std::shared_ptr<ml::train::Optimizer> optimizer =
     104          566 :       createOptimizerWrapped(opt_type, properties);
     105          554 :     model.setOptimizer(optimizer);
     106          554 :     loadLearningRateSchedulerConfigIni(ini, optimizer);
     107           12 :   } catch (std::exception &e) {
     108           12 :     ml_loge("%s %s", typeid(e).name(), e.what());
     109              :     return ML_ERROR_INVALID_PARAMETER;
     110           12 :   } catch (...) {
     111            0 :     ml_loge("Creating the optimizer failed");
     112              :     return ML_ERROR_INVALID_PARAMETER;
     113            0 :   }
     114              : 
     115          554 :   return status;
     116          566 : }
     117              : 
     118              : /**
     119              :  * @brief     load model config from ini
     120              :  */
     121          665 : int ModelLoader::loadModelConfigIni(dictionary *ini, NeuralNetwork &model) {
     122              :   int status = ML_ERROR_NONE;
     123              : 
     124          665 :   if (iniparser_find_entry(ini, "Model") == 0) {
     125           18 :     ml_loge("there is no [Model] section in given ini file");
     126           18 :     return ML_ERROR_INVALID_PARAMETER;
     127              :   }
     128              : 
     129              :   std::vector<std::string> properties = parseProperties(
     130              :     ini, "Model",
     131              :     {"optimizer", "learning_rate", "decay_steps", "decay_rate", "beta1",
     132         1294 :      "beta2", "epsilon", "type", "save_path", "tensor_type", "tensor_format"});
     133              :   try {
     134          647 :     model.setProperty(properties);
     135            0 :   } catch (std::exception &e) {
     136            0 :     ml_loge("%s %s", typeid(e).name(), e.what());
     137              :     return ML_ERROR_INVALID_PARAMETER;
     138            0 :   } catch (...) {
     139            0 :     ml_loge("Creating the optimizer failed");
     140              :     return ML_ERROR_INVALID_PARAMETER;
     141            0 :   }
     142              : 
     143              :   /** handle save_path as a special case for model_file_context */
     144              :   const std::string &save_path =
     145          647 :     iniparser_getstring(ini, "Model:Save_path", unknown);
     146          647 :   if (save_path != unknown) {
     147          120 :     model.setProperty({"save_path=" + resolvePath(save_path)});
     148              :   }
     149              : 
     150              :   /**
     151              :    ********
     152              :    * Note: Below is only to maintain backward compatibility
     153              :    ********
     154              :    */
     155              : 
     156              :   /** If no optimizer specified, exit without error */
     157          647 :   const char *opt_type = iniparser_getstring(ini, "Model:Optimizer", unknown);
     158          647 :   if (opt_type == unknown)
     159              :     return status;
     160              : 
     161           24 :   if (model.opt) {
     162              :     /** Optimizer already set with a new section */
     163            0 :     ml_loge("Error: optimizers specified twice.");
     164            0 :     return ML_ERROR_INVALID_PARAMETER;
     165              :   }
     166              : 
     167           24 :   ml_logw("Warning: using deprecated ini style for optimizers.");
     168           48 :   ml_logw(
     169              :     "Warning: create [ Optimizer ] section in ini to specify optimizers.");
     170              : 
     171              :   try {
     172              :     std::shared_ptr<ml::train::Optimizer> optimizer =
     173           48 :       createOptimizerWrapped(opt_type, {});
     174           48 :     model.setOptimizer(optimizer);
     175            0 :   } catch (std::exception &e) {
     176            0 :     ml_loge("%s %s", typeid(e).name(), e.what());
     177              :     return ML_ERROR_INVALID_PARAMETER;
     178            0 :   } catch (...) {
     179            0 :     ml_loge("Creating the optimizer failed");
     180              :     return ML_ERROR_INVALID_PARAMETER;
     181            0 :   }
     182              : 
     183              :   std::vector<std::string> optimizer_prop = {};
     184              : 
     185              :   /** push only if ini_key exist as prop_key=ini_value */
     186          144 :   auto maybe_push = [ini](std::vector<std::string> &prop_vector,
     187              :                           const std::string &ini_key,
     188              :                           const std::string &prop_key) {
     189              :     constexpr const char *LOCAL_UNKNOWN = "unknown";
     190              :     std::string ini_value =
     191          144 :       iniparser_getstring(ini, ini_key.c_str(), LOCAL_UNKNOWN);
     192          288 :     if (!istrequal(ini_value, LOCAL_UNKNOWN)) {
     193           48 :       prop_vector.push_back(prop_key + "=" + ini_value);
     194              :     }
     195          144 :   };
     196              : 
     197              :   const std::vector<std::string> deprecated_optimizer_keys = {
     198           24 :     "learning_rate", "decay_rate", "decay_steps", "beta1", "beta2", "epsilon"};
     199          168 :   for (const auto &key : deprecated_optimizer_keys) {
     200          288 :     maybe_push(optimizer_prop, "Model:" + key, key);
     201              :   }
     202              : 
     203              :   try {
     204           24 :     model.opt->setProperty(optimizer_prop);
     205            0 :   } catch (std::exception &e) {
     206            0 :     ml_loge("%s %s", typeid(e).name(), e.what());
     207              :     return ML_ERROR_INVALID_PARAMETER;
     208            0 :   } catch (...) {
     209            0 :     ml_loge("Settings properties to optimizer failed.");
     210              :     return ML_ERROR_INVALID_PARAMETER;
     211            0 :   }
     212              : 
     213              :   return status;
     214          701 : }
     215              : 
     216              : /**
     217              :  * @brief     load dataset config from ini
     218              :  */
     219          647 : int ModelLoader::loadDatasetConfigIni(dictionary *ini, NeuralNetwork &model) {
     220              :   /************ helper functors **************/
     221          647 :   auto try_parse_datasetsection_for_backward_compatibility = [&]() -> int {
     222              :     int status = ML_ERROR_NONE;
     223          647 :     if (iniparser_find_entry(ini, "Dataset") == 0) {
     224              :       return ML_ERROR_NONE;
     225              :     }
     226              : 
     227           91 :     ml_logw("Using dataset section is deprecated, please consider using "
     228              :             "train_set, valid_set, test_set sections");
     229              : 
     230              :     /// @note DataSet:BufferSize is parsed for backward compatibility
     231           91 :     std::string bufsizepros("buffer_size=");
     232              :     bufsizepros +=
     233              :       iniparser_getstring(ini, "DataSet:BufferSize",
     234           91 :                           iniparser_getstring(ini, "DataSet:buffer_size", "1"));
     235              : 
     236          237 :     auto parse_and_set = [&](const char *key, DatasetModeType dt,
     237              :                              bool required) -> int {
     238          237 :       const char *path = iniparser_getstring(ini, key, NULL);
     239              : 
     240          237 :       if (path == NULL) {
     241           92 :         return required ? ML_ERROR_INVALID_PARAMETER : ML_ERROR_NONE;
     242              :       }
     243              : 
     244              :       try {
     245          182 :         model.data_buffers[static_cast<int>(dt)] =
     246          182 :           createDataBuffer(DatasetType::FILE, resolvePath(path).c_str());
     247          546 :         model.data_buffers[static_cast<int>(dt)]->setProperty({bufsizepros});
     248            0 :       } catch (...) {
     249            0 :         ml_loge("path is not valid, path: %s", resolvePath(path).c_str());
     250              :         return ML_ERROR_INVALID_PARAMETER;
     251            0 :       }
     252              : 
     253          182 :       return ML_ERROR_NONE;
     254          182 :     };
     255              : 
     256              :     status =
     257           91 :       parse_and_set("DataSet:TrainData", DatasetModeType::MODE_TRAIN, true);
     258           91 :     NN_RETURN_STATUS();
     259              :     status =
     260           73 :       parse_and_set("DataSet:ValidData", DatasetModeType::MODE_VALID, false);
     261           73 :     NN_RETURN_STATUS();
     262              :     status =
     263           73 :       parse_and_set("DataSet:TestData", DatasetModeType::MODE_TEST, false);
     264           73 :     NN_RETURN_STATUS();
     265           73 :     const char *path = iniparser_getstring(ini, "Dataset:LabelData", NULL);
     266           73 :     if (path != NULL) {
     267           54 :       ml_logi("setting labelData is deprecated!, it is essentially noop now!");
     268              :     }
     269              : 
     270           73 :     ml_logd("parsing dataset done");
     271           73 :     return status;
     272          647 :   };
     273              : 
     274         1851 :   auto parse_buffer_section = [ini, this,
     275              :                                &model](const std::string &section_name,
     276              :                                        DatasetModeType type) -> int {
     277         1851 :     if (iniparser_find_entry(ini, section_name.c_str()) == 0) {
     278              :       return ML_ERROR_NONE;
     279              :     }
     280              :     const char *db_type =
     281           36 :       iniparser_getstring(ini, (section_name + ":type").c_str(), unknown);
     282           36 :     auto &db = model.data_buffers[static_cast<int>(type)];
     283              : 
     284              :     /// @todo delegate this to app context (currently there is only file
     285              :     /// databuffer so file is directly used)
     286           72 :     if (!istrequal(db_type, "file")) {
     287           36 :       ml_loge("databuffer type is unknonw, type: %s", db_type);
     288           36 :       return ML_ERROR_INVALID_PARAMETER;
     289              :     }
     290              : 
     291              :     try {
     292            0 :       db = createDataBuffer(DatasetType::FILE);
     293              :       const std::vector<std::string> properties =
     294            0 :         parseProperties(ini, section_name, {"type"});
     295              : 
     296            0 :       db->setProperty(properties);
     297            0 :     } catch (std::exception &e) {
     298            0 :       ml_loge("error while creating and setting dataset, %s", e.what());
     299              :       return ML_ERROR_INVALID_PARAMETER;
     300            0 :     }
     301              : 
     302            0 :     return ML_ERROR_NONE;
     303          647 :   };
     304              : 
     305              :   /************ start of the procedure **************/
     306              :   int status = ML_ERROR_NONE;
     307          647 :   status = try_parse_datasetsection_for_backward_compatibility();
     308          647 :   NN_RETURN_STATUS();
     309              : 
     310          629 :   status = parse_buffer_section("train_set", DatasetModeType::MODE_TRAIN);
     311          629 :   NN_RETURN_STATUS();
     312          617 :   status = parse_buffer_section("valid_set", DatasetModeType::MODE_VALID);
     313          617 :   NN_RETURN_STATUS();
     314         1210 :   status = parse_buffer_section("test_set", DatasetModeType::MODE_TEST);
     315              :   NN_RETURN_STATUS();
     316              : 
     317              :   return status;
     318              : }
     319              : 
     320              : std::vector<std::string>
     321         1218 : ModelLoader::parseProperties(dictionary *ini, const std::string &section_name,
     322              :                              const std::vector<std::string> &filter_props) {
     323         1218 :   int num_entries = iniparser_getsecnkeys(ini, section_name.c_str());
     324              : 
     325         1218 :   ml_logd("number of entries for %s: %d", section_name.c_str(), num_entries);
     326              : 
     327         1218 :   if (num_entries < 1) {
     328            0 :     std::stringstream ss;
     329              :     ss << "there are no entries in the section: " << section_name;
     330            0 :     throw std::invalid_argument(ss.str());
     331            0 :   }
     332              : 
     333         1218 :   std::unique_ptr<const char *[]> key_refs(new const char *[num_entries]);
     334              : 
     335         1218 :   if (iniparser_getseckeys(ini, section_name.c_str(), key_refs.get()) ==
     336              :       nullptr) {
     337            0 :     std::stringstream ss;
     338              :     ss << "failed to fetch key for section: " << section_name;
     339            0 :     throw std::invalid_argument(ss.str());
     340            0 :   }
     341              : 
     342              :   std::vector<std::string> properties;
     343         1218 :   properties.reserve(num_entries - 1);
     344              : 
     345         7120 :   for (int i = 0; i < num_entries; ++i) {
     346              :     /// key is ini section key, which is section_name + ":" + prop_key
     347         5902 :     std::string key(key_refs[i]);
     348         5902 :     std::string prop_key = key.substr(key.find(":") + 1);
     349              : 
     350              :     bool filter_key_found = false;
     351        53044 :     for (auto const &filter_key : filter_props)
     352        47142 :       if (istrequal(prop_key, filter_key))
     353              :         filter_key_found = true;
     354         5902 :     if (filter_key_found)
     355              :       continue;
     356              : 
     357         4358 :     std::string value = iniparser_getstring(ini, key_refs[i], unknown);
     358              : 
     359         4358 :     if (value == unknown) {
     360            0 :       std::stringstream ss;
     361              :       ss << "parsing property failed key: " << key;
     362            0 :       throw std::invalid_argument(ss.str());
     363            0 :     }
     364              : 
     365         4358 :     if (value == "") {
     366            0 :       std::stringstream ss;
     367            0 :       ss << "property key " << key << " has empty value. It is not allowed";
     368            0 :       throw std::invalid_argument(ss.str());
     369            0 :     }
     370         4358 :     ml_logd("parsed properties: %s=%s", prop_key.c_str(), value.c_str());
     371              : 
     372         8716 :     properties.push_back(prop_key + "=" + value);
     373              :   }
     374              : 
     375         1218 :   return properties;
     376            0 : }
     377              : 
     378              : /**
     379              :  * @brief     load all of model and dataset from ini
     380              :  */
     381          665 : int ModelLoader::loadFromIni(std::string ini_file, NeuralNetwork &model,
     382              :                              bool bare_layers) {
     383              :   int status = ML_ERROR_NONE;
     384              :   int num_ini_sec = 0;
     385              :   dictionary *ini;
     386              : 
     387          665 :   if (ini_file.empty()) {
     388            0 :     ml_loge("Error: Configuration File is not defined");
     389            0 :     return ML_ERROR_INVALID_PARAMETER;
     390              :   }
     391              : 
     392         1330 :   if (!isFileExist(ini_file)) {
     393            0 :     ml_loge("Cannot open model configuration file, filename : %s",
     394              :             ini_file.c_str());
     395            0 :     return ML_ERROR_INVALID_PARAMETER;
     396              :   }
     397              : 
     398              :   /** Parse ini file */
     399          665 :   ini = iniparser_load(ini_file.c_str());
     400          665 :   if (ini == NULL) {
     401            0 :     ml_loge("Error: cannot parse file: %s\n", ini_file.c_str());
     402            0 :     return ML_ERROR_INVALID_PARAMETER;
     403              :   }
     404              : 
     405              :   /** Get number of sections in the file */
     406          665 :   num_ini_sec = iniparser_getnsec(ini);
     407          665 :   if (num_ini_sec < 0) {
     408            0 :     ml_loge("Error: invalid number of sections.");
     409              :     status = ML_ERROR_INVALID_PARAMETER;
     410            0 :     NN_INI_RETURN_STATUS();
     411              :   }
     412              : 
     413          665 :   if (!bare_layers) {
     414          665 :     status = loadModelConfigIni(ini, model);
     415          665 :     NN_INI_RETURN_STATUS();
     416              : 
     417          647 :     status = loadDatasetConfigIni(ini, model);
     418          647 :     NN_INI_RETURN_STATUS();
     419              : 
     420          593 :     status = loadOptimizerConfigIni(ini, model);
     421          593 :     NN_INI_RETURN_STATUS();
     422              :   }
     423              : 
     424              :   auto path_resolver = [this](const std::string &path) {
     425         2903 :     return resolvePath(path);
     426          581 :   };
     427              : 
     428          581 :   ml_logd("parsing graph started");
     429              :   try {
     430              :     std::unique_ptr<GraphInterpreter> ini_interpreter =
     431          581 :       std::make_unique<nntrainer::IniGraphInterpreter>(ct_engine,
     432              :                                                        path_resolver);
     433          581 :     auto graph_representation = ini_interpreter->deserialize(ini_file);
     434              : 
     435         3391 :     for (auto &node : graph_representation) {
     436         5676 :       model.addLayer(node);
     437              :     }
     438         1106 :     ml_logd("parsing graph finished");
     439              : 
     440          553 :     if (model.empty()) {
     441           26 :       ml_loge("there is no layer section in the ini file");
     442              :       status = ML_ERROR_INVALID_PARAMETER;
     443              :     }
     444          581 :   } catch (std::exception &e) {
     445           28 :     ml_loge("failed to load graph, reason: %s ", e.what());
     446              :     status = ML_ERROR_INVALID_PARAMETER;
     447           28 :   }
     448              : 
     449          581 :   iniparser_freedict(ini);
     450              :   return status;
     451              : }
     452              : 
     453              : /**
     454              :  * @brief load model from ONNX file
     455              :  */
     456            0 : int ModelLoader::loadFromONNX(std::string onnx_file, NeuralNetwork &model) {
     457              : #ifdef ENABLE_ONNX_INTERPRETER
     458              :   int status = ML_ERROR_NONE;
     459              : 
     460              :   if (onnx_file.empty()) {
     461              :     ml_loge("Error: configuration file is not defined");
     462              :     return ML_ERROR_INVALID_PARAMETER;
     463              :   }
     464              : 
     465              :   if (!isFileExist(onnx_file)) {
     466              :     ml_loge("Cannot open onnx model configuration file, filename : %s",
     467              :             onnx_file.c_str());
     468              :     return ML_ERROR_INVALID_PARAMETER;
     469              :   }
     470              : 
     471              :   try {
     472              :     std::unique_ptr<GraphInterpreter> onnx_interpreter =
     473              :       std::make_unique<nntrainer::ONNXInterpreter>();
     474              : 
     475              :     auto graph_representation = onnx_interpreter->deserialize(onnx_file);
     476              : 
     477              :     for (auto &node : graph_representation) {
     478              :       model.addLayer(node);
     479              :     };
     480              : 
     481              :     if (model.empty()) {
     482              :       ml_loge("there is no layer section in the ini file");
     483              :       status = ML_ERROR_INVALID_PARAMETER;
     484              :     }
     485              :   } catch (std::exception &e) {
     486              :     ml_loge("failed to load graph, reason: %s ", e.what());
     487              :     status = ML_ERROR_INVALID_PARAMETER;
     488              :   }
     489              : 
     490              :   return status;
     491              : #else
     492            0 :   throw std::runtime_error{"enable-onnx-interpreter option is not enabled"};
     493              : #endif
     494              : }
     495              : 
     496              : /**
     497              :  * @brief     load all properties from context
     498              :  */
     499          666 : int ModelLoader::loadFromContext(NeuralNetwork &model) {
     500              :   /// @todo: Property for Context needs to updated
     501              :   // auto props = app_context.getProperties();
     502              :   // model.setTrainConfig(props);
     503              : 
     504          666 :   return ML_ERROR_NONE;
     505              : }
     506              : 
     507              : /**
     508              :  * @brief     load all of model and dataset from given config file
     509              :  */
     510          666 : int ModelLoader::loadFromConfig(std::string config, NeuralNetwork &model) {
     511              : 
     512          666 :   if (model_file_engine != nullptr) {
     513            0 :     ml_loge(
     514              :       "model_file_engine is already initialized, there is a possiblity that "
     515              :       "last load from config wasn't finished correctly, and model loader is "
     516              :       "reused");
     517            0 :     return ML_ERROR_UNKNOWN;
     518              :   }
     519              : 
     520         1332 :   model_file_engine = std::make_unique<Engine>();
     521              : 
     522          666 :   auto config_realpath_char = getRealpath(config.c_str(), nullptr);
     523          666 :   if (config_realpath_char == nullptr) {
     524              :     const size_t error_buflen = 100;
     525              :     char error_buf[error_buflen];
     526            2 :     ml_loge("failed to resolve config path to absolute path, reason: %s",
     527              :             SAFE_STRERROR(errno, error_buf, error_buflen));
     528              :     return ML_ERROR_INVALID_PARAMETER;
     529              :   }
     530          665 :   std::string config_realpath(config_realpath_char);
     531          665 :   free(config_realpath_char);
     532              : 
     533              :   auto base_path =
     534         1330 :     std::filesystem::path(config_realpath).parent_path().string();
     535              : 
     536          665 :   model_file_engine->setWorkingDirectory(base_path);
     537              : 
     538         1330 :   ml_logd("for the current model working directory is set to %s",
     539              :           base_path.c_str());
     540              : 
     541         1330 :   int status = loadFromConfig(config_realpath, model, false);
     542              :   model_file_engine.reset();
     543              :   return status;
     544              : }
     545              : 
     546              : /**
     547              :  * @brief     load all of model and dataset from given config file
     548              :  */
     549          665 : int ModelLoader::loadFromConfig(std::string config, NeuralNetwork &model,
     550              :                                 bool bare_layers) {
     551          665 :   if (isIniFile(config)) {
     552         1330 :     return loadFromIni(config, model, bare_layers);
     553              :   }
     554              : 
     555            0 :   if (isONNXFile(config)) {
     556            0 :     return loadFromONNX(config, model);
     557              :   }
     558              : 
     559              :   return ML_ERROR_INVALID_PARAMETER;
     560              : }
     561              : 
     562          665 : bool ModelLoader::fileExt(const std::string &filename, const std::string &ext) {
     563              :   size_t position = filename.find_last_of(".");
     564          665 :   if (position == std::string::npos)
     565              :     return false;
     566              : 
     567          665 :   if (filename.substr(position + 1) == ext) {
     568              :     return true;
     569              :   }
     570              : 
     571              :   return false;
     572              : }
     573              : 
     574          665 : bool ModelLoader::isIniFile(const std::string &filename) {
     575         1330 :   return fileExt(filename, "ini");
     576              : }
     577              : 
     578            0 : bool ModelLoader::isTfLiteFile(const std::string &filename) {
     579            0 :   return fileExt(filename, "tflite");
     580              : }
     581              : 
     582            0 : bool ModelLoader::isONNXFile(const std::string &filename) {
     583            0 :   return fileExt(filename, "onnx");
     584              : }
     585              : 
     586              : } // namespace nntrainer
        

Generated by: LCOV version 2.0-1