From e40cb29a41d436bfe249956a8bd72f00344031bb Mon Sep 17 00:00:00 2001 From: pseudo-rnd-thoughts Date: Fri, 9 Aug 2024 10:26:03 +0100 Subject: [PATCH] Remove old features --- gymnasium/vector/utils/batched_spaces.py | 141 ----------------------- tests/vector/test_batch_spaces.py | 76 ------------ 2 files changed, 217 deletions(-) delete mode 100644 gymnasium/vector/utils/batched_spaces.py delete mode 100644 tests/vector/test_batch_spaces.py diff --git a/gymnasium/vector/utils/batched_spaces.py b/gymnasium/vector/utils/batched_spaces.py deleted file mode 100644 index 5f7f597e6..000000000 --- a/gymnasium/vector/utils/batched_spaces.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Batching support for Spaces of same type but possibly varying low/high values.""" - -from __future__ import annotations - -from copy import deepcopy -from functools import singledispatch - -import numpy as np - -from gymnasium import Space -from gymnasium.spaces import ( - Box, - Dict, - Discrete, - Graph, - MultiBinary, - MultiDiscrete, - OneOf, - Sequence, - Text, - Tuple, -) - - -@singledispatch -def batch_differing_spaces(spaces: list[Space]): - """Batch a Sequence of spaces that allows the subspaces to contain minor differences.""" - assert len(spaces) > 0 - assert all(isinstance(space, type(spaces[0])) for space in spaces) - assert type(spaces[0]) in batch_differing_spaces.registry - - return batch_differing_spaces.dispatch(type(spaces[0]))(spaces) - - -@batch_differing_spaces.register(Box) -def _batch_differing_spaces_box(spaces: list[Box]): - assert all(spaces[0].dtype == space for space in spaces) - - return Box( - low=np.array([space.low for space in spaces]), - high=np.array([space.high for space in spaces]), - dtype=spaces[0].dtype, - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(Discrete) -def _batch_differing_spaces_discrete(spaces: list[Discrete]): - return MultiDiscrete( - nvec=np.array([space.n for space in spaces]), - start=np.array([space.start for space in spaces]), - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(MultiDiscrete) -def _batch_differing_spaces_multi_discrete(spaces: list[MultiDiscrete]): - return Box( - low=np.array([space.start for space in spaces]), - high=np.array([space.start + space.nvec for space in spaces]) - 1, - dtype=spaces[0].dtype, - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(MultiBinary) -def _batch_differing_spaces_multi_binary(spaces: list[MultiBinary]): - assert all(spaces[0].shape == space.shape for space in spaces) - - return Box( - low=0, - high=1, - shape=(len(spaces),) + spaces[0].shape, - dtype=spaces[0].dtype, - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(Tuple) -def _batch_differing_spaces_tuple(spaces: list[Tuple]): - return Tuple( - tuple( - batch_differing_spaces(subspaces) - for subspaces in zip(*[space.spaces for space in spaces]) - ), - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(Dict) -def _batch_differing_spaces_dict(spaces: list[Dict]): - assert all(spaces[0].keys() == space.keys() for space in spaces) - - return Dict( - { - key: batch_differing_spaces([space[key] for space in spaces]) - for key in spaces[0].keys() - }, - seed=deepcopy(spaces[0].np_random), - ) - - -@batch_differing_spaces.register(Graph) -@batch_differing_spaces.register(Text) -@batch_differing_spaces.register(Sequence) -@batch_differing_spaces.register(OneOf) -def _batch_spaces_undefined(spaces: list[Graph | Text | Sequence | OneOf]): - return Tuple(spaces, seed=deepcopy(spaces[0].np_random)) - - -def all_spaces_have_same_shape(spaces): - """Check if all spaces have the same size.""" - if not spaces: - return True # An empty list is considered to have the same shape - - def get_space_shape(space): - if isinstance(space, Box): - return space.shape - elif isinstance(space, Discrete): - return () # Discrete spaces are considered scalar - elif isinstance(space, Dict): - return tuple(get_space_shape(s) for s in space.spaces.values()) - elif isinstance(space, Tuple): - return tuple(get_space_shape(s) for s in space.spaces) - else: - raise ValueError(f"Unsupported space type: {type(space)}") - - first_shape = get_space_shape(spaces[0]) - return all(get_space_shape(space) == first_shape for space in spaces[1:]) - - -def all_spaces_have_same_type(spaces): - """Check if all spaces have the same space type (Box, Discrete, etc).""" - if not spaces: - return True # An empty list is considered to have the same type - - # Get the type of the first space - first_type = type(spaces[0]) - - # Check if all spaces have the same type as the first one - return all(isinstance(space, first_type) for space in spaces) diff --git a/tests/vector/test_batch_spaces.py b/tests/vector/test_batch_spaces.py deleted file mode 100644 index a91276dca..000000000 --- a/tests/vector/test_batch_spaces.py +++ /dev/null @@ -1,76 +0,0 @@ -import pytest - -import gymnasium as gym -from gymnasium.spaces import Box, Dict, Discrete -from gymnasium.vector import AsyncVectorEnv, SyncVectorEnv -from gymnasium.vector.utils import batch_space -from gymnasium.vector.utils.batched_spaces import batch_differing_spaces - - -class CustomEnv(gym.Env): - def __init__(self, observation_space): - super().__init__() - self.observation_space = observation_space - self.action_space = Discrete(2) # Dummy action space - - def reset(self, seed=None, options=None): - return self.observation_space.sample(), {} - - def step(self, action): - return self.observation_space.sample(), 0, False, False, {} - - -def create_env(obs_space): - return lambda: CustomEnv(obs_space) - - -# Test cases for both SyncVectorEnv and AsyncVectorEnv -@pytest.mark.parametrize("VectorEnv", [SyncVectorEnv, AsyncVectorEnv]) -class TestVectorEnvObservationModes: - - def test_invalid_observation_mode(self, VectorEnv): - with pytest.raises( - ValueError, match="Need to pass in mode for batching observations" - ): - VectorEnv( - [create_env(Box(low=0, high=1, shape=(5,))) for _ in range(3)], - observation_mode="invalid", - ) - - def test_mixed_observation_spaces(self, VectorEnv): - spaces = [ - Box(low=0, high=1, shape=(3,)), - Discrete(5), - Dict({"a": Discrete(2), "b": Box(low=0, high=1, shape=(2,))}), - ] - with pytest.raises( - AssertionError, - match="Low & High values for observation spaces can be different but shapes need to be the same", - ): - VectorEnv( - [create_env(space) for space in spaces], observation_mode="different" - ) - - def test_default_observation_mode(self, VectorEnv): - single_space = Box(low=0, high=1, shape=(5,)) - env = VectorEnv( - [create_env(single_space) for _ in range(3)] - ) # No observation_mode specified - assert env.observation_space == batch_space(single_space, 3) - - def test_different_observation_mode_same_shape(self, VectorEnv): - spaces = [Box(low=0, high=i, shape=(5,)) for i in range(1, 4)] - env = VectorEnv( - [create_env(space) for space in spaces], observation_mode="different" - ) - assert env.observation_space == batch_differing_spaces(spaces) - - def test_different_observation_mode_different_shapes(self, VectorEnv): - spaces = [Box(low=0, high=1, shape=(i + 1,)) for i in range(3)] - with pytest.raises( - AssertionError, - match="Low & High values for observation spaces can be different but shapes need to be the same", - ): - VectorEnv( - [create_env(space) for space in spaces], observation_mode="different" - )