Commit Graph

256 Commits

Author SHA1 Message Date
Sameer Agarwal d4cb94b6d6 Add adaptive stopping to inner iterations.
Change-Id: I83c909b8b87f1320aa30dcc80ac43a63765b9181
2013-05-22 20:04:57 +00:00
Sameer Agarwal 07f208fd6d Speed up corrector.cc
Remove the Eigen temporary by revealing the columnwise nature
of the computation. This also allows us to get rid of the
special case for nrow = 1.

On problem-356-226730-pre.txt with -robustify evaluation times
change from:

Before:
  Residual Evaluations                  1.015
  Jacobian Evaluations                 18.313

After:
  Residual Evaluations                  1.005
  Jacobian Evaluations                  8.382

To give a sense of the overhead reduction, compare these numbers
when loss functions are disabled.

  Residual Evaluations                  0.955
  Jacobian Evaluations                  7.772

So, this is a 17.5x speedup!

The one dimensional specialization was motivated by denoising.cc.
The evaluation times there are essentially unchanged.

Before:
  Residual Evaluations                  2.774
  Jacobian Evaluations                 20.178

After:
  Residual Evaluations                  2.588
  Jacobian Evaluations                 19.781

Change-Id: Ic0efbaed75fe4489635039f17189ae24b97802c8
2013-05-22 12:58:58 -07:00
Sameer Agarwal df0125666a Add profiling to covariance estimation.
Prevent GetCovarianceBlock from being called before
Compute or when Compute failed.

Change-Id: I5c28d27a88081e230d316c5e365d3e21d6e23376
2013-05-21 15:12:21 -07:00
Sameer Agarwal 45ac14fac7 Add destructor to Covariance.
This allows CovarianceImpl to be forward declared without
scoped_ptr freaking out.

Thanks to Nima Keivan for reporting this.

Change-Id: Icd5aa766b3aab70246055225231a4b971c6b7b90
2013-05-20 09:16:28 -07:00
Sameer Agarwal 096d5934a2 Comment cleanup from Jim Roseborough
Change-Id: Id47101fe32e1449e660ec536934ee91fdaf452c7
2013-05-20 08:49:09 -07:00
Sameer Agarwal b99550dc9a Add BlockRandomAccessCRSMatrix.
Change-Id: I4b88402e2216c6ea2728472e2f89479d368dbd4b
2013-05-19 12:47:48 -07:00
Joydeep Biswas aa20a6dc1b Updated depend.cmake to follow CMake IF convention.
Change-Id: I1e86cf134d3f40852033ae73f36d9143b389a918
2013-05-19 19:17:50 +00:00
Sameer Agarwal 02706c1906 Sparse covariance estimation.
Add a Covariance object to the API.

Given a Problem object and a set of parameter block pairs the
Covariance object computes a sparse covariance matrix corresponding
to those block pairs and provides random access to them.

Constant parameter blocks and parameter blocks with local parameterizations
are correctly handled.

Sparse and dense implementations are provided. With the dense implementation
rank deficient Jacobians can also be handled.

Parts of the code are threaded using OpenMP if available.

Change-Id: I5b49583b3d79579df3e0f334c22567acb23ed4ad
2013-05-18 23:33:02 -07:00
Keir Mierle f956615ef1 Proof of concept C API for Ceres
This introduces a simple C API for a subset of Ceres. This opens the door to
using languages like Python to call Ceres, since it is much easier to bind to C
than it is to bind to C++. It will mean giving up the native Ceres autodiff.

The implementation in this patch does not attempt to do everything but is only
just enough to get started. Subsequent patches will increase the surface area
of Ceres that is covered by the C API.

Change-Id: Ic51804bac6865e1a2e476553248aabc91dff3409
2013-05-19 06:29:18 +00:00
Sameer Agarwal 36c73c26bb Stablize the schur ordering algorithm.
The schur ordering is used to construct an elimination
ordering for Schur type solvers when the user has not
supplied an elimination ordering.

The ordering algorithm does an ordered traversal of the
sparsity graph of the Hessian. The order in which this is
done used to be determined by the degree of the parameter
blocks with ties broken arbitrarily using the memory address
of the parameter blocks.

This introduced non-determinism in the solver, causing subtle
numerical differences in the value of the solution everytime
the solve was run.

This change introduces ComputeStableSchurOrdering which utilizes
a new function StableIndependentSetOrdering. The latter takes
as input an ordering of the vertices of the graph which is used
to break ties when ordering the vertice by degree. The former
constructs such an ordering by using the order in which the
parameter blocks were added to the Problem.

In this way, as long as the construction of the problem is
deterministic, the schur ordering will always be deterministic
too.

I have chosen not to delete the existing unstable implementations
of these functions as they are used by the inner iteration
minimizer.

Sometime in the near future I will clean up some of the duplicate
code and see if we can move all the code to using a stable ordering.

Change-Id: I8fbfa240d7307a2c3fe9b135f6968aa410d78780
2013-05-17 22:52:21 -07:00
Sameer Agarwal 44c79b89c9 Update license header in split.h
Change-Id: I9d5ed58db59a77d2b28ccb36887a0f0e88fcaf48
2013-05-14 08:42:55 -07:00
Sameer Agarwal a1eaa262ea Update glog path
Change-Id: I47a69cb267c71a9f8f3350c4f645e8cf83e44cc9
2013-05-09 10:09:38 -07:00
Taylor Braun-Jones 5ed716754a Fix compile bug on RHEL6 due to missing header
Fixes compilation error: ‘lower_bound’ was not declared in this scope

Change-Id: I00a32edbb3f7f52c1d09ca4c1ef5ec48692b7748
2013-05-06 16:30:09 -04:00
Sameer Agarwal ac62696293 Lint cleanup
Version history update.

Update spec file for release.

Change-Id: Ic51dc33f0c6cc2584e812b3b71d85fe90d048c11
2013-05-06 07:25:15 -07:00
Sameer Agarwal 0e0a45472a Fix a typo in suitesparse.cc
Thanks Hyon Lim.

Change-Id: I73be87e805057427d5ad245beb30e1e177bae304
2013-04-29 17:27:26 -07:00
Sameer Agarwal d5b93bf9ec More pre-ordering support.
1. CX_SPARSE supports pre-ordering of the jacobian.
2. Add support for constrained approximate minimum degree ordering
   for SuiteSparse versions >= 4.2.0
3. Using 2, support for pre-ordering for SPARSE_SCHUR when used
   with SUITE_SPARSE.
4. Using 2, support for user orderings in SPARSE_NORMAL_CHOLESKY.
5. Minor cleanups in documentation and code all around.
6. Test update and refactoring.

Change-Id: Ibfe3ac95d59d54ab14d1d60a07f767688070f29f
2013-04-29 11:18:13 -07:00
Sameer Agarwal 344c09f5bc Block ordering for SPARSE_SCHUR + CX_SPARSE.
Uptil now only SuiteSparse when used with SPARSE_SCHUR would use
the block structure of the reduced camera matrix to find a fill-reducing
ordering.

This leads to substantial speedup for some bundle adjustment
problems.

Credit for this technique goes to the authors of g2o. I learned
about it from reading their source code.

Change-Id: I5403efefd4d9552c9c6fc6e02a65498bdf171584
2013-04-26 19:47:45 -07:00
Sameer Agarwal c3c3dd872b Use the evaluator to compute the gradient in TrustRegionMinimizer.
Evaluator now uses custom BLAS for gradient
computations.

Update the evaluator in trust_region_minimizer_test to compute
gradients.

Change-Id: I3f565bc203b47b2b795a0609d67f25775648653c
2013-04-26 07:38:13 -07:00
Sameer Agarwal c1e10d9f57 Death to BlockSparseMatrixBase
Change-Id: I13b2b951297ae81bfab0a7b4991a791ed91d594c
2013-04-24 19:15:39 +00:00
Sameer Agarwal cbdeb79e91 Lint cleanup from William Rucklidge
Change-Id: Id8b99a2f557efe3744e95a3947f26cdc0c9c269e
2013-04-22 10:18:18 -07:00
Sameer Agarwal 2b74970250 Fix a bounds error in the pre-ordering code.
Change-Id: I33c968bb075b60ad50374593302e08f42aeacf25
2013-04-20 02:54:45 +00:00
Sameer Agarwal 9189f4ea4b Enable pre-ordering for SPARSE_NORMAL_CHOLESKY.
Sparse Cholesky factorization algorithms use a fill-reducing
ordering to permute the columns of the Jacobian matrix. There
are two ways of doing this.

