From 2e527d666a7c89e26857dbe8b8d782dd4b22ad18 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Wed, 24 Aug 2022 16:31:30 -0700 Subject: [PATCH 01/21] Add auto-resetting atari environments --- setup.py | 10 +- src/seals/__init__.py | 79 ++++++ src/seals/atari.py | 503 ++++++++++++++++++++++++++++++++++++++ src/seals/testing/envs.py | 28 ++- tests/test_envs.py | 22 +- 5 files changed, 629 insertions(+), 13 deletions(-) create mode 100644 src/seals/atari.py diff --git a/setup.py b/setup.py index a4754f7..214382a 100644 --- a/setup.py +++ b/setup.py @@ -57,6 +57,13 @@ def get_readme() -> str: "sphinx-rtd-theme", "sphinxcontrib-napoleon", ] +ATARI_REQUIRE = [ + "opencv-python", + "ale-py==0.7.4", + "pillow", + "autorom[accept-rom-license]~=0.4.2", +] + setup( name="seals", @@ -73,12 +80,13 @@ def get_readme() -> str: tests_require=TESTS_REQUIRE, extras_require={ # recommended packages for development - "dev": ["ipdb", "jupyter", *TESTS_REQUIRE, *DOCS_REQUIRE], + "dev": ["ipdb", "jupyter", *TESTS_REQUIRE, *DOCS_REQUIRE, *ATARI_REQUIRE], "docs": DOCS_REQUIRE, "test": TESTS_REQUIRE, # We'd like to specify `gym[mujoco]`, but this is a no-op when Gym is already # installed. See https://github.com/pypa/pip/issues/4957 for issue. "mujoco": ["mujoco_py>=1.50, <2.0", "imageio"], + "atari": ATARI_REQUIRE, }, url="https://github.com/HumanCompatibleAI/benchmark-environments", license="MIT", diff --git a/src/seals/__init__.py b/src/seals/__init__.py index 7694c6a..8cd0e93 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -28,3 +28,82 @@ entry_point=f"seals.mujoco:{env_base}Env", max_episode_steps=util.get_gym_max_episode_steps(f"{env_base}-v3"), ) + +# Atari + +ATARI_ENV_NAMES = [ + "Adventure", + "AirRaid", + "Alien", + "Amidar", + "Assault", + "Asterix", + "Asteroids", + "Atlantis", + "BankHeist", + "BattleZone", + "BeamRider", + "Berzerk", + "Bowling", + "Boxing", + "Breakout", + "Carnival", + "Centipede", + "ChopperCommand", + "CrazyClimber", + "Defender", + "DemonAttack", + "DoubleDunk", + "ElevatorAction", + "Enduro", + "FishingDerby", + "Freeway", + "Frostbite", + "Gopher", + "Gravitar", + "Hero", + "IceHockey", + "Jamesbond", + "JourneyEscape", + "Kangaroo", + "Krull", + "KungFuMaster", + "MontezumaRevenge", + "MsPacman", + "NameThisGame", + "Phoenix", + "Pitfall", + "Pong", + "Pooyan", + "PrivateEye", + "Qbert", + "Riverraid", + "RoadRunner", + "Robotank", + "Seaquest", + "Skiing", + "Solaris", + "SpaceInvaders", + "StarGunner", + "Tennis", + "TimePilot", + "Tutankham", + "UpNDown", + "Venture", + "VideoPinball", + "WizardOfWor", + "YarsRevenge", + "Zaxxon", +] + +for env_name in ATARI_ENV_NAMES: + for frameskip in [True, False]: + if frameskip: + seals_name = "seals/" + env_name + ("-v5" if frameskip else "NoFrameskip-v4") + func_name = env_name.lower() + ("_v5" if frameskip else "_noframeskip") + gym_name = ("ALE/" + env_name + "-v5") if frameskip else (env_name + "NoFrameskip-v4") + gym.register( + id=seals_name, + entry_point=f"seals.atari:{func_name}", + max_episode_steps=util.get_gym_max_episode_steps(gym_name), + ) diff --git a/src/seals/atari.py b/src/seals/atari.py new file mode 100644 index 0000000..2344b4b --- /dev/null +++ b/src/seals/atari.py @@ -0,0 +1,503 @@ +"""Adaptation of Atari environments for specification learning algorithms.""" + +import gym + +from seals.util import AutoResetWrapper + +# TODO(df) in documentation clarify that we need to use atari wrapper with terminal_on_life_loss=False + + +def adventure_v5(): + return AutoResetWrapper(gym.make("ALE/Adventure-v5")) + + +def adventure_noframeskip(): + return AutoResetWrapper(gym.make("AdventureNoFrameskip-v4")) + + +def airraid_v5(): + return AutoResetWrapper(gym.make("ALE/AirRaid-v5")) + + +def airraid_noframeskip(): + return AutoResetWrapper(gym.make("AirRaidNoFrameskip-v4")) + + +def alien_v5(): + return AutoResetWrapper(gym.make("ALE/Alien-v5")) + + +def alien_noframeskip(): + return AutoResetWrapper(gym.make("AlienNoFrameskip-v4")) + + +def amidar_v5(): + return AutoResetWrapper(gym.make("ALE/Amidar-v5")) + + +def amidar_noframeskip(): + return AutoResetWrapper(gym.make("AmidarNoFrameskip-v4")) + + +def assault_v5(): + return AutoResetWrapper(gym.make("ALE/Assault-v5")) + + +def assault_noframeskip(): + return AutoResetWrapper(gym.make("AssaultNoFrameskip-v4")) + + +def asterix_v5(): + return AutoResetWrapper(gym.make("ALE/Asterix-v5")) + + +def asterix_noframeskip(): + return AutoResetWrapper(gym.make("AsterixNoFrameskip-v4")) + + +def asteroids_v5(): + return AutoResetWrapper(gym.make("ALE/Asteroids-v5")) + + +def asteroids_noframeskip(): + return AutoResetWrapper(gym.make("AsteroidsNoFrameskip-v4")) + + +def atlantis_v5(): + return AutoResetWrapper(gym.make("ALE/Atlantis-v5")) + + +def atlantis_noframeskip(): + return AutoResetWrapper(gym.make("AtlantisNoFrameskip-v4")) + + +def bankheist_v5(): + return AutoResetWrapper(gym.make("ALE/BankHeist-v5")) + + +def bankheist_noframeskip(): + return AutoResetWrapper(gym.make("BankHeistNoFrameskip-v4")) + + +def battlezone_v5(): + return AutoResetWrapper(gym.make("ALE/BattleZone-v5")) + + +def battlezone_noframeskip(): + return AutoResetWrapper(gym.make("BattleZoneNoFrameskip-v4")) + + +def beamrider_v5(): + return AutoResetWrapper(gym.make("ALE/BeamRider-v5")) + + +def beamrider_noframeskip(): + return AutoResetWrapper(gym.make("BeamRiderNoFrameskip-v4")) + + +def berzerk_v5(): + return AutoResetWrapper(gym.make("ALE/Berzerk-v5")) + + +def berzerk_noframeskip(): + return AutoResetWrapper(gym.make("BerzerkNoFrameskip-v4")) + + +def bowling_v5(): + return AutoResetWrapper(gym.make("ALE/Bowling-v5")) + + +def bowling_noframeskip(): + return AutoResetWrapper(gym.make("BowlingNoFrameskip-v4")) + + +def boxing_v5(): + return AutoResetWrapper(gym.make("ALE/Boxing-v5")) + + +def boxing_noframeskip(): + return AutoResetWrapper(gym.make("BoxingNoFrameskip-v4")) + + +def breakout_v5(): + return AutoResetWrapper(gym.make("ALE/Breakout-v5")) + + +def breakout_noframeskip(): + return AutoResetWrapper(gym.make("BreakoutNoFrameskip-v4")) + + +def carnival_v5(): + return AutoResetWrapper(gym.make("ALE/Carnival-v5")) + + +def carnival_noframeskip(): + return AutoResetWrapper(gym.make("CarnivalNoFrameskip-v4")) + + +def centipede_v5(): + return AutoResetWrapper(gym.make("ALE/Centipede-v5")) + + +def centipede_noframeskip(): + return AutoResetWrapper(gym.make("CentipedeNoFrameskip-v4")) + + +def choppercommand_v5(): + return AutoResetWrapper(gym.make("ALE/ChopperCommand-v5")) + + +def choppercommand_noframeskip(): + return AutoResetWrapper(gym.make("ChopperCommandNoFrameskip-v4")) + + +def crazyclimber_v5(): + return AutoResetWrapper(gym.make("ALE/CrazyClimber-v5")) + + +def crazyclimber_noframeskip(): + return AutoResetWrapper(gym.make("CrazyClimberNoFrameskip-v4")) + + +def defender_v5(): + return AutoResetWrapper(gym.make("ALE/Defender-v5")) + + +def defender_noframeskip(): + return AutoResetWrapper(gym.make("DefenderNoFrameskip-v4")) + + +def demonattack_v5(): + return AutoResetWrapper(gym.make("ALE/DemonAttack-v5")) + + +def demonattack_noframeskip(): + return AutoResetWrapper(gym.make("DemonAttackNoFrameskip-v4")) + + +def doubledunk_v5(): + return AutoResetWrapper(gym.make("ALE/DoubleDunk-v5")) + + +def doubledunk_noframeskip(): + return AutoResetWrapper(gym.make("DoubleDunkNoFrameskip-v4")) + + +def elevatoraction_v5(): + return AutoResetWrapper(gym.make("ALE/ElevatorAction-v5")) + + +def elevatoraction_noframeskip(): + return AutoResetWrapper(gym.make("ElevatorActionNoFrameskip-v4")) + + +def enduro_v5(): + return AutoResetWrapper(gym.make("ALE/Enduro-v5")) + + +def enduro_noframeskip(): + return AutoResetWrapper(gym.make("EnduroNoFrameskip-v4")) + + +def fishingderby_v5(): + return AutoResetWrapper(gym.make("ALE/FishingDerby-v5")) + + +def fishingderby_noframeskip(): + return AutoResetWrapper(gym.make("FishingDerbyNoFrameskip-v4")) + + +def freeway_v5(): + return AutoResetWrapper(gym.make("ALE/Freeway-v5")) + + +def freeway_noframeskip(): + return AutoResetWrapper(gym.make("FreewayNoFrameskip-v4")) + + +def frostbite_v5(): + return AutoResetWrapper(gym.make("ALE/Frostbite-v5")) + + +def frostbite_noframeskip(): + return AutoResetWrapper(gym.make("FrostbiteNoFrameskip-v4")) + + +def gopher_v5(): + return AutoResetWrapper(gym.make("ALE/Gopher-v5")) + + +def gopher_noframeskip(): + return AutoResetWrapper(gym.make("GopherNoFrameskip-v4")) + + +def gravitar_v5(): + return AutoResetWrapper(gym.make("ALE/Gravitar-v5")) + + +def gravitar_noframeskip(): + return AutoResetWrapper(gym.make("GravitarNoFrameskip-v4")) + + +def hero_v5(): + return AutoResetWrapper(gym.make("ALE/Hero-v5")) + + +def hero_noframeskip(): + return AutoResetWrapper(gym.make("HeroNoFrameskip-v4")) + + +def icehockey_v5(): + return AutoResetWrapper(gym.make("ALE/IceHockey-v5")) + + +def icehockey_noframeskip(): + return AutoResetWrapper(gym.make("IceHockeyNoFrameskip-v4")) + + +def jamesbond_v5(): + return AutoResetWrapper(gym.make("ALE/Jamesbond-v5")) + + +def jamesbond_noframeskip(): + return AutoResetWrapper(gym.make("JamesbondNoFrameskip-v4")) + + +def journeyescape_v5(): + return AutoResetWrapper(gym.make("ALE/JourneyEscape-v5")) + + +def journeyescape_noframeskip(): + return AutoResetWrapper(gym.make("JourneyEscapeNoFrameskip-v4")) + + +def kangaroo_v5(): + return AutoResetWrapper(gym.make("ALE/Kangaroo-v5")) + + +def kangaroo_noframeskip(): + return AutoResetWrapper(gym.make("KangarooNoFrameskip-v4")) + + +def krull_v5(): + return AutoResetWrapper(gym.make("ALE/Krull-v5")) + + +def krull_noframeskip(): + return AutoResetWrapper(gym.make("KrullNoFrameskip-v4")) + + +def kungfumaster_v5(): + return AutoResetWrapper(gym.make("ALE/KungFuMaster-v5")) + + +def kungfumaster_noframeskip(): + return AutoResetWrapper(gym.make("KungFuMasterNoFrameskip-v4")) + + +def montezumarevenge_v5(): + return AutoResetWrapper(gym.make("ALE/MontezumaRevenge-v5")) + + +def montezumarevenge_noframeskip(): + return AutoResetWrapper(gym.make("MontezumaRevengeNoFrameskip-v4")) + + +def mspacman_v5(): + return AutoResetWrapper(gym.make("ALE/MsPacman-v5")) + + +def mspacman_noframeskip(): + return AutoResetWrapper(gym.make("MsPacmanNoFrameskip-v4")) + + +def namethisgame_v5(): + return AutoResetWrapper(gym.make("ALE/NameThisGame-v5")) + + +def namethisgame_noframeskip(): + return AutoResetWrapper(gym.make("NameThisGameNoFrameskip-v4")) + + +def phoenix_v5(): + return AutoResetWrapper(gym.make("ALE/Phoenix-v5")) + + +def phoenix_noframeskip(): + return AutoResetWrapper(gym.make("PhoenixNoFrameskip-v4")) + + +def pitfall_v5(): + return AutoResetWrapper(gym.make("ALE/Pitfall-v5")) + + +def pitfall_noframeskip(): + return AutoResetWrapper(gym.make("PitfallNoFrameskip-v4")) + + +def pong_v5(): + return AutoResetWrapper(gym.make("ALE/Pong-v5")) + + +def pong_noframeskip(): + return AutoResetWrapper(gym.make("PongNoFrameskip-v4")) + + +def pooyan_v5(): + return AutoResetWrapper(gym.make("ALE/Pooyan-v5")) + + +def pooyan_noframeskip(): + return AutoResetWrapper(gym.make("PooyanNoFrameskip-v4")) + + +def privateeye_v5(): + return AutoResetWrapper(gym.make("ALE/PrivateEye-v5")) + + +def privateeye_noframeskip(): + return AutoResetWrapper(gym.make("PrivateEyeNoFrameskip-v4")) + + +def qbert_v5(): + return AutoResetWrapper(gym.make("ALE/Qbert-v5")) + + +def qbert_noframeskip(): + return AutoResetWrapper(gym.make("QbertNoFrameskip-v4")) + + +def riverraid_v5(): + return AutoResetWrapper(gym.make("ALE/Riverraid-v5")) + + +def riverraid_noframeskip(): + return AutoResetWrapper(gym.make("RiverraidNoFrameskip-v4")) + + +def roadrunner_v5(): + return AutoResetWrapper(gym.make("ALE/RoadRunner-v5")) + + +def roadrunner_noframeskip(): + return AutoResetWrapper(gym.make("RoadRunnerNoFrameskip-v4")) + + +def robotank_v5(): + return AutoResetWrapper(gym.make("ALE/Robotank-v5")) + + +def robotank_noframeskip(): + return AutoResetWrapper(gym.make("RobotankNoFrameskip-v4")) + + +def seaquest_v5(): + return AutoResetWrapper(gym.make("ALE/Seaquest-v5")) + + +def seaquest_noframeskip(): + return AutoResetWrapper(gym.make("SeaquestNoFrameskip-v4")) + + +def skiing_v5(): + return AutoResetWrapper(gym.make("ALE/Skiing-v5")) + + +def skiing_noframeskip(): + return AutoResetWrapper(gym.make("SkiingNoFrameskip-v4")) + + +def solaris_v5(): + return AutoResetWrapper(gym.make("ALE/Solaris-v5")) + + +def solaris_noframeskip(): + return AutoResetWrapper(gym.make("SolarisNoFrameskip-v4")) + + +def spaceinvaders_v5(): + return AutoResetWrapper(gym.make("ALE/SpaceInvaders-v5")) + + +def spaceinvaders_noframeskip(): + return AutoResetWrapper(gym.make("SpaceInvadersNoFrameskip-v4")) + + +def stargunner_v5(): + return AutoResetWrapper(gym.make("ALE/StarGunner-v5")) + + +def stargunner_noframeskip(): + return AutoResetWrapper(gym.make("StarGunnerNoFrameskip-v4")) + + +def tennis_v5(): + return AutoResetWrapper(gym.make("ALE/Tennis-v5")) + + +def tennis_noframeskip(): + return AutoResetWrapper(gym.make("TennisNoFrameskip-v4")) + + +def timepilot_v5(): + return AutoResetWrapper(gym.make("ALE/TimePilot-v5")) + + +def timepilot_noframeskip(): + return AutoResetWrapper(gym.make("TimePilotNoFrameskip-v4")) + + +def tutankham_v5(): + return AutoResetWrapper(gym.make("ALE/Tutankham-v5")) + + +def tutankham_noframeskip(): + return AutoResetWrapper(gym.make("TutankhamNoFrameskip-v4")) + + +def upndown_v5(): + return AutoResetWrapper(gym.make("ALE/UpNDown-v5")) + + +def upndown_noframeskip(): + return AutoResetWrapper(gym.make("UpNDownNoFrameskip-v4")) + + +def venture_v5(): + return AutoResetWrapper(gym.make("ALE/Venture-v5")) + + +def venture_noframeskip(): + return AutoResetWrapper(gym.make("VentureNoFrameskip-v4")) + + +def videopinball_v5(): + return AutoResetWrapper(gym.make("ALE/VideoPinball-v5")) + + +def videopinball_noframeskip(): + return AutoResetWrapper(gym.make("VideoPinballNoFrameskip-v4")) + + +def wizardofwor_v5(): + return AutoResetWrapper(gym.make("ALE/WizardOfWor-v5")) + + +def wizardofwor_noframeskip(): + return AutoResetWrapper(gym.make("WizardOfWorNoFrameskip-v4")) + + +def yarsrevenge_v5(): + return AutoResetWrapper(gym.make("ALE/YarsRevenge-v5")) + + +def yarsrevenge_noframeskip(): + return AutoResetWrapper(gym.make("YarsRevengeNoFrameskip-v4")) + + +def zaxxon_v5(): + return AutoResetWrapper(gym.make("ALE/Zaxxon-v5")) + + +def zaxxon_noframeskip(): + return AutoResetWrapper(gym.make("ZaxxonNoFrameskip-v4")) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 387b4de..590fd3a 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -4,6 +4,7 @@ projects such as `imitation`, and may be useful in other codebases. """ +import collections import re from typing import ( Any, @@ -137,7 +138,12 @@ def has_same_observations(rollout_a: Rollout, rollout_b: Rollout) -> bool: return True -def test_seed(env: gym.Env, env_name: str, deterministic_envs: Iterable[str]) -> None: +def test_seed( + env: gym.Env, + env_name: str, + deterministic_envs: Iterable[str], + few_check_envs: Iterable[str], +) -> None: """Tests environment seeding. If non-deterministic, different seeds should produce different transitions. @@ -148,10 +154,9 @@ def test_seed(env: gym.Env, env_name: str, deterministic_envs: Iterable[str]) -> """ env.action_space.seed(0) actions = [env.action_space.sample() for _ in range(10)] - # With the same seed, should always get the same result seeds = env.seed(42) - assert isinstance(seeds, list) + assert isinstance(seeds, collections.abc.Sequence) assert len(seeds) > 0 rollout_a = get_rollout(env, actions) @@ -164,7 +169,7 @@ def test_seed(env: gym.Env, env_name: str, deterministic_envs: Iterable[str]) -> # eventually get a different result. For deterministic environments, all # seeds should produce the same starting state. def different_seeds_same_rollout(seed1, seed2): - new_actions = [env.action_space.sample() for _ in range(10)] + new_actions = [env.action_space.sample() for _ in range(100)] env.seed(seed1) new_rollout_1 = get_rollout(env, new_actions) env.seed(seed2) @@ -172,7 +177,10 @@ def different_seeds_same_rollout(seed1, seed2): return has_same_observations(new_rollout_1, new_rollout_2) is_deterministic = matches_list(env_name, deterministic_envs) - same_obs = all(different_seeds_same_rollout(seed, seed + 1) for seed in range(100)) + num_seeds = 100 if not matches_list(env_name, few_check_envs) else 3 + same_obs = all( + different_seeds_same_rollout(seed, seed + 1) for seed in range(num_seeds) + ) assert same_obs == is_deterministic @@ -202,7 +210,8 @@ def _is_mujoco_env(env: gym.Env) -> bool: def test_rollout_schema( env: gym.Env, steps_after_done: int = 10, - max_steps: int = 10000, + max_steps: int = 10_000, + check_episode_ends: bool = True, ) -> None: """Check custom environments have correct types on `step` and `reset`. @@ -225,10 +234,11 @@ def test_rollout_schema( if done: break - assert done is True, "did not get to end of episode" + if check_episode_ends: + assert done is True, "did not get to end of episode" - for _ in range(steps_after_done): - _sample_and_check(env, obs_space) + for _ in range(steps_after_done): + _sample_and_check(env, obs_space) def test_premature_step(env: gym.Env, skip_fn, raises_fn) -> None: diff --git a/tests/test_envs.py b/tests/test_envs.py index 4e8c69b..003b63f 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -23,6 +23,17 @@ "seals/InitShiftTest-v0", ] +ATARI_V5_ENVS: List[str] = [ + "seals/" + env_name + "-v5" for env_name in seals.ATARI_ENV_NAMES +] +ATARI_NO_FRAMESKIP_ENVS: List[str] = [ + "seals/" + env_name + "NoFrameskip-v4" for env_name in seals.ATARI_ENV_NAMES +] + +DETERMINISTIC_ENVS += ATARI_NO_FRAMESKIP_ENVS + +ATARI_ENVS: List[str] = ATARI_V5_ENVS + ATARI_NO_FRAMESKIP_ENVS + env = pytest.fixture(envs.make_env_fixture(skip_fn=pytest.skip)) @@ -33,15 +44,20 @@ class TestEnvs: def test_seed(self, env: gym.Env, env_name: str): """Tests environment seeding.""" - envs.test_seed(env, env_name, DETERMINISTIC_ENVS) + envs.test_seed(env, env_name, DETERMINISTIC_ENVS, ATARI_NO_FRAMESKIP_ENVS) def test_premature_step(self, env: gym.Env): """Tests if step() before reset() raises error.""" envs.test_premature_step(env, skip_fn=pytest.skip, raises_fn=pytest.raises) - def test_rollout_schema(self, env: gym.Env): + # if env is atari then don't wait until done else do normal thing + # or maybe force done=True? + def test_rollout_schema(self, env: gym.Env, env_name: str): """Tests if environments have correct types on `step()` and `reset()`.""" - envs.test_rollout_schema(env) + if env_name in ATARI_ENVS: + envs.test_rollout_schema(env, max_steps=1_000, check_episode_ends=False) + else: + envs.test_rollout_schema(env) def test_render(self, env: gym.Env): """Tests `render()` supports modes specified in environment metadata.""" From e57612c197520aebc2582e64b446435ec5bb6d94 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Wed, 24 Aug 2022 18:30:37 -0700 Subject: [PATCH 02/21] Improve documentation, reduce testing time for atari envs --- README.md | 4 +- src/seals/__init__.py | 19 +- src/seals/atari.py | 746 +++++++++++++++++++++++++++++++++++++- src/seals/testing/envs.py | 4 +- 4 files changed, 759 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 71a5b39..6a4294a 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ There are two types of environments in *seals*: - **Diagnostic Tasks** which test individual facets of algorithm performance in isolation. - **Renovated Environments**, adaptations of widely-used benchmarks such as MuJoCo continuous - control tasks to be suitable for specification learning benchmarks. In particular, we remove - any side-channel sources of reward information. + control tasks and Atari games to be suitable for specification learning benchmarks. In particular, + we remove any side-channel sources of reward information. *seals* is under active development and we intend to add more categories of tasks soon. diff --git a/src/seals/__init__.py b/src/seals/__init__.py index 8cd0e93..a1218d1 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -98,12 +98,13 @@ for env_name in ATARI_ENV_NAMES: for frameskip in [True, False]: - if frameskip: - seals_name = "seals/" + env_name + ("-v5" if frameskip else "NoFrameskip-v4") - func_name = env_name.lower() + ("_v5" if frameskip else "_noframeskip") - gym_name = ("ALE/" + env_name + "-v5") if frameskip else (env_name + "NoFrameskip-v4") - gym.register( - id=seals_name, - entry_point=f"seals.atari:{func_name}", - max_episode_steps=util.get_gym_max_episode_steps(gym_name), - ) + seals_name = "seals/" + env_name + ("-v5" if frameskip else "NoFrameskip-v4") + func_name = env_name.lower() + ("_v5" if frameskip else "_noframeskip") + gym_name = ( + ("ALE/" + env_name + "-v5") if frameskip else (env_name + "NoFrameskip-v4") + ) + gym.register( + id=seals_name, + entry_point=f"seals.atari:{func_name}", + max_episode_steps=util.get_gym_max_episode_steps(gym_name), + ) diff --git a/src/seals/atari.py b/src/seals/atari.py index 2344b4b..88774b6 100644 --- a/src/seals/atari.py +++ b/src/seals/atari.py @@ -4,500 +4,1242 @@ from seals.util import AutoResetWrapper -# TODO(df) in documentation clarify that we need to use atari wrapper with terminal_on_life_loss=False - def adventure_v5(): + """Fixed-length variant of Adventure-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Adventure-v5")) def adventure_noframeskip(): + """Fixed-length variant of AdventureNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AdventureNoFrameskip-v4")) def airraid_v5(): + """Fixed-length variant of AirRaid-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/AirRaid-v5")) def airraid_noframeskip(): + """Fixed-length variant of AirRaidNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AirRaidNoFrameskip-v4")) def alien_v5(): + """Fixed-length variant of Alien-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Alien-v5")) def alien_noframeskip(): + """Fixed-length variant of AlienNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AlienNoFrameskip-v4")) def amidar_v5(): + """Fixed-length variant of Amidar-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Amidar-v5")) def amidar_noframeskip(): + """Fixed-length variant of AmidarNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AmidarNoFrameskip-v4")) def assault_v5(): + """Fixed-length variant of Assault-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Assault-v5")) def assault_noframeskip(): + """Fixed-length variant of AssaultNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AssaultNoFrameskip-v4")) def asterix_v5(): + """Fixed-length variant of Asterix-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Asterix-v5")) def asterix_noframeskip(): + """Fixed-length variant of AsterixNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AsterixNoFrameskip-v4")) def asteroids_v5(): + """Fixed-length variant of Asteroids-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Asteroids-v5")) def asteroids_noframeskip(): + """Fixed-length variant of AsteroidsNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AsteroidsNoFrameskip-v4")) def atlantis_v5(): + """Fixed-length variant of Atlantis-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Atlantis-v5")) def atlantis_noframeskip(): + """Fixed-length variant of AtlantisNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("AtlantisNoFrameskip-v4")) def bankheist_v5(): + """Fixed-length variant of BankHeist-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/BankHeist-v5")) def bankheist_noframeskip(): + """Fixed-length variant of BankHeistNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BankHeistNoFrameskip-v4")) def battlezone_v5(): + """Fixed-length variant of BattleZone-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/BattleZone-v5")) def battlezone_noframeskip(): + """Fixed-length variant of BattleZoneNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BattleZoneNoFrameskip-v4")) def beamrider_v5(): + """Fixed-length variant of BeamRider-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/BeamRider-v5")) def beamrider_noframeskip(): + """Fixed-length variant of BeamRiderNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BeamRiderNoFrameskip-v4")) def berzerk_v5(): + """Fixed-length variant of Berzerk-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Berzerk-v5")) def berzerk_noframeskip(): + """Fixed-length variant of BerzerkNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BerzerkNoFrameskip-v4")) def bowling_v5(): + """Fixed-length variant of Bowling-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Bowling-v5")) def bowling_noframeskip(): + """Fixed-length variant of BowlingNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BowlingNoFrameskip-v4")) def boxing_v5(): + """Fixed-length variant of Boxing-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Boxing-v5")) def boxing_noframeskip(): + """Fixed-length variant of BoxingNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BoxingNoFrameskip-v4")) def breakout_v5(): + """Fixed-length variant of Breakout-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Breakout-v5")) def breakout_noframeskip(): + """Fixed-length variant of BreakoutNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("BreakoutNoFrameskip-v4")) def carnival_v5(): + """Fixed-length variant of Carnival-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Carnival-v5")) def carnival_noframeskip(): + """Fixed-length variant of CarnivalNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("CarnivalNoFrameskip-v4")) def centipede_v5(): + """Fixed-length variant of Centipede-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Centipede-v5")) def centipede_noframeskip(): + """Fixed-length variant of CentipedeNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("CentipedeNoFrameskip-v4")) def choppercommand_v5(): + """Fixed-length variant of ChopperCommand-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/ChopperCommand-v5")) def choppercommand_noframeskip(): + """Fixed-length variant of ChopperCommandNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ChopperCommandNoFrameskip-v4")) def crazyclimber_v5(): + """Fixed-length variant of CrazyClimber-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/CrazyClimber-v5")) def crazyclimber_noframeskip(): + """Fixed-length variant of CrazyClimberNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("CrazyClimberNoFrameskip-v4")) def defender_v5(): + """Fixed-length variant of Defender-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Defender-v5")) def defender_noframeskip(): + """Fixed-length variant of DefenderNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("DefenderNoFrameskip-v4")) def demonattack_v5(): + """Fixed-length variant of DemonAttack-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/DemonAttack-v5")) def demonattack_noframeskip(): + """Fixed-length variant of DemonAttackNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("DemonAttackNoFrameskip-v4")) def doubledunk_v5(): + """Fixed-length variant of DoubleDunk-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/DoubleDunk-v5")) def doubledunk_noframeskip(): + """Fixed-length variant of DoubleDunkNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("DoubleDunkNoFrameskip-v4")) def elevatoraction_v5(): + """Fixed-length variant of ElevatorAction-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/ElevatorAction-v5")) def elevatoraction_noframeskip(): + """Fixed-length variant of ElevatorActionNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ElevatorActionNoFrameskip-v4")) def enduro_v5(): + """Fixed-length variant of Enduro-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Enduro-v5")) def enduro_noframeskip(): + """Fixed-length variant of EnduroNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("EnduroNoFrameskip-v4")) def fishingderby_v5(): + """Fixed-length variant of FishingDerby-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/FishingDerby-v5")) def fishingderby_noframeskip(): + """Fixed-length variant of FishingDerbyNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("FishingDerbyNoFrameskip-v4")) def freeway_v5(): + """Fixed-length variant of Freeway-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Freeway-v5")) def freeway_noframeskip(): + """Fixed-length variant of FreewayNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("FreewayNoFrameskip-v4")) def frostbite_v5(): + """Fixed-length variant of Frostbite-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Frostbite-v5")) def frostbite_noframeskip(): + """Fixed-length variant of FrostbiteNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("FrostbiteNoFrameskip-v4")) def gopher_v5(): + """Fixed-length variant of Gopher-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Gopher-v5")) def gopher_noframeskip(): + """Fixed-length variant of GopherNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("GopherNoFrameskip-v4")) def gravitar_v5(): + """Fixed-length variant of Gravitar-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Gravitar-v5")) def gravitar_noframeskip(): + """Fixed-length variant of GravitarNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("GravitarNoFrameskip-v4")) def hero_v5(): + """Fixed-length variant of Hero-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Hero-v5")) def hero_noframeskip(): + """Fixed-length variant of HeroNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("HeroNoFrameskip-v4")) def icehockey_v5(): + """Fixed-length variant of IceHockey-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/IceHockey-v5")) def icehockey_noframeskip(): + """Fixed-length variant of IceHockeyNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("IceHockeyNoFrameskip-v4")) def jamesbond_v5(): + """Fixed-length variant of Jamesbond-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Jamesbond-v5")) def jamesbond_noframeskip(): + """Fixed-length variant of JamesbondNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("JamesbondNoFrameskip-v4")) def journeyescape_v5(): + """Fixed-length variant of JourneyEscape-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/JourneyEscape-v5")) def journeyescape_noframeskip(): + """Fixed-length variant of JourneyEscapeNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("JourneyEscapeNoFrameskip-v4")) def kangaroo_v5(): + """Fixed-length variant of Kangaroo-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Kangaroo-v5")) def kangaroo_noframeskip(): + """Fixed-length variant of KangarooNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("KangarooNoFrameskip-v4")) def krull_v5(): + """Fixed-length variant of Krull-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Krull-v5")) def krull_noframeskip(): + """Fixed-length variant of KrullNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("KrullNoFrameskip-v4")) def kungfumaster_v5(): + """Fixed-length variant of KungFuMaster-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/KungFuMaster-v5")) def kungfumaster_noframeskip(): + """Fixed-length variant of KungFuMasterNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("KungFuMasterNoFrameskip-v4")) def montezumarevenge_v5(): + """Fixed-length variant of MontezumaRevenge-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/MontezumaRevenge-v5")) def montezumarevenge_noframeskip(): + """Fixed-length variant of MontezumaRevengeNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("MontezumaRevengeNoFrameskip-v4")) def mspacman_v5(): + """Fixed-length variant of MsPacman-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/MsPacman-v5")) def mspacman_noframeskip(): + """Fixed-length variant of MsPacmanNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("MsPacmanNoFrameskip-v4")) def namethisgame_v5(): + """Fixed-length variant of NameThisGame-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/NameThisGame-v5")) def namethisgame_noframeskip(): + """Fixed-length variant of NameThisGameNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("NameThisGameNoFrameskip-v4")) def phoenix_v5(): + """Fixed-length variant of Phoenix-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Phoenix-v5")) def phoenix_noframeskip(): + """Fixed-length variant of PhoenixNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("PhoenixNoFrameskip-v4")) def pitfall_v5(): + """Fixed-length variant of Pitfall-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Pitfall-v5")) def pitfall_noframeskip(): + """Fixed-length variant of PitfallNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("PitfallNoFrameskip-v4")) def pong_v5(): + """Fixed-length variant of Pong-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Pong-v5")) def pong_noframeskip(): + """Fixed-length variant of PongNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("PongNoFrameskip-v4")) def pooyan_v5(): + """Fixed-length variant of Pooyan-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Pooyan-v5")) def pooyan_noframeskip(): + """Fixed-length variant of PooyanNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("PooyanNoFrameskip-v4")) def privateeye_v5(): + """Fixed-length variant of PrivateEye-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/PrivateEye-v5")) def privateeye_noframeskip(): + """Fixed-length variant of PrivateEyeNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("PrivateEyeNoFrameskip-v4")) def qbert_v5(): + """Fixed-length variant of Qbert-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Qbert-v5")) def qbert_noframeskip(): + """Fixed-length variant of QbertNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("QbertNoFrameskip-v4")) def riverraid_v5(): + """Fixed-length variant of Riverraid-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Riverraid-v5")) def riverraid_noframeskip(): + """Fixed-length variant of RiverraidNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("RiverraidNoFrameskip-v4")) def roadrunner_v5(): + """Fixed-length variant of RoadRunner-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/RoadRunner-v5")) def roadrunner_noframeskip(): + """Fixed-length variant of RoadRunnerNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("RoadRunnerNoFrameskip-v4")) def robotank_v5(): + """Fixed-length variant of Robotank-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Robotank-v5")) def robotank_noframeskip(): + """Fixed-length variant of RobotankNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("RobotankNoFrameskip-v4")) def seaquest_v5(): + """Fixed-length variant of Seaquest-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Seaquest-v5")) def seaquest_noframeskip(): + """Fixed-length variant of SeaquestNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("SeaquestNoFrameskip-v4")) def skiing_v5(): + """Fixed-length variant of Skiing-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Skiing-v5")) def skiing_noframeskip(): + """Fixed-length variant of SkiingNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("SkiingNoFrameskip-v4")) def solaris_v5(): + """Fixed-length variant of Solaris-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Solaris-v5")) def solaris_noframeskip(): + """Fixed-length variant of SolarisNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("SolarisNoFrameskip-v4")) def spaceinvaders_v5(): + """Fixed-length variant of SpaceInvaders-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/SpaceInvaders-v5")) def spaceinvaders_noframeskip(): + """Fixed-length variant of SpaceInvadersNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("SpaceInvadersNoFrameskip-v4")) def stargunner_v5(): + """Fixed-length variant of StarGunner-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/StarGunner-v5")) def stargunner_noframeskip(): + """Fixed-length variant of StarGunnerNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("StarGunnerNoFrameskip-v4")) def tennis_v5(): + """Fixed-length variant of Tennis-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Tennis-v5")) def tennis_noframeskip(): + """Fixed-length variant of TennisNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("TennisNoFrameskip-v4")) def timepilot_v5(): + """Fixed-length variant of TimePilot-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/TimePilot-v5")) def timepilot_noframeskip(): + """Fixed-length variant of TimePilotNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("TimePilotNoFrameskip-v4")) def tutankham_v5(): + """Fixed-length variant of Tutankham-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Tutankham-v5")) def tutankham_noframeskip(): + """Fixed-length variant of TutankhamNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("TutankhamNoFrameskip-v4")) def upndown_v5(): + """Fixed-length variant of UpNDown-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/UpNDown-v5")) def upndown_noframeskip(): + """Fixed-length variant of UpNDownNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("UpNDownNoFrameskip-v4")) def venture_v5(): + """Fixed-length variant of Venture-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Venture-v5")) def venture_noframeskip(): + """Fixed-length variant of VentureNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("VentureNoFrameskip-v4")) def videopinball_v5(): + """Fixed-length variant of VideoPinball-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/VideoPinball-v5")) def videopinball_noframeskip(): + """Fixed-length variant of VideoPinballNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("VideoPinballNoFrameskip-v4")) def wizardofwor_v5(): + """Fixed-length variant of WizardOfWor-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/WizardOfWor-v5")) def wizardofwor_noframeskip(): + """Fixed-length variant of WizardOfWorNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("WizardOfWorNoFrameskip-v4")) def yarsrevenge_v5(): + """Fixed-length variant of YarsRevenge-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/YarsRevenge-v5")) def yarsrevenge_noframeskip(): + """Fixed-length variant of YarsRevengeNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("YarsRevengeNoFrameskip-v4")) def zaxxon_v5(): + """Fixed-length variant of Zaxxon-v5. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ALE/Zaxxon-v5")) def zaxxon_noframeskip(): + """Fixed-length variant of ZaxxonNoFrameskip-v4. + + When the environment would terminate, it instead resets. If wrapping with a further + preprocessing wrapper, make sure to not terminate on life loss, since that would + break the constant episode length property. + """ return AutoResetWrapper(gym.make("ZaxxonNoFrameskip-v4")) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 590fd3a..3f91499 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -177,7 +177,7 @@ def different_seeds_same_rollout(seed1, seed2): return has_same_observations(new_rollout_1, new_rollout_2) is_deterministic = matches_list(env_name, deterministic_envs) - num_seeds = 100 if not matches_list(env_name, few_check_envs) else 3 + num_seeds = 100 if not matches_list(env_name, few_check_envs) else 2 same_obs = all( different_seeds_same_rollout(seed, seed + 1) for seed in range(num_seeds) ) @@ -221,6 +221,8 @@ def test_rollout_schema( episode termination. This is an abuse of the Gym API, but we would like the environments to handle this case gracefully. max_steps: Test fails if we do not get `done` after this many timesteps. + check_episode_ends: Check that episode ends after `max_steps` steps, and that + steps taken after `done` is true are of the correct type. Raises: AssertionError if test fails. From 8f1d3a2f7587e6e38ca05849c540807ca0da052b Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Wed, 24 Aug 2022 18:39:58 -0700 Subject: [PATCH 03/21] Add atari dependencies for testing --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 214382a..4e715f8 100644 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ def get_readme() -> str: # recommended packages for development "dev": ["ipdb", "jupyter", *TESTS_REQUIRE, *DOCS_REQUIRE, *ATARI_REQUIRE], "docs": DOCS_REQUIRE, - "test": TESTS_REQUIRE, + "test": TESTS_REQUIRE + ATARI_REQUIRE, # We'd like to specify `gym[mujoco]`, but this is a no-op when Gym is already # installed. See https://github.com/pypa/pip/issues/4957 for issue. "mujoco": ["mujoco_py>=1.50, <2.0", "imageio"], From 5d8c44069e875c6ee79928753f3aa5efcc48e01e Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 10:53:15 -0700 Subject: [PATCH 04/21] Simplify boolean check Co-authored-by: Juan Rocamonde --- src/seals/testing/envs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 3f91499..d4b66a0 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -237,7 +237,7 @@ def test_rollout_schema( break if check_episode_ends: - assert done is True, "did not get to end of episode" + assert done, "did not get to end of episode" for _ in range(steps_after_done): _sample_and_check(env, obs_space) From 976630153a50a50a86c7000818e0bff02d95c000 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 10:56:17 -0700 Subject: [PATCH 05/21] Demand result of env.seed be a list or tuple --- src/seals/testing/envs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 3f91499..9460c2c 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -4,7 +4,6 @@ projects such as `imitation`, and may be useful in other codebases. """ -import collections import re from typing import ( Any, @@ -156,7 +155,7 @@ def test_seed( actions = [env.action_space.sample() for _ in range(10)] # With the same seed, should always get the same result seeds = env.seed(42) - assert isinstance(seeds, collections.abc.Sequence) + assert isinstance(seeds, (list, tuple)) assert len(seeds) > 0 rollout_a = get_rollout(env, actions) From af70b75860c90a161221334f25cee4a50e20dc89 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 11:06:21 -0700 Subject: [PATCH 06/21] Add documentation for why atari is treated differently in tests --- tests/test_envs.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/test_envs.py b/tests/test_envs.py index 003b63f..c10b1c0 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -43,7 +43,12 @@ class TestEnvs: """Battery of simple tests for environments.""" def test_seed(self, env: gym.Env, env_name: str): - """Tests environment seeding.""" + """Tests environment seeding. + + Deterministic atari environments are run with fewer seeds to minimize the number + of resets done in this test suite, since atari resets take a long time and there + are many atari environments. + """ envs.test_seed(env, env_name, DETERMINISTIC_ENVS, ATARI_NO_FRAMESKIP_ENVS) def test_premature_step(self, env: gym.Env): @@ -53,7 +58,12 @@ def test_premature_step(self, env: gym.Env): # if env is atari then don't wait until done else do normal thing # or maybe force done=True? def test_rollout_schema(self, env: gym.Env, env_name: str): - """Tests if environments have correct types on `step()` and `reset()`.""" + """Tests if environments have correct types on `step()` and `reset()`. + + Atari environments have a very long episode length (~100k observations), so in + the interest of time we do not run them to the end of their episodes or check + the return time of `env.step` after the end of the episode. + """ if env_name in ATARI_ENVS: envs.test_rollout_schema(env, max_steps=1_000, check_episode_ends=False) else: From e5162d7c36d1be55fb06d061dae39dadb5e097da Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 11:25:19 -0700 Subject: [PATCH 07/21] clarify why we check that env.seed returns a list or tuple --- src/seals/testing/envs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 8d07ad7..3808665 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -156,6 +156,7 @@ def test_seed( # With the same seed, should always get the same result seeds = env.seed(42) assert isinstance(seeds, (list, tuple)) + # output of env.seed should be a list, but atari environments return a tuple. assert len(seeds) > 0 rollout_a = get_rollout(env, actions) From cbef7d2a959505fdee9a4001c2fd435981c58ce1 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 12:11:50 -0700 Subject: [PATCH 08/21] Parametrize test_seed --- src/seals/testing/envs.py | 8 ++++---- tests/test_envs.py | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 3808665..36dd7b7 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -141,7 +141,8 @@ def test_seed( env: gym.Env, env_name: str, deterministic_envs: Iterable[str], - few_check_envs: Iterable[str], + rollout_len: int = 10, + num_seeds: int = 100, ) -> None: """Tests environment seeding. @@ -152,7 +153,7 @@ def test_seed( AssertionError if test fails. """ env.action_space.seed(0) - actions = [env.action_space.sample() for _ in range(10)] + actions = [env.action_space.sample() for _ in range(rollout_len)] # With the same seed, should always get the same result seeds = env.seed(42) assert isinstance(seeds, (list, tuple)) @@ -169,7 +170,7 @@ def test_seed( # eventually get a different result. For deterministic environments, all # seeds should produce the same starting state. def different_seeds_same_rollout(seed1, seed2): - new_actions = [env.action_space.sample() for _ in range(100)] + new_actions = [env.action_space.sample() for _ in range(rollout_len)] env.seed(seed1) new_rollout_1 = get_rollout(env, new_actions) env.seed(seed2) @@ -177,7 +178,6 @@ def different_seeds_same_rollout(seed1, seed2): return has_same_observations(new_rollout_1, new_rollout_2) is_deterministic = matches_list(env_name, deterministic_envs) - num_seeds = 100 if not matches_list(env_name, few_check_envs) else 2 same_obs = all( different_seeds_same_rollout(seed, seed + 1) for seed in range(num_seeds) ) diff --git a/tests/test_envs.py b/tests/test_envs.py index c10b1c0..d164d81 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -49,7 +49,22 @@ def test_seed(self, env: gym.Env, env_name: str): of resets done in this test suite, since atari resets take a long time and there are many atari environments. """ - envs.test_seed(env, env_name, DETERMINISTIC_ENVS, ATARI_NO_FRAMESKIP_ENVS) + if env_name in ATARI_ENVS: + rollout_len = ( + 100 + if env_name not in ["seals/Bowling-v5", "seals/NameThisGame-v5"] + else 400 + ) + num_seeds = 2 if env_name in ATARI_NO_FRAMESKIP_ENVS else 10 + envs.test_seed( + env, + env_name, + DETERMINISTIC_ENVS, + rollout_len=rollout_len, + num_seeds=num_seeds, + ) + else: + envs.test_seed(env, env_name, DETERMINISTIC_ENVS) def test_premature_step(self, env: gym.Env): """Tests if step() before reset() raises error.""" From 64203c4d6a01ee7af09047b0e6a7efee913a7b1c Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Thu, 25 Aug 2022 12:18:33 -0700 Subject: [PATCH 09/21] Explain why Bowling and NameThisGame are different --- tests/test_envs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_envs.py b/tests/test_envs.py index d164d81..ebe34d2 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -55,6 +55,7 @@ def test_seed(self, env: gym.Env, env_name: str): if env_name not in ["seals/Bowling-v5", "seals/NameThisGame-v5"] else 400 ) + # those two environments take a while for their non-determinism to show. num_seeds = 2 if env_name in ATARI_NO_FRAMESKIP_ENVS else 10 envs.test_seed( env, From e48d4178ebe95b206eb82c26c8ba54edd369fd66 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Tue, 30 Aug 2022 15:56:12 -0700 Subject: [PATCH 10/21] Tidy code, clarify README --- README.md | 2 +- setup.py | 17 +++++++++-------- src/seals/testing/envs.py | 2 +- tests/test_envs.py | 11 +++-------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6a4294a..b511588 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ There are two types of environments in *seals*: - **Diagnostic Tasks** which test individual facets of algorithm performance in isolation. - **Renovated Environments**, adaptations of widely-used benchmarks such as MuJoCo continuous control tasks and Atari games to be suitable for specification learning benchmarks. In particular, - we remove any side-channel sources of reward information. + we remove any side-channel sources of reward information from Mujoco tasks, and give Atari games constant-length episodes (although most Atari environments have observations that include the score). *seals* is under active development and we intend to add more categories of tasks soon. diff --git a/setup.py b/setup.py index 4e715f8..7b32d85 100644 --- a/setup.py +++ b/setup.py @@ -27,6 +27,12 @@ def get_readme() -> str: return f.read() +ATARI_REQUIRE = [ + "opencv-python", + "ale-py==0.7.4", + "pillow", + "autorom[accept-rom-license]~=0.4.2", +] TESTS_REQUIRE = [ # remove pin once https://github.com/nedbat/coveragepy/issues/881 fixed "black", @@ -50,6 +56,7 @@ def get_readme() -> str: "pytype", "stable-baselines3>=0.9.0", "pyglet>=1.4.0", + *ATARI_REQUIRE, ] DOCS_REQUIRE = [ "sphinx", @@ -57,12 +64,6 @@ def get_readme() -> str: "sphinx-rtd-theme", "sphinxcontrib-napoleon", ] -ATARI_REQUIRE = [ - "opencv-python", - "ale-py==0.7.4", - "pillow", - "autorom[accept-rom-license]~=0.4.2", -] setup( @@ -80,9 +81,9 @@ def get_readme() -> str: tests_require=TESTS_REQUIRE, extras_require={ # recommended packages for development - "dev": ["ipdb", "jupyter", *TESTS_REQUIRE, *DOCS_REQUIRE, *ATARI_REQUIRE], + "dev": ["ipdb", "jupyter", *TESTS_REQUIRE, *DOCS_REQUIRE], "docs": DOCS_REQUIRE, - "test": TESTS_REQUIRE + ATARI_REQUIRE, + "test": TESTS_REQUIRE, # We'd like to specify `gym[mujoco]`, but this is a no-op when Gym is already # installed. See https://github.com/pypa/pip/issues/4957 for issue. "mujoco": ["mujoco_py>=1.50, <2.0", "imageio"], diff --git a/src/seals/testing/envs.py b/src/seals/testing/envs.py index 36dd7b7..a927a50 100644 --- a/src/seals/testing/envs.py +++ b/src/seals/testing/envs.py @@ -156,8 +156,8 @@ def test_seed( actions = [env.action_space.sample() for _ in range(rollout_len)] # With the same seed, should always get the same result seeds = env.seed(42) - assert isinstance(seeds, (list, tuple)) # output of env.seed should be a list, but atari environments return a tuple. + assert isinstance(seeds, (list, tuple)) assert len(seeds) > 0 rollout_a = get_rollout(env, actions) diff --git a/tests/test_envs.py b/tests/test_envs.py index ebe34d2..dfbd61f 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -50,12 +50,9 @@ def test_seed(self, env: gym.Env, env_name: str): are many atari environments. """ if env_name in ATARI_ENVS: - rollout_len = ( - 100 - if env_name not in ["seals/Bowling-v5", "seals/NameThisGame-v5"] - else 400 - ) - # those two environments take a while for their non-determinism to show. + # these two environments take a while for their non-determinism to show. + slow_random_envs = ["seals/Bowling-v5", "seals/NameThisGame-v5"] + rollout_len = 100 if env_name not in slow_random_envs else 400 num_seeds = 2 if env_name in ATARI_NO_FRAMESKIP_ENVS else 10 envs.test_seed( env, @@ -71,8 +68,6 @@ def test_premature_step(self, env: gym.Env): """Tests if step() before reset() raises error.""" envs.test_premature_step(env, skip_fn=pytest.skip, raises_fn=pytest.raises) - # if env is atari then don't wait until done else do normal thing - # or maybe force done=True? def test_rollout_schema(self, env: gym.Env, env_name: str): """Tests if environments have correct types on `step()` and `reset()`. From ab9ac74d26c61af5fb53e60b9b2a023e5710a140 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Tue, 30 Aug 2022 18:17:39 -0700 Subject: [PATCH 11/21] Pull atari envs from gym registry, rather than hard-coding --- src/seals/__init__.py | 115 ++-- src/seals/atari.py | 1241 +---------------------------------------- tests/test_envs.py | 43 +- 3 files changed, 77 insertions(+), 1322 deletions(-) diff --git a/src/seals/__init__.py b/src/seals/__init__.py index a1218d1..aca46a5 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -31,80 +31,45 @@ # Atari -ATARI_ENV_NAMES = [ - "Adventure", - "AirRaid", - "Alien", - "Amidar", - "Assault", - "Asterix", - "Asteroids", - "Atlantis", - "BankHeist", - "BattleZone", - "BeamRider", - "Berzerk", - "Bowling", - "Boxing", - "Breakout", - "Carnival", - "Centipede", - "ChopperCommand", - "CrazyClimber", - "Defender", - "DemonAttack", - "DoubleDunk", - "ElevatorAction", - "Enduro", - "FishingDerby", - "Freeway", - "Frostbite", - "Gopher", - "Gravitar", - "Hero", - "IceHockey", - "Jamesbond", - "JourneyEscape", - "Kangaroo", - "Krull", - "KungFuMaster", - "MontezumaRevenge", - "MsPacman", - "NameThisGame", - "Phoenix", - "Pitfall", - "Pong", - "Pooyan", - "PrivateEye", - "Qbert", - "Riverraid", - "RoadRunner", - "Robotank", - "Seaquest", - "Skiing", - "Solaris", - "SpaceInvaders", - "StarGunner", - "Tennis", - "TimePilot", - "Tutankham", - "UpNDown", - "Venture", - "VideoPinball", - "WizardOfWor", - "YarsRevenge", - "Zaxxon", + +def _not_ram_or_det(env_id): + slash_separated = env_id.split("/") + # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" + assert len(slash_separated) in [1, 2] + after_slash = slash_separated[-1] + hyphen_separated = after_slash.split("-") + assert len(hyphen_separated) > 1 + not_ram = not ("ram" in hyphen_separated[1]) + not_deterministic = not ("Deterministic" in env_id) + return not_ram and not_deterministic + + +def _supported_atari_env(gym_spec): + is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv" + v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id) + v4_and_no_frameskip = gym_spec.id.endswith("-v4") and "NoFrameskip" in gym_spec.id + return ( + is_atari + and _not_ram_or_det(gym_spec.id) + and (v5_and_plain or v4_and_no_frameskip) + ) + + +# not a filter so that it doesn't update during the for loop below. +GYM_ATARI_ENV_SPECS = [ + gym_spec for gym_spec in gym.envs.registry.all() if _supported_atari_env(gym_spec) ] -for env_name in ATARI_ENV_NAMES: - for frameskip in [True, False]: - seals_name = "seals/" + env_name + ("-v5" if frameskip else "NoFrameskip-v4") - func_name = env_name.lower() + ("_v5" if frameskip else "_noframeskip") - gym_name = ( - ("ALE/" + env_name + "-v5") if frameskip else (env_name + "NoFrameskip-v4") - ) - gym.register( - id=seals_name, - entry_point=f"seals.atari:{func_name}", - max_episode_steps=util.get_gym_max_episode_steps(gym_name), - ) + +def _seals_name(gym_spec): + slash_separated = gym_spec.id.split("/") + return "seals/" + slash_separated[-1] + + +for gym_spec in GYM_ATARI_ENV_SPECS: + gym.register( + id=_seals_name(gym_spec), + entry_point="seals.atari:fixed_length_atari", + max_episode_steps=util.get_gym_max_episode_steps(gym_spec.id), + kwargs=dict(atari_env_id=gym_spec.id), + ) diff --git a/src/seals/atari.py b/src/seals/atari.py index 88774b6..90b2047 100644 --- a/src/seals/atari.py +++ b/src/seals/atari.py @@ -5,1241 +5,6 @@ from seals.util import AutoResetWrapper -def adventure_v5(): - """Fixed-length variant of Adventure-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Adventure-v5")) - - -def adventure_noframeskip(): - """Fixed-length variant of AdventureNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AdventureNoFrameskip-v4")) - - -def airraid_v5(): - """Fixed-length variant of AirRaid-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/AirRaid-v5")) - - -def airraid_noframeskip(): - """Fixed-length variant of AirRaidNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AirRaidNoFrameskip-v4")) - - -def alien_v5(): - """Fixed-length variant of Alien-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Alien-v5")) - - -def alien_noframeskip(): - """Fixed-length variant of AlienNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AlienNoFrameskip-v4")) - - -def amidar_v5(): - """Fixed-length variant of Amidar-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Amidar-v5")) - - -def amidar_noframeskip(): - """Fixed-length variant of AmidarNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AmidarNoFrameskip-v4")) - - -def assault_v5(): - """Fixed-length variant of Assault-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Assault-v5")) - - -def assault_noframeskip(): - """Fixed-length variant of AssaultNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AssaultNoFrameskip-v4")) - - -def asterix_v5(): - """Fixed-length variant of Asterix-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Asterix-v5")) - - -def asterix_noframeskip(): - """Fixed-length variant of AsterixNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AsterixNoFrameskip-v4")) - - -def asteroids_v5(): - """Fixed-length variant of Asteroids-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Asteroids-v5")) - - -def asteroids_noframeskip(): - """Fixed-length variant of AsteroidsNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AsteroidsNoFrameskip-v4")) - - -def atlantis_v5(): - """Fixed-length variant of Atlantis-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Atlantis-v5")) - - -def atlantis_noframeskip(): - """Fixed-length variant of AtlantisNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("AtlantisNoFrameskip-v4")) - - -def bankheist_v5(): - """Fixed-length variant of BankHeist-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/BankHeist-v5")) - - -def bankheist_noframeskip(): - """Fixed-length variant of BankHeistNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BankHeistNoFrameskip-v4")) - - -def battlezone_v5(): - """Fixed-length variant of BattleZone-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/BattleZone-v5")) - - -def battlezone_noframeskip(): - """Fixed-length variant of BattleZoneNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BattleZoneNoFrameskip-v4")) - - -def beamrider_v5(): - """Fixed-length variant of BeamRider-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/BeamRider-v5")) - - -def beamrider_noframeskip(): - """Fixed-length variant of BeamRiderNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BeamRiderNoFrameskip-v4")) - - -def berzerk_v5(): - """Fixed-length variant of Berzerk-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Berzerk-v5")) - - -def berzerk_noframeskip(): - """Fixed-length variant of BerzerkNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BerzerkNoFrameskip-v4")) - - -def bowling_v5(): - """Fixed-length variant of Bowling-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Bowling-v5")) - - -def bowling_noframeskip(): - """Fixed-length variant of BowlingNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BowlingNoFrameskip-v4")) - - -def boxing_v5(): - """Fixed-length variant of Boxing-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Boxing-v5")) - - -def boxing_noframeskip(): - """Fixed-length variant of BoxingNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BoxingNoFrameskip-v4")) - - -def breakout_v5(): - """Fixed-length variant of Breakout-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Breakout-v5")) - - -def breakout_noframeskip(): - """Fixed-length variant of BreakoutNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("BreakoutNoFrameskip-v4")) - - -def carnival_v5(): - """Fixed-length variant of Carnival-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Carnival-v5")) - - -def carnival_noframeskip(): - """Fixed-length variant of CarnivalNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("CarnivalNoFrameskip-v4")) - - -def centipede_v5(): - """Fixed-length variant of Centipede-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Centipede-v5")) - - -def centipede_noframeskip(): - """Fixed-length variant of CentipedeNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("CentipedeNoFrameskip-v4")) - - -def choppercommand_v5(): - """Fixed-length variant of ChopperCommand-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/ChopperCommand-v5")) - - -def choppercommand_noframeskip(): - """Fixed-length variant of ChopperCommandNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ChopperCommandNoFrameskip-v4")) - - -def crazyclimber_v5(): - """Fixed-length variant of CrazyClimber-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/CrazyClimber-v5")) - - -def crazyclimber_noframeskip(): - """Fixed-length variant of CrazyClimberNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("CrazyClimberNoFrameskip-v4")) - - -def defender_v5(): - """Fixed-length variant of Defender-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Defender-v5")) - - -def defender_noframeskip(): - """Fixed-length variant of DefenderNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("DefenderNoFrameskip-v4")) - - -def demonattack_v5(): - """Fixed-length variant of DemonAttack-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/DemonAttack-v5")) - - -def demonattack_noframeskip(): - """Fixed-length variant of DemonAttackNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("DemonAttackNoFrameskip-v4")) - - -def doubledunk_v5(): - """Fixed-length variant of DoubleDunk-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/DoubleDunk-v5")) - - -def doubledunk_noframeskip(): - """Fixed-length variant of DoubleDunkNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("DoubleDunkNoFrameskip-v4")) - - -def elevatoraction_v5(): - """Fixed-length variant of ElevatorAction-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/ElevatorAction-v5")) - - -def elevatoraction_noframeskip(): - """Fixed-length variant of ElevatorActionNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ElevatorActionNoFrameskip-v4")) - - -def enduro_v5(): - """Fixed-length variant of Enduro-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Enduro-v5")) - - -def enduro_noframeskip(): - """Fixed-length variant of EnduroNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("EnduroNoFrameskip-v4")) - - -def fishingderby_v5(): - """Fixed-length variant of FishingDerby-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/FishingDerby-v5")) - - -def fishingderby_noframeskip(): - """Fixed-length variant of FishingDerbyNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("FishingDerbyNoFrameskip-v4")) - - -def freeway_v5(): - """Fixed-length variant of Freeway-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Freeway-v5")) - - -def freeway_noframeskip(): - """Fixed-length variant of FreewayNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("FreewayNoFrameskip-v4")) - - -def frostbite_v5(): - """Fixed-length variant of Frostbite-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Frostbite-v5")) - - -def frostbite_noframeskip(): - """Fixed-length variant of FrostbiteNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("FrostbiteNoFrameskip-v4")) - - -def gopher_v5(): - """Fixed-length variant of Gopher-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Gopher-v5")) - - -def gopher_noframeskip(): - """Fixed-length variant of GopherNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("GopherNoFrameskip-v4")) - - -def gravitar_v5(): - """Fixed-length variant of Gravitar-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Gravitar-v5")) - - -def gravitar_noframeskip(): - """Fixed-length variant of GravitarNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("GravitarNoFrameskip-v4")) - - -def hero_v5(): - """Fixed-length variant of Hero-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Hero-v5")) - - -def hero_noframeskip(): - """Fixed-length variant of HeroNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("HeroNoFrameskip-v4")) - - -def icehockey_v5(): - """Fixed-length variant of IceHockey-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/IceHockey-v5")) - - -def icehockey_noframeskip(): - """Fixed-length variant of IceHockeyNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("IceHockeyNoFrameskip-v4")) - - -def jamesbond_v5(): - """Fixed-length variant of Jamesbond-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Jamesbond-v5")) - - -def jamesbond_noframeskip(): - """Fixed-length variant of JamesbondNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("JamesbondNoFrameskip-v4")) - - -def journeyescape_v5(): - """Fixed-length variant of JourneyEscape-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/JourneyEscape-v5")) - - -def journeyescape_noframeskip(): - """Fixed-length variant of JourneyEscapeNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("JourneyEscapeNoFrameskip-v4")) - - -def kangaroo_v5(): - """Fixed-length variant of Kangaroo-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Kangaroo-v5")) - - -def kangaroo_noframeskip(): - """Fixed-length variant of KangarooNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("KangarooNoFrameskip-v4")) - - -def krull_v5(): - """Fixed-length variant of Krull-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Krull-v5")) - - -def krull_noframeskip(): - """Fixed-length variant of KrullNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("KrullNoFrameskip-v4")) - - -def kungfumaster_v5(): - """Fixed-length variant of KungFuMaster-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/KungFuMaster-v5")) - - -def kungfumaster_noframeskip(): - """Fixed-length variant of KungFuMasterNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("KungFuMasterNoFrameskip-v4")) - - -def montezumarevenge_v5(): - """Fixed-length variant of MontezumaRevenge-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/MontezumaRevenge-v5")) - - -def montezumarevenge_noframeskip(): - """Fixed-length variant of MontezumaRevengeNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("MontezumaRevengeNoFrameskip-v4")) - - -def mspacman_v5(): - """Fixed-length variant of MsPacman-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/MsPacman-v5")) - - -def mspacman_noframeskip(): - """Fixed-length variant of MsPacmanNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("MsPacmanNoFrameskip-v4")) - - -def namethisgame_v5(): - """Fixed-length variant of NameThisGame-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/NameThisGame-v5")) - - -def namethisgame_noframeskip(): - """Fixed-length variant of NameThisGameNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("NameThisGameNoFrameskip-v4")) - - -def phoenix_v5(): - """Fixed-length variant of Phoenix-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Phoenix-v5")) - - -def phoenix_noframeskip(): - """Fixed-length variant of PhoenixNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("PhoenixNoFrameskip-v4")) - - -def pitfall_v5(): - """Fixed-length variant of Pitfall-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Pitfall-v5")) - - -def pitfall_noframeskip(): - """Fixed-length variant of PitfallNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("PitfallNoFrameskip-v4")) - - -def pong_v5(): - """Fixed-length variant of Pong-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Pong-v5")) - - -def pong_noframeskip(): - """Fixed-length variant of PongNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("PongNoFrameskip-v4")) - - -def pooyan_v5(): - """Fixed-length variant of Pooyan-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Pooyan-v5")) - - -def pooyan_noframeskip(): - """Fixed-length variant of PooyanNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("PooyanNoFrameskip-v4")) - - -def privateeye_v5(): - """Fixed-length variant of PrivateEye-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/PrivateEye-v5")) - - -def privateeye_noframeskip(): - """Fixed-length variant of PrivateEyeNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("PrivateEyeNoFrameskip-v4")) - - -def qbert_v5(): - """Fixed-length variant of Qbert-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Qbert-v5")) - - -def qbert_noframeskip(): - """Fixed-length variant of QbertNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("QbertNoFrameskip-v4")) - - -def riverraid_v5(): - """Fixed-length variant of Riverraid-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Riverraid-v5")) - - -def riverraid_noframeskip(): - """Fixed-length variant of RiverraidNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("RiverraidNoFrameskip-v4")) - - -def roadrunner_v5(): - """Fixed-length variant of RoadRunner-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/RoadRunner-v5")) - - -def roadrunner_noframeskip(): - """Fixed-length variant of RoadRunnerNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("RoadRunnerNoFrameskip-v4")) - - -def robotank_v5(): - """Fixed-length variant of Robotank-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Robotank-v5")) - - -def robotank_noframeskip(): - """Fixed-length variant of RobotankNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("RobotankNoFrameskip-v4")) - - -def seaquest_v5(): - """Fixed-length variant of Seaquest-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Seaquest-v5")) - - -def seaquest_noframeskip(): - """Fixed-length variant of SeaquestNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("SeaquestNoFrameskip-v4")) - - -def skiing_v5(): - """Fixed-length variant of Skiing-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Skiing-v5")) - - -def skiing_noframeskip(): - """Fixed-length variant of SkiingNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("SkiingNoFrameskip-v4")) - - -def solaris_v5(): - """Fixed-length variant of Solaris-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Solaris-v5")) - - -def solaris_noframeskip(): - """Fixed-length variant of SolarisNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("SolarisNoFrameskip-v4")) - - -def spaceinvaders_v5(): - """Fixed-length variant of SpaceInvaders-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/SpaceInvaders-v5")) - - -def spaceinvaders_noframeskip(): - """Fixed-length variant of SpaceInvadersNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("SpaceInvadersNoFrameskip-v4")) - - -def stargunner_v5(): - """Fixed-length variant of StarGunner-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/StarGunner-v5")) - - -def stargunner_noframeskip(): - """Fixed-length variant of StarGunnerNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("StarGunnerNoFrameskip-v4")) - - -def tennis_v5(): - """Fixed-length variant of Tennis-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Tennis-v5")) - - -def tennis_noframeskip(): - """Fixed-length variant of TennisNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("TennisNoFrameskip-v4")) - - -def timepilot_v5(): - """Fixed-length variant of TimePilot-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/TimePilot-v5")) - - -def timepilot_noframeskip(): - """Fixed-length variant of TimePilotNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("TimePilotNoFrameskip-v4")) - - -def tutankham_v5(): - """Fixed-length variant of Tutankham-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Tutankham-v5")) - - -def tutankham_noframeskip(): - """Fixed-length variant of TutankhamNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("TutankhamNoFrameskip-v4")) - - -def upndown_v5(): - """Fixed-length variant of UpNDown-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/UpNDown-v5")) - - -def upndown_noframeskip(): - """Fixed-length variant of UpNDownNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("UpNDownNoFrameskip-v4")) - - -def venture_v5(): - """Fixed-length variant of Venture-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Venture-v5")) - - -def venture_noframeskip(): - """Fixed-length variant of VentureNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("VentureNoFrameskip-v4")) - - -def videopinball_v5(): - """Fixed-length variant of VideoPinball-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/VideoPinball-v5")) - - -def videopinball_noframeskip(): - """Fixed-length variant of VideoPinballNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("VideoPinballNoFrameskip-v4")) - - -def wizardofwor_v5(): - """Fixed-length variant of WizardOfWor-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/WizardOfWor-v5")) - - -def wizardofwor_noframeskip(): - """Fixed-length variant of WizardOfWorNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("WizardOfWorNoFrameskip-v4")) - - -def yarsrevenge_v5(): - """Fixed-length variant of YarsRevenge-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/YarsRevenge-v5")) - - -def yarsrevenge_noframeskip(): - """Fixed-length variant of YarsRevengeNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("YarsRevengeNoFrameskip-v4")) - - -def zaxxon_v5(): - """Fixed-length variant of Zaxxon-v5. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ALE/Zaxxon-v5")) - - -def zaxxon_noframeskip(): - """Fixed-length variant of ZaxxonNoFrameskip-v4. - - When the environment would terminate, it instead resets. If wrapping with a further - preprocessing wrapper, make sure to not terminate on life loss, since that would - break the constant episode length property. - """ - return AutoResetWrapper(gym.make("ZaxxonNoFrameskip-v4")) +def fixed_length_atari(atari_env_id): + """Fixed-length variant of a given atari environment.""" + return AutoResetWrapper(gym.make(atari_env_id)) diff --git a/tests/test_envs.py b/tests/test_envs.py index dfbd61f..61e0656 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -15,6 +15,8 @@ if env_spec.id.startswith("seals/") ] +# TODO: add test that atari envs contain some things, like asteroids + DETERMINISTIC_ENVS: List[str] = [ "seals/EarlyTermPos-v0", "seals/EarlyTermNeg-v0", @@ -23,21 +25,38 @@ "seals/InitShiftTest-v0", ] -ATARI_V5_ENVS: List[str] = [ - "seals/" + env_name + "-v5" for env_name in seals.ATARI_ENV_NAMES -] -ATARI_NO_FRAMESKIP_ENVS: List[str] = [ - "seals/" + env_name + "NoFrameskip-v4" for env_name in seals.ATARI_ENV_NAMES +ATARI_ENVS: List[str] = [ + seals._seals_name(gym_spec) for gym_spec in seals.GYM_ATARI_ENV_SPECS ] -DETERMINISTIC_ENVS += ATARI_NO_FRAMESKIP_ENVS +ATARI_V5_ENVS: List[str] = list(filter(lambda name: name.endswith("-v5"), ATARI_ENVS)) +ATARI_NO_FRAMESKIP_ENVS: List[str] = list( + filter(lambda name: name.endswith("-v4"), ATARI_ENVS), +) -ATARI_ENVS: List[str] = ATARI_V5_ENVS + ATARI_NO_FRAMESKIP_ENVS +DETERMINISTIC_ENVS += ATARI_NO_FRAMESKIP_ENVS env = pytest.fixture(envs.make_env_fixture(skip_fn=pytest.skip)) +def test_some_atari_envs(): + """Tests if we succeeded in finding any atari envs.""" + assert len(seals.GYM_ATARI_ENV_SPECS) > 0 + + +def test_atari_space_invaders(): + """Tests if there's an atari environment called space invaders.""" + space_invader_environments = filter( + lambda name: "SpaceInvaders" in name, ATARI_ENVS, + ) + try: + dummy_env = next(space_invader_environments) + locals() + except StopIteration: + assert False + + @pytest.mark.parametrize("env_name", ENV_NAMES) class TestEnvs: """Battery of simple tests for environments.""" @@ -50,8 +69,14 @@ def test_seed(self, env: gym.Env, env_name: str): are many atari environments. """ if env_name in ATARI_ENVS: - # these two environments take a while for their non-determinism to show. - slow_random_envs = ["seals/Bowling-v5", "seals/NameThisGame-v5"] + # these environments take a while for their non-determinism to show. + slow_random_envs = [ + "seals/Bowling-v5", + "seals/Frogger-v5", + "seals/KingKong-v5", + "seals/Koolaid-v5", + "seals/NameThisGame-v5", + ] rollout_len = 100 if env_name not in slow_random_envs else 400 num_seeds = 2 if env_name in ATARI_NO_FRAMESKIP_ENVS else 10 envs.test_seed( From 50b473bbd31c950fc04ac6c8ed38ddd8cdedb0bf Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Tue, 30 Aug 2022 18:21:06 -0700 Subject: [PATCH 12/21] Fix formatting of test_envs --- tests/test_envs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_envs.py b/tests/test_envs.py index 61e0656..a2f0885 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -48,7 +48,8 @@ def test_some_atari_envs(): def test_atari_space_invaders(): """Tests if there's an atari environment called space invaders.""" space_invader_environments = filter( - lambda name: "SpaceInvaders" in name, ATARI_ENVS, + lambda name: "SpaceInvaders" in name, + ATARI_ENVS, ) try: dummy_env = next(space_invader_environments) From 1e37723d7cd5696507650e28dc681756ca116c70 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:09:25 -0700 Subject: [PATCH 13/21] Fix spelling of MuJoCo Co-authored-by: Adam Gleave --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b511588..7af6766 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ There are two types of environments in *seals*: - **Diagnostic Tasks** which test individual facets of algorithm performance in isolation. - **Renovated Environments**, adaptations of widely-used benchmarks such as MuJoCo continuous control tasks and Atari games to be suitable for specification learning benchmarks. In particular, - we remove any side-channel sources of reward information from Mujoco tasks, and give Atari games constant-length episodes (although most Atari environments have observations that include the score). + we remove any side-channel sources of reward information from MuJoCo tasks, and give Atari games constant-length episodes (although most Atari environments have observations that include the score). *seals* is under active development and we intend to add more categories of tasks soon. From 27d9cdb4dc7fdf4493885cb1d64b5231f51b15c5 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:10:23 -0700 Subject: [PATCH 14/21] Fix Atari capitalization Co-authored-by: Adam Gleave --- src/seals/atari.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seals/atari.py b/src/seals/atari.py index 90b2047..1dc830f 100644 --- a/src/seals/atari.py +++ b/src/seals/atari.py @@ -6,5 +6,5 @@ def fixed_length_atari(atari_env_id): - """Fixed-length variant of a given atari environment.""" + """Fixed-length variant of a given Atari environment.""" return AutoResetWrapper(gym.make(atari_env_id)) From 40c1637d81e84cce951f0a02cc7363af844ff3d8 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:11:10 -0700 Subject: [PATCH 15/21] Remove TODO --- tests/test_envs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_envs.py b/tests/test_envs.py index a2f0885..c6f454a 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -15,7 +15,6 @@ if env_spec.id.startswith("seals/") ] -# TODO: add test that atari envs contain some things, like asteroids DETERMINISTIC_ENVS: List[str] = [ "seals/EarlyTermPos-v0", From 5deca1d74ca3935f6a88da30aba69af8404b55f8 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:18:09 -0700 Subject: [PATCH 16/21] Simplify checking that filter isn't empty --- tests/test_envs.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_envs.py b/tests/test_envs.py index c6f454a..6c17b1a 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -46,15 +46,13 @@ def test_some_atari_envs(): def test_atari_space_invaders(): """Tests if there's an atari environment called space invaders.""" - space_invader_environments = filter( - lambda name: "SpaceInvaders" in name, - ATARI_ENVS, + space_invader_environments = list( + filter( + lambda name: "SpaceInvaders" in name, + ATARI_ENVS, + ), ) - try: - dummy_env = next(space_invader_environments) - locals() - except StopIteration: - assert False + assert len(space_invader_environments) > 0 @pytest.mark.parametrize("env_name", ENV_NAMES) From 9b44938434497d92dfb9b895dafd533100fd700b Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:21:16 -0700 Subject: [PATCH 17/21] Add documentation to helper methods --- src/seals/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/seals/__init__.py b/src/seals/__init__.py index aca46a5..8d7efda 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -33,6 +33,7 @@ def _not_ram_or_det(env_id): + """Checks a gym Atari environment isn't deterministic or using RAM observations.""" slash_separated = env_id.split("/") # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" assert len(slash_separated) in [1, 2] @@ -45,6 +46,7 @@ def _not_ram_or_det(env_id): def _supported_atari_env(gym_spec): + """Checks if a gym Atari environment is one of the ones we will support.""" is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv" v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id) v4_and_no_frameskip = gym_spec.id.endswith("-v4") and "NoFrameskip" in gym_spec.id @@ -62,6 +64,7 @@ def _supported_atari_env(gym_spec): def _seals_name(gym_spec): + """Makes a Gym ID for an Atari environment in the seals namespace.""" slash_separated = gym_spec.id.split("/") return "seals/" + slash_separated[-1] From 425c8d899417266b672d5371fda56870112c6296 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 19:26:52 -0700 Subject: [PATCH 18/21] Don't unnecessarily use list where tuple will do Co-authored-by: Adam Gleave --- src/seals/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seals/__init__.py b/src/seals/__init__.py index 8d7efda..008e0b4 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -36,7 +36,7 @@ def _not_ram_or_det(env_id): """Checks a gym Atari environment isn't deterministic or using RAM observations.""" slash_separated = env_id.split("/") # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" - assert len(slash_separated) in [1, 2] + assert len(slash_separated) in (1, 2) after_slash = slash_separated[-1] hyphen_separated = after_slash.split("-") assert len(hyphen_separated) > 1 From b1e70bca89fcb9d0e52574038de0c581513bf260 Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Fri, 2 Sep 2022 20:26:04 -0700 Subject: [PATCH 19/21] Move atari registration logic to atari.py --- src/seals/__init__.py | 49 +++---------------------------------------- src/seals/atari.py | 44 +++++++++++++++++++++++++++++++++++++- tests/test_envs.py | 3 ++- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/seals/__init__.py b/src/seals/__init__.py index 008e0b4..c4ef46e 100644 --- a/src/seals/__init__.py +++ b/src/seals/__init__.py @@ -2,7 +2,7 @@ import gym -from seals import util +from seals import atari, util import seals.diagnostics # noqa: F401 from seals.version import VERSION as __version__ # noqa: F401 @@ -31,48 +31,5 @@ # Atari - -def _not_ram_or_det(env_id): - """Checks a gym Atari environment isn't deterministic or using RAM observations.""" - slash_separated = env_id.split("/") - # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" - assert len(slash_separated) in (1, 2) - after_slash = slash_separated[-1] - hyphen_separated = after_slash.split("-") - assert len(hyphen_separated) > 1 - not_ram = not ("ram" in hyphen_separated[1]) - not_deterministic = not ("Deterministic" in env_id) - return not_ram and not_deterministic - - -def _supported_atari_env(gym_spec): - """Checks if a gym Atari environment is one of the ones we will support.""" - is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv" - v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id) - v4_and_no_frameskip = gym_spec.id.endswith("-v4") and "NoFrameskip" in gym_spec.id - return ( - is_atari - and _not_ram_or_det(gym_spec.id) - and (v5_and_plain or v4_and_no_frameskip) - ) - - -# not a filter so that it doesn't update during the for loop below. -GYM_ATARI_ENV_SPECS = [ - gym_spec for gym_spec in gym.envs.registry.all() if _supported_atari_env(gym_spec) -] - - -def _seals_name(gym_spec): - """Makes a Gym ID for an Atari environment in the seals namespace.""" - slash_separated = gym_spec.id.split("/") - return "seals/" + slash_separated[-1] - - -for gym_spec in GYM_ATARI_ENV_SPECS: - gym.register( - id=_seals_name(gym_spec), - entry_point="seals.atari:fixed_length_atari", - max_episode_steps=util.get_gym_max_episode_steps(gym_spec.id), - kwargs=dict(atari_env_id=gym_spec.id), - ) +GYM_ATARI_ENV_SPECS = list(filter(atari._supported_atari_env, gym.envs.registry.all())) +atari.register_atari_envs(GYM_ATARI_ENV_SPECS) diff --git a/src/seals/atari.py b/src/seals/atari.py index 1dc830f..9e90b25 100644 --- a/src/seals/atari.py +++ b/src/seals/atari.py @@ -2,9 +2,51 @@ import gym -from seals.util import AutoResetWrapper +from seals.util import AutoResetWrapper, get_gym_max_episode_steps def fixed_length_atari(atari_env_id): """Fixed-length variant of a given Atari environment.""" return AutoResetWrapper(gym.make(atari_env_id)) + + +def _not_ram_or_det(env_id): + """Checks a gym Atari environment isn't deterministic or using RAM observations.""" + slash_separated = env_id.split("/") + # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" + assert len(slash_separated) in (1, 2) + after_slash = slash_separated[-1] + hyphen_separated = after_slash.split("-") + assert len(hyphen_separated) > 1 + not_ram = not ("ram" in hyphen_separated[1]) + not_deterministic = not ("Deterministic" in env_id) + return not_ram and not_deterministic + + +def _supported_atari_env(gym_spec): + """Checks if a gym Atari environment is one of the ones we will support.""" + is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv" + v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id) + v4_and_no_frameskip = gym_spec.id.endswith("-v4") and "NoFrameskip" in gym_spec.id + return ( + is_atari + and _not_ram_or_det(gym_spec.id) + and (v5_and_plain or v4_and_no_frameskip) + ) + + +def _seals_name(gym_spec): + """Makes a Gym ID for an Atari environment in the seals namespace.""" + slash_separated = gym_spec.id.split("/") + return "seals/" + slash_separated[-1] + + +def register_atari_envs(gym_atari_env_specs): + """Register wrapped gym Atari environments.""" + for gym_spec in gym_atari_env_specs: + gym.register( + id=_seals_name(gym_spec), + entry_point="seals.atari:fixed_length_atari", + max_episode_steps=get_gym_max_episode_steps(gym_spec.id), + kwargs=dict(atari_env_id=gym_spec.id), + ) diff --git a/tests/test_envs.py b/tests/test_envs.py index 6c17b1a..c7878c7 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -7,6 +7,7 @@ import pytest import seals # noqa: F401 required for env registration +from seals.atari import _seals_name from seals.testing import envs ENV_NAMES: List[str] = [ @@ -25,7 +26,7 @@ ] ATARI_ENVS: List[str] = [ - seals._seals_name(gym_spec) for gym_spec in seals.GYM_ATARI_ENV_SPECS + _seals_name(gym_spec) for gym_spec in seals.GYM_ATARI_ENV_SPECS ] ATARI_V5_ENVS: List[str] = list(filter(lambda name: name.endswith("-v5"), ATARI_ENVS)) From 0e50cd04d6a1a20136eec5f54d227cde346a42bf Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Tue, 6 Sep 2022 14:16:41 -0700 Subject: [PATCH 20/21] Add type annotations --- src/seals/atari.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/seals/atari.py b/src/seals/atari.py index 9e90b25..ff01024 100644 --- a/src/seals/atari.py +++ b/src/seals/atari.py @@ -1,16 +1,18 @@ """Adaptation of Atari environments for specification learning algorithms.""" +from typing import Iterable + import gym from seals.util import AutoResetWrapper, get_gym_max_episode_steps -def fixed_length_atari(atari_env_id): +def fixed_length_atari(atari_env_id: str) -> gym.Env: """Fixed-length variant of a given Atari environment.""" return AutoResetWrapper(gym.make(atari_env_id)) -def _not_ram_or_det(env_id): +def _not_ram_or_det(env_id: str) -> bool: """Checks a gym Atari environment isn't deterministic or using RAM observations.""" slash_separated = env_id.split("/") # environment name should look like "ALE/Amidar-v5" or "Amidar-ramNoFrameskip-v4" @@ -23,7 +25,7 @@ def _not_ram_or_det(env_id): return not_ram and not_deterministic -def _supported_atari_env(gym_spec): +def _supported_atari_env(gym_spec: gym.envs.registration.EnvSpec) -> bool: """Checks if a gym Atari environment is one of the ones we will support.""" is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv" v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id) @@ -35,13 +37,15 @@ def _supported_atari_env(gym_spec): ) -def _seals_name(gym_spec): +def _seals_name(gym_spec: gym.envs.registration.EnvSpec) -> str: """Makes a Gym ID for an Atari environment in the seals namespace.""" slash_separated = gym_spec.id.split("/") return "seals/" + slash_separated[-1] -def register_atari_envs(gym_atari_env_specs): +def register_atari_envs( + gym_atari_env_specs: Iterable[gym.envs.registration.EnvSpec], +) -> None: """Register wrapped gym Atari environments.""" for gym_spec in gym_atari_env_specs: gym.register( From 000ca5c9a52723f46f0837db4833157da3d0c96b Mon Sep 17 00:00:00 2001 From: Daniel Filan Date: Tue, 6 Sep 2022 14:19:01 -0700 Subject: [PATCH 21/21] Fix capitalization of 'Atari' --- tests/test_envs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_envs.py b/tests/test_envs.py index c7878c7..c33e176 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -41,12 +41,12 @@ def test_some_atari_envs(): - """Tests if we succeeded in finding any atari envs.""" + """Tests if we succeeded in finding any Atari envs.""" assert len(seals.GYM_ATARI_ENV_SPECS) > 0 def test_atari_space_invaders(): - """Tests if there's an atari environment called space invaders.""" + """Tests if there's an Atari environment called space invaders.""" space_invader_environments = list( filter( lambda name: "SpaceInvaders" in name, @@ -63,9 +63,9 @@ class TestEnvs: def test_seed(self, env: gym.Env, env_name: str): """Tests environment seeding. - Deterministic atari environments are run with fewer seeds to minimize the number - of resets done in this test suite, since atari resets take a long time and there - are many atari environments. + Deterministic Atari environments are run with fewer seeds to minimize the number + of resets done in this test suite, since Atari resets take a long time and there + are many Atari environments. """ if env_name in ATARI_ENVS: # these environments take a while for their non-determinism to show.