diff --git a/genesis/engine/solvers/rigid/rigid_solver.py b/genesis/engine/solvers/rigid/rigid_solver.py index 053d275ac..42e926cd1 100644 --- a/genesis/engine/solvers/rigid/rigid_solver.py +++ b/genesis/engine/solvers/rigid/rigid_solver.py @@ -454,6 +454,9 @@ def _build_static_config(self): # Prefer the monolith solver on CPU (always faster there, perf dispatch is a waste of effort) if gs.backend == gs.cpu or self.sim.options.requires_grad: static_rigid_sim_config["prefer_decomposed_solver"] = 0 + # Prefer the decomposed solver on CUDA, which supports hardware accelerated graph and do-while condition + elif gs.backend == gs.cuda: + static_rigid_sim_config["prefer_decomposed_solver"] = 1 if self.is_active: # TODO: These alternative tiled algorithms are designed to reduce the impact of latency. However, naive diff --git a/genesis/ext/_trimesh_patch.py b/genesis/ext/_trimesh_patch.py index 95d0afd31..906f23d65 100644 --- a/genesis/ext/_trimesh_patch.py +++ b/genesis/ext/_trimesh_patch.py @@ -1,5 +1,6 @@ import os import re +import warnings from collections import defaultdict, deque import numpy as np @@ -25,6 +26,14 @@ import genesis as gs +# Silence trimesh mass_properties divide-by-zero on degenerate meshes. +warnings.filterwarnings( + "ignore", + category=RuntimeWarning, + message=r"(divide by zero|invalid value) encountered in (divide|scalar multiply)", +) + + def load_obj( file_obj, resolver=None, diff --git a/pyproject.toml b/pyproject.toml index d0d94360c..094aad52c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -178,7 +178,9 @@ ignore = [ [tool.pytest.ini_options] addopts = [ "--verbose", - "-r", "a", + # Exclude 'f' (failed) from short test summary because it duplicates the FAILURES section in verbose mode. + # A plain list of failed test IDs is printed instead by 'pytest_terminal_summary' hook in tests/conftest.py. + "-r", "EsxXw", "--color=yes", "--import-mode=importlib", "--pdbcls=IPython.terminal.debugger:TerminalPdb", diff --git a/tests/conftest.py b/tests/conftest.py index 6715188aa..63497ccbb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -487,6 +487,29 @@ def pytest_runtest_makereport(item, call): report.longrepr = (os.path.relpath(__file__), lineno, reason) +def pytest_terminal_summary(terminalreporter, exitstatus, config): + """Print a plain list of failed test IDs at the end of the run. + + Replaces pytest's default 'FAILED test_id - msg' short summary lines (which in verbose mode + duplicate the FAILURES section) with a compact, easy-to-scan ID-only list. + """ + failed = terminalreporter.stats.get("failed") + if not failed: + return + terminalreporter.write_sep("=", "Failed tests") + fullwidth = terminalreporter._tw.fullwidth + for report in failed: + reprcrash = getattr(report.longrepr, "reprcrash", None) + msg = " ".join(reprcrash.message.split()) if reprcrash is not None else "" + if not msg: + terminalreporter.write_line(report.nodeid) + continue + line = f"{report.nodeid} - {msg}" + if len(line) > fullwidth: + line = line[: fullwidth - 3] + "..." + terminalreporter.write_line(line) + + def pytest_addoption(parser: pytest.Parser) -> None: parser.addoption("--backend", action="store", default=None, help="Default simulation backend.") parser.addoption(