update nntrainer backend interface 09/263109/5
authorInki Dae <inki.dae@samsung.com>
Thu, 26 Aug 2021 05:55:18 +0000 (14:55 +0900)
committerInki Dae <inki.dae@samsung.com>
Thu, 26 Aug 2021 10:05:28 +0000 (19:05 +0900)
This patch updates below things
- implement to update dataset through a given callbacks - one is to send
  training data to NNTrainer, and other for verifying it.
- fix ml_train_model_compile function call by setting only valid property
  options.
- consider ml_train_model_run function call without any options.
  . Regarding this function, NNTrainer has default property optinos so
    in case of no given option, we can use the default ones.

Change-Id: I0bc25a491403149641f41931f43965efddbf15a8
Signed-off-by: Inki Dae <inki.dae@samsung.com>
src/training_engine_nntrainer.cpp
src/training_engine_nntrainer_private.h

index 6d38e37d016e0d774523a84280215ad6ecf62976..7aa82cd9e45e0832b76b962c6f72a46f5353842b 100644 (file)
 
 using namespace std;
 using namespace TrainingEngineInterface::Common;
+using namespace TrainingEngineImpl::NntrainerImpl;
 
 namespace TrainingEngineImpl
 {
 namespace NntrainerImpl
 {
-
        int UpdateTrainData(float **data, float **label, bool *last, void *user_data)
        {
-               // TODO.
+               auto engine = static_cast<TrainingNntrainer *>(user_data);
+               auto train = engine->GetTrainDataSet();
+
+               if (engine->_train_data_idx == engine->GetTrainDataCnt()) {
+                       // if last is false then NNTrainer starts training with given data and label.
+                       // Otherwise, it finalizes the training.
+                       // 'last = true' means that all data and labels have been passed.
+                       *last = true;
+                       engine->_train_data_idx = 0;
+
+                       return ML_ERROR_NONE;
+               }
+
+               int idx = 0;
+
+               for (auto v : train[engine->_train_data_idx].data)
+                       data[0][idx++] = v;
+
+               idx = 0;
+               for (auto l : train[engine->_train_data_idx].label)
+                       label[0][idx++] = l;
+
+               engine->_train_data_idx++;
+               *last = false;
+
+               LOGI("Updated train data.");
+
+               return ML_ERROR_NONE;
+       }
+
+       int UpdateVerifyData(float **data, float **label, bool *last, void *user_data)
+       {
+               auto engine = static_cast<TrainingNntrainer *>(user_data);
+               auto verify = engine->GetVerifyDataSet();
+
+               if (engine->_verify_data_idx == engine->GetVerifyDataCnt()) {
+                       // if last is false then NNTrainer starts training with given data and label.
+                       // Otherwise, it finalizes the training.
+                       // 'last = true' means that all data and labels have been passed.
+                       *last = true;
+                       engine->_verify_data_idx = 0;
+
+                       return ML_ERROR_NONE;
+               }
+
+               int idx = 0;
+
+               for (auto v : verify[engine->_verify_data_idx].data)
+                       data[0][idx++] = v;
+
+               idx = 0;
+               for (auto l : verify[engine->_verify_data_idx].label)
+                       label[0][idx++] = l;
+
+               engine->_verify_data_idx++;
+               *last = false;
+
+               LOGI("Updated verify data.");
 
                return ML_ERROR_NONE;
        }
 
        TrainingNntrainer::TrainingNntrainer(void) :
-               train_data_set(), test_data_set(), verify_data_set()
+               _train_data_sets(), _verify_data_sets()
        {
        }
 
@@ -302,7 +359,7 @@ namespace NntrainerImpl
                return TRAINING_ENGINE_ERROR_NONE;
        }
 
-       unique_ptr<training_engine_dataset> TrainingNntrainer::CreateDataset(training_engine_dataset_type_e type)
+       unique_ptr<training_engine_dataset> TrainingNntrainer::CreateDataset(void)
        {
                LOGI("ENTER");
 
@@ -316,9 +373,11 @@ namespace NntrainerImpl
                }
 
                auto dataset = make_unique<training_engine_dataset>();
-               dataset->type = type;
                dataset->dataset_handle = static_cast<void *>(handle);
 
+               _train_data_idx = 0;
+               _verify_data_idx = 0;
+
                LOGI("LEAVE");
 
                return dataset;
@@ -370,71 +429,47 @@ namespace NntrainerImpl
                return 0;
        }
 
