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

[solvers] Add SpecificOptions sugar for solvers to map their options #22043

Merged

Conversation

jwnimmer-tri
Copy link
Collaborator

@jwnimmer-tri jwnimmer-tri commented Oct 15, 2024

Towards #21345 (which ports all solvers to use this new sugar) and thus also #20967.


This change is Reviewable

@jwnimmer-tri jwnimmer-tri added priority: medium release notes: none This pull request should not be mentioned in the release notes labels Oct 15, 2024
@jwnimmer-tri
Copy link
Collaborator Author

+@ggould-tri for feature review, please. (If you have time? No particular ETA, maybe within a week is okay.)

Copy link
Contributor

@ggould-tri ggould-tri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 5 of 5 files at r1, all commit messages.
Reviewable status: 5 unresolved discussions, needs at least two assigned reviewers


solvers/specific_options.h line 25 at r1 (raw file):

generic SolverOptions struct into the specific solver's options API.

This class is intended a short-lived helper (i.e., a local variable on the call

typo?

Suggestion:

This class is intended as a short-lived helper (i.e., a local variable on the call

solvers/specific_options.h line 53 at r1 (raw file):

  participate in the Method 1 or 2 copying / callbacks.

For examples of use, refer to all of the existing Drake solver wrappers. */

nit , a less herculean task.

Suggestion:

any

solvers/specific_options.h line 60 at r1 (raw file):

  /* Creates a converter that reads the subset of `all_options` destined for the
  given `id`. Both arguments are aliased, so must outlive this object. */
  SpecificOptions(const SolverId* id, const SolverOptions* all_options);

BTW: I don't love a ctor aliasing default-copyable objects, and ...* id is very odd to read, but I assume that this is justified by callers expecting inner-loop performance.

Code quote:

  given `id`. Both arguments are aliased, so must outlive this object. */
  SpecificOptions(const SolverId* id, const SolverOptions* all_options);

solvers/specific_options.h line 153 at r1 (raw file):

  //@}

  // The solver we're operating on behalf of (as passed to our constructor).

nit: Mixing /* and // comment styles make styleguide sad.


solvers/specific_options.cc line 149 at r1 (raw file):

  // already been set.
  for (const auto& [respelled_key, boxed_value] : respelled_) {
    // Pedantially, lambdas cannot capture a structured binding so we need to

typo

Suggestion:

Pedantically

Copy link
Collaborator Author

@jwnimmer-tri jwnimmer-tri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+@SeanCurtis-TRI for platform review per schedule, please.

Reviewable status: LGTM missing from assignee SeanCurtis-TRI(platform)


solvers/specific_options.h line 60 at r1 (raw file):

Previously, ggould-tri wrote…

BTW: I don't love a ctor aliasing default-copyable objects, and ...* id is very odd to read, but I assume that this is justified by callers expecting inner-loop performance.

Correct.


solvers/specific_options.h line 153 at r1 (raw file):

Previously, ggould-tri wrote…

nit: Mixing /* and // comment styles make styleguide sad.

The rule is to be consistent, and this is consistent. Functions specifications are /* and implementation notes are //.

Copy link
Contributor

@ggould-tri ggould-tri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 3 files at r2.
Reviewable status: LGTM missing from assignee SeanCurtis-TRI(platform)

Copy link
Contributor

@ggould-tri ggould-tri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 3 files at r2, all commit messages.
Reviewable status: LGTM missing from assignee SeanCurtis-TRI(platform)

Copy link
Contributor

@SeanCurtis-TRI SeanCurtis-TRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:LGTM: With some cosmetic stuff.

Reviewed 2 of 5 files at r1, 3 of 3 files at r2, all commit messages.
Reviewable status: 7 unresolved discussions


solvers/specific_options.h line 29 at r2 (raw file):

convenient tools to map those options into whatever back-end is necessary. Two
different mechanisms are offered, depending on whether the solver's option names
are static or dynamic: CopyToCallbacks or CopyToSerializableStruct.

The ordering of the adjectives doesn't match the ordering of the methods.

Suggestion:

dyanmic or static

solvers/specific_options.h line 79 at r2 (raw file):

  /* Returns and effectively removes the value of the option named `key`. (To be
  specific -- `all_options` remain unchanged; instead, the `key` is memorized

btw This always a weird conflict between code and language. all_options is a pointer to a single thing, so should be singular. However, the idea of the options it holds are plural. British English would probably simplify this.

Either we can refer to all_options the C++ object as unchanged, or we can refer to "all options provided at construction remain unchanged", but the mixture is what causes weirdness.

That said, it's basically clear what's being communicated.

Suggestion:

remains 

solvers/specific_options.h line 84 at r2 (raw file):

  set, this checks `all_options` for our `id` as well as any options added
  during a Respell().
  @tparam T must be one of: double, int, std::string. */

nit: No note on the possible disagreement between T and the actual type of the option.


solvers/specific_options.h line 101 at r2 (raw file):

  /* Helper for "Method 2 - static", per our class overview. Converts options
  when the solver uses an options struct with names known at compile time. The
  `Output` struct must obey Drake's Serialize() protocol, for us to interrogate

nit: The struct formerly known as Output.

Suggestion:

`Result`

solvers/specific_options.cc line 279 at r2 (raw file):

              id_->name(), name, value));
        }
        if (static_cast<int64_t>(value) >

BTW What am I missing here? How can a value encoded as an int ever be bigger than the maximum uint32_t value? Is this simply protecting us from the C++ specification's only-lower-bound- language for defining sizeof(int)?


solvers/test/specific_options_test.cc line 79 at r2 (raw file):

GTEST_TEST(SpecificOptionsTest, CopyToCallbacksNoop) {
  // This is a code-coverage test to cover the early return no-op.

btw: This doesn't really test the early return. The test result is the same whether there's an early return or not (each for loop that would exercise the callbacks get exercised zero times). All one can really say about this test is that no options implies no problems.


solvers/test/specific_options_test.cc line 89 at r2 (raw file):

}

GTEST_TEST(SpecificOptionsTest, CopyToCallbacksEarlyReturn) {

nit: This test is an exact duplicate of the previous (but with a rename).

Copy link
Contributor

@SeanCurtis-TRI SeanCurtis-TRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 8 unresolved discussions


solvers/specific_options.h line 104 at r2 (raw file):

  the option names.
  @param [in,out] result The solver's specific options struct; any options not
  mentioned in `solver_options` will remain unchanged. */

nit: unclear reference...should this be all_options?

Code quote:

solver_options

In the near future, we anticipate changing the SolverOptions API in
support of loading and saving (i.e., serialization). That's especially
troublesome for our solver back-ends that consume its information,
given the low-level and hodge-podge ways in which they hunt for and
apply their specific options.

This commit introduces a higher-level intermediary between solver
back-ends and the program's options. The goal is that SolverOptions
will solely be a user-facing aspect of defining a program; the solver
back-ends will never touch SolverOptions anymore, instead using the
SpecificOptions sugar to map our options API into the back-end.

The new API is designed to improve uniformity of common errors, such
as unknown names or wrongly-typed values.

The new API also lays the groundwork for more efficient processing, as
future work. It removes the need for the "Merge" (copy) operation in
the hot path -- since it only provides a *view* of the options, it can
easily keep track of several dictionaries and query them in order,
with no copying.
@jwnimmer-tri jwnimmer-tri force-pushed the solver-specific-options branch from aabd27b to 7064b7e Compare October 21, 2024 19:51
Copy link
Collaborator Author

@jwnimmer-tri jwnimmer-tri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 unresolved discussion


solvers/specific_options.h line 29 at r2 (raw file):

Previously, SeanCurtis-TRI (Sean Curtis) wrote…

The ordering of the adjectives doesn't match the ordering of the methods.

Done.


solvers/test/specific_options_test.cc line 79 at r2 (raw file):

Previously, SeanCurtis-TRI (Sean Curtis) wrote…

btw: This doesn't really test the early return. The test result is the same whether there's an early return or not (each for loop that would exercise the callbacks get exercised zero times). All one can really say about this test is that no options implies no problems.

Yeah. Maybe the short-circuit isn't that valuable anyway, so I just punted it. We can add it back later if profiling tells us to.

Copy link
Contributor

@SeanCurtis-TRI SeanCurtis-TRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r3, all commit messages.
Reviewable status: :shipit: complete! all discussions resolved, LGTM from assignees ggould-tri(platform),SeanCurtis-TRI(platform)

@SeanCurtis-TRI SeanCurtis-TRI merged commit 32c7d00 into RobotLocomotion:master Oct 21, 2024
9 checks passed
@jwnimmer-tri jwnimmer-tri deleted the solver-specific-options branch October 21, 2024 21:41
RussTedrake pushed a commit to RussTedrake/drake that referenced this pull request Dec 15, 2024
…obotLocomotion#22043)

In the near future, we anticipate changing the SolverOptions API in
support of loading and saving (i.e., serialization). That's especially
troublesome for our solver back-ends that consume its information,
given the low-level and hodge-podge ways in which they hunt for and
apply their specific options.

This commit introduces a higher-level intermediary between solver
back-ends and the program's options. The goal is that SolverOptions
will solely be a user-facing aspect of defining a program; the solver
back-ends will never touch SolverOptions anymore, instead using the
SpecificOptions sugar to map our options API into the back-end.

The new API is designed to improve uniformity of common errors, such
as unknown names or wrongly-typed values.

The new API also lays the groundwork for more efficient processing, as
future work. It removes the need for the "Merge" (copy) operation in
the hot path -- since it only provides a *view* of the options, it can
easily keep track of several dictionaries and query them in order,
with no copying.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: low release notes: none This pull request should not be mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants