chore: release v0.1.0

(cherry picked from commit 82525f882f3924a332d9ce40bf64255d0d14f6a4)
This commit is contained in:
motphys-developers
2026-01-04 04:43:04 +00:00
parent 13cfbce9a7
commit 62011bb24f
390 changed files with 18897 additions and 626 deletions

158
scripts/test_all_demos.py Executable file
View 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()

View File

@@ -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: