Add Apple's Accelerate framework as a sparse linear algebra library. - Currently DynamicSparseNormalCholeskySolver is unsupported for Accelerate. Change-Id: I03b5a86bb22fef249c4aecd48947a613e8eff7a5
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fa11ca..a1fe27f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -135,6 +135,10 @@ option(GFLAGS "Enable Google Flags." ON) option(SUITESPARSE "Enable SuiteSparse." ON) option(CXSPARSE "Enable CXSparse." ON) +if (APPLE) + option(ACCELERATESPARSE + "Enable use of sparse solvers in Apple's Accelerate framework." ON) +endif() option(LAPACK "Enable use of LAPACK directly within Ceres." ON) # Template specializations for the Schur complement based solvers. If # compile time, binary size or compiler performance is an issue, you @@ -334,15 +338,33 @@ CXSPARSE_LIBRARY) endif (CXSPARSE) +if (ACCELERATESPARSE) + find_package(AccelerateSparse) + if (AccelerateSparse_FOUND) + message("-- Found Apple's Accelerate framework with sparse solvers, " + "building with Accelerate sparse support.") + else() + message("-- Failed to find Apple's Accelerate framework with sparse solvers, " + "building without Accelerate sparse support.") + update_cache_variable(ACCELERATESPARSE OFF) + list(APPEND CERES_COMPILE_OPTIONS CERES_NO_ACCELERATE_SPARSE) + endif() +else() + message("-- Building without Apple's Accelerate sparse support.") + list(APPEND CERES_COMPILE_OPTIONS CERES_NO_ACCELERATE_SPARSE) + mark_as_advanced(FORCE AccelerateSparse_INCLUDE_DIR + AccelerateSparse_LIBRARY) +endif() + # Ensure that the user understands they have disabled all sparse libraries. -if (NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE) +if (NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE AND NOT ACCELERATESPARSE) message(" ===============================================================") message(" Compiling without any sparse library: SuiteSparse, CXSparse ") - message(" & Eigen (Sparse) are all disabled or unavailable. No sparse ") - message(" linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)") + message(" EigenSparse & Apple's Accelerate are all disabled or unavailable. ") + message(" No sparse linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)") message(" will be available when Ceres is used.") message(" ===============================================================") -endif(NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE) +endif() # ANDROID define is set by the Android CMake toolchain file. if (ANDROID) @@ -475,6 +497,10 @@ include_directories(${CXSPARSE_INCLUDE_DIRS}) endif (CXSPARSE) +if (ACCELERATESPARSE) + include_directories(${AccelerateSparse_INCLUDE_DIRS}) +endif() + if (GFLAGS) include_directories(${GFLAGS_INCLUDE_DIRS}) endif (GFLAGS)
diff --git a/bazel/ceres.bzl b/bazel/ceres.bzl index ea6392a..28eef28 100644 --- a/bazel/ceres.bzl +++ b/bazel/ceres.bzl
@@ -29,6 +29,7 @@ # Support for building Ceres Solver with a specific configuration. CERES_SRCS = ["internal/ceres/" + filename for filename in [ + "accelerate_sparse.cc", "array_utils.cc", "blas.cc", "block_evaluate_preparer.cc", @@ -190,9 +191,11 @@ # TODO(keir): These defines are placeholders for now to facilitate getting # started with a Bazel build. However, these should become configurable as # part of a Skylark Ceres target macro. + # https://github.com/ceres-solver/ceres-solver/issues/396 defines = [ "CERES_NO_SUITESPARSE", "CERES_NO_CXSPARSE", + "CERES_NO_ACCELERATE_SPARSE", "CERES_NO_LAPACK", "CERES_USE_EIGEN_SPARSE", "CERES_USE_CXX11_THREADS",
diff --git a/cmake/CeresCompileOptionsToComponents.cmake b/cmake/CeresCompileOptionsToComponents.cmake index 872d9dc..971b833 100644 --- a/cmake/CeresCompileOptionsToComponents.cmake +++ b/cmake/CeresCompileOptionsToComponents.cmake
@@ -79,6 +79,8 @@ add_to_output_if_not_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR} CERES_NO_CXSPARSE "CXSparse;SparseLinearAlgebraLibrary") add_to_output_if_not_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR} + CERES_NO_ACCELERATE_SPARSE "AccelerateSparse;SparseLinearAlgebraLibrary") + add_to_output_if_not_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR} CERES_RESTRICT_SCHUR_SPECIALIZATION "SchurSpecializations") add_to_output_if_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR} CERES_USE_OPENMP "OpenMP;Multithreading")
diff --git a/cmake/FindAccelerateSparse.cmake b/cmake/FindAccelerateSparse.cmake new file mode 100644 index 0000000..f2f4340 --- /dev/null +++ b/cmake/FindAccelerateSparse.cmake
@@ -0,0 +1,145 @@ +# Ceres Solver - A fast non-linear least squares minimizer +# Copyright 2018 Google Inc. All rights reserved. +# http://ceres-solver.org/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Google Inc. nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Author: alexs.mac@gmail.com (Alex Stewart) +# + +# FindAccelerateSparse.cmake - Find the sparse solvers in Apple's Accelerate +# framework, introduced in Xcode 9.0 (2017). +# Note that this is distinct from the Accelerate +# framework on its own, which existed in previous +# versions but without the sparse solvers. +# +# This module defines the following variables which should be referenced +# by the caller to use the library. +# +# AccelerateSparse_FOUND: TRUE iff an Accelerate framework including the sparse +# solvers, and all dependencies, has been found. +# AccelerateSparse_INCLUDE_DIRS: Include directories for Accelerate framework. +# AccelerateSparse_LIBRARIES: Libraries for Accelerate framework and all +# dependencies. +# +# The following variables are also defined by this module, but in line with +# CMake recommended FindPackage() module style should NOT be referenced directly +# by callers (use the plural variables detailed above instead). These variables +# do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which +# are NOT re-called (i.e. search for library is not repeated) if these variables +# are set with valid values _in the CMake cache_. This means that if these +# variables are set directly in the cache, either by the user in the CMake GUI, +# or by the user passing -DVAR=VALUE directives to CMake when called (which +# explicitly defines a cache variable), then they will be used verbatim, +# bypassing the HINTS variables and other hard-coded search locations. +# +# AccelerateSparse_INCLUDE_DIR: Include directory for Accelerate framework, not +# including the include directory of any +# dependencies. +# AccelerateSparse_LIBRARY: Accelerate framework, not including the libraries of +# any dependencies. + +# Called if we failed to find the Accelerate framework with the sparse solvers. +# Unsets all public (designed to be used externally) variables and reports +# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument. +macro(accelerate_sparse_report_not_found REASON_MSG) + unset(AccelerateSparse_FOUND) + unset(AccelerateSparse_INCLUDE_DIRS) + unset(AccelerateSparse_LIBRARIES) + # Make results of search visible in the CMake GUI if Accelerate has not + # been found so that user does not have to toggle to advanced view. + mark_as_advanced(CLEAR AccelerateSparse_INCLUDE_DIR + AccelerateSparse_LIBRARY) + + # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage() + # use the camelcase library name, not uppercase. + if (AccelerateSparse_FIND_QUIETLY) + message(STATUS "Failed to find Accelerate framework with sparse solvers - " + ${REASON_MSG} ${ARGN}) + elseif (AccelerateSparse_FIND_REQUIRED) + message(FATAL_ERROR "Failed to find Accelerate framework with sparse solvers - " + ${REASON_MSG} ${ARGN}) + else() + # Neither QUIETLY nor REQUIRED, use no priority which emits a message + # but continues configuration and allows generation. + message("-- Failed to find Accelerate framework with sparse solvers - " + ${REASON_MSG} ${ARGN}) + endif() + return() +endmacro() + +unset(AccelerateSparse_FOUND) + +find_path(AccelerateSparse_INCLUDE_DIR NAMES Accelerate.h) +if (NOT AccelerateSparse_INCLUDE_DIR OR + NOT EXISTS ${AccelerateSparse_INCLUDE_DIR}) + accelerate_sparse_report_not_found( + "Could not find Accelerate framework headers. Set " + "AccelerateSparse_INCLUDE_DIR to the directory containing Accelerate.h") +endif() + +find_library(AccelerateSparse_LIBRARY NAMES Accelerate) +if (NOT AccelerateSparse_LIBRARY OR + NOT EXISTS ${AccelerateSparse_LIBRARY}) + accelerate_sparse_report_not_found( + "Could not find Accelerate framework. Set AccelerateSparse_LIBRARY " + "to the Accelerate.framework directory") +endif() + +set(AccelerateSparse_FOUND TRUE) + +# Determine if the Accelerate framework detected includes the sparse solvers. +include(CheckCXXSourceCompiles) +set(CMAKE_REQUIRED_INCLUDES ${AccelerateSparse_INCLUDE_DIR}) +set(CMAKE_REQUIRED_LIBRARIES ${AccelerateSparse_LIBRARY}) +check_cxx_source_compiles( + "#include <Accelerate.h> + int main() { + SparseMatrix_Double A; + SparseFactor(SparseFactorizationCholesky, A); + return 0; + }" + ACCELERATE_FRAMEWORK_HAS_SPARSE_SOLVER) +unset(CMAKE_REQUIRED_INCLUDES) +unset(CMAKE_REQUIRED_LIBRARIES) +if (NOT ACCELERATE_FRAMEWORK_HAS_SPARSE_SOLVER) + accelerate_sparse_report_not_found( + "Detected Accelerate framework: ${AccelerateSparse_LIBRARY} does not " + "include the sparse solvers.") +endif() + +if (AccelerateSparse_FOUND) + set(AccelerateSparse_INCLUDE_DIRS ${AccelerateSparse_INCLUDE_DIR}) + set(AccelerateSparse_LIBRARIES ${AccelerateSparse_LIBRARY}) +endif() + +# Handle REQUIRED / QUIET optional arguments and version. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(AccelerateSparse + REQUIRED_VARS AccelerateSparse_INCLUDE_DIRS AccelerateSparse_LIBRARIES) +if (AccelerateSparse_FOUND) + mark_as_advanced(FORCE AccelerateSparse_INCLUDE_DIR + AccelerateSparse_LIBRARY) +endif()
diff --git a/cmake/config.h.in b/cmake/config.h.in index 32c4a52..f766c5c 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in
@@ -53,6 +53,17 @@ // If defined, Ceres was compiled without CXSparse. @CERES_NO_CXSPARSE@ +// If defined, Ceres was compiled without Apple's Accelerate framework solvers. +@CERES_NO_ACCELERATE_SPARSE@ + +#if defined(CERES_NO_SUITESPARSE) && \ + defined(CERES_NO_ACCELERATE_SPARSE) && \ + defined(CERES_NO_CXSPARSE) && \ + !defined(CERES_USE_EIGEN_SPARSE) // NOLINT +// If defined Ceres was compiled without any sparse linear algebra support. +#define CERES_NO_SPARSE +#endif + // If defined, Ceres was compiled without Schur specializations. @CERES_RESTRICT_SCHUR_SPECIALIZATION@
diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 55bda82..00158cf 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst
@@ -89,6 +89,10 @@ no dependencies on ``LAPACK`` and ``BLAS``. This makes for a simpler build process and a smaller binary. **Optional** +- `Apple's Accelerate sparse solvers <https://developer.apple.com/documentation/accelerate/sparse_solvers>`_. + As of Xcode 9.0, Apple's Accelerate framework includes support for + solving sparse linear systems across macOS, iOS et al. **Optional** + - `BLAS <http://www.netlib.org/blas/>`_ and `LAPACK <http://www.netlib.org/lapack/>`_ routines are needed by ``SuiteSparse``, and optionally used by Ceres directly for some @@ -691,7 +695,13 @@ CXSparse is licensed under the LGPL. -#. ``EIGENSPARSE [Default: OFF]``: By default, Ceres will not use +#. ``ACCELERATESPARSE [Default: ON]``: By default, Ceres will link to + Apple's Accelerate framework directly if a version of it is detected + which supports solving sparse linear systems. Note that on Apple OSs + Accelerate usually also provides the BLAS/LAPACK implementations and + so would be linked against irrespective of the value of ``ACCELERATESPARSE``. + +#. ``EIGENSPARSE [Default: ON]``: By default, Ceres will not use Eigen's sparse Cholesky factorization. .. NOTE:: @@ -896,12 +906,14 @@ #. ``CXSparse``: Ceres built with CXSparse (``CXSPARSE=ON``). +#. ``AccelerateSparse``: Ceres built with Apple's Accelerate sparse solvers (``ACCELERATESPARSE=ON``). + #. ``EigenSparse``: Ceres built with Eigen's sparse Cholesky factorization (``EIGENSPARSE=ON``). #. ``SparseLinearAlgebraLibrary``: Ceres built with *at least one* sparse linear algebra library. This is equivalent to ``SuiteSparse`` **OR** ``CXSparse`` - **OR** ``EigenSparse``. + **OR** ``AccelerateSparse`` **OR** ``EigenSparse``. #. ``SchurSpecializations``: Ceres built with Schur specializations (``SCHUR_SPECIALIZATIONS=ON``).
diff --git a/include/ceres/internal/port.h b/include/ceres/internal/port.h index d69d8c5..f579028 100644 --- a/include/ceres/internal/port.h +++ b/include/ceres/internal/port.h
@@ -54,6 +54,24 @@ # error One of CERES_USE_OPENMP, CERES_USE_TBB,CERES_USE_CXX11_THREADS or CERES_NO_THREADS must be defined. #endif +// CERES_NO_SPARSE should be automatically defined by config.h if Ceres was +// compiled without any sparse back-end. Verify that it has not subsequently +// been inconsistently redefined. +#if defined(CERES_NO_SPARSE) +# if !defined(CERES_NO_SUITESPARSE) +# error CERES_NO_SPARSE requires CERES_NO_SUITESPARSE. +# endif +# if !defined(CERES_NO_CXSPARSE) +# error CERES_NO_SPARSE requires CERES_NO_CXSPARSE +# endif +# if !defined(CERES_NO_ACCELERATE_SPARSE) +# error CERES_NO_SPARSE requires CERES_NO_ACCELERATE_SPARSE +# endif +# if defined(CERES_USE_EIGEN_SPARSE) +# error CERES_NO_SPARSE requires !CERES_USE_EIGEN_SPARSE +# endif +#endif + // A macro to signal which functions and classes are exported when // building a DLL with MSVC. //
diff --git a/include/ceres/solver.h b/include/ceres/solver.h index 20f41cb..bd6172f 100644 --- a/include/ceres/solver.h +++ b/include/ceres/solver.h
@@ -318,8 +318,7 @@ // Linear least squares solver options ------------------------------------- LinearSolverType linear_solver_type = -#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE) && \ - !defined(CERES_USE_EIGEN_SPARSE) // NOLINT +#if defined(CERES_NO_SPARSE) DENSE_QR; #else SPARSE_NORMAL_CHOLESKY; @@ -353,16 +352,14 @@ SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type = #if !defined(CERES_NO_SUITESPARSE) SUITE_SPARSE; -#else - #if !defined(CERES_NO_CXSPARSE) +#elif !defined(CERES_NO_ACCELERATE_SPARSE) + ACCELERATE_SPARSE; +#elif !defined(CERES_NO_CXSPARSE) CX_SPARSE; - #else - #if defined(CERES_USE_EIGEN_SPARSE) +#elif defined(CERES_USE_EIGEN_SPARSE) EIGEN_SPARSE; - #else +#else NO_SPARSE; - #endif - #endif #endif // The order in which variables are eliminated in a linear solver @@ -919,8 +916,7 @@ // Type of the linear solver requested by the user. LinearSolverType linear_solver_type_given = -#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE) && \ - !defined(CERES_USE_EIGEN_SPARSE) // NOLINT +#if defined(CERES_NO_SPARSE) DENSE_QR; #else SPARSE_NORMAL_CHOLESKY; @@ -932,8 +928,7 @@ // available, e.g. The user requested SPARSE_NORMAL_CHOLESKY but // no sparse linear algebra library was available. LinearSolverType linear_solver_type_used = -#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE) && \ - !defined(CERES_USE_EIGEN_SPARSE) // NOLINT +#if defined(CERES_NO_SPARSE) DENSE_QR; #else SPARSE_NORMAL_CHOLESKY;
diff --git a/include/ceres/types.h b/include/ceres/types.h index a4a4861..f6dd6a1 100644 --- a/include/ceres/types.h +++ b/include/ceres/types.h
@@ -159,6 +159,9 @@ // the Simplicial LDLT routines. EIGEN_SPARSE, + // Apple's Accelerate framework sparse linear algebra routines. + ACCELERATE_SPARSE, + // No sparse linear solver should be used. This does not necessarily // imply that Ceres was built without any sparse library, although that // is the likely use case, merely that one should not be used.
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index 9d8b923..38ba9d4 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt
@@ -56,6 +56,7 @@ set(CERES_INTERNAL_SRC ${CERES_PARALLEL_FOR_SRC} + accelerate_sparse.cc array_utils.cc blas.cc block_evaluate_preparer.cc @@ -206,6 +207,10 @@ list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${CXSPARSE_LIBRARIES}) endif (CXSPARSE AND CXSPARSE_FOUND) +if (ACCELERATESPARSE AND AccelerateSparse_FOUND) + list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${AccelerateSparse_LIBRARIES}) +endif() + if (LAPACK_FOUND) list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${LAPACK_LIBRARIES}) endif ()
diff --git a/internal/ceres/accelerate_sparse.cc b/internal/ceres/accelerate_sparse.cc new file mode 100644 index 0000000..a82d90b --- /dev/null +++ b/internal/ceres/accelerate_sparse.cc
@@ -0,0 +1,238 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: alexs.mac@gmail.com (Alex Stewart) + +// This include must come before any #ifndef check on Ceres compile options. +#include "ceres/internal/port.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +#include "ceres/accelerate_sparse.h" + +#include <algorithm> +#include <string> +#include <vector> + +#include "ceres/compressed_col_sparse_matrix_utils.h" +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/triplet_sparse_matrix.h" +#include "glog/logging.h" + +#define CASESTR(x) case x: return #x + +namespace ceres { +namespace internal { + +const char* SparseStatusToString(SparseStatus_t status) { + switch (status) { + CASESTR(SparseStatusOK); + CASESTR(SparseFactorizationFailed); + CASESTR(SparseMatrixIsSingular); + CASESTR(SparseInternalError); + CASESTR(SparseParameterError); + CASESTR(SparseStatusReleased); + default: + return "UKNOWN"; + } +} + +template<typename Scalar> +void AccelerateSparse<Scalar>::Solve(NumericFactorization* numeric_factor, + DenseVector* rhs_and_solution) { + SparseSolve(*numeric_factor, *rhs_and_solution); +} + +template<typename Scalar> +typename AccelerateSparse<Scalar>::ASSparseMatrix +AccelerateSparse<Scalar>::CreateSparseMatrixTransposeView( + CompressedRowSparseMatrix* A) { + // Accelerate uses CSC as its sparse storage format whereas Ceres uses CSR. + // As this method returns the transpose view we can flip rows/cols to map + // from CSR to CSC^T. + // + // Accelerate's columnStarts is a long*, not an int*. These types might be + // different (e.g. ARM on iOS) so always make a copy. + column_starts_.resize(A->num_rows() +1); // +1 for final column length. + std::copy_n(A->rows(), column_starts_.size(), &column_starts_[0]); + + ASSparseMatrix At; + At.structure.rowCount = A->num_cols(); + At.structure.columnCount = A->num_rows(); + At.structure.columnStarts = &column_starts_[0]; + At.structure.rowIndices = A->mutable_cols(); + At.structure.attributes.transpose = false; + At.structure.attributes.triangle = SparseUpperTriangle; + At.structure.attributes.kind = SparseSymmetric; + At.structure.attributes._reserved = 0; + At.structure.attributes._allocatedBySparse = 0; + At.structure.blockSize = 1; + if (std::is_same<Scalar, double>::value) { + At.data = reinterpret_cast<Scalar*>(A->mutable_values()); + } else { + values_ = + ConstVectorRef(A->values(), A->num_nonzeros()).template cast<Scalar>(); + At.data = values_.data(); + } + return At; +} + +template<typename Scalar> +typename AccelerateSparse<Scalar>::SymbolicFactorization +AccelerateSparse<Scalar>::AnalyzeCholesky(ASSparseMatrix* A) { + return SparseFactor(SparseFactorizationCholesky, A->structure); +} + +template<typename Scalar> +typename AccelerateSparse<Scalar>::NumericFactorization +AccelerateSparse<Scalar>::Cholesky(ASSparseMatrix* A, + SymbolicFactorization* symbolic_factor) { + return SparseFactor(*symbolic_factor, *A); +} + +// Instantiate only for the specific template types required/supported s/t the +// definition can be in the .cc file. +template class AccelerateSparse<double>; +template class AccelerateSparse<float>; + +template<typename Scalar> +std::unique_ptr<SparseCholesky> +AppleAccelerateCholesky<Scalar>::Create(OrderingType ordering_type) { + return std::unique_ptr<SparseCholesky>( + new AppleAccelerateCholesky<Scalar>(ordering_type)); +} + +template<typename Scalar> +AppleAccelerateCholesky<Scalar>::AppleAccelerateCholesky( + const OrderingType ordering_type) + : ordering_type_(ordering_type) {} + +template<typename Scalar> +AppleAccelerateCholesky<Scalar>::~AppleAccelerateCholesky() { + FreeSymbolicFactorization(); + FreeNumericFactorization(); +} + +template<typename Scalar> +CompressedRowSparseMatrix::StorageType +AppleAccelerateCholesky<Scalar>::StorageType() const { + return CompressedRowSparseMatrix::LOWER_TRIANGULAR; +} + +template<typename Scalar> +LinearSolverTerminationType +AppleAccelerateCholesky<Scalar>::Factorize(CompressedRowSparseMatrix* lhs, + std::string* message) { + CHECK_EQ(lhs->storage_type(), StorageType()); + if (lhs == NULL) { + *message = "Failure: Input lhs is NULL."; + return LINEAR_SOLVER_FATAL_ERROR; + } + typename SparseTypesTrait<Scalar>::SparseMatrix as_lhs = + as_.CreateSparseMatrixTransposeView(lhs); + + if (!symbolic_factor_) { + symbolic_factor_.reset( + new typename SparseTypesTrait<Scalar>::SymbolicFactorization( + as_.AnalyzeCholesky(&as_lhs))); + if (symbolic_factor_->status != SparseStatusOK) { + *message = StringPrintf( + "Apple Accelerate Failure : Symbolic factorisation failed: %s", + SparseStatusToString(symbolic_factor_->status)); + FreeSymbolicFactorization(); + return LINEAR_SOLVER_FATAL_ERROR; + } + } + + FreeNumericFactorization(); + numeric_factor_.reset( + new typename SparseTypesTrait<Scalar>::NumericFactorization( + as_.Cholesky(&as_lhs, symbolic_factor_.get()))); + if (numeric_factor_->status != SparseStatusOK) { + *message = StringPrintf( + "Apple Accelerate Failure : Numeric factorisation failed: %s", + SparseStatusToString(numeric_factor_->status)); + return LINEAR_SOLVER_FAILURE; + } + + return LINEAR_SOLVER_SUCCESS; +} + +template<typename Scalar> +LinearSolverTerminationType +AppleAccelerateCholesky<Scalar>::Solve(const double* rhs, + double* solution, + std::string* message) { + CHECK_EQ(numeric_factor_->status, SparseStatusOK) + << "Solve called without a call to Factorize first (" + << SparseStatusToString(numeric_factor_->status) << ")."; + const int num_cols = numeric_factor_->symbolicFactorization.columnCount; + + typename SparseTypesTrait<Scalar>::DenseVector as_rhs_and_solution; + as_rhs_and_solution.count = num_cols; + if (std::is_same<Scalar, double>::value) { + as_rhs_and_solution.data = reinterpret_cast<Scalar*>(solution); + std::copy_n(rhs, num_cols, solution); + } else { + scalar_rhs_and_solution_ = + ConstVectorRef(rhs, num_cols).template cast<Scalar>(); + as_rhs_and_solution.data = scalar_rhs_and_solution_.data(); + } + as_.Solve(numeric_factor_.get(), &as_rhs_and_solution); + if (!std::is_same<Scalar, double>::value) { + VectorRef(solution, num_cols) = + scalar_rhs_and_solution_.template cast<double>(); + } + return LINEAR_SOLVER_SUCCESS; +} + +template<typename Scalar> +void AppleAccelerateCholesky<Scalar>::FreeSymbolicFactorization() { + if (symbolic_factor_) { + SparseCleanup(*symbolic_factor_); + symbolic_factor_.reset(); + } +} + +template<typename Scalar> +void AppleAccelerateCholesky<Scalar>::FreeNumericFactorization() { + if (numeric_factor_) { + SparseCleanup(*numeric_factor_); + numeric_factor_.reset(); + } +} + +// Instantiate only for the specific template types required/supported s/t the +// definition can be in the .cc file. +template class AppleAccelerateCholesky<double>; +template class AppleAccelerateCholesky<float>; + +} +} + +#endif // CERES_NO_ACCELERATE_SPARSE
diff --git a/internal/ceres/accelerate_sparse.h b/internal/ceres/accelerate_sparse.h new file mode 100644 index 0000000..cb5d084 --- /dev/null +++ b/internal/ceres/accelerate_sparse.h
@@ -0,0 +1,142 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: alexs.mac@gmail.com (Alex Stewart) + +#ifndef CERES_INTERNAL_ACCELERATE_SPARSE_H_ +#define CERES_INTERNAL_ACCELERATE_SPARSE_H_ + +// This include must come before any #ifndef check on Ceres compile options. +#include "ceres/internal/port.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +#include <memory> +#include <string> +#include <vector> + +#include "ceres/linear_solver.h" +#include "ceres/sparse_cholesky.h" +#include "Accelerate.h" + +namespace ceres { +namespace internal { + +class CompressedRowSparseMatrix; +class TripletSparseMatrix; + +template<typename Scalar> +struct SparseTypesTrait { +}; + +template<> +struct SparseTypesTrait<double> { + typedef DenseVector_Double DenseVector; + typedef SparseMatrix_Double SparseMatrix; + typedef SparseOpaqueSymbolicFactorization SymbolicFactorization; + typedef SparseOpaqueFactorization_Double NumericFactorization; +}; + +template<> +struct SparseTypesTrait<float> { + typedef DenseVector_Float DenseVector; + typedef SparseMatrix_Float SparseMatrix; + typedef SparseOpaqueSymbolicFactorization SymbolicFactorization; + typedef SparseOpaqueFactorization_Float NumericFactorization; +}; + +template<typename Scalar> +class AccelerateSparse { + public: + using DenseVector = typename SparseTypesTrait<Scalar>::DenseVector; + // Use ASSparseMatrix to avoid collision with ceres::internal::SparseMatrix. + using ASSparseMatrix = typename SparseTypesTrait<Scalar>::SparseMatrix; + using SymbolicFactorization = typename SparseTypesTrait<Scalar>::SymbolicFactorization; + using NumericFactorization = typename SparseTypesTrait<Scalar>::NumericFactorization; + + // Solves a linear system given its symbolic (reference counted within + // NumericFactorization) and numeric factorization. + void Solve(NumericFactorization* numeric_factor, + DenseVector* rhs_and_solution); + + // Note: Accelerate's API passes/returns its objects by value, but as the + // objects contain pointers to the underlying data these copies are + // all shallow (in some cases Accelerate also reference counts the + // objects internally). + ASSparseMatrix CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A); + // Computes a symbolic factorisation of A that can be used in Solve(). + SymbolicFactorization AnalyzeCholesky(ASSparseMatrix* A); + // Compute the numeric Cholesky factorization of A, given its + // symbolic factorization. + NumericFactorization Cholesky(ASSparseMatrix* A, + SymbolicFactorization* symbolic_factor); + + private: + std::vector<long> column_starts_; + // Storage for the values of A if Scalar != double (necessitating a copy). + Eigen::Matrix<Scalar, Eigen::Dynamic, 1> values_; +}; + +// An implementation of SparseCholesky interface using Apple's Accelerate +// framework. +template<typename Scalar> +class AppleAccelerateCholesky : public SparseCholesky { + public: + // Factory + static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type); + + // SparseCholesky interface. + virtual ~AppleAccelerateCholesky(); + virtual CompressedRowSparseMatrix::StorageType StorageType() const; + virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs, + std::string* message); + virtual LinearSolverTerminationType Solve(const double* rhs, + double* solution, + std::string* message); + + private: + AppleAccelerateCholesky(const OrderingType ordering_type); + void FreeSymbolicFactorization(); + void FreeNumericFactorization(); + + const OrderingType ordering_type_; + AccelerateSparse<Scalar> as_; + std::unique_ptr<typename AccelerateSparse<Scalar>::SymbolicFactorization> + symbolic_factor_; + std::unique_ptr<typename AccelerateSparse<Scalar>::NumericFactorization> + numeric_factor_; + // Copy of rhs/solution if Scalar != double (necessitating a copy). + Eigen::Matrix<Scalar, Eigen::Dynamic, 1> scalar_rhs_and_solution_; +}; + +} +} + +#endif // CERES_NO_ACCELERATE_SPARSE + +#endif // CERES_INTERNAL_ACCELERATE_SPARSE_H_
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h index 7032ce7..17be90c 100644 --- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h +++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
@@ -48,6 +48,9 @@ // sparsity is not constant across calls to Solve. This means that // there is no benefit to symbolically factorizing the matrix and // caching this factorization. +// +// TODO(alex): Add support for Accelerate sparse solvers: +// https://github.com/ceres-solver/ceres-solver/issues/397 class DynamicSparseNormalCholeskySolver : public CompressedRowSparseMatrixSolver { public:
diff --git a/internal/ceres/generate_bundle_adjustment_tests.py b/internal/ceres/generate_bundle_adjustment_tests.py index 86452b5..2f3375a 100644 --- a/internal/ceres/generate_bundle_adjustment_tests.py +++ b/internal/ceres/generate_bundle_adjustment_tests.py
@@ -49,15 +49,19 @@ ('ITERATIVE_SCHUR', 'SUITE_SPARSE', 'CLUSTER_JACOBI'), ('ITERATIVE_SCHUR', 'EIGEN_SPARSE', 'CLUSTER_JACOBI'), ('ITERATIVE_SCHUR', 'CX_SPARSE', 'CLUSTER_JACOBI'), + ('ITERATIVE_SCHUR', 'ACCELERATE_SPARSE','CLUSTER_JACOBI'), ('ITERATIVE_SCHUR', 'SUITE_SPARSE', 'CLUSTER_TRIDIAGONAL'), ('ITERATIVE_SCHUR', 'EIGEN_SPARSE', 'CLUSTER_TRIDIAGONAL'), ('ITERATIVE_SCHUR', 'CX_SPARSE', 'CLUSTER_TRIDIAGONAL'), + ('ITERATIVE_SCHUR', 'ACCELERATE_SPARSE','CLUSTER_TRIDIAGONAL'), ('SPARSE_NORMAL_CHOLESKY', 'SUITE_SPARSE', 'IDENTITY'), ('SPARSE_NORMAL_CHOLESKY', 'EIGEN_SPARSE', 'IDENTITY'), ('SPARSE_NORMAL_CHOLESKY', 'CX_SPARSE', 'IDENTITY'), + ('SPARSE_NORMAL_CHOLESKY', 'ACCELERATE_SPARSE','IDENTITY'), ('SPARSE_SCHUR', 'SUITE_SPARSE', 'IDENTITY'), ('SPARSE_SCHUR', 'EIGEN_SPARSE', 'IDENTITY'), ('SPARSE_SCHUR', 'CX_SPARSE', 'IDENTITY'), + ('SPARSE_SCHUR', 'ACCELERATE_SPARSE','IDENTITY'), ] FILENAME_SHORTENING_MAP = dict( @@ -69,6 +73,7 @@ SUITE_SPARSE='suitesparse', EIGEN_SPARSE='eigensparse', CX_SPARSE='cxsparse', + ACCELERATE_SPARSE='acceleratesparse', IDENTITY='identity', JACOBI='jacobi', SCHUR_JACOBI='schurjacobi', @@ -192,6 +197,9 @@ elif sparse_backend == 'CX_SPARSE': preprocessor_conditions_begin.append('#ifndef CERES_NO_CXSPARSE') preprocessor_conditions_end.insert(0, '#endif // CERES_NO_CXSPARSE') + elif sparse_backend == 'ACCELERATE_SPARSE': + preprocessor_conditions_begin.append('#ifndef CERES_NO_ACCELERATE_SPARSE') + preprocessor_conditions_end.insert(0, '#endif // CERES_NO_ACCELERATE_SPARSE') elif sparse_backend == 'EIGEN_SPARSE': preprocessor_conditions_begin.append('#ifdef CERES_USE_EIGEN_SPARSE') preprocessor_conditions_end.insert(0, '#endif // CERES_USE_EIGEN_SPARSE')
diff --git a/internal/ceres/generated_bundle_adjustment_tests/CMakeLists.txt b/internal/ceres/generated_bundle_adjustment_tests/CMakeLists.txt index 0a9cf59..db2d233 100644 --- a/internal/ceres/generated_bundle_adjustment_tests/CMakeLists.txt +++ b/internal/ceres/generated_bundle_adjustment_tests/CMakeLists.txt
@@ -59,6 +59,10 @@ ceres_test(ba_iterschur_cxsparse_clustjacobi_auto_threads) ceres_test(ba_iterschur_cxsparse_clustjacobi_user) ceres_test(ba_iterschur_cxsparse_clustjacobi_user_threads) +ceres_test(ba_iterschur_acceleratesparse_clustjacobi_auto) +ceres_test(ba_iterschur_acceleratesparse_clustjacobi_auto_threads) +ceres_test(ba_iterschur_acceleratesparse_clustjacobi_user) +ceres_test(ba_iterschur_acceleratesparse_clustjacobi_user_threads) ceres_test(ba_iterschur_suitesparse_clusttri_auto) ceres_test(ba_iterschur_suitesparse_clusttri_auto_threads) ceres_test(ba_iterschur_suitesparse_clusttri_user) @@ -71,6 +75,10 @@ ceres_test(ba_iterschur_cxsparse_clusttri_auto_threads) ceres_test(ba_iterschur_cxsparse_clusttri_user) ceres_test(ba_iterschur_cxsparse_clusttri_user_threads) +ceres_test(ba_iterschur_acceleratesparse_clusttri_auto) +ceres_test(ba_iterschur_acceleratesparse_clusttri_auto_threads) +ceres_test(ba_iterschur_acceleratesparse_clusttri_user) +ceres_test(ba_iterschur_acceleratesparse_clusttri_user_threads) ceres_test(ba_sparsecholesky_suitesparse_auto) ceres_test(ba_sparsecholesky_suitesparse_auto_threads) ceres_test(ba_sparsecholesky_suitesparse_user) @@ -83,6 +91,10 @@ ceres_test(ba_sparsecholesky_cxsparse_auto_threads) ceres_test(ba_sparsecholesky_cxsparse_user) ceres_test(ba_sparsecholesky_cxsparse_user_threads) +ceres_test(ba_sparsecholesky_acceleratesparse_auto) +ceres_test(ba_sparsecholesky_acceleratesparse_auto_threads) +ceres_test(ba_sparsecholesky_acceleratesparse_user) +ceres_test(ba_sparsecholesky_acceleratesparse_user_threads) ceres_test(ba_sparseschur_suitesparse_auto) ceres_test(ba_sparseschur_suitesparse_auto_threads) ceres_test(ba_sparseschur_suitesparse_user) @@ -95,3 +107,7 @@ ceres_test(ba_sparseschur_cxsparse_auto_threads) ceres_test(ba_sparseschur_cxsparse_user) ceres_test(ba_sparseschur_cxsparse_user_threads) +ceres_test(ba_sparseschur_acceleratesparse_auto) +ceres_test(ba_sparseschur_acceleratesparse_auto_threads) +ceres_test(ba_sparseschur_acceleratesparse_user) +ceres_test(ba_sparseschur_acceleratesparse_user_threads)
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc new file mode 100644 index 0000000..30443af --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterJacobi_AutomaticOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_JACOBI; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc new file mode 100644 index 0000000..f61e1d6 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterJacobi_AutomaticOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_JACOBI; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc new file mode 100644 index 0000000..6de1e4b --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterJacobi_UserOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_JACOBI; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc new file mode 100644 index 0000000..74cb674 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterJacobi_UserOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_JACOBI; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc new file mode 100644 index 0000000..4168466 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterTridiagonal_AutomaticOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_TRIDIAGONAL; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc new file mode 100644 index 0000000..11c962b --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterTridiagonal_AutomaticOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_TRIDIAGONAL; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc new file mode 100644 index 0000000..b8cb11d --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterTridiagonal_UserOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_TRIDIAGONAL; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc new file mode 100644 index 0000000..ff2e8de --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + IterativeSchur_AccelerateSparse_ClusterTridiagonal_UserOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = ITERATIVE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = CLUSTER_TRIDIAGONAL; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc new file mode 100644 index 0000000..4683d2b --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseNormalCholesky_AccelerateSparse_AutomaticOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = SPARSE_NORMAL_CHOLESKY; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc new file mode 100644 index 0000000..1b63415 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseNormalCholesky_AccelerateSparse_AutomaticOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = SPARSE_NORMAL_CHOLESKY; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc new file mode 100644 index 0000000..bdc7d62 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseNormalCholesky_AccelerateSparse_UserOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = SPARSE_NORMAL_CHOLESKY; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc new file mode 100644 index 0000000..36567f1 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseNormalCholesky_AccelerateSparse_UserOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = SPARSE_NORMAL_CHOLESKY; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc new file mode 100644 index 0000000..b43a26a --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseSchur_AccelerateSparse_AutomaticOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = SPARSE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc new file mode 100644 index 0000000..7e330c4 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseSchur_AccelerateSparse_AutomaticOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = SPARSE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kAutomaticOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc new file mode 100644 index 0000000..b5738b7 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc
@@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseSchur_AccelerateSparse_UserOrdering) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 1; + options->linear_solver_type = SPARSE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc new file mode 100644 index 0000000..b5c6105 --- /dev/null +++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc
@@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2018 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// ======================================== +// +// This file is generated using generate_bundle_adjustment_tests.py. + +#include "bundle_adjustment_test_util.h" + +#ifndef CERES_NO_ACCELERATE_SPARSE +#ifndef CERES_NO_THREADS + +namespace ceres { +namespace internal { + +TEST_F(BundleAdjustmentTest, + SparseSchur_AccelerateSparse_UserOrdering_Threads) { // NOLINT + BundleAdjustmentProblem bundle_adjustment_problem; + Solver::Options* options = + bundle_adjustment_problem.mutable_solver_options(); + options->num_threads = 4; + options->linear_solver_type = SPARSE_SCHUR; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options->preconditioner_type = IDENTITY; + if (kUserOrdering) { + options->linear_solver_ordering.reset(); + } + Problem* problem = bundle_adjustment_problem.mutable_problem(); + RunSolverForConfigAndExpectResidualsMatch(*options, problem); +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_THREADS +#endif // CERES_NO_ACCELERATE_SPARSE +
diff --git a/internal/ceres/linear_solver.cc b/internal/ceres/linear_solver.cc index da14d3d..107af6a 100644 --- a/internal/ceres/linear_solver.cc +++ b/internal/ceres/linear_solver.cc
@@ -78,9 +78,7 @@ return new CgnrSolver(options); case SPARSE_NORMAL_CHOLESKY: -#if defined(CERES_NO_SUITESPARSE) && \ - defined(CERES_NO_CXSPARSE) && \ - !defined(CERES_USE_EIGEN_SPARSE) +#if defined(CERES_NO_SPARSE) return NULL; #else if (options.dynamic_sparsity) { @@ -91,9 +89,7 @@ #endif case SPARSE_SCHUR: -#if defined(CERES_NO_SUITESPARSE) && \ - defined(CERES_NO_CXSPARSE) && \ - !defined(CERES_USE_EIGEN_SPARSE) +#if defined(CERES_NO_SPARSE) return NULL; #else return new SparseSchurComplementSolver(options);
diff --git a/internal/ceres/reorder_program.cc b/internal/ceres/reorder_program.cc index 86c1368..49e0449 100644 --- a/internal/ceres/reorder_program.cc +++ b/internal/ceres/reorder_program.cc
@@ -568,6 +568,12 @@ OrderingForSparseNormalCholeskyUsingCXSparse( *tsm_block_jacobian_transpose, &ordering[0]); + } else if (sparse_linear_algebra_library_type == ACCELERATE_SPARSE) { + // TODO(alex): Investigate what analysis on pre-ordered matrices + // Accelerate supports, but for now disable. + // https://github.com/ceres-solver/ceres-solver/issues/394. + return true; + } else if (sparse_linear_algebra_library_type == EIGEN_SPARSE) { #if EIGEN_VERSION_AT_LEAST(3, 2, 2) OrderingForSparseNormalCholeskyUsingEigenSparse(
diff --git a/internal/ceres/schur_complement_solver_test.cc b/internal/ceres/schur_complement_solver_test.cc index 2350858..a86c8ef 100644 --- a/internal/ceres/schur_complement_solver_test.cc +++ b/internal/ceres/schur_complement_solver_test.cc
@@ -220,6 +220,20 @@ } #endif // CERES_NO_CXSPARSE +#ifndef CERES_NO_ACCELERATE_SPARSE +TEST_F(SchurComplementSolverTest, + SparseSchurWithAccelerateSparseSmallProblem) { + ComputeAndCompareSolutions(2, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true); + ComputeAndCompareSolutions(2, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true); +} + +TEST_F(SchurComplementSolverTest, + SparseSchurWithAccelerateSparseLargeProblem) { + ComputeAndCompareSolutions(3, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true); + ComputeAndCompareSolutions(3, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true); +} +#endif // CERES_NO_ACCELERATE_SPARSE + #ifdef CERES_USE_EIGEN_SPARSE TEST_F(SchurComplementSolverTest, SparseSchurWithEigenSparseSmallProblem) {
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc index 8f68fec..d11fef4 100644 --- a/internal/ceres/solver_test.cc +++ b/internal/ceres/solver_test.cc
@@ -320,6 +320,24 @@ } #endif +#if defined(CERES_NO_ACCELERATE_SPARSE) +TEST(Solver, SparseNormalCholeskyNoAccelerateSparse) { + Solver::Options options; + options.sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options.linear_solver_type = SPARSE_NORMAL_CHOLESKY; + string message; + EXPECT_FALSE(options.IsValid(&message)); +} + +TEST(Solver, SparseSchurNoAccelerateSparse) { + Solver::Options options; + options.sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options.linear_solver_type = SPARSE_SCHUR; + string message; + EXPECT_FALSE(options.IsValid(&message)); +} +#endif + #if !defined(CERES_USE_EIGEN_SPARSE) TEST(Solver, SparseNormalCholeskyNoEigenSparse) { Solver::Options options;
diff --git a/internal/ceres/solver_utils.cc b/internal/ceres/solver_utils.cc index 084caeb..4b400d3 100644 --- a/internal/ceres/solver_utils.cc +++ b/internal/ceres/solver_utils.cc
@@ -70,6 +70,10 @@ value += "-cxsparse-(" + std::string(CERES_CXSPARSE_VERSION) + ")"; #endif +#ifndef CERES_NO_ACCELERATE_SPARSE + value += "-acceleratesparse"; +#endif + #ifdef CERES_USE_EIGEN_SPARSE value += "-eigensparse"; #endif
diff --git a/internal/ceres/sparse_cholesky.cc b/internal/ceres/sparse_cholesky.cc index e18f380..3275cc0 100644 --- a/internal/ceres/sparse_cholesky.cc +++ b/internal/ceres/sparse_cholesky.cc
@@ -30,6 +30,7 @@ #include "ceres/sparse_cholesky.h" +#include "ceres/accelerate_sparse.h" #include "ceres/cxsparse.h" #include "ceres/eigensparse.h" #include "ceres/float_cxsparse.h" @@ -78,10 +79,24 @@ } else { sparse_cholesky = CXSparseCholesky::Create(ordering_type); } + break; #else LOG(FATAL) << "Ceres was compiled without support for CXSparse."; #endif + + case ACCELERATE_SPARSE: +#ifndef CERES_NO_ACCELERATE_SPARSE + if (options.use_mixed_precision_solves) { + sparse_cholesky = AppleAccelerateCholesky<float>::Create(ordering_type); + } else { + sparse_cholesky = AppleAccelerateCholesky<double>::Create(ordering_type); + } break; +#else + LOG(FATAL) << "Ceres was compiled without support for Apple's Accelerate " + << "framework solvers."; +#endif + default: LOG(FATAL) << "Unknown sparse linear algebra library type : " << SparseLinearAlgebraLibraryTypeToString(
diff --git a/internal/ceres/sparse_cholesky_test.cc b/internal/ceres/sparse_cholesky_test.cc index 34098f3..60dae64 100644 --- a/internal/ceres/sparse_cholesky_test.cc +++ b/internal/ceres/sparse_cholesky_test.cc
@@ -204,6 +204,22 @@ ParamInfoToString); #endif +#ifndef CERES_NO_ACCELERATE_SPARSE +INSTANTIATE_TEST_CASE_P(AccelerateSparseCholesky, + SparseCholeskyTest, + ::testing::Combine(::testing::Values(ACCELERATE_SPARSE), + ::testing::Values(AMD, NATURAL), + ::testing::Values(true, false)), + ParamInfoToString); + +INSTANTIATE_TEST_CASE_P(AccelerateSparseCholeskySingle, + SparseCholeskyTest, + ::testing::Combine(::testing::Values(ACCELERATE_SPARSE), + ::testing::Values(AMD, NATURAL), + ::testing::Values(true, false)), + ParamInfoToString); +#endif + #ifdef CERES_USE_EIGEN_SPARSE INSTANTIATE_TEST_CASE_P(EigenSparseCholesky, SparseCholeskyTest,
diff --git a/internal/ceres/sparse_normal_cholesky_solver_test.cc b/internal/ceres/sparse_normal_cholesky_solver_test.cc index 1b836a5..aa9dc62 100644 --- a/internal/ceres/sparse_normal_cholesky_solver_test.cc +++ b/internal/ceres/sparse_normal_cholesky_solver_test.cc
@@ -154,6 +154,30 @@ } #endif +#ifndef CERES_NO_ACCELERATE_SPARSE +TEST_F(SparseNormalCholeskySolverTest, + SparseNormalCholeskyUsingAccelerateSparsePreOrdering) { + LinearSolver::Options options; + options.sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options.type = SPARSE_NORMAL_CHOLESKY; + options.use_postordering = false; + ContextImpl context; + options.context = &context; + TestSolver(options); +} + +TEST_F(SparseNormalCholeskySolverTest, + SparseNormalCholeskyUsingAcceleratePostOrdering) { + LinearSolver::Options options; + options.sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + options.type = SPARSE_NORMAL_CHOLESKY; + options.use_postordering = true; + ContextImpl context; + options.context = &context; + TestSolver(options); +} +#endif + #ifdef CERES_USE_EIGEN_SPARSE TEST_F(SparseNormalCholeskySolverTest, SparseNormalCholeskyUsingEigenPreOrdering) {
diff --git a/internal/ceres/subset_preconditioner_test.cc b/internal/ceres/subset_preconditioner_test.cc index b159e0f..0285680 100644 --- a/internal/ceres/subset_preconditioner_test.cc +++ b/internal/ceres/subset_preconditioner_test.cc
@@ -182,6 +182,14 @@ ParamInfoToString); #endif +#ifndef CERES_NO_ACCELERATE_SPARSE +INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithAccelerateSparse, + SubsetPreconditionerTest, + ::testing::Combine(::testing::Values(ACCELERATE_SPARSE), + ::testing::Values(true, false)), + ParamInfoToString); +#endif + #ifdef CERES_USE_EIGEN_SPARSE INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithEigenSparse, SubsetPreconditionerTest,
diff --git a/internal/ceres/system_test.cc b/internal/ceres/system_test.cc index ca0f529..3f635d0 100644 --- a/internal/ceres/system_test.cc +++ b/internal/ceres/system_test.cc
@@ -201,6 +201,17 @@ } #endif // CERES_NO_CXSPARSE +#ifndef CERES_NO_ACCELERATE_SPARSE +TEST_F(PowellTest, SparseNormalCholeskyUsingAccelerateSparse) { + PowellsFunction powells_function; + Solver::Options* options = powells_function.mutable_solver_options(); + options->linear_solver_type = SPARSE_NORMAL_CHOLESKY; + options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE; + RunSolverForConfigAndExpectResidualsMatch(*options, + powells_function.mutable_problem()); +} +#endif // CERES_NO_ACCELERATE_SPARSE + #ifdef CERES_USE_EIGEN_SPARSE TEST_F(PowellTest, SparseNormalCholeskyUsingEigenSparse) { PowellsFunction powells_function;
diff --git a/internal/ceres/trust_region_preprocessor_test.cc b/internal/ceres/trust_region_preprocessor_test.cc index 92162c1..0c91e21 100644 --- a/internal/ceres/trust_region_preprocessor_test.cc +++ b/internal/ceres/trust_region_preprocessor_test.cc
@@ -200,17 +200,13 @@ PreprocessForGivenLinearSolverAndVerify(DENSE_SCHUR); } -#if defined(CERES_USE_EIGEN_SPARSE) || \ - !defined(CERES_NO_SUITESPARSE) || \ - !defined(CERES_NO_CXSPARSE) +#if !defined(CERES_NO_SPARSE) TEST_F(LinearSolverAndEvaluatorCreationTest, SparseNormalCholesky) { PreprocessForGivenLinearSolverAndVerify(SPARSE_NORMAL_CHOLESKY); } #endif -#if defined(CERES_USE_EIGEN_SPARSE) || \ - !defined(CERES_NO_SUITESPARSE) || \ - !defined(CERES_NO_CXSPARSE) +#if !defined(CERES_NO_SPARSE) TEST_F(LinearSolverAndEvaluatorCreationTest, SparseSchur) { PreprocessForGivenLinearSolverAndVerify(SPARSE_SCHUR); }
diff --git a/internal/ceres/types.cc b/internal/ceres/types.cc index b833928..932ec7d 100644 --- a/internal/ceres/types.cc +++ b/internal/ceres/types.cc
@@ -99,6 +99,7 @@ CASESTR(SUITE_SPARSE); CASESTR(CX_SPARSE); CASESTR(EIGEN_SPARSE); + CASESTR(ACCELERATE_SPARSE); CASESTR(NO_SPARSE); default: return "UNKNOWN"; @@ -112,6 +113,7 @@ STRENUM(SUITE_SPARSE); STRENUM(CX_SPARSE); STRENUM(EIGEN_SPARSE); + STRENUM(ACCELERATE_SPARSE); STRENUM(NO_SPARSE); return false; } @@ -361,6 +363,14 @@ #endif } + if (type == ACCELERATE_SPARSE) { +#ifdef CERES_NO_ACCELERATE_SPARSE + return false; +#else + return true; +#endif + } + if (type == EIGEN_SPARSE) { #ifdef CERES_USE_EIGEN_SPARSE return true;
diff --git a/jni/Android.mk b/jni/Android.mk index d179406..668f651 100644 --- a/jni/Android.mk +++ b/jni/Android.mk
@@ -108,10 +108,12 @@ -DCERES_NO_LAPACK \ -DCERES_NO_SUITESPARSE \ -DCERES_NO_CXSPARSE \ + -DCERES_NO_ACCELERATE_SPARSE \ -DCERES_USE_EIGEN_SPARSE \ -DCERES_USE_OPENMP -LOCAL_SRC_FILES := $(CERES_SRC_PATH)/array_utils.cc \ +LOCAL_SRC_FILES := $(CERES_SRC_PATH)/accelerate_sparse.cc \ + $(CERES_SRC_PATH)/array_utils.cc \ $(CERES_SRC_PATH)/blas.cc \ $(CERES_SRC_PATH)/block_evaluate_preparer.cc \ $(CERES_SRC_PATH)/block_jacobian_writer.cc \