Fix potential memory leak when finalize.
authorJihoon Lee <jhoon.it.lee@samsung.com>
Thu, 7 May 2020 03:47:13 +0000 (12:47 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Thu, 7 May 2020 07:39:17 +0000 (16:39 +0900)
This PR...

 1. Solves memory leak detected from valgrind.
 2. Correct the author of `unittest_util_func.cpp`.

Self evaluation:

Build test: [X]Passed [ ]Failed [ ]Skipped
Run test: [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
api/capi/src/nntrainer.cpp
nntrainer/include/databuffer.h
nntrainer/src/databuffer.cpp
nntrainer/src/neuralnet.cpp
test/unittest/unittest_databuffer_file.cpp
test/unittest/unittest_util_func.cpp

index cd6baf9..4b4394c 100644 (file)
@@ -152,6 +152,7 @@ int ml_nnmodel_destruct(ml_nnmodel_h model) {
   NN = nnmodel->network;
   NN->finalize();
   delete NN;
+  delete nnmodel;
 
   return status;
 }
index 75489b6..fc31894 100644 (file)
@@ -172,6 +172,14 @@ public:
   virtual int clear(BufferType type);
 
   /**
+   * @brief     clear all thread ( training, validation, test )
+   * @retval #ML_ERROR_NONE Successful.
+   * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
+   */
+  virtual int clear();
+
+
+  /**
    * @brief     get Status of Buffer. if number of rest data
    *            is samller than minibatch, the return false
    * @param[in] BufferType training, validation, test
index 52e7c9e..21d8dab 100644 (file)
@@ -171,6 +171,23 @@ int DataBuffer::clear(BufferType type) {
   return status;
 }
 
+int DataBuffer::clear(){
+  unsigned int i;
+
+  int status = ML_ERROR_NONE;
+  for(i = BUF_TRAIN; i <= BUF_TEST; ++i){
+    BufferType type = static_cast<BufferType>(i);
+    status = this->clear(type);
+
+    if(status != ML_ERROR_NONE){
+      ml_loge("Error: error occurred during clearing");
+      return status;
+    }
+  }
+
+  return status;
+}
+
 DataStatus DataBuffer::getStatus(BufferType type) {
   DataStatus ret = DATA_READY;
   if (globalExceptionPtr)
index 8fb8ab2..ef2fc0f 100644 (file)
@@ -521,6 +521,11 @@ void NeuralNetwork::finalize() {
   for (unsigned int i = 0; i < layers.size(); i++) {
     delete layers[i];
   }
+
+  if (data_buffer){
+    data_buffer->clear();
+    delete data_buffer;
+  }
 }
 
 /**
index 170d8fc..13c2732 100644 (file)
@@ -186,6 +186,89 @@ TEST(nntrainer_DataBuffer, setDataFile_04_n) {
 
 
 /**
+ * @brief Data buffer clear all
+ */
+TEST(nntrainer_DataBuffer, clear_01_p){
+  int status = ML_ERROR_NONE;
+  nntrainer::DataBufferFromDataFile data_buffer;
+  status = data_buffer.setMiniBatch(32);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setClassNum(10);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setDataFile("trainingSet.dat", nntrainer::DATA_TRAIN);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setDataFile("valSet.dat", nntrainer::DATA_VAL);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setDataFile("testSet.dat", nntrainer::DATA_TEST);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setDataFile("label.dat", nntrainer::DATA_LABEL);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.setFeatureSize(62720);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.init();
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.run(nntrainer::BUF_TRAIN);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.run(nntrainer::BUF_TEST);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.run(nntrainer::BUF_VAL);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear();
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Data buffer partial clear
+ */
+TEST(nntrainer_DataBuffer, clear_02_p){
+  int status = ML_ERROR_NONE;
+  nntrainer::DataBufferFromDataFile data_buffer;
+  status = data_buffer.setDataFile("testSet.dat", nntrainer::DATA_TEST);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear(nntrainer::BUF_TEST);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Data buffer all clear after partial clear
+ */
+TEST(nntrainer_DataBuffer, clear_03_p){
+  int status = ML_ERROR_NONE;
+  nntrainer::DataBufferFromDataFile data_buffer;
+  status = data_buffer.setDataFile("testSet.dat", nntrainer::DATA_TEST);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear(nntrainer::BUF_TEST);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear();
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+
+/**
+ * @brief Data buffer partial clear after all clear
+ */
+TEST(nntrainer_DataBuffer, clear_04_p){
+  int status = ML_ERROR_NONE;
+  nntrainer::DataBufferFromDataFile data_buffer;
+  status = data_buffer.setDataFile("testSet.dat", nntrainer::DATA_TEST);
+  ASSERT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear(nntrainer::BUF_TEST);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = data_buffer.clear();
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Data buffer clear BUF_UNKNOWN
+ */
+TEST(nntrainer_DataBuffer, clear_05_n){
+  int status = ML_ERROR_NONE;
+  nntrainer::DataBufferFromDataFile data_buffer;
+  status = data_buffer.clear(nntrainer::BUF_UNKNOWN);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+}
+
+/**
  * @brief Main gtest
  */
 int main(int argc, char **argv) {
index b54669c..f103837 100644 (file)
@@ -17,7 +17,7 @@
  * @date        10 April 2020
  * @brief       Unit test for util_func.cpp.
  * @see         https://github.com/nnstreamer/nntrainer
- * @author      Jihoon Lee <jhoon.it.lee@samsung.com>
+ * @author      Jijoong Moon <jijoong.moon@samsung.com>
  * @bug         No known bugs
  */