1. Compute the Jacobian matrix in some order and then have the
   factorization algorithm permute the columns of the Jacobian.

2. Compute the Jacobian with its columns already permuted.

The first option incurs a significant memory penalty. The
factorization algorithm has to make a copy of the permuted
Jacobian matrix.

Starting with this change Ceres pre-permutes the columns of the
Jacobian matrix and generally speaking, there is no performance
penalty for doing so.

In some rare cases, it is worth using a more complicated
reordering algorithm which has slightly better runtime
performance at the expense of an extra copy of the Jacobian
matrix. Setting Solver::Options::use_postordering to true
enables this tradeoff.

This change also removes Solver::Options::use_block_amd
as an option. All matrices are ordered using their block
structure. The ability to order them by their scalar
sparsity structure has been removed.

Here is what performance on looks like on some BAL problems.

Memory
======
                                     HEAD         pre-ordering
16-22106                      137957376.0          113516544.0
49-7776                        56688640.0           46628864.0
245-198739                   1718005760.0         1383550976.0
257-65132                     387715072.0          319512576.0
356-226730                   2014826496.0         1626087424.0
744-543562                   4903358464.0         3957878784.0
1024-110968                   968626176.0          822071296.0

Time
====
                                     HEAD         pre-ordering
16-22106                              3.8                  3.7
49-7776                               1.9                  1.8
245-198739                           82.6                 81.9
257-65132                            14.0                 13.4
356-226730                           98.8                 95.8
744-543562                          325.2                301.6
1024-110968                          42.1                 37.1

Change-Id: I6b2e25f3fed7310f88905386a7898ac94d37467e
2013-04-19 19:27:23 -07:00
Sameer Agarwal f7ed22efc3 Add the ability to order the Program using AMD.
This will allow CHOLMOD to compute the sparse
Cholesky factorization of J'J without making
a permuted copy of it.

Change-Id: I25d0e18f5957ab7fdce15c543234bb2f09db482e
2013-04-19 15:21:32 -07:00
Sameer Agarwal c8f07905d7 Refactor SolverImpl::CreateReducedProgram.
Break up CreateReducedProgram into smaller functions in
preparation for more sophisticated ordering strategies.

Change-Id: Ic3897522574fde770646d747fe383f5dbd7a6619
2013-04-19 13:43:56 -07:00
Sameer Agarwal 2560b17b7c SuiteSparse cleanup.
1. CreateSparseMatrixTransposeView now returns a struct instead
of a pointer.

2. Add AnalyzeCholeskyWithNaturalOrdering.

Change-Id: If27a5502949c3994edd95be0d25ec7a0d1fa1ae1
2013-04-19 19:45:31 +00:00
Sameer Agarwal 3d9546963d Add the ability to query the Problem about parameter blocks.
Change-Id: Ieda1aefa28e7a1d18fe6c8d1665882e4d9c274f2
2013-04-18 22:43:56 +00:00
Sameer Agarwal 69ebad42eb Change Minimizer::Options::min_trust_region_radius to double.
This was accidentally an int, which was setting the minimum
trust region radius to zero and effectively disabling a convergence
test based on it.

(Thanks to Sergey Sharybin for providing a reproduction for this)

Change-Id: Id0b9e246bcfee074954a5dc6a3a2342adab56c16
2013-04-17 15:38:00 -07:00
Sameer Agarwal e6707b2411 Lint fixes from William Rucklidge.
Change-Id: I57a6383bb875b24083cd9b7049333292d26f718c
2013-04-16 15:44:23 -07:00
Sameer Agarwal c7e69beb52 Add a missing mutex lock in the SchurEliminator. This
was lost somewhere along in the BLAS based refactoring.

