diff --git a/CMakeLists.txt b/CMakeLists.txt index c707d358b..ea7e9b842 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,14 +182,8 @@ endif() if (MSVC) option(MSVC_USE_STATIC_CRT "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF) +endif() - if (BUILD_TESTING AND BUILD_SHARED_LIBS) - message( - "-- Disabling tests. The flags BUILD_TESTING and BUILD_SHARED_LIBS" - " are incompatible with MSVC.") - update_cache_variable(BUILD_TESTING OFF) - endif (BUILD_TESTING AND BUILD_SHARED_LIBS) -endif (MSVC) # Allow user to specify a suffix for the library install directory, the only # really sensible option (other than "") being "64", such that: # ${CMAKE_INSTALL_PREFIX}/lib -> ${CMAKE_INSTALL_PREFIX}/lib64. @@ -482,7 +476,7 @@ if (BUILD_SHARED_LIBS) # The CERES_BUILDING_SHARED_LIBRARY compile definition is NOT stored in # CERES_COMPILE_OPTIONS as it must only be defined when Ceres is compiled # not when it is used as it controls the CERES_EXPORT macro which provides - # dllimport/export support in MSVC. + # symbol import/export support. add_definitions(-DCERES_BUILDING_SHARED_LIBRARY) list(APPEND CERES_COMPILE_OPTIONS CERES_USING_SHARED_LIBRARY) else (BUILD_SHARED_LIBS) diff --git a/include/ceres/internal/port.h b/include/ceres/internal/port.h index 080121e4f..040a1efba 100644 --- a/include/ceres/internal/port.h +++ b/include/ceres/internal/port.h @@ -69,22 +69,42 @@ #endif // A macro to signal which functions and classes are exported when -// building a DLL with MSVC. -// -// Note that the ordering here is important, CERES_BUILDING_SHARED_LIBRARY -// is only defined locally when Ceres is compiled, it is never exported to -// users. However, in order that we do not have to configure config.h -// separately for building vs installing, if we are using MSVC and building -// a shared library, then both CERES_BUILDING_SHARED_LIBRARY and -// CERES_USING_SHARED_LIBRARY will be defined when Ceres is compiled. -// Hence it is important that the check for CERES_BUILDING_SHARED_LIBRARY -// happens first. -#if defined(_MSC_VER) && defined(CERES_BUILDING_SHARED_LIBRARY) -#define CERES_EXPORT __declspec(dllexport) -#elif defined(_MSC_VER) && defined(CERES_USING_SHARED_LIBRARY) -#define CERES_EXPORT __declspec(dllimport) +// building a shared library. +#if defined(_MSC_VER) +#define CERES_API_SHARED_IMPORT __declspec(dllimport) +#define CERES_API_SHARED_EXPORT __declspec(dllexport) +#elif defined(__GNUC__) +#define CERES_API_SHARED_IMPORT __attribute__((visibility("default"))) +#define CERES_API_SHARED_EXPORT __attribute__((visibility("default"))) #else +#define CERES_API_SHARED_IMPORT +#define CERES_API_SHARED_EXPORT +#endif + +// CERES_BUILDING_SHARED_LIBRARY is only defined locally when Ceres itself is +// compiled as a shared library, it is never exported to users. In order that +// we do not have to configure config.h separately when building Ceres as either +// a static or dynamic library, we define both CERES_USING_SHARED_LIBRARY and +// CERES_BUILDING_SHARED_LIBRARY when building as a shared library. +#if defined(CERES_USING_SHARED_LIBRARY) +#if defined(CERES_BUILDING_SHARED_LIBRARY) +// Compiling Ceres itself as a shared library. +#define CERES_EXPORT CERES_API_SHARED_EXPORT +#else +// Using Ceres as a shared library. +#define CERES_EXPORT CERES_API_SHARED_IMPORT +#endif +#else +// Ceres was compiled as a static library, export everything. #define CERES_EXPORT #endif +// Unit tests reach in and test internal functionality so we need a way to make +// those symbols visible +#ifdef CERES_EXPORT_INTERNAL_SYMBOLS +#define CERES_EXPORT_INTERNAL CERES_EXPORT +#else +#define CERES_EXPORT_INTERNAL +#endif + #endif // CERES_PUBLIC_INTERNAL_PORT_H_ diff --git a/include/ceres/local_parameterization.h b/include/ceres/local_parameterization.h index be4fb461d..1931a8981 100644 --- a/include/ceres/local_parameterization.h +++ b/include/ceres/local_parameterization.h @@ -306,6 +306,7 @@ class CERES_EXPORT ProductParameterization : public LocalParameterization { public: ProductParameterization(const ProductParameterization&) = delete; ProductParameterization& operator=(const ProductParameterization&) = delete; + virtual ~ProductParameterization() {} // // NOTE: The constructor takes ownership of the input local // parameterizations. @@ -341,7 +342,8 @@ class CERES_EXPORT ProductParameterization : public LocalParameterization { bool Plus(const double* x, const double* delta, double* x_plus_delta) const override; - bool ComputeJacobian(const double* x, double* jacobian) const override; + bool ComputeJacobian(const double* x, + double* jacobian) const override; int GlobalSize() const override { return global_size_; } int LocalSize() const override { return local_size_; } diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index 1ff92174d..6dc726238 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt @@ -233,6 +233,23 @@ add_library(ceres ${CERES_LIBRARY_SOURCE}) set_target_properties(ceres PROPERTIES VERSION ${CERES_VERSION} SOVERSION ${CERES_VERSION_MAJOR}) +if (BUILD_SHARED_LIBS) + set_target_properties(ceres PROPERTIES + # Set the default symbol visibility to hidden to unify the behavior among + # the various compilers and to get smaller binaries + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden) +endif() + +# When building as a shared libarary with testing enabled, we need to export +# internal symbols needed by the unit tests +if (BUILD_TESTING) + target_compile_definitions(ceres + PUBLIC + CERES_EXPORT_INTERNAL_SYMBOLS + ) +endif() + # The ability to specify a minimum language version via cxx_std_[11,14,17] # requires CMake >= 3.8. Prior to that we have to specify the compiler features diff --git a/internal/ceres/array_utils.h b/internal/ceres/array_utils.h index b068721b6..68feca5e7 100644 --- a/internal/ceres/array_utils.h +++ b/internal/ceres/array_utils.h @@ -52,20 +52,22 @@ namespace internal { // Fill the array x with an impossible value that the user code is // never expected to compute. -void InvalidateArray(int size, double* x); +CERES_EXPORT_INTERNAL void InvalidateArray(int size, double* x); // Check if all the entries of the array x are valid, i.e. all the // values in the array should be finite and none of them should be // equal to the "impossible" value used by InvalidateArray. -bool IsArrayValid(int size, const double* x); +CERES_EXPORT_INTERNAL bool IsArrayValid(int size, const double* x); // If the array contains an invalid value, return the index for it, // otherwise return size. -int FindInvalidValue(const int size, const double* x); +CERES_EXPORT_INTERNAL int FindInvalidValue(const int size, const double* x); // Utility routine to print an array of doubles to a string. If the // array pointer is NULL, it is treated as an array of zeros. -void AppendArrayToString(const int size, const double* x, std::string* result); +CERES_EXPORT_INTERNAL void AppendArrayToString(const int size, + const double* x, + std::string* result); // This routine takes an array of integer values, sorts and uniques // them and then maps each value in the array to its position in the @@ -80,7 +82,7 @@ void AppendArrayToString(const int size, const double* x, std::string* result); // gets mapped to // // [1 0 2 3 0 1 3] -void MapValuesToContiguousRange(int size, int* array); +CERES_EXPORT_INTERNAL void MapValuesToContiguousRange(int size, int* array); } // namespace internal } // namespace ceres diff --git a/internal/ceres/block_jacobi_preconditioner.h b/internal/ceres/block_jacobi_preconditioner.h index 4ede9b9e3..18f749533 100644 --- a/internal/ceres/block_jacobi_preconditioner.h +++ b/internal/ceres/block_jacobi_preconditioner.h @@ -34,6 +34,7 @@ #include #include "ceres/block_random_access_diagonal_matrix.h" +#include "ceres/internal/port.h" #include "ceres/preconditioner.h" namespace ceres { @@ -52,7 +53,8 @@ struct CompressedRowBlockStructure; // update the matrix by running Update(A, D). The values of the matrix A are // inspected to construct the preconditioner. The vector D is applied as the // D^TD diagonal term. -class BlockJacobiPreconditioner : public BlockSparseMatrixPreconditioner { +class CERES_EXPORT_INTERNAL BlockJacobiPreconditioner + : public BlockSparseMatrixPreconditioner { public: // A must remain valid while the BlockJacobiPreconditioner is. explicit BlockJacobiPreconditioner(const BlockSparseMatrix& A); diff --git a/internal/ceres/block_random_access_dense_matrix.h b/internal/ceres/block_random_access_dense_matrix.h index be67f342c..9e5552429 100644 --- a/internal/ceres/block_random_access_dense_matrix.h +++ b/internal/ceres/block_random_access_dense_matrix.h @@ -50,7 +50,8 @@ namespace internal { // pair. // // ReturnCell is a nop. -class BlockRandomAccessDenseMatrix : public BlockRandomAccessMatrix { +class CERES_EXPORT_INTERNAL BlockRandomAccessDenseMatrix + : public BlockRandomAccessMatrix { public: // blocks is a vector of block sizes. The resulting matrix has // blocks.size() * blocks.size() cells. diff --git a/internal/ceres/block_random_access_diagonal_matrix.h b/internal/ceres/block_random_access_diagonal_matrix.h index 4d3e1ccbc..3fe7c1e5b 100644 --- a/internal/ceres/block_random_access_diagonal_matrix.h +++ b/internal/ceres/block_random_access_diagonal_matrix.h @@ -46,7 +46,8 @@ namespace internal { // A thread safe block diagonal matrix implementation of // BlockRandomAccessMatrix. -class BlockRandomAccessDiagonalMatrix : public BlockRandomAccessMatrix { +class CERES_EXPORT_INTERNAL BlockRandomAccessDiagonalMatrix + : public BlockRandomAccessMatrix { public: // blocks is an array of block sizes. explicit BlockRandomAccessDiagonalMatrix(const std::vector& blocks); diff --git a/internal/ceres/block_random_access_matrix.h b/internal/ceres/block_random_access_matrix.h index 6fcf0dc8a..f190622ea 100644 --- a/internal/ceres/block_random_access_matrix.h +++ b/internal/ceres/block_random_access_matrix.h @@ -35,6 +35,8 @@ #include +#include "ceres/internal/port.h" + namespace ceres { namespace internal { @@ -91,7 +93,7 @@ struct CellInfo { std::mutex m; }; -class BlockRandomAccessMatrix { +class CERES_EXPORT_INTERNAL BlockRandomAccessMatrix { public: virtual ~BlockRandomAccessMatrix(); diff --git a/internal/ceres/block_random_access_sparse_matrix.h b/internal/ceres/block_random_access_sparse_matrix.h index ca0416392..0e58bbb6b 100644 --- a/internal/ceres/block_random_access_sparse_matrix.h +++ b/internal/ceres/block_random_access_sparse_matrix.h @@ -51,7 +51,8 @@ namespace internal { // BlockRandomAccessMatrix. Internally a TripletSparseMatrix is used // for doing the actual storage. This class augments this matrix with // an unordered_map that allows random read/write access. -class BlockRandomAccessSparseMatrix : public BlockRandomAccessMatrix { +class CERES_EXPORT_INTERNAL BlockRandomAccessSparseMatrix + : public BlockRandomAccessMatrix { public: // blocks is an array of block sizes. block_pairs is a set of // pairs to identify the non-zero cells diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h index fa9e4ed2d..e5b3634c3 100644 --- a/internal/ceres/block_sparse_matrix.h +++ b/internal/ceres/block_sparse_matrix.h @@ -38,6 +38,7 @@ #include "ceres/block_structure.h" #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/sparse_matrix.h" namespace ceres { @@ -53,7 +54,7 @@ class TripletSparseMatrix; // // internal/ceres/block_structure.h // -class BlockSparseMatrix : public SparseMatrix { +class CERES_EXPORT_INTERNAL BlockSparseMatrix : public SparseMatrix { public: // Construct a block sparse matrix with a fully initialized // CompressedRowBlockStructure objected. The matrix takes over diff --git a/internal/ceres/canonical_views_clustering.h b/internal/ceres/canonical_views_clustering.h index 630adfed7..465233ddf 100644 --- a/internal/ceres/canonical_views_clustering.h +++ b/internal/ceres/canonical_views_clustering.h @@ -45,6 +45,7 @@ #include #include "ceres/graph.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -94,13 +95,13 @@ struct CanonicalViewsClusteringOptions; // It is possible depending on the configuration of the clustering // algorithm that some of the vertices may not be assigned to any // cluster. In this case they are assigned to a cluster with id = -1; -void ComputeCanonicalViewsClustering( +CERES_EXPORT_INTERNAL void ComputeCanonicalViewsClustering( const CanonicalViewsClusteringOptions& options, const WeightedGraph& graph, std::vector* centers, std::unordered_map* membership); -struct CanonicalViewsClusteringOptions { +struct CERES_EXPORT_INTERNAL CanonicalViewsClusteringOptions { // The minimum number of canonical views to compute. int min_views = 3; diff --git a/internal/ceres/compressed_col_sparse_matrix_utils.h b/internal/ceres/compressed_col_sparse_matrix_utils.h index 8e5651960..d442e1a9b 100644 --- a/internal/ceres/compressed_col_sparse_matrix_utils.h +++ b/internal/ceres/compressed_col_sparse_matrix_utils.h @@ -48,7 +48,7 @@ namespace internal { // and column block j, then it is expected that A contains at least // one non-zero entry corresponding to the top left entry of c_ij, // as that entry is used to detect the presence of a non-zero c_ij. -void CompressedColumnScalarMatrixToBlockMatrix( +CERES_EXPORT_INTERNAL void CompressedColumnScalarMatrixToBlockMatrix( const int* scalar_rows, const int* scalar_cols, const std::vector& row_blocks, @@ -59,9 +59,10 @@ void CompressedColumnScalarMatrixToBlockMatrix( // Given a set of blocks and a permutation of these blocks, compute // the corresponding "scalar" ordering, where the scalar ordering of // size sum(blocks). -void BlockOrderingToScalarOrdering(const std::vector& blocks, - const std::vector& block_ordering, - std::vector* scalar_ordering); +CERES_EXPORT_INTERNAL void BlockOrderingToScalarOrdering( + const std::vector& blocks, + const std::vector& block_ordering, + std::vector* scalar_ordering); // Solve the linear system // diff --git a/internal/ceres/compressed_row_sparse_matrix.h b/internal/ceres/compressed_row_sparse_matrix.h index 203c7ea82..0a1b94519 100644 --- a/internal/ceres/compressed_row_sparse_matrix.h +++ b/internal/ceres/compressed_row_sparse_matrix.h @@ -46,7 +46,7 @@ namespace internal { class TripletSparseMatrix; -class CompressedRowSparseMatrix : public SparseMatrix { +class CERES_EXPORT_INTERNAL CompressedRowSparseMatrix : public SparseMatrix { public: enum StorageType { UNSYMMETRIC, diff --git a/internal/ceres/conjugate_gradients_solver.h b/internal/ceres/conjugate_gradients_solver.h index d89383e63..f79ca4965 100644 --- a/internal/ceres/conjugate_gradients_solver.h +++ b/internal/ceres/conjugate_gradients_solver.h @@ -34,6 +34,7 @@ #ifndef CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_ #define CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_ +#include "ceres/internal/port.h" #include "ceres/linear_solver.h" namespace ceres { @@ -54,7 +55,7 @@ class LinearOperator; // For more details see the documentation for // LinearSolver::PerSolveOptions::r_tolerance and // LinearSolver::PerSolveOptions::q_tolerance in linear_solver.h. -class ConjugateGradientsSolver : public LinearSolver { +class CERES_EXPORT_INTERNAL ConjugateGradientsSolver : public LinearSolver { public: explicit ConjugateGradientsSolver(const LinearSolver::Options& options); Summary Solve(LinearOperator* A, diff --git a/internal/ceres/context_impl.h b/internal/ceres/context_impl.h index 90ba344f4..574d1efcc 100644 --- a/internal/ceres/context_impl.h +++ b/internal/ceres/context_impl.h @@ -45,7 +45,7 @@ namespace ceres { namespace internal { -class ContextImpl : public Context { +class CERES_EXPORT_INTERNAL ContextImpl : public Context { public: ContextImpl() {} ContextImpl(const ContextImpl&) = delete; diff --git a/internal/ceres/corrector.h b/internal/ceres/corrector.h index a5b03dda8..3e11cdce1 100644 --- a/internal/ceres/corrector.h +++ b/internal/ceres/corrector.h @@ -35,6 +35,8 @@ #ifndef CERES_INTERNAL_CORRECTOR_H_ #define CERES_INTERNAL_CORRECTOR_H_ +#include "ceres/internal/port.h" + namespace ceres { namespace internal { @@ -46,7 +48,7 @@ namespace internal { // gauss newton approximation and then take its square root to get the // corresponding corrections to the residual and jacobian. For the // full expressions see Eq. 10 and 11 in BANS by Triggs et al. -class Corrector { +class CERES_EXPORT_INTERNAL Corrector { public: // The constructor takes the squared norm, the value, the first and // second derivatives of the LossFunction. It precalculates some of diff --git a/internal/ceres/covariance_impl.h b/internal/ceres/covariance_impl.h index a26763a09..394a04bbc 100644 --- a/internal/ceres/covariance_impl.h +++ b/internal/ceres/covariance_impl.h @@ -38,6 +38,7 @@ #include #include "ceres/covariance.h" +#include "ceres/internal/port.h" #include "ceres/problem_impl.h" #include "ceres/suitesparse.h" @@ -46,7 +47,7 @@ namespace internal { class CompressedRowSparseMatrix; -class CovarianceImpl { +class CERES_EXPORT_INTERNAL CovarianceImpl { public: explicit CovarianceImpl(const Covariance::Options& options); ~CovarianceImpl(); diff --git a/internal/ceres/dense_qr_solver.h b/internal/ceres/dense_qr_solver.h index a30cd1cf4..980243bd6 100644 --- a/internal/ceres/dense_qr_solver.h +++ b/internal/ceres/dense_qr_solver.h @@ -33,6 +33,7 @@ #define CERES_INTERNAL_DENSE_QR_SOLVER_H_ #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/linear_solver.h" namespace ceres { @@ -78,7 +79,7 @@ class DenseSparseMatrix; // library. This solver always returns a solution, it is the user's // responsibility to judge if the solution is good enough for their // purposes. -class DenseQRSolver : public DenseSparseMatrixSolver { +class CERES_EXPORT_INTERNAL DenseQRSolver : public DenseSparseMatrixSolver { public: explicit DenseQRSolver(const LinearSolver::Options& options); diff --git a/internal/ceres/dense_sparse_matrix.h b/internal/ceres/dense_sparse_matrix.h index 34a3be26c..94064b3ed 100644 --- a/internal/ceres/dense_sparse_matrix.h +++ b/internal/ceres/dense_sparse_matrix.h @@ -34,6 +34,7 @@ #define CERES_INTERNAL_DENSE_SPARSE_MATRIX_H_ #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/sparse_matrix.h" #include "ceres/types.h" @@ -42,7 +43,7 @@ namespace internal { class TripletSparseMatrix; -class DenseSparseMatrix : public SparseMatrix { +class CERES_EXPORT_INTERNAL DenseSparseMatrix : public SparseMatrix { public: // Build a matrix with the same content as the TripletSparseMatrix // m. This assumes that m does not have any repeated entries. diff --git a/internal/ceres/detect_structure.h b/internal/ceres/detect_structure.h index 602581c84..06242307c 100644 --- a/internal/ceres/detect_structure.h +++ b/internal/ceres/detect_structure.h @@ -32,6 +32,7 @@ #define CERES_INTERNAL_DETECT_STRUCTURE_H_ #include "ceres/block_structure.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -55,11 +56,11 @@ namespace internal { // Note: The structure of rows without any e-blocks has no effect on // the values returned by this function. It is entirely possible that // the f_block_size and row_blocks_size is not constant in such rows. -void DetectStructure(const CompressedRowBlockStructure& bs, - const int num_eliminate_blocks, - int* row_block_size, - int* e_block_size, - int* f_block_size); +void CERES_EXPORT DetectStructure(const CompressedRowBlockStructure& bs, + const int num_eliminate_blocks, + int* row_block_size, + int* e_block_size, + int* f_block_size); } // namespace internal } // namespace ceres diff --git a/internal/ceres/dogleg_strategy.h b/internal/ceres/dogleg_strategy.h index 9616ffe27..cc3778ea2 100644 --- a/internal/ceres/dogleg_strategy.h +++ b/internal/ceres/dogleg_strategy.h @@ -31,6 +31,7 @@ #ifndef CERES_INTERNAL_DOGLEG_STRATEGY_H_ #define CERES_INTERNAL_DOGLEG_STRATEGY_H_ +#include "ceres/internal/port.h" #include "ceres/linear_solver.h" #include "ceres/trust_region_strategy.h" @@ -52,7 +53,7 @@ namespace internal { // DoglegStrategy follows the approach by Shultz, Schnabel, Byrd. // This finds the exact optimum over the two-dimensional subspace // spanned by the two Dogleg vectors. -class DoglegStrategy : public TrustRegionStrategy { +class CERES_EXPORT_INTERNAL DoglegStrategy : public TrustRegionStrategy { public: explicit DoglegStrategy(const TrustRegionStrategy::Options& options); virtual ~DoglegStrategy() {} diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix.h b/internal/ceres/dynamic_compressed_row_sparse_matrix.h index ad41da7b1..d06c36ebb 100644 --- a/internal/ceres/dynamic_compressed_row_sparse_matrix.h +++ b/internal/ceres/dynamic_compressed_row_sparse_matrix.h @@ -44,11 +44,13 @@ #include #include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { -class DynamicCompressedRowSparseMatrix : public CompressedRowSparseMatrix { +class CERES_EXPORT_INTERNAL DynamicCompressedRowSparseMatrix + : public CompressedRowSparseMatrix { public: // Set the number of rows and columns for the underlyig // `CompressedRowSparseMatrix` and set the initial number of maximum non-zero diff --git a/internal/ceres/evaluator.h b/internal/ceres/evaluator.h index a66844596..9cf42593e 100644 --- a/internal/ceres/evaluator.h +++ b/internal/ceres/evaluator.h @@ -55,7 +55,7 @@ class SparseMatrix; // function that is useful for an optimizer that wants to minimize the least // squares objective. This insulates the optimizer from issues like Jacobian // storage, parameterization, etc. -class Evaluator { +class CERES_EXPORT_INTERNAL Evaluator { public: virtual ~Evaluator(); diff --git a/internal/ceres/evaluator_test_utils.h b/internal/ceres/evaluator_test_utils.h index 7401f0436..d47b6fab4 100644 --- a/internal/ceres/evaluator_test_utils.h +++ b/internal/ceres/evaluator_test_utils.h @@ -31,6 +31,8 @@ // // Test utils used for evaluation testing. +#include "ceres/internal/port.h" + namespace ceres { namespace internal { @@ -45,16 +47,16 @@ struct ExpectedEvaluation { }; // Compare two evaluations. -void CompareEvaluations(int expected_num_rows, - int expected_num_cols, - double expected_cost, - const double* expected_residuals, - const double* expected_gradient, - const double* expected_jacobian, - const double actual_cost, - const double* actual_residuals, - const double* actual_gradient, - const double* actual_jacobian); +CERES_EXPORT_INTERNAL void CompareEvaluations(int expected_num_rows, + int expected_num_cols, + double expected_cost, + const double* expected_residuals, + const double* expected_gradient, + const double* expected_jacobian, + const double actual_cost, + const double* actual_residuals, + const double* actual_gradient, + const double* actual_jacobian); } // namespace internal } // namespace ceres diff --git a/internal/ceres/file.h b/internal/ceres/file.h index 30c022562..c0015df60 100644 --- a/internal/ceres/file.h +++ b/internal/ceres/file.h @@ -46,7 +46,8 @@ void ReadFileToStringOrDie(const std::string& filename, std::string* data); // Join two path components, adding a slash if necessary. If basename is an // absolute path then JoinPath ignores dirname and simply returns basename. -std::string JoinPath(const std::string& dirname, const std::string& basename); +CERES_EXPORT_INTERNAL std::string JoinPath(const std::string& dirname, + const std::string& basename); } // namespace internal } // namespace ceres diff --git a/internal/ceres/function_sample.h b/internal/ceres/function_sample.h index 8889f765f..3bcea1bc5 100644 --- a/internal/ceres/function_sample.h +++ b/internal/ceres/function_sample.h @@ -34,6 +34,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -46,7 +47,7 @@ namespace internal { // line/direction. FunctionSample contains the information in two // ways. Information in the ambient space and information along the // direction of search. -struct FunctionSample { +struct CERES_EXPORT_INTERNAL FunctionSample { FunctionSample(); FunctionSample(double x, double value); FunctionSample(double x, double value, double gradient); diff --git a/internal/ceres/gradient_checking_cost_function.h b/internal/ceres/gradient_checking_cost_function.h index ab6e9f893..ea6e9b31c 100644 --- a/internal/ceres/gradient_checking_cost_function.h +++ b/internal/ceres/gradient_checking_cost_function.h @@ -36,6 +36,7 @@ #include #include "ceres/cost_function.h" +#include "ceres/internal/port.h" #include "ceres/iteration_callback.h" #include "ceres/local_parameterization.h" @@ -46,7 +47,8 @@ class ProblemImpl; // Callback that collects information about gradient checking errors, and // will abort the solve as soon as an error occurs. -class GradientCheckingIterationCallback : public IterationCallback { +class CERES_EXPORT_INTERNAL GradientCheckingIterationCallback + : public IterationCallback { public: GradientCheckingIterationCallback(); @@ -71,7 +73,7 @@ class GradientCheckingIterationCallback : public IterationCallback { // with finite differences. This API is only intended for unit tests that intend // to check the functionality of the GradientCheckingCostFunction // implementation directly. -CostFunction* CreateGradientCheckingCostFunction( +CERES_EXPORT_INTERNAL CostFunction* CreateGradientCheckingCostFunction( const CostFunction* cost_function, const std::vector* local_parameterizations, double relative_step_size, @@ -100,7 +102,7 @@ CostFunction* CreateGradientCheckingCostFunction( // jacobians obtained by numerically differentiating them. See the // documentation of 'numeric_derivative_relative_step_size' in solver.h for a // better explanation. -ProblemImpl* CreateGradientCheckingProblemImpl( +CERES_EXPORT_INTERNAL ProblemImpl* CreateGradientCheckingProblemImpl( ProblemImpl* problem_impl, double relative_step_size, double relative_precision, diff --git a/internal/ceres/implicit_schur_complement.h b/internal/ceres/implicit_schur_complement.h index cc22f24e5..e83892af0 100644 --- a/internal/ceres/implicit_schur_complement.h +++ b/internal/ceres/implicit_schur_complement.h @@ -37,6 +37,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/linear_operator.h" #include "ceres/linear_solver.h" #include "ceres/partitioned_matrix_view.h" @@ -87,7 +88,7 @@ class BlockSparseMatrix; // RightMultiply (and the LeftMultiply) methods are not thread safe as // they depend on mutable arrays used for the temporaries needed to // compute the product y += Sx; -class ImplicitSchurComplement : public LinearOperator { +class CERES_EXPORT_INTERNAL ImplicitSchurComplement : public LinearOperator { public: // num_eliminate_blocks is the number of E blocks in the matrix // A. diff --git a/internal/ceres/inner_product_computer.h b/internal/ceres/inner_product_computer.h index 73073f8ad..04ec1d183 100644 --- a/internal/ceres/inner_product_computer.h +++ b/internal/ceres/inner_product_computer.h @@ -36,6 +36,7 @@ #include "ceres/block_sparse_matrix.h" #include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -60,7 +61,7 @@ namespace internal { // This is not a problem as sparse linear algebra libraries can ignore // these entries with ease and the space used is minimal/linear in the // size of the matrices. -class InnerProductComputer { +class CERES_EXPORT_INTERNAL InnerProductComputer { public: // Factory // diff --git a/internal/ceres/is_close.h b/internal/ceres/is_close.h index d0b5e6b75..b781a4493 100644 --- a/internal/ceres/is_close.h +++ b/internal/ceres/is_close.h @@ -33,6 +33,8 @@ #ifndef CERES_INTERNAL_IS_CLOSE_H_ #define CERES_INTERNAL_IS_CLOSE_H_ +#include "ceres/internal/port.h" + namespace ceres { namespace internal { // Returns true if x and y have a relative (unsigned) difference less than @@ -40,11 +42,11 @@ namespace internal { // difference in relative/absolute_error if non-NULL. If one of the two values // is exactly zero, the absolute difference will be compared, and relative_error // will be set to the absolute difference. -bool IsClose(double x, - double y, - double relative_precision, - double* relative_error, - double* absolute_error); +CERES_EXPORT_INTERNAL bool IsClose(double x, + double y, + double relative_precision, + double* relative_error, + double* absolute_error); } // namespace internal } // namespace ceres diff --git a/internal/ceres/iterative_refiner.h b/internal/ceres/iterative_refiner.h index b2c39b56f..08f8d6762 100644 --- a/internal/ceres/iterative_refiner.h +++ b/internal/ceres/iterative_refiner.h @@ -57,7 +57,7 @@ class SparseMatrix; // Definite linear systems. // // The above iterative loop is run until max_num_iterations is reached. -class IterativeRefiner { +class CERES_EXPORT_INTERNAL IterativeRefiner { public: // max_num_iterations is the number of refinement iterations to // perform. diff --git a/internal/ceres/iterative_schur_complement_solver.h b/internal/ceres/iterative_schur_complement_solver.h index ca002d25c..37606b32d 100644 --- a/internal/ceres/iterative_schur_complement_solver.h +++ b/internal/ceres/iterative_schur_complement_solver.h @@ -34,6 +34,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/linear_solver.h" #include "ceres/types.h" @@ -68,7 +69,8 @@ class Preconditioner; // a proof of this fact and others related to this solver please see // the section on Domain Decomposition Methods in Saad's book // "Iterative Methods for Sparse Linear Systems". -class IterativeSchurComplementSolver : public BlockSparseMatrixSolver { +class CERES_EXPORT_INTERNAL IterativeSchurComplementSolver + : public BlockSparseMatrixSolver { public: explicit IterativeSchurComplementSolver(const LinearSolver::Options& options); IterativeSchurComplementSolver(const IterativeSchurComplementSolver&) = diff --git a/internal/ceres/levenberg_marquardt_strategy.h b/internal/ceres/levenberg_marquardt_strategy.h index 43b0bfdc3..12cd463c1 100644 --- a/internal/ceres/levenberg_marquardt_strategy.h +++ b/internal/ceres/levenberg_marquardt_strategy.h @@ -32,6 +32,7 @@ #define CERES_INTERNAL_LEVENBERG_MARQUARDT_STRATEGY_H_ #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/trust_region_strategy.h" namespace ceres { @@ -42,7 +43,8 @@ namespace internal { // K. Madsen, H.B. Nielsen and O. Tingleff. Available to download from // // http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf -class LevenbergMarquardtStrategy : public TrustRegionStrategy { +class CERES_EXPORT_INTERNAL LevenbergMarquardtStrategy + : public TrustRegionStrategy { public: explicit LevenbergMarquardtStrategy( const TrustRegionStrategy::Options& options); diff --git a/internal/ceres/line_search_preprocessor.h b/internal/ceres/line_search_preprocessor.h index 12ccb53e0..bd426c7f2 100644 --- a/internal/ceres/line_search_preprocessor.h +++ b/internal/ceres/line_search_preprocessor.h @@ -31,12 +31,13 @@ #ifndef CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_ #define CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_ +#include "ceres/internal/port.h" #include "ceres/preprocessor.h" namespace ceres { namespace internal { -class LineSearchPreprocessor : public Preprocessor { +class CERES_EXPORT_INTERNAL LineSearchPreprocessor : public Preprocessor { public: virtual ~LineSearchPreprocessor(); bool Preprocess(const Solver::Options& options, diff --git a/internal/ceres/linear_least_squares_problems.h b/internal/ceres/linear_least_squares_problems.h index 939c2b4dd..cddaa9fd4 100644 --- a/internal/ceres/linear_least_squares_problems.h +++ b/internal/ceres/linear_least_squares_problems.h @@ -43,7 +43,7 @@ namespace internal { // Structure defining a linear least squares problem and if possible // ground truth solutions. To be used by various LinearSolver tests. -struct LinearLeastSquaresProblem { +struct CERES_EXPORT_INTERNAL LinearLeastSquaresProblem { LinearLeastSquaresProblem() : num_eliminate_blocks(0) {} std::unique_ptr A; @@ -60,7 +60,8 @@ struct LinearLeastSquaresProblem { }; // Factories for linear least squares problem. -LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromId(int id); +CERES_EXPORT_INTERNAL LinearLeastSquaresProblem* +CreateLinearLeastSquaresProblemFromId(int id); LinearLeastSquaresProblem* LinearLeastSquaresProblem0(); LinearLeastSquaresProblem* LinearLeastSquaresProblem1(); diff --git a/internal/ceres/linear_operator.h b/internal/ceres/linear_operator.h index 6463fb508..9c59fc39c 100644 --- a/internal/ceres/linear_operator.h +++ b/internal/ceres/linear_operator.h @@ -33,6 +33,7 @@ #ifndef CERES_INTERNAL_LINEAR_OPERATOR_H_ #define CERES_INTERNAL_LINEAR_OPERATOR_H_ +#include "ceres/internal/port.h" #include "ceres/types.h" namespace ceres { @@ -40,7 +41,7 @@ namespace internal { // This is an abstract base class for linear operators. It supports // access to size information and left and right multiply operators. -class LinearOperator { +class CERES_EXPORT_INTERNAL LinearOperator { public: virtual ~LinearOperator(); diff --git a/internal/ceres/linear_solver.h b/internal/ceres/linear_solver.h index 47684e721..49c6527ac 100644 --- a/internal/ceres/linear_solver.h +++ b/internal/ceres/linear_solver.h @@ -45,6 +45,7 @@ #include "ceres/context_impl.h" #include "ceres/dense_sparse_matrix.h" #include "ceres/execution_summary.h" +#include "ceres/internal/port.h" #include "ceres/triplet_sparse_matrix.h" #include "ceres/types.h" #include "glog/logging.h" @@ -100,7 +101,7 @@ class LinearOperator; // The Options struct configures the LinearSolver object for its // lifetime. The PerSolveOptions struct is used to specify options for // a particular Solve call. -class LinearSolver { +class CERES_EXPORT_INTERNAL LinearSolver { public: struct Options { LinearSolverType type = SPARSE_NORMAL_CHOLESKY; diff --git a/internal/ceres/minimizer.h b/internal/ceres/minimizer.h index 69416b38e..246550de7 100644 --- a/internal/ceres/minimizer.h +++ b/internal/ceres/minimizer.h @@ -49,7 +49,7 @@ class CoordinateDescentMinimizer; class LinearSolver; // Interface for non-linear least squares solvers. -class Minimizer { +class CERES_EXPORT_INTERNAL Minimizer { public: // Options struct to control the behaviour of the Minimizer. Please // see solver.h for detailed information about the meaning and diff --git a/internal/ceres/numeric_diff_test_utils.h b/internal/ceres/numeric_diff_test_utils.h index 462553c82..392636e18 100644 --- a/internal/ceres/numeric_diff_test_utils.h +++ b/internal/ceres/numeric_diff_test_utils.h @@ -32,6 +32,7 @@ #define CERES_INTERNAL_NUMERIC_DIFF_TEST_UTILS_H_ #include "ceres/cost_function.h" +#include "ceres/internal/port.h" #include "ceres/sized_cost_function.h" #include "ceres/types.h" @@ -47,7 +48,7 @@ static constexpr unsigned int kRandomSeed = 1234; // y1 = x1'x2 -> dy1/dx1 = x2, dy1/dx2 = x1 // y2 = (x1'x2)^2 -> dy2/dx1 = 2 * x2 * (x1'x2), dy2/dx2 = 2 * x1 * (x1'x2) // y3 = x2'x2 -> dy3/dx1 = 0, dy3/dx2 = 2 * x2 -class EasyFunctor { +class CERES_EXPORT_INTERNAL EasyFunctor { public: bool operator()(const double* x1, const double* x2, double* residuals) const; void ExpectCostFunctionEvaluationIsNearlyCorrect( @@ -71,14 +72,15 @@ class EasyCostFunction : public SizedCostFunction<3, 5, 5> { // // dy1/dx1 = x2 * cos(x1'x2), dy1/dx2 = x1 * cos(x1'x2) // dy2/dx1 = -x2 * exp(-x1'x2 / 10) / 10, dy2/dx2 = -x2 * exp(-x1'x2 / 10) / 10 -class TranscendentalFunctor { +class CERES_EXPORT TranscendentalFunctor { public: bool operator()(const double* x1, const double* x2, double* residuals) const; void ExpectCostFunctionEvaluationIsNearlyCorrect( const CostFunction& cost_function, NumericDiffMethodType method) const; }; -class TranscendentalCostFunction : public SizedCostFunction<2, 5, 5> { +class CERES_EXPORT_INTERNAL TranscendentalCostFunction + : public SizedCostFunction<2, 5, 5> { public: bool Evaluate(double const* const* parameters, double* residuals, @@ -91,7 +93,7 @@ class TranscendentalCostFunction : public SizedCostFunction<2, 5, 5> { }; // y = exp(x), dy/dx = exp(x) -class ExponentialFunctor { +class CERES_EXPORT_INTERNAL ExponentialFunctor { public: bool operator()(const double* x1, double* residuals) const; void ExpectCostFunctionEvaluationIsNearlyCorrect( @@ -113,7 +115,7 @@ class ExponentialCostFunction : public SizedCostFunction<1, 1> { // Test adaptive numeric differentiation by synthetically adding random noise // to a functor. // y = x^2 + [random noise], dy/dx ~ 2x -class RandomizedFunctor { +class CERES_EXPORT_INTERNAL RandomizedFunctor { public: RandomizedFunctor(double noise_factor, unsigned int random_seed) : noise_factor_(noise_factor), random_seed_(random_seed) {} @@ -127,7 +129,8 @@ class RandomizedFunctor { unsigned int random_seed_; }; -class RandomizedCostFunction : public SizedCostFunction<1, 1> { +class CERES_EXPORT_INTERNAL RandomizedCostFunction + : public SizedCostFunction<1, 1> { public: RandomizedCostFunction(double noise_factor, unsigned int random_seed) : functor_(noise_factor, random_seed) {} diff --git a/internal/ceres/parallel_for.h b/internal/ceres/parallel_for.h index 2da2320c1..b64bd3106 100644 --- a/internal/ceres/parallel_for.h +++ b/internal/ceres/parallel_for.h @@ -34,6 +34,7 @@ #include #include "ceres/context_impl.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -45,22 +46,24 @@ int MaxNumThreadsAvailable(); // Execute the function for every element in the range [start, end) with at most // num_threads. It will execute all the work on the calling thread if // num_threads is 1. -void ParallelFor(ContextImpl* context, - int start, - int end, - int num_threads, - const std::function& function); +CERES_EXPORT_INTERNAL void ParallelFor( + ContextImpl* context, + int start, + int end, + int num_threads, + const std::function& function); // Execute the function for every element in the range [start, end) with at most // num_threads. It will execute all the work on the calling thread if // num_threads is 1. Each invocation of function() will be passed a thread_id // in [0, num_threads) that is guaranteed to be distinct from the value passed // to any concurrent execution of function(). -void ParallelFor(ContextImpl* context, - int start, - int end, - int num_threads, - const std::function& function); +CERES_EXPORT_INTERNAL void ParallelFor( + ContextImpl* context, + int start, + int end, + int num_threads, + const std::function& function); } // namespace internal } // namespace ceres diff --git a/internal/ceres/parallel_utils.h b/internal/ceres/parallel_utils.h index 129142822..89d21106d 100644 --- a/internal/ceres/parallel_utils.h +++ b/internal/ceres/parallel_utils.h @@ -31,6 +31,8 @@ #ifndef CERES_INTERNAL_PARALLEL_UTILS_H_ #define CERES_INTERNAL_PARALLEL_UTILS_H_ +#include "ceres/internal/port.h" + namespace ceres { namespace internal { @@ -59,7 +61,10 @@ namespace internal { // }); // which in each iteration will produce i and j satisfying // 0 <= i <= j < n -void LinearIndexToUpperTriangularIndex(int k, int n, int* i, int* j); +CERES_EXPORT_INTERNAL void LinearIndexToUpperTriangularIndex(int k, + int n, + int* i, + int* j); } // namespace internal } // namespace ceres diff --git a/internal/ceres/parameter_block_ordering.h b/internal/ceres/parameter_block_ordering.h index 7b58afd3d..82ab75dc6 100644 --- a/internal/ceres/parameter_block_ordering.h +++ b/internal/ceres/parameter_block_ordering.h @@ -34,6 +34,7 @@ #include #include "ceres/graph.h" +#include "ceres/internal/port.h" #include "ceres/ordered_groups.h" #include "ceres/types.h" @@ -56,33 +57,34 @@ class ParameterBlock; // ordering = [independent set, // complement of the independent set, // fixed blocks] -int ComputeSchurOrdering(const Program& program, - std::vector* ordering); +CERES_EXPORT_INTERNAL int ComputeSchurOrdering( + const Program& program, std::vector* ordering); // Same as above, except that ties while computing the independent set // ordering are resolved in favour of the order in which the parameter // blocks occur in the program. -int ComputeStableSchurOrdering(const Program& program, - std::vector* ordering); +CERES_EXPORT_INTERNAL int ComputeStableSchurOrdering( + const Program& program, std::vector* ordering); // Use an approximate independent set ordering to decompose the // parameter blocks of a problem in a sequence of independent // sets. The ordering covers all the non-constant parameter blocks in // the program. -void ComputeRecursiveIndependentSetOrdering(const Program& program, - ParameterBlockOrdering* ordering); +CERES_EXPORT_INTERNAL void ComputeRecursiveIndependentSetOrdering( + const Program& program, ParameterBlockOrdering* ordering); // Builds a graph on the parameter blocks of a Problem, whose // structure reflects the sparsity structure of the Hessian. Each // vertex corresponds to a parameter block in the Problem except for // parameter blocks that are marked constant. An edge connects two // parameter blocks, if they co-occur in a residual block. -Graph* CreateHessianGraph(const Program& program); +CERES_EXPORT_INTERNAL Graph* CreateHessianGraph( + const Program& program); // Iterate over each of the groups in order of their priority and fill // summary with their sizes. -void OrderingToGroupSizes(const ParameterBlockOrdering* ordering, - std::vector* group_sizes); +CERES_EXPORT_INTERNAL void OrderingToGroupSizes( + const ParameterBlockOrdering* ordering, std::vector* group_sizes); } // namespace internal } // namespace ceres diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h index b8ac3b202..9f204ee1f 100644 --- a/internal/ceres/partitioned_matrix_view.h +++ b/internal/ceres/partitioned_matrix_view.h @@ -42,6 +42,7 @@ #include "ceres/block_structure.h" #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/linear_solver.h" #include "ceres/small_blas.h" #include "glog/logging.h" @@ -59,7 +60,7 @@ namespace internal { // block structure of the matrix does not satisfy the requirements of // the Schur complement solver it will result in unpredictable and // wrong output. -class PartitionedMatrixViewBase { +class CERES_EXPORT_INTERNAL PartitionedMatrixViewBase { public: virtual ~PartitionedMatrixViewBase() {} diff --git a/internal/ceres/polynomial.h b/internal/ceres/polynomial.h index 40e415044..20071f2c6 100644 --- a/internal/ceres/polynomial.h +++ b/internal/ceres/polynomial.h @@ -66,13 +66,13 @@ inline double EvaluatePolynomial(const Vector& polynomial, double x) { // On failure, a more detailed message will be written to LOG(ERROR). // If real is not NULL, the real parts of the roots will be returned in it. // Likewise, if imaginary is not NULL, imaginary parts will be returned in it. -bool FindPolynomialRoots(const Vector& polynomial, - Vector* real, - Vector* imaginary); +CERES_EXPORT_INTERNAL bool FindPolynomialRoots(const Vector& polynomial, + Vector* real, + Vector* imaginary); // Return the derivative of the given polynomial. It is assumed that // the input polynomial is at least of degree zero. -Vector DifferentiatePolynomial(const Vector& polynomial); +CERES_EXPORT_INTERNAL Vector DifferentiatePolynomial(const Vector& polynomial); // Find the minimum value of the polynomial in the interval [x_min, // x_max]. The minimum is obtained by computing all the roots of the @@ -80,11 +80,11 @@ Vector DifferentiatePolynomial(const Vector& polynomial); // interval [x_min, x_max] are considered as well as the end points // x_min and x_max. Since polynomials are differentiable functions, // this ensures that the true minimum is found. -void MinimizePolynomial(const Vector& polynomial, - double x_min, - double x_max, - double* optimal_x, - double* optimal_value); +CERES_EXPORT_INTERNAL void MinimizePolynomial(const Vector& polynomial, + double x_min, + double x_max, + double* optimal_x, + double* optimal_value); // Given a set of function value and/or gradient samples, find a // polynomial whose value and gradients are exactly equal to the ones @@ -97,7 +97,8 @@ void MinimizePolynomial(const Vector& polynomial, // Of course its possible to sample a polynomial any number of times, // in which case, generally speaking the spurious higher order // coefficients will be zero. -Vector FindInterpolatingPolynomial(const std::vector& samples); +CERES_EXPORT_INTERNAL Vector +FindInterpolatingPolynomial(const std::vector& samples); // Interpolate the function described by samples with a polynomial, // and minimize it on the interval [x_min, x_max]. Depending on the @@ -105,11 +106,12 @@ Vector FindInterpolatingPolynomial(const std::vector& samples); // finding algorithms may fail due to numerical difficulties. But the // function is guaranteed to return its best guess of an answer, by // considering the samples and the end points as possible solutions. -void MinimizeInterpolatingPolynomial(const std::vector& samples, - double x_min, - double x_max, - double* optimal_x, - double* optimal_value); +CERES_EXPORT_INTERNAL void MinimizeInterpolatingPolynomial( + const std::vector& samples, + double x_min, + double x_max, + double* optimal_x, + double* optimal_value); } // namespace internal } // namespace ceres diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h index b10364b90..dd843b01c 100644 --- a/internal/ceres/preconditioner.h +++ b/internal/ceres/preconditioner.h @@ -36,6 +36,7 @@ #include "ceres/casts.h" #include "ceres/compressed_row_sparse_matrix.h" #include "ceres/context_impl.h" +#include "ceres/internal/port.h" #include "ceres/linear_operator.h" #include "ceres/sparse_matrix.h" #include "ceres/types.h" @@ -46,7 +47,7 @@ namespace internal { class BlockSparseMatrix; class SparseMatrix; -class Preconditioner : public LinearOperator { +class CERES_EXPORT_INTERNAL Preconditioner : public LinearOperator { public: struct Options { PreconditionerType type = JACOBI; diff --git a/internal/ceres/preprocessor.h b/internal/ceres/preprocessor.h index e69c79040..ec56c6e43 100644 --- a/internal/ceres/preprocessor.h +++ b/internal/ceres/preprocessor.h @@ -67,7 +67,7 @@ struct PreprocessedProblem; // // The output of the Preprocessor is stored in a PreprocessedProblem // object. -class Preprocessor { +class CERES_EXPORT_INTERNAL Preprocessor { public: // Factory. static Preprocessor* Create(MinimizerType minimizer_type); diff --git a/internal/ceres/problem_impl.h b/internal/ceres/problem_impl.h index 004918a5c..9abff3f19 100644 --- a/internal/ceres/problem_impl.h +++ b/internal/ceres/problem_impl.h @@ -63,7 +63,7 @@ namespace internal { class Program; class ResidualBlock; -class ProblemImpl { +class CERES_EXPORT_INTERNAL ProblemImpl { public: typedef std::map ParameterMap; typedef std::unordered_set ResidualBlockSet; diff --git a/internal/ceres/program.h b/internal/ceres/program.h index c4935e36a..ca29d3162 100644 --- a/internal/ceres/program.h +++ b/internal/ceres/program.h @@ -57,7 +57,7 @@ class TripletSparseMatrix; // another; for example, the first stage of solving involves stripping all // constant parameters and residuals. This is in contrast with Problem, which is // not built for transformation. -class Program { +class CERES_EXPORT_INTERNAL Program { public: Program(); explicit Program(const Program& program); diff --git a/internal/ceres/reorder_program.h b/internal/ceres/reorder_program.h index e32079c16..2e0c32643 100644 --- a/internal/ceres/reorder_program.h +++ b/internal/ceres/reorder_program.h @@ -44,17 +44,17 @@ namespace internal { class Program; // Reorder the parameter blocks in program using the ordering -bool ApplyOrdering(const ProblemImpl::ParameterMap& parameter_map, - const ParameterBlockOrdering& ordering, - Program* program, - std::string* error); +CERES_EXPORT_INTERNAL bool ApplyOrdering( + const ProblemImpl::ParameterMap& parameter_map, + const ParameterBlockOrdering& ordering, + Program* program, + std::string* error); // Reorder the residuals for program, if necessary, so that the residuals // involving each E block occur together. This is a necessary condition for the // Schur eliminator, which works on these "row blocks" in the jacobian. -bool LexicographicallyOrderResidualBlocks(int size_of_first_elimination_group, - Program* program, - std::string* error); +CERES_EXPORT_INTERNAL bool LexicographicallyOrderResidualBlocks( + int size_of_first_elimination_group, Program* program, std::string* error); // Schur type solvers require that all parameter blocks eliminated // by the Schur eliminator occur before others and the residuals be @@ -72,7 +72,7 @@ bool LexicographicallyOrderResidualBlocks(int size_of_first_elimination_group, // // Upon return, ordering contains the parameter block ordering that // was used to order the program. -bool ReorderProgramForSchurTypeLinearSolver( +CERES_EXPORT_INTERNAL bool ReorderProgramForSchurTypeLinearSolver( LinearSolverType linear_solver_type, SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type, const ProblemImpl::ParameterMap& parameter_map, @@ -90,7 +90,7 @@ bool ReorderProgramForSchurTypeLinearSolver( // fill-reducing ordering is available in the sparse linear algebra // library (SuiteSparse version >= 4.2.0) then the fill reducing // ordering will take it into account, otherwise it will be ignored. -bool ReorderProgramForSparseCholesky( +CERES_EXPORT_INTERNAL bool ReorderProgramForSparseCholesky( SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type, const ParameterBlockOrdering& parameter_block_ordering, int start_row_block, @@ -107,7 +107,7 @@ bool ReorderProgramForSparseCholesky( // bottom_residual_blocks.size() because we allow // bottom_residual_blocks to contain residual blocks not present in // the Program. -int ReorderResidualBlocksByPartition( +CERES_EXPORT_INTERNAL int ReorderResidualBlocksByPartition( const std::unordered_set& bottom_residual_blocks, Program* program); diff --git a/internal/ceres/residual_block.h b/internal/ceres/residual_block.h index 3d753396e..f28fd4285 100644 --- a/internal/ceres/residual_block.h +++ b/internal/ceres/residual_block.h @@ -65,7 +65,7 @@ class ParameterBlock; // // The residual block stores pointers to but does not own the cost functions, // loss functions, and parameter blocks. -class ResidualBlock { +class CERES_EXPORT_INTERNAL ResidualBlock { public: // Construct the residual block with the given cost/loss functions. Loss may // be null. The index is the index of the residual block in the Program's diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h index 464af09b8..3bfa22f22 100644 --- a/internal/ceres/schur_complement_solver.h +++ b/internal/ceres/schur_complement_solver.h @@ -107,7 +107,8 @@ class SparseCholesky; // set to DENSE_SCHUR and SPARSE_SCHUR // respectively. LinearSolver::Options::elimination_groups[0] should // be at least 1. -class SchurComplementSolver : public BlockSparseMatrixSolver { +class CERES_EXPORT_INTERNAL SchurComplementSolver + : public BlockSparseMatrixSolver { public: explicit SchurComplementSolver(const LinearSolver::Options& options) : options_(options) { diff --git a/internal/ceres/schur_eliminator.h b/internal/ceres/schur_eliminator.h index 66fcb4d58..42c016ee9 100644 --- a/internal/ceres/schur_eliminator.h +++ b/internal/ceres/schur_eliminator.h @@ -164,7 +164,7 @@ namespace internal { // 2008 for an example of such use]. // // Example usage: Please see schur_complement_solver.cc -class SchurEliminatorBase { +class CERES_EXPORT_INTERNAL SchurEliminatorBase { public: virtual ~SchurEliminatorBase() {} diff --git a/internal/ceres/single_linkage_clustering.h b/internal/ceres/single_linkage_clustering.h index ef6bff4e1..e891a9eec 100644 --- a/internal/ceres/single_linkage_clustering.h +++ b/internal/ceres/single_linkage_clustering.h @@ -34,6 +34,7 @@ #include #include "ceres/graph.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -54,10 +55,10 @@ struct SingleLinkageClusteringOptions { // // The return value of this function is the number of clusters // identified by the algorithm. -int ComputeSingleLinkageClustering( - const SingleLinkageClusteringOptions& options, - const WeightedGraph& graph, - std::unordered_map* membership); +int CERES_EXPORT_INTERNAL +ComputeSingleLinkageClustering(const SingleLinkageClusteringOptions& options, + const WeightedGraph& graph, + std::unordered_map* membership); } // namespace internal } // namespace ceres diff --git a/internal/ceres/sparse_cholesky.h b/internal/ceres/sparse_cholesky.h index 9be98bdba..a6af6b2c2 100644 --- a/internal/ceres/sparse_cholesky.h +++ b/internal/ceres/sparse_cholesky.h @@ -67,7 +67,7 @@ namespace internal { // CHECK_EQ(sparse_cholesky->Solve(rhs.data(), solution.data(), &message), // LINEAR_SOLVER_SUCCESS); -class SparseCholesky { +class CERES_EXPORT_INTERNAL SparseCholesky { public: static std::unique_ptr Create( const LinearSolver::Options& options); @@ -115,7 +115,7 @@ class IterativeRefiner; // Computes an initial solution using the given instance of // SparseCholesky, and then refines it using the IterativeRefiner. -class RefinedSparseCholesky : public SparseCholesky { +class CERES_EXPORT_INTERNAL RefinedSparseCholesky : public SparseCholesky { public: RefinedSparseCholesky(std::unique_ptr sparse_cholesky, std::unique_ptr iterative_refiner); diff --git a/internal/ceres/sparse_matrix.h b/internal/ceres/sparse_matrix.h index b8a3918bd..b57f10890 100644 --- a/internal/ceres/sparse_matrix.h +++ b/internal/ceres/sparse_matrix.h @@ -36,6 +36,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/linear_operator.h" #include "ceres/types.h" @@ -63,7 +64,7 @@ namespace internal { // matrix type dependent and we are at this stage unable to come up // with an efficient high level interface that spans multiple sparse // matrix types. -class SparseMatrix : public LinearOperator { +class CERES_EXPORT_INTERNAL SparseMatrix : public LinearOperator { public: virtual ~SparseMatrix(); diff --git a/internal/ceres/stringprintf.h b/internal/ceres/stringprintf.h index 98e98cd23..4d5127849 100644 --- a/internal/ceres/stringprintf.h +++ b/internal/ceres/stringprintf.h @@ -63,25 +63,28 @@ namespace internal { #endif // Return a C++ string. -extern std::string StringPrintf(const char* format, ...) +CERES_EXPORT_INTERNAL extern std::string StringPrintf(const char* format, ...) // Tell the compiler to do printf format string checking. CERES_PRINTF_ATTRIBUTE(1, 2); // Store result into a supplied string and return it. -extern const std::string& SStringPrintf(std::string* dst, - const char* format, - ...) +CERES_EXPORT_INTERNAL extern const std::string& SStringPrintf( + std::string* dst, const char* format, ...) // Tell the compiler to do printf format string checking. CERES_PRINTF_ATTRIBUTE(2, 3); // Append result to a supplied string. -extern void StringAppendF(std::string* dst, const char* format, ...) +CERES_EXPORT_INTERNAL extern void StringAppendF(std::string* dst, + const char* format, + ...) // Tell the compiler to do printf format string checking. CERES_PRINTF_ATTRIBUTE(2, 3); // Lower-level routine that takes a va_list and appends to a specified string. // All other routines are just convenience wrappers around it. -extern void StringAppendV(std::string* dst, const char* format, va_list ap); +CERES_EXPORT_INTERNAL extern void StringAppendV(std::string* dst, + const char* format, + va_list ap); #undef CERES_PRINTF_ATTRIBUTE diff --git a/internal/ceres/subset_preconditioner.h b/internal/ceres/subset_preconditioner.h index f83153c30..9844a669f 100644 --- a/internal/ceres/subset_preconditioner.h +++ b/internal/ceres/subset_preconditioner.h @@ -33,6 +33,7 @@ #include +#include "ceres/internal/port.h" #include "ceres/preconditioner.h" namespace ceres { @@ -66,7 +67,8 @@ class InnerProductComputer; // computationally expensive this preconditioner will be. // // See the tests for example usage. -class SubsetPreconditioner : public BlockSparseMatrixPreconditioner { +class CERES_EXPORT_INTERNAL SubsetPreconditioner + : public BlockSparseMatrixPreconditioner { public: SubsetPreconditioner(const Preconditioner::Options& options, const BlockSparseMatrix& A); diff --git a/internal/ceres/test_util.h b/internal/ceres/test_util.h index ad9822833..c33c69cd0 100644 --- a/internal/ceres/test_util.h +++ b/internal/ceres/test_util.h @@ -48,15 +48,17 @@ namespace internal { // // If x and y have the same non-finite value (inf or nan) we treat them as being // close. In such a case no error is thrown and true is returned. -bool ExpectClose(double x, double y, double max_abs_relative_difference); +CERES_EXPORT_INTERNAL bool ExpectClose(double x, + double y, + double max_abs_relative_difference); // Expects that for all i = 1,.., n - 1 // // |p[i] - q[i]| / max(|p[i]|, |q[i]|) < tolerance -void ExpectArraysClose(int n, - const double* p, - const double* q, - double tolerance); +CERES_EXPORT_INTERNAL void ExpectArraysClose(int n, + const double* p, + const double* q, + double tolerance); // Expects that for all i = 1,.., n - 1 // @@ -64,16 +66,17 @@ void ExpectArraysClose(int n, // // where max_norm_p and max_norm_q are the max norms of the arrays p // and q respectively. -void ExpectArraysCloseUptoScale(int n, - const double* p, - const double* q, - double tolerance); +CERES_EXPORT_INTERNAL void ExpectArraysCloseUptoScale(int n, + const double* p, + const double* q, + double tolerance); // Construct a fully qualified path for the test file depending on the // local build/testing environment. -std::string TestFileAbsolutePath(const std::string& filename); +CERES_EXPORT_INTERNAL std::string TestFileAbsolutePath( + const std::string& filename); -std::string ToString(const Solver::Options& options); +CERES_EXPORT_INTERNAL std::string ToString(const Solver::Options& options); // A templated test fixture, that is used for testing Ceres end to end // by computing a solution to the problem for a given solver diff --git a/internal/ceres/thread_pool.h b/internal/ceres/thread_pool.h index 1ebb52eb6..cdf6625e1 100644 --- a/internal/ceres/thread_pool.h +++ b/internal/ceres/thread_pool.h @@ -37,6 +37,7 @@ #include #include "ceres/concurrent_queue.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -57,7 +58,7 @@ namespace internal { // workers to stop. The workers will finish all of the tasks that have already // been added to the thread pool. // -class ThreadPool { +class CERES_EXPORT_INTERNAL ThreadPool { public: // Returns the maximum number of hardware threads. static int MaxNumThreadsAvailable(); diff --git a/internal/ceres/triplet_sparse_matrix.h b/internal/ceres/triplet_sparse_matrix.h index cbda2530e..cc9fee572 100644 --- a/internal/ceres/triplet_sparse_matrix.h +++ b/internal/ceres/triplet_sparse_matrix.h @@ -35,6 +35,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/sparse_matrix.h" #include "ceres/types.h" @@ -45,7 +46,7 @@ namespace internal { // manipulate sparse matrices in triplet (i,j,s) form. This object is // inspired by the design of the cholmod_triplet struct used in the // SuiteSparse package and is memory layout compatible with it. -class TripletSparseMatrix : public SparseMatrix { +class CERES_EXPORT_INTERNAL TripletSparseMatrix : public SparseMatrix { public: TripletSparseMatrix(); TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros); diff --git a/internal/ceres/trust_region_minimizer.h b/internal/ceres/trust_region_minimizer.h index 27a1b7848..be4d40653 100644 --- a/internal/ceres/trust_region_minimizer.h +++ b/internal/ceres/trust_region_minimizer.h @@ -34,6 +34,7 @@ #include #include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" #include "ceres/minimizer.h" #include "ceres/solver.h" #include "ceres/sparse_matrix.h" @@ -47,7 +48,7 @@ namespace internal { // Generic trust region minimization algorithm. // // For example usage, see SolverImpl::Minimize. -class TrustRegionMinimizer : public Minimizer { +class CERES_EXPORT_INTERNAL TrustRegionMinimizer : public Minimizer { public: ~TrustRegionMinimizer(); diff --git a/internal/ceres/trust_region_preprocessor.h b/internal/ceres/trust_region_preprocessor.h index 9597905ae..2655abe4b 100644 --- a/internal/ceres/trust_region_preprocessor.h +++ b/internal/ceres/trust_region_preprocessor.h @@ -31,12 +31,13 @@ #ifndef CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_ #define CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_ +#include "ceres/internal/port.h" #include "ceres/preprocessor.h" namespace ceres { namespace internal { -class TrustRegionPreprocessor : public Preprocessor { +class CERES_EXPORT_INTERNAL TrustRegionPreprocessor : public Preprocessor { public: virtual ~TrustRegionPreprocessor(); bool Preprocess(const Solver::Options& options, diff --git a/internal/ceres/trust_region_strategy.h b/internal/ceres/trust_region_strategy.h index 48e734750..176f73a48 100644 --- a/internal/ceres/trust_region_strategy.h +++ b/internal/ceres/trust_region_strategy.h @@ -54,7 +54,7 @@ class SparseMatrix; // the LevenbergMarquardtStrategy uses the inverse of the trust region // radius to scale the damping term, which controls the step size, but // does not set a hard limit on its size. -class TrustRegionStrategy { +class CERES_EXPORT_INTERNAL TrustRegionStrategy { public: struct Options { TrustRegionStrategyType trust_region_strategy_type = LEVENBERG_MARQUARDT; diff --git a/internal/ceres/visibility.h b/internal/ceres/visibility.h index ed25d53e9..68c6723fa 100644 --- a/internal/ceres/visibility.h +++ b/internal/ceres/visibility.h @@ -39,6 +39,7 @@ #include #include "ceres/graph.h" +#include "ceres/internal/port.h" namespace ceres { namespace internal { @@ -53,9 +54,10 @@ struct CompressedRowBlockStructure; // // In a structure from motion problem, e_blocks correspond to 3D // points and f_blocks correspond to cameras. -void ComputeVisibility(const CompressedRowBlockStructure& block_structure, - int num_eliminate_blocks, - std::vector>* visibility); +CERES_EXPORT_INTERNAL void ComputeVisibility( + const CompressedRowBlockStructure& block_structure, + int num_eliminate_blocks, + std::vector>* visibility); // Given f_block visibility as computed by the ComputeVisibility // function above, construct and return a graph whose vertices are @@ -70,7 +72,7 @@ void ComputeVisibility(const CompressedRowBlockStructure& block_structure, // // Caller acquires ownership of the returned WeightedGraph pointer // (heap-allocated). -WeightedGraph* CreateSchurComplementGraph( +CERES_EXPORT_INTERNAL WeightedGraph* CreateSchurComplementGraph( const std::vector>& visibility); } // namespace internal diff --git a/internal/ceres/wall_time.h b/internal/ceres/wall_time.h index 3f465e8b6..9c92e9e60 100644 --- a/internal/ceres/wall_time.h +++ b/internal/ceres/wall_time.h @@ -45,7 +45,7 @@ namespace internal { // OpenMP is available then the high precision openmp_get_wtime() // function is used. Otherwise on unixes, gettimeofday is used. The // granularity is in seconds on windows systems. -double WallTimeInSeconds(); +CERES_EXPORT_INTERNAL double WallTimeInSeconds(); // Log a series of events, recording for each event the time elapsed // since the last event and since the creation of the object.