mirror of
https://github.com/vale981/ray
synced 2025-03-06 02:21:39 -05:00
139 lines
4.9 KiB
Python
139 lines
4.9 KiB
Python
#!/usr/bin/env python
|
|
# Runs one or more regression tests. Retries tests up to 3 times.
|
|
#
|
|
# Example usage:
|
|
# $ python run_regression_tests.py regression-tests/cartpole-es-[tf|torch].yaml
|
|
#
|
|
# When using in BAZEL (with py_test), e.g. see in ray/rllib/BUILD:
|
|
# py_test(
|
|
# name = "run_regression_tests",
|
|
# main = "tests/run_regression_tests.py",
|
|
# tags = ["learning_tests"],
|
|
# size = "medium", # 5min timeout
|
|
# srcs = ["tests/run_regression_tests.py"],
|
|
# data = glob(["tuned_examples/regression_tests/*.yaml"]),
|
|
# # Pass `BAZEL` option and the path to look for yaml regression files.
|
|
# args = ["BAZEL", "tuned_examples/regression_tests"]
|
|
# )
|
|
|
|
import argparse
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import yaml
|
|
|
|
import ray
|
|
from ray.tune import run_experiments
|
|
from ray.rllib import _register_all
|
|
from ray.rllib.utils.deprecation import deprecation_warning
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--framework",
|
|
choices=["jax", "tf2", "tf", "tfe", "torch"],
|
|
default="tf",
|
|
help="The deep learning framework to use.")
|
|
parser.add_argument(
|
|
"--yaml-dir",
|
|
type=str,
|
|
required=True,
|
|
help="The directory in which to find all yamls to test.")
|
|
parser.add_argument(
|
|
"--local-mode",
|
|
action="store_true",
|
|
help="Run ray in local mode for easier debugging.")
|
|
|
|
# Obsoleted arg, use --framework=torch instead.
|
|
parser.add_argument(
|
|
"--torch",
|
|
action="store_true",
|
|
help="Runs all tests with PyTorch enabled.")
|
|
|
|
if __name__ == "__main__":
|
|
args = parser.parse_args()
|
|
|
|
# Bazel regression test mode: Get path to look for yaml files.
|
|
# Get the path or single file to use.
|
|
rllib_dir = Path(__file__).parent.parent
|
|
print("rllib dir={}".format(rllib_dir))
|
|
|
|
abs_yaml_path = os.path.join(rllib_dir, args.yaml_dir)
|
|
# Single file given.
|
|
if os.path.isfile(abs_yaml_path):
|
|
yaml_files = [abs_yaml_path]
|
|
# Given path/file does not exist.
|
|
elif not os.path.isdir(abs_yaml_path):
|
|
raise ValueError("yaml-dir ({}) not found!".format(args.yaml_dir))
|
|
# Path given -> Get all yaml files in there via rglob.
|
|
else:
|
|
yaml_files = rllib_dir.rglob(args.yaml_dir + "/*.yaml")
|
|
yaml_files = sorted(
|
|
map(lambda path: str(path.absolute()), yaml_files), reverse=True)
|
|
|
|
print("Will run the following regression tests:")
|
|
for yaml_file in yaml_files:
|
|
print("->", yaml_file)
|
|
|
|
# Loop through all collected files.
|
|
for yaml_file in yaml_files:
|
|
experiments = yaml.load(open(yaml_file).read())
|
|
assert len(experiments) == 1,\
|
|
"Error, can only run a single experiment per yaml file!"
|
|
|
|
# Add torch option to exp config.
|
|
exp = list(experiments.values())[0]
|
|
exp["config"]["framework"] = args.framework
|
|
if args.torch:
|
|
deprecation_warning(old="--torch", new="--framework=torch")
|
|
exp["config"]["framework"] = "torch"
|
|
args.framework = "torch"
|
|
|
|
# Print out the actual config.
|
|
print("== Test config ==")
|
|
print(yaml.dump(experiments))
|
|
|
|
# Try running each test 3 times and make sure it reaches the given
|
|
# reward.
|
|
passed = False
|
|
for i in range(3):
|
|
try:
|
|
ray.init(num_cpus=5, local_mode=args.local_mode)
|
|
trials = run_experiments(experiments, resume=False, verbose=2)
|
|
finally:
|
|
ray.shutdown()
|
|
_register_all()
|
|
|
|
for t in trials:
|
|
# If we have evaluation workers, use their rewards.
|
|
# This is useful for offline learning tests, where
|
|
# we evaluate against an actual environment.
|
|
check_eval = \
|
|
exp["config"].get("evaluation_interval", None) is not None
|
|
reward_mean = \
|
|
t.last_result["evaluation"]["episode_reward_mean"] if \
|
|
check_eval else t.last_result["episode_reward_mean"]
|
|
|
|
# If we are using evaluation workers, we may have
|
|
# a stopping criterion under the "evaluation/" scope. If
|
|
# not, use `episode_reward_mean`.
|
|
if check_eval:
|
|
min_reward = t.stopping_criterion.get(
|
|
"evaluation/episode_reward_mean",
|
|
t.stopping_criterion.get("episode_reward_mean"))
|
|
# Otherwise, expect `episode_reward_mean` to be set.
|
|
else:
|
|
min_reward = t.stopping_criterion["episode_reward_mean"]
|
|
|
|
if reward_mean >= min_reward:
|
|
passed = True
|
|
break
|
|
|
|
if passed:
|
|
print("Regression test PASSED")
|
|
break
|
|
else:
|
|
print("Regression test FAILED on attempt {}".format(i + 1))
|
|
|
|
if not passed:
|
|
print("Overall regression FAILED: Exiting with Error.")
|
|
sys.exit(1)
|