[mlpack-git] master,mlpack-1.0.x: memory leak fix (bf0e023)
gitdub at big.cc.gt.atl.ga.us
gitdub at big.cc.gt.atl.ga.us
Thu Mar 5 21:50:07 EST 2015
Repository : https://github.com/mlpack/mlpack
On branches: master,mlpack-1.0.x
Link : https://github.com/mlpack/mlpack/compare/904762495c039e345beba14c1142fd719b3bd50e...f94823c800ad6f7266995c700b1b630d5ffdcf40
>---------------------------------------------------------------
commit bf0e0239e988190e898d1729aa823f4bbd552c03
Author: andrewmw94 <andrewmw94 at gmail.com>
Date: Mon Jun 30 13:31:15 2014 +0000
memory leak fix
>---------------------------------------------------------------
bf0e0239e988190e898d1729aa823f4bbd552c03
.../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 | 7 +++--
5 files changed, 57 insertions(+), 19 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
@@ -13,9 +13,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
* We then call AssignPointDestNode to assign the remaining points to the two 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;
@@ -144,10 +144,6 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
}
}
- // 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.
assert(par->NumChildren() <= par->MaxNumChildren());
@@ -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
@@ -128,6 +128,11 @@ class RectangleTree
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
* of the leaf node where it is finally inserted, but we pass by reference since
* it may be passed many times before it actually reaches a leaf.
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);
+ 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,
@@ -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,
More information about the mlpack-git
mailing list