Skip to content

Instantly share code, notes, and snippets.

@rcurtin
Created January 16, 2018 16:05
Show Gist options
  • Save rcurtin/58e010fbf4344e905f8b892390b0d0fe to your computer and use it in GitHub Desktop.
Save rcurtin/58e010fbf4344e905f8b892390b0d0fe to your computer and use it in GitHub Desktop.
Memory fixes for FastMKS; correct this time.
diff --git a/src/mlpack/core/metrics/ip_metric.hpp b/src/mlpack/core/metrics/ip_metric.hpp
index a24552de3..8a8d48462 100644
--- a/src/mlpack/core/metrics/ip_metric.hpp
+++ b/src/mlpack/core/metrics/ip_metric.hpp
@@ -38,9 +38,21 @@ class IPMetric
//! Create the IPMetric with an instantiated kernel.
IPMetric(KernelType& kernel);
+ //! Create the IPMetric by copying the other IPMetric.
+ IPMetric(const IPMetric& other);
+
+ //! Create the IPMetric by taking ownership of the other IPMetric.
+ IPMetric(IPMetric&& other);
+
//! Destroy the IPMetric object.
~IPMetric();
+ //! Copy the given IPMetric object.
+ IPMetric& operator=(const IPMetric& other);
+
+ //! Take ownership of the given IPMetric object.
+ IPMetric& operator=(IPMetric&& other);
+
/**
* Evaluate the metric.
*
diff --git a/src/mlpack/core/metrics/ip_metric_impl.hpp b/src/mlpack/core/metrics/ip_metric_impl.hpp
index d39026593..a9f10729f 100644
--- a/src/mlpack/core/metrics/ip_metric_impl.hpp
+++ b/src/mlpack/core/metrics/ip_metric_impl.hpp
@@ -39,6 +39,26 @@ IPMetric<KernelType>::IPMetric(KernelType& kernel) :
// Nothing to do.
}
+// Copy constructor.
+template<typename KernelType>
+IPMetric<KernelType>::IPMetric(const IPMetric<KernelType>& other) :
+ kernel(new KernelType(*other.kernel)),
+ kernelOwner(true)
+{
+ // Nothing to do.
+}
+
+// Move constructor.
+template<typename KernelType>
+IPMetric<KernelType>::IPMetric(IPMetric<KernelType>&& other) :
+ kernel(other.kernel),
+ kernelOwner(other.kernelOwner)
+{
+ // Reset other object.
+ other.kernel = new KernelType();
+ other.kernelOwner = true;
+}
+
// Destructor for the IPMetric.
template<typename KernelType>
IPMetric<KernelType>::~IPMetric()
@@ -47,6 +67,38 @@ IPMetric<KernelType>::~IPMetric()
delete kernel;
}
+// Copy operator for the IPMetric.
+template<typename KernelType>
+IPMetric<KernelType>& IPMetric<KernelType>::operator=(
+ const IPMetric<KernelType>& other)
+{
+ if (kernelOwner)
+ delete kernel;
+
+ kernel = new KernelType(*other.kernel);
+ kernelOwner = true;
+
+ return *this;
+}
+
+// Move operator for the IPMetric.
+template<typename KernelType>
+IPMetric<KernelType>& IPMetric<KernelType>::operator=(
+ IPMetric<KernelType>&& other)
+{
+ if (kernelOwner)
+ delete kernel;
+
+ kernel = other.kernel;
+ kernelOwner = other.kernelOwner;
+
+ // Reset other object.
+ other.kernel = new KernelType();
+ other.kernelOwner = true;
+
+ return *this;
+}
+
template<typename KernelType>
template<typename Vec1Type, typename Vec2Type>
inline typename Vec1Type::elem_type IPMetric<KernelType>::Evaluate(@@ -68,7 +120,13 @@ void IPMetric<KernelType>::serialize(Archive& ar,
// If we're loading, we need to allocate space for the kernel, and we will own
// the kernel.
if (Archive::is_loading::value)
+ {
+ // Delete an existing kernel.
+ if (kernelOwner)
+ delete kernel;
+
kernelOwner = true;
+ }
ar & BOOST_SERIALIZATION_NVP(kernel);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment