From 0054585334b1d280c3481237bce8c57e01e889b7 Mon Sep 17 00:00:00 2001 From: Stefano Date: Wed, 5 Feb 2020 17:02:15 +0100 Subject: [PATCH 1/3] Removed deprecated methods. This should help in removing warnings about deprecation without the need to change any of the user code. --- include/OsqpEigen/Data.hpp | 56 ------- include/OsqpEigen/Data.tpp | 120 +-------------- include/OsqpEigen/Solver.hpp | 79 ---------- include/OsqpEigen/Solver.tpp | 280 ----------------------------------- 4 files changed, 3 insertions(+), 532 deletions(-) diff --git a/include/OsqpEigen/Data.hpp b/include/OsqpEigen/Data.hpp index c1a6d95..1978aa0 100644 --- a/include/OsqpEigen/Data.hpp +++ b/include/OsqpEigen/Data.hpp @@ -76,16 +76,6 @@ namespace OsqpEigen */ void setNumberOfConstraints(int m); - /** - * Set the quadratic part of the cost function (Hessian). - * It is assumed to be a simmetric matrix. - * @param hessianMatrix is the Hessian matrix. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use setHessianMatrix(const Eigen::SparseCompressedBase &hessianMatrix) instead")]] - bool setHessianMatrix(const Eigen::SparseMatrix &hessianMatrix); - /** * Set the quadratic part of the cost function (Hessian). * It is assumed to be a simmetric matrix. @@ -95,19 +85,6 @@ namespace OsqpEigen template bool setHessianMatrix(const Eigen::SparseCompressedBase &hessianMatrix); - - /** - * Set the linear part of the cost function (Gradient). - * @param gradientVector is the Gradient vector. - * @note the elements of the gradient are not copied inside the library. - * The user has to guarantee that the lifetime of the object passed is the same of the - * OsqpEigen object - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use setGradient(Eigen::Ref> gradientVector) instead")]] - bool setGradient(Eigen::Matrix &gradientVector); - /** * Set the linear part of the cost function (Gradient). * @param gradientVector is the Gradient vector. @@ -118,15 +95,6 @@ namespace OsqpEigen */ bool setGradient(Eigen::Ref> gradientVector); - /** - * Set the linear constraint matrix A (size m x n) - * @param linearConstraintsMatrix is the linear constraints matrix A. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use setLinearConstraintsMatrix(const Eigen::SparseCompressedBase &linearConstraintsMatrix) instead")]] - bool setLinearConstraintsMatrix(const Eigen::SparseMatrix &linearConstraintsMatrix); - /** * Set the linear constraint matrix A (size m x n) * @param linearConstraintsMatrix is the linear constraints matrix A. @@ -135,18 +103,6 @@ namespace OsqpEigen template bool setLinearConstraintsMatrix(const Eigen::SparseCompressedBase &linearConstraintsMatrix); - /** - * Set the array for lower bound (size m). - * @param lowerBoundVector is the lower bound constraint. - * @note the elements of the lowerBoundVector are not copied inside the library. - * The user has to guarantee that the lifetime of the object passed is the same of the - * OsqpEigen object - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use setLowerBound(Eigen::Ref> lowerBoundVector) instead")]] - bool setLowerBound(Eigen::Matrix& lowerBoundVector); - /** * Set the array for lower bound (size m). * @param lowerBoundVector is the lower bound constraint. @@ -157,18 +113,6 @@ namespace OsqpEigen */ bool setLowerBound(Eigen::Ref> lowerBoundVector); - /** - * Set the array for upper bound (size m). - * @param upperBoundVector is the upper bound constraint. - * @note the elements of the upperBoundVector are not copied inside the library. - * The user has to guarantee that the lifetime of the object passed is the same of the - * OsqpEigen object. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use setUpperBound(Eigen::Ref> upperBoundVector) instead")]] - bool setUpperBound(Eigen::Matrix& upperBoundVector); - /** * Set the array for upper bound (size m). * @param upperBoundVector is the upper bound constraint. diff --git a/include/OsqpEigen/Data.tpp b/include/OsqpEigen/Data.tpp index ac18340..bd0b81d 100644 --- a/include/OsqpEigen/Data.tpp +++ b/include/OsqpEigen/Data.tpp @@ -7,42 +7,6 @@ #include -template -bool OsqpEigen::Data::setHessianMatrix(const Eigen::SparseMatrix &hessianMatrix) -{ - if(m_isHessianMatrixSet){ - std::cerr << "[OsqpEigen::Data::setHessianMatrix] The hessian matrix was already set. " - << "Please use clearHessianMatrix() method to deallocate memory." - << std::endl; - return false; - } - - if(!m_isNumberOfVariablesSet){ - std::cerr << "[OsqpEigen::Data::setHessianMatrix] Please set the number of variables before " - << "add the hessian matrix." - << std::endl; - return false; - } - - // check if the number of row and columns are equal to the number of the optimization variables - if ((hessianMatrix.rows() != m_data->n) || (hessianMatrix.cols()!= m_data->n)){ - std::cerr << "[OsqpEigen::Data::setHessianMatrix] The Hessian matrix has to be a n x n size matrix." - << std::endl; - return false; - } - - //set the hessian matrix - // osqp 0.6.0 required only the upper triangular part of the hessian matrix - Eigen::SparseMatrix hessianMatrixUpperTriangular = hessianMatrix.template triangularView(); - if(!OsqpEigen::SparseMatrixHelper::createOsqpSparseMatrix(hessianMatrixUpperTriangular, m_data->P)){ - std::cerr << "[OsqpEigen::Data::setHessianMatrix] Unable to instantiate the osqp sparse matrix." - << std::endl; - return false; - } - m_isHessianMatrixSet = true; - return true; -} - template bool OsqpEigen::Data::setHessianMatrix(const Eigen::SparseCompressedBase &hessianMatrix) { @@ -68,7 +32,9 @@ bool OsqpEigen::Data::setHessianMatrix(const Eigen::SparseCompressedBaseP)){ + // osqp 0.6.0 required only the upper triangular part of the hessian matrix + Derived hessianMatrixUpperTriangular = hessianMatrix.template triangularView(); + if(!OsqpEigen::SparseMatrixHelper::createOsqpSparseMatrix(hessianMatrixUpperTriangular, m_data->P)){ std::cerr << "[OsqpEigen::Data::setHessianMatrix] Unable to instantiate the osqp sparse matrix." << std::endl; return false; @@ -117,83 +83,3 @@ bool OsqpEigen::Data::setLinearConstraintsMatrix(const Eigen::SparseCompressedBa return true; } - -template -bool OsqpEigen::Data::setGradient(Eigen::Matrix& gradient) -{ - if(gradient.rows() != m_data->n){ - std::cerr << "[OsqpEigen::Data::setGradient] The size of the gradient must be equal to the number of the variables." - << std::endl; - return false; - } - m_isGradientSet = true; - m_data->q = gradient.data(); - return true; -} - -template -bool OsqpEigen::Data::setLinearConstraintsMatrix(const Eigen::SparseMatrix &linearConstraintsMatrix) - { - if(m_isLinearConstraintsMatrixSet){ - std::cerr << "[OsqpEigen::Data::setLinearConstraintsMatrix] The linear constraint matrix was already set. " - << "Please use clearLinearConstraintsMatrix() method to deallocate memory." - << std::endl; - return false; - } - - if(!m_isNumberOfConstraintsSet){ - std::cerr << "[OsqpEigen::Data::setLinearConstraintsMatrix] Please set the number of constraints before add the constraint matrix." - << std::endl; - return false; - } - - if(!m_isNumberOfVariablesSet){ - std::cerr << "[OsqpEigen::Data::setLinearConstraintsMatrix] Please set the number of variables before add the constraint matrix." - << std::endl; - return false; - } - - if ((linearConstraintsMatrix.rows() != m_data->m) || (linearConstraintsMatrix.cols()!= m_data->n)){ - std::cerr << "[OsqpEigen::Data::setLinearConstraintsMatrix] The Linear constraints matrix has to be a m x n size matrix." - << std::endl; - return false; - } - - // set the hessian matrix - if(!OsqpEigen::SparseMatrixHelper::createOsqpSparseMatrix(linearConstraintsMatrix, - m_data->A)){ - std::cerr << "[OsqpEigen::Data::setLinearConstraintsMatrix] osqp sparse matrix not created." - << std::endl; - return false; - } - - m_isLinearConstraintsMatrixSet = true; - - return true; -} - -template -bool OsqpEigen::Data::setLowerBound(Eigen::Matrix& lowerBound) -{ - if(lowerBound.rows() != m_data->m){ - std::cerr << "[OsqpEigen::Data::setLowerBound] The size of the lower bound must be equal to the number of the variables." - << std::endl; - return false; - } - m_isLowerBoundSet = true; - m_data->l = lowerBound.data(); - return true; -} - -template -bool OsqpEigen::Data::setUpperBound(Eigen::Matrix& upperBound) -{ - if(upperBound.rows() != m_data->m){ - std::cerr << "[OsqpEigen::Data::setLowerBound] The size of the upper bound must be equal to the number of the variables." - << std::endl; - return false; - } - m_isUpperBoundSet = true; - m_data->u = upperBound.data(); - return true; -} diff --git a/include/OsqpEigen/Solver.hpp b/include/OsqpEigen/Solver.hpp index ff715ea..8875ba3 100644 --- a/include/OsqpEigen/Solver.hpp +++ b/include/OsqpEigen/Solver.hpp @@ -123,18 +123,6 @@ namespace OsqpEigen */ const Eigen::VectorXd &getSolution(); - /** - * Update the linear part of the cost function (Gradient). - * @param gradient is the Gradient vector. - * @note the elements of the gradient are not copied inside the library. - * The user has to guarantee that the lifetime of the objects passed is the same of the - * OsqpEigen object. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateGradient(const Eigen::Ref>& gradient) instead")]] - bool updateGradient(Eigen::Matrix& gradient); - /** * Update the linear part of the cost function (Gradient). * @param gradient is the Gradient vector. @@ -145,18 +133,6 @@ namespace OsqpEigen */ bool updateGradient(const Eigen::Ref>& gradient); - /** - * Update the lower bounds limit (size m). - * @param lowerBound is the lower bound constraint vector. - * @note the elements of the lowerBound are not copied inside the library. - * The user has to guarantee that the lifetime of the object passed is the same of the - * OsqpEigen object. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateLowerBound(Eigen::Matrix& lowerBound) instead")]] - bool updateLowerBound(Eigen::Matrix& lowerBound); - /** * Update the lower bounds limit (size m). * @param lowerBound is the lower bound constraint vector. @@ -167,18 +143,6 @@ namespace OsqpEigen */ bool updateLowerBound(const Eigen::Ref>& lowerBound); - /** - * Update the upper bounds limit (size m). - * @param upperBound is the upper bound constraint vector. - * @note the elements of the upperBound are not copied inside the library. - * The user has to guarantee that the lifetime of the object passed is the same of the - * OsqpEigen object. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateUpperBound(Eigen::Matrix& upperBound) instead")]] - bool updateUpperBound(Eigen::Matrix& upperBound); - /** * Update the upper bounds limit (size m). * @param upperBound is the upper bound constraint vector. @@ -189,20 +153,6 @@ namespace OsqpEigen */ bool updateUpperBound(const Eigen::Ref>& upperBound); - /** - * Update both upper and lower bounds (size m). - * @param lowerBound is the lower bound constraint vector; - * @param upperBound is the upper bound constraint vector. - * @note the elements of the lowerBound and upperBound are not copied inside the library. - * The user has to guarantee that the lifetime of the objects passed is the same of the - * OsqpEigen object - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateBounds(const Eigen::Ref>& lowerBound, const Eigen::Ref>& upperBound) instead")]] - bool updateBounds(Eigen::Matrix& lowerBound, - Eigen::Matrix& upperBound); - /** * Update both upper and lower bounds (size m). * @param lowerBound is the lower bound constraint vector; @@ -215,21 +165,6 @@ namespace OsqpEigen bool updateBounds(const Eigen::Ref>& lowerBound, const Eigen::Ref>& upperBound); - /** - * Update the quadratic part of the cost function (Hessian). - * It is assumed to be a simmetric matrix. - * \note - * If the sparsity pattern is preserved the matrix is simply update - * otherwise the entire solver will be reinitialized. In this case - * the primal and dual variable are copied in the new workspace. - * - * @param hessian is the Hessian matrix. - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateHessianMatrix(const Eigen::SparseCompressedBase &hessianMatrix) instead")]] - bool updateHessianMatrix(const Eigen::SparseMatrix &hessianMatrix); - /** * Update the quadratic part of the cost function (Hessian). * It is assumed to be a simmetric matrix. @@ -244,20 +179,6 @@ namespace OsqpEigen template bool updateHessianMatrix(const Eigen::SparseCompressedBase &hessianMatrix); - /** - * Update the linear constraints matrix (A) - * \note - * If the sparsity pattern is preserved the matrix is simply update - * otherwise the entire solver will be reinitialized. In this case - * the primal and dual variable are copied in the new workspace. - * - * @param linearConstraintsMatrix is the linear constraint matrix A - * @return true/false in case of success/failure. - */ - template - [[deprecated("Use updateLinearConstraintsMatrix(const Eigen::SparseCompressedBase &linearConstraintsMatrix) instead")]] - bool updateLinearConstraintsMatrix(const Eigen::SparseMatrix &linearConstraintsMatrix); - /** * Update the linear constraints matrix (A) * \note diff --git a/include/OsqpEigen/Solver.tpp b/include/OsqpEigen/Solver.tpp index ff33a53..26e1647 100644 --- a/include/OsqpEigen/Solver.tpp +++ b/include/OsqpEigen/Solver.tpp @@ -353,283 +353,3 @@ void OsqpEigen::Solver::selectUpperTriangularTriplets(const std::vector -bool OsqpEigen::Solver::updateGradient(Eigen::Matrix& gradient) -{ - // check if the dimension of the gradient is correct - if(gradient.rows() != m_workspace->data->n){ - std::cerr << "[OsqpEigen::Solver::updateGradient] The size of the gradient must be equal to the number of the variables." - << std::endl; - return false; - } - - // update the gradient vector - if(osqp_update_lin_cost(m_workspace.get(), gradient.data())){ - std::cerr << "[OsqpEigen::Solver::updateGradient] Error when the update gradient is called." - << std::endl; - return false; - } - return true; -} - -template -bool OsqpEigen::Solver::updateLowerBound(Eigen::Matrix& lowerBound) -{ - // check if the dimension of the lowerBound vector is correct - if(lowerBound.rows() != m_workspace->data->m){ - std::cerr << "[OsqpEigen::Solver::updateLowerBound] The size of the lower bound must be equal to the number of the variables." - << std::endl; - return false; - } - - // update the lower bound vector - if(osqp_update_lower_bound(m_workspace.get(), lowerBound.data())){ - std::cerr << "[OsqpEigen::Solver::updateLowerBound] Error when the update lower bound is called." - << std::endl; - return false; - } - - return true; -} - -template -bool OsqpEigen::Solver::updateUpperBound(Eigen::Matrix& upperBound) -{ - // check if the dimension of the upperBound vector is correct - if(upperBound.rows() != m_workspace->data->m){ - std::cerr << "[OsqpEigen::Solver::updateUpperBound] The size of the upper bound must be equal to the number of the variables." - << std::endl; - return false; - } - - // update the upper bound vector - if(osqp_update_upper_bound(m_workspace.get(), upperBound.data())){ - std::cerr << "[OsqpEigen::Solver::updateUpperBound] Error when the update upper bound is called." - << std::endl; - return false; - } - return true; -} - - -template -bool OsqpEigen::Solver::updateBounds(Eigen::Matrix& lowerBound, - Eigen::Matrix& upperBound) -{ - // check if the dimension of the upperBound vector is correct - if(upperBound.rows() != m_workspace->data->m){ - std::cerr << "[OsqpEigen::Solver::updateBounds] The size of the upper bound must be equal to the number of the variables." - << std::endl; - return false; - } - - // check if the dimension of the lowerBound vector is correct - if(lowerBound.rows() != m_workspace->data->m){ - std::cerr << "[OsqpEigen::Solver::updateBounds] The size of the lower bound must be equal to the number of the variables." - << std::endl; - return false; - } - - // update lower and upper constraints - if(osqp_update_bounds(m_workspace.get(), lowerBound.data(), upperBound.data())){ - std::cerr << "[OsqpEigen::Solver::updateBounds] Error when the update bounds is called." - << std::endl; - return false; - } - return true; -} - -template -bool OsqpEigen::Solver::updateHessianMatrix(const Eigen::SparseMatrix &hessianMatrix) - { - if(!m_isSolverInitialized){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] The solver has not been initialized." - << std::endl; - return false; - } - - if(((c_int)hessianMatrix.rows() != m_workspace->data->n)|| - ((c_int)hessianMatrix.cols() != m_workspace->data->n)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] The hessian matrix has to be a nxn matrix" - << std::endl; - return false; - } - - - // evaluate the triplets from old and new hessian sparse matrices - if(!OsqpEigen::SparseMatrixHelper::osqpSparseMatrixToTriplets(m_workspace->data->P, - m_oldHessianTriplet)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to evaluate triplets from the old hessian matrix." - << std::endl; - return false; - } - if(!OsqpEigen::SparseMatrixHelper::eigenSparseMatrixToTriplets(hessianMatrix, - m_newHessianTriplet)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to evaluate triplets from the old hessian matrix." - << std::endl; - return false; - } - - selectUpperTriangularTriplets(m_newHessianTriplet, m_newUpperTriangularHessianTriplets); - - // try to update the hessian matrix without reinitialize the solver - // according to the osqp library it can be done only if the sparsity pattern of the hessian - // matrix does not change. - - if(evaluateNewValues(m_oldHessianTriplet, m_newUpperTriangularHessianTriplets, - m_hessianNewIndices, m_hessianNewValues)){ - if (m_hessianNewValues.size() > 0) { - if(osqp_update_P(m_workspace.get(), m_hessianNewValues.data(), m_hessianNewIndices.data(), m_hessianNewIndices.size()) != 0){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to update hessian matrix." - << std::endl; - return false; - } - } - } - else{ - // the sparsity pattern has changed - // the solver has to be setup again - - // get the primal and the dual variables - - if(!getPrimalVariable(m_primalVariables)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to get the primal variable." - << std::endl; - return false; - } - - if(!getDualVariable(m_dualVariables)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to get the dual variable." - << std::endl; - return false; - } - - // clear old hessian matrix - m_data->clearHessianMatrix(); - - // set new hessian matrix - if(!m_data->setHessianMatrix(hessianMatrix)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to update the hessian matrix in " - << "OptimizaroData object." - << std::endl; - return false; - } - - // clear the old solver - clearSolver(); - - // initialize a new solver - initSolver(); - - // set the old primal and dual variables - if(!setPrimalVariable(m_primalVariables)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to set the primal variable." - << std::endl; - return false; - } - - if(!setDualVariable(m_dualVariables)){ - std::cerr << "[OsqpEigen::Solver::updateHessianMatrix] Unable to set the dual variable." - << std::endl; - return false; - } - } - return true; -} - -template -bool OsqpEigen::Solver::updateLinearConstraintsMatrix(const Eigen::SparseMatrix &linearConstraintsMatrix) -{ - if(!m_isSolverInitialized){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] The solver has not been initialized." - << std::endl; - return false; - } - - if(((c_int)linearConstraintsMatrix.rows() != m_workspace->data->m)|| - ((c_int)linearConstraintsMatrix.cols() != m_workspace->data->n)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] The constraints matrix has to be a mxn matrix" - << std::endl; - return false; - } - - // evaluate the triplets from old and new hessian sparse matrices - - if(!OsqpEigen::SparseMatrixHelper::osqpSparseMatrixToTriplets(m_workspace->data->A, - m_oldLinearConstraintsTriplet)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to evaluate triplets from the old hessian matrix." - << std::endl; - return false; - } - if(!OsqpEigen::SparseMatrixHelper::eigenSparseMatrixToTriplets(linearConstraintsMatrix, - m_newLinearConstraintsTriplet)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to evaluate triplets from the old hessian matrix." - << std::endl; - return false; - } - - // try to update the linear constraints matrix without reinitialize the solver - // according to the osqp library it can be done only if the sparsity pattern of the - // matrix does not change. - - if(evaluateNewValues(m_oldLinearConstraintsTriplet, m_newLinearConstraintsTriplet, - m_constraintsNewIndices, m_constraintsNewValues)){ - if (m_constraintsNewValues.size() > 0) { - if(osqp_update_A(m_workspace.get(), m_constraintsNewValues.data(), m_constraintsNewIndices.data(), m_constraintsNewIndices.size()) != 0){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to update linear constraints matrix." - << std::endl; - return false; - } - } - } - else{ - // the sparsity pattern has changed - // the solver has to be setup again - - // get the primal and the dual variables - - if(!getPrimalVariable(m_primalVariables)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to get the primal variable." - << std::endl; - return false; - } - - if(!getDualVariable(m_dualVariables)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to get the dual variable." - << std::endl; - return false; - } - - // clear old linear constraints matrix - m_data->clearLinearConstraintsMatrix(); - - // set new linear constraints matrix - if(!m_data->setLinearConstraintsMatrix(linearConstraintsMatrix)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to update the hessian matrix in " - << "Data object." - << std::endl; - return false; - } - - // clear the old solver - clearSolver(); - - // initialize a new solver - initSolver(); - - // set the old primal and dual variables - if(!setPrimalVariable(m_primalVariables)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to set the primal variable." - << std::endl; - return false; - } - - if(!setDualVariable(m_dualVariables)){ - std::cerr << "[OsqpEigen::Solver::updateLinearConstraintsMatrix] Unable to set the dual variable." - << std::endl; - return false; - } - } - return true; -} From bf818072345c75a51ece9601187bf2ed184aec2a Mon Sep 17 00:00:00 2001 From: Stefano Date: Wed, 5 Feb 2020 17:05:46 +0100 Subject: [PATCH 2/3] Bumped minor version. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b9138f..0ab0bce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED 11) project(OsqpEigen LANGUAGES CXX - VERSION 0.5.103) + VERSION 0.6.0) # add GNU dirs include(GNUInstallDirs) From fd054ee02ab34b6a2e0b2fd753a8e1fbbdfe9fba Mon Sep 17 00:00:00 2001 From: Stefano Date: Wed, 5 Feb 2020 17:48:15 +0100 Subject: [PATCH 3/3] Added Valgrind tests. --- CMakeLists.txt | 2 + cmake/FindVALGRIND.cmake | 26 ++++++ cmake/valgrind-macos.supp | 173 ++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 56 +++++++----- 4 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 cmake/FindVALGRIND.cmake create mode 100644 cmake/valgrind-macos.supp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ab0bce..2494459 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,8 @@ install_basic_package_files(${PROJECT_NAME} ## Testing option(BUILD_TESTING "Create tests using CMake" OFF) +option(RUN_VALGRIND_TESTS "Run tests with Valgrind" FALSE) +mark_as_advanced(RUN_VALGRIND_TESTS) include(CTest) if(BUILD_TESTING) add_subdirectory(tests) diff --git a/cmake/FindVALGRIND.cmake b/cmake/FindVALGRIND.cmake new file mode 100644 index 0000000..f20fad8 --- /dev/null +++ b/cmake/FindVALGRIND.cmake @@ -0,0 +1,26 @@ +# Find Valgrind. +# +# This module defines: +# VALGRIND_INCLUDE_DIR, where to find valgrind/memcheck.h, etc. +# VALGRIND_PROGRAM, the valgrind executable. +# VALGRIND_FOUND, If false, do not try to use valgrind. +# +# If you have valgrind installed in a non-standard place, you can define +# VALGRIND_ROOT to tell cmake where it is. +if (VALGRIND_FOUND) + return() +endif() + +find_path(VALGRIND_INCLUDE_DIR valgrind/memcheck.h + /usr/include /usr/local/include ${VALGRIND_ROOT}/include) + +# if VALGRIND_ROOT is empty, we explicitly add /bin to the search +# path, but this does not hurt... +find_program(VALGRIND_PROGRAM NAMES valgrind PATH ${VALGRIND_ROOT}/bin) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VALGRIND DEFAULT_MSG + VALGRIND_INCLUDE_DIR + VALGRIND_PROGRAM) + +mark_as_advanced(VALGRIND_ROOT VALGRIND_INCLUDE_DIR VALGRIND_PROGRAM) diff --git a/cmake/valgrind-macos.supp b/cmake/valgrind-macos.supp new file mode 100644 index 0000000..4e0424a --- /dev/null +++ b/cmake/valgrind-macos.supp @@ -0,0 +1,173 @@ +{ + macOS-Sierra-10.12.5-Leak.1 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_malloc + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register + fun:_objc_init + fun:_os_object_init +} +{ + macOS-Sierra-10.12.5-Leak.2 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_malloc + fun:NXCreateHashTableFromZone + fun:NXCreateHashTable + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register +} +{ + macOS-Sierra-10.12.5-Leak.3 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_malloc + fun:NXCreateHashTableFromZone + fun:NXCreateHashTable + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register +} +{ + macOS-Sierra-10.12.5-Leak.4 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:NXCreateHashTableFromZone + fun:NXCreateHashTable + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register +} +{ + macOS-Sierra-10.12.5-Leak.5 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register + fun:_objc_init + fun:_os_object_init +} +{ + macOS-Sierra-10.12.5-Leak.6 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_calloc + fun:_NXHashRehashToCapacity + fun:NXHashInsert + fun:NXCreateHashTableFromZone + fun:NXCreateHashTable + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb +} +{ + macOS-Sierra-10.12.5-Leak.7 + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register + fun:_objc_init + fun:_os_object_init + fun:libdispatch_init + fun:libSystem_initializer + fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE + fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE +} + +{ + macOS-Sierra-10.12.5-reachable.1 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc_zone_calloc + fun:_NXHashRehashToCapacity + fun:NXHashInsert + fun:NXCreateHashTableFromZone + fun:NXCreateHashTable + fun:NXCreateMapTableFromZone + fun:NXCreateMapTableFromZone + fun:_ZL18__sel_registerNamePKcii + fun:sel_init + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb +} + +{ + macOS-Sierra-10.12.5-possible.1 + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:map_images_nolock + fun:_ZN11objc_object21sidetable_retainCountEv + fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoEbb + fun:_ZN4dyld21registerObjCNotifiersEPFvjPKPKcPKPK11mach_headerEPFvS1_S6_ESC_ + fun:_dyld_objc_notify_register + fun:_objc_init + fun:_os_object_init + fun:libdispatch_init + fun:libSystem_initializer + fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE + fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE +} + +{ + macOS-Sierra-10.12.5-check.1 + Memcheck:Param + msg->desc.port.name + fun:mach_msg_trap + fun:mach_msg + fun:task_set_special_port + fun:_os_trace_create_debug_control_port + fun:_libtrace_init + fun:libSystem_initializer + fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE + fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE + fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjPKcRNS_21InitializerTimingListERNS_15UninitedUpwardsE + fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjPKcRNS_21InitializerTimingListERNS_15UninitedUpwardsE + fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE + fun:_ZN11ImageLoader15runInitializersERKNS_11LinkContextERNS_21InitializerTimingListE +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3356038..68f0ab1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,32 +17,48 @@ endif() find_package(GTest REQUIRED) include_directories(${GTEST_INCLUDE_DIRS}) +# adding support for checking the tests with valgrind +if(RUN_VALGRIND_TESTS) + find_package(VALGRIND REQUIRED) + if(VALGRIND_FOUND) + set(CTEST_MEMORYCHECK_COMMAND ${VALGRIND_PROGRAM}) + set(MEMORYCHECK_COMMAND ${VALGRIND_PROGRAM}) + if (APPLE) + set(MEMORYCHECK_SUPPRESSIONS "--suppressions=${PROJECT_SOURCE_DIR}/cmake/valgrind-macos.supp") + else () + set(MEMORYCHECK_SUPPRESSIONS "") + endif () + set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1 ${MEMORYCHECK_SUPPRESSIONS}" CACHE STRING "Options to pass to the memory checker") + mark_as_advanced(MEMORYCHECK_COMMAND_OPTIONS) + set(MEMCHECK_COMMAND_COMPLETE "${MEMORYCHECK_COMMAND} ${MEMORYCHECK_COMMAND_OPTIONS}") + separate_arguments(MEMCHECK_COMMAND_COMPLETE) + endif() +endif() + +macro(add_osqpeigen_test classname) + set(testsrc ${classname}Test.cpp) + set(testbinary ${classname}Test) + set(testname ${classname}Test) + add_executable(${testbinary} ${testsrc}) + target_link_libraries(${testbinary} PRIVATE OsqpEigen::OsqpEigen osqp::osqp Eigen3::Eigen ${GTEST_LIBRARIES} pthread) + add_test(NAME ${testname} COMMAND ${testbinary}) + + if(RUN_VALGRIND_TESTS) + add_test(NAME memcheck_${testname} COMMAND ${MEMCHECK_COMMAND_COMPLETE} $) + endif() +endmacro() + # QPTest -add_executable(SparseMatrixTest SparseMatrixTest.cpp) -target_link_libraries(SparseMatrixTest OsqpEigen::OsqpEigen osqp::osqp Eigen3::Eigen ${GTEST_LIBRARIES} pthread) -add_test(NAME SparseMatrixTest - COMMAND SparseMatrixTest) +add_osqpeigen_test(SparseMatrix) # QPTest -add_executable(QPTest QPTest.cpp) -target_link_libraries(QPTest OsqpEigen::OsqpEigen Eigen3::Eigen ${GTEST_LIBRARIES} pthread) -add_test(NAME QPTest - COMMAND QPTest) +add_osqpeigen_test(QP) # Update matrix -add_executable(UpdateMatricesTest UpdateMatricesTest.cpp) -target_link_libraries(UpdateMatricesTest OsqpEigen::OsqpEigen Eigen3::Eigen ${GTEST_LIBRARIES} pthread) -add_test(NAME UpdateMatricesTest - COMMAND UpdateMatricesTest) +add_osqpeigen_test(UpdateMatrices) # MPCTest -add_executable(MPCTest MPCTest.cpp) -target_link_libraries(MPCTest OsqpEigen::OsqpEigen Eigen3::Eigen ${GTEST_LIBRARIES} pthread) -add_test(NAME MPCTest - COMMAND MPCTest) +add_osqpeigen_test(MPC) # MPCTest update matrix -add_executable(MPCUpdateMatricesTest UpdateMatricesTest.cpp) -target_link_libraries(MPCUpdateMatricesTest OsqpEigen::OsqpEigen Eigen3::Eigen ${GTEST_LIBRARIES} pthread) -add_test(NAME MPCUpdateMatricesTest - COMMAND MPCUpdateMatricesTest) +add_osqpeigen_test(MPCUpdateMatrices)