Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallelize the generic method for checking boundedness of a convex set. #22084

Merged
merged 17 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bindings/pydrake/geometry/geometry_py_optimization.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ void DefineConvexSetBaseClassAndSubclasses(py::module m) {
cls_doc.ambient_dimension.doc)
.def("IntersectsWith", &ConvexSet::IntersectsWith, py::arg("other"),
cls_doc.IntersectsWith.doc)
.def("IsBounded", &ConvexSet::IsBounded, cls_doc.IsBounded.doc)
.def("IsBounded", &ConvexSet::IsBounded,
py::arg("parallelism") = Parallelism::None(),
py::call_guard<py::gil_scoped_release>(), cls_doc.IsBounded.doc)
.def("IsEmpty", &ConvexSet::IsEmpty, cls_doc.IsEmpty.doc)
.def("MaybeGetPoint", &ConvexSet::MaybeGetPoint,
cls_doc.MaybeGetPoint.doc)
Expand Down
3 changes: 2 additions & 1 deletion bindings/pydrake/geometry/test/optimization_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import numpy as np

from pydrake.common import RandomGenerator, temp_directory
from pydrake.common import RandomGenerator, temp_directory, Parallelism
from pydrake.common.test_utilities.deprecation import catch_drake_warnings
from pydrake.common.test_utilities.pickle_compare import assert_pickle
from pydrake.geometry import (
Expand Down Expand Up @@ -456,6 +456,7 @@ def test_spectrahedron(self):
self.assertFalse(s.IsEmpty())
self.assertFalse(s.MaybeGetFeasiblePoint() is None)
self.assertTrue(s.PointInSet(s.MaybeGetFeasiblePoint()))
self.assertTrue(s.IsBounded(Parallelism.Max()))

def test_v_polytope(self):
mut.VPolytope()
Expand Down
3 changes: 3 additions & 0 deletions geometry/optimization/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ drake_cc_library(
"//solvers:mosek_solver",
"//solvers:scs_solver",
"//solvers:solve",
"@common_robotics_utilities",
"@qhull_internal//:qhull",
],
)
Expand Down Expand Up @@ -516,6 +517,7 @@ drake_cc_googletest(

drake_cc_googletest(
name = "intersection_test",
num_threads = 2,
deps = [
":convex_set",
":test_utilities",
Expand Down Expand Up @@ -592,6 +594,7 @@ drake_cc_googletest(

drake_cc_googletest(
name = "spectrahedron_test",
num_threads = 2,
deps = [
":convex_set",
"//common/test_utilities:eigen_matrix_compare",
Expand Down
4 changes: 4 additions & 0 deletions geometry/optimization/affine_ball.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ double AffineBall::DoCalcVolume() const {
std::abs(B_.determinant());
}

std::optional<bool> AffineBall::DoIsBoundedShortcut() const {
return true;
}

AffineBall AffineBall::MakeAxisAligned(
const Eigen::Ref<const VectorXd>& radius,
const Eigen::Ref<const VectorXd>& center) {
Expand Down
8 changes: 7 additions & 1 deletion geometry/optimization/affine_ball.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,17 @@ class AffineBall final : public ConvexSet {
CheckInvariants();
}

/** Every AffineBall is bounded by construction.
@param parallelism Ignored -- no parallelization is used.
@note See @ref ConvexSet::IsBounded "parent class's documentation" for more
details. */
using ConvexSet::IsBounded;

private:
std::unique_ptr<ConvexSet> DoClone() const final;

/* AffineBall can only represent bounded sets. */
std::optional<bool> DoIsBoundedShortcut() const final { return true; };
std::optional<bool> DoIsBoundedShortcut() const final;

/* AffineBall can only represent nonempty sets. */
bool DoIsEmpty() const final { return false; };
Expand Down
7 changes: 7 additions & 0 deletions geometry/optimization/affine_subspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ class AffineSubspace final : public ConvexSet {
to this AffineSubspace.*/
Eigen::MatrixXd OrthogonalComplementBasis() const;

/** An AffineSubspace is bounded if and only if it is zero-dimensional (i.e.,
a point).
@param parallelism Ignored -- no parallelization is used.
@note See @ref ConvexSet::IsBounded "parent class's documentation" for more
details. */
using ConvexSet::IsBounded;

private:
std::unique_ptr<ConvexSet> DoClone() const final;

Expand Down
5 changes: 3 additions & 2 deletions geometry/optimization/cartesian_product.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ std::unique_ptr<ConvexSet> CartesianProduct::DoClone() const {
return std::make_unique<CartesianProduct>(*this);
}

std::optional<bool> CartesianProduct::DoIsBoundedShortcut() const {
std::optional<bool> CartesianProduct::DoIsBoundedShortcutParallel(
Parallelism parallelism) const {
// Note: The constructor enforces that A_ is full column rank.
for (const auto& s : sets_) {
if (!s->IsBounded()) {
if (!s->IsBounded(parallelism)) {
return false;
}
}
Expand Down
11 changes: 10 additions & 1 deletion geometry/optimization/cartesian_product.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,19 @@ class CartesianProduct final : public ConvexSet {
product. */
using ConvexSet::CalcVolume;

/** A CartesianProduct is bounded if and only if each constituent set is
bounded. This class honors requests for parallelism only so far as its
constituent sets do.
@param parallelism The maximum number of threads to use.
@note See @ref ConvexSet::IsBounded "parent class's documentation" for more
details. */
using ConvexSet::IsBounded;

private:
std::unique_ptr<ConvexSet> DoClone() const final;

std::optional<bool> DoIsBoundedShortcut() const final;
std::optional<bool> DoIsBoundedShortcutParallel(
Parallelism parallelism) const final;

bool DoIsEmpty() const final;

Expand Down
10 changes: 8 additions & 2 deletions geometry/optimization/convex_hull.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,14 @@ std::unique_ptr<ConvexSet> ConvexHull::DoClone() const {
return std::make_unique<ConvexHull>(*this);
}

std::optional<bool> ConvexHull::DoIsBoundedShortcut() const {
return std::nullopt;
std::optional<bool> ConvexHull::DoIsBoundedShortcutParallel(
Parallelism parallelism) const {
for (const auto& s : sets_) {
if (!s->IsBounded(parallelism)) {
return false;
}
}
return true;
}

bool ConvexHull::DoIsEmpty() const {
Expand Down
11 changes: 10 additions & 1 deletion geometry/optimization/convex_hull.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,19 @@ class ConvexHull final : public ConvexSet, private ShapeReifier {
/** @throws Not implemented. */
using ConvexSet::CalcVolume;

/** A ConvexHull is bounded if and only if each constituent set is bounded.
This class honors requests for parallelism only so far as its constituent sets
do.
@param parallelism The maximum number of threads to use.
@note See @ref ConvexSet::IsBounded "parent class's documentation" for more
details. */
using ConvexSet::IsBounded;

private:
std::unique_ptr<ConvexSet> DoClone() const final;

std::optional<bool> DoIsBoundedShortcut() const final;
std::optional<bool> DoIsBoundedShortcutParallel(
Parallelism parallelism) const final;

bool DoIsEmpty() const final;

Expand Down
Loading