-
Notifications
You must be signed in to change notification settings - Fork 321
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
[Versioning] Gymnasium 1.0 incompatibility errors #2484
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -59,6 +59,22 @@ | |||||
_has_minigrid = importlib.util.find_spec("minigrid") is not None | ||||||
|
||||||
|
||||||
GYMNASIUM_1_ERROR = """RuntimeError: TorchRL does not support gymnasium 1.0 or later versions due to incompatible | ||||||
changes in the Gym API. | ||||||
Using gymnasium 1.0 with TorchRL would require significant modifications to your code and may result in: | ||||||
* Inaccurate step counting, as the auto-reset feature can cause unpredictable numbers of steps to be executed. | ||||||
* Potential data corruption, as the environment may require/produce garbage data during reset steps. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* Trajectory overlap during data collection. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe explain this one too |
||||||
* Increased computational overhead, as the library would need to handle the additional complexity of auto-resets. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* Manual filtering and boilerplate code to mitigate these issues, which would compromise the modularity and ease of | ||||||
use of TorchRL. | ||||||
To maintain the integrity and efficiency of our library, we cannot support this version of gymnasium at this time. | ||||||
If you need to use gymnasium 1.0 or later, we recommend exploring alternative solutions or waiting for future updates | ||||||
to TorchRL and gymnasium that may address this compatibility issue. | ||||||
For more information, please refer to discussion https://github.com/pytorch/rl/discussions/2483 in torchrl. | ||||||
""" | ||||||
|
||||||
|
||||||
def _minigrid_lib(): | ||||||
assert _has_minigrid, "minigrid not found" | ||||||
import minigrid | ||||||
|
@@ -400,27 +416,37 @@ def _box_convert(spec, gym_spaces, shape): # noqa: F811 | |||||
return gym_spaces.Box(low=low, high=high, shape=shape) | ||||||
|
||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _box_convert(spec, gym_spaces, shape): # noqa: F811 | ||||||
low = spec.low.detach().cpu().numpy() | ||||||
high = spec.high.detach().cpu().numpy() | ||||||
return gym_spaces.Box(low=low, high=high, shape=shape) | ||||||
|
||||||
|
||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _box_convert(spec, gym_spaces, shape): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
|
||||||
@implement_for("gym", "0.21", None) | ||||||
def _multidiscrete_convert(gym_spaces, spec): | ||||||
return gym_spaces.multi_discrete.MultiDiscrete( | ||||||
spec.nvec, dtype=torch_to_numpy_dtype_dict[spec.dtype] | ||||||
) | ||||||
|
||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _multidiscrete_convert(gym_spaces, spec): # noqa: F811 | ||||||
return gym_spaces.multi_discrete.MultiDiscrete( | ||||||
spec.nvec, dtype=torch_to_numpy_dtype_dict[spec.dtype] | ||||||
) | ||||||
|
||||||
|
||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _multidiscrete_convert(gym_spaces, spec): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
|
||||||
@implement_for("gym", None, "0.21") | ||||||
def _multidiscrete_convert(gym_spaces, spec): # noqa: F811 | ||||||
return gym_spaces.multi_discrete.MultiDiscrete(spec.nvec) | ||||||
|
@@ -519,12 +545,17 @@ def _get_gym_envs(): # noqa: F811 | |||||
return gym.envs.registration.registry.keys() | ||||||
|
||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _get_gym_envs(): # noqa: F811 | ||||||
gym = gym_backend() | ||||||
return gym.envs.registration.registry.keys() | ||||||
|
||||||
|
||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _get_gym_envs(): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
|
||||||
def _is_from_pixels(env): | ||||||
observation_spec = env.observation_space | ||||||
try: | ||||||
|
@@ -835,7 +866,7 @@ def _get_batch_size(self, env): | |||||
batch_size = self.batch_size | ||||||
return batch_size | ||||||
|
||||||
@implement_for("gymnasium") # gymnasium wants the unwrapped env | ||||||
@implement_for("gymnasium", None, "1.0.0") # gymnasium wants the unwrapped env | ||||||
def _get_batch_size(self, env): # noqa: F811 | ||||||
env_unwrapped = env.unwrapped | ||||||
if hasattr(env_unwrapped, "num_envs"): | ||||||
|
@@ -844,6 +875,10 @@ def _get_batch_size(self, env): # noqa: F811 | |||||
batch_size = self.batch_size | ||||||
return batch_size | ||||||
|
||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _get_batch_size(self, env): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
def _check_kwargs(self, kwargs: Dict): | ||||||
if "env" not in kwargs: | ||||||
raise TypeError("Could not find environment key 'env' in kwargs.") | ||||||
|
@@ -920,7 +955,11 @@ def _build_gym_env(self, env, pixels_only): # noqa: F811 | |||||
|
||||||
return LegacyPixelObservationWrapper(env, pixels_only=pixels_only) | ||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _build_gym_env(self, env, pixels_only): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _build_gym_env(self, env, pixels_only): # noqa: F811 | ||||||
compatibility = gym_backend("wrappers.compatibility") | ||||||
pixel_observation = gym_backend("wrappers.pixel_observation") | ||||||
|
@@ -985,7 +1024,11 @@ def _set_seed_initial(self, seed: int) -> None: # noqa: F811 | |||||
except AttributeError as err2: | ||||||
raise err from err2 | ||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _set_seed_initial(self, seed: int) -> None: # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _set_seed_initial(self, seed: int) -> None: # noqa: F811 | ||||||
try: | ||||||
self.reset(seed=seed) | ||||||
|
@@ -1003,7 +1046,11 @@ def _reward_space(self, env): | |||||
if hasattr(env, "reward_space") and env.reward_space is not None: | ||||||
return env.reward_space | ||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _reward_space(self, env): # noqa: F811 | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _reward_space(self, env): # noqa: F811 | ||||||
env = env.unwrapped | ||||||
if hasattr(env, "reward_space") and env.reward_space is not None: | ||||||
|
@@ -1397,7 +1444,14 @@ def _set_gym_args( # noqa: F811 | |||||
) -> None: | ||||||
kwargs.setdefault("disable_env_checker", True) | ||||||
|
||||||
@implement_for("gymnasium") | ||||||
@implement_for("gymnasium", "1.0.0") | ||||||
def _set_gym_args( # noqa: F811 | ||||||
self, | ||||||
kwargs, | ||||||
) -> None: | ||||||
raise ImportError(GYMNASIUM_1_ERROR) | ||||||
|
||||||
@implement_for("gymnasium", None, "1.0.0") | ||||||
def _set_gym_args( # noqa: F811 | ||||||
self, | ||||||
kwargs, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.