Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
test-setup-minimal:
strategy:
matrix:
python_version: ["3.9", "3.14"]
python_version: ["3.10", "3.14"]
fail-fast: false
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
with:
Expand Down
3 changes: 3 additions & 0 deletions test/test_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3683,6 +3683,9 @@ def test_dynamic_multiasync_collector(self):
TORCH_VERSION < version.parse("2.5.0"), reason="requires Torch >= 2.5.0"
)
@pytest.mark.skipif(IS_WINDOWS, reason="windows is not supported for compile tests.")
@pytest.mark.skipif(
sys.version_info >= (3, 14), reason="torch.compile is not supported on Python 3.14+"
)
class TestCompile:
@pytest.mark.parametrize(
"collector_cls",
Expand Down
4 changes: 4 additions & 0 deletions test/test_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,10 @@ def test_ppo_trainer_config_optional_fields(self):
@pytest.mark.skipif(
not _configs_available, reason="Config system requires hydra-core and omegaconf"
)
@pytest.mark.skipif(
sys.version_info >= (3, 14),
reason="hydra-core argparse integration is not compatible with Python 3.14+",
)
class TestHydraParsing:
@pytest.fixture(autouse=True, scope="module")
def init_hydra(self):
Expand Down
3 changes: 3 additions & 0 deletions test/test_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -17875,6 +17875,9 @@ def __init__(self):
TORCH_VERSION < version.parse("2.5.0"), reason="requires torch>=2.5"
)
@pytest.mark.skipif(IS_WINDOWS, reason="windows tests do not support compile")
@pytest.mark.skipif(
sys.version_info >= (3, 14), reason="torch.compile is not supported on Python 3.14+"
)
@set_composite_lp_aggregate(False)
def test_exploration_compile():
try:
Expand Down
17 changes: 17 additions & 0 deletions test/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
pytest.mark.filterwarnings("ignore:unclosed file"),
]

_has_ale = importlib.util.find_spec("ale_py") is not None
_has_mujoco = importlib.util.find_spec("mujoco") is not None


@pytest.fixture(autouse=False) # Turn to True to enable
def check_no_lingering_multiprocessing_resources(request):
Expand Down Expand Up @@ -887,6 +890,8 @@ class TestRollout:
@pytest.mark.parametrize("env_name", [PENDULUM_VERSIONED, PONG_VERSIONED])
@pytest.mark.parametrize("frame_skip", [1, 4])
def test_rollout(self, env_name, frame_skip, seed=0):
if env_name is PONG_VERSIONED and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if env_name is PONG_VERSIONED and version.parse(
gym_backend().__version__
) < version.parse("0.19"):
Expand Down Expand Up @@ -2577,6 +2582,10 @@ class TestInfoDict:
)
@pytest.mark.parametrize("device", get_default_devices())
def test_info_dict_reader(self, device, seed=0):
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
try:
import gymnasium as gym
except ModuleNotFoundError:
Expand Down Expand Up @@ -2613,6 +2622,10 @@ def test_info_dict_reader(self, device, seed=0):
),
[Unbounded((), dtype=torch.float64)],
):
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
env2 = GymWrapper(gym.make("HalfCheetah-v5"))
env2.set_info_dict_reader(
default_info_dict_reader(["x_position"], spec=spec)
Expand All @@ -2635,6 +2648,10 @@ def test_info_dict_reader(self, device, seed=0):
)
@pytest.mark.parametrize("device", get_default_devices())
def test_auto_register(self, device, maybe_fork_ParallelEnv):
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
try:
import gymnasium as gym
except ModuleNotFoundError:
Expand Down
67 changes: 57 additions & 10 deletions test/test_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
)

_has_ray = importlib.util.find_spec("ray") is not None
_has_ale = importlib.util.find_spec("ale_py") is not None
_has_mujoco = importlib.util.find_spec("mujoco") is not None
if os.getenv("PYTORCH_TEST_FBCODE"):
from pytorch.rl.test._utils_internal import (
_make_multithreaded_env,
Expand Down Expand Up @@ -820,6 +822,13 @@ def reset(
],
)
def test_gym(self, env_name, frame_skip, from_pixels, pixels_only):
if env_name == PONG_VERSIONED() and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if env_name == HALFCHEETAH_VERSIONED() and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)

if env_name == PONG_VERSIONED() and not from_pixels:
# raise pytest.skip("already pixel")
# we don't skip because that would raise an exception
Expand Down Expand Up @@ -937,6 +946,13 @@ def non_null_obs(batched_td):
],
)
def test_gym_fake_td(self, env_name, frame_skip, from_pixels, pixels_only):
if env_name == PONG_VERSIONED() and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if env_name == HALFCHEETAH_VERSIONED() and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)

if env_name == PONG_VERSIONED() and not from_pixels:
# raise pytest.skip("already pixel")
return
Expand Down Expand Up @@ -1069,6 +1085,13 @@ def test_one_hot_and_categorical(self): # noqa: F811
def test_vecenvs_wrapper(self, envname):
import gymnasium

if envname.startswith("ALE/") and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if "HalfCheetah" in envname and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)

with set_gym_backend("gymnasium"):
self._test_vecenvs_wrapper(
envname,
Expand All @@ -1083,6 +1106,13 @@ def test_vecenvs_wrapper(self, envname):
)
@pytest.mark.flaky(reruns=5, reruns_delay=1)
def test_vecenvs_wrapper(self, envname): # noqa
if envname.startswith("ALE/") and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if "HalfCheetah" in envname and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)

with set_gym_backend("gymnasium"):
self._test_vecenvs_wrapper(envname)

Expand Down Expand Up @@ -1116,6 +1146,12 @@ def _test_vecenvs_wrapper(self, envname, kwargs=None):
)
@pytest.mark.flaky(reruns=5, reruns_delay=1)
def test_vecenvs_env(self, envname):
if envname.startswith("ALE/") and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if "HalfCheetah" in envname and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
self._test_vecenvs_env(envname)

@implement_for("gymnasium", None, "1.0.0")
Expand All @@ -1127,6 +1163,12 @@ def test_vecenvs_env(self, envname):
)
@pytest.mark.flaky(reruns=5, reruns_delay=1)
def test_vecenvs_env(self, envname): # noqa
if envname.startswith("ALE/") and not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
if "HalfCheetah" in envname and not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
self._test_vecenvs_env(envname)

def _test_vecenvs_env(self, envname):
Expand Down Expand Up @@ -1990,11 +2032,15 @@ def test_truncated(self):
[DMControlEnv, ("cheetah", "run"), {"from_pixels": False}],
]
if _has_gym:
params += [
# [GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": True}],
[GymEnv, (HALFCHEETAH_VERSIONED(),), {"from_pixels": False}],
[GymEnv, (PONG_VERSIONED(),), {}],
]
if _has_mujoco:
params += [
# [GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": True}],
[GymEnv, (HALFCHEETAH_VERSIONED(),), {"from_pixels": False}],
]
if _has_ale:
params += [
[GymEnv, (PONG_VERSIONED(),), {}],
]


@pytest.mark.skipif(
Expand Down Expand Up @@ -2037,11 +2083,12 @@ def test_td_creation_from_spec(env_lib, env_args, env_kwargs):
[DMControlEnv, ("cheetah", "run"), {"from_pixels": False}],
]
if _has_gym:
params += [
# [GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": True}],
[GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": False}],
# [GymEnv, (PONG_VERSIONED,), {}], # 1226: skipping
]
if _has_mujoco:
params += [
# [GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": True}],
[GymEnv, (HALFCHEETAH_VERSIONED,), {"from_pixels": False}],
# [GymEnv, (PONG_VERSIONED,), {}], # 1226: skipping
]


# @pytest.mark.skipif(IS_OSX, reason="rendering unstable on osx, skipping")
Expand Down
8 changes: 8 additions & 0 deletions test/test_rb.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ def data_iter():
# <https://github.com/pytorch/pytorch/blob/8231180147a096a703d8891756068c89365292e0/torch/_inductor/cpp_builder.py#L143>
# Our Windows CI jobs do not have "cl", so skip this test.
@pytest.mark.skipif(_os_is_windows, reason="windows tests do not support compile")
@pytest.mark.skipif(
sys.version_info >= (3, 14),
reason="torch.compile is not supported on Python 3.14+",
)
@pytest.mark.parametrize("avoid_max_size", [False, True])
def test_extend_sample_recompile(
self, rb_type, sampler, writer, storage, size, datatype, avoid_max_size
Expand Down Expand Up @@ -860,6 +864,10 @@ def test_storage_state_dict(self, storage_in, storage_out, init_out, backend):
TORCH_VERSION < version.parse("2.5.0"), reason="requires Torch >= 2.5.0"
)
@pytest.mark.skipif(_os_is_windows, reason="windows tests do not support compile")
@pytest.mark.skipif(
sys.version_info >= (3, 14),
reason="torch.compile is not supported on Python 3.14+",
)
# This test checks if the `torch._dynamo.disable` wrapper around
# `TensorStorage._rand_given_ndim` is still necessary.
def test__rand_given_ndim_recompile(self):
Expand Down
7 changes: 7 additions & 0 deletions test/test_trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from __future__ import annotations

import argparse
import importlib.util
import os
import tempfile
from argparse import Namespace
Expand Down Expand Up @@ -54,6 +55,8 @@
UpdateWeights,
)

_has_ale = importlib.util.find_spec("ale_py") is not None


def _fun_checker(fun, checker):
def new_fun(*args, **kwargs):
Expand Down Expand Up @@ -843,6 +846,10 @@ def test_subsampler_state_dict(self):

