From 60c530f4cbc4f25d325c182fa36bef6d05cfeb43 Mon Sep 17 00:00:00 2001 From: Erik Frey Date: Mon, 20 Apr 2026 11:33:08 -0700 Subject: [PATCH 1/2] Initial stab at moving benchmark logic to python. Cleans up testspeed to be only human readable output. Moves benchmark running to benchmarks/run.py with example in humanoid. --- benchmarks/humanoid/__init__.py | 16 + benchmarks/run.py | 49 +++ mujoco_warp/__init__.py | 1 + mujoco_warp/_src/benchmark.py | 354 ++++++++++++++++----- mujoco_warp/testspeed.py | 531 +++++++++++--------------------- 5 files changed, 529 insertions(+), 422 deletions(-) create mode 100644 benchmarks/humanoid/__init__.py create mode 100644 benchmarks/run.py diff --git a/benchmarks/humanoid/__init__.py b/benchmarks/humanoid/__init__.py new file mode 100644 index 000000000..7326a2087 --- /dev/null +++ b/benchmarks/humanoid/__init__.py @@ -0,0 +1,16 @@ +BENCHMARKS = [ + { + "name": "humanoid", + "mjcf": "humanoid.xml", + "nworld": 8192, + "nconmax": 24, + "njmax": 72, + }, + { + "name": "three_humanoids", + "mjcf": "three_humanoids.xml", + "nworld": 8192, + "nconmax": 100, + "njmax": 192, + }, +] diff --git a/benchmarks/run.py b/benchmarks/run.py new file mode 100644 index 000000000..fea04ca8e --- /dev/null +++ b/benchmarks/run.py @@ -0,0 +1,49 @@ +import importlib +import os +import re +import sys +from datetime import datetime +from typing import Sequence + +from absl import app +from absl import flags +import mujoco +import warp as wp + +import mujoco_warp as mjw + +_FILTER = flags.DEFINE_string("filter", "", "Filter benchmarks by name (regex)", short_name="f") + + +def _main(argv: Sequence[str]): + script_dir = os.path.dirname(os.path.abspath(__file__)) + + wp.config.quiet = True + wp.init() + + # Find all directories in benchmarks/ + for item in os.listdir(script_dir): + item_path = os.path.join(script_dir, item) + if not os.path.isdir(item_path) or not os.path.exists(os.path.join(item_path, "__init__.py")): + continue + module = importlib.import_module(item) + if not hasattr(module, "BENCHMARKS"): + continue + for bm in module.BENCHMARKS: + name = bm["name"] + + if _FILTER.value and not re.search(_FILTER.value, name): + continue + + mjm = mujoco.MjModel.from_xml_path(os.path.join(script_dir, item, bm["mjcf"])) + mjd = mujoco.MjData(mjm) + + m, d, metrics = mjw.benchmark.init(mjm, mjd, bm["nworld"], bm["nconmax"], bm["njmax"]) + metrics = mjw.benchmark.run(mjw.step, m, d, metrics, bm.get("nstep", 1000), None, True) + + for metric in metrics.to_short().split("\n"): + print(f"{name}.{metric}") + + +if __name__ == "__main__": + app.run(_main) diff --git a/mujoco_warp/__init__.py b/mujoco_warp/__init__.py index 3dbcb12c1..f506272cc 100644 --- a/mujoco_warp/__init__.py +++ b/mujoco_warp/__init__.py @@ -28,6 +28,7 @@ from mujoco_warp._src.types import Data as Data # isort: on +from mujoco_warp._src import benchmark as benchmark from mujoco_warp._src.bvh import refit_bvh as refit_bvh from mujoco_warp._src.collision_driver import collision as collision from mujoco_warp._src.collision_driver import nxn_broadphase as nxn_broadphase diff --git a/mujoco_warp/_src/benchmark.py b/mujoco_warp/_src/benchmark.py index f7baf2180..da32255b6 100644 --- a/mujoco_warp/_src/benchmark.py +++ b/mujoco_warp/_src/benchmark.py @@ -15,19 +15,127 @@ """Utilities for benchmarking MuJoCo Warp.""" +import dataclasses +import json +import shutil import time from typing import Callable, Tuple +import mujoco import numpy as np import warp as wp +from etils import epath from mujoco_warp._src import warp_util +from mujoco_warp._src.io import override_model +from mujoco_warp._src.io import put_data +from mujoco_warp._src.io import put_model from mujoco_warp._src.types import Data from mujoco_warp._src.types import Model from mujoco_warp._src.types import RenderContext from mujoco_warp._src.util_misc import halton +@dataclasses.dataclass +class Metrics: + """Metrics collected during benchmarking. + + Attributes: + jit_duration: Time spent JIT compiling (seconds). + run_time: Total simulation time (seconds). + steps_per_second: Throughput (steps/sec). + converged_worlds: Number of worlds that converged (e.g. stayed numerically stable). + model_memory: Model memory usage (bytes). + data_memory: Data memory usage (bytes). + total_memory: Total memory used (bytes). + ncon_mean: Mean number of contacts per world. + ncon_p95: 95th percentile of contacts per world. + nefc_mean: Mean number of constraints. + nefc_p95: 95th percentile of constraints. + solver_niter_mean: Mean solver iterations. + solver_niter_p95: 95th percentile of solver iterations. + model_mem_breakdown: Detailed model memory breakdown. + data_mem_breakdown: Detailed data memory breakdown. + trace_metrics: Flattened event trace timings (microseconds per step). + raw_trace: Raw event trace data. + raw_nacon: Raw number of contacts per step. + raw_nefc: Raw number of constraints per step. + raw_solver_niter: Raw solver iterations per step. + """ + + free_mem_at_init: float + jit_duration: float + run_time: float + steps_per_second: float + converged_worlds: int + + model_memory: float + data_memory: float + total_memory: float + + ncon_mean: float + ncon_p95: float + nefc_mean: float + nefc_p95: float + + solver_niter_mean: float + solver_niter_p95: float + + model_mem_breakdown: list[tuple[str, int]] + data_mem_breakdown: list[tuple[str, int]] + + trace: dict = dataclasses.field(default_factory=dict) + nacon: list = dataclasses.field(default_factory=list) + nefc: list = dataclasses.field(default_factory=list) + solver_niter: list = dataclasses.field(default_factory=list) + + def _flatten_trace(self) -> dict[str, float]: + """Flatten trace metrics.""" + trace_metrics = {} + steps = self.steps_per_second * self.run_time + if not steps: + return {} + + def flatten(prefix: str, trace, metrics): + for k, v in trace.items(): + times, sub_trace = v + for i, t in enumerate(times): + metrics[f"{prefix}{k}{f'[{i}]' if len(times) > 1 else ''}"] = 1e6 * t / steps + flatten(f"{prefix}{k}.", sub_trace, metrics) + + flatten("", self.trace, trace_metrics) + return trace_metrics + + def to_short(self) -> str: + """Return metrics in a short format string.""" + metrics_dict = dataclasses.asdict(self) + + # Flatten trace metrics + trace_metrics = self._flatten_trace() + metrics_dict.update(trace_metrics) + + exclude = {"trace", "nacon", "nefc", "solver_niter", "free_mem_at_init", "model_mem_breakdown", "data_mem_breakdown"} + filtered_metrics = {k: v for k, v in metrics_dict.items() if k not in exclude and v is not None} + + max_key_len = max(len(key) for key in filtered_metrics.keys()) + lines = [] + for key, value in filtered_metrics.items(): + lines.append(f"{key:<{max_key_len}} {value}") + return "\n".join(lines) + + def to_json(self) -> str: + """Return metrics in a JSON format string.""" + metrics_dict = dataclasses.asdict(self) + + # Flatten trace metrics + trace_metrics = self._flatten_trace() + metrics_dict.update(trace_metrics) + + exclude = {"trace", "nacon", "nefc", "solver_niter", "free_mem_at_init", "model_mem_breakdown", "data_mem_breakdown"} + json_metrics = {k: v for k, v in metrics_dict.items() if k not in exclude and v is not None} + return json.dumps(json_metrics) + + def _sum(stack1, stack2): ret = {} for k in stack1: @@ -83,89 +191,197 @@ def ctrl_noise( ctrl_out[worldid, actid] = ctrl -def benchmark( - fn: Callable[[Model, Data], None], +def _dataclass_memory(dataclass, prefix: str = "") -> list[tuple[str, int]]: + ret = [] + for field in dataclasses.fields(dataclass): + value = getattr(dataclass, field.name) + if dataclasses.is_dataclass(value): + ret.extend(_dataclass_memory(value, prefix=f"{prefix}{field.name}.")) + elif isinstance(value, wp.array): + ret.append((f"{prefix}{field.name}", value.capacity)) + return ret + + +def init( + mjm: mujoco.MjModel, + mjd: mujoco.MjData, + nworld: int, + nconmax: int | None = None, + njmax: int | None = None, + njmax_nnz: int | None = None, + nccdmax: int | None = None, + override: list[str] | None = None, + device: str | None = None, +) -> Tuple[Model, Data, Metrics]: + """Initialize Model, Data and partial Metrics for benchmarking. + + Args: + mjm: MuJoCo model. + mjd: MuJoCo data. + nworld: Number of parallel worlds. + nconmax: Maximum number of contacts per world. + njmax: Maximum number of constraints per world. + njmax_nnz: Maximum number of non-zeros in constraint Jacobian. + nccdmax: Maximum number of CCD contacts per world. + override: Model overrides (notation: foo.bar = baz). + device: Warp device name. + + Returns: + Tuple of (Model, Data, partial Metrics). + """ + free_mem_at_init = wp.get_device(device).free_memory + + with wp.ScopedDevice(device): + if override is not None: + override_model(mjm, override) + m = put_model(mjm) + if override is not None: + override_model(m, override) + d = put_data( + mjm, + mjd, + nworld=nworld, + nconmax=nconmax, + njmax=njmax, + njmax_nnz=njmax_nnz, + nccdmax=nccdmax, + ) + + metrics = Metrics( + free_mem_at_init=free_mem_at_init, + jit_duration=0.0, + run_time=0.0, + steps_per_second=0.0, + converged_worlds=0, + model_memory=0.0, + data_memory=0.0, + total_memory=0.0, + ncon_mean=0.0, + ncon_p95=0.0, + nefc_mean=0.0, + nefc_p95=0.0, + solver_niter_mean=0.0, + solver_niter_p95=0.0, + model_mem_breakdown=[], + data_mem_breakdown=[], + ) + + return m, d, metrics + + +def run( + fn: Callable, m: Model, d: Data, + metrics: Metrics, nstep: int, - ctrls: np.ndarray | None = None, + ctrls: list[np.ndarray] | None = None, event_trace: bool = False, - measure_alloc: bool = False, - measure_solver_niter: bool = False, render_context: RenderContext | None = None, -) -> Tuple[float, float, dict, list, list, list, int]: - """Benchmark a function of Model and Data. + device: str = "cuda:0", + clear_warp_cache: bool = False, +) -> Metrics: + """Run benchmark. Args: fn: Function to benchmark. - m: The model containing kinematic and dynamic information (device). - d: The data object containing the current state and output information (device). - nstep: Number of timesteps. - ctrls: Control sequence to apply during benchmarking. - event_trace: If True, time routines decorated with @event_scope. - measure_alloc: If True, record number of contacts and constraints. - measure_solver_niter: If True, record the number of solver iterations. - render_context: The render context to use for rendering. + m: Model. + d: Data. + metrics: Partially filled Metrics object. + nstep: Number of steps to run. + ctrls: Optional control trajectory. + event_trace: Enable event tracing. + render_context: Optional render context. + device: Warp device. + clear_warp_cache: Clear warp caches before running. Returns: - - Time to JIT fn. - - Total time to run the benchmark. - - Trace. - - Number of contacts. - - Number of constraints. - - Number of solver iterations. - - Number of converged worlds. + Completed Metrics object. """ - trace = {} - nacon, nefc, solver_niter = [], [], [] - center = wp.array([], dtype=wp.float32) - - with warp_util.EventTracer(enabled=event_trace) as tracer: - # capture the whole function as a CUDA graph - jit_beg = time.perf_counter() - - if render_context is not None: - with wp.ScopedCapture() as capture: - fn(m, d, render_context) - else: - with wp.ScopedCapture() as capture: - fn(m, d) - - jit_end = time.perf_counter() - jit_duration = jit_end - jit_beg - - graph = capture.graph - - time_vec = np.zeros(nstep) - for i in range(nstep): - with wp.ScopedStream(wp.get_stream()): - if ctrls is not None: - center = wp.array(ctrls[i], dtype=wp.float32) - wp.launch( - ctrl_noise, - dim=(d.nworld, m.nu), - inputs=[m.opt.timestep, m.actuator_ctrllimited, m.actuator_ctrlrange, d.ctrl, center, i, 0.01, 0.1], - outputs=[d.ctrl], - ) - wp.synchronize() - - run_beg = time.perf_counter() - wp.capture_launch(graph) - wp.synchronize() - run_end = time.perf_counter() - - time_vec[i] = run_end - run_beg - if trace: - trace = _sum(trace, tracer.trace()) + with wp.ScopedDevice(device): + if clear_warp_cache: + wp.clear_kernel_cache() + wp.clear_lto_cache() + compute_cache = epath.Path("~/.nv/ComputeCache").expanduser() + if compute_cache.exists(): + shutil.rmtree(compute_cache) + compute_cache.mkdir() + + trace = {} + nacon, nefc, solver_niter = [], [], [] + center = wp.array([], dtype=wp.float32) + + with warp_util.EventTracer(enabled=event_trace) as tracer: + # capture the whole function as a CUDA graph + jit_beg = time.perf_counter() + + if render_context is not None: + with wp.ScopedCapture() as capture: + fn(m, d, render_context) else: - trace = tracer.trace() - if measure_alloc: + with wp.ScopedCapture() as capture: + fn(m, d) + + jit_end = time.perf_counter() + jit_duration = jit_end - jit_beg + + graph = capture.graph + + time_vec = np.zeros(nstep) + for i in range(nstep): + with wp.ScopedStream(wp.get_stream()): + if ctrls is not None: + center = wp.array(ctrls[i], dtype=wp.float32) + wp.launch( + ctrl_noise, + dim=(d.nworld, m.nu), + inputs=[m.opt.timestep, m.actuator_ctrllimited, m.actuator_ctrlrange, d.ctrl, center, i, 0.01, 0.1], + outputs=[d.ctrl], + ) + wp.synchronize() + + run_beg = time.perf_counter() + wp.capture_launch(graph) + wp.synchronize() + run_end = time.perf_counter() + + time_vec[i] = run_end - run_beg + if trace: + trace = _sum(trace, tracer.trace()) + else: + trace = tracer.trace() + + # Always collect allocations and solver iterations nacon.append(np.max([d.nacon.numpy()[0], d.ncollision.numpy()[0]])) nefc.append(np.max(d.nefc.numpy())) - if measure_solver_niter: solver_niter.append(d.solver_niter.numpy()) - nsuccess = np.sum(~np.any(np.isnan(d.qpos.numpy()), axis=1)) - run_duration = np.sum(time_vec) + nconverged = np.sum(~np.any(np.isnan(d.qpos.numpy()), axis=1)) + run_duration = np.sum(time_vec) + + steps = d.nworld * nstep + model_mem = _dataclass_memory(m) + data_mem = _dataclass_memory(d) - return jit_duration, run_duration, trace, nacon, nefc, solver_niter, nsuccess + return Metrics( + free_mem_at_init=metrics.free_mem_at_init, + jit_duration=jit_duration, + run_time=run_duration, + steps_per_second=steps / run_duration, + converged_worlds=int(nconverged), + model_memory=sum(c for _, c in model_mem), + data_memory=sum(c for _, c in data_mem), + total_memory=metrics.free_mem_at_init - wp.get_device(device).free_memory, + ncon_mean=np.mean(nacon) / d.nworld, + ncon_p95=np.percentile(nacon, 95) / d.nworld, + nefc_mean=np.mean(nefc), + nefc_p95=np.percentile(nefc, 95), + solver_niter_mean=np.mean(solver_niter), + solver_niter_p95=np.percentile(solver_niter, 95), + model_mem_breakdown=model_mem, + data_mem_breakdown=data_mem, + trace=trace, + nacon=nacon, + nefc=nefc, + solver_niter=solver_niter, + ) diff --git a/mujoco_warp/testspeed.py b/mujoco_warp/testspeed.py index 67d98a12c..980a06899 100644 --- a/mujoco_warp/testspeed.py +++ b/mujoco_warp/testspeed.py @@ -23,10 +23,9 @@ import dataclasses import inspect -import json -import shutil import sys -from typing import Sequence +import typing +from typing import Annotated, Sequence import mujoco import numpy as np @@ -38,10 +37,10 @@ import mujoco_warp as mjw # mjwarp-testspeed has priviledged access to a few internal methods -from mujoco_warp._src.benchmark import benchmark +from mujoco_warp._src.collision_driver import MJ_COLLISION_TABLE from mujoco_warp._src.io import find_keys from mujoco_warp._src.io import make_trajectory -from mujoco_warp._src.io import override_model +from mujoco_warp._src.types import CollisionType _FUNCS = { n: f @@ -66,8 +65,7 @@ _DEVICE = flags.DEFINE_string("device", None, "override the default Warp device") _REPLAY = flags.DEFINE_string("replay", None, "keyframe sequence to replay, keyframe name must prefix match") _MEMORY = flags.DEFINE_bool("memory", False, "print memory report") -_FORMAT = flags.DEFINE_enum("format", "human", ["human", "short", "json"], "output format for results") -_INFO = flags.DEFINE_bool("info", False, "print Model and Data info") +_INFO = flags.DEFINE_bool("info", False, "print extra Model and Data info") # Render _WIDTH = flags.DEFINE_integer("width", 64, "render width (pixels)") @@ -78,119 +76,165 @@ _USE_SHADOWS = flags.DEFINE_bool("shadows", False, "use shadows") -def _load_model(path: epath.Path) -> mujoco.MjModel: - if not path.exists(): - resource_path = epath.resource_path("mujoco_warp") / path - if not resource_path.exists(): - raise FileNotFoundError(f"file not found: {path}\nalso tried: {resource_path}") - path = resource_path - - if path.suffix == ".mjb": - return mujoco.MjModel.from_binary_path(path.as_posix()) - - spec = mujoco.MjSpec.from_file(path.as_posix()) - # check if the file has any mujoco.sdf test plugins - if any(p.plugin_name.startswith("mujoco.sdf") for p in spec.plugins): - from mujoco_warp.test_data.collision_sdf.utils import register_sdf_plugins as register_sdf_plugins +def _main(argv: Sequence[str]): + """Run the benchmark.""" - register_sdf_plugins(mjw) + if len(argv) < 2: + raise app.UsageError("Missing required input: mjcf path.") + elif len(argv) > 2: + raise app.UsageError("Too many command-line arguments.") - return spec.compile() + wp.config.quiet = flags.FLAGS["verbosity"].value < 1 + wp.init() + path = epath.Path(argv[1]) + fn = _FUNCS.get(_FUNCTION.value) + if fn is None: + raise app.UsageError(f"Unknown function: {_FUNCTION.value}") + nstep, nworld, nconmax, njmax, njmax_nnz, nccdmax, override, device = ( + _NSTEP.value, + _NWORLD.value, + _NCONMAX.value, + _NJMAX.value, + _NJMAX_NNZ.value, + _NCCDMAX.value, + _OVERRIDE.value, + wp.get_device(_DEVICE.value), + ) + if device == "cpu": + raise ValueError("testspeed available for gpu only") + wp.set_device(device) -def _dataclass_memory(dataclass, prefix: str = "") -> list[tuple[str, int]]: - ret = [] - for field in dataclasses.fields(dataclass): - value = getattr(dataclass, field.name) - if dataclasses.is_dataclass(value): - ret.extend(_dataclass_memory(value, prefix=f"{prefix}{field.name}.")) - elif isinstance(value, wp.array): - ret.append((f"{prefix}{field.name}", value.capacity)) - return ret - - -def _collect_metrics( - m, d, path: epath.Path, free_mem_at_init, jit_time, run_time, trace, nacon, nefc, solver_niter, nsuccess -) -> dict[str, float]: - """Collect all metrics into a dictionary.""" - steps = _NWORLD.value * _NSTEP.value - metrics = { - "benchmark": path.parent.name + path.stem.replace("scene", "") if path.name.startswith("scene") else path.stem, - "jit_duration": jit_time, - "run_time": run_time, - "steps_per_second": steps / run_time, - "converged_worlds": int(nsuccess), - } - - def flatten_trace(prefix: str, trace, metrics): - for k, v in trace.items(): - times, sub_trace = v - for i, t in enumerate(times): - metrics[f"{prefix}{k}{f'[{i}]' if len(times) > 1 else ''}"] = 1e6 * t / steps - flatten_trace(f"{prefix}{k}.", sub_trace, metrics) - - flatten_trace("", trace, metrics) + print(f"Loading model from: {path}...\n") + mjm = _load_model(path) + mjd = mujoco.MjData(mjm) + ctrls = None + if _REPLAY.value: + keys = find_keys(mjm, _REPLAY.value) + if not keys: + raise app.UsageError(f"Key prefix not find: {_REPLAY.value}") + ctrls = make_trajectory(mjm, keys) + mujoco.mj_resetDataKeyframe(mjm, mjd, keys[0]) + elif mjm.nkey > 0 and _KEYFRAME.value > -1: + mujoco.mj_resetDataKeyframe(mjm, mjd, _KEYFRAME.value) + if ctrls is None: + ctrls = [mjd.ctrl.copy() for _ in range(_NSTEP.value)] - if _MEMORY.value: - metrics.update( - { - "model_memory": sum(c for _, c in _dataclass_memory(m)), - "data_memory": sum(c for _, c in _dataclass_memory(d)), - "total_memory": free_mem_at_init - wp.get_device(_DEVICE.value).free_memory, - } + m, d, metrics = mjw.benchmark.init(mjm, mjd, nworld, nconmax, njmax, njmax_nnz, nccdmax, override, device) + + # Model + print("Model") + if _INFO.value: + size_fields = [f.name for f in dataclasses.fields(m) if f.type is int and getattr(m, f.name) > 0] + else: + size_fields = ["nq", "nv", "nu", "nbody", "ngeom"] + for i, f in enumerate(size_fields): + print(f"{' ' if i % 5 == 0 else ' '}{f}: {getattr(m, f)}", end="\n" if i % 5 == 4 or i == len(size_fields) - 1 else "") + + # RenderContext + if "rc" in inspect.signature(fn).parameters.keys(): + print("RenderContext") + rc = mjw.create_render_context( + mjm, + nworld, + (_WIDTH.value, _HEIGHT.value), + _RENDER_RGB.value, + _RENDER_DEPTH.value, + _USE_TEXTURES.value, + _USE_SHADOWS.value, ) + print(f" shadows: {rc.use_shadows} textures: {rc.use_textures} nlight: {m.nlight} bvh_ngeom: {rc.bvh_ngeom}") + print(f" ncam: {rc.nrender} cam_res: {[(int(x[0]), int(x[1])) for x in rc.cam_res.numpy()]}") + else: + rc = None - if nacon and nefc: - metrics.update( - { - "ncon_mean": np.mean(nacon) / _NWORLD.value, - "ncon_p95": np.percentile(nacon, 95) / _NWORLD.value, - "nefc_mean": np.mean(nefc), - "nefc_p95": np.percentile(nefc, 95), - } + # Option + print("Option") + disable_names = [f.name for f in mjw.DisableBit if m.opt.disableflags & f] + enable_names = [f.name for f in mjw.EnableBit if m.opt.enableflags & f] + disableflags_str = ", ".join(disable_names) if disable_names else "none" + enableflags_str = ", ".join(enable_names) if enable_names else "none" + + if _INFO.value: + print( + f" timestep: {m.opt.timestep.numpy()[0]:g}\n" + f" tolerance: {m.opt.tolerance.numpy()[0]:g} ls_tolerance: {m.opt.ls_tolerance.numpy()[0]:g}\n" + f" ccd_tolerance: {m.opt.ccd_tolerance.numpy()[0]:g}\n" + f" density: {m.opt.density.numpy()[0]:g} viscosity: {m.opt.viscosity.numpy()[0]:g}\n" + f" gravity: {m.opt.gravity.numpy()[0]}\n" + f" wind: {m.opt.wind.numpy()[0]} magnetic: {m.opt.magnetic.numpy()[0]}\n" + f" integrator: {mjw.IntegratorType(m.opt.integrator).name}\n" + f" cone: {mjw.ConeType(m.opt.cone).name}\n" + f" solver: {mjw.SolverType(m.opt.solver).name} iterations: {m.opt.iterations} ls_iterations: {m.opt.ls_iterations}\n" + f" ccd_iterations: {m.opt.ccd_iterations}\n" + f" sdf_initpoints: {m.opt.sdf_initpoints} sdf_iterations: {m.opt.sdf_iterations}\n" + f" disableflags: [{disableflags_str}]\n" + f" enableflags: [{enableflags_str}]\n" + f" impratio: {1.0 / np.square(m.opt.impratio_invsqrt.numpy()[0]):g}\n" + f" is_sparse: {m.is_sparse}\n" + f" ls_parallel: {m.opt.ls_parallel} ls_parallel_min_step: {m.opt.ls_parallel_min_step:g}\n" + f" has_fluid: {m.has_fluid}\n" + f" broadphase: {m.opt.broadphase.name} broadphase_filter: {m.opt.broadphase_filter.name}\n" + f" graph_conditional: {m.opt.graph_conditional}\n" + f" run_collision_detection: {m.opt.run_collision_detection}\n" + f" contact_sensor_maxmatch: {m.opt.contact_sensor_maxmatch}" ) - - if solver_niter: - metrics.update( - { - "solver_niter_mean": np.mean(solver_niter), - "solver_niter_p95": np.percentile(solver_niter, 95), - } + else: + print( + f" integrator: {mjw.IntegratorType(m.opt.integrator).name}\n" + f" cone: {mjw.ConeType(m.opt.cone).name}\n" + f" solver: {mjw.SolverType(m.opt.solver).name} iterations: {m.opt.iterations} ls_iterations: {m.opt.ls_iterations}\n" + f" is_sparse: {m.is_sparse}\n" + f" ls_parallel: {m.opt.ls_parallel}\n" + f" broadphase: {m.opt.broadphase.name} broadphase_filter: {m.opt.broadphase_filter.name}" ) - return metrics - - -def _output_short(*args): - """Output metrics in a short format.""" - metrics = _collect_metrics(*args) - benchmark = metrics.pop("benchmark") - max_key_len = max(len(key) for key in metrics.keys()) + len(benchmark) - for key, value in metrics.items(): - print(f"{benchmark}:{key:<{max_key_len}} {value}") - - -def _output_json(*args): - """Output metrics in a JSON format.""" - metrics = _collect_metrics(*args) - del metrics["benchmark"] - print(json.dumps(metrics)) - - -def _output_human(m, d, path: epath.Path, free_mem_at_init, jit_time, run_time, trace, nacon, nefc, solver_niter, nsuccess): - """Output metrics in a human-readable format.""" - steps = _NWORLD.value * _NSTEP.value + # Colliders + colliders = {"Primitive": [], "HfieldCCD": [], "CCD": []} + + for trid, count in enumerate(m.geom_pair_type_count): + if count == 0: + continue + # convert triangle index to i, j + n = len(mjw.GeomType) + i = mjw.GeomType(int((2 * n + 1 - np.sqrt((2 * n + 1) ** 2 - 8 * trid)) / 2)) + j = mjw.GeomType(trid - i * (2 * n - i - 1) // 2) + match MJ_COLLISION_TABLE.get((i, j)): + case CollisionType.PRIMITIVE: + colliders["Primitive"].append(f"{i.name}-{j.name}: {count}") + case CollisionType.CONVEX if mjw.GeomType.HFIELD in (i, j): + colliders["HfieldCCD"].append(f"{i.name}-{j.name}: {count}") + case CollisionType.CONVEX: + colliders["CCD"].append(f"{i.name}-{j.name}: {count}") + + if _INFO.value and any(colliders.values()): + print("Colliders") + + for typ, pairs in colliders.items(): + if pairs: + print(f" {typ}\n" + "\n".join(f" {p}" for p in pairs)) + + print(f" max collisions: {sum(m.geom_pair_type_count)}") + + print(f"Data\n nworld: {d.nworld} naconmax: {d.naconmax} njmax: {d.njmax}") + timestep = m.opt.timestep.numpy()[0] + print(f"Rolling out {nstep} steps at dt = {f'{timestep:g}' if timestep < 0.001 else f'{timestep:.3f}'}...") + + fn = _FUNCS[_FUNCTION.value] + metrics = mjw.benchmark.run(fn, m, d, metrics, nstep, ctrls, _EVENT_TRACE.value, rc, device, _CLEAR_WARP_CACHE.value) + + steps = nworld * nstep print(f""" -Summary for {_NWORLD.value} parallel rollouts +Summary for {nworld} parallel rollouts -Total JIT time: {jit_time:.2f} s -Total simulation time: {run_time:.2f} s -Total steps per second: {steps / run_time:,.0f} -Total realtime factor: {steps * m.opt.timestep.numpy()[0] / run_time:,.2f} x -Total time per step: {1e9 * run_time / steps:.2f} ns -Total converged worlds: {nsuccess} / {d.nworld}""") +Total JIT time: {metrics.jit_duration:.2f} s +Total simulation time: {metrics.run_time:.2f} s +Total steps per second: {steps / metrics.run_time:,.0f} +Total realtime factor: {steps * timestep / metrics.run_time:,.2f} x +Total time per step: {1e9 * metrics.run_time / steps:.2f} ns +Total converged worlds: {metrics.converged_worlds} / {d.nworld}""") - if trace: + if metrics.trace: print("\nEvent trace:\n") def print_trace(trace, indent): @@ -219,13 +263,13 @@ def print_table(matrix, headers, title): for row in matrix: print(" ".join(f"{row[i]:{col_widths[i]}g}" for i in range(num_cols))) - if nacon and nefc: + if _MEASURE_ALLOC.value and metrics.nacon and metrics.nefc: idx = 0 nacon_matrix, nefc_matrix = [], [] for i in range(_NUM_BUCKETS.value): - size = _NSTEP.value // _NUM_BUCKETS.value + (i < (_NSTEP.value % _NUM_BUCKETS.value)) - nacon_arr = np.array(nacon[idx : idx + size]) - nefc_arr = np.array(nefc[idx : idx + size]) + size = nstep // _NUM_BUCKETS.value + (i < (nstep % _NUM_BUCKETS.value)) + nacon_arr = np.array(metrics.nacon[idx : idx + size]) + nefc_arr = np.array(metrics.nefc[idx : idx + size]) nacon_matrix.append([np.mean(nacon_arr), np.std(nacon_arr), np.min(nacon_arr), np.max(nacon_arr)]) nefc_matrix.append([np.mean(nefc_arr), np.std(nefc_arr), np.min(nefc_arr), np.max(nefc_arr)]) idx += size @@ -233,23 +277,24 @@ def print_table(matrix, headers, title): print_table(nacon_matrix, ("mean", "std", "min", "max"), "nacon alloc") print_table(nefc_matrix, ("mean", "std", "min", "max"), "nefc alloc") - if solver_niter: + if _MEASURE_SOLVER.value and metrics.solver_niter: idx = 0 matrix = [] for i in range(_NUM_BUCKETS.value): - size = _NSTEP.value // _NUM_BUCKETS.value + (i < (_NSTEP.value % _NUM_BUCKETS.value)) - arr = np.array(solver_niter[idx : idx + size]) + size = nstep // _NUM_BUCKETS.value + (i < (nstep % _NUM_BUCKETS.value)) + arr = np.array(metrics.solver_niter[idx : idx + size]) matrix.append([np.mean(arr), np.std(arr), np.min(arr), np.max(arr)]) idx += size print_table(matrix, ("mean", "std", "min", "max"), "solver niter") if _MEMORY.value: - total_mem = wp.get_device(_DEVICE.value).total_memory - used_mem = free_mem_at_init - wp.get_device(_DEVICE.value).free_memory + total_mem = wp.get_device(device).total_memory + used_mem = metrics.total_memory other_mem = used_mem - for dataclass, name in [(m, "\nModel"), (d, "Data")]: - mem = _dataclass_memory(dataclass) + for mem, name in [(metrics.model_mem_breakdown, "\nModel"), (metrics.data_mem_breakdown, "Data")]: + if mem is None: + continue other_mem -= sum(c for _, c in mem) other_mem_total = sum(c for _, c in mem) print(f"{name} memory {other_mem_total / 1024**2:.2f} MiB ({100 * other_mem_total / used_mem:.2f}% of used memory):") @@ -262,244 +307,24 @@ def print_table(matrix, headers, title): print(f"Total memory: {used_mem / 1024**2:.2f} MiB ({100 * used_mem / total_mem:.2f}% of total device memory)") -def _main(argv: Sequence[str]): - if len(argv) < 2: - raise app.UsageError("Missing required input: mjcf path.") - elif len(argv) > 2: - raise app.UsageError("Too many command-line arguments.") +def _load_model(path: epath.Path) -> mujoco.MjModel: + if not path.exists(): + resource_path = epath.resource_path("mujoco_warp") / path + if not resource_path.exists(): + raise FileNotFoundError(f"file not found: {path}\nalso tried: {resource_path}") + path = resource_path - path = epath.Path(argv[1]) - if _FORMAT.value == "human": - print(f"Loading model from: {path}...\n") - mjm = _load_model(path) - mjd = mujoco.MjData(mjm) - ctrls = None - if _REPLAY.value: - keys = find_keys(mjm, _REPLAY.value) - if not keys: - raise app.UsageError(f"Key prefix not find: {_REPLAY.value}") - ctrls = make_trajectory(mjm, keys) - mujoco.mj_resetDataKeyframe(mjm, mjd, keys[0]) - elif mjm.nkey > 0 and _KEYFRAME.value > -1: - mujoco.mj_resetDataKeyframe(mjm, mjd, _KEYFRAME.value) - if ctrls is None: - ctrls = [mjd.ctrl.copy() for _ in range(_NSTEP.value)] + if path.suffix == ".mjb": + return mujoco.MjModel.from_binary_path(path.as_posix()) - wp.config.quiet = flags.FLAGS["verbosity"].value < 1 - wp.init() - free_mem_at_init = wp.get_device(_DEVICE.value).free_memory - if _CLEAR_WARP_CACHE.value: - wp.clear_kernel_cache() - wp.clear_lto_cache() - # Clear CUDA compute cache for truly cold start JIT - compute_cache = epath.Path("~/.nv/ComputeCache").expanduser() - if compute_cache.exists(): - shutil.rmtree(compute_cache) - compute_cache.mkdir() - - if (_DEVICE.value or wp.get_device()) == "cpu": - raise ValueError("testspeed available for gpu only") + spec = mujoco.MjSpec.from_file(path.as_posix()) + # check if the file has any mujoco.sdf test plugins + if any(p.plugin_name.startswith("mujoco.sdf") for p in spec.plugins): + from mujoco_warp.test_data.collision_sdf.utils import register_sdf_plugins as register_sdf_plugins - with wp.ScopedDevice(_DEVICE.value): - override_model(mjm, _OVERRIDE.value) - m = mjw.put_model(mjm) - override_model(m, _OVERRIDE.value) - d = mjw.put_data( - mjm, - mjd, - nworld=_NWORLD.value, - nconmax=_NCONMAX.value, - njmax=_NJMAX.value, - njmax_nnz=_NJMAX_NNZ.value, - nccdmax=_NCCDMAX.value, - ) - rc = None - if "rc" in inspect.signature(_FUNCS[_FUNCTION.value]).parameters.keys(): - rc = mjw.create_render_context( - mjm, - _NWORLD.value, - (_WIDTH.value, _HEIGHT.value), - _RENDER_RGB.value, - _RENDER_DEPTH.value, - _USE_TEXTURES.value, - _USE_SHADOWS.value, - ) - - if _FORMAT.value == "human": - # Model sizes - if _INFO.value: - size_fields = [ - "nq", - "nv", - "nu", - "na", - "nbody", - "noct", - "njnt", - "nM", - "nC", - "ngeom", - "nsite", - "ncam", - "nlight", - "nflex", - "nflexvert", - "nflexedge", - "nflexelem", - "nflexelemdata", - "nflexelemedge", - "nmesh", - "nmeshvert", - "nmeshnormal", - "nmeshface", - "nmeshgraph", - "nmeshpoly", - "nmeshpolyvert", - "nmeshpolymap", - "nhfield", - "nhfielddata", - "nmat", - "npair", - "nexclude", - "neq", - "ntendon", - "nwrap", - "nsensor", - "nmocap", - "nplugin", - "ngravcomp", - "nsensordata", - ] - else: - size_fields = [ - "nq", - "nv", - "nu", - "nbody", - "ngeom", - ] - - size_items = [f"{name}: {getattr(m, name)}" for name in size_fields if getattr(m, name) > 0] - # Wrap sizes at 10 items per line - sizes_lines = [] - for i in range(0, len(size_items), 5): - sizes_lines.append(" " + " ".join(size_items[i : i + 5])) - sizes_str = "\n".join(sizes_lines) + "\n" - - # Parse Option.disableflags and Option.enableflags to show individual flag names - disable_names = [f.name for f in mjw.DisableBit if m.opt.disableflags & f] - enable_names = [f.name for f in mjw.EnableBit if m.opt.enableflags & f] - disableflags_str = ", ".join(disable_names) if disable_names else "none" - enableflags_str = ", ".join(enable_names) if enable_names else "none" - - # Option fields - if _INFO.value: - opt_str = ( - f"Option\n" - f" timestep: {m.opt.timestep.numpy()[0]:g}\n" - f" tolerance: {m.opt.tolerance.numpy()[0]:g} ls_tolerance: {m.opt.ls_tolerance.numpy()[0]:g}\n" - f" ccd_tolerance: {m.opt.ccd_tolerance.numpy()[0]:g}\n" - f" density: {m.opt.density.numpy()[0]:g} viscosity: {m.opt.viscosity.numpy()[0]:g}\n" - f" gravity: {m.opt.gravity.numpy()[0]}\n" - f" wind: {m.opt.wind.numpy()[0]} magnetic: {m.opt.magnetic.numpy()[0]}\n" - f" integrator: {mjw.IntegratorType(m.opt.integrator).name}\n" - f" cone: {mjw.ConeType(m.opt.cone).name}\n" - f" solver: {mjw.SolverType(m.opt.solver).name} iterations: {m.opt.iterations} ls_iterations: {m.opt.ls_iterations}\n" - f" ccd_iterations: {m.opt.ccd_iterations}\n" - f" sdf_initpoints: {m.opt.sdf_initpoints} sdf_iterations: {m.opt.sdf_iterations}\n" - f" disableflags: [{disableflags_str}]\n" - f" enableflags: [{enableflags_str}]\n" - f" impratio: {1.0 / np.square(m.opt.impratio_invsqrt.numpy()[0]):g}\n" - f" is_sparse: {m.is_sparse}\n" - f" ls_parallel: {m.opt.ls_parallel} ls_parallel_min_step: {m.opt.ls_parallel_min_step:g}\n" - f" has_fluid: {m.has_fluid}\n" - f" broadphase: {m.opt.broadphase.name} broadphase_filter: {m.opt.broadphase_filter.name}\n" - f" graph_conditional: {m.opt.graph_conditional}\n" - f" run_collision_detection: {m.opt.run_collision_detection}\n" - f" contact_sensor_maxmatch: {m.opt.contact_sensor_maxmatch}\n" - ) - else: - opt_str = ( - f"Option\n" - f" integrator: {mjw.IntegratorType(m.opt.integrator).name}\n" - f" cone: {mjw.ConeType(m.opt.cone).name}\n" - f" solver: {mjw.SolverType(m.opt.solver).name} iterations: {m.opt.iterations} ls_iterations: {m.opt.ls_iterations}\n" - f" is_sparse: {m.is_sparse}\n" - f" ls_parallel: {m.opt.ls_parallel}\n" - f" broadphase: {m.opt.broadphase.name} broadphase_filter: {m.opt.broadphase_filter.name}\n" - ) - - if _INFO.value: - # Collider types grouped by category - from mujoco_warp._src.collision_driver import MJ_COLLISION_TABLE - from mujoco_warp._src.types import CollisionType - - def trid_to_types(trid): - """Convert triangular index back to geom type pair.""" - n = len(mjw.GeomType) - i = 0 - while (i + 1) * (2 * n - i) // 2 <= trid: - i += 1 - j = trid - i * (2 * n - i - 1) // 2 - return mjw.GeomType(i), mjw.GeomType(j) - - # Categorize collision pairs using MJ_COLLISION_TABLE - primitive_pairs = {k for k, v in MJ_COLLISION_TABLE.items() if v == CollisionType.PRIMITIVE} - hfield_ccd_pairs = {k for k, v in MJ_COLLISION_TABLE.items() if v == CollisionType.CONVEX and mjw.GeomType.HFIELD in k} - ccd_pairs = {k for k, v in MJ_COLLISION_TABLE.items() if v == CollisionType.CONVEX and mjw.GeomType.HFIELD not in k} - - primitive_colliders, hfield_ccd_colliders, ccd_colliders = [], [], [] - for trid, count in enumerate(m.geom_pair_type_count): - if count > 0: - t1, t2 = trid_to_types(trid) - pair = (t1, t2) - pair_str = f"{t1.name}-{t2.name}: {count}" - if pair in primitive_pairs: - primitive_colliders.append(pair_str) - elif pair in hfield_ccd_pairs: - hfield_ccd_colliders.append(pair_str) - elif pair in ccd_pairs: - ccd_colliders.append(pair_str) - - collider_lines = [] - if primitive_colliders: - primitives = " Primitive" - for collider in primitive_colliders: - primitives += f"\n {collider}" - collider_lines.append(primitives) - if hfield_ccd_colliders: - hfield = " HFieldCCD" - for collider in hfield_ccd_colliders: - hfield += f"\n {collider}" - collider_lines.append(hfield) - if ccd_colliders: - ccd = " CCD" - for collider in ccd_colliders: - ccd += f"\n {collider}" - collider_lines.append(ccd) - max_collisions = sum(m.geom_pair_type_count) - collider_lines.append(f" max collisions: {max_collisions}") - collider_str = "Colliders\n" + "\n".join(collider_lines) + "\n" if collider_lines else "" - else: - collider_str = "" - - out = f"Model\n{sizes_str}{opt_str}{collider_str}" - out += f"Data\n nworld: {d.nworld} naconmax: {d.naconmax} njmax: {d.njmax}\n" - if rc: - out += f"RenderContext\n shadows: {_USE_SHADOWS.value} textures: {_USE_TEXTURES.value} nlight: {m.nlight} bvh_ngeom: {rc.bvh_ngeom} ncam: {rc.nrender} cam_res: {rc.cam_res.numpy()}\n" - out += f"Rolling out {_NSTEP.value} steps at dt = {f'{m.opt.timestep.numpy()[0]:g}' if m.opt.timestep.numpy()[0] < 0.001 else f'{m.opt.timestep.numpy()[0]:.3f}'}..." - print(out) - - fn = _FUNCS[_FUNCTION.value] - res = benchmark(fn, m, d, _NSTEP.value, ctrls, _EVENT_TRACE.value, _MEASURE_ALLOC.value, _MEASURE_SOLVER.value, rc) - - match _FORMAT.value: - case "short": - _output_short(m, d, path, free_mem_at_init, *res) - case "json": - _output_json(m, d, path, free_mem_at_init, *res) - case "human": - _output_human(m, d, path, free_mem_at_init, *res) + register_sdf_plugins(mjw) + + return spec.compile() def main(): From 4348c31901b16b07099c4dd21f9eeb17f4b6ddce Mon Sep 17 00:00:00 2001 From: Erik Frey Date: Mon, 20 Apr 2026 17:48:05 -0700 Subject: [PATCH 2/2] Support for asset fetching from git repos. --- benchmarks/aloha_pot/__init__.py | 18 + ...8426c7d466d59b03a7f048c5304d28205b3069.stl | Bin 23384 -> 0 bytes .../original-10_col_collision_0.obj} | 0 .../original-10_col_collision_1.obj} | 0 .../original-10_col_collision_2.obj} | 0 .../original-11_col_collision_0.obj} | 0 .../original-13_col_collision_0.obj} | 0 .../original-13_col_collision_1.obj} | 0 .../original-13_col_collision_2.obj} | 0 .../original-13_col_collision_3.obj} | 0 .../original-13_col_collision_4.obj} | 0 .../original-13_col_collision_5.obj} | 0 .../original-13_col_collision_6.obj} | 0 .../original-13_col_collision_7.obj} | 0 .../original-14_col_collision_0.obj} | 0 .../original-14_col_collision_1.obj} | 0 .../original-14_col_collision_2.obj} | 0 .../original-14_col_collision_3.obj} | 0 .../original-14_col_collision_4.obj} | 0 .../original-14_col_collision_5.obj} | 0 .../original-14_col_collision_6.obj} | 0 .../original-14_col_collision_7.obj} | 0 .../original-14_col_collision_8.obj} | 0 .../original-17_col_collision_0.obj} | 0 .../original-17_col_collision_1.obj} | 0 .../original-17_col_collision_2.obj} | 0 .../original-17_col_collision_3.obj} | 0 .../original-19_0.obj} | 0 .../original-19_col_collision_0.obj} | 0 .../original-21_0.obj} | 0 .../original-21_col_collision_0.obj} | 0 .../original-21_col_collision_1.obj} | 0 .../original-21_col_collision_10.obj} | 0 .../original-21_col_collision_11.obj} | 0 .../original-21_col_collision_12.obj} | 0 .../original-21_col_collision_13.obj} | 0 .../original-21_col_collision_14.obj} | 0 .../original-21_col_collision_15.obj} | 0 .../original-21_col_collision_16.obj} | 0 .../original-21_col_collision_17.obj} | 0 .../original-21_col_collision_18.obj} | 0 .../original-21_col_collision_2.obj} | 0 .../original-21_col_collision_3.obj} | 0 .../original-21_col_collision_4.obj} | 0 .../original-21_col_collision_5.obj} | 0 .../original-21_col_collision_6.obj} | 0 .../original-21_col_collision_7.obj} | 0 .../original-21_col_collision_8.obj} | 0 .../original-21_col_collision_9.obj} | 0 .../original-22_0.obj} | 0 .../original-22_col_collision_0.obj} | 0 .../original-22_col_collision_1.obj} | 0 .../original-22_col_collision_2.obj} | 0 .../original-22_col_collision_3.obj} | 0 .../original-22_col_collision_4.obj} | 0 .../original-22_col_collision_5.obj} | 0 .../original-22_col_collision_6.obj} | 0 .../original-22_col_collision_7.obj} | 0 .../original-23_0.obj} | 0 .../original-23_col_collision_0.obj} | 0 .../original-23_col_collision_1.obj} | 0 .../original-23_col_collision_10.obj} | 0 .../original-23_col_collision_11.obj} | 0 .../original-23_col_collision_12.obj} | 0 .../original-23_col_collision_13.obj} | 0 .../original-23_col_collision_14.obj} | 0 .../original-23_col_collision_15.obj} | 0 .../original-23_col_collision_16.obj} | 0 .../original-23_col_collision_17.obj} | 0 .../original-23_col_collision_18.obj} | 0 .../original-23_col_collision_2.obj} | 0 .../original-23_col_collision_3.obj} | 0 .../original-23_col_collision_4.obj} | 0 .../original-23_col_collision_5.obj} | 0 .../original-23_col_collision_6.obj} | 0 .../original-23_col_collision_7.obj} | 0 .../original-23_col_collision_8.obj} | 0 .../original-23_col_collision_9.obj} | 0 .../original-25_0.obj} | 0 .../original-25_0.obj.mtl} | 0 .../original-25_col_collision_0.obj} | 0 .../original-25_col_collision_1.obj} | 0 .../original-26_0.obj} | 0 .../original-26_0.obj.mtl} | 0 .../original-26_col_collision_0.obj} | 0 .../original-26_col_collision_1.obj} | 0 .../original-27_0.obj} | 0 .../original-27_col_collision_0.obj} | 0 .../original-29_0.obj} | 0 .../original-29_0.obj.mtl} | 0 .../original-29_col_collision_0.obj} | 0 .../original-29_col_collision_1.obj} | 0 .../original-30_0.obj} | 0 .../original-30_0.obj.mtl} | 0 .../original-30_col_collision_0.obj} | 0 .../original-30_col_collision_1.obj} | 0 .../original-31_0.obj} | 0 .../original-31_col_collision_0.obj} | 0 .../original-5_0.obj} | 0 .../original-5_0.obj.mtl} | 0 .../original-5_col_collision_0.obj} | 0 .../original-5_col_collision_1.obj} | 0 .../original-5_col_collision_2.obj} | 0 .../original-5_col_collision_3.obj} | 0 .../original-5_col_collision_4.obj} | 0 .../original-5_col_collision_5.obj} | 0 .../original-5_col_collision_6.obj} | 0 .../original-5_col_collision_7.obj} | 0 .../original-5_col_collision_8.obj} | 0 .../original-6_0.obj} | 0 .../original-6_0.obj.mtl} | 0 .../original-6_col_collision_0.obj} | 0 .../original-6_col_collision_1.obj} | 0 .../original-6_col_collision_2.obj} | 0 .../original-6_col_collision_3.obj} | 0 .../original-6_col_collision_4.obj} | 0 .../original-6_col_collision_5.obj} | 0 .../original-6_col_collision_6.obj} | 0 .../original-6_col_collision_7.obj} | 0 .../original-7_0.obj} | 0 .../original-7_col_collision_0.obj} | 0 .../original-7_col_collision_1.obj} | 0 .../original-7_col_collision_2.obj} | 0 .../original-7_col_collision_3.obj} | 0 .../original-7_col_collision_4.obj} | 0 .../original-7_col_collision_5.obj} | 0 .../original-7_col_collision_6.obj} | 0 .../original-7_col_collision_7.obj} | 0 .../original-7_col_collision_8.obj} | 0 .../original-8_col_collision_0.obj} | 0 ...129cf77510d68c89cf2ddf67bd36dacef387b3.stl | Bin 25684 -> 0 bytes ...5f08a7e5e7488eb120fc62c3e6458e6be0f956.stl | Bin 6484 -> 0 bytes ...1ca8ed83291edde7bc9ab61d7d4828b37b0343.stl | Bin 40084 -> 0 bytes ...c8ad369e839057b4e10539978b87e39b5f81bf.stl | Bin 40084 -> 0 bytes ...e2ad6e912937b9c5f0ebde8e23f34ff982455a.stl | Bin 40084 -> 0 bytes ...e7ca5723c6e8bedf8a1138046f5419c7440b72.stl | Bin 84084 -> 0 bytes ...10c72c0b4ae36b2e4f79e29fe1fe8f3a9a678a.stl | Bin 84084 -> 0 bytes ...df49f763bf3784925b76eab16d8c28641a4529.stl | Bin 40084 -> 0 bytes ...df90098757a980b68bc9b546bddce3257c7263.stl | Bin 25684 -> 0 bytes benchmarks/aloha_pot/scene.xml | 269 ++++++------ ...055adb309111efb32fb9fc0417883865cf9bf2.obj | 414 ------------------ ...aaf6399ee429de60273fe61f29a7a7fcd20440.obj | 370 ---------------- ...72d9cc47a6f6792f1b4a7fd4ac6e6862d06105.obj | 190 -------- ...11efddeb54716caf91218e0beee848e0083aad.stl | Bin 49984 -> 0 bytes ...ee3af162e071b59ae35b1b7279fe257c375ffb.stl | Bin 63884 -> 0 bytes ...b3692a22ad52ba9b3c439033c552c51222ed28.stl | Bin 51384 -> 0 bytes ...4b69653fd0cc02e83bb7d65ba3e7ec1604b71c.stl | Bin 49584 -> 0 bytes ...55d345ad2564df22bcbd24557f5a69d362ef68.stl | Bin 49984 -> 0 bytes ...facdc0498ab0119fb164f573de994a27c7401e.stl | Bin 70784 -> 0 bytes ...f4b35b626deb7894668277f953fc4143ad9898.stl | Bin 25684 -> 0 bytes ...8e61f159d0594d74deb8fabda682e9971dc2b5.stl | Bin 25634 -> 0 bytes ...d29471843d7ca6e0e8a970bdc9256a822c8b15.stl | Bin 25684 -> 0 bytes ...982864f8591ef106a4b771fc7502c724ef3d7c.stl | Bin 25684 -> 0 bytes ...349941da5624f43b137273d462f62ab9605c36.stl | Bin 25684 -> 0 bytes ...c7acdce0b7e4d90ec0ec56b4fcd8a7ff0cf2e7.stl | Bin 25684 -> 0 bytes benchmarks/run.py | 72 ++- mujoco_warp/testspeed.py | 15 +- 157 files changed, 219 insertions(+), 1129 deletions(-) create mode 100644 benchmarks/aloha_pot/__init__.py delete mode 100644 benchmarks/aloha_pot/angled_extrusion-2b8426c7d466d59b03a7f048c5304d28205b3069.stl rename benchmarks/aloha_pot/{original-10_col_collision_0-208fe51a40113c78c2172ae79d2d0b8a5d9002d1.obj => assets/original-10_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-10_col_collision_1-e1c239941aa3757c1a8c08c0e7ac9ce503ec8d05.obj => assets/original-10_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-10_col_collision_2-e190f600631515ffcf851e485d44658c713792e2.obj => assets/original-10_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-11_col_collision_0-a478c968f22f8fb86ec096bfa4739e8fa1eeceaf.obj => assets/original-11_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_0-0cd922b53e782e2add994cbafff464e869755941.obj => assets/original-13_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_1-88e56b18a79a8daec67f71cf3dfb02c50659863c.obj => assets/original-13_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_2-ec8e1afc2bcaa23895712349e76fcd00eb0bd33f.obj => assets/original-13_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_3-722d5fffa71966e308e7f2993748005d70a874c9.obj => assets/original-13_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_4-61a0de5070f55e2bb145b0122ecba1848e40cae6.obj => assets/original-13_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_5-f927db3114dd0fe49bd66244990f88c818c756b3.obj => assets/original-13_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_6-cfce18dc0d773030ae0aeb24475d7789b68e858e.obj => assets/original-13_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-13_col_collision_7-d3a6f38e04f915c4ac7c0a5134a0b680881190b8.obj => assets/original-13_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_0-778f4a2bfbfe1a245ef5339cf88ba2d67f6047e3.obj => assets/original-14_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_1-ee44d4c9c075207d4618aa4990a635cce9621dd7.obj => assets/original-14_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_2-74987c61a726a3ac722b52fb4eee10763febd48d.obj => assets/original-14_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_3-928a14acef9d0fb5ceb5658cdb1e61bbec00b058.obj => assets/original-14_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_4-8977d2ce50ff654661aea7888c3851962f049c9c.obj => assets/original-14_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_5-c336653cef4a18fe2bc8967e34ca58404b73fa4d.obj => assets/original-14_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_6-6493d308c471712f4b27bd7ac69e433f779b31a6.obj => assets/original-14_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_7-403fcdc88dfbd4473e87852461b45193c22f7a5d.obj => assets/original-14_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-14_col_collision_8-634b94344d8aa949eb4e59ce7cfc72e6c6421751.obj => assets/original-14_col_collision_8.obj} (100%) rename benchmarks/aloha_pot/{original-17_col_collision_0-b439e444107a6087da79e6278eafc574c027bcd0.obj => assets/original-17_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-17_col_collision_1-ca56bb587dfb53ac2dc9a1b879f6ee4621776c47.obj => assets/original-17_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-17_col_collision_2-98d1a01665521786bae65a8926f051b0bfdbdbd6.obj => assets/original-17_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-17_col_collision_3-213ea4e7a3d15bd82c74f43117462d5098777802.obj => assets/original-17_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-19_0-7a5956077c32ec52183ba6330c26f2388b662199.obj => assets/original-19_0.obj} (100%) rename benchmarks/aloha_pot/{original-19_col_collision_0-ea922fffdad3044d90075c80dcb505681d487cb5.obj => assets/original-19_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-21_0-51797f8472c190ed84c6122055337442976fd74e.obj => assets/original-21_0.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_0-c8948b4fccbd63e4c4835435b6e32c87f0cd1b5b.obj => assets/original-21_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_1-2708605fa032bbd3c3458a0823fc3adb4e6095d1.obj => assets/original-21_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_10-225221cb64e522621919eddad8b1cbb56367ee40.obj => assets/original-21_col_collision_10.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_11-e3ef67903a31437ad5b27e2f0fca54596d68a026.obj => assets/original-21_col_collision_11.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_12-b44e24db22fafda8618c5c5c784debc3c74d4298.obj => assets/original-21_col_collision_12.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_13-cbc5cc87f26f9079dec574f7683dfd9e950cd10e.obj => assets/original-21_col_collision_13.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_14-8e8dfdca17412c2cacd2d3558f53110d9f9df0f2.obj => assets/original-21_col_collision_14.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_15-3a6e65dc60499d1b3ebabafd73eef5615cefc236.obj => assets/original-21_col_collision_15.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_16-3104b26d016115d98af353973731e730d3a6dc0a.obj => assets/original-21_col_collision_16.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_17-df37344b83d744900ac4fc2ca3397c2da1dba5cc.obj => assets/original-21_col_collision_17.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_18-e24714646f4c886da3b1472b959a9ada8f08333b.obj => assets/original-21_col_collision_18.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_2-3b94f002a719c9606862e1fb1227f9110825bb79.obj => assets/original-21_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_3-e4933c58c0e8ad8b2de88ff6af7f4293ad96929c.obj => assets/original-21_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_4-5465a7ef409ce22edd43097a0569168883c3eb5c.obj => assets/original-21_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_5-d03b05250829877106a511befd9cf6fa8823675a.obj => assets/original-21_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_6-12a5679233100eec0a3295abb54b1b7b9b4b0839.obj => assets/original-21_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_7-2374e4da93bd05a4065813d1d2efe3cd2102dfe7.obj => assets/original-21_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_8-d140e96d3a62e6fac0428a167cc13de2f120c57a.obj => assets/original-21_col_collision_8.obj} (100%) rename benchmarks/aloha_pot/{original-21_col_collision_9-6edf8358c6c7f7dd89929ae63b66ef778bd8746c.obj => assets/original-21_col_collision_9.obj} (100%) rename benchmarks/aloha_pot/{original-22_0-b6923025c8be39433f5b8ef1fac9d74f5ba3556b.obj => assets/original-22_0.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_0-db5abc551d7a44ee3d4d97301c152cb05af78767.obj => assets/original-22_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_1-96400f78b8859f07b401002cd19ffaa952da7468.obj => assets/original-22_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_2-8a318237a2ff73b64244d87128194ea897852e93.obj => assets/original-22_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_3-df7c5e4cd695911b0efeafbf97c62e1a82418c67.obj => assets/original-22_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_4-dc9963e0fb42ed6852e78415fdc74faa645347ee.obj => assets/original-22_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_5-6bcda3d287d1cfcabe91c62bc3aa506569f518b7.obj => assets/original-22_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_6-60b9408de472c6c15fcfe0ddb302b65c5bf9e960.obj => assets/original-22_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-22_col_collision_7-9382299967302621d8e6ed94305028a9b209dfd2.obj => assets/original-22_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-23_0-34c5d4471387579448d36399cc44ef392e8ef355.obj => assets/original-23_0.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_0-12ce5ed902c7b7a8a0c407f48118fff68016dfec.obj => assets/original-23_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_1-d498452198415d0e7d49f87079b6eeca643a356f.obj => assets/original-23_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_10-73c4c0aeef953ee56e3531c0f2ae64b2dc3655ce.obj => assets/original-23_col_collision_10.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_11-8b7a70b9746eb429fd6fb1555649ae813a4cee43.obj => assets/original-23_col_collision_11.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_12-486a9bb9b03dc60fb32bb6ca9f7fddbd172f08fa.obj => assets/original-23_col_collision_12.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_13-920bb87696882db99697715207acc1d326b62947.obj => assets/original-23_col_collision_13.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_14-f1351b3484dabfb2999f03923638186f714e52ae.obj => assets/original-23_col_collision_14.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_15-f8ede1030270611430302fee1fc06cf8f6a8c101.obj => assets/original-23_col_collision_15.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_16-d605d61a021487a768f29be67bf681bf19bbbd36.obj => assets/original-23_col_collision_16.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_17-c3f2ecf0799db93fd1d265370bb939e0f33c5c18.obj => assets/original-23_col_collision_17.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_18-bb412f7d3891d34d1425bf5829dcdb9576b7fee5.obj => assets/original-23_col_collision_18.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_2-6f4cedd984c14af625555605dec4650b7286d5fa.obj => assets/original-23_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_3-b71ea9d6f39011787da8fbb18f65ed5932cd23db.obj => assets/original-23_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_4-ea78c38f2458a8e06326875928b64ea676c3a083.obj => assets/original-23_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_5-d519cc650173b632bc1329ddf4c2ddcf9337d5cd.obj => assets/original-23_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_6-5a7124ea953dd835721ae4893a0d480c6202e9fc.obj => assets/original-23_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_7-552ef675dbe9332f84d2ec2bd523ca31c5fc9c21.obj => assets/original-23_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_8-a4f5b867c535a7b91a54511fd9e36eee82e9b943.obj => assets/original-23_col_collision_8.obj} (100%) rename benchmarks/aloha_pot/{original-23_col_collision_9-c3b5946fc3874b7ebfd1ac0f0a2bac3407b6d1ad.obj => assets/original-23_col_collision_9.obj} (100%) rename benchmarks/aloha_pot/{original-25_0-b85ee4e74c9ce3b86d1b7233bfccb4f6e11876c9.obj => assets/original-25_0.obj} (100%) rename benchmarks/aloha_pot/{original-25_0-b85ee4e74c9ce3b86d1b7233bfccb4f6e11876c9.obj.mtl => assets/original-25_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-25_col_collision_0-0f44eed200b016b11d4936140ec35102f9e8d4ab.obj => assets/original-25_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-25_col_collision_1-16ef9250fff030b5c0cc3df5565b7763875b1f11.obj => assets/original-25_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-26_0-0d95d51ef7bde4cdca2697b29a7e58076df9cb5f.obj => assets/original-26_0.obj} (100%) rename benchmarks/aloha_pot/{original-26_0-0d95d51ef7bde4cdca2697b29a7e58076df9cb5f.obj.mtl => assets/original-26_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-26_col_collision_0-259901813433e123bb23132256974b4cbb27f450.obj => assets/original-26_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-26_col_collision_1-87f2f4ceb88b73a331d804f2c4658746126af80f.obj => assets/original-26_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-27_0-078a04b6db2eff1ca910caab9aa265d77782cc6d.obj => assets/original-27_0.obj} (100%) rename benchmarks/aloha_pot/{original-27_col_collision_0-c5b903ddd2b86d74a023dc3caa2977ddb0414ae8.obj => assets/original-27_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-29_0-59204bd53e09bed87fb790d0204e6bc9aa92673b.obj => assets/original-29_0.obj} (100%) rename benchmarks/aloha_pot/{original-29_0-59204bd53e09bed87fb790d0204e6bc9aa92673b.obj.mtl => assets/original-29_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-29_col_collision_0-898f82718a43061e3f7d46041e964fe213a45c18.obj => assets/original-29_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-29_col_collision_1-c2c4706030166e8c1b0834f343d6812fdc8623e0.obj => assets/original-29_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-30_0-2cca1674b22089a5c0558949aa539d95f5fe9039.obj => assets/original-30_0.obj} (100%) rename benchmarks/aloha_pot/{original-30_0-2cca1674b22089a5c0558949aa539d95f5fe9039.obj.mtl => assets/original-30_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-30_col_collision_0-18bf7ffccaf2bf740bd3134f32fa2c221678fa0f.obj => assets/original-30_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-30_col_collision_1-249061bdc92ac3a5e4ee6614811f4d022863ac30.obj => assets/original-30_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-31_0-fac36bb29d030fdd3ee6d3150c46429a2c01fb6a.obj => assets/original-31_0.obj} (100%) rename benchmarks/aloha_pot/{original-31_col_collision_0-d7dd02393237429b33a2296feda0a0f2e3887e90.obj => assets/original-31_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-5_0-98c614ac600458b2d5a77e9abf8ac3930d0b3f01.obj => assets/original-5_0.obj} (100%) rename benchmarks/aloha_pot/{original-5_0-98c614ac600458b2d5a77e9abf8ac3930d0b3f01.obj.mtl => assets/original-5_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_0-03fd8fe1964def48aa4fe42635f9542bc6015573.obj => assets/original-5_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_1-543900e1c3bad73bd2b2a016cf4ae951dc16a798.obj => assets/original-5_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_2-6cc34f530a06ad54b80a9006aaf215bbac9509fa.obj => assets/original-5_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_3-e12322ca1c81b79a05bff62846ac490b8d1ac3d4.obj => assets/original-5_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_4-edc2a944b721ef784d23454f3252f30bae943bd2.obj => assets/original-5_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_5-7b80b71c4d74bf20ac97b1f0875e34a789547c53.obj => assets/original-5_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_6-6a99b40aab7dab531fef77ff92bdec5a3410b9bc.obj => assets/original-5_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_7-2a8b7651225ffadfd716665f99970af90a86e52f.obj => assets/original-5_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-5_col_collision_8-f3ede03f8a622ddcc01fc62430a1d6c807741421.obj => assets/original-5_col_collision_8.obj} (100%) rename benchmarks/aloha_pot/{original-6_0-15e7a1ee44f3e24dd5a8973509e8efd2b0169c8c.obj => assets/original-6_0.obj} (100%) rename benchmarks/aloha_pot/{original-6_0-15e7a1ee44f3e24dd5a8973509e8efd2b0169c8c.obj.mtl => assets/original-6_0.obj.mtl} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_0-91dd649f5629943594425caa55f1e4d5a4e93e0d.obj => assets/original-6_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_1-d99b4cd611d64e52b1529afd3668ba7bed221919.obj => assets/original-6_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_2-a2fcfa80779b37d0b35006ff6ff99d1e2d77e774.obj => assets/original-6_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_3-118912a3efd6064071faf75a14023617d7a29750.obj => assets/original-6_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_4-a5d16325a58a37ef9fa2bbdaf15b6d20f798e33e.obj => assets/original-6_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_5-da44cc1653ede725016118d7cdd0eceb1af55583.obj => assets/original-6_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_6-ebfef0d9372bf84dec2f832426530128338bbfb2.obj => assets/original-6_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-6_col_collision_7-dbb4279ab8f42b3a35de1b776130701108a50bc3.obj => assets/original-6_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-7_0-d32d72dd026c36e9694154a5d8aba6193d1c1878.obj => assets/original-7_0.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_0-3638c6eae9bf1f3ae55798660678516b5820fc46.obj => assets/original-7_col_collision_0.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_1-616d2b3c89ad237434b655c8490aa663274cb58f.obj => assets/original-7_col_collision_1.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_2-25c9e799427a1745776a8110a2b9aeb34cb5d3b3.obj => assets/original-7_col_collision_2.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_3-27e866ca632c952bcd7e8fb4d08b1c02ca70230f.obj => assets/original-7_col_collision_3.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_4-06b9a772794eb9b36235a69486bb86d42e381ad2.obj => assets/original-7_col_collision_4.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_5-4b6a8bb29df4bfb7dcc3af405310880df1109f0b.obj => assets/original-7_col_collision_5.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_6-505d98f451863b8794bb95c618796c8c752c6518.obj => assets/original-7_col_collision_6.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_7-2e466ad73a6129bf39af3c092662bc00b560a663.obj => assets/original-7_col_collision_7.obj} (100%) rename benchmarks/aloha_pot/{original-7_col_collision_8-7f396c1ac75f494900bf8db473bcc89d6412342d.obj => assets/original-7_col_collision_8.obj} (100%) rename benchmarks/aloha_pot/{original-8_col_collision_0-3e66afde19240856451b0fc8f5e31590e7e998f0.obj => assets/original-8_col_collision_0.obj} (100%) delete mode 100644 benchmarks/aloha_pot/corner_bracket-c4129cf77510d68c89cf2ddf67bd36dacef387b3.stl delete mode 100644 benchmarks/aloha_pot/d405_solid-a35f08a7e5e7488eb120fc62c3e6458e6be0f956.stl delete mode 100644 benchmarks/aloha_pot/extrusion_1000-421ca8ed83291edde7bc9ab61d7d4828b37b0343.stl delete mode 100644 benchmarks/aloha_pot/extrusion_1220-a3c8ad369e839057b4e10539978b87e39b5f81bf.stl delete mode 100644 benchmarks/aloha_pot/extrusion_150-62e2ad6e912937b9c5f0ebde8e23f34ff982455a.stl delete mode 100644 benchmarks/aloha_pot/extrusion_2040_1000-3ae7ca5723c6e8bedf8a1138046f5419c7440b72.stl delete mode 100644 benchmarks/aloha_pot/extrusion_2040_880-df10c72c0b4ae36b2e4f79e29fe1fe8f3a9a678a.stl delete mode 100644 benchmarks/aloha_pot/extrusion_600-87df49f763bf3784925b76eab16d8c28641a4529.stl delete mode 100644 benchmarks/aloha_pot/overhead_mount-2edf90098757a980b68bc9b546bddce3257c7263.stl delete mode 100644 benchmarks/aloha_pot/table_mesh_mapped-6c055adb309111efb32fb9fc0417883865cf9bf2.obj delete mode 100644 benchmarks/aloha_pot/tablelegs-d0aaf6399ee429de60273fe61f29a7a7fcd20440.obj delete mode 100644 benchmarks/aloha_pot/tabletop-2972d9cc47a6f6792f1b4a7fd4ac6e6862d06105.obj delete mode 100644 benchmarks/aloha_pot/vx300s_1_base-8911efddeb54716caf91218e0beee848e0083aad.stl delete mode 100644 benchmarks/aloha_pot/vx300s_2_shoulder-5dee3af162e071b59ae35b1b7279fe257c375ffb.stl delete mode 100644 benchmarks/aloha_pot/vx300s_3_upper_arm-f0b3692a22ad52ba9b3c439033c552c51222ed28.stl delete mode 100644 benchmarks/aloha_pot/vx300s_4_upper_forearm-6d4b69653fd0cc02e83bb7d65ba3e7ec1604b71c.stl delete mode 100644 benchmarks/aloha_pot/vx300s_5_lower_forearm-8555d345ad2564df22bcbd24557f5a69d362ef68.stl delete mode 100644 benchmarks/aloha_pot/vx300s_6_wrist-b3facdc0498ab0119fb164f573de994a27c7401e.stl delete mode 100644 benchmarks/aloha_pot/vx300s_7_gripper_bar-c5f4b35b626deb7894668277f953fc4143ad9898.stl delete mode 100644 benchmarks/aloha_pot/vx300s_7_gripper_prop-fb8e61f159d0594d74deb8fabda682e9971dc2b5.stl delete mode 100644 benchmarks/aloha_pot/vx300s_7_gripper_wrist_mount-61d29471843d7ca6e0e8a970bdc9256a822c8b15.stl delete mode 100644 benchmarks/aloha_pot/vx300s_8_custom_finger_left-bf982864f8591ef106a4b771fc7502c724ef3d7c.stl delete mode 100644 benchmarks/aloha_pot/vx300s_8_custom_finger_right-41349941da5624f43b137273d462f62ab9605c36.stl delete mode 100644 benchmarks/aloha_pot/wormseye_mount-4ac7acdce0b7e4d90ec0ec56b4fcd8a7ff0cf2e7.stl diff --git a/benchmarks/aloha_pot/__init__.py b/benchmarks/aloha_pot/__init__.py new file mode 100644 index 000000000..0c1d7a39c --- /dev/null +++ b/benchmarks/aloha_pot/__init__.py @@ -0,0 +1,18 @@ +ASSETS = [ + { + "source": "git@github.com:google-deepmind/mujoco_menagerie.git", + "ref": "affef0836947b64cc06c4ab1cbf0152835693374", + } +] + +BENCHMARKS = [ + { + "name": "aloha_pot", + "mjcf": "scene.xml", + "nworld": 8192, + "nconmax": 24, + "njmax": 128, + "replay": "lift_pot", + "assets": [(ASSETS[0], "aloha")], + }, +] diff --git a/benchmarks/aloha_pot/angled_extrusion-2b8426c7d466d59b03a7f048c5304d28205b3069.stl b/benchmarks/aloha_pot/angled_extrusion-2b8426c7d466d59b03a7f048c5304d28205b3069.stl deleted file mode 100644 index 9d223a414fa45747bcda78ea3687b992ea3db629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23384 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 SU);^rt`;Z3ZO&FHN&g2~!!`f_ diff --git a/benchmarks/aloha_pot/d405_solid-a35f08a7e5e7488eb120fc62c3e6458e6be0f956.stl b/benchmarks/aloha_pot/d405_solid-a35f08a7e5e7488eb120fc62c3e6458e6be0f956.stl deleted file mode 100644 index fb002c617cc78b5400de3fed8e85996a3ccce8b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6484 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 diff --git a/benchmarks/aloha_pot/extrusion_1000-421ca8ed83291edde7bc9ab61d7d4828b37b0343.stl b/benchmarks/aloha_pot/extrusion_1000-421ca8ed83291edde7bc9ab61d7d4828b37b0343.stl deleted file mode 100644 index 7393ead53c4115c080c94a19ab08e302f17308eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40084 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 HRK))U8Tgx6 diff --git a/benchmarks/aloha_pot/extrusion_150-62e2ad6e912937b9c5f0ebde8e23f34ff982455a.stl b/benchmarks/aloha_pot/extrusion_150-62e2ad6e912937b9c5f0ebde8e23f34ff982455a.stl deleted file mode 100644 index 68edb4ee26bccabe182e94279b05c459f81bc809..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40084 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 diff --git a/benchmarks/aloha_pot/extrusion_2040_1000-3ae7ca5723c6e8bedf8a1138046f5419c7440b72.stl b/benchmarks/aloha_pot/extrusion_2040_1000-3ae7ca5723c6e8bedf8a1138046f5419c7440b72.stl deleted file mode 100644 index 47a6d5c69817c003edc337f4cbc38664622879d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84084 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 TDMAS`KmH6_URH$rDB}MEbV1R7 diff --git a/benchmarks/aloha_pot/extrusion_2040_880-df10c72c0b4ae36b2e4f79e29fe1fe8f3a9a678a.stl b/benchmarks/aloha_pot/extrusion_2040_880-df10c72c0b4ae36b2e4f79e29fe1fe8f3a9a678a.stl deleted file mode 100644 index d45b459173d91026651e5c184b71b576c4bde535..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84084 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 kM|ukHw!uxAXf2D}j_}JESl7v`}f$ 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 HRK))U^Qn}m diff --git a/benchmarks/aloha_pot/overhead_mount-2edf90098757a980b68bc9b546bddce3257c7263.stl b/benchmarks/aloha_pot/overhead_mount-2edf90098757a980b68bc9b546bddce3257c7263.stl deleted file mode 100644 index 8626b458386878d560b524e5985bcbce3f37100c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25684 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 SIZ54z^$}V-68Q2TA^#7<8s(?} diff --git a/benchmarks/aloha_pot/scene.xml b/benchmarks/aloha_pot/scene.xml index e377efe39..117bbd5ae 100644 --- a/benchmarks/aloha_pot/scene.xml +++ b/benchmarks/aloha_pot/scene.xml @@ -1,5 +1,5 @@ - +