-       int TrainingNntrainer::AddDataToDataset(const training_engine_dataset *dataset,
-                                                                                       float *data, size_t data_len,
-                                                                                       float *label, size_t label_len,
+       int TrainingNntrainer::AddDataToDataset(training_engine_dataset *dataset,
+                                                                                       std::vector<float>& data, std::vector<float>& label,
                                                                                        training_engine_dataset_type_e type)
        {
                LOGI("ENTER");
 
+               ml_train_dataset_mode_e dataset_mode;
+               int (*func)(float **, float **, bool *, void *) = nullptr;
+
                switch (type) {
                        case TRAINING_DATASET_TYPE_TRAIN:
-                               for (size_t i = 0; i < data_len; ++i)
-                                       train_data_set.data_set.push_back(data[i]);
-
-                               for (size_t i = 0; i < label_len; ++i)
-                                       train_data_set.label_set.push_back(label[i]);
-
-                               train_data_set.total_data_len += data_len;
-                               train_data_set.total_label_len += label_len;
+                               _train_data_sets.push_back({data,label});
+                               dataset_mode = ML_TRAIN_DATASET_MODE_TRAIN;
+                               func = UpdateTrainData;
 
                                break;
-                       case TRAINING_DATASET_TYPE_TEST:
-                               for (size_t i = 0; i < data_len; ++i)
-                                       test_data_set.data_set.push_back(data[i]);
-
-                               for (size_t i = 0; i < label_len; ++i)
-                                       test_data_set.label_set.push_back(label[i]);
 
-                               test_data_set.total_data_len += data_len;
-                               test_data_set.total_label_len += label_len;
-
-                               break;
                        case TRAINING_DATASET_TYPE_VERIFY:
-                               for (size_t i = 0; i < data_len; ++i)
-                                       verify_data_set.data_set.push_back(data[i]);
+                               _verify_data_sets.push_back({data,label});
+                               dataset_mode = ML_TRAIN_DATASET_MODE_VALID;
+                               func = UpdateVerifyData;
 
-                               for (size_t i = 0; i < label_len; ++i)
-                                       verify_data_set.label_set.push_back(label[i]);
-
-                               verify_data_set.total_data_len += data_len;
-                               verify_data_set.total_label_len += label_len;
                                break;
+
                        default:
                                LOGE("Invalid dataset type");
                                return TRAINING_ENGINE_ERROR_INVALID_PARAMETER;
                }
 
-               LOGI("LEAVE");
-
-               return TRAINING_ENGINE_ERROR_NONE;
-       }
-
-       int TrainingNntrainer::AddDataToDataset(const training_engine_dataset *dataset,
-                                                                                       uint32_t *data, size_t data_len,
-                                                                                       uint32_t *label, size_t label_len,
-                                                                                       training_engine_dataset_type_e type)
-       {
-               LOGI("ENTER");
-
-               // TODO.
+               int ret = ml_train_dataset_add_generator(dataset->dataset_handle, dataset_mode, func, static_cast<void *>(this));
+               if (ret != ML_ERROR_NONE) {
+                       LOGE("Failed to add user callback. %d", ret);
+                       return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+               }
 
                LOGI("LEAVE");
 
-               return 0;
+               return TRAINING_ENGINE_ERROR_NONE;
        }
 
-       int TrainingNntrainer::SetDataset(const training_engine_model *model,
+       int TrainingNntrainer::SetDataset(training_engine_model *model,
                                                                          const training_engine_dataset *dataset)
        {
                LOGI("ENTER");
@@ -445,7 +480,7 @@ namespace NntrainerImpl
                int ret = ml_train_model_set_dataset(static_cast<ml_train_model_h>(model->model_handle),
                                                                                           static_cast<ml_train_dataset_h>(dataset->dataset_handle));
                if (ret != ML_ERROR_NONE) {
-                       LOGE("Failed to add a given dataset to a given model.");
+                       LOGE("Failed to add a given dataset to a given model. %d", ret);
                        return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
                }
 
@@ -460,32 +495,16 @@ namespace NntrainerImpl
                LOGI("ENTER");
 
                TE_CHECK_OBJ(model, TRAINING_ENGINE_ERROR_INVALID_PARAMETER);
+               LOGI("Compile option size : %zu", property.options.size());
 
-               std::vector<std::string> strings;
-               // The maximum count of model and compile properties is 5.
-               const unsigned int max_property_size = 5;
-               size_t original_size = property.options.size();
-
-               if (max_property_size < original_size) {
-                       LOGE("Invalid a number of property.");
-                       return TRAINING_ENGINE_ERROR_INVALID_PARAMETER;
-               }
-
-               size_t actual_size = 0;
-
-               for (size_t index = 0; index < original_size; ++index) {
-                       strings.push_back(property.options[index]);
-                       actual_size++;
-               }
-
-               for (size_t index = 0; index < max_property_size - actual_size; ++index)
-                       strings.push_back("");
+               for (auto& opt : property.options) {
+                       LOGI("Set %s property", opt.c_str());
 
-               int ret = ml_train_model_compile(model->model_handle, strings[0], strings[1],
-                                                                                strings[2], strings[3], strings[4], NULL);
-               if (ret != ML_ERROR_NONE) {
-                       LOGE("Failed to compile a given model.");
-                       return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+                       int ret = ml_train_model_compile(model->model_handle, opt.c_str(), NULL);
+                       if (ret != ML_ERROR_NONE) {
+                               LOGE("Failed to compile a given model.");
+                               return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+                       }
                }
 
                LOGI("LEAVE");
@@ -499,38 +518,36 @@ namespace NntrainerImpl
                LOGI("ENTER");
 
                TE_CHECK_OBJ(model, TRAINING_ENGINE_ERROR_INVALID_PARAMETER);
+               LOGI("Model option size : %zu", property.options.size());
 
-               std::vector<std::string> strings;
-               // The maximum count of model and compile properties is 5.
-               const unsigned int max_property_size = 5;
-               size_t original_size = property.options.size();
-
-               if (max_property_size < original_size) {
-                       LOGE("Invalid a number of property.");
-                       return TRAINING_ENGINE_ERROR_INVALID_PARAMETER;
-               }
+               int ret = TRAINING_ENGINE_ERROR_NONE;
 
-               size_t actual_size = 0;
+               // It's able to train a given model with no option. In this case,
+               // default options will be used.
+               if (property.options.empty()) {
+                       ret = ml_train_model_run(model->model_handle, NULL, NULL);
+                       if (ret != ML_ERROR_NONE) {
+                               LOGE("Failed to compile a given model.");
+                               return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+                       }
 
-               for (size_t index = 0; index < original_size; ++index) {
-                       strings.push_back(property.options[index]);
-                       actual_size++;
+                       goto out;
                }
 
-               for (size_t index = 0; index < max_property_size - actual_size; ++index)
-                       strings.push_back("");
+               for (auto& opt : property.options) {
+                       LOGI("Set %s property", opt.c_str());
 
-               int ret = ml_train_model_run(model->model_handle, strings[0], strings[1],
-                                                                        strings[2], strings[3], strings[4], NULL);
-               if (ret != ML_ERROR_NONE) {
-                       LOGE("Failed to train a given model.");
-                       return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+                       ret = ml_train_model_run(model->model_handle, opt.c_str(), NULL);
+                       if (ret != ML_ERROR_NONE) {
+                               LOGE("Failed to compile a given model.");
+                               return TRAINING_ENGINE_ERROR_INVALID_OPERATION;
+                       }
                }
 
-
+out:
                LOGI("LEAVE");
 
-               return 0;
+               return ret;
        }
        extern "C"
        {
index 872edcc47d8402627218bf9eb6954e6c33a78e3d..406148d883f20375670c92aca5f1fe3c249abd72 100644 (file)
@@ -34,11 +34,9 @@ namespace TrainingEngineImpl
 namespace NntrainerImpl
 {
 
-       typedef struct dataset_type {
-               size_t total_data_len;
-               size_t total_label_len;
-               std::vector<float> data_set;
-               std::vector<float> label_set;
+       typedef struct {
+               std::vector<float> data;
+               std::vector<float> label;
        } dataset_type;
 
        class TrainingNntrainer : public TrainingEngineInterface::Common::ITrainingEngineCommon
@@ -46,9 +44,8 @@ namespace NntrainerImpl
        private:
                ml_train_layer_type_e ConvertLayerType(training_engine_layer_type_e type);
                ml_train_optimizer_type_e ConvertOptimizerType(training_engine_optimizer_type_e type);
-               dataset_type train_data_set;
-               dataset_type test_data_set;
-               dataset_type verify_data_set;
+               std::vector<dataset_type> _train_data_sets;
+               std::vector<dataset_type> _verify_data_sets;
 
        public:
                TrainingNntrainer();
@@ -64,16 +61,37 @@ namespace NntrainerImpl
                std::unique_ptr<training_engine_optimizer> CreateOptimizer(training_engine_optimizer_type_e type) final;
                int SetOptimizerProperty(const training_engine_optimizer *optimizer, training_engine_optimizer_property &property) final;
                int AddOptimizer(const training_engine_model *model, const training_engine_optimizer *optimizer) final;
-               std::unique_ptr<training_engine_dataset> CreateDataset(training_engine_dataset_type_e type) final;
+               std::unique_ptr<training_engine_dataset> CreateDataset(void) final;
                void DestroyDataset(const training_engine_dataset *dataset) final;
                int SetDatasetProperty(const training_engine_dataset *dataset, training_engine_dataset_property &property) final;
-               int AddDataToDataset(const training_engine_dataset *dataset, float *data, size_t data_len,
-                                                        float *label, size_t label_len, training_engine_dataset_type_e type) final;
-               int AddDataToDataset(const training_engine_dataset *dataset, unsigned int *data, size_t data_len,
-                                                        unsigned int *label, size_t label_len, training_engine_dataset_type_e type) final;
-               int SetDataset(const training_engine_model *model, const training_engine_dataset *dataset) final;
+               int AddDataToDataset(training_engine_dataset *dataset, std::vector<float>& data,
+                                                        std::vector<float>& label, training_engine_dataset_type_e type) final;
+               int SetDataset(training_engine_model *model, const training_engine_dataset *dataset) final;
                int CompileModel(const training_engine_model *model, training_engine_compile_property &property) final;
                int TrainModel(const training_engine_model *model, training_engine_model_property &property) final;
+
+               std::vector<dataset_type>& GetTrainDataSet(void)
+               {
+                       return _train_data_sets;
+               }
+
+               std::vector<dataset_type>& GetVerifyDataSet(void)
+               {
+                       return _verify_data_sets;
+               }
+
+               int GetTrainDataCnt(void)
+               {
+                       return static_cast<int>(_train_data_sets.size());
+               }
+
+               int GetVerifyDataCnt(void)
+               {
+                       return static_cast<int>(_verify_data_sets.size());
+               }
+
+               int _train_data_idx;
+               int _verify_data_idx;
        };
 
 } /* NntrainerImpl */