Change-Id: I90b94fa9c3a8ea1b900a18f76ef6a7d0dbf24318
2013-04-16 09:41:26 -07:00
Sameer Agarwal 487250eb27 Minor cleanups.
1. Further BLAS and heap allocation cleanups in  schur_eliminator_impl.h
2. Modularize blas.h using macros.
3. Lint cleanups from William Rucklidge.
4. Small changes to jet.h
5. ResidualBlock now uses blas.h

Performance improvements:

For static and dynamic sized blocks, the peformance is not changed much.

-use_quaternions -ordering user -linear_solver sparse_schur

                                        master         change
problem: 16-22106
gcc                                        3.4            3.3
clang                                      2.8            2.7

problem: 49-7776
gcc                                        1.7            1.7
clang                                      1.4            1.4

problem: 245-198739
gcc                                       80.1           79.6
clang                                     80.6           76.2

problem: 257-65132
gcc                                       12.2           12.0
clang                                     10.4           10.2

problem: 356-226730
gcc                                       99.0           96.8
clang                                     88.9           88.3

problem: 744-543562
gcc                                      361.5          356.2
clang                                    352.7          343.5

problem: 1024-110968
gcc                                       45.9           45.6
clang                                     42.6           42.1

However, performance when using local parameterizations is
significantly improved due to residual_block.cc using blas.h

-use_quaternions -use_local_parameterization -ordering user -linear_solver sparse_schur

                                        master         change
problem: 16-22106
gcc                                        3.6            3.3
clang                                      3.5            2.8

problem: 49-7776
gcc                                        1.8            1.6
clang                                      1.7            1.4

problem: 245-198739
gcc                                       79.7           76.1
clang                                     79.7           73.0

problem: 257-65132
gcc                                       12.8           11.9
clang                                     12.3            9.8

problem: 356-226730
gcc                                      101.9           93.5
clang                                    105.0           86.8

problem: 744-543562
gcc                                      367.9          350.5
clang                                    355.3          323.1

problem: 1024-110968
gcc                                       43.0           40.3
clang                                     41.0           37.5

Change-Id: I6dcf7476ddaa77cb116558d112a9cf1e832f5fc9
2013-04-14 09:33:11 -07:00
Sergey Sharybin eeedd3a592 Autodiff local parameterization class
This class is used to create local parameterization
with Jacobians computed via automatic differentiation.

To get an auto differentiated local parameterization,
class with a templated operator() (a functor) that
computes

 plus_delta = Plus(x, delta);

shall be defined.

Then given such functor, the auto differentiated local
parameterization can be constructed as

 LocalParameterization* local_parameterization =
   new AutoDiffLocalParameterization<PlusFunctor, 4, 3>;
                                                  |  |
                       Global Size ---------------+  |
                       Local Size -------------------+

See autodiff_local_parameterization.h for more information
and usage example.

Initial implementation by Keir Mierle, finished by self
and integrated into Ceres and covered with unit tests
by Sameer Agarwal.

Change-Id: I1b3e48ae89f81e0cf1f51416c5696e18223f4b21
2013-04-11 03:07:09 +06:00
Sameer Agarwal c290df85a4 Typo fix.
(Thanks to Pieree Moulon for reporting this)

Change-Id: I536724ab4b7e9c97768d5197aa86b41f37a04d38
2013-04-07 19:41:40 +00:00
Sameer Agarwal dc3a27fa60 Fix MatrixVectorMultiply and incorrect DCHECKS.
(Thanks to Serget Sharybin for reporting this)

Change-Id: I6bbc41667308fc2932871cf25ad07b431f70801f
2013-04-07 09:18:12 -07:00
Sameer Agarwal 520d35ef22 Further BLAS improvements.
1. Switch to Eigen's implementation when all dimensions are fixed.
2. Use lazyProduct for eigen matrix-vector product. This brings
   eigen's performance on iterative_schur closer to what it used
   to be before the last commit. There is however still an
   improvement to be had by using the naive implementation when
   the matrix and vector have dynamic dimensions.

BENCHMARK
                                      HEAD                                       CHANGE

problem-16-22106-pre.txt
gcc-eigen       sparse_schur         0.859    gcc-eigen       sparse_schur        0.853
clang-eigen     sparse_schur         0.848    clang-eigen     sparse_schur        0.850
gcc-blas        sparse_schur         0.956    gcc-blas        sparse_schur        0.865
clang-blas      sparse_schur         0.954    clang-blas      sparse_schur        0.858
gcc-eigen       iterative_schur      4.656    gcc-eigen       iterative_schur     3.271
clang-eigen     iterative_schur      4.664    clang-eigen     iterative_schur     3.307
gcc-blas        iterative_schur      2.598    gcc-blas        iterative_schur     2.620
clang-blas      iterative_schur      2.554    clang-blas      iterative_schur     2.567

problem-49-7776-pre.txt
gcc-eigen       sparse_schur         0.477    gcc-eigen       sparse_schur        0.472
clang-eigen     sparse_schur         0.475    clang-eigen     sparse_schur        0.479
gcc-blas        sparse_schur         0.521    gcc-blas        sparse_schur        0.469
clang-blas      sparse_schur         0.508    clang-blas      sparse_schur        0.471
gcc-eigen       iterative_schur      3.172    gcc-eigen       iterative_schur     2.088
clang-eigen     iterative_schur      3.161    clang-eigen     iterative_schur     2.079
gcc-blas        iterative_schur      1.701    gcc-blas        iterative_schur     1.720
clang-blas      iterative_schur      1.708    clang-blas      iterative_schur     1.694

problem-245-198739-pre.txt
gcc-eigen       sparse_schur        28.092    gcc-eigen       sparse_schur       28.233
clang-eigen     sparse_schur        28.148    clang-eigen     sparse_schur       28.400
gcc-blas        sparse_schur        30.919    gcc-blas        sparse_schur       28.110
clang-blas      sparse_schur        31.001    clang-blas      sparse_schur       28.407
gcc-eigen       iterative_schur     63.095    gcc-eigen       iterative_schur    43.694
clang-eigen     iterative_schur     63.412    clang-eigen     iterative_schur    43.473
gcc-blas        iterative_schur     33.353    gcc-blas        iterative_schur    33.321
clang-blas      iterative_schur     33.276    clang-blas      iterative_schur    33.278

problem-257-65132-pre.txt
gcc-eigen       sparse_schur         3.687    gcc-eigen       sparse_schur        3.629
clang-eigen     sparse_schur         3.669    clang-eigen     sparse_schur        3.652
gcc-blas        sparse_schur         3.947    gcc-blas        sparse_schur        3.673
clang-blas      sparse_schur         3.952    clang-blas      sparse_schur        3.678
gcc-eigen       iterative_schur    121.512    gcc-eigen       iterative_schur    76.833
clang-eigen     iterative_schur    123.547    clang-eigen     iterative_schur    78.763
gcc-blas        iterative_schur     68.334    gcc-blas        iterative_schur    68.612
clang-blas      iterative_schur     67.793    clang-blas      iterative_schur    68.266

Notes:

1. Naive BLAS was a bit worse than eigen on fixed sized matrices. We did not see this
   before because of the different inlining thresholds. Fixing this boosted eigen's
   performance. Also the disparity between gcc and clang has gone away.

2. SPARSE_SCHUR performance remains the same, since it is only testing static sized
   matrices.

3. ITERATIVE_SCHUR performance goes up substantially due to the lazyProduct change,
   but even there, since most of the products are dynamic sized, the naive implementation
   wins handily.

Change-Id: Idc17f35b9c68aaebb1b2e131adf3af8374a85a4c
2013-04-04 18:02:08 -07:00
Sameer Agarwal 3d6eceb45c Replace more instances of Eigen GEMV with Ceres BLAS.
With this ITERATIVE_SCHUR with JACOBI preconditioner went down from
280 seconds to 150 seconds on problem-744-543562-pre.txt.

Change-Id: I4f319c1108421e8d59f58654a4c0576ad65df609
2013-04-03 16:07:26 -07:00
Sameer Agarwal 296fa9b127 Replace Eigen block operations with small GEMM and GEMV loops.
1. Add Matrix-Matrix and Matrix-Vector multiply functions.
2. Replace Eigen usage in SchurEliminator with these custom
   matrix operations.
3. Save on some memory allocations in ChunkOuterProduct.
4. Replace LDLT with LLT.

As a result on problem-16-22106-pre.txt, the linear solver time
goes down from 1.2s to 0.64s.

Change-Id: I2daa667960e0a1e8834489965a30be31f37fd87f
2013-04-02 18:04:39 -07:00
Sameer Agarwal 222ca20e8f SuiteSparse cleanup.
1. Silence CHOLMOD's indefiniteness warnings.
2. Add a comment about how the error handling in suitesparse.cc
   needs to be improved.
3. Move the analysis logging into suitesparse.cc and out of the
   three callsites.

Change-Id: Idd396b8ea4bf59fc1ffc7f9fcbbc7b38ed71643c
2013-04-01 11:42:19 -07:00
Sameer Agarwal 564a83fcc6 Lint cleanup from William Rucklidge.
Change-Id: I8d4a0aa3e264775d20e99a6b5265f3023de92560
2013-03-26 11:41:50 -07:00
Sergey Sharybin f46de9e697 Silent no previous declaration warning for FindParameterBlockOrDie
Use anonymous namespace for this. Also move some surrounding static
function to this anonymous namespace.

Change-Id: Ie235eb7936976563a9db115ec13c59e6e6869b96
2013-03-21 23:03:58 +06:00
Sergey Sharybin 16636efeff Compilation fix for msvc2010
Usage of back_inserter requires <iterator> header when using msvc2010

Change-Id: I92ee1649795ce0468ce337fc414eb0ca6e90c51e
2013-03-21 15:12:01 +06:00
Pablo Speciale 16dbf11626 Added CeresConfig.cmake based on this example:
https://projects.kde.org/projects/kde/kdeexamples/repository/revisions/master/show/buildsystem/HowToInstallALibrary

Change-Id: I130cac5d43d9fbbf359abc04d3691e25c4e2bb63
2013-03-20 18:38:27 +00:00
Pablo Speciale 015d57f173 Avoiding the Warning: "deprecated conversion from string constant to char*"
Change-Id: Ifa47f9b0724f79c5c695828628c89818ddefd844
2013-03-19 21:22:11 +00:00
Sameer Agarwal 700d50d807 Lint cleanup from William Rucklidge
Change-Id: Iacbf77246109f687708696eee7fb6144d23e7ec5
2013-03-12 16:12:42 -07: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 c59c1e4472 Propagate ifdefs correctly to improve build efficiency.
With -DRESTRICT_SCHUR_SPECIALIZATIONS, now the various
specializations are empty, decreasing build time and
reducing the size of the static library.

Change-Id: I8ec431279741a9a83516a4167c54a364c4608143
2013-03-11 17:28:38 -07:00
Yuliy Schwartzburg 32874b861f Fix CMake "LIB_SUFFIX" for non-linux installations
Change-Id: Ieb8a2825a4378b388149e7934ecc7b96ba5a29fa
2013-03-11 20:12:00 +00:00
Sameer Agarwal 020d8e1e48 Better error reporting in the modeling API.
More informative error when user passes an
unknown parameter block to Problem methods.

Change-Id: I517360e4b0b55814904ca3e664877d76ad3f59e8
2013-03-06 16:19:26 -08:00
Sameer Agarwal e7148795c3 Fix a memory leak in CXSparse::SolveCholesky.
Thanks to Alexander Mordvintsev for reporting this.

Change-Id: I5c6be4d3d28f062e83a1ad41cb8089c19362a005
2013-03-04 13:30:09 -08:00
Sameer Agarwal a363a7b69c Multithread DENSE_SCHUR
Replace the global lock in BlockRandomAccessDenseMatrix
with a per cell lock.

Change-Id: Iddbe38616157b6e0d3770eede3335a056c3ba18c
2013-03-03 18:23:12 -08:00
Sameer Agarwal 31730ef55d DenseSparseMatrix is now column-major.
1. Introduce new typdefs in eigen.h to allow for column
   major matrices.

2. Clean up old unused typedefs, and the aligned typedefs
   since they do not actually add any real performance.

3. Made eigen.h conform to the google style guide by removing
   the using directives. They were polluting the ceres namespace.

4. Made the template specialization generator work again.

Change-Id: Ic2268c784534b737ebd6e1a043e2a327adaeca37
2013-03-03 17:08:32 -08:00