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

Add call, get_attr and set_attr methods to VectorEnv #1600

Merged
merged 4 commits into from
Jan 29, 2022

Conversation

tristandeleu
Copy link
Contributor

As suggested in #1513, this PR adds 3 new methods to VectorEnv:

  • call(name, *args, **kwargs), which calls get_attr in each individual environment, and returns either its property name (in which case *args and **kwargs are ignored), or the result of name(*args, **kwargs).
  • get_attr(name), which is syntactic sugar for a call to call to get a property of the individual environments.
  • set_attr(name, values), which alls setattr on each individual environment.

@namheegordonkim
Copy link

Is this getting merged anytime soon?

@tristandeleu tristandeleu force-pushed the feature/vector_env_call branch from bf17629 to afeff82 Compare August 30, 2020 11:55
@tristandeleu
Copy link
Contributor Author

@pzhokhov I have rebased on master to remove any merge conflict. This PR is now ready to be merged or closed.

Copy link
Contributor

@FirefoxMetzger FirefoxMetzger left a comment

Choose a reason for hiding this comment

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

Nice work 🚀 I left some minor comments that you may choose to accept or reject depending on what you think the best solution is here.

Edit: FYI, I didn't review the test code; just the changes to the library code.

Comment on lines 569 to 570
"Trying to call function `{0}` with "
"`_call`. Use `{0}` directly instead.".format(name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"Trying to call function `{0}` with "
"`_call`. Use `{0}` directly instead.".format(name)
f"Trying to call function `{name}` with "
f"`_call`. Use `{name}` directly instead."

Perhaps this can become more readable with format strings.

if self._state != AsyncState.DEFAULT:
raise AlreadyPendingCallError(
"Calling `set_attr` while waiting "
"for a pending call to `{0}` to complete.".format(self._state.value),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"for a pending call to `{0}` to complete.".format(self._state.value),
"for a pending call to `{self._state.value}` to complete.",

Comment on lines +307 to +413
Parameters
----------
name : string
Name of the method or property to call.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think we should also add a line documenting args and kwargs here?

if self._state != AsyncState.DEFAULT:
raise AlreadyPendingCallError(
"Calling `call_async` while waiting "
"for a pending call to `{0}` to complete.".format(self._state.value),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"for a pending call to `{0}` to complete.".format(self._state.value),
f"for a pending call to `{self._state.value}` to complete.",

Since the minimum python version in CI is 3.6 I assume that we can use f-strings? If so, they might make things a little more readable here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed f-strings are much nicer! At the time CI was testing also for versions 2.7 and 3.5, that shows how old this PR is.

----------
timeout : int or float, optional
Number of seconds before the call to `step_wait` times out. If
`None`, the call to `step_wait` never times out.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
`None`, the call to `step_wait` never times out.
`None` (default), the call to `step_wait` never times out.

self._assert_is_running()
if not isinstance(values, list):
values = [values for _ in range(self.num_envs)]
assert len(values) == self.num_envs
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert len(values) == self.num_envs
if len(values) == self.num_envs:
raise ValueError("values must have one value for each environment or be a single (non-list) object.")

Potentially an opinionated comment: I'm not a fan of assert outside of testing code. I'd raise a specific exception here that will tell the user what went wrong (instead of implicitly doing so by showing the assertion that failed.

Also, it may be worthwhile to remove this check and simply fail in the zip loop below if necessary.

Comment on lines 510 to 511
"Trying to call function `{0}` with "
"`_call`. Use `{0}` directly instead.".format(name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"Trying to call function `{0}` with "
"`_call`. Use `{0}` directly instead.".format(name)
f"Trying to call function `{name}` with "
f"`_call`. Use `{name}` directly instead."

Comment on lines 586 to 587
"be one of {`reset`, `step`, `seed`, `close`, `_call`, "
"`_setattr`, `_check_observation_space`}.".format(command)
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't suggest a format string here, since the relevant line was only partially modified, but I'd probably use it here, too.

Comment on lines 100 to 103
Parameters
----------
name : string
Name of the method or property to call.
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to above, would it be worthwhile to document args and kwargs?

Comment on lines 133 to 135
if not isinstance(values, list):
values = [values for _ in range(self.num_envs)]
assert len(values) == self.num_envs
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to above, are we worried about other iterables?

Copy link
Contributor

@FirefoxMetzger FirefoxMetzger left a comment

Choose a reason for hiding this comment

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

Some updates based on the changes you added :)

Comment on lines 309 to 311

args, kwargs :
Arguments and keyword arguments to apply to the method call.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
args, kwargs :
Arguments and keyword arguments to apply to the method call.
args, kwargs :
Arguments and keyword arguments to apply to the method call.

Nitpick: remove extra whitespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't know what was the change you suggested (where the extra whitespace was), but I changed the docstring to match more closely the Numpy docstring guidelines. I also moved the docstrings from SyncVectorEnv to the base class VectorEnv to match what was done for the other methods.

Copy link
Contributor

Choose a reason for hiding this comment

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

it's really just a small thing; there was a leading newline (\n) above args, kwargs that separated it from the previous parameter. If you look closely the suggestion changes 3 lines of code into 2 lines of code.

@@ -362,20 +362,25 @@ def set_attr(self, name, values):
name : string
Name of the property to be set in each individual environment.

values : list or object
Values of the property to bet set to. If `values` is a list, then
values : list of object
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be or like before (suggested by the description and by the code), or of as changed to now? If the latter, I think the description should be updated to reflect that change. Should the source code raise an exception on non-list types, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No this was a mistake indeed, I thought it was a typo but it is list or object.

assert len(values) == self.num_envs
if len(values) != self.num_envs:
raise ValueError(
"The values must be a list of length the number "
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"The values must be a list of length the number "
"Values must be a list with length equal to the number "

@@ -125,14 +128,19 @@ def set_attr(self, name, values):
name : string
Name of the property to be set in each individual environment.

values : list or object
Values of the property to bet set to. If `values` is a list, then
values : list of object
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question as previously; is the of here intentional?

@tristandeleu
Copy link
Contributor Author

What is the status of this PR? Any timeline for this PR getting merged? @jkterry1

@vwxyzjn
Copy link
Contributor

vwxyzjn commented Jan 25, 2022

@jkterry1 this PR makes sense to me. In gym-microrts we use this feature to get invalid action masks.

Everything in the PR looks good to me except the testing environment might need to be replaced with CartPole-v1. CubeCrush-v0 has been deprecated in #2553.

@jkterry1
Copy link
Collaborator

There's also merge conflicts. If you're happy with it I'll merge it once tests and merge conflicts are fixed.

@tristandeleu tristandeleu force-pushed the feature/vector_env_call branch from 27d04f6 to 2d90563 Compare January 26, 2022 00:30
@vwxyzjn
Copy link
Contributor

vwxyzjn commented Jan 29, 2022

LGTM

@jkterry1 jkterry1 merged commit 39ba73f into openai:master Jan 29, 2022
Markus28 pushed a commit to Markus28/gym that referenced this pull request Jan 29, 2022
* Add call, get_attr and set_attr methods

* Use f-strings and remove assert

* Allow tuples in set_attr and move docstrings

* Replace CubeCrash by CartPole in tests
@tristandeleu tristandeleu deleted the feature/vector_env_call branch January 29, 2022 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants