Recycle numeric factorisation when using Accelerate Sparse.
Change-Id: Id94d77f9437e31c37ae99f48d28800fc9ce841ec
diff --git a/internal/ceres/accelerate_sparse.cc b/internal/ceres/accelerate_sparse.cc
index a82d90b..dc02986 100644
--- a/internal/ceres/accelerate_sparse.cc
+++ b/internal/ceres/accelerate_sparse.cc
@@ -115,6 +115,12 @@
return SparseFactor(*symbolic_factor, *A);
}
+template<typename Scalar>
+void AccelerateSparse<Scalar>::Cholesky(ASSparseMatrix* A,
+ NumericFactorization* numeric_factor) {
+ return SparseRefactor(*A, numeric_factor);
+}
+
// Instantiate only for the specific template types required/supported s/t the
// definition can be in the .cc file.
template class AccelerateSparse<double>;
@@ -169,14 +175,19 @@
}
}
- FreeNumericFactorization();
- numeric_factor_.reset(
- new typename SparseTypesTrait<Scalar>::NumericFactorization(
- as_.Cholesky(&as_lhs, symbolic_factor_.get())));
+ if (!numeric_factor_) {
+ numeric_factor_.reset(
+ new typename SparseTypesTrait<Scalar>::NumericFactorization(
+ as_.Cholesky(&as_lhs, symbolic_factor_.get())));
+ } else {
+ // Recycle memory from previous numeric factorization.
+ as_.Cholesky(&as_lhs, numeric_factor_.get());
+ }
if (numeric_factor_->status != SparseStatusOK) {
*message = StringPrintf(
"Apple Accelerate Failure : Numeric factorisation failed: %s",
SparseStatusToString(numeric_factor_->status));
+ FreeNumericFactorization();
return LINEAR_SOLVER_FAILURE;
}
diff --git a/internal/ceres/accelerate_sparse.h b/internal/ceres/accelerate_sparse.h
index cb5d084..b849a80 100644
--- a/internal/ceres/accelerate_sparse.h
+++ b/internal/ceres/accelerate_sparse.h
@@ -95,6 +95,9 @@
// symbolic factorization.
NumericFactorization Cholesky(ASSparseMatrix* A,
SymbolicFactorization* symbolic_factor);
+ // Reuse the NumericFactorization from a previous matrix with the same
+ // symbolic factorization to represent a new numeric factorization.
+ void Cholesky(ASSparseMatrix* A, NumericFactorization* numeric_factor);
private:
std::vector<long> column_starts_;