[mlpack] 91/324: memory leak fix

Barak A. Pearlmutter barak+git at cs.nuim.ie
Sun Aug 17 08:21:59 UTC 2014


This is an automated email from the git hooks/post-receive script.

bap pushed a commit to branch svn-trunk
in repository mlpack.

commit b86180a3eedc958b588af543febb51fb28d5c6b2
Author: andrewmw94 <andrewmw94 at 9d5b8971-822b-0410-80eb-d18c1038ef23>
Date:   Mon Jun 30 13:31:15 2014 +0000

    memory leak fix
    
    git-svn-id: http://svn.cc.gatech.edu/fastlab/mlpack/trunk@16729 9d5b8971-822b-0410-80eb-d18c1038ef23
---
 .../r_tree_descent_heuristic_impl.hpp              | 11 +++++++-
 .../core/tree/rectangle_tree/r_tree_split_impl.hpp | 20 ++++++-------
 .../core/tree/rectangle_tree/rectangle_tree.hpp    |  5 ++++
 .../tree/rectangle_tree/rectangle_tree_impl.hpp    | 33 ++++++++++++++++++----
 src/mlpack/tests/rectangle_tree_test.cpp           | 11 ++++----
 5 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
index 7c15a22..5542119 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
@@ -13,9 +13,18 @@
 namespace mlpack {
 namespace tree {
 
+// Return the increase in volume required when inserting point into bound.
 inline double RTreeDescentHeuristic::EvalNode(const HRectBound<>& bound, const arma::vec& point)
 {
-  return bound.Contains(point) ? 0 : bound.MinDistance(point);
+  double v1 = 1.0;
+  double v2 = 1.0;
+  for(size_t i = 0; i < bound.Dim(); i++) {
+    v1 *= bound[i].Width();
+    v2 *= bound[i].Contains(point[i]) ? bound[i].Width() : (bound[i].Hi() < point[i] ? (point[i] - bound[i].Lo()) :
+      (bound[i].Hi() - point[i]));
+  }
+  assert(v2 - v1 >= 0);
+  return v2 - v1;
 }
 
 }; // namespace tree
diff --git a/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
index 32dbee0..fbe4519 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
@@ -12,9 +12,6 @@
 
 namespace mlpack {
 namespace tree {
-
-  //-r ../test_data_3_1000.csv -n neighbors_out.csv -d distances_out.csv -k 3 -v --r_tree
-  
   
 /**
  * We call GetPointSeeds to get the two points which will be the initial points in the new nodes
@@ -35,6 +32,7 @@ void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
       new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
     copy->Parent() = tree;
     tree->Count() = 0;
+    tree->NullifyData();
     tree->Children()[(tree->NumChildren())++] = copy; // Because this was a leaf node, numChildren must be 0.
     assert(tree->NumChildren() == 1);
     RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(copy);
@@ -69,9 +67,6 @@ void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   par->Children()[index] = treeOne;
   par->Children()[par->NumChildren()++] = treeTwo;
      
-  // We need to delete this carefully since references to points are used.
-  tree->softDelete();
-
   // we only add one at a time, so we should only need to test for equality
   // just in case, we use an assert.
   assert(par->NumChildren() <= par->MaxNumChildren());
@@ -83,6 +78,10 @@ void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   assert(treeOne->Parent()->NumChildren() >= treeOne->MinNumChildren());
   assert(treeTwo->Parent()->NumChildren() < treeTwo->MaxNumChildren());
   assert(treeTwo->Parent()->NumChildren() >= treeTwo->MinNumChildren());
+  
+  // We need to delete this carefully since references to points are used.
+  tree->softDelete();
+  
   return;
 }
 
@@ -106,6 +105,7 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
       new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
     copy->Parent() = tree;
     tree->NumChildren() = 0;
+    tree->NullifyData();
     tree->Children()[(tree->NumChildren())++] = copy;
     RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(copy);
     return true;
@@ -143,10 +143,6 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
       assert(par->Children()[i] != tree);
     }
   }
-
-  // Because we now have pointers to the information stored under this tree,
-  // we need to delete this node carefully.
-  tree->softDelete(); //currently does nothing but leak memory.
   
   // we only add one at a time, so should only need to test for equality
   // just in case, we use an assert.
@@ -169,6 +165,10 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   assert(treeTwo->NumChildren() < treeTwo->MaxNumChildren());
   assert(treeOne->Parent()->NumChildren() < treeOne->MaxNumChildren()); 
 
+  // Because we now have pointers to the information stored under this tree,
+  // we need to delete this node carefully.
+  tree->softDelete(); //currently does nothing but leak memory.
+  
   return false;
 }
 
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
index 1095c8a..3e4bdfd 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -126,6 +126,11 @@ class RectangleTree
    * other trees.
    */
   void softDelete();
+  
+  /**
+   * Set dataset to null. Used for memory management.  Be cafeful.
+   */
+  void NullifyData();
 
   /**
    * Inserts a point into the tree. The point will be copied to the data matrix
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
index 6cd63ae..1589343 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -89,23 +89,46 @@ RectangleTree<SplitType, DescentType, StatisticType, MatType>::
   for(int i = 0; i < numChildren; i++) {
     delete children[i];
   }
-  delete dataset;
+  //if(numChildren == 0)
+    delete dataset;
 }
 
+
 /**
   * Deletes this node but leaves the children untouched.  Needed for when we 
   * split nodes and remove nodes (inserting and deleting points).
   */
 template<typename SplitType,
-                  typename DescentType,
-                  typename StatisticType,
-                  typename MatType>
+         typename DescentType,
+         typename StatisticType,
+         typename MatType>
 void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
     softDelete()
 {
-  /* do nothing.  I'm not sure how to handle this yet, so for now, we will leak memory */
+  //if(numChildren != 0)
+    //dataset = NULL;
+  parent = NULL;
+  for(int i = 0; i < children.size(); i++) {
+    children[i] = NULL;    
+  }
+  numChildren = 0;
+  delete this;  
+}
+
+/**
+  * Set the dataset to null.
+  */
+template<typename SplitType,
+         typename DescentType,
+         typename StatisticType,
+         typename MatType>
+void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
+    NullifyData()
+{
+  dataset = NULL;
 }
 
+
 /**
  * Recurse through the tree and insert the point at the leaf node chosen
  * by the heuristic.
diff --git a/src/mlpack/tests/rectangle_tree_test.cpp b/src/mlpack/tests/rectangle_tree_test.cpp
index bbfa4ee..da04f58 100644
--- a/src/mlpack/tests/rectangle_tree_test.cpp
+++ b/src/mlpack/tests/rectangle_tree_test.cpp
@@ -47,13 +47,14 @@ BOOST_AUTO_TEST_CASE(RectangeTreeTraitsTest)
 BOOST_AUTO_TEST_CASE(RectangleTreeConstructionCountTest)
 {
   arma::mat dataset;
-  dataset.randu(3, 1000); // 1000 points in 3 dimensions.
+  dataset.randu(8, 1000); // 1000 points in 3 dimensions.
   
   RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
                       tree::RTreeDescentHeuristic,
                       NeighborSearchStat<NearestNeighborSort>,
                       arma::mat> tree(dataset, 20, 6, 5, 2, 0);
-  BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000); 
+  BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000);
+  std::cout << tree.ToString() << std::endl;
 }
 
 std::vector<arma::vec*> getAllPointsInTree(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
@@ -79,7 +80,7 @@ std::vector<arma::vec*> getAllPointsInTree(const RectangleTree<tree::RTreeSplit<
 BOOST_AUTO_TEST_CASE(RectangleTreeConstructionRepeatTest)
 {
   arma::mat dataset;
-  dataset.randu(8, 1000); // 1000 points in 8 dimensions.
+  dataset.randu(8, 15); // 1000 points in 8 dimensions.
   
   RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
                       tree::RTreeDescentHeuristic,
@@ -100,7 +101,7 @@ BOOST_AUTO_TEST_CASE(RectangleTreeConstructionRepeatTest)
   }
   for(size_t i = 0; i < allPoints.size(); i++) {
     delete allPoints[i];
-  }  
+  }
 }
 
 bool checkContainment(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
@@ -129,7 +130,7 @@ bool checkContainment(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeu
 BOOST_AUTO_TEST_CASE(RectangleTreeContainmentTest)
 {
     arma::mat dataset;
-  dataset.randu(8, 1000); // 1000 points in 8 dimensions.
+  dataset.randu(8, 15); // 1000 points in 8 dimensions.
   
   RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
                       tree::RTreeDescentHeuristic,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mlpack.git



More information about the debian-science-commits mailing list