Modularize the build.
1. Add -DLINE_SEARCH_MINIMIZER to CMake to make the line search
minimizer optional.
2. Better handling of -DSUITESPARSE/-DCXSPARSE in top level cmake
file.
3. Disable code which will never be used if SuiteSparse and/or
CXSparse is not available.
4. Update build docs.
5. Update jni/Android.mk
6. Minor lint cleanup from William Rucklidge.
Change-Id: If60460a858000df82faed7a6bb056dd2bfdde562
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d33b1e..b6c7359 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,6 +122,7 @@
SET(CXSPARSE_SEARCH_HEADERS ${SEARCH_HEADERS})
LIST(APPEND CXSPARSE_SEARCH_HEADERS /usr/include/suitesparse) # Ubuntu
+IF ((NOT DEFINED SUITESPARSE) OR (DEFINED SUITESPARSE AND SUITESPARSE))
# Check for SuiteSparse dependencies
MESSAGE("-- Check for AMD")
SET(AMD_FOUND TRUE)
@@ -300,6 +301,7 @@
(${SUITESPARSE_CONFIG_FOUND} OR ${UFCONFIG_FOUND}) AND
${BLAS_AND_LAPACK_FOUND})
+ENDIF ((NOT DEFINED SUITESPARSE) OR (DEFINED SUITESPARSE AND SUITESPARSE))
# By default, if all of SuiteSparse's dependencies are found, Ceres is
# built with SuiteSparse support. -DSUITESPARSE=ON/OFF can be used to
# enable/disable SuiteSparse explicitly.
@@ -325,6 +327,7 @@
# By default, if all of CXSparse's dependencies are found, Ceres is
# built with CXSparse support. -DCXSPARSE=ON/OFF can be used to
# enable/disable CXSparse explicitly.
+IF ((NOT DEFINED CXSPARSE) OR (DEFINED CXSPARSE AND CXSPARSE))
MESSAGE("-- Check for CXSparse")
SET(CXSPARSE_FOUND ON)
@@ -343,6 +346,7 @@
MESSAGE("-- Did not find CXSparse header")
SET(CXSPARSE_FOUND FALSE)
ENDIF (EXISTS ${CXSPARSE_INCLUDE})
+ENDIF ((NOT DEFINED CXSPARSE) OR (DEFINED CXSPARSE AND CXSPARSE))
IF (DEFINED CXSPARSE)
IF (${CXSPARSE})
@@ -434,6 +438,19 @@
MESSAGE("-- Disabling Schur specializations (faster compiles)")
ENDIF (NOT ${SCHUR_SPECIALIZATIONS})
+# Line search minimizer is useful for large scale problems or when
+# sparse linear algebra libraries are not available. If compile time,
+# binary size or compiler performance is an issue, consider disabling
+# this.
+OPTION(LINE_SEARCH_MINIMIZER
+ "Enable the line search minimizer."
+ ON)
+
+IF (NOT ${LINE_SEARCH_MINIMIZER})
+ ADD_DEFINITIONS(-DCERES_NO_LINE_SEARCH_MINIMIZER)
+ MESSAGE("-- Disabling line search minimizer")
+ENDIF (NOT ${LINE_SEARCH_MINIMIZER})
+
# Multithreading using OpenMP
OPTION(OPENMP
"Enable threaded solving in Ceres (requires OpenMP)"
diff --git a/docs/source/building.rst b/docs/source/building.rst
index fa81975..c2d7e24 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -320,6 +320,11 @@
the ``SPARSE_SCHUR`` solver, you can disable some of the template
specializations by using this flag.
+#. ``-DLINE_SEARCH_MINIMIZER=OFF``: The line search based minimizer is
+ mostly suitable for large scale optimization problems, or when sparse
+ linear algebra libraries are not available. You can further save on
+ some compile time and binary size by using this flag.
+
#. ``-DOPENMP=OFF``: On certain platforms like Android,
multi-threading with ``OpenMP`` is not supported. Use this flag to
disable multithreading.
diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc
index d0dc1e6..6531945 100644
--- a/internal/ceres/canonical_views_clustering.cc
+++ b/internal/ceres/canonical_views_clustering.cc
@@ -29,6 +29,8 @@
// Author: David Gallup (dgallup@google.com)
// Sameer Agarwal (sameeragarwal@google.com)
+#ifndef CERES_NO_SUITESPARSE
+
#include "ceres/canonical_views_clustering.h"
#include "ceres/collections_port.h"
@@ -236,3 +238,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_SUITESPARSE
diff --git a/internal/ceres/canonical_views_clustering.h b/internal/ceres/canonical_views_clustering.h
index 5f8e4e3..48d1ed2 100644
--- a/internal/ceres/canonical_views_clustering.h
+++ b/internal/ceres/canonical_views_clustering.h
@@ -41,6 +41,8 @@
#ifndef CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
#define CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
+#ifndef CERES_NO_SUITESPARSE
+
#include <vector>
#include "ceres/collections_port.h"
@@ -130,4 +132,5 @@
} // namespace internal
} // namespace ceres
+#endif // CERES_NO_SUITESPARSE
#endif // CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
diff --git a/internal/ceres/canonical_views_clustering_test.cc b/internal/ceres/canonical_views_clustering_test.cc
index 29bac3c..78d5635 100644
--- a/internal/ceres/canonical_views_clustering_test.cc
+++ b/internal/ceres/canonical_views_clustering_test.cc
@@ -29,6 +29,8 @@
// Author: Sameer Agarwal (sameeragarwal@google.com)
// David Gallup (dgallup@google.com)
+#ifndef CERES_NO_SUITESPARSE
+
#include "ceres/canonical_views_clustering.h"
#include "ceres/collections_port.h"
@@ -141,3 +143,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_SUITESPARSE
diff --git a/internal/ceres/generate_eliminator_specialization.py b/internal/ceres/generate_eliminator_specialization.py
index b14b145..caeca69 100644
--- a/internal/ceres/generate_eliminator_specialization.py
+++ b/internal/ceres/generate_eliminator_specialization.py
@@ -104,7 +104,7 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
-// This file is generated using generate_eliminator_specializations.py.
+// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
"""
@@ -204,10 +204,10 @@
template = SPECIALIZATION_FILE
if (row_block_size == "Eigen::Dynamic" and
e_block_size == "Eigen::Dynamic" and
- f_block_size == "Eigen::Dynamic") :
+ f_block_size == "Eigen::Dynamic"):
template = DYNAMIC_FILE
- fptr.write(template % (row_block_size, e_block_size, f_block_size));
+ fptr.write(template % (row_block_size, e_block_size, f_block_size))
fptr.close()
f.write(FACTORY_CONDITIONAL % (row_block_size,
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index e7508ca..437f742 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -28,6 +28,7 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
#include "ceres/line_search.h"
#include <glog/logging.h>
@@ -209,3 +210,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index fccf63b..95bf56e 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -33,6 +33,8 @@
#ifndef CERES_INTERNAL_LINE_SEARCH_H_
#define CERES_INTERNAL_LINE_SEARCH_H_
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
+
#include <glog/logging.h>
#include <vector>
#include "ceres/internal/eigen.h"
@@ -209,4 +211,5 @@
} // namespace internal
} // namespace ceres
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
#endif // CERES_INTERNAL_LINE_SEARCH_H_
diff --git a/internal/ceres/line_search_direction.cc b/internal/ceres/line_search_direction.cc
index 1fc4de5..b8b582c 100644
--- a/internal/ceres/line_search_direction.cc
+++ b/internal/ceres/line_search_direction.cc
@@ -28,6 +28,8 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
+
#include "ceres/line_search_direction.h"
#include "ceres/line_search_minimizer.h"
#include "ceres/low_rank_inverse_hessian.h"
@@ -143,3 +145,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
diff --git a/internal/ceres/line_search_direction.h b/internal/ceres/line_search_direction.h
index 71063ab..0874754 100644
--- a/internal/ceres/line_search_direction.h
+++ b/internal/ceres/line_search_direction.h
@@ -31,6 +31,8 @@
#ifndef CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
#define CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
+
#include "ceres/internal/eigen.h"
#include "ceres/line_search_minimizer.h"
#include "ceres/types.h"
@@ -67,4 +69,5 @@
} // namespace internal
} // namespace ceres
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
#endif // CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index ca7d639..f43278c 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -38,6 +38,8 @@
// For details on the theory and implementation see "Numerical
// Optimization" by Nocedal & Wright.
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
+
#include "ceres/line_search_minimizer.h"
#include <algorithm>
@@ -281,3 +283,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
diff --git a/internal/ceres/line_search_minimizer.h b/internal/ceres/line_search_minimizer.h
index f82f139..59f5c3f 100644
--- a/internal/ceres/line_search_minimizer.h
+++ b/internal/ceres/line_search_minimizer.h
@@ -31,6 +31,8 @@
#ifndef CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
#define CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
+
#include "ceres/minimizer.h"
#include "ceres/solver.h"
#include "ceres/types.h"
@@ -74,4 +76,5 @@
} // namespace internal
} // namespace ceres
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
#endif // CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index 1753759..bd68c45 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -141,6 +141,7 @@
return true;
}
+#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
SparseSchurComplementSolver::SparseSchurComplementSolver(
const LinearSolver::Options& options)
@@ -365,5 +366,6 @@
}
#endif // CERES_NO_CXPARSE
+#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
} // namespace internal
} // namespace ceres
diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h
index 7e98f31..7c8d2e7 100644
--- a/internal/ceres/schur_complement_solver.h
+++ b/internal/ceres/schur_complement_solver.h
@@ -151,7 +151,7 @@
CERES_DISALLOW_COPY_AND_ASSIGN(DenseSchurComplementSolver);
};
-
+#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
// Sparse Cholesky factorization based solver.
class SparseSchurComplementSolver : public SchurComplementSolver {
public:
@@ -182,6 +182,7 @@
CERES_DISALLOW_COPY_AND_ASSIGN(SparseSchurComplementSolver);
};
+#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
} // namespace internal
} // namespace ceres
diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
index e18d3b9..7ea6d1f 100644
--- a/internal/ceres/solver_impl.cc
+++ b/internal/ceres/solver_impl.cc
@@ -268,7 +268,7 @@
WallTimeInSeconds() - minimizer_start_time;
}
-
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
void SolverImpl::LineSearchMinimize(
const Solver::Options& options,
Program* program,
@@ -309,6 +309,7 @@
summary->minimizer_time_in_seconds =
WallTimeInSeconds() - minimizer_start_time;
}
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
void SolverImpl::Solve(const Solver::Options& options,
ProblemImpl* problem_impl,
@@ -316,7 +317,11 @@
if (options.minimizer_type == TRUST_REGION) {
TrustRegionSolve(options, problem_impl, summary);
} else {
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
LineSearchSolve(options, problem_impl, summary);
+#else
+ LOG(FATAL) << "Ceres Solver was compiled with -DLINE_SEARCH_MINIMIZER=OFF";
+#endif
}
}
@@ -608,6 +613,8 @@
event_logger.AddEvent("PostProcess");
}
+
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
void SolverImpl::LineSearchSolve(const Solver::Options& original_options,
ProblemImpl* original_problem_impl,
Solver::Summary* summary) {
@@ -661,7 +668,7 @@
<< "to single threaded mode.";
options.num_threads = 1;
}
-#endif
+#endif // CERES_USE_OPENMP
summary->num_threads_given = original_options.num_threads;
summary->num_threads_used = options.num_threads;
@@ -800,7 +807,7 @@
summary->postprocessor_time_in_seconds =
WallTimeInSeconds() - post_process_start_time;
}
-
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
bool SolverImpl::IsOrderingValid(const Solver::Options& options,
const ProblemImpl* problem_impl,
diff --git a/internal/ceres/solver_impl.h b/internal/ceres/solver_impl.h
index c5f5efa..d2a2dd1 100644
--- a/internal/ceres/solver_impl.h
+++ b/internal/ceres/solver_impl.h
@@ -59,10 +59,29 @@
ProblemImpl* problem_impl,
Solver::Summary* summary);
+ // Run the TrustRegionMinimizer for the given evaluator and configuration.
+ static void TrustRegionMinimize(
+ const Solver::Options &options,
+ Program* program,
+ CoordinateDescentMinimizer* inner_iteration_minimizer,
+ Evaluator* evaluator,
+ LinearSolver* linear_solver,
+ double* parameters,
+ Solver::Summary* summary);
+
+#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
static void LineSearchSolve(const Solver::Options& options,
ProblemImpl* problem_impl,
Solver::Summary* summary);
+ // Run the LineSearchMinimizer for the given evaluator and configuration.
+ static void LineSearchMinimize(const Solver::Options &options,
+ Program* program,
+ Evaluator* evaluator,
+ double* parameters,
+ Solver::Summary* summary);
+#endif // CERES_NO_LINE_SEARCH_MINIMIZER
+
// Create the transformed Program, which has all the fixed blocks
// and residuals eliminated, and in the case of automatic schur
// ordering, has the E blocks first in the resulting program, with
@@ -108,24 +127,6 @@
Program* program,
string* error);
- // Run the TrustRegionMinimizer for the given evaluator and configuration.
- static void TrustRegionMinimize(
- const Solver::Options &options,
- Program* program,
- CoordinateDescentMinimizer* inner_iteration_minimizer,
- Evaluator* evaluator,
- LinearSolver* linear_solver,
- double* parameters,
- Solver::Summary* summary);
-
- // Run the LineSearchMinimizer for the given evaluator and configuration.
- static void LineSearchMinimize(
- const Solver::Options &options,
- Program* program,
- Evaluator* evaluator,
- double* parameters,
- Solver::Summary* summary);
-
// Remove the fixed or unused parameter blocks and residuals
// depending only on fixed parameters from the problem. Also updates
// num_eliminate_blocks, since removed parameters changes the point
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc
index dd05f0c..7946665 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -28,6 +28,8 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
+
#include "ceres/sparse_normal_cholesky_solver.h"
#include <algorithm>
@@ -257,3 +259,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
diff --git a/internal/ceres/sparse_normal_cholesky_solver.h b/internal/ceres/sparse_normal_cholesky_solver.h
index 8d48096..ebb32e6 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.h
+++ b/internal/ceres/sparse_normal_cholesky_solver.h
@@ -34,6 +34,8 @@
#ifndef CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
#define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
+#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
+
#include "ceres/cxsparse.h"
#include "ceres/internal/macros.h"
#include "ceres/linear_solver.h"
@@ -90,4 +92,5 @@
} // namespace internal
} // namespace ceres
+#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
#endif // CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index 371bdfa..fcd793c 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -28,6 +28,8 @@
//
// Author: kushalav@google.com (Avanish Kushal)
+#ifndef CERES_NO_SUITESPARSE
+
#include "ceres/visibility.h"
#include <cmath>
@@ -150,3 +152,5 @@
} // namespace internal
} // namespace ceres
+
+#endif
diff --git a/internal/ceres/visibility.h b/internal/ceres/visibility.h
index f29e3c6..2d1e6f8 100644
--- a/internal/ceres/visibility.h
+++ b/internal/ceres/visibility.h
@@ -35,6 +35,8 @@
#ifndef CERES_INTERNAL_VISIBILITY_H_
#define CERES_INTERNAL_VISIBILITY_H_
+#ifndef CERES_NO_SUITESPARSE
+
#include <set>
#include <vector>
#include "ceres/graph.h"
@@ -74,4 +76,5 @@
} // namespace internal
} // namespace ceres
+#endif // CERES_NO_SUITESPARSE
#endif // CERES_INTERNAL_VISIBILITY_H_
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index a75d6f0..9c92190 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -28,6 +28,8 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#ifndef CERES_NO_SUITESPARSE
+
#include "ceres/visibility_based_preconditioner.h"
#include <algorithm>
@@ -62,7 +64,6 @@
static const double kSizePenaltyWeight = 3.0;
static const double kSimilarityPenaltyWeight = 0.0;
-#ifndef CERES_NO_SUITESPARSE
VisibilityBasedPreconditioner::VisibilityBasedPreconditioner(
const CompressedRowBlockStructure& bs,
const Preconditioner::Options& options)
@@ -584,7 +585,7 @@
}
}
-#endif // CERES_NO_SUITESPARSE
-
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_SUITESPARSE
diff --git a/internal/ceres/visibility_test.cc b/internal/ceres/visibility_test.cc
index 793a19d..3cfb232 100644
--- a/internal/ceres/visibility_test.cc
+++ b/internal/ceres/visibility_test.cc
@@ -29,6 +29,8 @@
// Author: kushalav@google.com (Avanish Kushal)
// sameeragarwal@google.com (Sameer Agarwal)
+#ifndef CERES_NO_SUITESPARSE
+
#include "ceres/visibility.h"
#include <set>
@@ -201,3 +203,5 @@
} // namespace internal
} // namespace ceres
+
+#endif // CERES_NO_SUITESPARSE
diff --git a/jni/Android.mk b/jni/Android.mk
index fddb81f..345b3d6 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -65,6 +65,10 @@
#
# to the LOCAL_CFLAGS variable below, and commenting out all the
# generated/schur_eliminator_2_2_2.cc-alike files, leaving only the _d_d_d one.
+#
+# Similarly if you do not need the line search minimizer, consider adding
+#
+# -DCERES_NO_LINE_SEARCH_MINIMIZER
LOCAL_PATH := $(call my-dir)