Commit Graph

25 Commits

Author SHA1 Message Date
Sameer Agarwal 2ffddaccfe Use override & final instead of just using virtual.
This is safer than using virtual and this lead to a minor
bug fixes.

Change-Id: Id69cb1cc569bf6bf245f22f029c7871b6c712568
2019-07-25 16:29:14 -07:00
Sameer Agarwal 31f24521cc Deprecate macros.h and fpclassify.h
1. Replace CERES_DISALLOW_* with explicitly deleted constructors.
2. Replace use of CERES_ARRAY_SIZE and stack allocated arrays
   with std::vector.
3. Move CERES_ALIGN_* macros into manual_constructor.h, which is
   the one place they are used and will be deprecated along with that
   file.
4. Introduce isnan,isnormal,isinf and isfinite for Jets.
5. Replace IsNormal,IsFinite,IsNaN and IsInfinite with corresponding
   c++11 function calls.

Change-Id: I04f33a221aae77d247602150988b6d4aa4efeeab
2018-04-18 09:54:42 -07:00
Sameer Agarwal f973e107d2 Enable mixed precision solves.
1. Add Solver::Options::use_mixed_precision_solves,
   and Solver::Options::max_num_refinement_iterations.
2. Make SparseCholesky::Create return a unique_ptr.
3. SparseCholesky::Create now takes LinearSolver::Options
   as an argument.
4. IterativeRefiner's constructor does not require num_cols
   as an argument.
5. SparseNormalCholeskySolver now uses a separate rhs vector.

This basic implementation results in a 10% reduction in solver time
and 30% reduction in linear solver memory usage.

Change-Id: I6830f32cae2febf082d2733262eb2c9f0482b0ea
2018-04-10 11:01:38 -07:00
Keir Mierle 7c4e8a454e Replace scoped_ptr with C++11's unique_ptr
Change-Id: Ib5a504c491e3a79af52a95accf009df473470c6b
2018-04-02 14:47:47 -07:00
Sameer Agarwal 08e60379ba Integrate InnerProductComputer
Despite its relative size, this is very significant change
to Ceres.

Why
===

Up till now, when the user chose SPARSE_NORMAL_CHOLESKY,
the Jacobian was evaluated in a CompressedRowSparseMatrix,
which was then use to compute the normal equations which were
passed to a sparse linear algebra library for factorization.

The reason to do this was because in the case of SuiteSparse,
we were able to pass the Jacobian matrix directly without
computing the normal equations and SuiteSparse/CHOLMOD did the
normal equation computation.

This turned out to be slow, so Cheng Wang implemented a high
performance version of the matrix-matrix multiply to compute
the normal equations, and all the sparse linear algebra libraries
now are passed the normal equations.

So that raises the question, as to what the best representation
of the Jacobian which is suitable for the normal equation computation.

Turns out BlockSparseMatrix is ideal. It brings two advantages.

1. Jacobian evaluation into a BlockSparseMatrix is considerably
   faster when using a BlockSparseMatrix than
   CompressedRowSparseMatrix. This is because we save on a bunch
   of memory copies.

2. To make the matrix multiplication fast and use the block structure
   Cheng Wang had to essentially make the CompressedRowSparseMatrix
   carry a bunch of sidecar information about the block sparsity,
   essentially making it behave like a BlockSparseMatrix. The resulting
   code had fairly complicated indexing and complicated the semantics
   of CompressedRowSparseMatrix. The new InnerProductComputer class
   does away with all that and once this CL goes in, I will be able to
   remove all that code and simplify the semantics of
   CompressedRowSparseMatrix.

Changes
=======

1. Use InnerProductComputer in SparseNormalCholeskySolver.
2. Change the evaluator instantiated for SPARSE_NORMAL_CHOLESKY with
   static sparsity inside evaluator.cc
3. The former change necessitates that we change ProblemImpl::Evaluate
   to create the evaluate it needs on its own, because it was
   depending on passing "SPARSE_NORMAL_CHOLESKY" as linear solver type
   to the evaluator factor to get an Evaluator which can use
   CompressedRowSparseMatrix objects for storing the Jacobian.
4. Update the tests for SparseNormalCholeskySolver.
5. Separate out the tests for DynamicSparseNormalCholeskySolver into its
   own file.

Change-Id: I2ef7ef8fbfbb4967d0c1ec2068c1c778248fdf5b
2017-06-21 23:41:36 -07:00
Sameer Agarwal 29c21f5680 Add SparseCholesky
SparseCholesky is an interface to sparse cholesky factorization
routines across sparse linear algebra libraries. Each sparse
linear algebra library is responsible for implementing its own
instance of this interface.

As a result the various places - SparseNormalCholeskySolver,
SparseSchurComplementSolver and VisibilityBasedPreconditioner
are significantly simplified.

Change-Id: I8b465705eae83bba9e1adfffcc741a05c70faf2e
2017-05-24 00:00:25 -07:00
Sameer Agarwal 1d7185f130 Refactor SparseNormalCholeskySolver
Now that there is a single piece of code doing the outer product
computation for all three sparse linear algebra backends, move
this code one level up the call stack and there by make the actual
per-library solver code shorter and simpler.

Also fix a minor omission in the outer product computation code
where row/column blocks were not being copied over to the
outer product matrix.

Change-Id: I22a7967bdc659385b741901afefa7af312e676e5
2017-04-27 01:45:05 -07:00
Sameer Agarwal 5742b7d0f1 Improve performance of SPARSE_NORMAL_CHOLESKY + dynamic_sparsity
The outer product computation logic in SparseNormalCholeskySolver
does not work well with dynamic sparsity. The overhead of computing
the sparsity pattern of the normal equations is only amortized if
the sparsity is constant. If the sparsity can change from call to call
SparseNormalCholeskySolver will actually be more expensive.

For Eigen and for CXSparse we now explicitly compute the normal
equations using their respective matrix-matrix product routines and solve.
Change-Id: Ifbd8ed78987cdf71640e66ed69500442526a23d4
2015-09-05 14:31:52 -07:00
Keir Mierle 7492b0d8de Update copyright headers with new year and URL
Since Ceres is moving to using GitHub for issues, and the Google
Code URL in the current copyright header will soon become invalid,
update all the headers.

Change-Id: I1fce70375d1bcf098591f07b4d8f01a5c1e0789c
2015-03-18 05:43:23 +00:00
Sameer Agarwal bcc865f81c Remove using namespace std;
For historical reasons we had a "using namespace std;" in port.h. This
is generally a bad idea. So removing it and along the way doing a bunch
of cpplint cleanup.

Change-Id: Ia125601a55ae62695e247fb0250df4c6f86c46c6
2015-01-07 14:26:53 -08:00
Sameer Agarwal 0e1cc2a554 Fix the build on Eigen version 3.2.1 and older.
Change-Id: I18f5cb5d42113737d7b8f78a67acee28bd5b3e08
2014-08-29 09:24:59 -07:00
Sameer Agarwal 7344626c04 Let EIGEN_SPARSE + SPARSE_NORMAL_CHOLESKY use block AMD.
Modify SparseNormalCholeskySolver to use a pre-ordered Jacobian
matrix.

Change-Id: Ib4d725d7a2d7bb94ea76dbb3a9b172784dbc8ea0
2014-08-28 22:47:27 -07:00
Sameer Agarwal b43e73a034 Simplify the Eigen code in SparseNormalCholeskySolver.
Simplifying some of the template handling, and remove the use
of SelfAdjointView as it is not needed. The solver itself takes
an argument for where the data is actually stored.

The performance of SparseNormalCholesky with EIGEN_SPARSE
seems to be on par with CX_SPARSE.

Change-Id: I69e22a144b447c052b6cbe59ef1aa33eae2dd9e3
2014-08-01 12:10:04 -07:00
Sameer Agarwal 031598295c Enable Eigen as sparse linear algebra library.
SPARSE_NORMAL_CHOLESKY and SPARSE_SCHUR can now be used
with EIGEN_SPARSE as the backend.

The performance is not as good as CXSparse. This needs to be
investigated. Is it because the quality of AMD ordering that
we are computing is not as good as the one for CXSparse? This
could be because we are working with the scalar matrix instead
of the block matrix.

Also, the upper/lower triangular story is not completely clear.
Both of these issues will be benchmarked and tackled in the
near future.

Also included in this change is a bunch of cleanup to the
SparseNormalCholeskySolver and SparseSchurComplementSolver
classes around the use of the of defines used to conditionally
compile out parts of the code.

The system_test has been updated to test EIGEN_SPARSE also.

Change-Id: I46a57e9c4c97782696879e0b15cfc7a93fe5496a
2014-07-31 22:05:34 -07:00
Alex Stewart ea76585068 Adding autogenerated Ceres config.h to #define Ceres compile options.
- Previously we passed all compile options to Ceres via add_definitions
  in CMake.  This was fine for private definitions (used only by Ceres)
  but required additional work for public definitions to ensure they
  were correctly propagated to clients via CMake using
  target_compile_definitions() (>= 2.8.11) or add_definitions().
- A drawback to these approaches is that they did not work for chained
  dependencies on Ceres, as in if in the users project B <- A <- Ceres,
  then although the required Ceres public compile definitions would
  be used when compiling A, they would not be propagated to B.

- This patch replaces the addition of compile definitions via
  add_definitions() with an autogenerated config.h header which
  is installed with Ceres and defines all of the enabled Ceres compile
  options.
- This removes the need for the user to propagate any compile
  definitions in their projects, and additionally allows post-install
  inspect of the options with which Ceres was compiled.

Change-Id: Idbdb6abdad0eb31e7540370e301afe87a07f2260
2014-05-09 10:57:31 +01:00
Richard Stebbing 32530788d0 Add dynamic_sparsity option.
The standard sparse normal Cholesky solver assumes a fixed
sparsity pattern which is useful for a large number of problems
presented to Ceres. However, some problems are symbolically dense
but numerically sparse i.e. each residual is a function of a
large number of parameters but at any given state the residual
only depends on a sparse subset of them. For these class of
problems it is faster to re-analyse the sparsity pattern of the
jacobian at each iteration of the non-linear optimisation instead
of including all of the zero entries in the step computation.

The proposed solution adds the dynamic_sparsity option which can
be used with SPARSE_NORMAL_CHOLESKY. A
DynamicCompressedRowSparseMatrix type (which extends
CompressedRowSparseMatrix) has been introduced which allows
dynamic addition and removal of elements. A Finalize method is
provided which then consolidates the matrix so that it can be
used in place of a regular CompressedRowSparseMatrix. An
associated jacobian writer has also been provided.

Changes that were required to make this extension were adding the
SetMaxNumNonZeros method to CompressedRowSparseMatrix and adding
a JacobianFinalizer template parameter to the ProgramEvaluator.

Change-Id: Ia5a8a9523fdae8d5b027bc35e70b4611ec2a8d01
2014-04-28 07:13:09 +00:00
Sameer Agarwal f14f6bf9b7 Speed up SPARSE_NORMAL_CHOLESKY when using CX_SPARSE.
When using sparse cholesky factorization to solve the linear
least squares problem:

  Ax = b

There are two sources of computational complexity.

1. Computing H = A'A
2. Computing the sparse Cholesky factorization of H.

Doing 1. using CX_SPARSE is particularly expensive, as it uses
a generic cs_multiply function which computes the structure of
the matrix H everytime, reallocates memory and does not take
advantage of the fact that the matrix being computed is a symmetric
outer product.

This change adds a custom symmetric outer product algorithm for
CompressedRowSparseMatrix.

It has a symbolic phase, where it computes the sparsity structure
of the output matrix and a "program" which allows the actual
multiplication routine to determine exactly which entry in the
values array each term in the product contributes to.

With these two bits of information, the outer product H = A'A
can be computed extremely fast without any reasoning about
the structure of H.

Further gains in efficiency are made by exploiting the block
structure of A.

With this change, SPARSE_NORMAL_CHOLESKY with CX_SPARSE as the
backend results in > 300% speedup for some problems.

The symbolic analysis phase of the solver is a bit more expensive
now but the increased cost is made up in 3-4 iterations.

Change-Id: I5e4a72b4d03ba41b378a2634330bc22b299c0f12
2013-12-30 10:00:06 -08:00
Sergey Sharybin f258e4624f Move most of suitesparse/cxsparse ifdef code to their headers
Main purpose of this is to make implementation files free from
endless ifdef blocks every time this libraries are needed to be
included. This would hopefully prevent compilation errors in
the future caused by missing ifdef around header include.

This also includes some stubs added to suitesparse/cxsparse
headers to make code even more free from ifdefs.

Change-Id: Ic8554e7df31d8c4751583fe004b99e71b3c9087b
2013-08-15 17:54:55 +00:00
Sameer Agarwal 8140f0fc97 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
2013-03-12 11:11:57 -07:00
Sameer Agarwal 42a84b87fa Expand reporting of timing information.
1. Add an ExecutionSummary object to record execution
   information about Ceres objects.
2. Add an EventLogger object to log events in a function call.
3. Add a ScopedExecutionTimer object to log times in ExecutionSummary.
4. Instrument ProgramEvaluator and all the linear solvers
   to report their timing statistics.
5. Connect the timing statistics to Summary::FullReport.
6. Add high precision timer on unix systems using
   gettimeofday() call.
7. Various minor clean ups all around.

Change-Id: I5e09804b730b09535484124be7dbc1c58eccd1d4
2013-02-06 01:00:38 -08:00
Petter Strandmark 1e3cbd9a44 Caching the symbolic Cholesky factorization when using CXSparse
Average factorization times for bundle adjustment test problem:
SuiteSparse: 0.2794 s.
CXSparse: 0.4039 s.
CXSparse cached: 0.2399 s.

CXSparse will still be slower, though, because it has to compute
the transpose and J^T * J.

Change-Id: If9cdaa3dd520bee84b56e5fd4953b56a93db6bde
2012-08-30 09:45:20 -07:00
Sameer Agarwal 7a3c43b847 Block oriented fill reducing orderings.
By virtue of the modeling layer in Ceres being block oriented,
all the matrices used by Ceres are also block oriented.
When doing sparse direct factorization of these matrices, the
fill-reducing ordering algorithms can either be run on the
block or the scalar form of these matrices. Running it on the
block form exposes more of the super-nodal structure of the
matrix to the Cholesky factorization routines. This leads to
substantial gains in factorization performance.

This changelist adds support for approximate minimium degree
orderings to be computed on the block structure of the
Schur complement matrix. This affects, SchurComplementSolver
and VisibilityBasedPreconditioner and SparseNormalCholesky
 when using SuiteSparse.

A bool, use_block_amd has been added to Solver::Options and
bundle_adjuster.cc has been updated to allow testing with it.

When combined with a multithreaded Schur elimination, speed ups
can be seen quite uniformly across the board. For some problems
this can be dramatic, reducing the factorization time from 70
seconds down to 17 seconds.

Change-Id: I15ebb0afcbc85ada032ec8d179ee3a2f7c8d3e46
2012-06-06 22:02:17 -07:00
Sameer Agarwal 237d659b8d Added CERES_ prefix to the DISALLOW macros.
Change-Id: Ib81e9112e8bbc6ed6cb52f21825df0f6e659be51
2012-05-30 21:50:32 -07:00
Sameer Agarwal b051873a55 Multiple sparse linear algebra backends.
1. Added support for CXSparse - SparseNormalCholesky and
   SchurComplementSolver support SuiteSparse and CXSparse now.
   I am not sure I will add suport for visibility based
   preconditioning using CXSparse. Its not a high priority.

2. New enum SparseLinearAlgebraLibraryType which allows the user
   to indicate which sparse linear algebra library should be used.

3. Updated tests for SolverImpl and system_test.

4. Build system changes to automatically detect CXSparse and
   link to it by default -- just like SuiteSparse.

5. Minor bug fixes dealing in the cmake files and VBP.

6. Changed the order of the system test.

7. Deduped the unsymmetric linear solver test.

Change-Id: I33252a103c87b722ecb7ed7b5f0ae7fd91249244
2012-05-29 19:44:43 -07:00
Keir Mierle 8ebb073038 Initial commit of Ceres Solver. 2012-04-30 23:09:08 -07:00