From 5b107a935d1e2dd3396e40b02ca84def1b0c6cfd Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Sun, 31 Mar 2024 15:23:25 -0700 Subject: [PATCH] Parallelize constraint group solving --- cmake/DARTFindDependencies.cmake | 3 + cmake/DARTFindTaskflow.cmake | 9 + dart/CMakeLists.txt | 3 +- dart/constraint/BoxedLcpConstraintSolver.cpp | 481 ++++++++++++------- dart/constraint/BoxedLcpConstraintSolver.hpp | 164 +++++-- dart/constraint/ConstraintSolver.cpp | 2 + dart/constraint/ConstraintSolver.hpp | 10 +- docker/dev/v6.14/Dockerfile.ubuntu.noble | 3 +- examples/boxes/main.cpp | 2 +- pixi.lock | 141 ++++-- pixi.toml | 12 +- tests/benchmark/integration/bm_boxes.cpp | 2 +- 12 files changed, 549 insertions(+), 283 deletions(-) create mode 100644 cmake/DARTFindTaskflow.cmake diff --git a/cmake/DARTFindDependencies.cmake b/cmake/DARTFindDependencies.cmake index 9e631d3a35aa2..1c05ff10f427a 100644 --- a/cmake/DARTFindDependencies.cmake +++ b/cmake/DARTFindDependencies.cmake @@ -106,6 +106,9 @@ else() ) endif() +# Taskflow +dart_find_package(Taskflow) + #======================= # Optional dependencies #======================= diff --git a/cmake/DARTFindTaskflow.cmake b/cmake/DARTFindTaskflow.cmake new file mode 100644 index 0000000000000..ddc3eeda29e70 --- /dev/null +++ b/cmake/DARTFindTaskflow.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2011-2024, The DART development contributors +# All rights reserved. +# +# The list of contributors can be found at: +# https://github.com/dartsim/dart/blob/main/LICENSE +# +# This file is provided under the "BSD-style" License + +find_package(Taskflow) diff --git a/dart/CMakeLists.txt b/dart/CMakeLists.txt index 6a0a14bf3484a..7a7ef33656bb2 100644 --- a/dart/CMakeLists.txt +++ b/dart/CMakeLists.txt @@ -127,6 +127,7 @@ target_link_libraries(dart Eigen3::Eigen fcl assimp + Taskflow::Taskflow ) if(TARGET fmt::fmt-header-only) target_link_libraries(dart PUBLIC fmt::fmt-header-only) @@ -213,7 +214,7 @@ endif() add_component_targets(${PROJECT_NAME} dart dart) add_component_dependencies(${PROJECT_NAME} dart external-odelcpsolver) add_component_dependency_packages(${PROJECT_NAME} dart - assimp Eigen3 fcl fmt + assimp Eigen3 fcl fmt Taskflow ) if(TARGET octomap) add_component_dependency_packages(${PROJECT_NAME} dart octomap) diff --git a/dart/constraint/BoxedLcpConstraintSolver.cpp b/dart/constraint/BoxedLcpConstraintSolver.cpp index c455b3416af62..8b28f925bf6cf 100644 --- a/dart/constraint/BoxedLcpConstraintSolver.cpp +++ b/dart/constraint/BoxedLcpConstraintSolver.cpp @@ -32,13 +32,7 @@ #include "dart/constraint/BoxedLcpConstraintSolver.hpp" -#include -#if DART_BUILD_MODE_DEBUG - #include - #include -#endif - -#include "dart/common/Console.hpp" +#include "dart/common/Logging.hpp" #include "dart/common/Profile.hpp" #include "dart/constraint/ConstraintBase.hpp" #include "dart/constraint/DantzigBoxedLcpSolver.hpp" @@ -46,10 +40,184 @@ #include "dart/external/odelcpsolver/lcp.h" #include "dart/lcpsolver/Lemke.hpp" +#include + +#if DART_BUILD_MODE_DEBUG + #include + #include +#endif +#include +#include +#include + +#include + namespace dart { namespace constraint { +namespace { + +[[nodiscard]] BoxedLcpSolverPtr createBoxedLcpSolver( + const BoxedLcpSolverType type) +{ + switch (type) { + case BoxedLcpSolverType::Dantzig: { + return std::make_shared(); + } + case BoxedLcpSolverType::Pgs: { + return std::make_shared(); + } + default: { + DART_WARN("Unknown BoxedLcpSolverType. Using Dantzig solver instead."); + return std::make_shared(); + } + } +} + +#if DART_BUILD_MODE_DEBUG +bool isSymmetric(std::size_t n, double* A) +{ + std::size_t nSkip = dPAD(n); + for (std::size_t i = 0; i < n; ++i) { + for (std::size_t j = 0; j < n; ++j) { + if (std::abs(A[nSkip * i + j] - A[nSkip * j + i]) > 1e-6) { + std::cout << "A: " << std::endl; + for (std::size_t k = 0; k < n; ++k) { + for (std::size_t l = 0; l < nSkip; ++l) { + std::cout << std::setprecision(4) << A[k * nSkip + l] << " "; + } + std::cout << std::endl; + } + + std::cout << "A(" << i << ", " << j << "): " << A[nSkip * i + j] + << std::endl; + std::cout << "A(" << j << ", " << i << "): " << A[nSkip * j + i] + << std::endl; + return false; + } + } + } + + return true; +} + +//============================================================================== +bool isSymmetric(std::size_t n, double* A, std::size_t begin, std::size_t end) +{ + std::size_t nSkip = dPAD(n); + for (std::size_t i = begin; i <= end; ++i) { + for (std::size_t j = begin; j <= end; ++j) { + if (std::abs(A[nSkip * i + j] - A[nSkip * j + i]) > 1e-6) { + std::cout << "A: " << std::endl; + for (std::size_t k = 0; k < n; ++k) { + for (std::size_t l = 0; l < nSkip; ++l) { + std::cout << std::setprecision(4) << A[k * nSkip + l] << " "; + } + std::cout << std::endl; + } + + std::cout << "A(" << i << ", " << j << "): " << A[nSkip * i + j] + << std::endl; + std::cout << "A(" << j << ", " << i << "): " << A[nSkip * j + i] + << std::endl; + return false; + } + } + } + + return true; +} + +//============================================================================== +void print( + std::size_t n, + double* A, + double* x, + double* /*lo*/, + double* /*hi*/, + double* b, + double* w, + int* findex) +{ + std::size_t nSkip = dPAD(n); + std::cout << "A: " << std::endl; + for (std::size_t i = 0; i < n; ++i) { + for (std::size_t j = 0; j < nSkip; ++j) { + std::cout << std::setprecision(4) << A[i * nSkip + j] << " "; + } + std::cout << std::endl; + } + + std::cout << "b: "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << std::setprecision(4) << b[i] << " "; + } + std::cout << std::endl; + + std::cout << "w: "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << w[i] << " "; + } + std::cout << std::endl; + + std::cout << "x: "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << x[i] << " "; + } + std::cout << std::endl; + + // std::cout << "lb: "; + // for (int i = 0; i < dim; ++i) + // { + // std::cout << lb[i] << " "; + // } + // std::cout << std::endl; + + // std::cout << "ub: "; + // for (int i = 0; i < dim; ++i) + // { + // std::cout << ub[i] << " "; + // } + // std::cout << std::endl; + + std::cout << "frictionIndex: "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << findex[i] << " "; + } + std::cout << std::endl; + + double* Ax = new double[n]; + + for (std::size_t i = 0; i < n; ++i) { + Ax[i] = 0.0; + } + + for (std::size_t i = 0; i < n; ++i) { + for (std::size_t j = 0; j < n; ++j) { + Ax[i] += A[i * nSkip + j] * x[j]; + } + } + + std::cout << "Ax : "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << Ax[i] << " "; + } + std::cout << std::endl; + + std::cout << "b + w: "; + for (std::size_t i = 0; i < n; ++i) { + std::cout << b[i] + w[i] << " "; + } + std::cout << std::endl; + + delete[] Ax; +} +#endif + +} // namespace + //============================================================================== +DART_SUPPRESS_DEPRECATED_BEGIN BoxedLcpConstraintSolver::BoxedLcpConstraintSolver( double timeStep, BoxedLcpSolverPtr boxedLcpSolver, @@ -59,15 +227,17 @@ BoxedLcpConstraintSolver::BoxedLcpConstraintSolver( { setTimeStep(timeStep); } +DART_SUPPRESS_DEPRECATED_END //============================================================================== -BoxedLcpConstraintSolver::BoxedLcpConstraintSolver() - : BoxedLcpConstraintSolver(std::make_shared()) +BoxedLcpConstraintSolver::BoxedLcpConstraintSolver(const Config& config) + : ConstraintSolver(), mConfig(config), mExecutor(4) { - // Do nothing + // Empty } //============================================================================== +DART_SUPPRESS_DEPRECATED_BEGIN BoxedLcpConstraintSolver::BoxedLcpConstraintSolver( BoxedLcpSolverPtr boxedLcpSolver) : BoxedLcpConstraintSolver( @@ -75,37 +245,70 @@ BoxedLcpConstraintSolver::BoxedLcpConstraintSolver( { // Do nothing } +DART_SUPPRESS_DEPRECATED_END //============================================================================== +DART_SUPPRESS_DEPRECATED_BEGIN BoxedLcpConstraintSolver::BoxedLcpConstraintSolver( BoxedLcpSolverPtr boxedLcpSolver, BoxedLcpSolverPtr secondaryBoxedLcpSolver) - : ConstraintSolver() + : ConstraintSolver(), mExecutor(4) { if (boxedLcpSolver) { setBoxedLcpSolver(std::move(boxedLcpSolver)); } else { - dtwarn << "[BoxedLcpConstraintSolver] Attempting to construct with nullptr " - << "LCP solver, which is not allowed. Using Dantzig solver " - << "instead.\n"; + DART_WARN( + "[BoxedLcpConstraintSolver] Attempting to construct with nullptr LCP " + "solver, which is not allowed. Using Dantzig solver instead."); setBoxedLcpSolver(std::make_shared()); } setSecondaryBoxedLcpSolver(std::move(secondaryBoxedLcpSolver)); } +DART_SUPPRESS_DEPRECATED_END + +//============================================================================== +void BoxedLcpConstraintSolver::setPrimaryBoxedLcpSolverType( + BoxedLcpSolverType type) +{ + mConfig.primaryBoxedLcpSolver = type; +} + +//============================================================================== +BoxedLcpSolverType BoxedLcpConstraintSolver::getPrimaryBoxedLcpSolverType() + const +{ + return mConfig.primaryBoxedLcpSolver; +} + +//============================================================================== +void BoxedLcpConstraintSolver::setSecondaryBoxedLcpSolverType( + BoxedLcpSolverType type) +{ + mConfig.secondaryBoxedLcpSolver = type; +} + +//============================================================================== +BoxedLcpSolverType BoxedLcpConstraintSolver::getSecondaryBoxedLcpSolverType() + const +{ + return mConfig.secondaryBoxedLcpSolver; +} //============================================================================== void BoxedLcpConstraintSolver::setBoxedLcpSolver(BoxedLcpSolverPtr lcpSolver) { if (!lcpSolver) { - dtwarn << "[BoxedLcpConstraintSolver::setBoxedLcpSolver] " - << "nullptr for boxed LCP solver is not allowed.\n"; + DART_WARN( + "[BoxedLcpConstraintSolver::setBoxedLcpSolver] nullptr for boxed LCP " + "solver is not allowed."); return; } if (lcpSolver == mSecondaryBoxedLcpSolver) { - dtwarn << "[BoxedLcpConstraintSolver::setBoxedLcpSolver] Attempting to set " - << "a primary LCP solver that is the same with the secondary LCP " - << "solver, which is discouraged. Ignoring this request.\n"; + DART_WARN( + "[BoxedLcpConstraintSolver::setBoxedLcpSolver] Attempting to set a " + "primary LCP solver that is the same with the secondary LCP solver, " + "which is discouraged. Ignoring this request."); } mBoxedLcpSolver = std::move(lcpSolver); @@ -122,10 +325,11 @@ void BoxedLcpConstraintSolver::setSecondaryBoxedLcpSolver( BoxedLcpSolverPtr lcpSolver) { if (lcpSolver == mBoxedLcpSolver) { - dtwarn << "[BoxedLcpConstraintSolver::setBoxedLcpSolver] Attempting to set " - << "the secondary LCP solver that is identical to the primary LCP " - << "solver, which is redundant. Please use different solvers or set " - << "the secondary LCP solver to nullptr.\n"; + DART_WARN( + "[BoxedLcpConstraintSolver::setSecondaryBoxedLcpSolver] Attempting " + "to set the secondary LCP solver that is identical to the primary " + "LCP solver, which is redundant. Please use different solvers or " + "set the secondary LCP solver to nullptr."); } mSecondaryBoxedLcpSolver = std::move(lcpSolver); @@ -139,54 +343,70 @@ ConstBoxedLcpSolverPtr BoxedLcpConstraintSolver::getSecondaryBoxedLcpSolver() } //============================================================================== -void BoxedLcpConstraintSolver::solveConstrainedGroup(ConstrainedGroup& group) +void solveBoxedLcp(BoxedLcp& lcp, ConstrainedGroup& group) { DART_PROFILE_SCOPED; + (void)lcp; + (void)group; // Build LCP terms by aggregating them from constraints const std::size_t numConstraints = group.getNumConstraints(); const std::size_t n = group.getTotalDimension(); // If there is no constraint, then just return. - if (0u == n) + if (0u == n) { return; + } + + auto& mA = lcp.A; + auto& mABackup = lcp.ABackup; + auto& mX = lcp.x; + auto& mXBackup = lcp.xBackup; + auto& mB = lcp.b; + auto& mBBackup = lcp.bBackup; + // auto& mW = lcp.w; + auto& mLo = lcp.lo; + auto& mLoBackup = lcp.loBackup; + auto& mHi = lcp.hi; + auto& mHiBackup = lcp.hiBackup; + auto& mFIndex = lcp.fIndex; + auto& mFIndexBackup = lcp.fIndexBackup; + auto& mOffset = lcp.offset; + auto& mBoxedLcpSolver = lcp.boxedLcpSolver; + auto& mSecondaryBoxedLcpSolver = lcp.secondaryBoxedLcpSolver; const int nSkip = dPAD(n); -#if DART_BUILD_MODE_RELEASE - mA.resize(n, nSkip); -#else // debug - mA.setZero(n, nSkip); -#endif - mX.resize(n); - mB.resize(n); - mW.setZero(n); // set w to 0 - mLo.resize(n); - mHi.resize(n); - mFIndex.setConstant(n, -1); // set findex to -1 + lcp.A.resize(n, nSkip); + lcp.x.resize(n); + lcp.b.resize(n); + lcp.w.setZero(n); + lcp.lo.resize(n); + lcp.hi.resize(n); + lcp.fIndex.setConstant(n, -1); // Compute offset indices - mOffset.resize(numConstraints); - mOffset[0] = 0; + lcp.offset.resize(numConstraints); + lcp.offset[0] = 0; for (std::size_t i = 1; i < numConstraints; ++i) { - const ConstraintBasePtr& constraint = group.getConstraint(i - 1); + const auto constraint = group.getConstraint(i - 1); assert(constraint->getDimension() > 0); - mOffset[i] = mOffset[i - 1] + constraint->getDimension(); + lcp.offset[i] = lcp.offset[i - 1] + constraint->getDimension(); } // For each constraint { DART_PROFILE_SCOPED_N("Construct LCP"); ConstraintInfo constInfo; - constInfo.invTimeStep = 1.0 / mTimeStep; + constInfo.invTimeStep = 1.0 / lcp.timeStep; for (std::size_t i = 0; i < numConstraints; ++i) { - const ConstraintBasePtr& constraint = group.getConstraint(i); + const auto constraint = group.getConstraint(i); - constInfo.x = mX.data() + mOffset[i]; - constInfo.lo = mLo.data() + mOffset[i]; - constInfo.hi = mHi.data() + mOffset[i]; - constInfo.b = mB.data() + mOffset[i]; - constInfo.findex = mFIndex.data() + mOffset[i]; - constInfo.w = mW.data() + mOffset[i]; + constInfo.x = lcp.x.data() + lcp.offset[i]; + constInfo.lo = lcp.lo.data() + lcp.offset[i]; + constInfo.hi = lcp.hi.data() + lcp.offset[i]; + constInfo.b = lcp.b.data() + lcp.offset[i]; + constInfo.findex = lcp.fIndex.data() + lcp.offset[i]; + constInfo.w = lcp.w.data() + lcp.offset[i]; // Fill vectors: lo, hi, b, w { @@ -200,8 +420,9 @@ void BoxedLcpConstraintSolver::solveConstrainedGroup(ConstrainedGroup& group) constraint->excite(); for (std::size_t j = 0; j < constraint->getDimension(); ++j) { // Adjust findex for global index - if (mFIndex[mOffset[i] + j] >= 0) - mFIndex[mOffset[i] + j] += mOffset[i]; + if (lcp.fIndex[lcp.offset[i] + j] >= 0) { + lcp.fIndex[lcp.offset[i] + j] += lcp.offset[i]; + } // Apply impulse for impulse test { @@ -212,10 +433,10 @@ void BoxedLcpConstraintSolver::solveConstrainedGroup(ConstrainedGroup& group) // Fill upper triangle blocks of A matrix { DART_PROFILE_SCOPED_N("Fill upper triangle of A"); - int index = nSkip * (mOffset[i] + j) + mOffset[i]; + int index = nSkip * (lcp.offset[i] + j) + lcp.offset[i]; constraint->getVelocityChange(mA.data() + index, true); for (std::size_t k = i + 1; k < numConstraints; ++k) { - index = nSkip * (mOffset[i] + j) + mOffset[k]; + index = nSkip * (lcp.offset[i] + j) + lcp.offset[k]; group.getConstraint(k)->getVelocityChange( mA.data() + index, false); } @@ -271,8 +492,9 @@ void BoxedLcpConstraintSolver::solveConstrainedGroup(ConstrainedGroup& group) // Sanity check. LCP solvers should not report success with nan values, but // it could happen. So we set the success to false for nan values. - if (success && mX.hasNaN()) + if (success && mX.hasNaN()) { success = false; + } if (!success && mSecondaryBoxedLcpSolver) { DART_PROFILE_SCOPED_N("Secondary LCP"); @@ -315,146 +537,41 @@ void BoxedLcpConstraintSolver::solveConstrainedGroup(ConstrainedGroup& group) } //============================================================================== -#if DART_BUILD_MODE_DEBUG -bool BoxedLcpConstraintSolver::isSymmetric(std::size_t n, double* A) +void BoxedLcpConstraintSolver::solveConstrainedGroups() { - std::size_t nSkip = dPAD(n); - for (std::size_t i = 0; i < n; ++i) { - for (std::size_t j = 0; j < n; ++j) { - if (std::abs(A[nSkip * i + j] - A[nSkip * j + i]) > 1e-6) { - std::cout << "A: " << std::endl; - for (std::size_t k = 0; k < n; ++k) { - for (std::size_t l = 0; l < nSkip; ++l) { - std::cout << std::setprecision(4) << A[k * nSkip + l] << " "; - } - std::cout << std::endl; - } - - std::cout << "A(" << i << ", " << j << "): " << A[nSkip * i + j] - << std::endl; - std::cout << "A(" << j << ", " << i << "): " << A[nSkip * j + i] - << std::endl; - return false; - } - } - } + DART_PROFILE_SCOPED; - return true; -} + const int numGroups = mConstrainedGroups.size(); -//============================================================================== -bool BoxedLcpConstraintSolver::isSymmetric( - std::size_t n, double* A, std::size_t begin, std::size_t end) -{ - std::size_t nSkip = dPAD(n); - for (std::size_t i = begin; i <= end; ++i) { - for (std::size_t j = begin; j <= end; ++j) { - if (std::abs(A[nSkip * i + j] - A[nSkip * j + i]) > 1e-6) { - std::cout << "A: " << std::endl; - for (std::size_t k = 0; k < n; ++k) { - for (std::size_t l = 0; l < nSkip; ++l) { - std::cout << std::setprecision(4) << A[k * nSkip + l] << " "; - } - std::cout << std::endl; - } - - std::cout << "A(" << i << ", " << j << "): " << A[nSkip * i + j] - << std::endl; - std::cout << "A(" << j << ", " << i << "): " << A[nSkip * j + i] - << std::endl; - return false; + // Prepare problems + { + DART_PROFILE_SCOPED_N("Prepare problems"); + mProblems.resize(numGroups); + for (auto& prob : mProblems) { + if (!prob.boxedLcpSolver) { + prob.boxedLcpSolver + = createBoxedLcpSolver(mConfig.primaryBoxedLcpSolver); } - } - } - return true; -} - -//============================================================================== -void BoxedLcpConstraintSolver::print( - std::size_t n, - double* A, - double* x, - double* /*lo*/, - double* /*hi*/, - double* b, - double* w, - int* findex) -{ - std::size_t nSkip = dPAD(n); - std::cout << "A: " << std::endl; - for (std::size_t i = 0; i < n; ++i) { - for (std::size_t j = 0; j < nSkip; ++j) { - std::cout << std::setprecision(4) << A[i * nSkip + j] << " "; - } - std::cout << std::endl; - } - - std::cout << "b: "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << std::setprecision(4) << b[i] << " "; - } - std::cout << std::endl; - - std::cout << "w: "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << w[i] << " "; - } - std::cout << std::endl; - - std::cout << "x: "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << x[i] << " "; - } - std::cout << std::endl; - - // std::cout << "lb: "; - // for (int i = 0; i < dim; ++i) - // { - // std::cout << lb[i] << " "; - // } - // std::cout << std::endl; - - // std::cout << "ub: "; - // for (int i = 0; i < dim; ++i) - // { - // std::cout << ub[i] << " "; - // } - // std::cout << std::endl; - - std::cout << "frictionIndex: "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << findex[i] << " "; - } - std::cout << std::endl; - - double* Ax = new double[n]; - - for (std::size_t i = 0; i < n; ++i) { - Ax[i] = 0.0; - } + if (!prob.secondaryBoxedLcpSolver) { + prob.secondaryBoxedLcpSolver + = createBoxedLcpSolver(mConfig.secondaryBoxedLcpSolver); + } - for (std::size_t i = 0; i < n; ++i) { - for (std::size_t j = 0; j < n; ++j) { - Ax[i] += A[i * nSkip + j] * x[j]; + prob.timeStep = mTimeStep; } } - std::cout << "Ax : "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << Ax[i] << " "; - } - std::cout << std::endl; - - std::cout << "b + w: "; - for (std::size_t i = 0; i < n; ++i) { - std::cout << b[i] + w[i] << " "; + // Solve problems + { + DART_PROFILE_SCOPED_N("Solve problems"); + tf::Taskflow mTaskflow; + mTaskflow.for_each_index(0, numGroups, 1, [&](int i) { + solveBoxedLcp(mProblems[i], mConstrainedGroups[i]); + }); + mExecutor.run(mTaskflow).wait(); } - std::cout << std::endl; - - delete[] Ax; } -#endif } // namespace constraint } // namespace dart diff --git a/dart/constraint/BoxedLcpConstraintSolver.hpp b/dart/constraint/BoxedLcpConstraintSolver.hpp index 3220c1876aaad..5fd8c8540862b 100644 --- a/dart/constraint/BoxedLcpConstraintSolver.hpp +++ b/dart/constraint/BoxedLcpConstraintSolver.hpp @@ -36,12 +36,84 @@ #include #include +#include + namespace dart { namespace constraint { +struct BoxedLcp +{ + using RowMajorMatrixXd + = Eigen::Matrix; + + /// Cache data for boxed LCP formulation + RowMajorMatrixXd A; + + /// Cache data for boxed LCP formulation + RowMajorMatrixXd ABackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd x; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd xBackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd b; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd bBackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd w; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd lo; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd loBackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd hi; + + /// Cache data for boxed LCP formulation + Eigen::VectorXd hiBackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXi fIndex; + + /// Cache data for boxed LCP formulation + Eigen::VectorXi fIndexBackup; + + /// Cache data for boxed LCP formulation + Eigen::VectorXi offset; + + /// Boxed LCP solver + BoxedLcpSolverPtr boxedLcpSolver; + + /// Boxed LCP solver to be used when the primary solver failed + BoxedLcpSolverPtr secondaryBoxedLcpSolver; + + double timeStep{-1}; +}; + +enum class BoxedLcpSolverType +{ + Dantzig, ///< The Dantzig solver + Pgs, ///< The projected Gauss-Seidel solver +}; + +struct BoxedLcpConstraintSolverConfig +{ + BoxedLcpSolverType primaryBoxedLcpSolver = BoxedLcpSolverType::Dantzig; + BoxedLcpSolverType secondaryBoxedLcpSolver = BoxedLcpSolverType::Pgs; +}; + class BoxedLcpConstraintSolver : public ConstraintSolver { public: + using Config = BoxedLcpConstraintSolverConfig; + /// Constructor /// /// \param[in] timeStep Simulation time step @@ -51,25 +123,22 @@ class BoxedLcpConstraintSolver : public ConstraintSolver /// nullptr is passed, PGS solver will be used. This is to make the default /// solver setting to be Dantzig + PGS. In order to disable use of secondary /// solver, call setSecondaryBoxedLcpSolver(nullptr) explicitly. - /// - /// \deprecated Deprecated in DART 6.8. Please use other constructors that - /// doesn't take timespte. Timestep should be set by the owner of this solver - /// such as dart::simulation::World when the solver added. - DART_DEPRECATED(6.8) - BoxedLcpConstraintSolver( - double timeStep, - BoxedLcpSolverPtr boxedLcpSolver = nullptr, - BoxedLcpSolverPtr secondaryBoxedLcpSolver = nullptr); - - /// Constructos with default primary and secondary LCP solvers, which are - /// Dantzig and PGS, respectively. - BoxedLcpConstraintSolver(); + [[deprecated( + "Since DART 6.14. Please use other constructor that takes config " + "struct instead.")]] BoxedLcpConstraintSolver(double timeStep, BoxedLcpSolverPtr boxedLcpSolver = nullptr, BoxedLcpSolverPtr secondaryBoxedLcpSolver = nullptr); + + /// Constructs with specific primary and secondary LCP solvers, which are + /// specified by the config struct. + explicit BoxedLcpConstraintSolver(const Config& config = Config()); /// Constructors with specific primary LCP solver. /// /// \param[in] boxedLcpSolver The primary boxed LCP solver. When nullptr is /// passed, which is discouraged, Dantzig solver will be used. - BoxedLcpConstraintSolver(BoxedLcpSolverPtr boxedLcpSolver); + [[deprecated( + "Since DART 6.14. Please use other constructor that takes config " + "struct instead.")]] BoxedLcpConstraintSolver(BoxedLcpSolverPtr + boxedLcpSolver); /// Constructs with specific primary and secondary LCP solvers. /// @@ -77,29 +146,54 @@ class BoxedLcpConstraintSolver : public ConstraintSolver /// passed, which is discouraged, Dantzig solver will be used. /// \param[in] secondaryBoxedLcpSolver The secondary boxed-LCP solver. Pass /// nullptr to disable using secondary LCP solver. - BoxedLcpConstraintSolver( - BoxedLcpSolverPtr boxedLcpSolver, - BoxedLcpSolverPtr secondaryBoxedLcpSolver); + [[deprecated( + "Since DART 6.14. Please use other constructor that takes config " + "struct instead.")]] BoxedLcpConstraintSolver(BoxedLcpSolverPtr boxedLcpSolver, BoxedLcpSolverPtr secondaryBoxedLcpSolver); + + /// Sets the primary boxed LCP solver type + void setPrimaryBoxedLcpSolverType(BoxedLcpSolverType type); + + /// Returns the primary boxed LCP solver type + [[nodiscard]] BoxedLcpSolverType getPrimaryBoxedLcpSolverType() const; + + /// Sets the secondary boxed LCP solver type + void setSecondaryBoxedLcpSolverType(BoxedLcpSolverType type); + + /// Returns the secondary boxed LCP solver type + [[nodiscard]] BoxedLcpSolverType getSecondaryBoxedLcpSolverType() const; /// Sets boxed LCP (BLCP) solver /// /// \param[in] lcpSolver The primary boxed LCP solver. When nullptr is /// passed, Dantzig solver will be used. - void setBoxedLcpSolver(BoxedLcpSolverPtr lcpSolver); + [[deprecated( + "Since DART 6.14. Please use setPrimaryBoxedLcpSolverType() " + "instead.")]] void + setBoxedLcpSolver(BoxedLcpSolverPtr lcpSolver); /// Returns boxed LCP (BLCP) solver - ConstBoxedLcpSolverPtr getBoxedLcpSolver() const; + [[deprecated( + "Since DART 6.14. Please use getPrimaryBoxedLcpSolverType() " + "instead.")]] ConstBoxedLcpSolverPtr + getBoxedLcpSolver() const; /// Sets boxed LCP (BLCP) solver that is used when the primary solver failed - void setSecondaryBoxedLcpSolver(BoxedLcpSolverPtr lcpSolver); + [[deprecated( + "Since DART 6.14. Please use setSecondaryBoxedLcpSolverType() " + "instead.")]] void + setSecondaryBoxedLcpSolver(BoxedLcpSolverPtr lcpSolver); /// Returns boxed LCP (BLCP) solver that is used when the primary solver /// failed - ConstBoxedLcpSolverPtr getSecondaryBoxedLcpSolver() const; + [[deprecated( + "Since DART 6.14. Please use getSecondaryBoxedLcpSolverType() " + "instead.")]] ConstBoxedLcpSolverPtr + getSecondaryBoxedLcpSolver() const; protected: - // Documentation inherited. - void solveConstrainedGroup(ConstrainedGroup& group) override; + void solveConstrainedGroups() override; + + Config mConfig; /// Boxed LCP solver BoxedLcpSolverPtr mBoxedLcpSolver; @@ -154,26 +248,10 @@ class BoxedLcpConstraintSolver : public ConstraintSolver /// Cache data for boxed LCP formulation Eigen::VectorXi mOffset; -#if DART_BUILD_MODE_DEBUG -private: - /// Return true if the matrix is symmetric - bool isSymmetric(std::size_t n, double* A); - - /// Return true if the diagonal block of matrix is symmetric - bool isSymmetric( - std::size_t n, double* A, std::size_t begin, std::size_t end); - - /// Print debug information - void print( - std::size_t n, - double* A, - double* x, - double* lo, - double* hi, - double* b, - double* w, - int* findex); -#endif + std::vector mProblems; + + tf::Executor mExecutor; + // tf::Taskflow mTaskflow; }; } // namespace constraint diff --git a/dart/constraint/ConstraintSolver.cpp b/dart/constraint/ConstraintSolver.cpp index 7f3331c535412..c36c6b123d134 100644 --- a/dart/constraint/ConstraintSolver.cpp +++ b/dart/constraint/ConstraintSolver.cpp @@ -697,7 +697,9 @@ void ConstraintSolver::solveConstrainedGroups() DART_PROFILE_SCOPED; for (auto& constraintGroup : mConstrainedGroups) { + DART_SUPPRESS_DEPRECATED_BEGIN solveConstrainedGroup(constraintGroup); + DART_SUPPRESS_DEPRECATED_END } } diff --git a/dart/constraint/ConstraintSolver.hpp b/dart/constraint/ConstraintSolver.hpp index 4935eb5ffda98..d11ab755af6fc 100644 --- a/dart/constraint/ConstraintSolver.hpp +++ b/dart/constraint/ConstraintSolver.hpp @@ -235,8 +235,12 @@ class ConstraintSolver bool removeContactSurfaceHandler(const ContactSurfaceHandlerPtr& handler); protected: - // TODO(JS): Docstring - virtual void solveConstrainedGroup(ConstrainedGroup& group) = 0; + [[deprecated( + "Since DART 6.14. Use solveConstrainedGroups() instead.")]] virtual void + solveConstrainedGroup(ConstrainedGroup& group) + { + (void)group; + } /// Checks if the skeleton is contained in this solver /// @@ -263,7 +267,7 @@ class ConstraintSolver void buildConstrainedGroups(); /// Solve constrained groups - void solveConstrainedGroups(); + virtual void solveConstrainedGroups(); /// Return true if at least one of colliding body is soft body bool isSoftContact(const collision::Contact& contact) const; diff --git a/docker/dev/v6.14/Dockerfile.ubuntu.noble b/docker/dev/v6.14/Dockerfile.ubuntu.noble index 8882bfd8b3886..16b836134a958 100644 --- a/docker/dev/v6.14/Dockerfile.ubuntu.noble +++ b/docker/dev/v6.14/Dockerfile.ubuntu.noble @@ -33,7 +33,8 @@ RUN apt-get install -y --no-install-recommends \ libassimp-dev \ libeigen3-dev \ libfcl-dev \ - libfmt-dev + libfmt-dev \ + libtaskflow-cpp-dev # ============================================================================== # DART optional dependencies diff --git a/examples/boxes/main.cpp b/examples/boxes/main.cpp index 13c8b6bb02931..641dca38a5c97 100644 --- a/examples/boxes/main.cpp +++ b/examples/boxes/main.cpp @@ -88,7 +88,7 @@ int main() for (auto k = 0; k < dim; ++k) { auto x = i - dim / 2; auto y = j - dim / 2; - auto z = k + 5; + auto z = k + 1; auto position = Eigen::Vector3d(x, y, z); auto size = Eigen::Vector3d(0.9, 0.9, 0.9); auto color = Eigen::Vector3d( diff --git a/pixi.lock b/pixi.lock index a3eddd1bb0fa2..f985059381e1a 100644 --- a/pixi.lock +++ b/pixi.lock @@ -74,14 +74,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_13.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.10.3-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_13.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_13.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-hf974151_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_13.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.49-h4f305b6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.10.0-default_h5622ce7_1001.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda @@ -102,7 +102,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libspral-2024.05.08-h1b93dcb_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_13.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-255-h3516f8a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtasn1-4.19.0-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda @@ -155,6 +155,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.12.0-hd2e6256_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-1.4.1-hcb278e6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/taskflow-3.7.0-h297d8ca_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.12.0-h297d8ca_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tinyxml2-10.0.0-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda @@ -317,6 +318,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/spdlog-1.12.0-h8dd852c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/svt-av1-1.4.1-hf0c8a7f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/taskflow-3.7.0-h3c5361c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.12.0-h3c5361c_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tinyxml2-10.0.0-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda @@ -578,6 +580,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.12.0-h64d2f7d_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-1.4.1-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/taskflow-3.7.0-h7f575de_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tinyxml2-10.0.0-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda @@ -3981,21 +3984,20 @@ packages: - kind: conda name: libgcc-ng version: 13.2.0 - build: h77fa898_11 - build_number: 11 + build: h77fa898_13 + build_number: 13 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda - sha256: bbdd49b5a191105cf4bf82a59d611afa1e8568efa556dd988e4e5d0efc3058b1 - md5: 0b3b218a596bb4c3854cc9ee799f94e5 + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_13.conda + sha256: ffa0f472c8b37f864de855af2d3c057f1813162319f10ebd97332d73fc27ba60 + md5: 9358cdd61ef0d600d2a0dde2d53b006c depends: - _libgcc_mutex 0.1 conda_forge - _openmp_mutex >=4.5 constrains: - - libgomp 13.2.0 h77fa898_11 + - libgomp 13.2.0 h77fa898_13 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 796010 - timestamp: 1718867009281 + size: 792721 + timestamp: 1719179941452 - kind: conda name: libgcrypt version: 1.10.3 @@ -4141,18 +4143,17 @@ packages: - kind: conda name: libgfortran-ng version: 13.2.0 - build: h69a702a_11 - build_number: 11 + build: h69a702a_13 + build_number: 13 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda - sha256: f91aa928161201f189057c90db1508def36bef6329ebb29a71d8064b180250dd - md5: 4c3e460d6acf8e43e4ce8bf405187eb7 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_13.conda + sha256: 3ef5d92510e9cdd70ec2a9f1f83b8c1d327ff0f9bfc17831a8f8f06f10c2085c + md5: 516e66b26eea14e7e322fe99e88e0f02 depends: - - libgfortran5 13.2.0 h3d2ce59_11 + - libgfortran5 13.2.0 h3d2ce59_13 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 48638 - timestamp: 1718867040994 + size: 48419 + timestamp: 1719179972468 - kind: conda name: libgfortran5 version: 13.2.0 @@ -4173,20 +4174,19 @@ packages: - kind: conda name: libgfortran5 version: 13.2.0 - build: h3d2ce59_11 - build_number: 11 + build: h3d2ce59_13 + build_number: 13 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_11.conda - sha256: de8535b5fb39a78f4b7473b88c400c922ae063f29500c097743b480fd0a4f326 - md5: c485da4fdb454539f852a90ae06e9bb7 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_13.conda + sha256: 19cffb68b19ff5f426d1cb3db670dccb73c09f54b8d3f8e304665e2cee68f14f + md5: 1e380198685bc1e993bbbc4b579f5916 depends: - libgcc-ng >=13.2.0 constrains: - libgfortran-ng 13.2.0 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 1467184 - timestamp: 1718867019794 + size: 1459384 + timestamp: 1719179951703 - kind: conda name: libgfortran5 version: 13.2.0 @@ -4269,18 +4269,17 @@ packages: - kind: conda name: libgomp version: 13.2.0 - build: h77fa898_11 - build_number: 11 + build: h77fa898_13 + build_number: 13 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda - sha256: f4112111fa350bcd8d6d354cdde3426751a579add88fa523f6483c714821e681 - md5: 8c462ced2af33648195dc9459f331f31 + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_13.conda + sha256: c5949bec7eee93cdd5c367e6e5c5e92ee1c5139a827567af23853dd52721d8ed + md5: d370d1855cca14dff6a819c90c77497c depends: - _libgcc_mutex 0.1 conda_forge license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 444606 - timestamp: 1718866940233 + size: 444091 + timestamp: 1719179831697 - kind: conda name: libgpg-error version: '1.49' @@ -5261,18 +5260,17 @@ packages: - kind: conda name: libstdcxx-ng version: 13.2.0 - build: hc0a3c3a_11 - build_number: 11 + build: hc0a3c3a_13 + build_number: 13 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda - sha256: e03f0f2712f45a85234016bcc5afa76023e31e00a2e74d8819a1b3bdf091fdb0 - md5: eaa8ea74083fb4a78ae19e431e556003 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_13.conda + sha256: 143171c6084e526122cc2976fbbfadf7b9f50e5d13036adf20feb7ed9d036dd2 + md5: 1053882642ed5bbc799e1e866ff86826 depends: - - libgcc-ng 13.2.0 h77fa898_11 + - libgcc-ng 13.2.0 h77fa898_13 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 3874046 - timestamp: 1718867032452 + size: 3836375 + timestamp: 1719179964037 - kind: conda name: libsystemd0 version: '255' @@ -5898,6 +5896,7 @@ packages: constrains: - openmp 18.1.8|18.1.8.* license: Apache-2.0 WITH LLVM-exception + license_family: APACHE size: 276438 timestamp: 1718911793488 - kind: conda @@ -7736,6 +7735,52 @@ packages: license_family: BSD size: 2413709 timestamp: 1670989070228 +- kind: conda + name: taskflow + version: 3.7.0 + build: h297d8ca_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/taskflow-3.7.0-h297d8ca_0.conda + sha256: 962e7636085fab4d7a79f09036881a7105cfb17a2c0e2105a370169c438a57d4 + md5: a0cacff3af3b38b61d7cf01a7f5a1339 + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: MIT + license_family: MIT + size: 143383 + timestamp: 1715068154996 +- kind: conda + name: taskflow + version: 3.7.0 + build: h3c5361c_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/taskflow-3.7.0-h3c5361c_0.conda + sha256: 833d91fe5f98844b2ddd411660b53ac1d6957a52baf26b1736159c0612a48bfc + md5: 3e80f5232372178ea8bc753ad0021309 + depends: + - __osx >=10.13 + - libcxx >=16 + license: MIT + license_family: MIT + size: 143776 + timestamp: 1715068524511 +- kind: conda + name: taskflow + version: 3.7.0 + build: h7f575de_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/taskflow-3.7.0-h7f575de_0.conda + sha256: c35492db9775ecff5f502b4c79f8cf0980f2aab4b5b2cd319ffb3b834c2ce601 + md5: 8b089a4a7c16be4786ae3bb8ba9c768a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 143555 + timestamp: 1715068441731 - kind: conda name: tbb version: 2021.12.0 diff --git a/pixi.toml b/pixi.toml index ee7cdc62519bd..24bb517bae025 100644 --- a/pixi.toml +++ b/pixi.toml @@ -74,13 +74,16 @@ test-all = { cmd = "cmake --build build -j --target ALL", depends_on = [ "configure", ] } -example-hello-world = { cmd = "cmake --build build --target hello_world --parallel && ./build/bin/hello_world", depends_on = [ +ex-hello-world = { cmd = "cmake --build build --target hello_world --parallel && ./build/bin/hello_world", depends_on = [ "configure", ] } -example-atlas-puppet = { cmd = "cmake --build build --target atlas_puppet --parallel && ./build/bin/atlas_puppet", depends_on = [ +ex-atlas-puppet = { cmd = "cmake --build build --target atlas_puppet --parallel && ./build/bin/atlas_puppet", depends_on = [ "configure", ] } -example-atlas-simbicon = { cmd = "cmake --build build --target atlas_simbicon --parallel && ./build/bin/atlas_simbicon", depends_on = [ +ex-atlas-simbicon = { cmd = "cmake --build build --target atlas_simbicon --parallel && ./build/bin/atlas_simbicon", depends_on = [ + "configure", +] } +ex-boxes = { cmd = "cmake --build build --target boxes --parallel && ./build/bin/boxes", depends_on = [ "configure", ] } @@ -107,6 +110,7 @@ clang-format-14 = ">=14.0.6,<14.1" [target.linux-64.dependencies] freeglut = ">=3.2.2,<3.3" imgui = ">=1.90.4,<1.91" +taskflow = ">=3.7.0,<3.8" [target.linux-64.tasks] tracy = { cmd = "docker run --rm -d -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw --net=host tracy-profiler" } @@ -120,6 +124,7 @@ clang-format-14 = ">=14.0.6,<14.1" [target.osx-64.dependencies] imgui = ">=1.90.4,<1.91" +taskflow = ">=3.7.0,<3.8" [target.osx-64.tasks] @@ -141,6 +146,7 @@ imgui = ">=1.90.4,<1.91" [target.win-64.dependencies] freeglut = ">=3.2.2,<3.3" +taskflow = ">=3.7.0,<3.8" [target.win-64.tasks] configure = { cmd = "cmake -S . -B build -G 'Visual Studio 17 2022' -DDART_VERBOSE=ON -DDART_MSVC_DEFAULT_OPTIONS=ON -DBUILD_SHARED_LIBS=OFF -DDART_USE_SYSTEM_IMGUI=OFF" } diff --git a/tests/benchmark/integration/bm_boxes.cpp b/tests/benchmark/integration/bm_boxes.cpp index ca61f00147636..17cfde427add0 100644 --- a/tests/benchmark/integration/bm_boxes.cpp +++ b/tests/benchmark/integration/bm_boxes.cpp @@ -135,4 +135,4 @@ static void BM_RunBoxes(benchmark::State& state) } } -BENCHMARK(BM_RunBoxes)->Arg(2)->Arg(5)->Unit(benchmark::kMillisecond); +BENCHMARK(BM_RunBoxes)->Arg(2)->Arg(4)->Arg(8)->Unit(benchmark::kMillisecond);