From e8071774c43714b010ced247c8b2aaf30d364770 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:20:34 +0000 Subject: [PATCH 001/100] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-clang-format: v18.1.5 → v18.1.6](https://github.com/pre-commit/mirrors-clang-format/compare/v18.1.5...v18.1.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 353da0dfc..f1e0ff0df 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ ci: autoupdate_branch: 'devel' repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.5 + rev: v18.1.6 hooks: - id: clang-format args: ['--style={BasedOnStyle: Mozilla, SortIncludes: false}'] From 1ce420a7ade29cba189d5ffbb0801b16b6b9824d Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:54:49 +0200 Subject: [PATCH 002/100] fix infeasibility detection logic --- include/proxsuite/proxqp/dense/utils.hpp | 4 ++-- include/proxsuite/proxqp/sparse/utils.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/proxsuite/proxqp/dense/utils.hpp b/include/proxsuite/proxqp/dense/utils.hpp index 41be150a8..6d9c62857 100644 --- a/include/proxsuite/proxqp/dense/utils.hpp +++ b/include/proxsuite/proxqp/dense/utils.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // /** * @file utils.hpp @@ -289,7 +289,7 @@ global_primal_residual_infeasibility( // // the variables in entry are changed in place - bool res = infty_norm(dy.to_eigen()) != 0 && infty_norm(dz.to_eigen()) != 0; + bool res = infty_norm(dy.to_eigen()) != 0 || infty_norm(dz.to_eigen()) != 0; if (!res) { return res; } diff --git a/include/proxsuite/proxqp/sparse/utils.hpp b/include/proxsuite/proxqp/sparse/utils.hpp index c3da2b81c..62e55413b 100644 --- a/include/proxsuite/proxqp/sparse/utils.hpp +++ b/include/proxsuite/proxqp/sparse/utils.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022-2023 INRIA +// Copyright (c) 2022-2024 INRIA // /** \file */ @@ -488,7 +488,7 @@ global_primal_residual_infeasibility(VectorViewMut ATdy, // // the variables in entry are changed in place - bool res = infty_norm(dy.to_eigen()) != 0 && infty_norm(dz.to_eigen()) != 0; + bool res = infty_norm(dy.to_eigen()) != 0 || infty_norm(dz.to_eigen()) != 0; if (!res) { return res; } From f32a5786df85aeb883b0fe9e705eae256dba75c6 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:08:53 +0200 Subject: [PATCH 003/100] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5357e054..43645d290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed * Fixes compilation issue with GCC 14 on Arch ([#322](https://github.com/Simple-Robotics/proxsuite/pull/322)) +* Fix infeasibility detection and add unittest ([#328](https://github.com/Simple-Robotics/proxsuite/pull/328)) ### What's Changed * Change from torch.Tensor to torch.empty or torch.tensor and specify type explicitly ([#308](https://github.com/Simple-Robotics/proxsuite/pull/308)) From cfce8bba577c11d14f4361f46bdbc46ff50cb885 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:10:02 +0200 Subject: [PATCH 004/100] unittest: check status if qp was solved --- test/src/dense_qp_with_eq_and_in.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/src/dense_qp_with_eq_and_in.cpp b/test/src/dense_qp_with_eq_and_in.cpp index 9950ca650..73de0d012 100644 --- a/test/src/dense_qp_with_eq_and_in.cpp +++ b/test/src/dense_qp_with_eq_and_in.cpp @@ -197,6 +197,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " qp_random.l, qp_random.u); qp.solve(); + DOCTEST_CHECK(qp.results.info.status == + proxqp::QPSolverOutput::PROXQP_SOLVED); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + From 45e59d260de1e9eb2bed3e161838c60b38926bd4 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:38:11 +0200 Subject: [PATCH 005/100] unittest: add infeasible qp and check infeas. detection --- test/src/dense_qp_eq.cpp | 43 +++++++++++++++++++++++++++- test/src/dense_qp_with_eq_and_in.cpp | 2 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/test/src/dense_qp_eq.cpp b/test/src/dense_qp_eq.cpp index 9a6a9befd..2a6aa2541 100644 --- a/test/src/dense_qp_eq.cpp +++ b/test/src/dense_qp_eq.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022 - 2024 INRIA // #include #include @@ -212,4 +212,45 @@ DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " std::cout << "total number of iteration: " << qp.results.info.iter << std::endl; } +} + +DOCTEST_TEST_CASE("infeasible qp") +{ + // (x1- 9)^2 + (x2-6)^2 + // s.t. + // x1 <= 10 + // x2 <= 10 + // x1 >= 20 + Eigen::Matrix H; + H << 1.0, 0.0, 0.0, 1.0; + H = 2 * H; + + Eigen::Matrix g; + g << -18.0, -12.0; + + Eigen::Matrix C; + C << 1, 0, // x1 <= 10 + 0, 1, // x2 <= 10 + -1, 0; // x1 >= 20 + + Eigen::Matrix u; + u << 10, 10, -20; + + int n = H.rows(); + int n_in = C.rows(); + int n_eq = 0; + + Eigen::Matrix l = + Eigen::Matrix::Constant( + n_in, -std::numeric_limits::infinity()); + + proxsuite::proxqp::dense::QP qp(n, n_eq, n_in); + qp.init(H, g, nullopt, nullopt, C, l, u); + qp.settings.eps_rel = 0.; + qp.settings.eps_abs = 1e-9; + + qp.solve(); + + DOCTEST_CHECK(qp.results.info.status == + proxsuite::proxqp::QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE); } \ No newline at end of file diff --git a/test/src/dense_qp_with_eq_and_in.cpp b/test/src/dense_qp_with_eq_and_in.cpp index 73de0d012..cb7e1d808 100644 --- a/test/src/dense_qp_with_eq_and_in.cpp +++ b/test/src/dense_qp_with_eq_and_in.cpp @@ -172,7 +172,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " << "---testing sparse random strongly convex qp with degenerate " "inequality constraints and increasing dimension using the API---" << std::endl; - T sparsity_factor = 0.15; + T sparsity_factor = 0.45; T eps_abs = T(1e-9); T strong_convexity_factor(1e-2); proxqp::utils::rand::set_seed(1); From b7adeb8084a7ab0afbaa88ac56e058a82f99d098 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 14 Jun 2024 17:35:31 +0200 Subject: [PATCH 006/100] changelog: fix --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43645d290..bd3e991b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +* Fix infeasibility detection and add a unit test ([#328](https://github.com/Simple-Robotics/proxsuite/pull/328)) + ## [0.6.5] - 2024-05-31 ### Added @@ -13,7 +16,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed * Fixes compilation issue with GCC 14 on Arch ([#322](https://github.com/Simple-Robotics/proxsuite/pull/322)) -* Fix infeasibility detection and add unittest ([#328](https://github.com/Simple-Robotics/proxsuite/pull/328)) ### What's Changed * Change from torch.Tensor to torch.empty or torch.tensor and specify type explicitly ([#308](https://github.com/Simple-Robotics/proxsuite/pull/308)) From 72c7f9f421d433a624df9a44525126766ecc6475 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 09:54:49 +0200 Subject: [PATCH 007/100] cmake: sync submodule --- cmake-module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake-module b/cmake-module index dd3e4127f..2bea127e8 160000 --- a/cmake-module +++ b/cmake-module @@ -1 +1 @@ -Subproject commit dd3e4127f2b223496859fe05be02726e9d1a071b +Subproject commit 2bea127e8113a32f216ae7a7201e36a6e7c56cc2 From 9beddfd2d37d6d9439bcaaabf4ff77390b29de2d Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 09:56:02 +0200 Subject: [PATCH 008/100] release: Update package.xml version to 0.6.6 --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index f4d734b2b..9fe309bed 100644 --- a/package.xml +++ b/package.xml @@ -1,7 +1,7 @@ proxsuite - 0.6.5 + 0.6.6 The Advanced Proximal Optimization Toolbox Justin Carpentier From b298b8872c083ef1c094fd0e5a41427e671e1849 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 09:56:03 +0200 Subject: [PATCH 009/100] release: Update pyproject.toml version to 0.6.6 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f8d999384..186eaf6d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "proxsuite" -version = "0.6.5" +version = "0.6.6" description = "Quadratic Programming Solver for Robotics and beyond." readme = "README.md" requires-python = ">= 3.7" From d88e61195e09f26a0749f0a4f60e4d9c11a95f74 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 09:56:04 +0200 Subject: [PATCH 010/100] release: Update CHANGELOG.md for 0.6.6 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3e991b7..27925e586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [0.6.6] - 2024-06-15 + ### Fixed * Fix infeasibility detection and add a unit test ([#328](https://github.com/Simple-Robotics/proxsuite/pull/328)) @@ -412,7 +414,8 @@ More to come ([#](a forthcoming release.)) The first release of ProxSuite. -[Unreleased]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.5...HEAD +[Unreleased]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.6...HEAD +[0.6.6]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.5...v0.6.6 [0.6.5]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.4...v0.6.5 [0.6.4]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.3...v0.6.4 [0.6.3]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.2...v0.6.3 From 84b4211cd3d4fcc38dc80a205a6a4db866a8889c Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 09:56:06 +0200 Subject: [PATCH 011/100] release: Update CITATION.cff version to 0.6.6 --- CITATION.cff | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 2e5852728..2def662cd 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,7 +14,7 @@ authors: - family-names: Carpentier given-names: Justin orcid: "https://orcid.org/0000-0001-6585-2894" -version: 0.6.5 -date-released: "2024-05-31" +version: 0.6.6 +date-released: "2024-06-15" license: BSD-2-Clause repository-code: "https://github.com/Simple-Robotics/proxsuite" From f19f07b51f66268db1f16cbeb538e891bb6d4e21 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 10:02:31 +0200 Subject: [PATCH 012/100] core: fix deprecated __has_trivial_destructor compilation warning --- .../proxsuite/linalg/veg/type_traits/constructible.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/include/proxsuite/linalg/veg/type_traits/constructible.hpp b/include/proxsuite/linalg/veg/type_traits/constructible.hpp index 7036fd2b0..ce1ed6396 100644 --- a/include/proxsuite/linalg/veg/type_traits/constructible.hpp +++ b/include/proxsuite/linalg/veg/type_traits/constructible.hpp @@ -23,13 +23,9 @@ VEG_DEF_CONCEPT(typename T, nothrow_destructible, noexcept(static_cast(nullptr)->~T())); -VEG_DEF_CONCEPT( - typename T, - trivially_destructible, - VEG_HAS_BUILTIN_OR(__has_trivial_destructor, - ((_detail::assert_complete<_detail::Wrapper>(), - __has_trivial_destructor(T))), - (std::is_trivially_destructible::value))); +VEG_DEF_CONCEPT(typename T, + trivially_destructible, + std::is_trivially_destructible::value); VEG_DEF_CONCEPT_FROM_BUILTIN_OR_STD(typename T, trivially_copyable, T); From 2bcadd4993a9940c545136faa71bf1e97a972735 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Tue, 18 Jun 2024 18:09:56 +0200 Subject: [PATCH 013/100] CMake: allow use of installed jrl-cmakemodules --- CMakeLists.txt | 57 +++++++++++++++++++++++----------- bindings/python/CMakeLists.txt | 4 +-- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d22c3ed7..a8b7bb54e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,37 @@ set(PROJECT_CUSTOM_HEADER_EXTENSION "hpp") set(PROJECT_USE_CMAKE_EXPORT TRUE) set(PROJECT_USE_KEYWORD_LINK_LIBRARIES TRUE) +# Check if the submodule cmake have been initialized +set(JRL_CMAKE_MODULES "${CMAKE_CURRENT_LIST_DIR}/cmake-module") +if(EXISTS "${JRL_CMAKE_MODULES}/base.cmake") + message(STATUS "JRL cmakemodules found in 'cmake/' git submodule") +else() + find_package(jrl-cmakemodules QUIET CONFIG) + if(jrl-cmakemodules_FOUND) + get_property( + JRL_CMAKE_MODULES + TARGET jrl-cmakemodules::jrl-cmakemodules + PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + message(STATUS "JRL cmakemodules found on system at ${JRL_CMAKE_MODULES}") + elseif(${CMAKE_VERSION} VERSION_LESS "3.14.0") + message( + FATAL_ERROR + "\nCan't find jrl-cmakemodules. Please either:\n" + " - use git submodule: 'git submodule update --init'\n" + " - or install https://github.com/jrl-umi3218/jrl-cmakemodules\n" + " - or upgrade your CMake version to >= 3.14 to allow automatic fetching\n" + ) + else() + message(STATUS "JRL cmakemodules not found. Let's fetch it.") + include(FetchContent) + FetchContent_Declare( + "jrl-cmakemodules" + GIT_REPOSITORY "https://github.com/jrl-umi3218/jrl-cmakemodules.git") + FetchContent_MakeAvailable("jrl-cmakemodules") + FetchContent_GetProperties("jrl-cmakemodules" SOURCE_DIR JRL_CMAKE_MODULES) + endif() +endif() + # Disable -Werror on Unix for now. set(CXX_DISABLE_WERROR True) set(CMAKE_VERBOSE_MAKEFILE True) @@ -24,14 +55,6 @@ if(POLICY CMP0068) cmake_policy(SET CMP0068 NEW) endif(POLICY CMP0068) -# Check if the submodule cmake have been initialized -if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/cmake-module/base.cmake") - message( - FATAL_ERROR - "\nPlease run the following command first:\ngit submodule update --init\n" - ) -endif() - # ---------------------------------------------------- # --- OPTIONS --------------------------------------- # Need to be set before including base.cmake @@ -42,19 +65,18 @@ option(INSTALL_DOCUMENTATION "Install the documentation" OFF) set(DOXYGEN_USE_MATHJAX YES) set(DOXYGEN_USE_TEMPLATE_CSS YES) -include(${CMAKE_CURRENT_LIST_DIR}/cmake-module/base.cmake) +include(${JRL_CMAKE_MODULES}/base.cmake) compute_project_args(PROJECT_ARGS LANGUAGES CXX) project(${PROJECT_NAME} ${PROJECT_ARGS}) -include(${CMAKE_CURRENT_LIST_DIR}/cmake-module/ide.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/cmake-module/apple.cmake) +include(${JRL_CMAKE_MODULES}/ide.cmake) +include(${JRL_CMAKE_MODULES}/apple.cmake) if(NOT ${CMAKE_VERSION} VERSION_GREATER "3.26.0" OR WIN32) - set(CMAKE_MODULE_PATH - ${CMAKE_CURRENT_LIST_DIR}/cmake-module/find-external/OpenMP - ${CMAKE_MODULE_PATH}) + set(CMAKE_MODULE_PATH ${JRL_CMAKE_MODULES}/find-external/OpenMP + ${CMAKE_MODULE_PATH}) endif() -include(${CMAKE_CURRENT_LIST_DIR}/cmake-module/julia.cmake) +include(${JRL_CMAKE_MODULES}/julia.cmake) include(CMakeDependentOption) # If needed, set CMake policy for APPLE systems @@ -85,9 +107,8 @@ if(BUILD_WITH_OPENMP_SUPPORT) separate_arguments(OpenMP_CXX_FLAGS UNIX_COMMAND "${OpenMP_CXX_FLAGS}") endif(BUILD_WITH_OPENMP_SUPPORT) -set(CMAKE_MODULE_PATH - "${CMAKE_CURRENT_LIST_DIR}/cmake-module/find-external/Julia" - ${CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH "${JRL_CMAKE_MODULES}/find-external/Julia" + ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake-external" ${CMAKE_MODULE_PATH}) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 4e3d927fd..da6d4d892 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -2,8 +2,8 @@ if(UNIX) set(PYTHON_COMPONENTS Development.Module) endif() -include(../../cmake-module/python.cmake) -include(../../cmake-module/python-helpers.cmake) +include(${JRL_CMAKE_MODULES}/python.cmake) +include(${JRL_CMAKE_MODULES}/python-helpers.cmake) findpython(REQUIRED Development.Module) From 878337c6284c9fd73b19f1f80d5fa802def8cdc6 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Tue, 18 Jun 2024 18:21:24 +0200 Subject: [PATCH 014/100] CMake: allow use of installed cereal --- CMakeLists.txt | 17 +- bindings/python/CMakeLists.txt | 9 +- doc/rankupdate/rankupdate.aux | 9 - doc/rankupdate/rankupdate.fdb_latexmk | 68 -------- doc/rankupdate/rankupdate.fls | 239 -------------------------- test/CMakeLists.txt | 10 +- 6 files changed, 24 insertions(+), 328 deletions(-) delete mode 100644 doc/rankupdate/rankupdate.aux delete mode 100644 doc/rankupdate/rankupdate.fdb_latexmk delete mode 100644 doc/rankupdate/rankupdate.fls diff --git a/CMakeLists.txt b/CMakeLists.txt index a8b7bb54e..3e1f47aac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,13 +184,16 @@ endif() if(BUILD_TESTING OR BUILD_PYTHON_INTERFACE) # Download cereal for pything bindings and unittests - set(cereal_dir ${PROJECT_SOURCE_DIR}/external/cereal) - set(cereal ${cereal_dir}/README.md) - find_package(Git REQUIRED) - if(NOT EXISTS ${cereal}) - execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init ${cereal_dir} - WORKING_DIRECTORY ${cereal_dir} COMMAND_ERROR_IS_FATAL ANY) + find_package(cereal QUIET CONFIG) + if(NOT cereal_FOUND) + set(cereal_dir ${PROJECT_SOURCE_DIR}/external/cereal) + set(cereal ${cereal_dir}/README.md) + find_package(Git REQUIRED) + if(NOT EXISTS ${cereal}) + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init ${cereal_dir} + WORKING_DIRECTORY ${cereal_dir} COMMAND_ERROR_IS_FATAL ANY) + endif() endif() endif() diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index da6d4d892..c27344875 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -91,8 +91,13 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) list_filter("${PYWRAP_HEADERS}" "expose-parallel" PYWRAP_HEADERS) endif(BUILD_WITH_OPENMP_SUPPORT) - target_include_directories( - ${target_name} SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include) + if(cereal_FOUND) + target_link_libraries(${target_name} SYSTEM PRIVATE cereal) + else() + target_include_directories( + ${target_name} SYSTEM + PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include) + endif() set_target_properties( ${target_name} PROPERTIES OUTPUT_NAME ${target_name} diff --git a/doc/rankupdate/rankupdate.aux b/doc/rankupdate/rankupdate.aux deleted file mode 100644 index 64a75506e..000000000 --- a/doc/rankupdate/rankupdate.aux +++ /dev/null @@ -1,9 +0,0 @@ -\relax -\newlabel{eq:rank_update_definition}{{1}{1}} -\@writefile{toc}{\contentsline {section}{\numberline {1}Rank-one update:}{1}{}\protected@file@percent } -\newlabel{sec:Rank-one_update}{{1}{1}} -\newlabel{eq:unfold}{{3}{1}} -\newlabel{eq:lincomb}{{6}{2}} -\@writefile{toc}{\contentsline {section}{\numberline {2}Rank-$m$ update}{2}{}\protected@file@percent } -\newlabel{sec:Rank-$m$_update}{{2}{2}} -\gdef \@abspage@last{3} diff --git a/doc/rankupdate/rankupdate.fdb_latexmk b/doc/rankupdate/rankupdate.fdb_latexmk deleted file mode 100644 index c653edf04..000000000 --- a/doc/rankupdate/rankupdate.fdb_latexmk +++ /dev/null @@ -1,68 +0,0 @@ -# Fdb version 3 -["pdflatex"] 1641376399 "rankupdate.tex" "rankupdate.pdf" "rankupdate" 1641376399 - "/etc/texmf/web2c/texmf.cnf" 1640843101 475 c0e671620eb5563b2130f56340a5fde8 "" - "/usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/jknappen/ec/tcrm1000.tfm" 1136768653 1536 e07581a4bb3136ece9eeb4c3ffab8233 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1246382020 1004 54797486969f23fa377b128694d548df "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1246382020 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1246382020 916 f87d7c45f9c908e672703b83b72241a3 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm" 1246382020 924 9904cf1d39e9767e7a3622f2a125a565 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm" 1246382020 928 2dc8d444221b7a635bb58038579b861a "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm" 1246382020 908 2921f8a10601f252058503cc6570e581 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm" 1246382020 940 75ac932a52f80982a9f8ea75d03a34cf "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm" 1246382020 940 228d6584342e91276bf566bcf9716b83 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx12.tfm" 1136768653 1324 c910af8c371558dc20f2d7822f66fe64 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmex10.tfm" 1136768653 992 662f679a0b3d2d53c1b94050fdaa3f50 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm" 1136768653 1524 4414a8315f39513458b80dfc63bff03a "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi6.tfm" 1136768653 1512 f21f83efb36853c0b70002322c1ab3ad "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi8.tfm" 1136768653 1520 eccf95517727cb11801f4f1aee3a21b4 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm" 1136768653 1288 655e228510b4c2a1abe905c368440826 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr17.tfm" 1136768653 1292 296a67155bdbfc32aa9c636f21e91433 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr6.tfm" 1136768653 1300 b62933e007d01cfd073f79b963c01526 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr8.tfm" 1136768653 1292 21c1c5bfeaebccffdb478fd231a0997d "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm" 1136768653 1124 6c73e740cf17375f03eec0ee63599741 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy6.tfm" 1136768653 1116 933a60c408fc0a863a92debe84b2d294 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy8.tfm" 1136768653 1120 8b7d695260f3cff42e636090a8002094 "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb" 1248133631 32080 340ef9bf63678554ee606688e7b5339d "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb" 1248133631 30251 6afa5cb1d0204815a708a080681d4674 "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb" 1248133631 36299 5f9df58c2139e7edcf37c8fca4bd384d "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi12.pfb" 1248133631 36741 fa121aac0049305630cf160b86157ee4 "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb" 1248133631 36281 c355509802a035cadc5f15869451dcee "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb" 1248133631 35752 024fb6c41858982481f6968b5fc26508 "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr17.pfb" 1248133631 32362 179c33bbf43f19adbb3825bb4e36e57a "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr5.pfb" 1248133631 31809 8670ca339bf94e56da1fc21c80635e2a "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb" 1248133631 32762 224316ccc9ad3ca0423a14971cfa7fc1 "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb" 1248133631 32569 5e5ddc8df908dea60932f3c484a54c0d "" - "/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb" 1248133631 32716 08e384dc442464e7285e891af9f45947 "" - "/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty" 1591045760 12594 0d51ac3a545aaaa555021326ff22a6cc "" - "/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty" 1359763108 5949 3f3fd50a8cc94c3d4cbf4fc66cd3df1c "" - "/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty" 1359763108 13829 94730e64147574077f8ecfea9bb69af4 "" - "/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd" 1359763108 961 6518c6525a34feb5e8250ffa91731cff "" - "/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd" 1359763108 961 d02606146ba5601b5645f987c92e6193 "" - "/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty" 1523134290 2211 ca7ce284ab93c8eecdc6029dc5ccbd73 "" - "/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty" 1523134290 4161 7f6eb9092061a11f87d08ed13515b48d "" - "/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty" 1601675358 87353 2c21ff5f2e32e1bf714e600924d810db "" - "/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty" 1523134290 4116 32e6abd27229755a83a8b7f18e583890 "" - "/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty" 1523134290 2432 8ff93b1137020e8f21930562a874ae66 "" - "/usr/share/texlive/texmf-dist/tex/latex/base/article.cls" 1601675358 20145 aad8c3dd3bc36e260347b84002182bc2 "" - "/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo" 1601675358 8449 a72d5d4e612221b46000c3d71724e0ef "" - "/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty" 1580683321 2590 e3b24ff953e5b58d924f163d25380312 "" - "/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def" 1611959857 27097 58278863d97b10ab86e334b8da33df7a "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def" 1607465040 49121 4911f21dad8c1eb79a63aebba9643ece "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg" 1607465040 24929 baec9b115829e21e1ba4dfcaf6260d24 "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty" 1607465040 71807 0724aff58b422fcce3421aebcd5fc631 "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/mt-cmr.cfg" 1607465040 22870 85ef48580eb35bcb3beca9130657ae3b "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msa.cfg" 1607465040 5893 a60144fa9c61ba60cd8c1fe66baa02b3 "" - "/usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msb.cfg" 1607465040 5558 997b28f7d84cccc5fd6d2e3162e09e1e "" - "/usr/share/texlive/texmf-dist/web2c/texmf.cnf" 1613593815 38841 799d1dd9682a55ce442e10c99777ecc1 "" - "/usr/share/texmf/fonts/enc/dvips/cm-super/cm-super-ts1.enc" 1565080000 2900 1537cc8184ad1792082cd229ecc269f4 "" - "/usr/share/texmf/fonts/type1/public/cm-super/sfrm1000.pfb" 1565080000 138258 6525c253f16cededa14c7fd0da7f67b2 "" - "/usr/share/texmf/web2c/texmf.cnf" 1613593815 38841 799d1dd9682a55ce442e10c99777ecc1 "" - "/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1640843127 5160710 ecf427ae8fa19139d8691f526e47bb9b "" - "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1640843148 2571203 eb8afda0270e9970b44064aadd8ed7f2 "" - "rankupdate.aux" 1641376399 421 e4ea47dcf05024e543bb4c3c57eb39e3 "pdflatex" - "rankupdate.tex" 1641376398 4930 d4fb108de9084263a9e28c65147a235d "" - (generated) - "rankupdate.aux" - "rankupdate.log" - "rankupdate.pdf" diff --git a/doc/rankupdate/rankupdate.fls b/doc/rankupdate/rankupdate.fls deleted file mode 100644 index 51eee1ce8..000000000 --- a/doc/rankupdate/rankupdate.fls +++ /dev/null @@ -1,239 +0,0 @@ -PWD /home/sarah/projects/inria_ldlt/rankupdate -INPUT /etc/texmf/web2c/texmf.cnf -INPUT /usr/share/texmf/web2c/texmf.cnf -INPUT /usr/share/texlive/texmf-dist/web2c/texmf.cnf -INPUT /var/lib/texmf/web2c/pdftex/pdflatex.fmt -INPUT rankupdate.tex -OUTPUT rankupdate.log -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT ./rankupdate.aux -INPUT rankupdate.aux -INPUT rankupdate.aux -OUTPUT rankupdate.aux -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-cmr.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-cmr.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-cmr.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-cmr.cfg -INPUT /usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr17.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmex10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmex10.tfm -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msa.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msa.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msa.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msa.cfg -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msb.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msb.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msb.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/microtype/mt-msb.cfg -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx12.tfm -OUTPUT rankupdate.pdf -INPUT /var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmex10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/jknappen/ec/tcrm1000.tfm -INPUT rankupdate.aux -INPUT /usr/share/texmf/fonts/enc/dvips/cm-super/cm-super-ts1.enc -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi12.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr17.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr5.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb -INPUT /usr/share/texmf/fonts/type1/public/cm-super/sfrm1000.pfb diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 052b38080..a86bed82b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -62,9 +62,13 @@ add_test_cflags( test-cpp-serialization "-DTEST_SERIALIZATION_FOLDER=\\\\\"${CMAKE_CURRENT_BINARY_DIR}/serialization-data\\\\\"" ) -target_include_directories( - test-cpp-serialization SYSTEM - PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include) +if(cereal_FOUND) + target_link_libraries(test-cpp-serialization PRIVATE cereal) +else() + target_include_directories( + test-cpp-serialization SYSTEM + PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include) +endif() if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC) proxsuite_test(dense_maros_meszaros src/dense_maros_meszaros.cpp) From 6c98a74ed36d6addf3416fc00463b578f6883a20 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Wed, 19 Jun 2024 14:56:15 +0200 Subject: [PATCH 015/100] python: fix compatibility with Numpy 2 --- test/src/dense_qp_solve.py | 2 +- test/src/dense_qp_wrapper.py | 2 +- test/src/sparse_qp_solve.py | 2 +- test/src/sparse_qp_wrapper.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/src/dense_qp_solve.py b/test/src/dense_qp_solve.py index d8fe30736..6475da821 100644 --- a/test/src/dense_qp_solve.py +++ b/test/src/dense_qp_solve.py @@ -315,7 +315,7 @@ def test_sparse_problem_with_exact_solution_known(self): b = None C = spa.csc_matrix(spa.eye(n)).toarray() l = 2.0 * np.ones((n,)) - u = np.full(l.shape, +np.infty) + u = np.full(l.shape, +np.inf) results = proxsuite.proxqp.dense.solve(H, g, A, b, C, l, u) x_theoretically_optimal = np.array([2.0] * 149 + [3.0]) diff --git a/test/src/dense_qp_wrapper.py b/test/src/dense_qp_wrapper.py index 429f5fb80..0bda2f085 100644 --- a/test/src/dense_qp_wrapper.py +++ b/test/src/dense_qp_wrapper.py @@ -3930,7 +3930,7 @@ def test_sparse_problem_with_exact_solution_known(self): b = None C = spa.csc_matrix(spa.eye(n)).toarray() l = 2.0 * np.ones((n,)) - u = np.full(l.shape, +np.infty) + u = np.full(l.shape, +np.inf) qp = proxsuite.proxqp.dense.QP(n, 0, n) qp.init(H, g, A, b, C, l, u) diff --git a/test/src/sparse_qp_solve.py b/test/src/sparse_qp_solve.py index a8949ec1c..f882b50e3 100644 --- a/test/src/sparse_qp_solve.py +++ b/test/src/sparse_qp_solve.py @@ -347,7 +347,7 @@ def test_sparse_problem_with_exact_solution_known(self): b = None C = spa.csc_matrix(spa.eye(n)) l = 2.0 * np.ones((n,)) - u = np.full(l.shape, +np.infty) + u = np.full(l.shape, +np.inf) results = proxsuite.proxqp.sparse.solve(H, g, A, b, C, l, u) x_theoretically_optimal = np.array([2.0] * 149 + [3.0]) diff --git a/test/src/sparse_qp_wrapper.py b/test/src/sparse_qp_wrapper.py index 5b702a36f..d9e9eae8c 100644 --- a/test/src/sparse_qp_wrapper.py +++ b/test/src/sparse_qp_wrapper.py @@ -4523,7 +4523,7 @@ def test_sparse_problem_with_exact_solution_known(self): b = None C = spa.csc_matrix(spa.eye(n)) l = 2.0 * np.ones((n,)) - u = np.full(l.shape, +np.infty) + u = np.full(l.shape, +np.inf) qp = proxsuite.proxqp.sparse.QP(n, 0, n) qp.init(H, g, A, b, C, l, u) From 0d3a27d624e6fd55608315a800c5d4668d64ef57 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Wed, 19 Jun 2024 15:03:05 +0200 Subject: [PATCH 016/100] changelog: sync --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27925e586..3fcef102b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added +* Allow use of installed cereal and jrl-cmakemodules via cmake + ## [0.6.6] - 2024-06-15 ### Fixed From f8f4c15c4ee2eaa4a8131fcb90f6778713f89b89 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 23:09:51 +0000 Subject: [PATCH 017/100] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-clang-format: v18.1.6 → v18.1.7](https://github.com/pre-commit/mirrors-clang-format/compare/v18.1.6...v18.1.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f1e0ff0df..80916a3da 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ ci: autoupdate_branch: 'devel' repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.6 + rev: v18.1.7 hooks: - id: clang-format args: ['--style={BasedOnStyle: Mozilla, SortIncludes: false}'] From 02cdafd18b3a245ab3352f22b66d2e2c34303f4e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 01:22:19 +0000 Subject: [PATCH 018/100] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-clang-format: v18.1.7 → v18.1.8](https://github.com/pre-commit/mirrors-clang-format/compare/v18.1.7...v18.1.8) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 80916a3da..ecf6c8a21 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ ci: autoupdate_branch: 'devel' repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.7 + rev: v18.1.8 hooks: - id: clang-format args: ['--style={BasedOnStyle: Mozilla, SortIncludes: false}'] From 878713040968c491f8cbcf370aa216b62d1936e7 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Jul 2024 15:25:10 +0200 Subject: [PATCH 019/100] pre-commit: Don't autofix PR and update quarterly --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ecf6c8a21..7cec081c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,7 @@ ci: autoupdate_branch: 'devel' + autofix_prs: false + autoupdate_schedule: quarterly repos: - repo: https://github.com/pre-commit/mirrors-clang-format rev: v18.1.8 From 0953d3079799f2be4e3bbe9ff4b3a9ad4ae67beb Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Mon, 15 Jul 2024 17:08:18 +0200 Subject: [PATCH 020/100] cmake: Apply change to be compatible with workspace --- CMakeLists.txt | 3 +++ benchmark/CMakeLists.txt | 4 ++-- bindings/python/CMakeLists.txt | 32 ++++++++++++++++---------------- doc/Doxyfile.extra.in | 6 +++--- examples/cpp/CMakeLists.txt | 8 ++++---- examples/julia/CMakeLists.txt | 5 +++-- examples/python/CMakeLists.txt | 6 +++--- test/CMakeLists.txt | 32 +++++++++++++++++--------------- 8 files changed, 51 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e1f47aac..b9ab33e70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(PROJECT_URL "http://github.com/Simple-Robotics/proxsuite") set(PROJECT_CUSTOM_HEADER_EXTENSION "hpp") set(PROJECT_USE_CMAKE_EXPORT TRUE) set(PROJECT_USE_KEYWORD_LINK_LIBRARIES TRUE) +set(PROJECT_AUTO_RUN_FINALIZE FALSE) # Check if the submodule cmake have been initialized set(JRL_CMAKE_MODULES "${CMAKE_CURRENT_LIST_DIR}/cmake-module") @@ -241,3 +242,5 @@ if(BUILD_PYTHON_INTERFACE) FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/python_path.dsv DESTINATION share/${PROJECT_NAME}/hook) endif(BUILD_PYTHON_INTERFACE) + +setup_project_finalize() diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 0c4f00a43..6f6ea47ef 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,4 +1,4 @@ -add_custom_target(bench) +add_custom_target(${PROJECT_NAME}_bench) macro(proxsuite_benchmark bench_name) if(BUILD_BENCHMARK) @@ -12,7 +12,7 @@ macro(proxsuite_benchmark bench_name) else() target_link_libraries(${bench_name} PUBLIC proxsuite) endif() - add_dependencies(bench ${bench_name}) + add_dependencies(${PROJECT_NAME}_bench ${bench_name}) endmacro(proxsuite_benchmark) proxsuite_benchmark(timings-lp) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index c27344875..02e94c2cc 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -18,7 +18,7 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) add_subdirectory(external/pybind11 ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) -add_custom_target(python) +add_custom_target(${PROJECT_NAME}_python) # Collect files file(GLOB_RECURSE PYWRAP_HEADERS ${CMAKE_CURRENT_LIST_DIR}/src/*.hpp) @@ -27,7 +27,7 @@ file(GLOB_RECURSE PYWRAP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) # Add simd feature detectors for current intel CPU if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") python3_add_library(instructionset MODULE helpers/instruction-set.cpp) - add_dependencies(python instructionset) + add_dependencies(${PROJECT_NAME}_python instructionset) target_link_libraries(instructionset PRIVATE proxsuite pybind11::module) set_target_properties( instructionset @@ -35,18 +35,18 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") PREFIX "" SUFFIX ${PYTHON_EXT_SUFFIX} LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_RELEASE - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_DEBUG - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" # On Windows, shared library are treat as binary RUNTIME_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" RUNTIME_OUTPUT_DIRECTORY_RELEASE - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" RUNTIME_OUTPUT_DIRECTORY_DEBUG - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}") + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}") if(UNIX AND NOT APPLE) set_target_properties(instructionset PROPERTIES INSTALL_RPATH "\$ORIGIN/../../..") @@ -70,7 +70,7 @@ endfunction(list_filter) function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) python3_add_library(${target_name} MODULE ${PYWRAP_SOURCES} ${PYWRAP_HEADERS}) - add_dependencies(python ${target_name}) + add_dependencies(${PROJECT_NAME}_python ${target_name}) target_link_libraries(${target_name} PUBLIC ${dependencies} pybind11::module) target_compile_options(${target_name} PRIVATE ${COMPILE_OPTIONS}) @@ -104,18 +104,18 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) PREFIX "" SUFFIX ${PYTHON_EXT_SUFFIX} LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_RELEASE - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_DEBUG - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" # On Windows, shared library are treat as binary RUNTIME_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" RUNTIME_OUTPUT_DIRECTORY_RELEASE - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" RUNTIME_OUTPUT_DIRECTORY_DEBUG - "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}") + "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}") if(UNIX AND NOT APPLE) set_target_properties(${target_name} PROPERTIES INSTALL_RPATH @@ -195,7 +195,7 @@ else() endif() python_build_get_target(compile_pyc) -add_dependencies(python ${compile_pyc}) +add_dependencies(${PROJECT_NAME}_python ${compile_pyc}) set(PYTHON_FILES torch/__init__.py torch/qplayer.py torch/utils.py) diff --git a/doc/Doxyfile.extra.in b/doc/Doxyfile.extra.in index 13eef9ae3..db68df82d 100644 --- a/doc/Doxyfile.extra.in +++ b/doc/Doxyfile.extra.in @@ -1,5 +1,5 @@ -INPUT = @CMAKE_SOURCE_DIR@/doc \ - @CMAKE_SOURCE_DIR@/include \ +INPUT = @PROJECT_SOURCE_DIR@/doc \ + @PROJECT_SOURCE_DIR@/include \ RECURSIVE = YES @@ -54,7 +54,7 @@ SOURCE_BROWSER = YES ALPHABETICAL_INDEX = YES -USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/doc/1-Overview.md +USE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/doc/1-Overview.md BUILTIN_STL_SUPPORT = YES HAVE_DOT = YES diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index d26c446af..fc055fc2e 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -2,19 +2,19 @@ # Copyright (c) 2022 INRIA # -add_custom_target(example-cpp) +add_custom_target(${PROJECT_NAME}-example-cpp) function(ADD_PROXSUITE_CPP_EXAMPLE EXAMPLE) get_filename_component(EXAMPLE_NAME ${EXAMPLE} NAME_WE) - set(EXAMPLE_TARGET "example-cpp-${EXAMPLE_NAME}") + set(EXAMPLE_TARGET "${PROJECT_NAME}-example-cpp-${EXAMPLE_NAME}") add_unit_test(${EXAMPLE_TARGET} "${EXAMPLE}") target_link_libraries(${EXAMPLE_TARGET} PRIVATE proxsuite-test-util) - add_dependencies(example-cpp ${EXAMPLE_TARGET}) + add_dependencies(${PROJECT_NAME}-example-cpp ${EXAMPLE_TARGET}) endfunction() file(GLOB_RECURSE ${PROJECT_NAME}_CPP_EXAMPLES *.cpp) foreach(EXAMPLE ${${PROJECT_NAME}_CPP_EXAMPLES}) add_proxsuite_cpp_example(${EXAMPLE}) -endforeach(EXAMPLE ${${PROJECT_NAME}_CPP_EXAMPLES}) +endforeach() diff --git a/examples/julia/CMakeLists.txt b/examples/julia/CMakeLists.txt index dd654f27a..e7022ade0 100644 --- a/examples/julia/CMakeLists.txt +++ b/examples/julia/CMakeLists.txt @@ -3,5 +3,6 @@ file(GLOB_RECURSE ${PROJECT_NAME}_JULIA_EXAMPLES *.jl) foreach(EXAMPLE ${${PROJECT_NAME}_JULIA_EXAMPLES}) string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/examples/julia/" "" EXAMPLE ${EXAMPLE}) - add_julia_unit_test("example-jl-${EXAMPLE}" "examples/julia/${EXAMPLE}") -endforeach(EXAMPLE ${${PROJECT_NAME}_JULIA_EXAMPLES}) + add_julia_unit_test("${PROJECT_NAME}-example-jl-${EXAMPLE}" + "examples/julia/${EXAMPLE}") +endforeach() diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt index 16e4e3bd1..fb26dcb3c 100644 --- a/examples/python/CMakeLists.txt +++ b/examples/python/CMakeLists.txt @@ -3,6 +3,6 @@ file(GLOB_RECURSE ${PROJECT_NAME}_PYTHON_EXAMPLES *.py) foreach(EXAMPLE_FILE ${${PROJECT_NAME}_PYTHON_EXAMPLES}) get_filename_component(EXAMPLE_NAME ${EXAMPLE_FILE} NAME_WE) string(REGEX REPLACE "${PROJECT_SOURCE_DIR}" "" EXAMPLE_FILE ${EXAMPLE_FILE}) - add_python_unit_test("example-py-${EXAMPLE_NAME}" "${EXAMPLE_FILE}" - "bindings/python") -endforeach(EXAMPLE_FILE ${${PROJECT_NAME}_PYTHON_EXAMPLES}) + add_python_unit_test("${PROJECT_NAME}-example-py-${EXAMPLE_NAME}" + "${EXAMPLE_FILE}" "bindings/python") +endforeach() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a86bed82b..2bdc74162 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,8 @@ include(../cmake-external/doctest.cmake) find_package(Matio REQUIRED) -add_library(doctest STATIC doctest/doctest.cpp) -target_include_directories(doctest PUBLIC ./doctest) +add_library(${PROJECT_NAME}-doctest STATIC doctest/doctest.cpp) +target_include_directories(${PROJECT_NAME}-doctest PUBLIC ./doctest) add_library(cnpy OBJECT src/cnpy.cpp) target_link_libraries(cnpy Eigen3::Eigen) target_include_directories(cnpy PUBLIC ./include) @@ -20,13 +20,14 @@ else() endif() macro(proxsuite_test name path) - add_executable(test-cpp-${name} ${path}) - doctest_discover_tests(test-cpp-${name}) - target_link_libraries(test-cpp-${name} PUBLIC proxsuite doctest - proxsuite-test-util) - target_compile_definitions(test-cpp-${name} + set(target_name ${PROJECT_NAME}-test-cpp-${name}) + add_executable(${target_name} ${path}) + # doctest_discover_tests(${target_name}) + target_link_libraries(${target_name} PUBLIC proxsuite ${PROJECT_NAME}-doctest + proxsuite-test-util) + target_compile_definitions(${target_name} PRIVATE PROBLEM_PATH="${CMAKE_CURRENT_SOURCE_DIR}") - add_dependencies(build_tests test-cpp-${name}) + add_dependencies(build_tests ${target_name}) endmacro() proxsuite_test(dense_ruiz_equilibration src/dense_ruiz_equilibration.cpp) @@ -45,7 +46,8 @@ proxsuite_test(cvxpy src/cvxpy.cpp) if(BUILD_WITH_OPENMP_SUPPORT) proxsuite_test(parallel src/parallel_qp_solve.cpp) - target_link_libraries(test-cpp-parallel PRIVATE OpenMP::OpenMP_CXX) + target_link_libraries(${PROJECT_NAME}-test-cpp-parallel + PRIVATE OpenMP::OpenMP_CXX) endif() # Test serialization @@ -54,19 +56,19 @@ macro(ADD_TEST_CFLAGS target flag) TARGET ${target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${flag}") -endmacro(ADD_TEST_CFLAGS) +endmacro() make_directory("${CMAKE_CURRENT_BINARY_DIR}/serialization-data") proxsuite_test(serialization src/serialization.cpp) add_test_cflags( - test-cpp-serialization + ${PROJECT_NAME}-test-cpp-serialization "-DTEST_SERIALIZATION_FOLDER=\\\\\"${CMAKE_CURRENT_BINARY_DIR}/serialization-data\\\\\"" ) if(cereal_FOUND) - target_link_libraries(test-cpp-serialization PRIVATE cereal) + target_link_libraries(${PROJECT_NAME}-test-cpp-serialization PRIVATE cereal) else() target_include_directories( - test-cpp-serialization SYSTEM + ${PROJECT_NAME}-test-cpp-serialization SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include) endif() @@ -87,7 +89,7 @@ if(BUILD_PYTHON_INTERFACE) foreach(TEST_FILE ${${PROJECT_NAME}_PYTHON_UNITTEST}) get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE) string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/" "" TEST_FILE ${TEST_FILE}) - add_python_unit_test("test-py-${TEST_NAME}" "${TEST_FILE}" + add_python_unit_test("${PROJECT_NAME}-test-py-${TEST_NAME}" "${TEST_FILE}" "bindings/python") - endforeach(TEST_FILE ${${PROJECT_NAME}_PYTHON_UNITTEST}) + endforeach() endif(BUILD_PYTHON_INTERFACE) From 566aa0d46c7a552d766c062b76712a4186c9e2ac Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 16 Jul 2024 16:42:32 +0200 Subject: [PATCH 021/100] cmake: Configure PROJECT_SOURCE_DIR --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9ab33e70..7f305d3a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) -if(DEFINED PROJECT_NAME) +if(DEFINED PROJECT_NAME AND NOT PROJECT_WORKSPACE) set(PROXSUITE_AS_SUBPROJECT ON) endif() @@ -14,7 +14,10 @@ set(PROJECT_URL "http://github.com/Simple-Robotics/proxsuite") set(PROJECT_CUSTOM_HEADER_EXTENSION "hpp") set(PROJECT_USE_CMAKE_EXPORT TRUE) set(PROJECT_USE_KEYWORD_LINK_LIBRARIES TRUE) +# To enable jrl-cmakemodules compatibility with workspace we must define the two +# following lines set(PROJECT_AUTO_RUN_FINALIZE FALSE) +set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) # Check if the submodule cmake have been initialized set(JRL_CMAKE_MODULES "${CMAKE_CURRENT_LIST_DIR}/cmake-module") From e07ef0fb8ce56c7fcf0f3bd090c698014ef9b9c4 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 16 Jul 2024 16:43:24 +0200 Subject: [PATCH 022/100] cmake: Use topic/workspace jrl-cmakemodules --- .gitmodules | 4 +--- cmake-module | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index ce4fc4593..426d1223f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,9 +3,7 @@ url = https://github.com/pybind/pybind11 [submodule "cmake-module"] path = cmake-module - url = https://github.com/jrl-umi3218/jrl-cmakemodules.git + url = https://github.com/jorisv/jrl-cmakemodules.git [submodule "external/cereal"] path = external/cereal url = https://github.com/USCiLab/cereal.git -[submodule "cmake"] - url = https://github.com/jrl-umi3218/jrl-cmakemodules.git diff --git a/cmake-module b/cmake-module index 2bea127e8..b03972c2a 160000 --- a/cmake-module +++ b/cmake-module @@ -1 +1 @@ -Subproject commit 2bea127e8113a32f216ae7a7201e36a6e7c56cc2 +Subproject commit b03972c2aab5d4ed63bc7cc596d29328f388ef83 From 8f99186c00eccb74e305b74c5dac026f305d0bd2 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 16 Jul 2024 16:44:57 +0200 Subject: [PATCH 023/100] changelog: Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fcef102b..7b563420a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added * Allow use of installed cereal and jrl-cmakemodules via cmake +* Add compatibility with jrl-cmakemodules workspace ([#339](https://github.com/Simple-Robotics/proxsuite/pull/339)) ## [0.6.6] - 2024-06-15 From f733f5c50fd42ea965f3bb557b9258969a8782a7 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Wed, 24 Jul 2024 10:40:59 +0200 Subject: [PATCH 024/100] cmake: Switch to upstream jrl-cmakemodules --- .gitmodules | 2 +- cmake-module | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 426d1223f..69ac5fe4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/pybind/pybind11 [submodule "cmake-module"] path = cmake-module - url = https://github.com/jorisv/jrl-cmakemodules.git + url = https://github.com/jrl-umi3218/jrl-cmakemodules.git [submodule "external/cereal"] path = external/cereal url = https://github.com/USCiLab/cereal.git diff --git a/cmake-module b/cmake-module index b03972c2a..91b8f5f21 160000 --- a/cmake-module +++ b/cmake-module @@ -1 +1 @@ -Subproject commit b03972c2aab5d4ed63bc7cc596d29328f388ef83 +Subproject commit 91b8f5f2168b123a198da079b8e6c09fd1f60285 From 81a44532b0240de54ecca242f0be0ae63b05b730 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:30:59 +0200 Subject: [PATCH 025/100] specify timings in microseconds --- bindings/python/src/expose-solve.hpp | 9 +++++--- doc/2-ProxQP_api.md | 2 +- doc/3-ProxQP_solve.md | 2 +- include/proxsuite/proxqp/dense/solver.hpp | 26 +++++++++++----------- include/proxsuite/proxqp/settings.hpp | 6 ++--- include/proxsuite/proxqp/sparse/solver.hpp | 24 ++++++++++---------- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/bindings/python/src/expose-solve.hpp b/bindings/python/src/expose-solve.hpp index 8a0a2f091..038bccaec 100644 --- a/bindings/python/src/expose-solve.hpp +++ b/bindings/python/src/expose-solve.hpp @@ -82,7 +82,8 @@ solveDenseQp(pybind11::module_ m) true, "executes the default preconditioner for reducing ill " "conditioning and speeding up the solver."), - pybind11::arg_v("compute_timings", false, "compute solver's timings."), + pybind11::arg_v( + "compute_timings", false, "compute solver's timings in μs."), pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), pybind11::arg_v( "initial_guess", @@ -177,7 +178,8 @@ solveDenseQp(pybind11::module_ m) true, "executes the default preconditioner for reducing ill " "conditioning and speeding up the solver."), - pybind11::arg_v("compute_timings", false, "compute solver's timings."), + pybind11::arg_v( + "compute_timings", false, "compute solver's timings in μs."), pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), pybind11::arg_v( "initial_guess", @@ -255,7 +257,8 @@ solveSparseQp(pybind11::module_ m) true, "executes the default preconditioner for reducing ill " "conditioning and speeding up the solver."), - pybind11::arg_v("compute_timings", false, "compute solver's timings."), + pybind11::arg_v( + "compute_timings", false, "compute solver's timings in μs."), pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), pybind11::arg_v("initial_guess", proxsuite::proxqp::InitialGuessStatus:: diff --git a/doc/2-ProxQP_api.md b/doc/2-ProxQP_api.md index 592274d2e..fedebac47 100644 --- a/doc/2-ProxQP_api.md +++ b/doc/2-ProxQP_api.md @@ -388,7 +388,7 @@ In this table, you have the three columns from left to right: the name of the se | default_rho | 1.E-6 | Default rho parameter of result class (i.e., for each initial guess, except WARM_START_WITH_PREVIOUS_RESULT, after a new solve or update, the solver initializes rho to this value). | default_mu_eq | 1.E-3 | Default mu_eq parameter of result class (i.e., for each initial guess, except WARM_START_WITH_PREVIOUS_RESULT, after a new solve or update, the solver initializes mu_eq to this value). | default_mu_in | 1.E-1 | Default mu_in parameter of result class (i.e., for each initial guess, except WARM_START_WITH_PREVIOUS_RESULT, after a new solve or update, the solver initializes mu_in to this value). -| compute_timings | False | If set to true, timings will be computed by the solver (setup time, solving time, and run time = setup time + solving time). +| compute_timings | False | If set to true, timings in microseconds will be computed by the solver (setup time, solving time, and run time = setup time + solving time). | max_iter | 10.000 | Maximal number of authorized outer iterations. | max_iter_in | 1500 | Maximal number of authorized inner iterations. | initial_guess | EQUALITY_CONSTRAINED_INITIAL_GUESS | Sets the initial guess option for initilizing x, y and z. diff --git a/doc/3-ProxQP_solve.md b/doc/3-ProxQP_solve.md index 59371c87e..79223f605 100644 --- a/doc/3-ProxQP_solve.md +++ b/doc/3-ProxQP_solve.md @@ -113,7 +113,7 @@ Different options are available for the solve function. In the table below you h | rho | 1.E-6 | Proximal step size wrt primal variable. | VERBOSE | False | If set to true, the solver prints information at each loop. | compute_preconditioner | True | If set to true, the preconditioner will be derived. -| compute_timings | False | If set to true, timings will be computed by the solver (setup time, solving time, and run time = setup time + solving time). +| compute_timings | False | If set to true, timings in microseconds will be computed by the solver (setup time, solving time, and run time = setup time + solving time). | max_iter | 10.000 | Maximal number of authorized outer iterations. | initial_guess | EQUALITY_CONSTRAINED_INITIAL_GUESS | Sets the initial guess option for initilizing x, y and z. diff --git a/include/proxsuite/proxqp/dense/solver.hpp b/include/proxsuite/proxqp/dense/solver.hpp index 5710fe6db..0e544c3ac 100644 --- a/include/proxsuite/proxqp/dense/solver.hpp +++ b/include/proxsuite/proxqp/dense/solver.hpp @@ -1778,7 +1778,7 @@ qp_solve( // } if (qpsettings.compute_timings) { - qpresults.info.solve_time = qpwork.timer.elapsed().user; // in nanoseconds + qpresults.info.solve_time = qpwork.timer.elapsed().user; // in microseconds qpresults.info.run_time = qpresults.info.solve_time + qpresults.info.setup_time; } @@ -1786,46 +1786,46 @@ qp_solve( // if (qpsettings.verbose) { std::cout << "-------------------SOLVER STATISTICS-------------------" << std::endl; - std::cout << "outer iter: " << qpresults.info.iter_ext << std::endl; - std::cout << "total iter: " << qpresults.info.iter << std::endl; - std::cout << "mu updates: " << qpresults.info.mu_updates << std::endl; - std::cout << "rho updates: " << qpresults.info.rho_updates << std::endl; - std::cout << "objective: " << qpresults.info.objValue << std::endl; + std::cout << "outer iter: " << qpresults.info.iter_ext << std::endl; + std::cout << "total iter: " << qpresults.info.iter << std::endl; + std::cout << "mu updates: " << qpresults.info.mu_updates << std::endl; + std::cout << "rho updates: " << qpresults.info.rho_updates << std::endl; + std::cout << "objective: " << qpresults.info.objValue << std::endl; switch (qpresults.info.status) { case QPSolverOutput::PROXQP_SOLVED: { - std::cout << "status: " + std::cout << "status: " << "Solved" << std::endl; break; } case QPSolverOutput::PROXQP_MAX_ITER_REACHED: { - std::cout << "status: " + std::cout << "status: " << "Maximum number of iterations reached" << std::endl; break; } case QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Primal infeasible" << std::endl; break; } case QPSolverOutput::PROXQP_DUAL_INFEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Dual infeasible" << std::endl; break; } case QPSolverOutput::PROXQP_SOLVED_CLOSEST_PRIMAL_FEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Solved closest primal feasible" << std::endl; break; } case QPSolverOutput::PROXQP_NOT_RUN: { - std::cout << "status: " + std::cout << "status: " << "Solver not run" << std::endl; break; } } if (qpsettings.compute_timings) - std::cout << "run time: " << qpresults.info.solve_time << std::endl; + std::cout << "run time [μs]: " << qpresults.info.solve_time << std::endl; std::cout << "--------------------------------------------------------" << std::endl; } diff --git a/include/proxsuite/proxqp/settings.hpp b/include/proxsuite/proxqp/settings.hpp index b3d7ce264..f455238b4 100644 --- a/include/proxsuite/proxqp/settings.hpp +++ b/include/proxsuite/proxqp/settings.hpp @@ -182,9 +182,9 @@ struct Settings * re-computed when calling the update method. * @param compute_preconditioner If set to true, the preconditioner will be * computed with the init method. - * @param compute_timings If set to true, timings will be computed by the - * solver (setup time, solving time, and run time = setup time + solving - * time). + * @param compute_timings If set to true, timings in microseconds will be + * computed by the solver (setup time, solving time, and run time = setup time + * + solving time). * @param check_duality_gap If set to true, duality gap will be calculated and * included in the stopping criterion. * @param eps_duality_gap_abs absolute duality-gap stopping criterion. diff --git a/include/proxsuite/proxqp/sparse/solver.hpp b/include/proxsuite/proxqp/sparse/solver.hpp index 609d2b84d..c2ecd56dd 100644 --- a/include/proxsuite/proxqp/sparse/solver.hpp +++ b/include/proxsuite/proxqp/sparse/solver.hpp @@ -1623,45 +1623,45 @@ qp_solve(Results& results, if (settings.verbose) { std::cout << "-------------------SOLVER STATISTICS-------------------" << std::endl; - std::cout << "outer iter: " << results.info.iter_ext << std::endl; - std::cout << "total iter: " << results.info.iter << std::endl; - std::cout << "mu updates: " << results.info.mu_updates << std::endl; - std::cout << "rho updates: " << results.info.rho_updates << std::endl; - std::cout << "objective: " << results.info.objValue << std::endl; + std::cout << "outer iter: " << results.info.iter_ext << std::endl; + std::cout << "total iter: " << results.info.iter << std::endl; + std::cout << "mu updates: " << results.info.mu_updates << std::endl; + std::cout << "rho updates: " << results.info.rho_updates << std::endl; + std::cout << "objective: " << results.info.objValue << std::endl; switch (results.info.status) { case QPSolverOutput::PROXQP_SOLVED: { - std::cout << "status: " + std::cout << "status: " << "Solved" << std::endl; break; } case QPSolverOutput::PROXQP_MAX_ITER_REACHED: { - std::cout << "status: " + std::cout << "status: " << "Maximum number of iterations reached" << std::endl; break; } case QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Primal infeasible" << std::endl; break; } case QPSolverOutput::PROXQP_DUAL_INFEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Dual infeasible" << std::endl; break; } case QPSolverOutput::PROXQP_SOLVED_CLOSEST_PRIMAL_FEASIBLE: { - std::cout << "status: " + std::cout << "status: " << "Solved closest primal feasible" << std::endl; break; } case QPSolverOutput::PROXQP_NOT_RUN: { - std::cout << "status: " + std::cout << "status: " << "Solver not run" << std::endl; break; } } if (settings.compute_timings) - std::cout << "run time: " << results.info.solve_time << std::endl; + std::cout << "run time [μs]: " << results.info.solve_time << std::endl; std::cout << "--------------------------------------------------------" << std::endl; } From 9a447e7a0e42a90d4389b9b58024db059619c245 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:08:42 +0200 Subject: [PATCH 026/100] add hint to pass `-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX` for build - discussed with @Bambade --- doc/5-installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/5-installation.md b/doc/5-installation.md index 376f679c7..67dc810af 100644 --- a/doc/5-installation.md +++ b/doc/5-installation.md @@ -27,6 +27,8 @@ make make install ``` +Note: if you are building Proxsuite within a conda environment, consider passing `-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX`. + 3. Build the Python interface You just need to ensure that Python3 is indeed present on your system and activate the cmake option `BUILD_PYTHON_INTERFACE=ON` by replacing: From 1c693475323b524453be7bb47c211bcc6a34fc1c Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:14:26 +0200 Subject: [PATCH 027/100] fix cereal include directories in cmake --- bindings/python/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 02e94c2cc..252063b87 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -92,7 +92,8 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) endif(BUILD_WITH_OPENMP_SUPPORT) if(cereal_FOUND) - target_link_libraries(${target_name} SYSTEM PRIVATE cereal) + target_include_directories(${target_name} SYSTEM + PRIVATE ${CEREAL_INCLUDE_DIRS}) else() target_include_directories( ${target_name} SYSTEM From c42274937f7001aaba46af36b13fd1e9cea1a6f6 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:17:55 +0200 Subject: [PATCH 028/100] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b563420a..867375bff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added * Allow use of installed cereal and jrl-cmakemodules via cmake * Add compatibility with jrl-cmakemodules workspace ([#339](https://github.com/Simple-Robotics/proxsuite/pull/339)) +* Specifically mention that timings are in microseconds ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) +* Fix cereal include directory in cmake ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) +* Extend doc with hint for conda installation from source ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) ## [0.6.6] - 2024-06-15 From 89c647c6b34e041508b0ebc7323a8e54992f4f13 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 00:10:42 +0000 Subject: [PATCH 029/100] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 24.4.2 → 24.8.0](https://github.com/psf/black/compare/24.4.2...24.8.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7cec081c7..8c69882f7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: hooks: - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.8.0 hooks: - id: black - repo: https://github.com/cheshirekow/cmake-format-precommit From 7d8cc7301c54a1593469f74dbf985846ca23fe17 Mon Sep 17 00:00:00 2001 From: abambade Date: Mon, 29 Jul 2024 16:26:55 +0200 Subject: [PATCH 030/100] qplayer - infeasible case : fix dimensional typo for double sided inequalities --- bindings/python/proxsuite/torch/qplayer.py | 40 ++++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/bindings/python/proxsuite/torch/qplayer.py b/bindings/python/proxsuite/torch/qplayer.py index 1c9955946..c7076eaa5 100644 --- a/bindings/python/proxsuite/torch/qplayer.py +++ b/bindings/python/proxsuite/torch/qplayer.py @@ -256,6 +256,7 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus): class QPFunctionFn_infeas(Function): @staticmethod def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): + n_in, nz = G_.size() # true double-sided inequality size nBatch = extract_nBatch(Q_, p_, A_, b_, G_, l_, u_) Q, _ = expandParam(Q_, nBatch, 3) @@ -276,6 +277,7 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): zhats = torch.empty((nBatch, ctx.nz), dtype=Q.dtype) nus = torch.empty((nBatch, ctx.nineq), dtype=Q.dtype) + nus_sol = torch.empty((nBatch, n_in), dtype=Q.dtype) # double-sided inequality multiplier lams = ( torch.empty(nBatch, ctx.neq, dtype=Q.dtype) if ctx.neq > 0 @@ -287,7 +289,7 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): else torch.empty() ) slacks = torch.empty((nBatch, ctx.nineq), dtype=Q.dtype) - s_i = torch.empty((nBatch, ctx.nineq), dtype=Q.dtype) + s_i = torch.empty((nBatch, n_in), dtype=Q.dtype) # this one is of size the one of the original n_in vector_of_qps = proxsuite.proxqp.dense.BatchQP() @@ -339,20 +341,23 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): vector_of_qps.get(i).solve() for i in range(nBatch): - si = -h[i] + G[i] @ vector_of_qps.get(i).results.x zhats[i] = torch.tensor(vector_of_qps.get(i).results.x) - nus[i] = torch.tensor(vector_of_qps.get(i).results.z) - slacks[i] = si.clone().detach() + if nineq>0: + # we re-convert the solution to a double sided inequality QP + slack = -h[i] + G[i] @ vector_of_qps.get(i).results.x + nus_sol[i] = torch.Tensor(-vector_of_qps.get(i).results.z[:n_in]+vector_of_qps.get(i).results.z[n_in:]) # de-projecting this one may provoke loss of information when using inexact solution + nus[i] = torch.tensor(vector_of_qps.get(i).results.z) + slacks[i] = slack.clone().detach() + s_i[i] = torch.tensor(-vector_of_qps.get(i).results.si[:n_in]+vector_of_qps.get(i).results.si[n_in:]) if neq > 0: lams[i] = torch.tensor(vector_of_qps.get(i).results.y) s_e[i] = torch.tensor(vector_of_qps.get(i).results.se) - s_i[i] = torch.tensor(vector_of_qps.get(i).results.si) - + ctx.lams = lams ctx.nus = nus ctx.slacks = slacks ctx.save_for_backward(zhats, s_e, Q_, p_, G_, l_, u_, A_, b_) - return zhats, lams, nus, s_e, s_i + return zhats, lams, nus_sol, s_e, s_i @staticmethod def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): @@ -371,6 +376,8 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): G = torch.cat((-G, G), axis=1) neq, nineq = ctx.neq, ctx.nineq + # true size + n_in_sol = int(nineq/2) dx = torch.zeros((nBatch, Q.shape[1])) dnu = None b_5 = None @@ -457,15 +464,26 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): rhs = np.zeros(kkt.shape[0]) rhs[:dim] = -dl_dzhat[i] if dl_dlams != None: - rhs[dim : dim + n_eq] = -dl_dlams[i] + if n_eq!= 0: + rhs[dim : dim + n_eq] = -dl_dlams[i] + active_set = None + if n_in!=0: + active_set = -z_i[:n_in_sol]+z_i[n_in_sol:] >= 0 if dl_dnus != None: - rhs[dim + n_eq : dim + n_eq + n_in] = -dl_dnus[i] + if n_in !=0: + # we must convert dl_dnus to a uni sided version + # to do so we reconstitute the active set + rhs[dim + n_eq : dim + n_eq + n_in_sol][~active_set] = dl_dnus[i][~active_set] + rhs[dim + n_eq + n_in_sol: dim + n_eq + n_in][active_set] = -dl_dnus[i][active_set] if dl_ds_e != None: if dl_ds_e.shape[0] != 0: rhs[dim + n_eq + n_in : dim + 2 * n_eq + n_in] = -dl_ds_e[i] if dl_ds_i != None: if dl_ds_i.shape[0] != 0: - rhs[dim + 2 * n_eq + n_in :] = -dl_ds_i[i] + # we must convert dl_dnus to a uni sided version + # to do so we reconstitute the active set + rhs[dim + 2 * n_eq + n_in : dim + 2 * n_eq + n_in + n_in_sol][~active_set] = dl_ds_i[i][~active_set] + rhs[dim + 2 * n_eq + n_in + n_in_sol:][active_set] = -dl_ds_i[i][active_set] l = np.zeros(0) u = np.zeros(0) @@ -562,7 +580,7 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): if p_e: dps = dps.mean(0) - grads = (dQs, dps, dAs, dbs, dGs[nineq:, :], -dhs[:nineq], dhs[nineq:]) + grads = (dQs, dps, dAs, dbs, dGs[n_in_sol:, :], -dhs[:n_in_sol], dhs[n_in_sol:]) return grads From fd23b2134051585224a861552d0467b75e4b99a1 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Wed, 7 Aug 2024 10:11:35 +0200 Subject: [PATCH 031/100] changelog: sync --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 867375bff..7d2870e3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Fix cereal include directory in cmake ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) * Extend doc with hint for conda installation from source ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) +### Fixed +* Fix inequality constraints return in QPLayer ([#343](https://github.com/Simple-Robotics/proxsuite/pull/343)) + ## [0.6.6] - 2024-06-15 ### Fixed From 25827f61f11ca3348288c1406ba9cf8392ef04d1 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Thu, 8 Aug 2024 15:14:29 +0200 Subject: [PATCH 032/100] CMake: allow use of installed dependencies, take 2 (#337) * CMake: allow use of installed pybind11 * CMake: modernize cereal use * changelog: sync --- CHANGELOG.md | 2 +- bindings/python/CMakeLists.txt | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 867375bff..2f1395f0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added -* Allow use of installed cereal and jrl-cmakemodules via cmake +* Allow use of installed pybind11, cereal and jrl-cmakemodules via cmake * Add compatibility with jrl-cmakemodules workspace ([#339](https://github.com/Simple-Robotics/proxsuite/pull/339)) * Specifically mention that timings are in microseconds ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) * Fix cereal include directory in cmake ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 252063b87..9f2f93d30 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -14,9 +14,12 @@ else() ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME}) endif() -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) -add_subdirectory(external/pybind11 - ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) +find_package(pybind11 CONFIG) +if(NOT pybind11_FOUND) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) + add_subdirectory(external/pybind11 + ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) +endif() add_custom_target(${PROJECT_NAME}_python) @@ -92,8 +95,7 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) endif(BUILD_WITH_OPENMP_SUPPORT) if(cereal_FOUND) - target_include_directories(${target_name} SYSTEM - PRIVATE ${CEREAL_INCLUDE_DIRS}) + target_link_libraries(${target_name} PRIVATE cereal::cereal) else() target_include_directories( ${target_name} SYSTEM From 315f4d301fb1e9666108737f36c22996cae1785e Mon Sep 17 00:00:00 2001 From: Wilson Date: Wed, 14 Aug 2024 13:27:46 +0200 Subject: [PATCH 033/100] Refactor Python examples with a new "util.py" file (#347) * [examples/python] Add util.py file, move "generate_mixed_qp" function to it give reg a meaning * update CHANGELOG * apply suggestion --- CHANGELOG.md | 4 +++ .../python/estimate_nonconvex_eigenvalue.py | 27 +--------------- examples/python/init_dense_qp.py | 27 +--------------- examples/python/init_dense_qp_with_box.py | 27 +--------------- .../init_dense_qp_with_other_options.py | 27 +--------------- examples/python/init_dense_qp_with_timings.py | 27 +--------------- examples/python/init_with_default_options.py | 27 +--------------- examples/python/loading_sparse_qp.py | 29 ++--------------- examples/python/overview-simple.py | 27 +--------------- examples/python/solve_dense_qp.py | 27 +--------------- .../python/solve_dense_qp_with_setting.py | 27 +--------------- examples/python/solve_without_api.py | 29 ++--------------- .../python/solve_without_api_and_option.py | 27 +--------------- examples/python/update_dense_qp.py | 28 +--------------- .../update_dense_qp_ws_previous_result.py | 28 +--------------- examples/python/update_sparse_qp.py | 32 ++----------------- examples/python/util.py | 31 ++++++++++++++++++ 17 files changed, 54 insertions(+), 397 deletions(-) create mode 100644 examples/python/util.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f1395f0b..c95665016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Fix cereal include directory in cmake ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) * Extend doc with hint for conda installation from source ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) +### Changed + +* Refactor Python examples with a new "util.py" file ([#347](https://github.com/Simple-Robotics/proxsuite/pull/347)) + ## [0.6.6] - 2024-06-15 ### Fixed diff --git a/examples/python/estimate_nonconvex_eigenvalue.py b/examples/python/estimate_nonconvex_eigenvalue.py index 21e2e54ef..7b6ecac59 100644 --- a/examples/python/estimate_nonconvex_eigenvalue.py +++ b/examples/python/estimate_nonconvex_eigenvalue.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1, reg=-2.0): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/init_dense_qp.py b/examples/python/init_dense_qp.py index d76736360..4408870f4 100644 --- a/examples/python/init_dense_qp.py +++ b/examples/python/init_dense_qp.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/init_dense_qp_with_box.py b/examples/python/init_dense_qp_with_box.py index 268e96e8b..15aa61c69 100644 --- a/examples/python/init_dense_qp_with_box.py +++ b/examples/python/init_dense_qp_with_box.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/init_dense_qp_with_other_options.py b/examples/python/init_dense_qp_with_other_options.py index 8b3faa97a..dbc9b4ab4 100644 --- a/examples/python/init_dense_qp_with_other_options.py +++ b/examples/python/init_dense_qp_with_other_options.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/init_dense_qp_with_timings.py b/examples/python/init_dense_qp_with_timings.py index 09cb66e2c..b156bd4c5 100644 --- a/examples/python/init_dense_qp_with_timings.py +++ b/examples/python/init_dense_qp_with_timings.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/init_with_default_options.py b/examples/python/init_with_default_options.py index caf2929c5..133cbb6cf 100644 --- a/examples/python/init_with_default_options.py +++ b/examples/python/init_with_default_options.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/loading_sparse_qp.py b/examples/python/loading_sparse_qp.py index f762fb096..7b8b3f880 100644 --- a/examples/python/loading_sparse_qp.py +++ b/examples/python/loading_sparse_qp.py @@ -8,36 +8,11 @@ import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc") - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp2 object using matrix masks -H, g, A, b, C, u, l = generate_mixed_qp(n) +H, g, A, b, C, u, l = generate_mixed_qp(n, True) H_ = H != 0.0 A_ = A != 0.0 diff --git a/examples/python/overview-simple.py b/examples/python/overview-simple.py index cc0fbb438..e220efb8b 100644 --- a/examples/python/overview-simple.py +++ b/examples/python/overview-simple.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # generate a qp problem diff --git a/examples/python/solve_dense_qp.py b/examples/python/solve_dense_qp.py index 4eb04547c..d3cd330bc 100644 --- a/examples/python/solve_dense_qp.py +++ b/examples/python/solve_dense_qp.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/solve_dense_qp_with_setting.py b/examples/python/solve_dense_qp_with_setting.py index 5999037e1..0673a0f99 100644 --- a/examples/python/solve_dense_qp_with_setting.py +++ b/examples/python/solve_dense_qp_with_setting.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/solve_without_api.py b/examples/python/solve_without_api.py index 9e84676fc..3a489203a 100644 --- a/examples/python/solve_without_api.py +++ b/examples/python/solve_without_api.py @@ -1,39 +1,14 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc") - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions n = 10 n_eq = 2 n_in = 2 -H, g, A, b, C, u, l = generate_mixed_qp(n) +H, g, A, b, C, u, l = generate_mixed_qp(n, True) # solve the problem using the sparse backend results = proxsuite.proxqp.sparse.solve(H, g, A, b, C, l, u) diff --git a/examples/python/solve_without_api_and_option.py b/examples/python/solve_without_api_and_option.py index 9e1cea272..930715dc8 100644 --- a/examples/python/solve_without_api_and_option.py +++ b/examples/python/solve_without_api_and_option.py @@ -1,32 +1,7 @@ import proxsuite import numpy as np import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/update_dense_qp.py b/examples/python/update_dense_qp.py index 106d8f544..5ceab125f 100644 --- a/examples/python/update_dense_qp.py +++ b/examples/python/update_dense_qp.py @@ -1,32 +1,6 @@ import proxsuite import numpy as np -import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/update_dense_qp_ws_previous_result.py b/examples/python/update_dense_qp_ws_previous_result.py index e8289490b..3e9b995a8 100644 --- a/examples/python/update_dense_qp_ws_previous_result.py +++ b/examples/python/update_dense_qp_ws_previous_result.py @@ -1,32 +1,6 @@ import proxsuite import numpy as np -import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating sparse random convex qps in dense format - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions diff --git a/examples/python/update_sparse_qp.py b/examples/python/update_sparse_qp.py index 12bfe7886..f52319139 100644 --- a/examples/python/update_sparse_qp.py +++ b/examples/python/update_sparse_qp.py @@ -1,32 +1,6 @@ import proxsuite import numpy as np -import scipy.sparse as spa - - -def generate_mixed_qp(n, seed=1): - # A function for generating random convex qps - - np.random.seed(seed) - n_eq = int(n / 4) - n_in = int(n / 4) - m = n_eq + n_in - - P = spa.random( - n, n, density=0.075, data_rvs=np.random.randn, format="csc" - ).toarray() - P = (P + P.T) / 2.0 - - s = max(np.absolute(np.linalg.eigvals(P))) - P += (abs(s) + 1e-02) * spa.eye(n) - P = spa.coo_matrix(P) - q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc") - v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality - u = A @ v - l = -1.0e20 * np.ones(m) - - return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] +from util import generate_mixed_qp # load a qp object using qp problem dimensions @@ -35,7 +9,7 @@ def generate_mixed_qp(n, seed=1): n_in = 2 qp = proxsuite.proxqp.sparse.QP(n, n_eq, n_in) # generate a random QP -H, g, A, b, C, u, l = generate_mixed_qp(n) +H, g, A, b, C, u, l = generate_mixed_qp(n, True) # initialize the model of the problem to solve qp.init(H, g, A, b, C, l, u) qp.solve() @@ -44,7 +18,7 @@ def generate_mixed_qp(n, seed=1): qp.solve() # generate a QP with another sparsity structure # create a new problem and update qp -H2, g_new, A_new, b_new, C_new, u_new, l_new = generate_mixed_qp(n) +H2, g_new, A_new, b_new, C_new, u_new, l_new = generate_mixed_qp(n, True) qp.update(H=H2) # nothing will happen qp.update(g=g_new) # if only a vector changes, then the update takes effect qp.solve() # it solves the problem with the QP H,g_new,A,b,C,u,l diff --git a/examples/python/util.py b/examples/python/util.py new file mode 100644 index 000000000..53c0c53da --- /dev/null +++ b/examples/python/util.py @@ -0,0 +1,31 @@ +import numpy as np +import scipy.sparse as spa + + +def generate_mixed_qp(n, sparse=False, seed=1, reg=1e-2, dens1=0.075): + # A function for generating sparse random convex qps + + np.random.seed(seed) + n_eq = int(n / 4) + n_in = int(n / 4) + m = n_eq + n_in + + P = spa.random( + n, n, density=dens1, data_rvs=np.random.randn, format="csc" + ).toarray() + P = (P + P.T) / 2.0 + + s = max(np.absolute(np.linalg.eigvals(P))) + P += (abs(s) + reg) * spa.eye(n) + P = spa.coo_matrix(P) + q = np.random.randn(n) + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc") + if not sparse: + A = A.toarray() + P = P.toarray() + v = np.random.randn(n) # Fictitious solution + delta = np.random.rand(m) # To get inequality + u = A @ v + l = -1.0e20 * np.ones(m) + + return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] From 22d0d91d1b3178a47578dfc988431e6b5cdfcb4a Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 20 Aug 2024 17:34:44 +0200 Subject: [PATCH 034/100] [examples/python] minor fix --- examples/python/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/util.py b/examples/python/util.py index 53c0c53da..75efea225 100644 --- a/examples/python/util.py +++ b/examples/python/util.py @@ -28,4 +28,4 @@ def generate_mixed_qp(n, sparse=False, seed=1, reg=1e-2, dens1=0.075): u = A @ v l = -1.0e20 * np.ones(m) - return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] + return P, q, A[:n_eq, :], u[:n_eq], A[n_eq:, :], u[n_eq:], l[n_eq:] From 0021dbc5a6161d24748f7ce7aedf1b74d8473dc0 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:51:27 +0200 Subject: [PATCH 035/100] fix `mu_update` for `PrimalLDLT` backend --- include/proxsuite/proxqp/dense/solver.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/proxsuite/proxqp/dense/solver.hpp b/include/proxsuite/proxqp/dense/solver.hpp index 0e544c3ac..e2ec81633 100644 --- a/include/proxsuite/proxqp/dense/solver.hpp +++ b/include/proxsuite/proxqp/dense/solver.hpp @@ -212,14 +212,14 @@ mu_update(const Model& qpmodel, } } qpwork.ldl.rank_r_update( - new_cols, qpwork.dw_aug.head(qpmodel.dim), stack); + new_cols, qpwork.dw_aug.head(qpwork.n_c), stack); } // mu update for A { LDLT_TEMP_MAT_UNINIT(T, new_cols, qpmodel.dim, qpmodel.n_eq, stack); new_cols = qpwork.A_scaled.transpose(); qpwork.ldl.rank_r_update( - new_cols, qpwork.dw_aug.head(qpmodel.dim), stack); + new_cols, qpwork.dw_aug.head(qpmodel.n_eq), stack); } } break; case DenseBackend::Automatic: From ddd876655c46e6cfdcf4d502ef4b995d611bb5ed Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:51:44 +0200 Subject: [PATCH 036/100] fix typo in `mu_update` --- include/proxsuite/proxqp/dense/solver.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/proxsuite/proxqp/dense/solver.hpp b/include/proxsuite/proxqp/dense/solver.hpp index e2ec81633..9a3c1a5cf 100644 --- a/include/proxsuite/proxqp/dense/solver.hpp +++ b/include/proxsuite/proxqp/dense/solver.hpp @@ -195,7 +195,7 @@ mu_update(const Model& qpmodel, { LDLT_TEMP_MAT_UNINIT(T, new_cols, qpmodel.dim, qpwork.n_c, stack); qpwork.dw_aug.head(qpmodel.dim).setOnes(); - T delta_mu(mu_in_new - qpresults.info.mu_in_inv); + T delta_mu(1 / mu_in_new - qpresults.info.mu_in_inv); qpwork.dw_aug.head(qpmodel.dim).array() *= delta_mu; for (isize i = 0; i < n_constraints; ++i) { isize j = qpwork.current_bijection_map[i]; From fa9066ec39746ccc0baff93a5d745db27120a2a9 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:52:38 +0200 Subject: [PATCH 037/100] update dw for eq. constraints --- include/proxsuite/proxqp/dense/solver.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/proxsuite/proxqp/dense/solver.hpp b/include/proxsuite/proxqp/dense/solver.hpp index 9a3c1a5cf..9bc5bc002 100644 --- a/include/proxsuite/proxqp/dense/solver.hpp +++ b/include/proxsuite/proxqp/dense/solver.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // /** * @file solver.hpp @@ -217,6 +217,9 @@ mu_update(const Model& qpmodel, // mu update for A { LDLT_TEMP_MAT_UNINIT(T, new_cols, qpmodel.dim, qpmodel.n_eq, stack); + qpwork.dw_aug.head(qpmodel.n_eq).setOnes(); + T delta_mu(1 / mu_eq_new - qpresults.info.mu_eq_inv); + qpwork.dw_aug.head(qpmodel.n_eq).array() *= delta_mu; new_cols = qpwork.A_scaled.transpose(); qpwork.ldl.rank_r_update( new_cols, qpwork.dw_aug.head(qpmodel.n_eq), stack); From 2507ef7f2e6eb469e176c89b2b7e90f67bc5bad0 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:41:41 +0200 Subject: [PATCH 038/100] add unittest for mu_update with PrimalLDLT --- test/src/dense_qp_wrapper.cpp | 59 ++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/test/src/dense_qp_wrapper.cpp b/test/src/dense_qp_wrapper.cpp index d51f8609a..353fb7dce 100644 --- a/test/src/dense_qp_wrapper.cpp +++ b/test/src/dense_qp_wrapper.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // #include #include @@ -7614,3 +7614,60 @@ TEST_CASE("ProxQP::dense: test memory allocation when estimating biggest " dense::power_iteration(H, dw, rhs, err_v, 1.E-6, 10000); PROXSUITE_EIGEN_MALLOC_ALLOWED(); } + +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with" + "inequality constraints: test PrimalLDLT backend mu update") +{ + + std::cout << "---testing sparse random strongly convex qp with" + "inequality constraints: test PrimalLDLT backend mu update---" + << std::endl; + double sparsity_factor = 1; + utils::rand::set_seed(1); + isize dim = 3; + isize n_eq(0); + isize n_in(9); + T strong_convexity_factor(1.e-2); + proxqp::dense::Model qp_random = proxqp::utils::dense_strongly_convex_qp( + dim, n_eq, n_in, sparsity_factor, strong_convexity_factor); + dense::QP qp{ + dim, + n_eq, + n_in, + false, + proxsuite::proxqp::HessianType::Dense, + proxsuite::proxqp::DenseBackend::PrimalLDLT + }; // creating QP object + T eps_abs = T(1e-7); + qp.settings.eps_abs = eps_abs; + qp.settings.eps_rel = 0; + qp.settings.compute_timings = true; + qp.settings.verbose = true; + qp.init(qp_random.H, + qp_random.g, + nullopt, + nullopt, + qp_random.C, + nullopt, + qp_random.u); + qp.solve(); + + DOCTEST_CHECK(qp.results.info.mu_updates > 0); + + T pri_res = (helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) + .lpNorm(); + T dua_res = (qp_random.H * qp.results.x + qp_random.g + + qp_random.C.transpose() * qp.results.z) + .lpNorm(); + DOCTEST_CHECK(pri_res <= eps_abs); + DOCTEST_CHECK(dua_res <= eps_abs); + + std::cout << "------using API solving qp with dim: " << dim + << " neq: " << n_eq << " nin: " << n_in << std::endl; + std::cout << "primal residual: " << pri_res << std::endl; + std::cout << "dual residual: " << dua_res << std::endl; + std::cout << "total number of iteration: " << qp.results.info.iter + << std::endl; + std::cout << "setup timing " << qp.results.info.setup_time << " solve time " + << qp.results.info.solve_time << std::endl; +} From c5f734b410bebd594c68a9a9a41ee2aed154b393 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:13:22 +0200 Subject: [PATCH 039/100] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c95665016..0df499d8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added +* Fix mu update function for PrimalLDLT backend ([#349](https://github.com/Simple-Robotics/proxsuite/pull/349)) * Allow use of installed pybind11, cereal and jrl-cmakemodules via cmake * Add compatibility with jrl-cmakemodules workspace ([#339](https://github.com/Simple-Robotics/proxsuite/pull/339)) * Specifically mention that timings are in microseconds ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) From bc54ff3011f03d0e9fdfa0fddc62db76c2c5c401 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:44:32 +0200 Subject: [PATCH 040/100] Update include/proxsuite/proxqp/dense/solver.hpp Co-authored-by: Justin Carpentier --- include/proxsuite/proxqp/dense/solver.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/proxsuite/proxqp/dense/solver.hpp b/include/proxsuite/proxqp/dense/solver.hpp index 9bc5bc002..6d428ae64 100644 --- a/include/proxsuite/proxqp/dense/solver.hpp +++ b/include/proxsuite/proxqp/dense/solver.hpp @@ -195,7 +195,7 @@ mu_update(const Model& qpmodel, { LDLT_TEMP_MAT_UNINIT(T, new_cols, qpmodel.dim, qpwork.n_c, stack); qpwork.dw_aug.head(qpmodel.dim).setOnes(); - T delta_mu(1 / mu_in_new - qpresults.info.mu_in_inv); + T delta_mu(T(1) / mu_in_new - qpresults.info.mu_in_inv); qpwork.dw_aug.head(qpmodel.dim).array() *= delta_mu; for (isize i = 0; i < n_constraints; ++i) { isize j = qpwork.current_bijection_map[i]; From 769e4501be747c37749265ff72525be01edfabff Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Sat, 15 Jun 2024 10:02:31 +0200 Subject: [PATCH 041/100] cmake: sync submodule --- cmake-module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake-module b/cmake-module index 91b8f5f21..b3c2af1b6 160000 --- a/cmake-module +++ b/cmake-module @@ -1 +1 @@ -Subproject commit 91b8f5f2168b123a198da079b8e6c09fd1f60285 +Subproject commit b3c2af1b68686dc9d5f459fb617647e37a15a76d From c66e6662296e19ab17d35327d76ddc7f2ceafba7 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Tue, 27 Aug 2024 10:21:06 +0200 Subject: [PATCH 042/100] pre-commit: format --- bindings/python/proxsuite/torch/qplayer.py | 66 +++++++++++++++------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/bindings/python/proxsuite/torch/qplayer.py b/bindings/python/proxsuite/torch/qplayer.py index c7076eaa5..f3cee2b1b 100644 --- a/bindings/python/proxsuite/torch/qplayer.py +++ b/bindings/python/proxsuite/torch/qplayer.py @@ -256,7 +256,7 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus): class QPFunctionFn_infeas(Function): @staticmethod def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): - n_in, nz = G_.size() # true double-sided inequality size + n_in, nz = G_.size() # true double-sided inequality size nBatch = extract_nBatch(Q_, p_, A_, b_, G_, l_, u_) Q, _ = expandParam(Q_, nBatch, 3) @@ -277,7 +277,9 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): zhats = torch.empty((nBatch, ctx.nz), dtype=Q.dtype) nus = torch.empty((nBatch, ctx.nineq), dtype=Q.dtype) - nus_sol = torch.empty((nBatch, n_in), dtype=Q.dtype) # double-sided inequality multiplier + nus_sol = torch.empty( + (nBatch, n_in), dtype=Q.dtype + ) # double-sided inequality multiplier lams = ( torch.empty(nBatch, ctx.neq, dtype=Q.dtype) if ctx.neq > 0 @@ -289,7 +291,9 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): else torch.empty() ) slacks = torch.empty((nBatch, ctx.nineq), dtype=Q.dtype) - s_i = torch.empty((nBatch, n_in), dtype=Q.dtype) # this one is of size the one of the original n_in + s_i = torch.empty( + (nBatch, n_in), dtype=Q.dtype + ) # this one is of size the one of the original n_in vector_of_qps = proxsuite.proxqp.dense.BatchQP() @@ -342,17 +346,23 @@ def forward(ctx, Q_, p_, A_, b_, G_, l_, u_): for i in range(nBatch): zhats[i] = torch.tensor(vector_of_qps.get(i).results.x) - if nineq>0: + if nineq > 0: # we re-convert the solution to a double sided inequality QP slack = -h[i] + G[i] @ vector_of_qps.get(i).results.x - nus_sol[i] = torch.Tensor(-vector_of_qps.get(i).results.z[:n_in]+vector_of_qps.get(i).results.z[n_in:]) # de-projecting this one may provoke loss of information when using inexact solution + nus_sol[i] = torch.Tensor( + -vector_of_qps.get(i).results.z[:n_in] + + vector_of_qps.get(i).results.z[n_in:] + ) # de-projecting this one may provoke loss of information when using inexact solution nus[i] = torch.tensor(vector_of_qps.get(i).results.z) slacks[i] = slack.clone().detach() - s_i[i] = torch.tensor(-vector_of_qps.get(i).results.si[:n_in]+vector_of_qps.get(i).results.si[n_in:]) + s_i[i] = torch.tensor( + -vector_of_qps.get(i).results.si[:n_in] + + vector_of_qps.get(i).results.si[n_in:] + ) if neq > 0: lams[i] = torch.tensor(vector_of_qps.get(i).results.y) s_e[i] = torch.tensor(vector_of_qps.get(i).results.se) - + ctx.lams = lams ctx.nus = nus ctx.slacks = slacks @@ -377,7 +387,7 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): neq, nineq = ctx.neq, ctx.nineq # true size - n_in_sol = int(nineq/2) + n_in_sol = int(nineq / 2) dx = torch.zeros((nBatch, Q.shape[1])) dnu = None b_5 = None @@ -464,26 +474,34 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): rhs = np.zeros(kkt.shape[0]) rhs[:dim] = -dl_dzhat[i] if dl_dlams != None: - if n_eq!= 0: + if n_eq != 0: rhs[dim : dim + n_eq] = -dl_dlams[i] - active_set = None - if n_in!=0: - active_set = -z_i[:n_in_sol]+z_i[n_in_sol:] >= 0 + active_set = None + if n_in != 0: + active_set = -z_i[:n_in_sol] + z_i[n_in_sol:] >= 0 if dl_dnus != None: - if n_in !=0: + if n_in != 0: # we must convert dl_dnus to a uni sided version - # to do so we reconstitute the active set - rhs[dim + n_eq : dim + n_eq + n_in_sol][~active_set] = dl_dnus[i][~active_set] - rhs[dim + n_eq + n_in_sol: dim + n_eq + n_in][active_set] = -dl_dnus[i][active_set] + # to do so we reconstitute the active set + rhs[dim + n_eq : dim + n_eq + n_in_sol][~active_set] = dl_dnus[ + i + ][~active_set] + rhs[dim + n_eq + n_in_sol : dim + n_eq + n_in][active_set] = ( + -dl_dnus[i][active_set] + ) if dl_ds_e != None: if dl_ds_e.shape[0] != 0: rhs[dim + n_eq + n_in : dim + 2 * n_eq + n_in] = -dl_ds_e[i] if dl_ds_i != None: if dl_ds_i.shape[0] != 0: # we must convert dl_dnus to a uni sided version - # to do so we reconstitute the active set - rhs[dim + 2 * n_eq + n_in : dim + 2 * n_eq + n_in + n_in_sol][~active_set] = dl_ds_i[i][~active_set] - rhs[dim + 2 * n_eq + n_in + n_in_sol:][active_set] = -dl_ds_i[i][active_set] + # to do so we reconstitute the active set + rhs[dim + 2 * n_eq + n_in : dim + 2 * n_eq + n_in + n_in_sol][ + ~active_set + ] = dl_ds_i[i][~active_set] + rhs[dim + 2 * n_eq + n_in + n_in_sol :][active_set] = -dl_ds_i[ + i + ][active_set] l = np.zeros(0) u = np.zeros(0) @@ -580,7 +598,15 @@ def backward(ctx, dl_dzhat, dl_dlams, dl_dnus, dl_ds_e, dl_ds_i): if p_e: dps = dps.mean(0) - grads = (dQs, dps, dAs, dbs, dGs[n_in_sol:, :], -dhs[:n_in_sol], dhs[n_in_sol:]) + grads = ( + dQs, + dps, + dAs, + dbs, + dGs[n_in_sol:, :], + -dhs[:n_in_sol], + dhs[n_in_sol:], + ) return grads From 29f96083e21d18c879f5a732336ec19e557580b2 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Tue, 27 Aug 2024 11:08:14 +0200 Subject: [PATCH 043/100] release: Update package.xml version to 0.6.7 --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 9fe309bed..4aa4539ae 100644 --- a/package.xml +++ b/package.xml @@ -1,7 +1,7 @@ proxsuite - 0.6.6 + 0.6.7 The Advanced Proximal Optimization Toolbox Justin Carpentier From 9a90f97364cb1c0dfc51ebb7c531b1ce22a2ea89 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Tue, 27 Aug 2024 11:08:17 +0200 Subject: [PATCH 044/100] release: Update pyproject.toml version to 0.6.7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 186eaf6d6..e40bd4616 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "proxsuite" -version = "0.6.6" +version = "0.6.7" description = "Quadratic Programming Solver for Robotics and beyond." readme = "README.md" requires-python = ">= 3.7" From c90564b68b5d3205b0fe3e232c7cec5e79f69360 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Tue, 27 Aug 2024 11:08:19 +0200 Subject: [PATCH 045/100] release: Update CHANGELOG.md for 0.6.7 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9703885fc..e7f6fad16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [0.6.7] - 2024-08-27 + ### Added * Fix mu update function for PrimalLDLT backend ([#349](https://github.com/Simple-Robotics/proxsuite/pull/349)) * Allow use of installed pybind11, cereal and jrl-cmakemodules via cmake @@ -429,7 +431,8 @@ More to come ([#](a forthcoming release.)) The first release of ProxSuite. -[Unreleased]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.6...HEAD +[Unreleased]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.7...HEAD +[0.6.7]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.6...v0.6.7 [0.6.6]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.5...v0.6.6 [0.6.5]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.4...v0.6.5 [0.6.4]: https://github.com/Simple-Robotics/proxsuite/compare/v0.6.3...v0.6.4 From 72f8c3b13e4c5929f1767bd0ebb4718b1fa3e9a7 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Tue, 27 Aug 2024 11:08:21 +0200 Subject: [PATCH 046/100] release: Update CITATION.cff version to 0.6.7 --- CITATION.cff | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 2def662cd..fd84309e6 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,7 +14,7 @@ authors: - family-names: Carpentier given-names: Justin orcid: "https://orcid.org/0000-0001-6585-2894" -version: 0.6.6 -date-released: "2024-06-15" +version: 0.6.7 +date-released: "2024-08-27" license: BSD-2-Clause repository-code: "https://github.com/Simple-Robotics/proxsuite" From f004de9da9c5a6d860e569a38190ec9c38cd8107 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 15:38:38 +0200 Subject: [PATCH 047/100] [python/external] swap out pybind11 for nanobind --- .gitmodules | 6 +++--- bindings/python/external/nanobind | 1 + bindings/python/external/pybind11 | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) create mode 160000 bindings/python/external/nanobind delete mode 160000 bindings/python/external/pybind11 diff --git a/.gitmodules b/.gitmodules index 69ac5fe4e..2867bf33b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "external/pybind11"] - path = bindings/python/external/pybind11 - url = https://github.com/pybind/pybind11 +[submodule "bindings/python/external/nanobind"] + path = bindings/python/external/nanobind + url = https://github.com/wjakob/nanobind [submodule "cmake-module"] path = cmake-module url = https://github.com/jrl-umi3218/jrl-cmakemodules.git diff --git a/bindings/python/external/nanobind b/bindings/python/external/nanobind new file mode 160000 index 000000000..8d7f1ee06 --- /dev/null +++ b/bindings/python/external/nanobind @@ -0,0 +1 @@ +Subproject commit 8d7f1ee0621c17fa370b704b2100ffa0243d5bfb diff --git a/bindings/python/external/pybind11 b/bindings/python/external/pybind11 deleted file mode 160000 index 849322806..000000000 --- a/bindings/python/external/pybind11 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 849322806cd4b3697ad1d35eedd6d0352c5f267a From d28e4ebbd4b65dbfab00d74840259f6e588d7c71 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 18:11:00 +0200 Subject: [PATCH 048/100] [bindings/python] update CMake listfile, targets and instruction-set.cpp for nanobind [bindings/python] cmake : nanobind's helper function already sets prefix and suffix for us. --- bindings/python/CMakeLists.txt | 25 +++++++++------------ bindings/python/helpers/instruction-set.cpp | 4 ++-- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 9f2f93d30..d6b3cf216 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -6,6 +6,7 @@ include(${JRL_CMAKE_MODULES}/python.cmake) include(${JRL_CMAKE_MODULES}/python-helpers.cmake) findpython(REQUIRED Development.Module) +find_package(Python 3.8 COMPONENTS ${PYTHON_COMPONENTS}) if(IS_ABSOLUTE ${PYTHON_SITELIB}) set(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME}) @@ -14,12 +15,9 @@ else() ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME}) endif() -find_package(pybind11 CONFIG) -if(NOT pybind11_FOUND) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) - add_subdirectory(external/pybind11 - ${CMAKE_CURRENT_BINARY_DIR}/external/pybind11) -endif() +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) +add_subdirectory(external/nanobind + ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) add_custom_target(${PROJECT_NAME}_python) @@ -29,14 +27,12 @@ file(GLOB_RECURSE PYWRAP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) # Add simd feature detectors for current intel CPU if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - python3_add_library(instructionset MODULE helpers/instruction-set.cpp) + nanobind_add_module(instructionset helpers/instruction-set.cpp) add_dependencies(${PROJECT_NAME}_python instructionset) - target_link_libraries(instructionset PRIVATE proxsuite pybind11::module) + target_link_libraries(instructionset PRIVATE proxsuite) set_target_properties( instructionset PROPERTIES OUTPUT_NAME instructionset - PREFIX "" - SUFFIX ${PYTHON_EXT_SUFFIX} LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_RELEASE @@ -72,12 +68,13 @@ function(list_filter list regular_expression dest_list) endfunction(list_filter) function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) - python3_add_library(${target_name} MODULE ${PYWRAP_SOURCES} ${PYWRAP_HEADERS}) + nanobind_add_module(${target_name} ${PYWRAP_SOURCES} + ${PYWRAP_HEADERS}) add_dependencies(${PROJECT_NAME}_python ${target_name}) - target_link_libraries(${target_name} PUBLIC ${dependencies} pybind11::module) + target_link_libraries(${target_name} PUBLIC ${dependencies}) target_compile_options(${target_name} PRIVATE ${COMPILE_OPTIONS}) - target_link_libraries(${target_name} PRIVATE proxsuite pybind11::module) + target_link_libraries(${target_name} PRIVATE proxsuite) target_compile_definitions(${target_name} PRIVATE PYTHON_MODULE_NAME=${target_name}) @@ -104,8 +101,6 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) set_target_properties( ${target_name} PROPERTIES OUTPUT_NAME ${target_name} - PREFIX "" - SUFFIX ${PYTHON_EXT_SUFFIX} LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" LIBRARY_OUTPUT_DIRECTORY_RELEASE diff --git a/bindings/python/helpers/instruction-set.cpp b/bindings/python/helpers/instruction-set.cpp index c99c43672..40342bb85 100644 --- a/bindings/python/helpers/instruction-set.cpp +++ b/bindings/python/helpers/instruction-set.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // -#include +#include #include @@ -10,7 +10,7 @@ namespace proxsuite { namespace helpers { namespace python { -PYBIND11_MODULE(instructionset, m) +NB_MODULE(instructionset, m) { m.doc() = R"pbdoc( CPU info library From 7168637f2d27e7a467875b2dce92210b7d10cf6d Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 19:59:01 +0200 Subject: [PATCH 049/100] [bindings/python] instruction-set.cpp : fix crashes because of lack of std::string support + add relevant nanobind stl support header --- bindings/python/helpers/instruction-set.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/helpers/instruction-set.cpp b/bindings/python/helpers/instruction-set.cpp index 40342bb85..cc92bf214 100644 --- a/bindings/python/helpers/instruction-set.cpp +++ b/bindings/python/helpers/instruction-set.cpp @@ -3,6 +3,7 @@ // #include +#include #include From 14ab3a38fdb69d4633be06c72c3fa4b55d4cc3b3 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:00:02 +0200 Subject: [PATCH 050/100] [proxqp/sparse] explicitly delete copy ctor and operator, fixing confusion with is_copy_constructible-type traits --- include/proxsuite/proxqp/sparse/wrapper.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/proxsuite/proxqp/sparse/wrapper.hpp b/include/proxsuite/proxqp/sparse/wrapper.hpp index b9884bc7e..6cfa48641 100644 --- a/include/proxsuite/proxqp/sparse/wrapper.hpp +++ b/include/proxsuite/proxqp/sparse/wrapper.hpp @@ -147,6 +147,11 @@ struct QP } } + QP(const QP&) = delete; + QP& operator=(const QP&) = delete; + QP(QP&&) = default; + QP& operator=(QP&&) = default; + /*! * Setups the QP model (with sparse matrix format) and equilibrates it. * @param H quadratic cost input defining the QP model. @@ -814,6 +819,10 @@ struct BatchQP } m_size = 0; } + BatchQP(const BatchQP&) = delete; + BatchQP& operator=(const BatchQP&) = delete; + BatchQP(BatchQP&&) = default; + BatchQP& operator=(BatchQP&&) = default; /*! * Init a QP in place and return a reference to it From a0a97fa7d65630ade9da5b42b7127e06910d64cb Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:01:15 +0200 Subject: [PATCH 051/100] [bindings/python] expose-all.cpp : do pybind11 -> nanobind swap --- bindings/python/src/expose-all.cpp | 38 ++++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/bindings/python/src/expose-all.cpp b/bindings/python/src/expose-all.cpp index 78545620b..cdfc4f87c 100644 --- a/bindings/python/src/expose-all.cpp +++ b/bindings/python/src/expose-all.cpp @@ -1,10 +1,12 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // #include -#include -#include +#include +#include +#include +#include #include "algorithms.hpp" #include @@ -16,7 +18,7 @@ namespace python { template void -exposeCommon(pybind11::module_ m) +exposeCommon(nanobind::module_ m) { exposeResults(m); exposeSettings(m); @@ -29,7 +31,7 @@ exposeCommon(pybind11::module_ m) template void -exposeSparseAlgorithms(pybind11::module_ m) +exposeSparseAlgorithms(nanobind::module_ m) { sparse::python::exposeSparseModel(m); sparse::python::exposeQpObjectSparse(m); @@ -40,7 +42,7 @@ exposeSparseAlgorithms(pybind11::module_ m) template void -exposeDenseAlgorithms(pybind11::module_ m) +exposeDenseAlgorithms(nanobind::module_ m) { dense::python::exposeWorkspaceDense(m); dense::python::exposeDenseModel(m); @@ -51,7 +53,7 @@ exposeDenseAlgorithms(pybind11::module_ m) } template void -exposeBackward(pybind11::module_ m) +exposeBackward(nanobind::module_ m) { dense::python::backward(m); } @@ -59,19 +61,19 @@ exposeBackward(pybind11::module_ m) #ifdef PROXSUITE_PYTHON_INTERFACE_WITH_OPENMP template void -exposeDenseParallel(pybind11::module_ m) +exposeDenseParallel(nanobind::module_ m) { dense::python::solveDenseQpParallel(m); } template void -exposeSparseParallel(pybind11::module_ m) +exposeSparseParallel(nanobind::module_ m) { sparse::python::solveSparseQpParallel(m); } #endif -PYBIND11_MODULE(PYTHON_MODULE_NAME, m) +NB_MODULE(PYTHON_MODULE_NAME, m) { m.doc() = R"pbdoc( The proxSuite library @@ -84,17 +86,17 @@ PYBIND11_MODULE(PYTHON_MODULE_NAME, m) proxsuite )pbdoc"; - pybind11::module_ proxqp_module = + nanobind::module_ proxqp_module = m.def_submodule("proxqp", "The proxQP solvers of the proxSuite library"); exposeCommon(proxqp_module); - pybind11::module_ dense_module = + nanobind::module_ dense_module = proxqp_module.def_submodule("dense", "Dense solver of proxQP"); exposeDenseAlgorithms(dense_module); exposeBackward(dense_module); #ifdef PROXSUITE_PYTHON_INTERFACE_WITH_OPENMP exposeDenseParallel(dense_module); #endif - pybind11::module_ sparse_module = + nanobind::module_ sparse_module = proxqp_module.def_submodule("sparse", "Sparse solver of proxQP"); exposeSparseAlgorithms(sparse_module); #ifdef PROXSUITE_PYTHON_INTERFACE_WITH_OPENMP @@ -105,17 +107,17 @@ PYBIND11_MODULE(PYTHON_MODULE_NAME, m) m.attr("__version__") = helpers::printVersion(); // Add helpers - pybind11::module_ helpers_module = + nanobind::module_ helpers_module = m.def_submodule("helpers", "Helper module"); helpers_module.def("printVersion", helpers::printVersion, - pybind11::arg("delimiter") = ".", + nanobind::arg("delimiter") = ".", "Print the current version of the package."); helpers_module.def("checkVersionAtLeast", helpers::checkVersionAtLeast, - pybind11::arg("major_version"), - pybind11::arg("minor_version"), - pybind11::arg("patch_version"), + nanobind::arg("major_version"), + nanobind::arg("minor_version"), + nanobind::arg("patch_version"), "Check version of the package is at least greater than " "the one provided as input."); } From 86863f25792ce44db659d392c58eb50a36c32566 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:02:27 +0200 Subject: [PATCH 052/100] [bindings/python] expose-workspace.hpp : do pybind11 -> nanobind swap + only concerns def_* methods and pickling (now managed manually through setting the relevant special methods) --- bindings/python/src/expose-workspace.hpp | 130 +++++++++++------------ 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/bindings/python/src/expose-workspace.hpp b/bindings/python/src/expose-workspace.hpp index f827f4f34..9fa9fde65 100644 --- a/bindings/python/src/expose-workspace.hpp +++ b/bindings/python/src/expose-workspace.hpp @@ -1,87 +1,81 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // -#include -#include +#include +#include +#include #include #include #include #include #include -#include "helpers.hpp" + namespace proxsuite { namespace proxqp { namespace dense { namespace python { template void -exposeWorkspaceDense(pybind11::module_ m) +exposeWorkspaceDense(nanobind::module_ m) { - ::pybind11::class_>( - m, "workspace", pybind11::module_local()) - .def(::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + ::nanobind::class_>(m, "workspace") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Constructor using QP model dimensions.") // constructor) - .def_readonly("H_scaled", &Workspace::H_scaled) - .def_readonly("g_scaled", &Workspace::g_scaled) - .def_readonly("A_scaled", &Workspace::A_scaled) - .def_readonly("C_scaled", &Workspace::C_scaled) - .def_readonly("b_scaled", &Workspace::b_scaled) - .def_readonly("u_scaled", &Workspace::u_scaled) - .def_readonly("l_scaled", &Workspace::l_scaled) - .def_readonly("x_prev", &Workspace::x_prev) - .def_readonly("y_prev", &Workspace::y_prev) - .def_readonly("z_prev", &Workspace::z_prev) - .def_readonly("kkt", &Workspace::kkt) - .def_readonly("current_bijection_map", &Workspace::current_bijection_map) - .def_readonly("new_bijection_map", &Workspace::new_bijection_map) - .def_readonly("active_set_up", &Workspace::active_set_up) - .def_readonly("active_set_low", &Workspace::active_set_low) - .def_readonly("active_inequalities", &Workspace::active_inequalities) - .def_readonly("Hdx", &Workspace::Hdx) - .def_readonly("Cdx", &Workspace::Cdx) - .def_readonly("Adx", &Workspace::Adx) - .def_readonly("active_part_z", &Workspace::active_part_z) - .def_readonly("alphas", &Workspace::alphas) - .def_readonly("dw_aug", &Workspace::dw_aug) - .def_readonly("rhs", &Workspace::rhs) - .def_readonly("err", &Workspace::err) - .def_readonly("dual_feasibility_rhs_2", - &Workspace::dual_feasibility_rhs_2) - .def_readonly("correction_guess_rhs_g", - &Workspace::correction_guess_rhs_g) - .def_readonly("correction_guess_rhs_b", - &Workspace::correction_guess_rhs_b) - .def_readonly("alpha", &Workspace::alpha) - .def_readonly("dual_residual_scaled", &Workspace::dual_residual_scaled) - .def_readonly("primal_residual_in_scaled_up", - &Workspace::primal_residual_in_scaled_up) - .def_readonly("primal_residual_in_scaled_up_plus_alphaCdx", - &Workspace::primal_residual_in_scaled_up_plus_alphaCdx) - .def_readonly("primal_residual_in_scaled_low_plus_alphaCdx", - &Workspace::primal_residual_in_scaled_low_plus_alphaCdx) - .def_readonly("CTz", &Workspace::CTz) - .def_readonly("constraints_changed", &Workspace::constraints_changed) - .def_readonly("dirty", &Workspace::dirty) - .def_readonly("refactorize", &Workspace::refactorize) - .def_readonly("proximal_parameter_update", - &Workspace::proximal_parameter_update) - .def_readonly("is_initialized", &Workspace::is_initialized) - .def_readonly("n_c", &Workspace::n_c) - .def(pybind11::pickle( - - [](const Workspace& workspace) { - return pybind11::bytes( - proxsuite::serialization::saveToString(workspace)); - }, - [](pybind11::bytes& s) { - Workspace workspace; - proxsuite::serialization::loadFromString(workspace, s); - return workspace; - })); + .def_ro("H_scaled", &Workspace::H_scaled) + .def_ro("g_scaled", &Workspace::g_scaled) + .def_ro("A_scaled", &Workspace::A_scaled) + .def_ro("C_scaled", &Workspace::C_scaled) + .def_ro("b_scaled", &Workspace::b_scaled) + .def_ro("u_scaled", &Workspace::u_scaled) + .def_ro("l_scaled", &Workspace::l_scaled) + .def_ro("x_prev", &Workspace::x_prev) + .def_ro("y_prev", &Workspace::y_prev) + .def_ro("z_prev", &Workspace::z_prev) + .def_ro("kkt", &Workspace::kkt) + .def_ro("current_bijection_map", &Workspace::current_bijection_map) + .def_ro("new_bijection_map", &Workspace::new_bijection_map) + .def_ro("active_set_up", &Workspace::active_set_up) + .def_ro("active_set_low", &Workspace::active_set_low) + .def_ro("active_inequalities", &Workspace::active_inequalities) + .def_ro("Hdx", &Workspace::Hdx) + .def_ro("Cdx", &Workspace::Cdx) + .def_ro("Adx", &Workspace::Adx) + .def_ro("active_part_z", &Workspace::active_part_z) + .def_ro("alphas", &Workspace::alphas) + .def_ro("dw_aug", &Workspace::dw_aug) + .def_ro("rhs", &Workspace::rhs) + .def_ro("err", &Workspace::err) + .def_ro("dual_feasibility_rhs_2", &Workspace::dual_feasibility_rhs_2) + .def_ro("correction_guess_rhs_g", &Workspace::correction_guess_rhs_g) + .def_ro("correction_guess_rhs_b", &Workspace::correction_guess_rhs_b) + .def_ro("alpha", &Workspace::alpha) + .def_ro("dual_residual_scaled", &Workspace::dual_residual_scaled) + .def_ro("primal_residual_in_scaled_up", + &Workspace::primal_residual_in_scaled_up) + .def_ro("primal_residual_in_scaled_up_plus_alphaCdx", + &Workspace::primal_residual_in_scaled_up_plus_alphaCdx) + .def_ro("primal_residual_in_scaled_low_plus_alphaCdx", + &Workspace::primal_residual_in_scaled_low_plus_alphaCdx) + .def_ro("CTz", &Workspace::CTz) + .def_ro("constraints_changed", &Workspace::constraints_changed) + .def_ro("dirty", &Workspace::dirty) + .def_ro("refactorize", &Workspace::refactorize) + .def_ro("proximal_parameter_update", + &Workspace::proximal_parameter_update) + .def_ro("is_initialized", &Workspace::is_initialized) + .def_ro("n_c", &Workspace::n_c) + .def("__getstate__", + [](const Workspace& workspace) { + return proxsuite::serialization::saveToString(workspace); + }) + .def("__setstate__", [](Workspace& workspace, nanobind::bytes& s) { + new (&workspace) Workspace{}; + proxsuite::serialization::loadFromString(workspace, s.c_str()); + }); ; } From 82d372fced20b26da6ac1a805f40dca5c52f26c1 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:03:28 +0200 Subject: [PATCH 053/100] [bindings/python] helpers.hpp : do pybind11 -> nanobind swap --- bindings/python/src/helpers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/src/helpers.hpp b/bindings/python/src/helpers.hpp index cd0fe716a..fc7c37de6 100644 --- a/bindings/python/src/helpers.hpp +++ b/bindings/python/src/helpers.hpp @@ -5,7 +5,7 @@ #define proxsuite_python_helpers_hpp #define PROXSUITE_PYTHON_EIGEN_READWRITE(class, field_name, doc) \ - def_property( \ + def_prop_rw( \ #field_name, \ [](class& self) { return self.field_name; }, \ [](class& self, const decltype(class ::field_name)& value) { \ From 887b5c3b03ddd790992db26c57b78177fd6069c3 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:04:42 +0200 Subject: [PATCH 054/100] [bindings/python] expose-settings.hpp : do pybind11 -> nanobind swap + concerns def_* methods and pickling (now managed manually through setting the relevant special methods) + remove module_local(), as it is not supported in nanobind: https://nanobind.readthedocs.io/en/latest/porting.html#removed-features --- bindings/python/src/expose-settings.hpp | 139 +++++++++++------------- 1 file changed, 65 insertions(+), 74 deletions(-) diff --git a/bindings/python/src/expose-settings.hpp b/bindings/python/src/expose-settings.hpp index c9188ca1d..4569f7d3e 100644 --- a/bindings/python/src/expose-settings.hpp +++ b/bindings/python/src/expose-settings.hpp @@ -1,9 +1,10 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // -#include -#include -#include +#include +#include +#include +#include #include #include @@ -15,11 +16,10 @@ namespace proxqp { namespace python { template void -exposeSettings(pybind11::module_ m) +exposeSettings(nanobind::module_ m) { - ::pybind11::enum_( - m, "InitialGuess", pybind11::module_local()) + ::nanobind::enum_(m, "InitialGuess") .value("NO_INITIAL_GUESS", InitialGuessStatus::NO_INITIAL_GUESS) .value("EQUALITY_CONSTRAINED_INITIAL_GUESS", InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS) @@ -30,85 +30,76 @@ exposeSettings(pybind11::module_ m) InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT) .export_values(); - ::pybind11::enum_( - m, "MeritFunctionType", pybind11::module_local()) + ::nanobind::enum_(m, "MeritFunctionType") .value("GPDAL", MeritFunctionType::GPDAL) .value("PDAL", MeritFunctionType::PDAL) .export_values(); - ::pybind11::enum_(m, "SparseBackend", pybind11::module_local()) + ::nanobind::enum_(m, "SparseBackend") .value("Automatic", SparseBackend::Automatic) .value("MatrixFree", SparseBackend::MatrixFree) .value("SparseCholesky", SparseBackend::SparseCholesky) .export_values(); - ::pybind11::enum_( - m, "EigenValueEstimateMethodOption", pybind11::module_local()) + ::nanobind::enum_( + m, "EigenValueEstimateMethodOption") .value("PowerIteration", EigenValueEstimateMethodOption::PowerIteration) .value("ExactMethod", EigenValueEstimateMethodOption::ExactMethod) .export_values(); - ::pybind11::class_>(m, "Settings", pybind11::module_local()) - .def(::pybind11::init(), "Default constructor.") // constructor - .def_readwrite("default_rho", &Settings::default_rho) - .def_readwrite("default_mu_eq", &Settings::default_mu_eq) - .def_readwrite("default_mu_in", &Settings::default_mu_in) - .def_readwrite("alpha_bcl", &Settings::alpha_bcl) - .def_readwrite("beta_bcl", &Settings::beta_bcl) - .def_readwrite("refactor_dual_feasibility_threshold", - &Settings::refactor_dual_feasibility_threshold) - .def_readwrite("refactor_rho_threshold", - &Settings::refactor_rho_threshold) - .def_readwrite("mu_min_eq", &Settings::mu_min_eq) - .def_readwrite("mu_min_in", &Settings::mu_min_in) - .def_readwrite("mu_max_eq_inv", &Settings::mu_max_eq_inv) - .def_readwrite("mu_max_in_inv", &Settings::mu_max_in_inv) - .def_readwrite("mu_update_factor", &Settings::mu_update_factor) - .def_readwrite("cold_reset_mu_eq", &Settings::cold_reset_mu_eq) - .def_readwrite("cold_reset_mu_in", &Settings::cold_reset_mu_in) - .def_readwrite("max_iter", &Settings::max_iter) - .def_readwrite("max_iter_in", &Settings::max_iter_in) - .def_readwrite("eps_abs", &Settings::eps_abs) - .def_readwrite("eps_rel", &Settings::eps_rel) - .def_readwrite("eps_primal_inf", &Settings::eps_primal_inf) - .def_readwrite("eps_dual_inf", &Settings::eps_dual_inf) - .def_readwrite("nb_iterative_refinement", - &Settings::nb_iterative_refinement) - .def_readwrite("initial_guess", &Settings::initial_guess) - .def_readwrite("sparse_backend", &Settings::sparse_backend) - .def_readwrite("preconditioner_accuracy", - &Settings::preconditioner_accuracy) - .def_readwrite("preconditioner_max_iter", - &Settings::preconditioner_max_iter) - .def_readwrite("compute_timings", &Settings::compute_timings) - .def_readwrite("compute_preconditioner", - &Settings::compute_preconditioner) - .def_readwrite("update_preconditioner", &Settings::update_preconditioner) - .def_readwrite("check_duality_gap", &Settings::check_duality_gap) - .def_readwrite("eps_duality_gap_abs", &Settings::eps_duality_gap_abs) - .def_readwrite("eps_duality_gap_rel", &Settings::eps_duality_gap_rel) - .def_readwrite("verbose", &Settings::verbose) - .def_readwrite("bcl_update", &Settings::bcl_update) - .def_readwrite("merit_function_type", &Settings::merit_function_type) - .def_readwrite("alpha_gpdal", &Settings::alpha_gpdal) - .def_readwrite("primal_infeasibility_solving", - &Settings::primal_infeasibility_solving) - .def_readwrite("frequence_infeasibility_check", - &Settings::frequence_infeasibility_check) - .def_readwrite("default_H_eigenvalue_estimate", - &Settings::default_H_eigenvalue_estimate) - .def(pybind11::self == pybind11::self) - .def(pybind11::self != pybind11::self) - .def(pybind11::pickle( - - [](const Settings& settings) { - return pybind11::bytes( - proxsuite::serialization::saveToString(settings)); - }, - [](pybind11::bytes& s) { - Settings settings; - proxsuite::serialization::loadFromString(settings, s); - return settings; - })); + ::nanobind::class_>(m, "Settings") + .def(::nanobind::init(), "Default constructor.") // constructor + .def_rw("default_rho", &Settings::default_rho) + .def_rw("default_mu_eq", &Settings::default_mu_eq) + .def_rw("default_mu_in", &Settings::default_mu_in) + .def_rw("alpha_bcl", &Settings::alpha_bcl) + .def_rw("beta_bcl", &Settings::beta_bcl) + .def_rw("refactor_dual_feasibility_threshold", + &Settings::refactor_dual_feasibility_threshold) + .def_rw("refactor_rho_threshold", &Settings::refactor_rho_threshold) + .def_rw("mu_min_eq", &Settings::mu_min_eq) + .def_rw("mu_min_in", &Settings::mu_min_in) + .def_rw("mu_max_eq_inv", &Settings::mu_max_eq_inv) + .def_rw("mu_max_in_inv", &Settings::mu_max_in_inv) + .def_rw("mu_update_factor", &Settings::mu_update_factor) + .def_rw("cold_reset_mu_eq", &Settings::cold_reset_mu_eq) + .def_rw("cold_reset_mu_in", &Settings::cold_reset_mu_in) + .def_rw("max_iter", &Settings::max_iter) + .def_rw("max_iter_in", &Settings::max_iter_in) + .def_rw("eps_abs", &Settings::eps_abs) + .def_rw("eps_rel", &Settings::eps_rel) + .def_rw("eps_primal_inf", &Settings::eps_primal_inf) + .def_rw("eps_dual_inf", &Settings::eps_dual_inf) + .def_rw("nb_iterative_refinement", &Settings::nb_iterative_refinement) + .def_rw("initial_guess", &Settings::initial_guess) + .def_rw("sparse_backend", &Settings::sparse_backend) + .def_rw("preconditioner_accuracy", &Settings::preconditioner_accuracy) + .def_rw("preconditioner_max_iter", &Settings::preconditioner_max_iter) + .def_rw("compute_timings", &Settings::compute_timings) + .def_rw("compute_preconditioner", &Settings::compute_preconditioner) + .def_rw("update_preconditioner", &Settings::update_preconditioner) + .def_rw("check_duality_gap", &Settings::check_duality_gap) + .def_rw("eps_duality_gap_abs", &Settings::eps_duality_gap_abs) + .def_rw("eps_duality_gap_rel", &Settings::eps_duality_gap_rel) + .def_rw("verbose", &Settings::verbose) + .def_rw("bcl_update", &Settings::bcl_update) + .def_rw("merit_function_type", &Settings::merit_function_type) + .def_rw("alpha_gpdal", &Settings::alpha_gpdal) + .def_rw("primal_infeasibility_solving", + &Settings::primal_infeasibility_solving) + .def_rw("frequence_infeasibility_check", + &Settings::frequence_infeasibility_check) + .def_rw("default_H_eigenvalue_estimate", + &Settings::default_H_eigenvalue_estimate) + .def(nanobind::self == nanobind::self) + .def(nanobind::self != nanobind::self) + .def("__getstate__", + [](const Settings& settings) { + return proxsuite::serialization::saveToString(settings); + }) + .def("__setstate__", [](Settings& settings, nanobind::bytes& s) { + new (&settings) Settings{}; + proxsuite::serialization::loadFromString(settings, s.c_str()); + }); ; } } // namespace python From ad7e215a13bdd0d0874255e303d18276cae2802f Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:06:11 +0200 Subject: [PATCH 055/100] [bindings/python] workspace, model : do pybind11 -> nanobind swap + concerns def_* methods and pickling (now managed manually through setting the relevant special methods) + remove module_local(), as it is not supported in nanobind: https://nanobind.readthedocs.io/en/latest/porting.html#removed-features + ::arg_v() no longer behaves the same. had to strip per-argument docstrings --- bindings/python/src/expose-helpers.hpp | 35 +++---- bindings/python/src/expose-model.hpp | 133 ++++++++++++------------- bindings/python/src/expose-results.hpp | 105 ++++++++++--------- 3 files changed, 130 insertions(+), 143 deletions(-) diff --git a/bindings/python/src/expose-helpers.hpp b/bindings/python/src/expose-helpers.hpp index 6dc8768e5..76cba0e70 100644 --- a/bindings/python/src/expose-helpers.hpp +++ b/bindings/python/src/expose-helpers.hpp @@ -2,9 +2,9 @@ // Copyright (c) 2022 INRIA // -#include -#include -#include +#include +#include +#include #include #include @@ -18,7 +18,7 @@ namespace python { template void -exposeDenseHelpers(pybind11::module_ m) +exposeDenseHelpers(nanobind::module_ m) { m.def( "estimate_minimal_eigen_value_of_symmetric_matrix", @@ -38,17 +38,11 @@ exposeDenseHelpers(pybind11::module_ m) "SelfAdjointEigenSolver from Eigen, " "or a Power Iteration algorithm (with parameters : " "power_iteration_accuracy and nb_power_iteration).", - pybind11::arg("H"), - pybind11::arg_v("estimate_method_option", - EigenValueEstimateMethodOption::ExactMethod, - "Two options are available for " - "estimating smallest eigenvalue: either a power " - "iteration algorithm, or an exact method from Eigen."), - pybind11::arg_v( - "power_iteration_accuracy", T(1.E-3), "power iteration accuracy."), - pybind11::arg_v("nb_power_iteration", - 1000, - "maximal number of power iteration executed.")); + nanobind::arg("H"), + nanobind::arg("estimate_method_option") = + EigenValueEstimateMethodOption::ExactMethod, + nanobind::arg("power_iteration_accuracy") = T(1.E-3), + nanobind::arg("nb_power_iteration") = 1000); } } // namespace python } // namespace dense @@ -59,7 +53,7 @@ namespace python { template void -exposeSparseHelpers(pybind11::module_ m) +exposeSparseHelpers(nanobind::module_ m) { m.def("estimate_minimal_eigen_value_of_symmetric_matrix", &sparse::estimate_minimal_eigen_value_of_symmetric_matrix, @@ -67,12 +61,9 @@ exposeSparseHelpers(pybind11::module_ m) "matrix, " " using aPower Iteration algorithm (with parameters : " "power_iteration_accuracy and nb_power_iteration).", - pybind11::arg("H"), - pybind11::arg_v( - "power_iteration_accuracy", T(1.E-3), "power iteration accuracy."), - pybind11::arg_v("nb_power_iteration", - 1000, - "maximal number of power iteration executed.")); + nanobind::arg("H"), + nanobind::arg("power_iteration_accuracy") = T(1.E-3), + nanobind::arg("nb_power_iteration") = 1000); } } // namespace python diff --git a/bindings/python/src/expose-model.hpp b/bindings/python/src/expose-model.hpp index 7e6da20a8..2b4a37d4a 100644 --- a/bindings/python/src/expose-model.hpp +++ b/bindings/python/src/expose-model.hpp @@ -1,10 +1,10 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // -#include -#include -#include +#include +#include +#include #include #include @@ -19,18 +19,18 @@ namespace dense { namespace python { template void -exposeDenseModel(pybind11::module_ m) +exposeDenseModel(nanobind::module_ m) { - ::pybind11::class_>( - m, "BackwardData", pybind11::module_local()) - .def(::pybind11::init(), "Default constructor.") + ::nanobind::class_>(m, + "BackwardData") + .def(::nanobind::init(), "Default constructor.") .def( "initialize", &proxsuite::proxqp::dense::BackwardData::initialize, - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Initialize the jacobians (allocate memory if not already done) and set" " by default their value to zero.") .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dH, "dL_dH.") @@ -41,56 +41,53 @@ exposeDenseModel(pybind11::module_ m) .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_du, "dL_du.") .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dl, "dL_dl.") .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dl, "dL_dl."); - // .def_readonly("dL_dH", &proxsuite::proxqp::dense::BackwardData::dL_dH) - // .def_readonly("dL_dg", &proxsuite::proxqp::dense::BackwardData::dL_dg) - // .def_readonly("dL_dA", &proxsuite::proxqp::dense::BackwardData::dL_dA) - // .def_readonly("dL_db", + // .def_ro("dL_dH", &proxsuite::proxqp::dense::BackwardData::dL_dH) + // .def_ro("dL_dg", &proxsuite::proxqp::dense::BackwardData::dL_dg) + // .def_ro("dL_dA", &proxsuite::proxqp::dense::BackwardData::dL_dA) + // .def_ro("dL_db", // &proxsuite::proxqp::dense::BackwardData::dL_db) - // .def_readonly("dL_dC", + // .def_ro("dL_dC", // &proxsuite::proxqp::dense::BackwardData::dL_dC) - // .def_readonly("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du) - // .def_readonly("dL_dl", + // .def_ro("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du) + // .def_ro("dL_dl", // &proxsuite::proxqp::dense::BackwardData::dL_dl) - // .def_readonly("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du); - // .def_readonly("dL_dse", &proxsuite::proxqp::dense::BackwardData::dL_dse) - // .def_readonly("dL_dsi", + // .def_ro("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du); + // .def_ro("dL_dse", &proxsuite::proxqp::dense::BackwardData::dL_dse) + // .def_ro("dL_dsi", // &proxsuite::proxqp::dense::BackwardData::dL_dsi); - ::pybind11::class_>(m, "model") - .def(::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + ::nanobind::class_>(m, "model") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Constructor using QP model dimensions.") // constructor) - .def_readonly("H", &Model::H) - .def_readonly("g", &Model::g) - .def_readonly("A", &Model::A) - .def_readonly("b", &Model::b) - .def_readonly("C", &Model::C) - .def_readonly("l", &Model::l) - .def_readonly("u", &Model::u) - .def_readonly("dim", &Model::dim) - .def_readonly("n_eq", &Model::n_eq) - .def_readonly("n_in", &Model::n_in) - .def_readonly("n_total", &Model::n_total) - .def_readwrite("backward_data", &Model::backward_data) + .def_ro("H", &Model::H) + .def_ro("g", &Model::g) + .def_ro("A", &Model::A) + .def_ro("b", &Model::b) + .def_ro("C", &Model::C) + .def_ro("l", &Model::l) + .def_ro("u", &Model::u) + .def_ro("dim", &Model::dim) + .def_ro("n_eq", &Model::n_eq) + .def_ro("n_in", &Model::n_in) + .def_ro("n_total", &Model::n_total) + .def_rw("backward_data", &Model::backward_data) .def("is_valid", &Model::is_valid, "Check if model is containing valid data.") - .def(pybind11::self == pybind11::self) - .def(pybind11::self != pybind11::self) - .def(pybind11::pickle( - - [](const proxsuite::proxqp::dense::Model& model) { - return pybind11::bytes(proxsuite::serialization::saveToString(model)); - }, - [](pybind11::bytes& s) { - // create qp model which will be updated by loaded data - proxsuite::proxqp::dense::Model model(1, 1, 1); - proxsuite::serialization::loadFromString(model, s); - - return model; - })); + .def(nanobind::self == nanobind::self) + .def(nanobind::self != nanobind::self) + .def("__getstate__", + [](const proxsuite::proxqp::dense::Model& model) { + return proxsuite::serialization::saveToString(model); + }) + .def("__setstate__", [](dense::Model& model, nanobind::bytes& s) { + // create qp model which will be updated by loaded data + new (&model) dense::Model(1, 1, 1); + proxsuite::serialization::loadFromString(model, s.c_str()); + }); } } // namespace python } // namespace dense @@ -99,24 +96,24 @@ namespace sparse { namespace python { template void -exposeSparseModel(pybind11::module_ m) +exposeSparseModel(nanobind::module_ m) { - ::pybind11::class_>(m, "model") - .def(::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + ::nanobind::class_>(m, "model") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Constructor using QP model dimensions.") // constructor) - .def_readonly("g", &Model::g) - .def_readonly("b", &Model::b) - .def_readonly("l", &Model::l) - .def_readonly("u", &Model::u) - .def_readonly("dim", &Model::dim) - .def_readonly("n_eq", &Model::n_eq) - .def_readonly("n_in", &Model::n_in) - .def_readonly("H_nnz", &Model::H_nnz) - .def_readonly("A_nnz", &Model::A_nnz) - .def_readonly("C_nnz", &Model::C_nnz); + .def_ro("g", &Model::g) + .def_ro("b", &Model::b) + .def_ro("l", &Model::l) + .def_ro("u", &Model::u) + .def_ro("dim", &Model::dim) + .def_ro("n_eq", &Model::n_eq) + .def_ro("n_in", &Model::n_in) + .def_ro("H_nnz", &Model::H_nnz) + .def_ro("A_nnz", &Model::A_nnz) + .def_ro("C_nnz", &Model::C_nnz); } } // namespace python } // namespace sparse diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index 941cd32b5..a882bfa91 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -2,15 +2,17 @@ // Copyright (c) 2022-2023 INRIA // #include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include "helpers.hpp" -#include "optional.hpp" namespace proxsuite { namespace proxqp { @@ -18,10 +20,9 @@ namespace python { template void -exposeResults(pybind11::module_ m) +exposeResults(nanobind::module_ m) { - ::pybind11::enum_( - m, "QPSolverOutput", pybind11::module_local()) + ::nanobind::enum_(m, "QPSolverOutput") .value("PROXQP_SOLVED", QPSolverOutput::PROXQP_SOLVED) .value("PROXQP_MAX_ITER_REACHED", QPSolverOutput::PROXQP_MAX_ITER_REACHED) .value("PROXQP_PRIMAL_INFEASIBLE", QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE) @@ -31,40 +32,40 @@ exposeResults(pybind11::module_ m) .value("PROXQP_NOT_RUN", QPSolverOutput::PROXQP_NOT_RUN) .export_values(); - ::pybind11::class_>(m, "Info", pybind11::module_local()) - .def(::pybind11::init(), "Default constructor.") - .def_readwrite("mu_eq", &Info::mu_eq) - .def_readwrite("mu_in", &Info::mu_in) - .def_readwrite("rho", &Info::rho) - .def_readwrite("iter", &Info::iter) - .def_readwrite("iter_ext", &Info::iter_ext) - .def_readwrite("run_time", &Info::run_time) - .def_readwrite("setup_time", &Info::setup_time) - .def_readwrite("solve_time", &Info::solve_time) - .def_readwrite("duality_gap", &Info::duality_gap) - .def_readwrite("pri_res", &Info::pri_res) - .def_readwrite("dua_res", &Info::dua_res) - .def_readwrite("duality_gap", &Info::duality_gap) - .def_readwrite("iterative_residual", &Info::iterative_residual) - .def_readwrite("objValue", &Info::objValue) - .def_readwrite("status", &Info::status) - .def_readwrite("rho_updates", &Info::rho_updates) - .def_readwrite("mu_updates", &Info::mu_updates) - .def_readwrite("sparse_backend", - &Info::sparse_backend, - "Sparse backend used to solve the qp, either SparseCholesky " - "or MatrixFree.") - .def_readwrite("minimal_H_eigenvalue_estimate", - &Info::minimal_H_eigenvalue_estimate, - "By default it equals 0, in order to get an estimate, set " - "appropriately the setting option " - "find_H_minimal_eigenvalue."); + ::nanobind::class_>(m, "Info") + .def(::nanobind::init(), "Default constructor.") + .def_rw("mu_eq", &Info::mu_eq) + .def_rw("mu_in", &Info::mu_in) + .def_rw("rho", &Info::rho) + .def_rw("iter", &Info::iter) + .def_rw("iter_ext", &Info::iter_ext) + .def_rw("run_time", &Info::run_time) + .def_rw("setup_time", &Info::setup_time) + .def_rw("solve_time", &Info::solve_time) + .def_rw("duality_gap", &Info::duality_gap) + .def_rw("pri_res", &Info::pri_res) + .def_rw("dua_res", &Info::dua_res) + .def_rw("duality_gap", &Info::duality_gap) + .def_rw("iterative_residual", &Info::iterative_residual) + .def_rw("objValue", &Info::objValue) + .def_rw("status", &Info::status) + .def_rw("rho_updates", &Info::rho_updates) + .def_rw("mu_updates", &Info::mu_updates) + .def_rw("sparse_backend", + &Info::sparse_backend, + "Sparse backend used to solve the qp, either SparseCholesky " + "or MatrixFree.") + .def_rw("minimal_H_eigenvalue_estimate", + &Info::minimal_H_eigenvalue_estimate, + "By default it equals 0, in order to get an estimate, set " + "appropriately the setting option " + "find_H_minimal_eigenvalue."); - ::pybind11::class_>(m, "Results", pybind11::module_local()) - .def(::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + ::nanobind::class_>(m, "Results") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Constructor from QP model dimensions.") // constructor .PROXSUITE_PYTHON_EIGEN_READWRITE(Results, x, "The primal solution.") .PROXSUITE_PYTHON_EIGEN_READWRITE( @@ -83,19 +84,17 @@ exposeResults(pybind11::module_ m) si, "Pptimal shift to the closest feasible " "problem wrt inequality constraints.") - .def_readwrite("info", &Results::info) - .def(pybind11::self == pybind11::self) - .def(pybind11::self != pybind11::self) - .def(pybind11::pickle( - - [](const Results& results) { - return pybind11::bytes(proxsuite::serialization::saveToString(results)); - }, - [](pybind11::bytes& s) { - Results results; - proxsuite::serialization::loadFromString(results, s); - return results; - })); + .def_rw("info", &Results::info) + .def(nanobind::self == nanobind::self) + .def(nanobind::self != nanobind::self) + .def("__getstate__", + [](const Results& results) { + return proxsuite::serialization::saveToString(results); + }) + .def("__setstate__", [](Results& results, nanobind::bytes& s) { + new (&results) Results{}; + proxsuite::serialization::loadFromString(results, s.c_str()); + }); ; } } // namespace python From 54040cd45764fc5f5b53779baedfb06687bf26f9 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:08:34 +0200 Subject: [PATCH 056/100] [bindings/python] remove optional.hpp + nanobind has no out-of-the-box utility for tl::optional AFAIK + nanobind requires C++17 - hence proxsuite will be using std::optional anyway --- bindings/python/src/optional.hpp | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 bindings/python/src/optional.hpp diff --git a/bindings/python/src/optional.hpp b/bindings/python/src/optional.hpp deleted file mode 100644 index bbdd5a153..000000000 --- a/bindings/python/src/optional.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright (c) 2022 INRIA -// -#ifndef proxsuite_python_optional_hpp -#define proxsuite_python_optional_hpp - -#include -#include -#include - -#if __cplusplus < 201703L -template -struct pybind11::detail::type_caster> - : public pybind11::detail::optional_caster> -{}; - -template<> -struct pybind11::detail::type_caster - : public pybind11::detail::void_caster -{}; -#endif - -#endif // ifndef proxsuite_python_optional_hpp From 16a882528a2880a16fa8206bca8cebd9f9824e36 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:09:08 +0200 Subject: [PATCH 057/100] [bindings/python] expose-solver.hpp : switch to nanobind + this nuked a bunch of argument docstrings... --- bindings/python/src/expose-solve.hpp | 275 +++++++++------------------ 1 file changed, 89 insertions(+), 186 deletions(-) diff --git a/bindings/python/src/expose-solve.hpp b/bindings/python/src/expose-solve.hpp index 038bccaec..8721ba570 100644 --- a/bindings/python/src/expose-solve.hpp +++ b/bindings/python/src/expose-solve.hpp @@ -1,11 +1,12 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // #include #include -#include -#include -#include +#include +#include +#include +#include namespace proxsuite { namespace proxqp { @@ -16,11 +17,11 @@ namespace python { template void -solveDenseQp(pybind11::module_ m) +solveDenseQp(nanobind::module_ m) { m.def( "solve", - pybind11::overload_cast>, + nanobind::overload_cast>, optional>, optional>, optional>, @@ -50,69 +51,36 @@ solveDenseQp(pybind11::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - pybind11::arg_v("H", nullopt, "quadratic cost with dense format."), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v( - "A", nullopt, "equality constraint matrix with dense format."), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v( - "C", nullopt, "inequality constraint matrix with dense format."), - pybind11::arg_v("l", nullopt, "lower inequality constraint vector"), - pybind11::arg_v("u", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("x", nullopt, "primal warm start"), - pybind11::arg_v("y", nullopt, "dual equality warm start"), - pybind11::arg_v("z", nullopt, "dual inequality warm start"), - pybind11::arg_v( - "eps_abs", - nullopt, - "absolute accuracy level used for the solver stopping criterion."), - pybind11::arg_v("eps_rel", - nullopt, - "relative accuracy level used for the solver stopping " - "criterion. Deactivated in standard settings."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("verbose", - nullopt, - "verbose option to print information at each iteration."), - pybind11::arg_v("compute_preconditioner", - true, - "executes the default preconditioner for reducing ill " - "conditioning and speeding up the solver."), - pybind11::arg_v( - "compute_timings", false, "compute solver's timings in μs."), - pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), - pybind11::arg_v( - "initial_guess", - proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, - "maximum number of iteration."), - pybind11::arg_v( - "check_duality_gap", - false, - "if set to true, include the duality gap in absolute and relative " - "stopping criteria."), - pybind11::arg_v("eps_duality_gap_abs", - nullopt, - "absolute accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("eps_duality_gap_rel", - nullopt, - "relative accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("primal_infeasibility_solving", - false, - "solves the closest feasible problem in L2 sense " - "if the QP problem appears to be infeasible."), - pybind11::arg_v("default_H_eigenvalue_estimate", - 0., - "Default estimate of the minimal eigen value of H.")); + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("x") = nullopt, + nanobind::arg("y") = nullopt, + nanobind::arg("z") = nullopt, + nanobind::arg("eps_abs") = nullopt, + nanobind::arg("eps_rel") = nullopt, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("verbose") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("compute_timings") = false, + nanobind::arg("max_iter") = nullopt, + nanobind::arg("initial_guess") = + InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, + nanobind::arg("check_duality_gap") = false, + nanobind::arg("eps_duality_gap_abs") = nullopt, + nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("primal_infeasibility_solving") = false, + nanobind::arg("default_H_eigenvalue_estimate") = 0.); m.def( "solve", - pybind11::overload_cast>, + nanobind::overload_cast>, optional>, optional>, optional>, @@ -144,67 +112,34 @@ solveDenseQp(pybind11::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - pybind11::arg_v("H", nullopt, "quadratic cost with dense format."), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v( - "A", nullopt, "equality constraint matrix with dense format."), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v( - "C", nullopt, "inequality constraint matrix with dense format."), - pybind11::arg_v("l", nullopt, "lower inequality constraint vector"), - pybind11::arg_v("u", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("l_box", nullopt, "lower box inequality constraint vector"), - pybind11::arg_v("u_box", nullopt, "upper box inequality constraint vector"), - pybind11::arg_v("x", nullopt, "primal warm start"), - pybind11::arg_v("y", nullopt, "dual equality warm start"), - pybind11::arg_v("z", nullopt, "dual inequality warm start"), - pybind11::arg_v( - "eps_abs", - nullopt, - "absolute accuracy level used for the solver stopping criterion."), - pybind11::arg_v("eps_rel", - nullopt, - "relative accuracy level used for the solver stopping " - "criterion. Deactivated in standard settings."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("verbose", - nullopt, - "verbose option to print information at each iteration."), - pybind11::arg_v("compute_preconditioner", - true, - "executes the default preconditioner for reducing ill " - "conditioning and speeding up the solver."), - pybind11::arg_v( - "compute_timings", false, "compute solver's timings in μs."), - pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), - pybind11::arg_v( - "initial_guess", + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("l_box") = nullopt, + nanobind::arg("u_box") = nullopt, + nanobind::arg("x") = nullopt, + nanobind::arg("y") = nullopt, + nanobind::arg("z") = nullopt, + nanobind::arg("eps_abs") = nullopt, + nanobind::arg("eps_rel") = nullopt, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("verbose") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("compute_timings") = false, + nanobind::arg("max_iter") = nullopt, + nanobind::arg("initial_guess") = proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, - "maximum number of iteration."), - pybind11::arg_v( - "check_duality_gap", - false, - "if set to true, include the duality gap in absolute and relative " - "stopping criteria."), - pybind11::arg_v("eps_duality_gap_abs", - nullopt, - "absolute accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("eps_duality_gap_rel", - nullopt, - "relative accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("primal_infeasibility_solving", - false, - "solves the closest feasible problem in L2 sense " - "if the QP problem appears to be infeasible."), - pybind11::arg_v("default_H_eigenvalue_estimate", - 0., - "Default estimate of the minimal eigen value of H.")); + nanobind::arg("check_duality_gap") = false, + nanobind::arg("eps_duality_gap_abs") = nullopt, + nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("primal_infeasibility_solving") = false, + nanobind::arg("default_H_eigenvalue_estimate") = 0.); } } // namespace python @@ -215,7 +150,7 @@ namespace python { template void -solveSparseQp(pybind11::module_ m) +solveSparseQp(nanobind::module_ m) { m.def( "solve", @@ -225,65 +160,33 @@ solveSparseQp(pybind11::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - pybind11::arg_v("H", nullopt, "quadratic cost with sparse format."), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v( - "A", nullopt, "equality constraint matrix with sparse format."), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v( - "C", nullopt, "inequality constraint matrix with sparse format."), - pybind11::arg_v("l", nullopt, "lower inequality constraint vector"), - pybind11::arg_v("u", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("x", nullopt, "primal warm start"), - pybind11::arg_v("y", nullopt, "dual equality warm start"), - pybind11::arg_v("z", nullopt, "dual inequality warm start"), - pybind11::arg_v( - "eps_abs", - nullopt, - "absolute accuracy level used for the solver stopping criterion."), - pybind11::arg_v("eps_rel", - nullopt, - "relative accuracy level used for the solver stopping " - "criterion. Deactivated in standard settings."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("verbose", - nullopt, - "verbose option to print information at each iteration."), - pybind11::arg_v("compute_preconditioner", - true, - "executes the default preconditioner for reducing ill " - "conditioning and speeding up the solver."), - pybind11::arg_v( - "compute_timings", false, "compute solver's timings in μs."), - pybind11::arg_v("max_iter", nullopt, "maximum number of iteration."), - pybind11::arg_v("initial_guess", - proxsuite::proxqp::InitialGuessStatus:: - EQUALITY_CONSTRAINED_INITIAL_GUESS), - pybind11::arg_v("sparse_backend", - proxsuite::proxqp::SparseBackend::Automatic), - pybind11::arg_v("check_duality_gap", - false, - "if set to true, include the duality gap in absolute and " - "relative stopping criteria."), - pybind11::arg_v("eps_duality_gap_abs", - nullopt, - "absolute accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("eps_duality_gap_rel", - nullopt, - "relative accuracy threshold used for the duality-gap " - "stopping criterion."), - pybind11::arg_v("primal_infeasibility_solving", - false, - "solves the closest feasible problem in L2 sense " - "if the QP problem appears to be infeasible."), - pybind11::arg_v("default_H_eigenvalue_estimate", - 0., - "Default estimate of the minimal eigen value of H.")); + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("x") = nullopt, + nanobind::arg("y") = nullopt, + nanobind::arg("z") = nullopt, + nanobind::arg("eps_abs") = nullopt, + nanobind::arg("eps_rel") = nullopt, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("verbose") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("compute_timings") = false, + nanobind::arg("max_iter") = nullopt, + nanobind::arg("initial_guess") = + InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, + nanobind::arg("sparse_backend") = SparseBackend::Automatic, + nanobind::arg("check_duality_gap") = false, + nanobind::arg("eps_duality_gap_abs") = nullopt, + nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("primal_infeasibility_solving") = false, + nanobind::arg("default_H_eigenvalue_estimate") = 0.); } } // namespace python From 97909b416d4f9d26372ab4137d0d0cee70e630cd Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:09:42 +0200 Subject: [PATCH 058/100] [bindings/python] expose-{backward,parallel,qpobject}.hpp : switch to nanobind + this nuked a bunch of argument docstrings... --- bindings/python/src/expose-backward.hpp | 31 +- bindings/python/src/expose-parallel.hpp | 120 +++----- bindings/python/src/expose-qpobject.hpp | 381 ++++++++++-------------- 3 files changed, 215 insertions(+), 317 deletions(-) diff --git a/bindings/python/src/expose-backward.hpp b/bindings/python/src/expose-backward.hpp index 85716ece7..29db4b553 100644 --- a/bindings/python/src/expose-backward.hpp +++ b/bindings/python/src/expose-backward.hpp @@ -5,9 +5,9 @@ #include #include #include "proxsuite/proxqp/dense/compute_ECJ.hpp" -#include -#include -#include +#include +#include +#include namespace proxsuite { namespace proxqp { @@ -18,23 +18,16 @@ namespace python { template void -backward(pybind11::module_ m) +backward(nanobind::module_ m) { - m.def( - "compute_backward", - &compute_backward, - "Function for computing derivatives of solved QP.", - pybind11::arg_v("qp", "Solved dense QP."), - pybind11::arg_v("loss_derivative", "Derivate of loss wrt to qp solution."), - pybind11::arg_v( - "eps", 1e-4, "Backward pass accuracy for deriving solution Jacobians."), - pybind11::arg_v("rho_backward", - 1e-6, - "New primal proximal parameter for iterative refinement."), - pybind11::arg_v("mu_backward", - 1e-6, - "New dual proximal parameter used both for inequality and " - "equality for iterative refinement.")); + m.def("compute_backward", + &compute_backward, + "Function for computing derivatives of solved QP.", + nanobind::arg("qp"), + nanobind::arg("loss_derivative"), + nanobind::arg("eps") = 1e-4, + nanobind::arg("rho_backward") = 1e-6, + nanobind::arg("mu_backward") = 1e-6); } } // namespace python diff --git a/bindings/python/src/expose-parallel.hpp b/bindings/python/src/expose-parallel.hpp index 9b90186b7..11ffaa2d0 100644 --- a/bindings/python/src/expose-parallel.hpp +++ b/bindings/python/src/expose-parallel.hpp @@ -5,13 +5,13 @@ #include #include #include -#include -#include -#include -#include // For binding STL containers +#include +#include +#include +#include -PYBIND11_MAKE_OPAQUE(std::vector>) -PYBIND11_MAKE_OPAQUE(std::vector>) +NB_MAKE_OPAQUE(std::vector>) +NB_MAKE_OPAQUE(std::vector>) namespace proxsuite { namespace proxqp { using proxsuite::linalg::veg::isize; @@ -21,86 +21,65 @@ namespace python { template void -solveDenseQpParallel(pybind11::module_ m) +solveDenseQpParallel(nanobind::module_ m) { - pybind11::bind_vector>>( + nanobind::bind_vector>>( m, "VectorLossDerivatives"); - pybind11::bind_vector>>( + nanobind::bind_vector>>( m, "VectorQP"); m.def("solve_in_parallel", - pybind11::overload_cast>&, + nanobind::overload_cast>&, const optional>(&solve_in_parallel), "Function for solving a list of dense QPs in parallel.", - pybind11::arg_v("qps", "List of initialized dense Qps."), - pybind11::arg_v("num_threads", - nullopt, - "number of threads used for the computation.")); + nanobind::arg("qps"), + nanobind::arg("num_threads") = nullopt); m.def( "solve_in_parallel", - pybind11::overload_cast&, const optional>( + nanobind::overload_cast&, const optional>( &solve_in_parallel), "Function for solving a list of dense QPs in parallel.", - pybind11::arg_v("qps", "List of initialized dense Qps."), - pybind11::arg_v( - "num_threads", nullopt, "number of threads used for the computation.")); + nanobind::arg("qps"), + nanobind::arg("num_threads") = nullopt); // m.def("solve_in_parallel", // &qp_solve_in_parallel, // "Function for solving a list of dense QPs in parallel.", - // pybind11::arg_v("num_threads", - // nullopt, - // "number of threads used for the computation."), - // pybind11::arg_v("qps", "List of initialized dense Qps.")); + // nanobind::arg("num_threads") = nullopt, + // nanobind::arg("qps")); - m.def( - "solve_backward_in_parallel", - pybind11::overload_cast, - proxqp::dense::BatchQP&, - std::vector>&, - T, - T, - T>(&qp_solve_backward_in_parallel), - "Function for solving a list of dense QPs in parallel.", - pybind11::arg_v( - "num_threads", nullopt, "number of threads used for the computation."), - pybind11::arg_v("qps", "List of initialized dense Qps."), - pybind11::arg_v("loss_derivatives", "List of loss derivatives."), - pybind11::arg_v( - "eps", 1e-4, "Backward pass accuracy for deriving solution Jacobians."), - pybind11::arg_v("rho_backward", - 1e-6, - "New primal proximal parameter for iterative refinement."), - pybind11::arg_v("mu_backward", - 1e-6, - "New dual proximal parameter used both for inequality " - "and equality for iterative refinement.")); + m.def("solve_backward_in_parallel", + nanobind::overload_cast, + proxqp::dense::BatchQP&, + std::vector>&, + T, + T, + T>(&qp_solve_backward_in_parallel), + "Function for solving a list of dense QPs in parallel.", + nanobind::arg("num_threads") = nullopt, + nanobind::arg("qps"), + nanobind::arg("loss_derivatives"), + nanobind::arg("eps") = 1e-4, + nanobind::arg("rho_backward") = 1e-6, + nanobind::arg("mu_backward") = 1e-6); - m.def( - "solve_backward_in_parallel", - pybind11::overload_cast, - std::vector>&, - std::vector>&, - T, - T, - T>(&qp_solve_backward_in_parallel), - "Function for solving a list of dense QPs in parallel.", - pybind11::arg_v( - "num_threads", nullopt, "number of threads used for the computation."), - pybind11::arg_v("qps", "List of initialized dense Qps."), - pybind11::arg_v("loss_derivatives", "List of loss derivatives."), - pybind11::arg_v( - "eps", 1e-4, "Backward pass accuracy for deriving solution Jacobians."), - pybind11::arg_v("rho_backward", - 1e-6, - "New primal proximal parameter for iterative refinement."), - pybind11::arg_v("mu_backward", - 1e-6, - "New dual proximal parameter used both for inequality and " - "equality for iterative refinement.")); + m.def("solve_backward_in_parallel", + nanobind::overload_cast, + std::vector>&, + std::vector>&, + T, + T, + T>(&qp_solve_backward_in_parallel), + "Function for solving a list of dense QPs in parallel.", + nanobind::arg("num_threads") = nullopt, + nanobind::arg("qps"), + nanobind::arg("loss_derivatives"), + nanobind::arg("eps") = 1e-4, + nanobind::arg("rho_backward") = 1e-6, + nanobind::arg("mu_backward") = 1e-6); } } // namespace python @@ -110,16 +89,15 @@ namespace sparse { namespace python { template void -solveSparseQpParallel(pybind11::module_ m) +solveSparseQpParallel(nanobind::module_ m) { m.def( "solve_in_parallel", - pybind11::overload_cast&, + nanobind::overload_cast&, const optional>(&solve_in_parallel), "Function for solving a list of sparse QPs in parallel.", - pybind11::arg_v("qps", "List of initialized sparse Qps."), - pybind11::arg_v( - "num_threads", nullopt, "number of threads used for the computation.")); + nanobind::arg("qps"), + nanobind::arg("num_threads") = nullopt); } } // namespace python diff --git a/bindings/python/src/expose-qpobject.hpp b/bindings/python/src/expose-qpobject.hpp index f6824ed26..70e22f2b6 100644 --- a/bindings/python/src/expose-qpobject.hpp +++ b/bindings/python/src/expose-qpobject.hpp @@ -1,10 +1,11 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // -#include -#include -#include +#include +#include +#include +#include #include #include @@ -22,72 +23,62 @@ namespace python { template void -exposeQpObjectDense(pybind11::module_ m) +exposeQpObjectDense(nanobind::module_ m) { - ::pybind11::enum_(m, "DenseBackend", pybind11::module_local()) + ::nanobind::enum_(m, "DenseBackend") .value("Automatic", DenseBackend::Automatic) .value("PrimalDualLDLT", DenseBackend::PrimalDualLDLT) .value("PrimalLDLT", DenseBackend::PrimalLDLT) .export_values(); - ::pybind11::enum_(m, "HessianType", pybind11::module_local()) + ::nanobind::enum_(m, "HessianType") .value("Dense", proxsuite::proxqp::HessianType::Dense) .value("Zero", proxsuite::proxqp::HessianType::Zero) .value("Diagonal", proxsuite::proxqp::HessianType::Diagonal) .export_values(); - // ::pybind11::class_>(m, - // "ruiz", pybind11::module_local()) - // .def(::pybind11::init(), "Default constructor.") - // .def_readwrite("mu_eq", &RuizEquilibration::delta) - // .def_readwrite("mu_in", &RuizEquilibration::c) - // .def_readwrite("rho", &RuizEquilibration::dim) - // .def_readwrite("iter", &RuizEquilibration::epsilon) - // .def_readwrite("iter_ext", &RuizEquilibration::max_iter) - // .def_readwrite("run_time", &RuizEquilibration::sym); + // ::nanobind::class_>(m, + // "ruiz") + // .def(::nanobind::init(), "Default constructor.") + // .def_rw("mu_eq", &RuizEquilibration::delta) + // .def_rw("mu_in", &RuizEquilibration::c) + // .def_rw("rho", &RuizEquilibration::dim) + // .def_rw("iter", &RuizEquilibration::epsilon) + // .def_rw("iter_ext", &RuizEquilibration::max_iter) + // .def_rw("run_time", &RuizEquilibration::sym); - // ::pybind11::class_>(m, - // "ruiz", pybind11::module_local()) - // .def(::pybind11::init(), "Default constructor.") - // .def_readwrite("mu_eq", &RuizEquilibration::delta) - // .def_readwrite("mu_in", &RuizEquilibration::c) - // .def_readwrite("rho", &RuizEquilibration::dim) - // .def_readwrite("iter", &RuizEquilibration::epsilon) - // .def_readwrite("iter_ext", &RuizEquilibration::max_iter) - // .def_readwrite("run_time", &RuizEquilibration::sym); + // ::nanobind::class_>(m, + // "ruiz") + // .def(::nanobind::init(), "Default constructor.") + // .def_rw("mu_eq", &RuizEquilibration::delta) + // .def_rw("mu_in", &RuizEquilibration::c) + // .def_rw("rho", &RuizEquilibration::dim) + // .def_rw("iter", &RuizEquilibration::epsilon) + // .def_rw("iter_ext", &RuizEquilibration::max_iter) + // .def_rw("run_time", &RuizEquilibration::sym); - ::pybind11::class_>(m, "QP") - .def( - ::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), - pybind11::arg_v( - "box_constraints", - false, - "specify or not that the QP has box inequality constraints."), - pybind11::arg_v("hessian_type", - proxsuite::proxqp::HessianType::Dense, - "specify the problem type to be solved."), - pybind11::arg_v("dense_backend", - proxsuite::proxqp::DenseBackend::Automatic, - "specify which backend using for solving the problem."), - "Default constructor using QP model dimensions.") // constructor - .def_readwrite( - "results", - &dense::QP::results, - "class containing the solution or certificate of infeasibility, " - "and " - "information statistics in an info subclass.") - .def_readwrite( - "settings", &dense::QP::settings, "Settings of the solver.") - .def_readwrite( - "model", &dense::QP::model, "class containing the QP model") + ::nanobind::class_>(m, "QP") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, + nanobind::arg("box_constraints") = false, + nanobind::arg("hessian_type") = proxsuite::proxqp::HessianType::Dense, + nanobind::arg("dense_backend") = + proxsuite::proxqp::DenseBackend::Automatic, + "Default constructor using QP model dimensions.") // constructor + .def_rw("results", + &dense::QP::results, + "class containing the solution or certificate of infeasibility, " + "and " + "information statistics in an info subclass.") + .def_rw("settings", &dense::QP::settings, "Settings of the solver.") + .def_rw("model", &dense::QP::model, "class containing the QP model") .def("is_box_constrained", &dense::QP::is_box_constrained, "precise whether or not the QP is designed with box constraints.") @@ -111,26 +102,18 @@ exposeQpObjectDense(pybind11::module_ m) optional, optional)>(&dense::QP::init), "function for initialize the QP model.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v("compute_preconditioner", - true, - "execute the preconditioner for reducing " - "ill-conditioning and speeding up solver execution."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def("init", static_cast::*)(optional>, optional>, @@ -147,30 +130,20 @@ exposeQpObjectDense(pybind11::module_ m) optional, optional)>(&dense::QP::init), "function for initialize the QP model.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v( - "l_box", nullopt, "upper box inequality constraint vector"), - pybind11::arg_v( - "u_box", nullopt, "lower box inequality constraint vector"), - pybind11::arg_v("compute_preconditioner", - true, - "execute the preconditioner for reducing " - "ill-conditioning and speeding up solver execution."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("l_box") = nullopt, + nanobind::arg("u_box") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def("solve", static_cast::*)()>(&dense::QP::solve), "function used for solving the QP problem, using default parameters.") @@ -197,28 +170,18 @@ exposeQpObjectDense(pybind11::module_ m) optional)>(&dense::QP::update), "function used for updating matrix or vector entry of the model using " "dense matrix entries.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v( - "update_preconditioner", - false, - "update the preconditioner considering new matrices entries for " - "reducing ill-conditioning and speeding up solver execution. If set up " - "to false, use previous derived preconditioner."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("update_preconditioner") = false, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def( "update", static_cast::*)(optional>, @@ -237,48 +200,34 @@ exposeQpObjectDense(pybind11::module_ m) optional)>(&dense::QP::update), "function used for updating matrix or vector entry of the model using " "dense matrix entries.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v( - "l_box", nullopt, "upper box inequality constraint vector"), - pybind11::arg_v( - "u_box", nullopt, "lower box inequality constraint vector"), - pybind11::arg_v( - "update_preconditioner", - false, - "update the preconditioner considering new matrices entries for " - "reducing ill-conditioning and speeding up solver execution. If set up " - "to false, use previous derived preconditioner."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("l_box") = nullopt, + nanobind::arg("u_box") = nullopt, + nanobind::arg("update_preconditioner") = false, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def("cleanup", &dense::QP::cleanup, "function used for cleaning the workspace and result " "classes.") - .def(pybind11::self == pybind11::self) - .def(pybind11::self != pybind11::self) - .def(pybind11::pickle( - - [](const dense::QP& qp) { - return pybind11::bytes(proxsuite::serialization::saveToString(qp)); - }, - [](pybind11::bytes& s) { - proxsuite::proxqp::dense::QP qp(1, 1, 1); - proxsuite::serialization::loadFromString(qp, s); - return qp; - })); + .def(nanobind::self == nanobind::self) + .def(nanobind::self != nanobind::self) + .def("__getstate__", + [](const dense::QP& qp) { + return proxsuite::serialization::saveToString(qp); + }) + .def("__setstate__", [](dense::QP& qp, nanobind::bytes& s) { + new (&qp) dense::QP(1, 1, 1); + proxsuite::serialization::loadFromString(qp, s.c_str()); + }); ; } } // namespace python @@ -290,84 +239,62 @@ namespace python { template void -exposeQpObjectSparse(pybind11::module_ m) +exposeQpObjectSparse(nanobind::module_ m) { - ::pybind11::class_>(m, "QP") //,pybind11::module_local() - .def(::pybind11::init(), - pybind11::arg_v("n", 0, "primal dimension."), - pybind11::arg_v("n_eq", 0, "number of equality constraints."), - pybind11::arg_v("n_in", 0, "number of inequality constraints."), + ::nanobind::class_>(m, "QP") + .def(::nanobind::init(), + nanobind::arg("n") = 0, + nanobind::arg("n_eq") = 0, + nanobind::arg("n_in") = 0, "Constructor using QP model dimensions.") // constructor - .def( - ::pybind11::init&, - const sparse::SparseMat&, - const sparse::SparseMat&>(), - pybind11::arg_v("H_mask", nullopt, "mask of the quadratic cost."), - pybind11::arg_v( - "A_mask", nullopt, "mask of the equality constraint matrix."), - pybind11::arg_v("C_mask", 0, "mask of the inequality constraint matrix."), - "Constructor using QP model sparsity structure.") // constructor - .def_readwrite( - "model", &sparse::QP::model, "class containing the QP model") - .def_readwrite( - "results", - &sparse::QP::results, - "class containing the solution or certificate of infeasibility, " - "and " - "information statistics in an info subclass.") - .def_readwrite( - "settings", &sparse::QP::settings, "Settings of the solver.") + .def(::nanobind::init&, + const sparse::SparseMat&, + const sparse::SparseMat&>(), + nanobind::arg("H_mask") = nullopt, + nanobind::arg("A_mask") = nullopt, + nanobind::arg("C_mask") = 0, + "Constructor using QP model sparsity structure.") // constructor + .def_ro("model", &sparse::QP::model, "class containing the QP model") + .def_rw("results", + &sparse::QP::results, + "class containing the solution or certificate of infeasibility, " + "and " + "information statistics in an info subclass.") + .def_rw("settings", &sparse::QP::settings, "Settings of the solver.") .def("init", &sparse::QP::init, "function for initializing the model when passing sparse matrices in " "entry.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v("compute_preconditioner", - true, - "execute the preconditioner for reducing " - "ill-conditioning and speeding up solver execution."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("compute_preconditioner") = true, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def("update", &sparse::QP::update, "function for updating the model when passing sparse matrices in " "entry.", - pybind11::arg_v("H", nullopt, "quadratic cost"), - pybind11::arg_v("g", nullopt, "linear cost"), - pybind11::arg_v("A", nullopt, "equality constraint matrix"), - pybind11::arg_v("b", nullopt, "equality constraint vector"), - pybind11::arg_v("C", nullopt, "inequality constraint matrix"), - pybind11::arg_v("l", nullopt, "upper inequality constraint vector"), - pybind11::arg_v("u", nullopt, "lower inequality constraint vector"), - pybind11::arg_v( - "update_preconditioner", - false, - "update the preconditioner or re-use previous derived for reducing " - "ill-conditioning and speeding up solver execution."), - pybind11::arg_v("rho", nullopt, "primal proximal parameter"), - pybind11::arg_v( - "mu_eq", nullopt, "dual equality constraint proximal parameter"), - pybind11::arg_v( - "mu_in", nullopt, "dual inequality constraint proximal parameter"), - pybind11::arg_v("manual_minimal_H_eigenvalue", - nullopt, - "manual minimal H eigenvalue proposed to regularize H" - " in case it is non convex.")) + nanobind::arg("H") = nullopt, + nanobind::arg("g") = nullopt, + nanobind::arg("A") = nullopt, + nanobind::arg("b") = nullopt, + nanobind::arg("C") = nullopt, + nanobind::arg("l") = nullopt, + nanobind::arg("u") = nullopt, + nanobind::arg("update_preconditioner") = false, + nanobind::arg("rho") = nullopt, + nanobind::arg("mu_eq") = nullopt, + nanobind::arg("mu_in") = nullopt, + nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) .def("solve", static_cast::*)()>(&sparse::QP::solve), "function used for solving the QP problem, using default parameters.") From 520afabdb218f04a328b7ca0229c0840fa4b3473 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Mon, 5 Aug 2024 20:10:51 +0200 Subject: [PATCH 059/100] [bindings/python] expose-qpvector.hpp : upgrade to nanobind + change pybind11::return_value_policy to nanobind::rv_policy when relevant + include the nanobind header here (helps for IDEs) + change ctor init types from i64 to u64 -> nanobind is STRICT when it comes to integer signedness conversions --- bindings/python/src/expose-qpvector.hpp | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/bindings/python/src/expose-qpvector.hpp b/bindings/python/src/expose-qpvector.hpp index 06abf8b35..1b077a4af 100644 --- a/bindings/python/src/expose-qpvector.hpp +++ b/bindings/python/src/expose-qpvector.hpp @@ -3,6 +3,9 @@ // #include +#include + +#include namespace proxsuite { namespace proxqp { @@ -13,17 +16,17 @@ namespace python { template void -exposeQPVectorDense(pybind11::module_ m) +exposeQPVectorDense(nanobind::module_ m) { - ::pybind11::class_>(m, "BatchQP") + ::nanobind::class_>(m, "BatchQP") .def( - ::pybind11::init(), - pybind11::arg_v("batch_size", 0, "number of QPs to be stored."), + ::nanobind::init(), + nanobind::arg("batch_size") = 0, "Default constructor using the BatchSize of qp models to store.") // constructor .def("init_qp_in_place", &dense::BatchQP::init_qp_in_place, - pybind11::return_value_policy::reference, + nanobind::rv_policy::reference, "init a dense QP in place and return a reference to it.") .def("insert", &dense::BatchQP::insert, @@ -32,7 +35,7 @@ exposeQPVectorDense(pybind11::module_ m) .def("get", (dense::QP & (dense::BatchQP::*)(isize)) & dense::BatchQP::get, - pybind11::return_value_policy::reference, + nanobind::rv_policy::reference, "get the qp."); } } // namespace python @@ -43,23 +46,23 @@ namespace python { template void -exposeQPVectorSparse(pybind11::module_ m) +exposeQPVectorSparse(nanobind::module_ m) { - ::pybind11::class_>(m, "BatchQP") + ::nanobind::class_>(m, "BatchQP") .def( - ::pybind11::init(), - pybind11::arg_v("batch_size", 0, "number of QPs to be stored."), + ::nanobind::init(), + nanobind::arg("batch_size") = 0, "Default constructor using the BatchSize of qp models to store.") // constructor .def("init_qp_in_place", &sparse::BatchQP::init_qp_in_place, - pybind11::return_value_policy::reference, + nanobind::rv_policy::reference, "init a sparse QP in place and return a reference to it.") .def("size", &sparse::BatchQP::size) .def("get", (sparse::QP & (sparse::BatchQP::*)(isize)) & sparse::BatchQP::get, - pybind11::return_value_policy::reference, + nanobind::rv_policy::reference, "get the qp."); } From 783d88f011d976331b9643851129e839ff178a0f Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:12:17 +0200 Subject: [PATCH 060/100] [ci] checkout submodule recursive --- .github/workflows/ci-arch.yml | 2 +- .github/workflows/ci-linux-osx-win-conda.yml | 4 +++- .github/workflows/gh-pages.yml | 4 +++- .github/workflows/release-linux.yml | 4 ++-- .github/workflows/release-osx-win.yml | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-arch.yml b/.github/workflows/ci-arch.yml index 18e21d371..af0cfd2ad 100644 --- a/.github/workflows/ci-arch.yml +++ b/.github/workflows/ci-arch.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v4 with: - submodules: true + submodules: recursive - run: cmake -B build -S . -DBUILD_PYTHON_INTERFACE=ON - run: cmake --build build diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index bdf3af56f..48f32ad21 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -55,7 +55,9 @@ jobs: continue_on_error: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: recursive - uses: conda-incubator/setup-miniconda@v2 if: matrix.os != 'macos-14' diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index cf9ae190e..c096bd318 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -8,7 +8,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: recursive - uses: conda-incubator/setup-miniconda@v2 with: diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index a47c2526d..54125cbc8 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -33,9 +33,9 @@ jobs: build: "cp312-manylinux*" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: - submodules: 'true' + submodules: recursive - uses: actions/setup-python@v4 with: python-version: "3.10" diff --git a/.github/workflows/release-osx-win.yml b/.github/workflows/release-osx-win.yml index 351cee208..65f4f91de 100644 --- a/.github/workflows/release-osx-win.yml +++ b/.github/workflows/release-osx-win.yml @@ -21,7 +21,7 @@ jobs: toolset: v143 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive From 7de7adf72705f42f89b7d2259ef9babdf6675ddc Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 13:47:05 +0200 Subject: [PATCH 061/100] [bindings/python] cmake : add stub generation (basic) pyproject.toml: add dependency on typing-extensions (required for stubgen on python<3.11) Make stub generation optional --- bindings/python/CMakeLists.txt | 33 +++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index d6b3cf216..30d49293e 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -5,6 +5,8 @@ endif() include(${JRL_CMAKE_MODULES}/python.cmake) include(${JRL_CMAKE_MODULES}/python-helpers.cmake) +option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) + findpython(REQUIRED Development.Module) find_package(Python 3.8 COMPONENTS ${PYTHON_COMPONENTS}) @@ -54,6 +56,20 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") TARGETS instructionset EXPORT ${TARGETS_EXPORT_NAME} DESTINATION ${${PYWRAP}_INSTALL_DIR}) + if(GENERATE_PYTHON_STUBS) + nanobind_add_stub( + instructionset_stub + MODULE + instructionset + OUTPUT + instructionset.pyi + PYTHON_PATH + $ + DEPENDS + instructionset) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/instructionset.pyi + DESTINATION ${${PYWRAP}_INSTALL_DIR}) + endif() endif() function(list_filter list regular_expression dest_list) @@ -68,8 +84,7 @@ function(list_filter list regular_expression dest_list) endfunction(list_filter) function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) - nanobind_add_module(${target_name} ${PYWRAP_SOURCES} - ${PYWRAP_HEADERS}) + nanobind_add_module(${target_name} ${PYWRAP_SOURCES} ${PYWRAP_HEADERS}) add_dependencies(${PROJECT_NAME}_python ${target_name}) target_link_libraries(${target_name} PUBLIC ${dependencies}) @@ -121,6 +136,20 @@ function(CREATE_PYTHON_TARGET target_name COMPILE_OPTIONS dependencies) endif() install(TARGETS ${target_name} DESTINATION ${${PYWRAP}_INSTALL_DIR}) + if(GENERATE_PYTHON_STUBS) + nanobind_add_stub( + ${target_name}_stub + MODULE + ${target_name} + OUTPUT + ${target_name}.pyi + PYTHON_PATH + $ + DEPENDS + ${target_name}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${target_name}.pyi + DESTINATION ${${PYWRAP}_INSTALL_DIR}) + endif() endfunction() if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) diff --git a/pyproject.toml b/pyproject.toml index e40bd4616..3aa236457 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ requires = [ "cmeel[build]", "cmeel-eigen", "cmeel-simde", + "typing-extensions", ] build-backend = "cmeel.build" configure-args = ["-DBUILD_TESTING:BOOL=OFF","-DBUILD_PYTHON_INTERFACE:BOOL=ON","-DBUILD_WITH_VECTORIZATION_SUPPORT:BOOL=ON","-DINSTALL_DOCUMENTATION:BOOL=OFF","-DBUILD_WITH_OPENMP_SUPPORT=OFF"] From bc0e35ab835f8b1f8e382884736f493d94cc4a0f Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 13:50:49 +0200 Subject: [PATCH 062/100] Update CHANGELOG --- CHANGELOG.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f6fad16..0953075b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added + +* Stub files for Python bindings, using [nanobind's native support](https://nanobind.readthedocs.io/en/latest/typing.html#stub-generation) ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) + +### Changed + +* Change Python bindings to use nanobind instead of pybind11 ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) + ## [0.6.7] - 2024-08-27 ### Added * Fix mu update function for PrimalLDLT backend ([#349](https://github.com/Simple-Robotics/proxsuite/pull/349)) * Allow use of installed pybind11, cereal and jrl-cmakemodules via cmake * Add compatibility with jrl-cmakemodules workspace ([#339](https://github.com/Simple-Robotics/proxsuite/pull/339)) -* Specifically mention that timings are in microseconds ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) -* Fix cereal include directory in cmake ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) -* Extend doc with hint for conda installation from source ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) +* Specifically mention that timings are in microseconds ([#342](https://github.com/Simple-Robotics/proxsuite/pull/342)) +* Fix cereal include directory in cmake ([#342](https://github.com/Simple-Robotics/proxsuite/pull/342)) +* Extend doc with hint for conda installation from source ([#342](https://github.com/Simple-Robotics/proxsuite/pull/342)) ### Fixed * Fix inequality constraints return in QPLayer ([#343](https://github.com/Simple-Robotics/proxsuite/pull/343)) From 3ea4718dd5022ff34506509ef8bb2f082496586b Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 18:31:37 +0200 Subject: [PATCH 063/100] [test] dense_qp_solve.py : remove useless line --- test/src/dense_qp_solve.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/src/dense_qp_solve.py b/test/src/dense_qp_solve.py index 6475da821..b26896fd8 100644 --- a/test/src/dense_qp_solve.py +++ b/test/src/dense_qp_solve.py @@ -39,7 +39,6 @@ def generate_mixed_qp(n, seed=1): q = np.random.randn(n) A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality u = A @ v l = -1.0e20 * np.ones(m) From a8256bf1e6f731a343a75f0e73a8824baf6d4446 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 21:58:15 +0200 Subject: [PATCH 064/100] [bindings/python] remove macro PROXSUITE_PYTHON_EIGEN_READWRITE + nanobind handles things well already --- bindings/python/src/expose-model.hpp | 33 +++++------------ bindings/python/src/expose-results.hpp | 51 +++++++++++++++++--------- bindings/python/src/helpers.hpp | 16 -------- 3 files changed, 43 insertions(+), 57 deletions(-) delete mode 100644 bindings/python/src/helpers.hpp diff --git a/bindings/python/src/expose-model.hpp b/bindings/python/src/expose-model.hpp index 2b4a37d4a..3739f26b3 100644 --- a/bindings/python/src/expose-model.hpp +++ b/bindings/python/src/expose-model.hpp @@ -12,7 +12,7 @@ #include #include #include -#include "helpers.hpp" + namespace proxsuite { namespace proxqp { namespace dense { @@ -22,36 +22,23 @@ void exposeDenseModel(nanobind::module_ m) { - ::nanobind::class_>(m, - "BackwardData") + ::nanobind::class_>(m, "BackwardData") .def(::nanobind::init(), "Default constructor.") .def( "initialize", - &proxsuite::proxqp::dense::BackwardData::initialize, + &BackwardData::initialize, nanobind::arg("n") = 0, nanobind::arg("n_eq") = 0, nanobind::arg("n_in") = 0, "Initialize the jacobians (allocate memory if not already done) and set" " by default their value to zero.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dH, "dL_dH.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dg, "dL_dg.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dA, "dL_dA.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_db, "dL_db.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dC, "dL_dC.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_du, "dL_du.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dl, "dL_dl.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(BackwardData, dL_dl, "dL_dl."); - // .def_ro("dL_dH", &proxsuite::proxqp::dense::BackwardData::dL_dH) - // .def_ro("dL_dg", &proxsuite::proxqp::dense::BackwardData::dL_dg) - // .def_ro("dL_dA", &proxsuite::proxqp::dense::BackwardData::dL_dA) - // .def_ro("dL_db", - // &proxsuite::proxqp::dense::BackwardData::dL_db) - // .def_ro("dL_dC", - // &proxsuite::proxqp::dense::BackwardData::dL_dC) - // .def_ro("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du) - // .def_ro("dL_dl", - // &proxsuite::proxqp::dense::BackwardData::dL_dl) - // .def_ro("dL_du", &proxsuite::proxqp::dense::BackwardData::dL_du); + .def_ro("dL_dH", &BackwardData::dL_dH) + .def_ro("dL_dg", &BackwardData::dL_dg) + .def_ro("dL_dA", &BackwardData::dL_dA) + .def_ro("dL_db", &BackwardData::dL_db) + .def_ro("dL_dC", &BackwardData::dL_dC) + .def_ro("dL_du", &BackwardData::dL_du) + .def_ro("dL_dl", &BackwardData::dL_dl); // .def_ro("dL_dse", &proxsuite::proxqp::dense::BackwardData::dL_dse) // .def_ro("dL_dsi", // &proxsuite::proxqp::dense::BackwardData::dL_dsi); diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index a882bfa91..10b2135bd 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -12,8 +12,6 @@ #include #include -#include "helpers.hpp" - namespace proxsuite { namespace proxqp { namespace python { @@ -67,23 +65,40 @@ exposeResults(nanobind::module_ m) nanobind::arg("n_eq") = 0, nanobind::arg("n_in") = 0, "Constructor from QP model dimensions.") // constructor - .PROXSUITE_PYTHON_EIGEN_READWRITE(Results, x, "The primal solution.") - .PROXSUITE_PYTHON_EIGEN_READWRITE( - Results, - y, - "The dual solution associated to the equality constraints.") - .PROXSUITE_PYTHON_EIGEN_READWRITE( - Results, - z, - "The dual solution associated to the inequality constraints.") - .PROXSUITE_PYTHON_EIGEN_READWRITE( - Results, - se, + // .PROXSUITE_PYTHON_EIGEN_READWRITE(Results, x, "The primal solution.") + // .PROXSUITE_PYTHON_EIGEN_READWRITE( + // Results, + // y, + // "The dual solution associated to the equality constraints.") + // .PROXSUITE_PYTHON_EIGEN_READWRITE( + // Results, + // z, + // "The dual solution associated to the inequality constraints.") + // .PROXSUITE_PYTHON_EIGEN_READWRITE( + // Results, + // se, + // "Optimal shift to the closest feasible problem wrt equality + // constraints.") + // .PROXSUITE_PYTHON_EIGEN_READWRITE(Results, + // si, + // "Optimal shift to the closest feasible + // " "problem wrt inequality + // constraints.") + .def_rw("x", &Results::x, "The primal solution.") + .def_rw("y", + &Results::y, + "The dual solution associated to the equality constraints.") + .def_rw("z", + &Results::z, + "The dual solution associated to the inequality constraints.") + .def_rw( + "se", + &Results::se, "Optimal shift to the closest feasible problem wrt equality constraints.") - .PROXSUITE_PYTHON_EIGEN_READWRITE(Results, - si, - "Pptimal shift to the closest feasible " - "problem wrt inequality constraints.") + .def_rw("si", + &Results::si, + "Optimal shift to the closest feasible problem wrt inequality " + "constraints.") .def_rw("info", &Results::info) .def(nanobind::self == nanobind::self) .def(nanobind::self != nanobind::self) diff --git a/bindings/python/src/helpers.hpp b/bindings/python/src/helpers.hpp deleted file mode 100644 index fc7c37de6..000000000 --- a/bindings/python/src/helpers.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright (c) 2022 INRIA -// -#ifndef proxsuite_python_helpers_hpp -#define proxsuite_python_helpers_hpp - -#define PROXSUITE_PYTHON_EIGEN_READWRITE(class, field_name, doc) \ - def_prop_rw( \ - #field_name, \ - [](class& self) { return self.field_name; }, \ - [](class& self, const decltype(class ::field_name)& value) { \ - self.field_name = value; \ - }, \ - doc) - -#endif // ifndef proxsuite_python_helpers_hpp From aaeca09f7e19b4b0fcf4bd056b9eed00d05ae0c2 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 22:08:19 +0200 Subject: [PATCH 065/100] [test] fix bare except --- test/src/serialization.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/serialization.py b/test/src/serialization.py index 0fd4c5770..0c72298e2 100644 --- a/test/src/serialization.py +++ b/test/src/serialization.py @@ -42,7 +42,7 @@ def generic_test(object, filename): try: with open(filename, "wb") as f: pickle.dump(object, f) - except: + except pickle.PickleError: dump_success = False else: dump_success = True @@ -52,7 +52,7 @@ def generic_test(object, filename): try: with open(filename, "rb") as f: loaded_object = pickle.load(f) - except: + except pickle.PickleError: read_success = False else: read_success = True From 54f42c6d8de399c967588dc93741995e85694288 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 22:22:13 +0200 Subject: [PATCH 066/100] [test] Fix serialization + pickle expects to be loading a str instead of bytes --- bindings/python/src/expose-model.hpp | 4 ++-- bindings/python/src/expose-qpobject.hpp | 4 ++-- bindings/python/src/expose-results.hpp | 4 ++-- bindings/python/src/expose-settings.hpp | 4 ++-- test/src/serialization.py | 5 +---- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/bindings/python/src/expose-model.hpp b/bindings/python/src/expose-model.hpp index 3739f26b3..92ea5c6ce 100644 --- a/bindings/python/src/expose-model.hpp +++ b/bindings/python/src/expose-model.hpp @@ -70,10 +70,10 @@ exposeDenseModel(nanobind::module_ m) [](const proxsuite::proxqp::dense::Model& model) { return proxsuite::serialization::saveToString(model); }) - .def("__setstate__", [](dense::Model& model, nanobind::bytes& s) { + .def("__setstate__", [](dense::Model& model, const std::string& s) { // create qp model which will be updated by loaded data new (&model) dense::Model(1, 1, 1); - proxsuite::serialization::loadFromString(model, s.c_str()); + proxsuite::serialization::loadFromString(model, s); }); } } // namespace python diff --git a/bindings/python/src/expose-qpobject.hpp b/bindings/python/src/expose-qpobject.hpp index 70e22f2b6..3f37d3b72 100644 --- a/bindings/python/src/expose-qpobject.hpp +++ b/bindings/python/src/expose-qpobject.hpp @@ -224,9 +224,9 @@ exposeQpObjectDense(nanobind::module_ m) [](const dense::QP& qp) { return proxsuite::serialization::saveToString(qp); }) - .def("__setstate__", [](dense::QP& qp, nanobind::bytes& s) { + .def("__setstate__", [](dense::QP& qp, const std::string& s) { new (&qp) dense::QP(1, 1, 1); - proxsuite::serialization::loadFromString(qp, s.c_str()); + proxsuite::serialization::loadFromString(qp, s); }); ; } diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index 10b2135bd..73440dd33 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -106,9 +106,9 @@ exposeResults(nanobind::module_ m) [](const Results& results) { return proxsuite::serialization::saveToString(results); }) - .def("__setstate__", [](Results& results, nanobind::bytes& s) { + .def("__setstate__", [](Results& results, const std::string& s) { new (&results) Results{}; - proxsuite::serialization::loadFromString(results, s.c_str()); + proxsuite::serialization::loadFromString(results, s); }); ; } diff --git a/bindings/python/src/expose-settings.hpp b/bindings/python/src/expose-settings.hpp index 4569f7d3e..c99d8767d 100644 --- a/bindings/python/src/expose-settings.hpp +++ b/bindings/python/src/expose-settings.hpp @@ -96,9 +96,9 @@ exposeSettings(nanobind::module_ m) [](const Settings& settings) { return proxsuite::serialization::saveToString(settings); }) - .def("__setstate__", [](Settings& settings, nanobind::bytes& s) { + .def("__setstate__", [](Settings& settings, const std::string& s) { new (&settings) Settings{}; - proxsuite::serialization::loadFromString(settings, s.c_str()); + proxsuite::serialization::loadFromString(settings, s); }); ; } diff --git a/test/src/serialization.py b/test/src/serialization.py index 0c72298e2..4dd935ef8 100644 --- a/test/src/serialization.py +++ b/test/src/serialization.py @@ -29,9 +29,8 @@ def generate_mixed_qp(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality u = A @ v l = -1.0e20 * np.ones(m) @@ -63,8 +62,6 @@ def generic_test(object, filename): class DenseqpWrapperSerialization(unittest.TestCase): def test_pickle(self): - import pickle - print("------------------------test pickle") n = 10 H, g, A, b, C, u, l = generate_mixed_qp(n) From 029767647b733e817e1ef333adbdfdf32939ba25 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 22:22:46 +0200 Subject: [PATCH 067/100] [test] Force C-order (row-major) for all matrices in the tests --- test/src/dense_qp_solve.py | 12 ++++++++---- test/src/dense_qp_wrapper.py | 9 ++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/src/dense_qp_solve.py b/test/src/dense_qp_solve.py index b26896fd8..3920199d6 100644 --- a/test/src/dense_qp_solve.py +++ b/test/src/dense_qp_solve.py @@ -37,7 +37,9 @@ def generate_mixed_qp(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray( + order="C" + ) # row-major v = np.random.randn(n) # Fictitious solution u = A @ v l = -1.0e20 * np.ones(m) @@ -309,10 +311,12 @@ def test_sparse_problem_with_exact_solution_known(self): M[i, i - 1] = 1 H = spa.csc_matrix(M.dot(M.transpose())).toarray() + H = np.ascontiguousarray(H) g = -np.ones((n,)) A = None b = None C = spa.csc_matrix(spa.eye(n)).toarray() + C = np.ascontiguousarray(C) l = 2.0 * np.ones((n,)) u = np.full(l.shape, +np.inf) @@ -378,11 +382,11 @@ def test_solve_qpsolvers_problem(self): os.path.join(data_path, "simple_qp_with_inifinity_lower_bound.mat"), squeeze_me=True, ) - P = m["P"].astype(float) + P = np.ascontiguousarray(m["P"].astype(float)) q = m["q"].astype(float) - A = m["A"].astype(float).reshape((1, 3)) + A = np.ascontiguousarray(m["A"].astype(float).reshape((1, 3))) b = np.array([m["b"]]).reshape((1,)) - C = m["C"].astype(float) + C = np.ascontiguousarray(m["C"].astype(float)) l = m["l"].astype(float) u = m["u"].astype(float) diff --git a/test/src/dense_qp_wrapper.py b/test/src/dense_qp_wrapper.py index 0bda2f085..4f3810bae 100644 --- a/test/src/dense_qp_wrapper.py +++ b/test/src/dense_qp_wrapper.py @@ -37,7 +37,7 @@ def generate_mixed_qp(n, seed=1, reg=0.01): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') v = np.random.randn(n) # Fictitious solution delta = np.random.rand(m) # To get inequality u = A @ v @@ -67,9 +67,8 @@ def generate_mixed_qp_with_box(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray() + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') v = np.random.randn(n) # Fictitious solution - delta = np.random.rand(m) # To get inequality u = A @ v l = -1.0e20 * np.ones(m) delta_box = np.random.rand(n) @@ -3924,11 +3923,11 @@ def test_sparse_problem_with_exact_solution_known(self): M[i, i + 1] = -1 M[i, i - 1] = 1 - H = spa.csc_matrix(M.dot(M.transpose())).toarray() + H = spa.csc_matrix(M.dot(M.transpose())).toarray(order='C') g = -np.ones((n,)) A = None b = None - C = spa.csc_matrix(spa.eye(n)).toarray() + C = spa.csc_matrix(spa.eye(n)).toarray(order='C') l = 2.0 * np.ones((n,)) u = np.full(l.shape, +np.inf) From 8dccf3b1b5c0dec08d2116b0e2e37ea90ca06911 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 22:23:25 +0200 Subject: [PATCH 068/100] [bindings/python] Fix overloaded dense.solve() signatures, switch nullopt for nanobind::none() --- bindings/python/src/expose-solve.hpp | 118 +++++++++++++-------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/bindings/python/src/expose-solve.hpp b/bindings/python/src/expose-solve.hpp index 8721ba570..c89faad1b 100644 --- a/bindings/python/src/expose-solve.hpp +++ b/bindings/python/src/expose-solve.hpp @@ -51,30 +51,30 @@ solveDenseQp(nanobind::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, - nanobind::arg("x") = nullopt, - nanobind::arg("y") = nullopt, - nanobind::arg("z") = nullopt, - nanobind::arg("eps_abs") = nullopt, - nanobind::arg("eps_rel") = nullopt, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("verbose") = nullopt, + nanobind::arg("H"), + nanobind::arg("g"), + nanobind::arg("A").none(), + nanobind::arg("b").none(), + nanobind::arg("C").none(), + nanobind::arg("l").none(), + nanobind::arg("u").none(), + nanobind::arg("x") = nanobind::none(), + nanobind::arg("y") = nanobind::none(), + nanobind::arg("z") = nanobind::none(), + nanobind::arg("eps_abs") = nanobind::none(), + nanobind::arg("eps_rel") = nanobind::none(), + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("verbose") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, nanobind::arg("compute_timings") = false, - nanobind::arg("max_iter") = nullopt, + nanobind::arg("max_iter") = nanobind::none(), nanobind::arg("initial_guess") = InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, nanobind::arg("check_duality_gap") = false, - nanobind::arg("eps_duality_gap_abs") = nullopt, - nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("eps_duality_gap_abs") = nanobind::none(), + nanobind::arg("eps_duality_gap_rel") = nanobind::none(), nanobind::arg("primal_infeasibility_solving") = false, nanobind::arg("default_H_eigenvalue_estimate") = 0.); @@ -112,32 +112,32 @@ solveDenseQp(nanobind::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, - nanobind::arg("l_box") = nullopt, - nanobind::arg("u_box") = nullopt, - nanobind::arg("x") = nullopt, - nanobind::arg("y") = nullopt, - nanobind::arg("z") = nullopt, - nanobind::arg("eps_abs") = nullopt, - nanobind::arg("eps_rel") = nullopt, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("verbose") = nullopt, + nanobind::arg("H"), + nanobind::arg("g"), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), + nanobind::arg("l_box") = nanobind::none(), + nanobind::arg("u_box") = nanobind::none(), + nanobind::arg("x") = nanobind::none(), + nanobind::arg("y") = nanobind::none(), + nanobind::arg("z") = nanobind::none(), + nanobind::arg("eps_abs") = nanobind::none(), + nanobind::arg("eps_rel") = nanobind::none(), + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("verbose") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, nanobind::arg("compute_timings") = false, - nanobind::arg("max_iter") = nullopt, + nanobind::arg("max_iter") = nanobind::none(), nanobind::arg("initial_guess") = proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, nanobind::arg("check_duality_gap") = false, - nanobind::arg("eps_duality_gap_abs") = nullopt, - nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("eps_duality_gap_abs") = nanobind::none(), + nanobind::arg("eps_duality_gap_rel") = nanobind::none(), nanobind::arg("primal_infeasibility_solving") = false, nanobind::arg("default_H_eigenvalue_estimate") = 0.); } @@ -160,31 +160,31 @@ solveSparseQp(nanobind::module_ m) "parameters (warm start, initial guess option, proximal step sizes, " "absolute and relative accuracies, maximum number of iterations, " "preconditioner execution).", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, - nanobind::arg("x") = nullopt, - nanobind::arg("y") = nullopt, - nanobind::arg("z") = nullopt, - nanobind::arg("eps_abs") = nullopt, - nanobind::arg("eps_rel") = nullopt, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("verbose") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), + nanobind::arg("x") = nanobind::none(), + nanobind::arg("y") = nanobind::none(), + nanobind::arg("z") = nanobind::none(), + nanobind::arg("eps_abs") = nanobind::none(), + nanobind::arg("eps_rel") = nanobind::none(), + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("verbose") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, nanobind::arg("compute_timings") = false, - nanobind::arg("max_iter") = nullopt, + nanobind::arg("max_iter") = nanobind::none(), nanobind::arg("initial_guess") = InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, nanobind::arg("sparse_backend") = SparseBackend::Automatic, nanobind::arg("check_duality_gap") = false, - nanobind::arg("eps_duality_gap_abs") = nullopt, - nanobind::arg("eps_duality_gap_rel") = nullopt, + nanobind::arg("eps_duality_gap_abs") = nanobind::none(), + nanobind::arg("eps_duality_gap_rel") = nanobind::none(), nanobind::arg("primal_infeasibility_solving") = false, nanobind::arg("default_H_eigenvalue_estimate") = 0.); } From 395933c85f82193fa88ece54184c92401f31b542 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 22:29:17 +0200 Subject: [PATCH 069/100] [test] reformat using black --- test/src/dense_qp_wrapper.py | 12 ++++++++---- test/src/serialization.py | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/test/src/dense_qp_wrapper.py b/test/src/dense_qp_wrapper.py index 4f3810bae..871f0a612 100644 --- a/test/src/dense_qp_wrapper.py +++ b/test/src/dense_qp_wrapper.py @@ -37,7 +37,9 @@ def generate_mixed_qp(n, seed=1, reg=0.01): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray( + order="C" + ) v = np.random.randn(n) # Fictitious solution delta = np.random.rand(m) # To get inequality u = A @ v @@ -67,7 +69,9 @@ def generate_mixed_qp_with_box(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray( + order="C" + ) v = np.random.randn(n) # Fictitious solution u = A @ v l = -1.0e20 * np.ones(m) @@ -3923,11 +3927,11 @@ def test_sparse_problem_with_exact_solution_known(self): M[i, i + 1] = -1 M[i, i - 1] = 1 - H = spa.csc_matrix(M.dot(M.transpose())).toarray(order='C') + H = spa.csc_matrix(M.dot(M.transpose())).toarray(order="C") g = -np.ones((n,)) A = None b = None - C = spa.csc_matrix(spa.eye(n)).toarray(order='C') + C = spa.csc_matrix(spa.eye(n)).toarray(order="C") l = 2.0 * np.ones((n,)) u = np.full(l.shape, +np.inf) diff --git a/test/src/serialization.py b/test/src/serialization.py index 4dd935ef8..4c03725e9 100644 --- a/test/src/serialization.py +++ b/test/src/serialization.py @@ -29,7 +29,9 @@ def generate_mixed_qp(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray(order='C') + A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray( + order="C" + ) v = np.random.randn(n) # Fictitious solution u = A @ v l = -1.0e20 * np.ones(m) From 9008bf95ed5118f42f1d75dac97e483cfc9f2608 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 6 Aug 2024 23:07:15 +0200 Subject: [PATCH 070/100] [workflows] also install typing_extensions package --- .github/workflows/ci-linux-osx-win-conda.yml | 2 +- .github/workflows/release-osx-win.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index 48f32ad21..a17df614e 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -82,7 +82,7 @@ jobs: # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/186 conda config --remove channels defaults # Compilation related dependencies - mamba install cmake compilers make pkg-config doxygen ninja graphviz + mamba install cmake compilers make pkg-config doxygen ninja graphviz typing_extensions # Main dependencies mamba install eigen simde # Test dependencies diff --git a/.github/workflows/release-osx-win.yml b/.github/workflows/release-osx-win.yml index 65f4f91de..8437eac91 100644 --- a/.github/workflows/release-osx-win.yml +++ b/.github/workflows/release-osx-win.yml @@ -57,7 +57,7 @@ jobs: run: | # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/186 conda config --remove channels defaults - mamba install doxygen graphviz eigen simde cmake compilers + mamba install doxygen graphviz eigen simde cmake compilers typing_extensions - name: Print environment [Conda] if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows') From 22fcd22483bb2ae3b050f0162bbd84f063737ea4 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Wed, 7 Aug 2024 12:03:01 +0200 Subject: [PATCH 071/100] [examples/python] fix toarray() for C order --- examples/python/solve_without_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/solve_without_api.py b/examples/python/solve_without_api.py index 3a489203a..1ba2c166d 100644 --- a/examples/python/solve_without_api.py +++ b/examples/python/solve_without_api.py @@ -16,7 +16,7 @@ # solve the problem using the dense backend results2 = proxsuite.proxqp.dense.solve( - H.toarray(), g, A.toarray(), b, C.toarray(), l, u + H.toarray(order="C"), g, A.toarray(order="C"), b, C.toarray(order="C"), l, u ) # Note finally, that the matrices are in sparse format, when using the dense backend you # should convert them in dense format From 603e208d866d92b6050d19556056d385f8d96288 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Wed, 7 Aug 2024 12:19:33 +0200 Subject: [PATCH 072/100] [test] parallel_qp_solve : .toarray() to C order --- test/src/parallel_qp_solve.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/src/parallel_qp_solve.py b/test/src/parallel_qp_solve.py index 4ea203569..11654c753 100644 --- a/test/src/parallel_qp_solve.py +++ b/test/src/parallel_qp_solve.py @@ -33,13 +33,23 @@ def generate_mixed_qp(n, seed=1): P = spa.coo_matrix(P) # print("sparsity of P : {}".format((P.nnz) / (n**2))) q = np.random.randn(n) - A = spa.random(m, n, density=0.95, data_rvs=np.random.randn, format="csc").toarray() + A = spa.random(m, n, density=0.95, data_rvs=np.random.randn, format="csc").toarray( + order="C" + ) v = np.random.randn(n) # Fictitious solution delta = np.random.rand(m) # To get inequality u = A @ v l = -1.0e20 * np.ones(m) - return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:] + return ( + P.toarray(order="C"), + q, + A[:n_eq, :], + u[:n_eq], + A[n_in:, :], + u[n_in:], + l[n_in:], + ) class ParallelWrapper(unittest.TestCase): From 856e0571a0b13e09b8229d005264a79e50a79be4 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Wed, 7 Aug 2024 17:39:50 +0200 Subject: [PATCH 073/100] Update minimum Python to 3.8 (3.7 has been EOL for a year) --- bindings/python/CMakeLists.txt | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 30d49293e..2e41019a5 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -8,7 +8,7 @@ include(${JRL_CMAKE_MODULES}/python-helpers.cmake) option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) findpython(REQUIRED Development.Module) -find_package(Python 3.8 COMPONENTS ${PYTHON_COMPONENTS}) +find_package(Python 3.7 COMPONENTS ${PYTHON_COMPONENTS}) if(IS_ABSOLUTE ${PYTHON_SITELIB}) set(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME}) diff --git a/pyproject.toml b/pyproject.toml index 3aa236457..9f65cf1c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "proxsuite" version = "0.6.7" description = "Quadratic Programming Solver for Robotics and beyond." readme = "README.md" -requires-python = ">= 3.7" +requires-python = ">= 3.8" license = "BSD-2-Clause" dependencies = ["numpy","scipy"] From 4882f59d70edc003e157607fba3c5e1e63c1a9ef Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 8 Aug 2024 12:11:15 +0200 Subject: [PATCH 074/100] [test] cvxpy.py : ensure matrix and gradient are float64 --- test/src/cvxpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/cvxpy.py b/test/src/cvxpy.py index d4e609e16..cd45496cf 100644 --- a/test/src/cvxpy.py +++ b/test/src/cvxpy.py @@ -56,8 +56,8 @@ def test_trigger_infeasibility_with_exact_solution_known(self): def test_one_dim_with_exact_solution_known(self): print("------------------------ test_one_dim_with_exact_solution_known") n = 1 - H = np.array([[20]]) - g = np.array([-10]) + H = np.array([[20.0]]) + g = np.array([-10.0]) A = None b = None C = np.array([[1.0]]) From b810caf506d5b9da894092cc3d78d3259873465b Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 8 Aug 2024 14:37:45 +0200 Subject: [PATCH 075/100] [bindings/python] cmake : fix the bloody include dirs variable ?? --- bindings/python/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 2e41019a5..93d8d3b91 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -8,7 +8,7 @@ include(${JRL_CMAKE_MODULES}/python-helpers.cmake) option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) findpython(REQUIRED Development.Module) -find_package(Python 3.7 COMPONENTS ${PYTHON_COMPONENTS}) +set(Python_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) if(IS_ABSOLUTE ${PYTHON_SITELIB}) set(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME}) From e7394b3cb1002fb4314ec5d05e50115102698bb3 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 8 Aug 2024 18:03:48 +0200 Subject: [PATCH 076/100] [examples/python] fix some more C orders --- examples/python/solve_without_api.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/python/solve_without_api.py b/examples/python/solve_without_api.py index 1ba2c166d..53904c718 100644 --- a/examples/python/solve_without_api.py +++ b/examples/python/solve_without_api.py @@ -34,7 +34,15 @@ # make sure to specify l_box=l_box, u_box=u_box in order to make work the # overloading results_dense_solver_box = proxsuite.proxqp.dense.solve( - H.toarray(), g, A.toarray(), b, C.toarray(), l, u, l_box=l_box, u_box=u_box + H.toarray(order="C"), + g, + A.toarray(order="C"), + b, + C.toarray(order="C"), + l, + u, + l_box=l_box, + u_box=u_box, ) # print an optimal solution print("optimal x: {}".format(results_dense_solver_box.x)) From f004f5d303893ca1a08aa77f80c114e26033871b Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Fri, 9 Aug 2024 11:42:00 +0200 Subject: [PATCH 077/100] cmake : alias some targets to Python::* --- bindings/python/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 93d8d3b91..a58b39df6 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -1,5 +1,5 @@ if(UNIX) - set(PYTHON_COMPONENTS Development.Module) + set(PYTHON_COMPONENTS Interpreter Development.Module) endif() include(${JRL_CMAKE_MODULES}/python.cmake) @@ -7,8 +7,12 @@ include(${JRL_CMAKE_MODULES}/python-helpers.cmake) option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) -findpython(REQUIRED Development.Module) -set(Python_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) +findpython(REQUIRED) +set(Python_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) +# Nanobind expects these targets instead of Python3::* +# https://github.com/jrl-umi3218/jrl-cmakemodules/issues/708 +add_library(Python::Module ALIAS Python3::Module) +add_executable(Python::Interpreter ALIAS Python3::Interpreter) if(IS_ABSOLUTE ${PYTHON_SITELIB}) set(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME}) From 05632d223b8707ee79f8a106bb5a44ac27b7ab6d Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Fri, 9 Aug 2024 12:07:49 +0200 Subject: [PATCH 078/100] [workflows] remove macOS C++14 --- .github/workflows/ci-linux-osx-win-conda.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index a17df614e..be2bec460 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -29,10 +29,6 @@ jobs: compiler: clang-cl - name: windows-latest os: windows-latest - - name: macos-latest - os: macos-latest - build_type: Release - cxx_std: 14 - name: macos-latest os: macos-latest build_type: Debug From 27238729482744425f05c0c2ca8a7fa4d2f38dc8 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Fri, 9 Aug 2024 13:23:49 +0200 Subject: [PATCH 079/100] [bindings/python] use nanobind::none() instead of nullopt --- bindings/python/src/expose-qpobject.hpp | 144 ++++++++++++------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/bindings/python/src/expose-qpobject.hpp b/bindings/python/src/expose-qpobject.hpp index 3f37d3b72..84237b640 100644 --- a/bindings/python/src/expose-qpobject.hpp +++ b/bindings/python/src/expose-qpobject.hpp @@ -102,18 +102,18 @@ exposeQpObjectDense(nanobind::module_ m) optional, optional)>(&dense::QP::init), "function for initialize the QP model.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, + nanobind::arg("H"), + nanobind::arg("g"), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def("init", static_cast::*)(optional>, optional>, @@ -130,20 +130,20 @@ exposeQpObjectDense(nanobind::module_ m) optional, optional)>(&dense::QP::init), "function for initialize the QP model.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, - nanobind::arg("l_box") = nullopt, - nanobind::arg("u_box") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), + nanobind::arg("l_box") = nanobind::none(), + nanobind::arg("u_box") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def("solve", static_cast::*)()>(&dense::QP::solve), "function used for solving the QP problem, using default parameters.") @@ -170,18 +170,18 @@ exposeQpObjectDense(nanobind::module_ m) optional)>(&dense::QP::update), "function used for updating matrix or vector entry of the model using " "dense matrix entries.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), nanobind::arg("update_preconditioner") = false, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def( "update", static_cast::*)(optional>, @@ -200,20 +200,20 @@ exposeQpObjectDense(nanobind::module_ m) optional)>(&dense::QP::update), "function used for updating matrix or vector entry of the model using " "dense matrix entries.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, - nanobind::arg("l_box") = nullopt, - nanobind::arg("u_box") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), + nanobind::arg("l_box") = nanobind::none(), + nanobind::arg("u_box") = nanobind::none(), nanobind::arg("update_preconditioner") = false, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def("cleanup", &dense::QP::cleanup, "function used for cleaning the workspace and result " @@ -251,8 +251,8 @@ exposeQpObjectSparse(nanobind::module_ m) .def(::nanobind::init&, const sparse::SparseMat&, const sparse::SparseMat&>(), - nanobind::arg("H_mask") = nullopt, - nanobind::arg("A_mask") = nullopt, + nanobind::arg("H_mask") = nanobind::none(), + nanobind::arg("A_mask") = nanobind::none(), nanobind::arg("C_mask") = 0, "Constructor using QP model sparsity structure.") // constructor .def_ro("model", &sparse::QP::model, "class containing the QP model") @@ -266,35 +266,35 @@ exposeQpObjectSparse(nanobind::module_ m) &sparse::QP::init, "function for initializing the model when passing sparse matrices in " "entry.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), nanobind::arg("compute_preconditioner") = true, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def("update", &sparse::QP::update, "function for updating the model when passing sparse matrices in " "entry.", - nanobind::arg("H") = nullopt, - nanobind::arg("g") = nullopt, - nanobind::arg("A") = nullopt, - nanobind::arg("b") = nullopt, - nanobind::arg("C") = nullopt, - nanobind::arg("l") = nullopt, - nanobind::arg("u") = nullopt, + nanobind::arg("H") = nanobind::none(), + nanobind::arg("g") = nanobind::none(), + nanobind::arg("A") = nanobind::none(), + nanobind::arg("b") = nanobind::none(), + nanobind::arg("C") = nanobind::none(), + nanobind::arg("l") = nanobind::none(), + nanobind::arg("u") = nanobind::none(), nanobind::arg("update_preconditioner") = false, - nanobind::arg("rho") = nullopt, - nanobind::arg("mu_eq") = nullopt, - nanobind::arg("mu_in") = nullopt, - nanobind::arg("manual_minimal_H_eigenvalue") = nullopt) + nanobind::arg("rho") = nanobind::none(), + nanobind::arg("mu_eq") = nanobind::none(), + nanobind::arg("mu_in") = nanobind::none(), + nanobind::arg("manual_minimal_H_eigenvalue") = nanobind::none()) .def("solve", static_cast::*)()>(&sparse::QP::solve), "function used for solving the QP problem, using default parameters.") From 94f13f1898a1f66fea2ec30c7aa18b3dc2481df8 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 20 Aug 2024 17:50:00 +0200 Subject: [PATCH 080/100] [bindings] point nanobind to latest master --- .gitmodules | 2 +- bindings/python/external/nanobind | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2867bf33b..0556288d9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "bindings/python/external/nanobind"] path = bindings/python/external/nanobind - url = https://github.com/wjakob/nanobind + url = https://github.com/ManifoldFR/nanobind [submodule "cmake-module"] path = cmake-module url = https://github.com/jrl-umi3218/jrl-cmakemodules.git diff --git a/bindings/python/external/nanobind b/bindings/python/external/nanobind index 8d7f1ee06..8a65e0e39 160000 --- a/bindings/python/external/nanobind +++ b/bindings/python/external/nanobind @@ -1 +1 @@ -Subproject commit 8d7f1ee0621c17fa370b704b2100ffa0243d5bfb +Subproject commit 8a65e0e39ca1621fdf20130e94bccb5850ca0f81 From 6d167e899256bbc69b10c9cb4f920d8dd82524d8 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 27 Aug 2024 13:14:22 +0200 Subject: [PATCH 081/100] Add fix for std::optional> --- bindings/python/src/expose-results.hpp | 2 +- bindings/python/src/expose-solve.hpp | 2 +- bindings/python/src/optional-eigen-fix.hpp | 45 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 bindings/python/src/optional-eigen-fix.hpp diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index 73440dd33..f4bd8c492 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include "optional-eigen-fix.hpp" #include #include diff --git a/bindings/python/src/expose-solve.hpp b/bindings/python/src/expose-solve.hpp index c89faad1b..25befc0bd 100644 --- a/bindings/python/src/expose-solve.hpp +++ b/bindings/python/src/expose-solve.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include "optional-eigen-fix.hpp" namespace proxsuite { namespace proxqp { diff --git a/bindings/python/src/optional-eigen-fix.hpp b/bindings/python/src/optional-eigen-fix.hpp new file mode 100644 index 000000000..3a09564d7 --- /dev/null +++ b/bindings/python/src/optional-eigen-fix.hpp @@ -0,0 +1,45 @@ +// +// Copyright (c) 2024 INRIA +// +#pragma once + +#include +#include + +NAMESPACE_BEGIN(NB_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/// Fix std::optional for Eigen::Ref +/// Credit to github.com/WKarel for this suggestion! +/// https://github.com/wjakob/nanobind/issues/682#issuecomment-2310746145 +template +struct type_caster>> + : optional_caster>> +{ + using Ref = Eigen::Ref; + using Optional = std::optional; + using Caster = typename type_caster::optional_caster::Caster; + using Map = typename Caster::Map; + using DMap = typename Caster::DMap; + NB_TYPE_CASTER(Optional, optional_name(Caster::Name)) + + bool from_python(handle src, uint8_t flags, cleanup_list* cleanup) noexcept + { + if (src.is_none()) + return true; + Caster caster; + if (!caster.from_python(src, flags_for_local_caster(flags), cleanup) || + !caster.template can_cast()) + return false; + /// This allows us to bypass the type_caster for Eigen::Ref + /// which is broken due to lack of NRVO + move ctor in latest Eigen release. + if (caster.dcaster.caster.value.is_valid()) + value.emplace(caster.dcaster.operator DMap()); + else + value.emplace(caster.caster.operator Map()); + return true; + } +}; + +NAMESPACE_END(detail) +NAMESPACE_END(NB_NAMESPACE) From 3d637fd951876204c97698c51e064d3f699f8d90 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 27 Aug 2024 13:27:00 +0200 Subject: [PATCH 082/100] apparently i64/u64 and isize/size_t are not the same thing on the Windows --- bindings/python/src/expose-qpobject.hpp | 8 ++++---- bindings/python/src/expose-qpvector.hpp | 4 ++-- bindings/python/src/expose-results.hpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bindings/python/src/expose-qpobject.hpp b/bindings/python/src/expose-qpobject.hpp index 84237b640..288c1a7d2 100644 --- a/bindings/python/src/expose-qpobject.hpp +++ b/bindings/python/src/expose-qpobject.hpp @@ -58,9 +58,9 @@ exposeQpObjectDense(nanobind::module_ m) // .def_rw("run_time", &RuizEquilibration::sym); ::nanobind::class_>(m, "QP") - .def(::nanobind::init(), @@ -243,7 +243,7 @@ exposeQpObjectSparse(nanobind::module_ m) { ::nanobind::class_>(m, "QP") - .def(::nanobind::init(), + .def(::nanobind::init(), nanobind::arg("n") = 0, nanobind::arg("n_eq") = 0, nanobind::arg("n_in") = 0, diff --git a/bindings/python/src/expose-qpvector.hpp b/bindings/python/src/expose-qpvector.hpp index 1b077a4af..0530ac41a 100644 --- a/bindings/python/src/expose-qpvector.hpp +++ b/bindings/python/src/expose-qpvector.hpp @@ -21,7 +21,7 @@ exposeQPVectorDense(nanobind::module_ m) ::nanobind::class_>(m, "BatchQP") .def( - ::nanobind::init(), + ::nanobind::init(), nanobind::arg("batch_size") = 0, "Default constructor using the BatchSize of qp models to store.") // constructor .def("init_qp_in_place", @@ -51,7 +51,7 @@ exposeQPVectorSparse(nanobind::module_ m) ::nanobind::class_>(m, "BatchQP") .def( - ::nanobind::init(), + ::nanobind::init(), nanobind::arg("batch_size") = 0, "Default constructor using the BatchSize of qp models to store.") // constructor .def("init_qp_in_place", diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index f4bd8c492..bab63daba 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -60,7 +60,7 @@ exposeResults(nanobind::module_ m) "find_H_minimal_eigenvalue."); ::nanobind::class_>(m, "Results") - .def(::nanobind::init(), + .def(::nanobind::init(), nanobind::arg("n") = 0, nanobind::arg("n_eq") = 0, nanobind::arg("n_in") = 0, From 3804bae16d47fd007217f8347f9f876b3b7c0185 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 27 Aug 2024 16:29:09 +0200 Subject: [PATCH 083/100] Change back URL of nanobind submodule --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 0556288d9..2867bf33b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "bindings/python/external/nanobind"] path = bindings/python/external/nanobind - url = https://github.com/ManifoldFR/nanobind + url = https://github.com/wjakob/nanobind [submodule "cmake-module"] path = cmake-module url = https://github.com/jrl-umi3218/jrl-cmakemodules.git From bfc2bea1ac52ffa87f86bd5cca440ed69a7d00bb Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 27 Aug 2024 17:29:28 +0200 Subject: [PATCH 084/100] Allow use of installed nanobind --- bindings/python/CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index a58b39df6..29487b9a9 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -21,9 +21,22 @@ else() ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME}) endif() -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) -add_subdirectory(external/nanobind - ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) +cmake_policy(PUSH) +cmake_policy(SET CMP0074 NEW) +# Detect the installed nanobind package and import it into CMake +execute_process( + COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE nanobind_ROOT) +find_package(nanobind CONFIG) +cmake_policy(POP) +if(NOT nanobind_FOUND) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) + add_subdirectory(external/nanobind + ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) +else() + message(STATUS "Found installed nanobind.") +endif() add_custom_target(${PROJECT_NAME}_python) From 0e4db0af171b02c0f5c11f814c65262bd567e571 Mon Sep 17 00:00:00 2001 From: Wilson Date: Tue, 27 Aug 2024 19:14:04 +0200 Subject: [PATCH 085/100] Update bindings/python/helpers/instruction-set.cpp Co-authored-by: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> --- bindings/python/helpers/instruction-set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/helpers/instruction-set.cpp b/bindings/python/helpers/instruction-set.cpp index cc92bf214..64035c447 100644 --- a/bindings/python/helpers/instruction-set.cpp +++ b/bindings/python/helpers/instruction-set.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // #include From 449267f60a68f14bcea7203f5863817acde4b009 Mon Sep 17 00:00:00 2001 From: Wilson Date: Tue, 27 Aug 2024 19:16:28 +0200 Subject: [PATCH 086/100] Update bindings/python/src/expose-results.hpp Co-authored-by: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> --- bindings/python/src/expose-results.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/src/expose-results.hpp b/bindings/python/src/expose-results.hpp index bab63daba..fa1e63160 100644 --- a/bindings/python/src/expose-results.hpp +++ b/bindings/python/src/expose-results.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022-2023 INRIA +// Copyright (c) 2022-2024 INRIA // #include #include From d509b5e373f5993ac473e06731fe886589c647f0 Mon Sep 17 00:00:00 2001 From: Wilson Date: Tue, 27 Aug 2024 19:18:51 +0200 Subject: [PATCH 087/100] Update bindings/python/src/expose-helpers.hpp Co-authored-by: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> --- bindings/python/src/expose-helpers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/src/expose-helpers.hpp b/bindings/python/src/expose-helpers.hpp index 76cba0e70..872a60fdd 100644 --- a/bindings/python/src/expose-helpers.hpp +++ b/bindings/python/src/expose-helpers.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 INRIA +// Copyright (c) 2022-2024 INRIA // #include From 519a6246437420b4be25ab13c5a3b16920248046 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Tue, 27 Aug 2024 19:52:51 +0200 Subject: [PATCH 088/100] [workflows] do not re-run linux, osx, win, arch CI and release CI when updating CHANGELOG.md --- .github/workflows/ci-arch.yml | 2 ++ .github/workflows/ci-linux-osx-win-conda.yml | 2 ++ .github/workflows/ci-linux-ros.yml | 6 +++++- .github/workflows/release-linux.yml | 2 ++ .github/workflows/release-osx-win.yml | 2 ++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-arch.yml b/.github/workflows/ci-arch.yml index af0cfd2ad..b9d2866d4 100644 --- a/.github/workflows/ci-arch.yml +++ b/.github/workflows/ci-arch.yml @@ -3,6 +3,8 @@ name: CI - ArchLinux on: push: pull_request: + paths-ignore: + - CHANGELOG.md jobs: build-with-arch: diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index be2bec460..ac7ed0e53 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -3,6 +3,8 @@ name: CI - Linux/OSX/Windows - Conda on: push: pull_request: + paths-ignore: + - CHANGELOG.md jobs: build-with-conda: diff --git a/.github/workflows/ci-linux-ros.yml b/.github/workflows/ci-linux-ros.yml index 49c54f1bd..c24478bc9 100644 --- a/.github/workflows/ci-linux-ros.yml +++ b/.github/workflows/ci-linux-ros.yml @@ -1,5 +1,9 @@ name: CI - Linux - ROS -on: [push, pull_request] +on: + push: + pull_request: + paths-ignore: + - CHANGELOG.md jobs: CI: diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 54125cbc8..84bcc72b3 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -2,6 +2,8 @@ name: Release on PyPI [Linux] on: pull_request: + paths-ignore: + - CHANGELOG.md release: types: - published diff --git a/.github/workflows/release-osx-win.yml b/.github/workflows/release-osx-win.yml index 8437eac91..845a980e6 100644 --- a/.github/workflows/release-osx-win.yml +++ b/.github/workflows/release-osx-win.yml @@ -2,6 +2,8 @@ name: Release on PyPI [Windows, Mac] on: pull_request: + paths-ignore: + - CHANGELOG.md release: types: - published From 8305864f13ca7dff7210f89004a56652b71f8891 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Fri, 30 Aug 2024 11:54:32 +0200 Subject: [PATCH 089/100] CMake: fix cereal link --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2bdc74162..bc6ba4a0b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -65,7 +65,7 @@ add_test_cflags( "-DTEST_SERIALIZATION_FOLDER=\\\\\"${CMAKE_CURRENT_BINARY_DIR}/serialization-data\\\\\"" ) if(cereal_FOUND) - target_link_libraries(${PROJECT_NAME}-test-cpp-serialization PRIVATE cereal) + target_link_libraries(${PROJECT_NAME}-test-cpp-serialization PRIVATE cereal::cereal) else() target_include_directories( ${PROJECT_NAME}-test-cpp-serialization SYSTEM From c7c2b2a504398dae27895e76b81df2460b71a551 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Fri, 30 Aug 2024 11:55:34 +0200 Subject: [PATCH 090/100] Set version of nanobind submodule to release v2.1.0 --- bindings/python/external/nanobind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/external/nanobind b/bindings/python/external/nanobind index 8a65e0e39..9641bb715 160000 --- a/bindings/python/external/nanobind +++ b/bindings/python/external/nanobind @@ -1 +1 @@ -Subproject commit 8a65e0e39ca1621fdf20130e94bccb5850ca0f81 +Subproject commit 9641bb7151f04120013b812789b3ebdfa7e7324f From d8b56b92acce87cddf745aec4cad220e002e9fb2 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Fri, 30 Aug 2024 11:55:49 +0200 Subject: [PATCH 091/100] add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f6fad16..59987ad57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +* CMake: Fix link to system cereal in tests ([#353](https://github.com/Simple-Robotics/proxsuite/pull/352)) + ## [0.6.7] - 2024-08-27 ### Added From d71966317a12ec943ce4702135c3d90828924899 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Fri, 30 Aug 2024 12:05:15 +0200 Subject: [PATCH 092/100] Fix for nanobind v2.1.0 release --- bindings/python/src/optional-eigen-fix.hpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/bindings/python/src/optional-eigen-fix.hpp b/bindings/python/src/optional-eigen-fix.hpp index 3a09564d7..cedd91103 100644 --- a/bindings/python/src/optional-eigen-fix.hpp +++ b/bindings/python/src/optional-eigen-fix.hpp @@ -14,15 +14,19 @@ NAMESPACE_BEGIN(detail) /// https://github.com/wjakob/nanobind/issues/682#issuecomment-2310746145 template struct type_caster>> - : optional_caster>> { using Ref = Eigen::Ref; using Optional = std::optional; - using Caster = typename type_caster::optional_caster::Caster; + using Caster = make_caster; using Map = typename Caster::Map; using DMap = typename Caster::DMap; NB_TYPE_CASTER(Optional, optional_name(Caster::Name)) + type_caster() + : value(std::nullopt) + { + } + bool from_python(handle src, uint8_t flags, cleanup_list* cleanup) noexcept { if (src.is_none()) @@ -39,6 +43,17 @@ struct type_caster>> value.emplace(caster.caster.operator Map()); return true; } + + template + static handle from_cpp(T_&& value, + rv_policy policy, + cleanup_list* cleanup) noexcept + { + if (!value) + return none().release(); + + return Caster::from_cpp(forward_like_(*value), policy, cleanup); + } }; NAMESPACE_END(detail) From dd63c04735a1d49959eb9e5ecbc3289bd16fa63f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 00:22:21 +0000 Subject: [PATCH 093/100] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-clang-format: v18.1.8 → v19.1.3](https://github.com/pre-commit/mirrors-clang-format/compare/v18.1.8...v19.1.3) - [github.com/pre-commit/pre-commit-hooks: v4.6.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.6.0...v5.0.0) - [github.com/psf/black: 24.8.0 → 24.10.0](https://github.com/psf/black/compare/24.8.0...24.10.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c69882f7..65aeabd18 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,16 +4,16 @@ ci: autoupdate_schedule: quarterly repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.8 + rev: v19.1.3 hooks: - id: clang-format args: ['--style={BasedOnStyle: Mozilla, SortIncludes: false}'] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 24.8.0 + rev: 24.10.0 hooks: - id: black - repo: https://github.com/cheshirekow/cmake-format-precommit From 46461795b4cf189d228d988d7db5a05d825b0e9a Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:32:23 +0100 Subject: [PATCH 094/100] fix windows build error --- include/proxsuite/linalg/veg/tuple.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/proxsuite/linalg/veg/tuple.hpp b/include/proxsuite/linalg/veg/tuple.hpp index 8fe3ca1a9..36fea520d 100644 --- a/include/proxsuite/linalg/veg/tuple.hpp +++ b/include/proxsuite/linalg/veg/tuple.hpp @@ -754,9 +754,15 @@ struct cat proxsuite::linalg::veg::meta::false_type /*unused*/, Tuples&&... tups) VEG_NOEXCEPT -> Concat { - return cat::template from_ref_to_result( - Tag>{}, - cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); +#ifdef _MSC_VER +return cat::from_ref_to_result( + Tag>{}, + cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); +#else +return cat::template from_ref_to_result( + Tag>{}, + cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); +#endif } template From 1dd0c2b40da31b8b3812781af33a29e8b435a7ee Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:04:14 +0100 Subject: [PATCH 095/100] discover cpp tests --- .github/workflows/ci-linux-osx-win-conda.yml | 2 +- test/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index ac7ed0e53..f111ac0d0 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -80,7 +80,7 @@ jobs: # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/186 conda config --remove channels defaults # Compilation related dependencies - mamba install cmake compilers make pkg-config doxygen ninja graphviz typing_extensions + mamba install cmake compilers make pkg-config doxygen ninja graphviz typing_extensions llvm-openmp # Main dependencies mamba install eigen simde # Test dependencies diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bc6ba4a0b..1d0960d46 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,7 +22,7 @@ endif() macro(proxsuite_test name path) set(target_name ${PROJECT_NAME}-test-cpp-${name}) add_executable(${target_name} ${path}) - # doctest_discover_tests(${target_name}) + doctest_discover_tests(${target_name}) target_link_libraries(${target_name} PUBLIC proxsuite ${PROJECT_NAME}-doctest proxsuite-test-util) target_compile_definitions(${target_name} From 7b9c3260df2b1fb9f2abc1c2670203d4156054c8 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:26:29 +0100 Subject: [PATCH 096/100] do not run julia example --- .github/workflows/ci-linux-osx-win-conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index f111ac0d0..1b74bd091 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -114,7 +114,7 @@ jobs: git submodule update --init mkdir build cd build - cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=ON -DOpenMP_ROOT=$CONDA_PREFIX + cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=OFF -DOpenMP_ROOT=$CONDA_PREFIX - name: Configure [Conda/macOS14] if: contains(matrix.os, 'macos-14') @@ -135,7 +135,7 @@ jobs: echo $(whereis ccache) echo $(which ccache) cd build - cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCHECK_RUNTIME_MALLOC:BOOL=ON -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=ON -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DOpenMP_ROOT=$CONDA_PREFIX + cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCHECK_RUNTIME_MALLOC:BOOL=ON -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=OFF -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DOpenMP_ROOT=$CONDA_PREFIX - name: Configure [Conda/Windows-2019] if: contains(matrix.os, 'windows-2019') From 124100f7885be0cb66a62331872297ec0426d296 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:05:08 +0100 Subject: [PATCH 097/100] edit changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f546a3f5..dacdbf799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed * CMake: Fix link to system cereal in tests ([#353](https://github.com/Simple-Robotics/proxsuite/pull/352)) +* Fix windows build error related to template usage in veg ([#357](https://github.com/Simple-Robotics/proxsuite/pull/357)) ### Added * Stub files for Python bindings, using [nanobind's native support](https://nanobind.readthedocs.io/en/latest/typing.html#stub-generation) ([#340](https://github.com/Simple-Robotics/proxsuite/pull/340)) From da71abf7bd8094dc158b3fd1a26b99d12c6fe969 Mon Sep 17 00:00:00 2001 From: Fabian Schramm <55981657+fabinsch@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:14:40 +0100 Subject: [PATCH 098/100] apply pre-commit --- include/proxsuite/linalg/dense/core.hpp | 121 ++++++++---------- include/proxsuite/linalg/dense/factorize.hpp | 4 +- include/proxsuite/linalg/dense/ldlt.hpp | 24 ++-- include/proxsuite/linalg/sparse/factorize.hpp | 13 +- .../linalg/veg/internal/dyn_index.hpp | 8 +- .../veg/internal/external/hedley.ext.hpp | 2 +- .../proxsuite/linalg/veg/internal/macros.hpp | 24 ++-- .../linalg/veg/memory/dynamic_stack.hpp | 4 +- .../linalg/veg/memory/stack_alloc.hpp | 16 +-- include/proxsuite/linalg/veg/slice.hpp | 8 +- include/proxsuite/linalg/veg/tuple.hpp | 34 ++--- .../linalg/veg/type_traits/constructible.hpp | 2 +- include/proxsuite/linalg/veg/util/get.hpp | 4 +- include/proxsuite/linalg/veg/vec.hpp | 6 +- include/proxsuite/proxqp/dense/views.hpp | 31 ++--- include/proxsuite/proxqp/sparse/utils.hpp | 43 ++++--- .../proxqp/utils/random_qp_problems.hpp | 25 ++-- test/CMakeLists.txt | 3 +- test/doctest/doctest.hpp | 3 +- 19 files changed, 176 insertions(+), 199 deletions(-) diff --git a/include/proxsuite/linalg/dense/core.hpp b/include/proxsuite/linalg/dense/core.hpp index a5f1dffc2..5c43d5005 100644 --- a/include/proxsuite/linalg/dense/core.hpp +++ b/include/proxsuite/linalg/dense/core.hpp @@ -117,8 +117,8 @@ static_assert(sizeof(f64) == 8, "f64 should be 64 bits"); LDLT_FN_IMPL3(fnmadd, Prefix, Suffix); /* (-a * b + c) */ #define LDLT_LOAD_STORE(Prefix, Suffix) \ - VEG_INLINE static auto load_unaligned( \ - ScalarType const* ptr) noexcept -> Pack \ + VEG_INLINE static auto load_unaligned(ScalarType const* ptr) noexcept \ + -> Pack \ { \ return Pack{ simde_mm##Prefix##_loadu_##Suffix(ptr) }; \ } \ @@ -560,9 +560,8 @@ elem_addr(T* ptr, template auto -matrix_elem_addr(Mat&& mat, - isize row, - isize col) noexcept -> decltype(mat.data()) +matrix_elem_addr(Mat&& mat, isize row, isize col) noexcept + -> decltype(mat.data()) { return util::elem_addr::IsRowMajor)>( // @@ -575,18 +574,16 @@ matrix_elem_addr(Mat&& mat, template auto -col(T&& mat, isize col_idx) noexcept -> - typename _detail::RowColAccessImpl< - !bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor)>::template Col +col(T&& mat, isize col_idx) noexcept -> typename _detail::RowColAccessImpl< + !bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor)>::template Col { return _detail::RowColAccessImpl::IsRowMajor)>::col(mat, col_idx); } template auto -row(T&& mat, isize row_idx) noexcept -> - typename _detail::RowColAccessImpl< - !bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor)>::template Row +row(T&& mat, isize row_idx) noexcept -> typename _detail::RowColAccessImpl< + !bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor)>::template Row { return _detail::RowColAccessImpl::IsRowMajor)>::row(mat, row_idx); @@ -594,19 +591,17 @@ row(T&& mat, isize row_idx) noexcept -> template auto -trans(Mat&& mat) noexcept - -> Eigen::Map< // - _detail::const_if< - _detail::ptr_is_const::value, - Eigen::Matrix< // - typename proxsuite::linalg::veg::uncvref_t::Scalar, - proxsuite::linalg::veg::uncvref_t::ColsAtCompileTime, - proxsuite::linalg::veg::uncvref_t::RowsAtCompileTime, - bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor) - ? Eigen::ColMajor - : Eigen::RowMajor>>, - Eigen::Unaligned, - _detail::StrideOf>> +trans(Mat&& mat) noexcept -> Eigen::Map< // + _detail::const_if<_detail::ptr_is_const::value, + Eigen::Matrix< // + typename proxsuite::linalg::veg::uncvref_t::Scalar, + proxsuite::linalg::veg::uncvref_t::ColsAtCompileTime, + proxsuite::linalg::veg::uncvref_t::RowsAtCompileTime, + bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor) + ? Eigen::ColMajor + : Eigen::RowMajor>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { mat.data(), @@ -621,16 +616,15 @@ trans(Mat&& mat) noexcept template auto -diagonal(Mat&& mat) noexcept - -> Eigen::Map< // - _detail::const_if<_detail::ptr_is_const::value, - Eigen::Matrix< // - typename proxsuite::linalg::veg::uncvref_t::Scalar, - Eigen::Dynamic, - 1, - Eigen::ColMajor>>, - Eigen::Unaligned, - Eigen::InnerStride> +diagonal(Mat&& mat) noexcept -> Eigen::Map< // + _detail::const_if<_detail::ptr_is_const::value, + Eigen::Matrix< // + typename proxsuite::linalg::veg::uncvref_t::Scalar, + Eigen::Dynamic, + 1, + Eigen::ColMajor>>, + Eigen::Unaligned, + Eigen::InnerStride> { VEG_DEBUG_ASSERT( // mat.rows() == mat.cols()); @@ -667,12 +661,11 @@ submatrix(Mat&& mat, template auto -to_view(Mat&& mat) noexcept - -> Eigen::Map<_detail::const_if< - _detail::ptr_is_const::value, - _detail::OwnedAll>>, - Eigen::Unaligned, - _detail::StrideOf>> +to_view(Mat&& mat) noexcept -> Eigen::Map< + _detail::const_if<_detail::ptr_is_const::value, + _detail::OwnedAll>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { mat.data(), @@ -687,12 +680,11 @@ to_view(Mat&& mat) noexcept template auto -to_view_dyn_rows(Mat&& mat) noexcept - -> Eigen::Map<_detail::const_if< - _detail::ptr_is_const::value, - _detail::OwnedRows>>, - Eigen::Unaligned, - _detail::StrideOf>> +to_view_dyn_rows(Mat&& mat) noexcept -> Eigen::Map< + _detail::const_if<_detail::ptr_is_const::value, + _detail::OwnedRows>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { mat.data(), @@ -707,12 +699,11 @@ to_view_dyn_rows(Mat&& mat) noexcept template auto -to_view_dyn_cols(Mat&& mat) noexcept - -> Eigen::Map<_detail::const_if< - _detail::ptr_is_const::value, - _detail::OwnedCols>>, - Eigen::Unaligned, - _detail::StrideOf>> +to_view_dyn_cols(Mat&& mat) noexcept -> Eigen::Map< + _detail::const_if<_detail::ptr_is_const::value, + _detail::OwnedCols>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { mat.data(), @@ -747,12 +738,11 @@ to_view_dyn(Mat&& mat) noexcept template auto -subrows(Mat&& mat, isize row_start, isize nrows) noexcept - -> Eigen::Map<_detail::const_if< - _detail::ptr_is_const::value, - _detail::OwnedRows>>, - Eigen::Unaligned, - _detail::StrideOf>> +subrows(Mat&& mat, isize row_start, isize nrows) noexcept -> Eigen::Map< + _detail::const_if<_detail::ptr_is_const::value, + _detail::OwnedRows>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { util::elem_addr::IsRowMajor)>( @@ -768,12 +758,11 @@ subrows(Mat&& mat, isize row_start, isize nrows) noexcept template auto -subcols(Mat&& mat, isize col_start, isize ncols) noexcept - -> Eigen::Map<_detail::const_if< - _detail::ptr_is_const::value, - _detail::OwnedCols>>, - Eigen::Unaligned, - _detail::StrideOf>> +subcols(Mat&& mat, isize col_start, isize ncols) noexcept -> Eigen::Map< + _detail::const_if<_detail::ptr_is_const::value, + _detail::OwnedCols>>, + Eigen::Unaligned, + _detail::StrideOf>> { return { util::elem_addr::IsRowMajor)>( @@ -859,8 +848,8 @@ temp_mat_req(proxsuite::linalg::veg::Tag /*tag*/, template auto -temp_vec_req(proxsuite::linalg::veg::Tag /*tag*/, - isize rows) noexcept -> proxsuite::linalg::veg::dynstack::StackReq +temp_vec_req(proxsuite::linalg::veg::Tag /*tag*/, isize rows) noexcept + -> proxsuite::linalg::veg::dynstack::StackReq { return { rows * isize{ sizeof(T) }, diff --git a/include/proxsuite/linalg/dense/factorize.hpp b/include/proxsuite/linalg/dense/factorize.hpp index c11f2368b..1f3c20e3f 100644 --- a/include/proxsuite/linalg/dense/factorize.hpp +++ b/include/proxsuite/linalg/dense/factorize.hpp @@ -350,8 +350,8 @@ factorize_recursive(Mat&& mat, template auto -factorize_req(proxsuite::linalg::veg::Tag tag, - isize n) noexcept -> proxsuite::linalg::veg::dynstack::StackReq +factorize_req(proxsuite::linalg::veg::Tag tag, isize n) noexcept + -> proxsuite::linalg::veg::dynstack::StackReq { return proxsuite::linalg::dense::factorize_blocked_req(tag, n, 128) | proxsuite::linalg::dense::factorize_recursive_req(tag, n); diff --git a/include/proxsuite/linalg/dense/ldlt.hpp b/include/proxsuite/linalg/dense/ldlt.hpp index 1a64dfd23..b74bde51a 100644 --- a/include/proxsuite/linalg/dense/ldlt.hpp +++ b/include/proxsuite/linalg/dense/ldlt.hpp @@ -614,23 +614,23 @@ struct Ldlt auto dim() const noexcept -> isize { return perm.len(); } auto ld_col() const noexcept -> Eigen::Map< // - ColMat const, - Eigen::Unaligned, - Eigen::OuterStride> + ColMat const, + Eigen::Unaligned, + Eigen::OuterStride> { return { ld_storage.ptr(), dim(), dim(), stride }; } auto ld_col_mut() noexcept -> Eigen::Map< // - ColMat, - Eigen::Unaligned, - Eigen::OuterStride> + ColMat, + Eigen::Unaligned, + Eigen::OuterStride> { return { ld_storage.ptr_mut(), dim(), dim(), stride }; } auto ld_row() const noexcept -> Eigen::Map< // - RowMat const, - Eigen::Unaligned, - Eigen::OuterStride> + RowMat const, + Eigen::Unaligned, + Eigen::OuterStride> { return { ld_storage.ptr(), @@ -640,9 +640,9 @@ struct Ldlt }; } auto ld_row_mut() noexcept -> Eigen::Map< // - RowMat, - Eigen::Unaligned, - Eigen::OuterStride> + RowMat, + Eigen::Unaligned, + Eigen::OuterStride> { return { ld_storage.ptr_mut(), diff --git a/include/proxsuite/linalg/sparse/factorize.hpp b/include/proxsuite/linalg/sparse/factorize.hpp index 46451dd1c..225a82f7b 100644 --- a/include/proxsuite/linalg/sparse/factorize.hpp +++ b/include/proxsuite/linalg/sparse/factorize.hpp @@ -249,8 +249,8 @@ dense_ltsolve(DenseVecMut x, MatRef l) noexcept(false) */ template auto -etree_req(proxsuite::linalg::veg::Tag /*tag*/, - isize n) noexcept -> proxsuite::linalg::veg::dynstack::StackReq +etree_req(proxsuite::linalg::veg::Tag /*tag*/, isize n) noexcept + -> proxsuite::linalg::veg::dynstack::StackReq { return { n * isize{ sizeof(I) }, alignof(I) }; } @@ -456,8 +456,8 @@ postorder_depth_first_search( // */ template auto -postorder_req(proxsuite::linalg::veg::Tag /*tag*/, - isize n) noexcept -> proxsuite::linalg::veg::dynstack::StackReq +postorder_req(proxsuite::linalg::veg::Tag /*tag*/, isize n) noexcept + -> proxsuite::linalg::veg::dynstack::StackReq { return { (3 * n) * isize(sizeof(I)), alignof(I) }; } @@ -716,9 +716,8 @@ column_counts(I* counts, template auto -amd_req(proxsuite::linalg::veg::Tag /*tag*/, - isize /*n*/, - isize nnz) noexcept -> proxsuite::linalg::veg::dynstack::StackReq +amd_req(proxsuite::linalg::veg::Tag /*tag*/, isize /*n*/, isize nnz) noexcept + -> proxsuite::linalg::veg::dynstack::StackReq { return { nnz * isize{ sizeof(char) }, alignof(char) }; } diff --git a/include/proxsuite/linalg/veg/internal/dyn_index.hpp b/include/proxsuite/linalg/veg/internal/dyn_index.hpp index ce3c4050b..5b208293b 100644 --- a/include/proxsuite/linalg/veg/internal/dyn_index.hpp +++ b/include/proxsuite/linalg/veg/internal/dyn_index.hpp @@ -223,8 +223,8 @@ struct binary_traits, Dyn> : binary_traits { using Mul = Fix<0>; VEG_NODISCARD - constexpr VEG_INLINE static auto mul_fn(Fix<0> /*a*/, - Dyn /*b*/) VEG_NOEXCEPT -> Mul + constexpr VEG_INLINE static auto mul_fn(Fix<0> /*a*/, Dyn /*b*/) VEG_NOEXCEPT + -> Mul { return {}; } @@ -234,8 +234,8 @@ template struct binary_traits> : binary_traits { using Mul = typename binary_traits, Dyn>::Mul; - VEG_INLINE static constexpr auto mul_fn(Dyn a, - Fix /*b*/) VEG_NOEXCEPT -> Mul + VEG_INLINE static constexpr auto mul_fn(Dyn a, Fix /*b*/) VEG_NOEXCEPT + -> Mul { return binary_traits, Dyn>::mul_fn({}, a); } diff --git a/include/proxsuite/linalg/veg/internal/external/hedley.ext.hpp b/include/proxsuite/linalg/veg/internal/external/hedley.ext.hpp index 91a3edf63..af3872e25 100644 --- a/include/proxsuite/linalg/veg/internal/external/hedley.ext.hpp +++ b/include/proxsuite/linalg/veg/internal/external/hedley.ext.hpp @@ -1838,7 +1838,7 @@ HEDLEY_DIAGNOSTIC_POP #else #include #define HEDLEY_IS_CONSTEXPR_(expr) \ - _Generic((1 ? (void*)((intptr_t) * 0) : (int*)0), int*: 1, void*: 0) + _Generic((1 ? (void*)((intptr_t)*0) : (int*)0), int*: 1, void*: 0) #endif #elif defined(HEDLEY_GCC_VERSION) || defined(HEDLEY_INTEL_VERSION) || \ defined(HEDLEY_TINYC_VERSION) || defined(HEDLEY_TI_ARMCL_VERSION) || \ diff --git a/include/proxsuite/linalg/veg/internal/macros.hpp b/include/proxsuite/linalg/veg/internal/macros.hpp index eed6354a3..5f277f443 100644 --- a/include/proxsuite/linalg/veg/internal/macros.hpp +++ b/include/proxsuite/linalg/veg/internal/macros.hpp @@ -324,11 +324,11 @@ Name, \ (__VA_ARGS__), \ ::proxsuite::linalg::veg::meta::bool_constant<__VA_ARGS__>); \ - VEG_TEMPLATE( \ - Tpl, \ - requires(__VA_ARGS__), \ - constexpr auto check_##Name, \ - (_ = 0, int)) noexcept -> ::proxsuite::linalg::veg::meta::true_type + VEG_TEMPLATE(Tpl, \ + requires(__VA_ARGS__), \ + constexpr auto check_##Name, \ + (_ = 0, int)) noexcept \ + -> ::proxsuite::linalg::veg::meta::true_type #define __VEG_IMPL_SFINAE(_, Param) \ , ::proxsuite::linalg::veg::meta:: \ @@ -1195,20 +1195,18 @@ struct ExtractCharsImplExpr> template auto -extract_chars(LiteralType /*unused*/) -> - typename ExtractCharsImpl< - LiteralType, - _meta::make_index_sequence>::Type +extract_chars(LiteralType /*unused*/) -> typename ExtractCharsImpl< + LiteralType, + _meta::make_index_sequence>::Type { return {}; } template auto -extract_chars_expr(LiteralType /*unused*/) -> - typename ExtractCharsImplExpr< - LiteralType, - _meta::make_index_sequence>::Type +extract_chars_expr(LiteralType /*unused*/) -> typename ExtractCharsImplExpr< + LiteralType, + _meta::make_index_sequence>::Type { return {}; } diff --git a/include/proxsuite/linalg/veg/memory/dynamic_stack.hpp b/include/proxsuite/linalg/veg/memory/dynamic_stack.hpp index b6110d1ed..528d6e900 100644 --- a/include/proxsuite/linalg/veg/memory/dynamic_stack.hpp +++ b/include/proxsuite/linalg/veg/memory/dynamic_stack.hpp @@ -279,8 +279,8 @@ struct DynStackMut template VEG_NODISCARD auto make_alloc(Tag /*unused*/, isize len, - isize align = alignof(T)) - VEG_NOEXCEPT -> DynStackAlloc + isize align = alignof(T)) VEG_NOEXCEPT + -> DynStackAlloc { assert_valid_len(len); DynStackAlloc get{ diff --git a/include/proxsuite/linalg/veg/memory/stack_alloc.hpp b/include/proxsuite/linalg/veg/memory/stack_alloc.hpp index a0affffb9..becb39cb6 100644 --- a/include/proxsuite/linalg/veg/memory/stack_alloc.hpp +++ b/include/proxsuite/linalg/veg/memory/stack_alloc.hpp @@ -76,8 +76,8 @@ struct BumpAllocLayout return blk; } - auto _grow_last_unchecked(void* ptr, - usize new_byte_size) noexcept -> mem::AllocBlock + auto _grow_last_unchecked(void* ptr, usize new_byte_size) noexcept + -> mem::AllocBlock { auto rem_bytes = usize(end_ptr - static_cast(ptr)); auto given_bytes = _align(new_byte_size); @@ -157,8 +157,8 @@ struct Alloc> using ImplMut = _detail::_mem::BumpAllocLayout&; using RefMut = proxsuite::linalg::veg::RefMut>; - VEG_INLINE static auto alloc(RefMut ref, - mem::Layout layout) noexcept -> AllocBlock + VEG_INLINE static auto alloc(RefMut ref, mem::Layout layout) noexcept + -> AllocBlock { return ImplMut(ref.get())._alloc(layout); } @@ -184,8 +184,8 @@ struct Alloc> using ImplMut = _detail::_mem::BumpAllocLayout&; using RefMut = proxsuite::linalg::veg::RefMut>; - VEG_INLINE static auto alloc(RefMut ref, - mem::Layout layout) noexcept -> AllocBlock + VEG_INLINE static auto alloc(RefMut ref, mem::Layout layout) noexcept + -> AllocBlock { return ImplMut(ref.get())._alloc(layout); } @@ -211,8 +211,8 @@ struct Alloc> using ImplMut = _detail::_mem::BumpAllocLayout&; using RefMut = proxsuite::linalg::veg::RefMut>; - VEG_INLINE static auto alloc(RefMut ref, - mem::Layout layout) noexcept -> AllocBlock + VEG_INLINE static auto alloc(RefMut ref, mem::Layout layout) noexcept + -> AllocBlock { return ImplMut(ref.get())._alloc(layout); } diff --git a/include/proxsuite/linalg/veg/slice.hpp b/include/proxsuite/linalg/veg/slice.hpp index 965875619..8abb3f0ee 100644 --- a/include/proxsuite/linalg/veg/slice.hpp +++ b/include/proxsuite/linalg/veg/slice.hpp @@ -60,8 +60,8 @@ struct Slice : _detail::_slice::adl::AdlBase } VEG_NODISCARD VEG_INLINE - constexpr auto get_unchecked(Unsafe /*tag*/, - isize idx) const VEG_NOEXCEPT -> Ref + constexpr auto get_unchecked(Unsafe /*tag*/, isize idx) const VEG_NOEXCEPT + -> Ref { return ref(*(data + idx)); } @@ -149,8 +149,8 @@ struct SliceMut : private Slice { return mut(const_cast(*(this->data + idx))); } - VEG_NODISCARD VEG_INLINE auto as_mut_bytes() - VEG_NOEXCEPT -> SliceMut + VEG_NODISCARD VEG_INLINE auto as_mut_bytes() VEG_NOEXCEPT + -> SliceMut { return { unsafe, diff --git a/include/proxsuite/linalg/veg/tuple.hpp b/include/proxsuite/linalg/veg/tuple.hpp index 36fea520d..d0104bd47 100644 --- a/include/proxsuite/linalg/veg/tuple.hpp +++ b/include/proxsuite/linalg/veg/tuple.hpp @@ -401,7 +401,7 @@ struct IndexedTuple, Ts...> (/*arg*/, Fix)) && VEG_NOEXCEPT_IF( VEG_CONCEPT(nothrow_movable(I), Ts...>>)) - -> ith(I), Ts...> + -> ith(I), Ts...> { return __VEG_IMPL_LEAF_ONCE( *this, static_cast(I), ith(I), Ts...>); @@ -535,8 +535,8 @@ get(tuple::IndexedTuple, template VEG_NODISCARD VEG_INLINE constexpr auto get(tuple::IndexedTuple, - Ts...> const&& tup) - VEG_NOEXCEPT -> ith const&& + Ts...> const&& tup) VEG_NOEXCEPT + -> ith const&& { return static_cast const&&>( __VEG_IMPL_LEAF(tup, I, ith)); @@ -659,9 +659,9 @@ struct zip VEG_INLINE static constexpr auto apply( IndexedTuple, Ts...> first, - Tuples... rest) VEG_NOEXCEPT -> Tuple< // - typename Helper:: // - template Type...> + Tuples... rest) VEG_NOEXCEPT -> Tuple< // + typename Helper:: // + template Type...> { return { ((void)first, tuplify{}), @@ -755,13 +755,13 @@ struct cat Tuples&&... tups) VEG_NOEXCEPT -> Concat { #ifdef _MSC_VER -return cat::from_ref_to_result( - Tag>{}, - cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); + return cat::from_ref_to_result( + Tag>{}, + cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); #else -return cat::template from_ref_to_result( - Tag>{}, - cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); + return cat::template from_ref_to_result( + Tag>{}, + cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); #endif } @@ -783,11 +783,11 @@ return cat::template from_ref_to_result( VEG_INLINE static constexpr auto apply( IndexedTuple, Ts...>&& first, - Tuples&&... rest) - VEG_NOEXCEPT -> proxsuite::linalg::veg::meta::type_sequence_cat< - Tuple, - Tuple, - typename _detail::meta_::IndexedToTuple::Type...> + Tuples&&... rest) VEG_NOEXCEPT + -> proxsuite::linalg::veg::meta::type_sequence_cat< + Tuple, + Tuple, + typename _detail::meta_::IndexedToTuple::Type...> { return cat::apply2(VEG_FWD(first), cat::apply(VEG_FWD(rest)...)); } diff --git a/include/proxsuite/linalg/veg/type_traits/constructible.hpp b/include/proxsuite/linalg/veg/type_traits/constructible.hpp index ce1ed6396..1872b3e59 100644 --- a/include/proxsuite/linalg/veg/type_traits/constructible.hpp +++ b/include/proxsuite/linalg/veg/type_traits/constructible.hpp @@ -189,7 +189,7 @@ struct WithArg Fn&& fn; T&& arg; VEG_INLINE constexpr auto operator()() const&& -> decltype(VEG_FWD(fn)( - VEG_FWD(arg))) + VEG_FWD(arg))) { return VEG_FWD(fn)(VEG_FWD(arg)); } diff --git a/include/proxsuite/linalg/veg/util/get.hpp b/include/proxsuite/linalg/veg/util/get.hpp index df0f3789e..453e63c9a 100644 --- a/include/proxsuite/linalg/veg/util/get.hpp +++ b/include/proxsuite/linalg/veg/util/get.hpp @@ -36,8 +36,8 @@ struct array_get using result_type = decltype(VEG_DECLVAL(T&&)[I::value]); template - VEG_INLINE static constexpr auto apply(T&& arr) - VEG_NOEXCEPT -> decltype(VEG_FWD(arr)[I]) + VEG_INLINE static constexpr auto apply(T&& arr) VEG_NOEXCEPT + -> decltype(VEG_FWD(arr)[I]) { return VEG_FWD(arr)[I]; } diff --git a/include/proxsuite/linalg/veg/vec.hpp b/include/proxsuite/linalg/veg/vec.hpp index eb409c3e6..f6166208d 100644 --- a/include/proxsuite/linalg/veg/vec.hpp +++ b/include/proxsuite/linalg/veg/vec.hpp @@ -277,9 +277,9 @@ realloc_and_append( // mem::AllocBlock out, usize out_len, T const* in, - usize in_len) - VEG_NOEXCEPT_IF(VEG_CONCEPT(alloc::nothrow_grow) && - VEG_CONCEPT(alloc::nothrow_clone)) -> mem::AllocBlock + usize in_len) VEG_NOEXCEPT_IF(VEG_CONCEPT(alloc::nothrow_grow) && + VEG_CONCEPT(alloc::nothrow_clone)) + -> mem::AllocBlock { if (in_len == 0) { diff --git a/include/proxsuite/proxqp/dense/views.hpp b/include/proxsuite/proxqp/dense/views.hpp index c8cc22c6e..c43c8cae9 100644 --- a/include/proxsuite/proxqp/dense/views.hpp +++ b/include/proxsuite/proxqp/dense/views.hpp @@ -395,8 +395,7 @@ using DataExpr = decltype(static_cast(VEG_DECLVAL(Mat&).data())); template - class F, + template class F, typename... Ts> struct DetectedImpl : proxsuite::linalg::veg::meta::false_type { @@ -717,8 +716,8 @@ struct StridedVectorView { return *ptr(index); } - VEG_INLINE auto segment(isize i, - isize size) const noexcept -> StridedVectorView + VEG_INLINE auto segment(isize i, isize size) const noexcept + -> StridedVectorView { return { from_ptr_size_stride, @@ -784,8 +783,8 @@ struct StridedVectorViewMut { return *ptr(index); } - VEG_INLINE auto segment(isize i, - isize size) const noexcept -> StridedVectorViewMut + VEG_INLINE auto segment(isize i, isize size) const noexcept + -> StridedVectorViewMut { return { from_ptr_size_stride, @@ -884,15 +883,13 @@ struct MatrixView } public: - VEG_INLINE auto col(isize c) const noexcept - -> proxsuite::linalg::veg::meta:: - if_t<(L == colmajor), VectorView, StridedVectorView> + VEG_INLINE auto col(isize c) const noexcept -> proxsuite::linalg::veg::meta:: + if_t<(L == colmajor), VectorView, StridedVectorView> { return col_impl(proxsuite::linalg::veg::meta::constant{}, c); } - VEG_INLINE auto row(isize r) const noexcept - -> proxsuite::linalg::veg::meta:: - if_t<(L == rowmajor), VectorView, StridedVectorView> + VEG_INLINE auto row(isize r) const noexcept -> proxsuite::linalg::veg::meta:: + if_t<(L == rowmajor), VectorView, StridedVectorView> { return trans().col(r); } @@ -992,15 +989,13 @@ struct MatrixViewMut } public: - VEG_INLINE auto col(isize c) const noexcept - -> proxsuite::linalg::veg::meta:: - if_t<(L == colmajor), VectorViewMut, StridedVectorViewMut> + VEG_INLINE auto col(isize c) const noexcept -> proxsuite::linalg::veg::meta:: + if_t<(L == colmajor), VectorViewMut, StridedVectorViewMut> { return col_impl(proxsuite::linalg::veg::meta::constant{}, c); } - VEG_INLINE auto row(isize r) const noexcept - -> proxsuite::linalg::veg::meta:: - if_t<(L == rowmajor), VectorViewMut, StridedVectorViewMut> + VEG_INLINE auto row(isize r) const noexcept -> proxsuite::linalg::veg::meta:: + if_t<(L == rowmajor), VectorViewMut, StridedVectorViewMut> { return trans().col(r); } diff --git a/include/proxsuite/proxqp/sparse/utils.hpp b/include/proxsuite/proxqp/sparse/utils.hpp index 62e55413b..fe1e4b275 100644 --- a/include/proxsuite/proxqp/sparse/utils.hpp +++ b/include/proxsuite/proxqp/sparse/utils.hpp @@ -613,27 +613,28 @@ global_dual_residual_infeasibility(VectorViewMut Adx, */ template auto -unscaled_primal_dual_residual(Workspace& work, - Results& results, - const Settings& settings, - VecMapMut primal_residual_eq_scaled, - VecMapMut primal_residual_in_scaled_lo, - VecMapMut primal_residual_in_scaled_up, - VecMapMut dual_residual_scaled, - T& primal_feasibility_eq_rhs_0, - T& primal_feasibility_in_rhs_0, - T& dual_feasibility_rhs_0, - T& dual_feasibility_rhs_1, - T& dual_feasibility_rhs_3, - T& rhs_duality_gap, - const P& precond, - Model const& data, - const QpView qp_scaled, - VecMapMut x_e, - VecMapMut y_e, - VecMapMut z_e, - proxsuite::linalg::veg::dynstack::DynStackMut - stack) -> proxsuite::linalg::veg::Tuple +unscaled_primal_dual_residual( + Workspace& work, + Results& results, + const Settings& settings, + VecMapMut primal_residual_eq_scaled, + VecMapMut primal_residual_in_scaled_lo, + VecMapMut primal_residual_in_scaled_up, + VecMapMut dual_residual_scaled, + T& primal_feasibility_eq_rhs_0, + T& primal_feasibility_in_rhs_0, + T& dual_feasibility_rhs_0, + T& dual_feasibility_rhs_1, + T& dual_feasibility_rhs_3, + T& rhs_duality_gap, + const P& precond, + Model const& data, + const QpView qp_scaled, + VecMapMut x_e, + VecMapMut y_e, + VecMapMut z_e, + proxsuite::linalg::veg::dynstack::DynStackMut stack) + -> proxsuite::linalg::veg::Tuple { isize n = x_e.rows(); diff --git a/include/proxsuite/proxqp/utils/random_qp_problems.hpp b/include/proxsuite/proxqp/utils/random_qp_problems.hpp index 2a13423c6..e08641d47 100644 --- a/include/proxsuite/proxqp/utils/random_qp_problems.hpp +++ b/include/proxsuite/proxqp/utils/random_qp_problems.hpp @@ -226,9 +226,8 @@ positive_definite_rand(isize n, Scalar cond) -> Mat template auto -sparse_positive_definite_rand(isize n, - Scalar cond, - Scalar p) -> SparseMat +sparse_positive_definite_rand(isize n, Scalar cond, Scalar p) + -> SparseMat { auto H = SparseMat(n, n); @@ -277,9 +276,8 @@ sparse_positive_definite_rand(isize n, template auto -sparse_positive_definite_rand_compressed(isize n, - Scalar rho, - Scalar p) -> SparseMat +sparse_positive_definite_rand_compressed(isize n, Scalar rho, Scalar p) + -> SparseMat { auto H = SparseMat(n, n); @@ -308,9 +306,8 @@ sparse_positive_definite_rand_compressed(isize n, template auto -sparse_positive_definite_rand_not_compressed(isize n, - Scalar rho, - Scalar p) -> Mat +sparse_positive_definite_rand_not_compressed(isize n, Scalar rho, Scalar p) + -> Mat { auto H = Mat(n, n); H.setZero(); @@ -355,9 +352,8 @@ sparse_matrix_rand(isize nrows, isize ncols, Scalar p) -> SparseMat template auto -sparse_matrix_rand_not_compressed(isize nrows, - isize ncols, - Scalar p) -> Mat +sparse_matrix_rand_not_compressed(isize nrows, isize ncols, Scalar p) + -> Mat { auto A = Mat(nrows, ncols); A.setZero(); @@ -416,9 +412,8 @@ template auto -matmul3(MatLhs const& a, - MatMid const& b, - MatRhs const& c) -> Mat +matmul3(MatLhs const& a, MatMid const& b, MatRhs const& c) + -> Mat { return matmul(matmul(a, b), c); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1d0960d46..f1fcd7a95 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -65,7 +65,8 @@ add_test_cflags( "-DTEST_SERIALIZATION_FOLDER=\\\\\"${CMAKE_CURRENT_BINARY_DIR}/serialization-data\\\\\"" ) if(cereal_FOUND) - target_link_libraries(${PROJECT_NAME}-test-cpp-serialization PRIVATE cereal::cereal) + target_link_libraries(${PROJECT_NAME}-test-cpp-serialization + PRIVATE cereal::cereal) else() target_include_directories( ${PROJECT_NAME}-test-cpp-serialization SYSTEM diff --git a/test/doctest/doctest.hpp b/test/doctest/doctest.hpp index 3aa1418e0..f44173193 100644 --- a/test/doctest/doctest.hpp +++ b/test/doctest/doctest.hpp @@ -1563,8 +1563,7 @@ namespace detail { #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING // clang-format on -struct DOCTEST_INTERFACE TestFailureException -{}; +struct DOCTEST_INTERFACE TestFailureException{}; DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at); From c0664d5aeb8b403a9c07b49d11f4ff649cb2c6df Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Wed, 4 Dec 2024 10:29:21 +0100 Subject: [PATCH 099/100] ci: Use conda-forge clang --- .github/workflows/ci-linux-osx-win-conda.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index 1b74bd091..8c0f163ae 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -80,7 +80,7 @@ jobs: # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/186 conda config --remove channels defaults # Compilation related dependencies - mamba install cmake compilers make pkg-config doxygen ninja graphviz typing_extensions llvm-openmp + mamba install cmake compilers make pkg-config doxygen ninja graphviz typing_extensions llvm-openmp clang # Main dependencies mamba install eigen simde # Test dependencies From 645acb1117cdf87dc263df60598755f40d0f856a Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Wed, 4 Dec 2024 10:43:14 +0100 Subject: [PATCH 100/100] ci: Use Ninja CMake generator to try to find conda-forge clang-cl --- .github/workflows/ci-linux-osx-win-conda.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml index 8c0f163ae..8ec76678e 100644 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ b/.github/workflows/ci-linux-osx-win-conda.yml @@ -146,7 +146,9 @@ jobs: git submodule update --init mkdir build cd build - cmake .. -G"Visual Studio 16 2019" -T "ClangCl" -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON + export CXX=clang-cl + export CC=clang-cl + cmake .. -G"Ninja" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON - name: Configure [Conda/Windows-latest] if: contains(matrix.os, 'windows-latest') && contains(matrix.cxx_std, '20') @@ -157,7 +159,9 @@ jobs: git submodule update --init mkdir build cd build - cmake .. -G"Visual Studio 17 2022" -T "ClangCl" -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON + export CXX=clang-cl + export CC=clang-cl + cmake .. -G"Ninja" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON - name: Configure [Conda/Windows-latest] if: contains(matrix.os, 'windows-latest') && contains(matrix.cxx_std, '17') @@ -168,7 +172,9 @@ jobs: git submodule update --init mkdir build cd build - cmake .. -G"Visual Studio 17 2022" -T "v143" -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON + export CXX=clang-cl + export CC=clang-cl + cmake .. -G"Ninja" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=${CONDA_PREFIX}/Lib/site-packages -DPYTHON_EXECUTABLE=${CONDA_PREFIX}/python.exe -DOpenMP_ROOT=$CONDA_PREFIX -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON - name: Build [Conda] shell: bash -l {0}