chore: release v0.1.0
(cherry picked from commit 82525f882f3924a332d9ce40bf64255d0d14f6a4)
This commit is contained in:
158
scripts/test_all_demos.py
Executable file
158
scripts/test_all_demos.py
Executable file
@@ -0,0 +1,158 @@
|
||||
# Copyright (C) 2020-2025 Motphys Technology Co., Ltd. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
|
||||
"""
|
||||
Run all training demos with both JAX and PyTorch backends.
|
||||
|
||||
This script iterates through all available demo environments and runs
|
||||
training for each one using both training backends.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
# List of all available demo environments
|
||||
ALL_DEMOS = [
|
||||
"cartpole",
|
||||
"dm-cheetah",
|
||||
"dm-hopper-stand",
|
||||
"dm-hopper-hop",
|
||||
"dm-reacher",
|
||||
"dm-stander",
|
||||
"dm-walker",
|
||||
"dm-runner",
|
||||
"bounce_ball",
|
||||
"go1-flat-terrain-walk",
|
||||
"go1-rough-terrain-walk",
|
||||
"go1-stairs-terrain-walk",
|
||||
"anymal_c_navigation_flat",
|
||||
"franka-lift-cube",
|
||||
"franka-open-cabinet",
|
||||
]
|
||||
|
||||
# Available training backends
|
||||
BACKENDS = ["jax", "torch"]
|
||||
|
||||
|
||||
def run_command(env: str, backend: str, extra_args: List[str]) -> int:
|
||||
"""Run a single training command."""
|
||||
cmd = [
|
||||
"uv",
|
||||
"run",
|
||||
"scripts/train.py",
|
||||
"--env",
|
||||
env,
|
||||
"--train-backend",
|
||||
backend,
|
||||
] + extra_args
|
||||
|
||||
print(f"\n{'=' * 80}")
|
||||
print(f"Running: {' '.join(cmd)}")
|
||||
print(f"{'=' * 80}\n")
|
||||
|
||||
result = subprocess.run(cmd)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"\n❌ Error: Training failed for {env} with {backend} backend")
|
||||
return result.returncode
|
||||
|
||||
print(f"\n✅ Success: Training completed for {env} with {backend} backend")
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Run training demos with both JAX and PyTorch backends")
|
||||
parser.add_argument(
|
||||
"--demos",
|
||||
nargs="+",
|
||||
choices=ALL_DEMOS + ["all"],
|
||||
default=["all"],
|
||||
help="List of demos to run (default: all)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--backends",
|
||||
nargs="+",
|
||||
choices=BACKENDS + ["all"],
|
||||
default=["all"],
|
||||
help="Training backends to use (default: all)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--extra-args",
|
||||
nargs=argparse.REMAINDER,
|
||||
default=[],
|
||||
help="Extra arguments to pass to train.py",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--stop-on-error",
|
||||
action="store_true",
|
||||
help="Stop execution if any training fails",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Determine which demos to run
|
||||
if "all" in args.demos:
|
||||
demos_to_run = ALL_DEMOS
|
||||
else:
|
||||
demos_to_run = args.demos
|
||||
|
||||
# Determine which backends to use
|
||||
if "all" in args.backends:
|
||||
backends_to_run = BACKENDS
|
||||
else:
|
||||
backends_to_run = args.backends
|
||||
|
||||
print(f"Will run {len(demos_to_run)} demos with {len(backends_to_run)} backend(s)")
|
||||
print(f"Demos: {demos_to_run}")
|
||||
print(f"Backends: {backends_to_run}")
|
||||
print(f"Total training runs: {len(demos_to_run) * len(backends_to_run)}")
|
||||
|
||||
failed_runs = []
|
||||
|
||||
for demo in demos_to_run:
|
||||
for backend in backends_to_run:
|
||||
returncode = run_command(demo, backend, args.extra_args)
|
||||
|
||||
if returncode != 0:
|
||||
failed_runs.append((demo, backend))
|
||||
if args.stop_on_error:
|
||||
print("\n⚠️ Stopping due to error as requested")
|
||||
sys.exit(1)
|
||||
|
||||
# Summary
|
||||
print(f"\n{'=' * 80}")
|
||||
print("SUMMARY")
|
||||
print(f"{'=' * 80}")
|
||||
total_runs = len(demos_to_run) * len(backends_to_run)
|
||||
successful_runs = total_runs - len(failed_runs)
|
||||
|
||||
print(f"Total runs: {total_runs}")
|
||||
print(f"Successful: {successful_runs}")
|
||||
print(f"Failed: {len(failed_runs)}")
|
||||
|
||||
if failed_runs:
|
||||
print("\nFailed runs:")
|
||||
for demo, backend in failed_runs:
|
||||
print(f" - {demo} ({backend})")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("\n✅ All training runs completed successfully!")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -37,9 +37,13 @@ class NpEnvRunner:
|
||||
action_space = self._env.action_space
|
||||
if isinstance(action_space, gym.spaces.Box):
|
||||
size = (self._env.num_envs, *action_space.shape)
|
||||
low = action_space.low
|
||||
high = action_space.high
|
||||
low = np.where(np.isneginf(low), -1e6, low)
|
||||
high = np.where(np.isposinf(high), 1e6, high)
|
||||
return np.random.uniform(
|
||||
low=action_space.low,
|
||||
high=action_space.high,
|
||||
low=low,
|
||||
high=high,
|
||||
size=size,
|
||||
).astype(action_space.dtype)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user