@pytest.mark.skipif(not _has_gym, reason="No gym library")
@pytest.mark.skipif(not _has_tb, reason="No tensorboard library")
@pytest.mark.skipif(
not _has_ale,
reason="ALE not available (missing ale_py); skipping Atari gym tests.",
)
class TestRecorder:
def _get_args(self):
args = Namespace()
Expand Down
27 changes: 27 additions & 0 deletions test/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@
)

_has_ray = importlib.util.find_spec("ray") is not None
_has_ale = importlib.util.find_spec("ale_py") is not None
_has_mujoco = importlib.util.find_spec("mujoco") is not None

IS_WIN = platform == "win32"
if IS_WIN:
Expand Down Expand Up @@ -3684,6 +3686,8 @@ def test_trans_parallel_env_check(self):
@pytest.mark.skipif(not _has_gym, reason="No Gym detected")
@pytest.mark.parametrize("out_key", [None, ["outkey"], [("out", "key")]])
def test_transform_env(self, out_key):
if not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
keys = ["pixels"]
ct = Compose(ToTensorImage(), Crop(out_keys=out_key, w=20, h=20, in_keys=keys))
env = TransformedEnv(GymEnv(PONG_VERSIONED()), ct)
Expand Down Expand Up @@ -3893,6 +3897,8 @@ def test_trans_parallel_env_check(self, maybe_fork_ParallelEnv):
@pytest.mark.skipif(not _has_gym, reason="No Gym detected")
@pytest.mark.parametrize("out_key", [None, ["outkey"], [("out", "key")]])
def test_transform_env(self, out_key):
if not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
keys = ["pixels"]
ct = Compose(
ToTensorImage(), CenterCrop(out_keys=out_key, w=20, h=20, in_keys=keys)
Expand Down Expand Up @@ -4932,6 +4938,8 @@ def test_transform_compose(self, keys, size, nchannels, batch, device):
"out_keys", [None, ["stuff"], [("some_other", "nested_key")]]
)
def test_transform_env(self, out_keys):
if not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
env = TransformedEnv(
GymEnv(PONG_VERSIONED()), FlattenObservation(-3, -1, out_keys=out_keys)
)
Expand Down Expand Up @@ -6135,6 +6143,8 @@ def test_trans_parallel_env_check(self, maybe_fork_ParallelEnv):
@pytest.mark.skipif(not _has_gym, reason="No gym")
@pytest.mark.parametrize("out_key", ["pixels", ("agents", "pixels")])
def test_transform_env(self, out_key):
if not _has_ale:
pytest.skip("ALE not available (missing ale_py); skipping Atari gym test.")
env = TransformedEnv(
GymEnv(PONG_VERSIONED()),
Compose(
Expand Down Expand Up @@ -7311,6 +7321,10 @@ def test_transform_rb(self, rbclass, out_keys, dim):
)
@pytest.mark.skipif(not _has_gym, reason="No gym")
def test_transform_inverse(self):
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
env = TransformedEnv(
GymEnv(HALFCHEETAH_VERSIONED()),
# the order is inverted
Expand Down Expand Up @@ -7595,6 +7609,10 @@ def test_transform_rb(self, out_keys, rbclass):
)
@pytest.mark.skipif(not _has_gym, reason="No Gym")
def test_transform_inverse(self):
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
env = TransformedEnv(
GymEnv(HALFCHEETAH_VERSIONED()), self._inv_circular_transform
)
Expand Down Expand Up @@ -12592,6 +12610,10 @@ def test_transform_no_env(self, batch):
not _has_gymnasium,
reason="EndOfLifeTransform can only be tested when Gym is present.",
)
@pytest.mark.skipif(
not _has_ale,
reason="ALE not available (missing ale_py); skipping Atari gym tests.",
)
class TestEndOfLife(TransformBase):
pytest.mark.filterwarnings("ignore:The base_env is not a gym env")

Expand Down Expand Up @@ -13782,6 +13804,10 @@ def test_transform_compose(self):
def test_transform_env(self, env_cls, interval_as_tensor, categorical, sampling):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if env_cls == "cheetah":
if not _has_mujoco:
pytest.skip(
"MuJoCo not available (missing mujoco); skipping MuJoCo gym test."
)
base_env = GymEnv(
HALFCHEETAH_VERSIONED(),
device=device,
Expand Down Expand Up @@ -15008,6 +15034,7 @@ def test_ray_extension(self):
ray.stop()


@pytest.mark.skipif(not _has_ray, reason="ray required")
class TestRayModuleTransform:
@pytest.fixture(autouse=True, scope="function")
def start_ray(self):
Expand Down
4 changes: 4 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,10 @@ def test_rng_decorator(device):
@pytest.mark.skipif(
TORCH_VERSION < version.parse("2.5.0"), reason="requires Torch >= 2.5.0"
)
@pytest.mark.skipif(
sys.version_info >= (3, 14),
reason="torch.compile is not supported on Python 3.14+",
)
def test_capture_log_records_recompile():
torch.compiler.reset()

Expand Down
Loading