diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 2352d59cfd..bd0f0f8cfe 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -1,4 +1,4 @@ -name: Lint and Format +name: Precommit Checks (Lint and Format) on: pull_request: @@ -12,7 +12,7 @@ concurrency: jobs: pre-commit: runs-on: ubuntu-24.04 - name: ubuntu-24.04-3.12-examples + name: precommit-checks steps: - name: Checkout code uses: actions/checkout@v4 @@ -20,7 +20,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' # Update to your project's version + python-version: '3.12' - name: Run pre-commit hooks uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 38825590ed..3a3c342689 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -45,7 +45,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - name: Start container + + - name: Spawn Slurm job if: github.event_name == 'pull_request' run: | SLURM_JOB_NAME="$(uuidgen)_$(date +%Y%m%d_%H%M%S)" @@ -74,14 +75,10 @@ jobs: echo "SLURM_JOB_NAME=${SLURM_JOB_NAME}" >> $GITHUB_ENV echo "SRUN_COMMON=${SRUN_COMMON}" >> "$GITHUB_ENV" - - - name: Build + - name: Initialize Python virtual env if: github.event_name == 'pull_request' - run: | - srun ${SRUN_COMMON} \ - bash .github/workflows/scripts/production_build.sh - - - name: Run benchmarks + run: srun ${SRUN_COMMON} bash .github/workflows/scripts/production_build.sh + - name: Run unit tests if: github.event_name == 'pull_request' run: | srun ${SRUN_COMMON} bash -e -s <<'EOF' @@ -97,8 +94,7 @@ jobs: # tmate -S /tmp/tmate.sock wait tmate-exit EOF - - - name: Kill srun job systematically + - name: Kill Slurm job if: always() run: | if [ -n "${SLURM_JOB_NAME}" ] ; then @@ -127,7 +123,8 @@ jobs: # Checkout full history is required to shallow cloning while mark HEAD as "grafted". This breaks remote # tracking thereby making it impossible to detect whether a commit is contained in upstream main. fetch-depth: 0 - - name: Start container + + - name: Spawn Slurm job run: | SLURM_JOB_NAME="$(uuidgen)_$(date +%Y%m%d_%H%M%S)" CONTAINER_NAME="${SLURM_JOB_NAME}" @@ -158,12 +155,8 @@ jobs: echo "SLURM_JOB_NAME=${SLURM_JOB_NAME}" >> $GITHUB_ENV echo "SRUN_COMMON=${SRUN_COMMON}" >> "$GITHUB_ENV" - - - name: Build - run: | - srun ${SRUN_COMMON} \ - bash .github/workflows/scripts/production_build.sh - + - name: Initialize Python virtual env + run: srun ${SRUN_COMMON} bash .github/workflows/scripts/production_build.sh - name: Run benchmarks run: | srun ${SRUN_COMMON} bash -e -s <<'EOF' @@ -172,13 +165,13 @@ jobs: --print -x -m "benchmarks" ./tests cat speed_test*.txt > "/mnt/data/artifacts/speed_test_${SLURM_JOB_NAME}.txt" EOF - - - name: Kill srun job systematically + - name: Kill Slurm job if: always() run: | if [ -n "${SLURM_JOB_NAME}" ] ; then scancel --user=${USER} --name="${SLURM_JOB_NAME}" fi + - name: Display benchmark stats run: | cat "/mnt/data/artifacts/speed_test_${SLURM_JOB_NAME}.txt" diff --git a/examples/tutorials/visualization.py b/examples/tutorials/visualization.py index 1d81982eb3..eba0daa604 100644 --- a/examples/tutorials/visualization.py +++ b/examples/tutorials/visualization.py @@ -6,7 +6,7 @@ scene = gs.Scene( viewer_options=gs.options.ViewerOptions( - res=(1280, 960), + res=(1280, 960) if "PYTEST_VERSION" not in os.environ else (64, 64), camera_pos=(3.5, 0.0, 2.5), camera_lookat=(0.0, 0.0, 0.5), camera_fov=40, @@ -47,8 +47,8 @@ cam.start_recording() -horizon = 120 if "PYTEST_VERSION" not in os.environ else 5 -for i in range(120): +horizon = 120 if "PYTEST_VERSION" not in os.environ else 1 +for i in range(horizon): scene.step() cam.set_pose( pos=(3.0 * math.sin(i / 60), 3.0 * math.cos(i / 60), 2.5), diff --git a/genesis/engine/couplers/sap_coupler.py b/genesis/engine/couplers/sap_coupler.py index d28e0be8d8..1969075d45 100644 --- a/genesis/engine/couplers/sap_coupler.py +++ b/genesis/engine/couplers/sap_coupler.py @@ -854,6 +854,7 @@ def update_batch_active(self): norm_thr = self._sap_convergence_atol + self._sap_convergence_rtol * ti.max( self.sap_state[i_b].momentum_norm, self.sap_state[i_b].impulse_norm ) + self.batch_active[i_b] = self.sap_state[i_b].gradient_norm >= norm_thr @ti.kernel def compute_regularization( diff --git a/genesis/engine/solvers/rigid/rigid_solver_decomp.py b/genesis/engine/solvers/rigid/rigid_solver_decomp.py index c7d66efc67..93a8e90e5d 100644 --- a/genesis/engine/solvers/rigid/rigid_solver_decomp.py +++ b/genesis/engine/solvers/rigid/rigid_solver_decomp.py @@ -2877,8 +2877,9 @@ def kernel_init_meaninertia( for i_e in range(n_entities): for i_d in range(entities_info.dof_start[i_e], entities_info.dof_end[i_e]): I_d = [i_d, i_b] if ti.static(static_rigid_sim_config.batch_dofs_info) else i_d - # FIXME: this atomic is not necessary but for some reason it improves performance in our benchmarks - ti.atomic_add(rigid_global_info.meaninertia[i_b], rigid_global_info.mass_mat[i_d, i_d, i_b]) + rigid_global_info.meaninertia[i_b] = ( + rigid_global_info.meaninertia[i_b] + rigid_global_info.mass_mat[i_d, i_d, i_b] + ) rigid_global_info.meaninertia[i_b] = rigid_global_info.meaninertia[i_b] / n_dofs else: rigid_global_info.meaninertia[i_b] = 1.0 diff --git a/genesis/ext/pyrender/renderer.py b/genesis/ext/pyrender/renderer.py index 50a44aed94..4a700429f3 100644 --- a/genesis/ext/pyrender/renderer.py +++ b/genesis/ext/pyrender/renderer.py @@ -355,7 +355,7 @@ def _floor_pass(self, scene, flags, seg_node_map=None, env_idx=-1): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) V, P = self._get_camera_matrices(scene, env_idx) - cam_pose = self._get_camera_pose(scene, env_idx)[:3, 3] + cam_pos = self._get_camera_pose(scene, env_idx)[:3, 3] screen_size = np.array([self.viewport_width, self.viewport_height], np.float32) diff --git a/genesis/utils/image_exporter.py b/genesis/utils/image_exporter.py index cea527da27..f1681987b2 100644 --- a/genesis/utils/image_exporter.py +++ b/genesis/utils/image_exporter.py @@ -53,7 +53,7 @@ def as_grayscale_image( # Normalize values between 0.0 and 1.0 data_delta = data_max - data_min data_rel = data_float - data_min if black_to_white else data_max - data_float - data_normalized = np.divide(data_max - data_float, data_delta, where=data_delta > gs.EPS) + data_normalized = np.divide(data_rel, data_delta, where=data_delta > gs.EPS) # Discretize as unsigned int8 return (data_normalized * 255.0).astype(np.uint8) diff --git a/tests/test_examples.py b/tests/test_examples.py index 2163da84c4..b4e60fb53e 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -24,7 +24,6 @@ IGNORE_SCRIPT_NAMES = { "ddp_multi_gpu.py", "multi_gpu.py", - "visualization.py", # FIXME: Flaky because of possibly undefined shadow map when running in thread "single_franka_batch_render.py", # FIXME: segfault on exit "fem_cube_linked_with_arm.py", # FIXME: segfault on exit (corrupted double-linked list) } @@ -33,7 +32,7 @@ "cut_dragon.py", } -TIMEOUT = 500.0 +TIMEOUT = 600.0 pytestmark = [ diff --git a/tests/test_rigid_physics.py b/tests/test_rigid_physics.py index da2af310cc..ad91052cab 100644 --- a/tests/test_rigid_physics.py +++ b/tests/test_rigid_physics.py @@ -2207,7 +2207,7 @@ def test_nan_reset(gs_sim, mode): ], ) @pytest.mark.parametrize("is_named", [True, False]) -def test_terrain_generation(is_named, show_viewer): +def test_terrain_generation(is_named, show_viewer, tol): TERRAIN_PATTERN = [ ["flat_terrain", "flat_terrain", "flat_terrain", "flat_terrain", "flat_terrain"], ["flat_terrain", "fractal_terrain", "random_uniform_terrain", "sloped_terrain", "flat_terrain"], @@ -2287,7 +2287,7 @@ def test_terrain_generation(is_named, show_viewer): scene = gs.Scene() terrain_2 = scene.add_entity(gs.morphs.Terrain(**{**terrain_kwargs, **dict(randomize=True)})) terrain_2_mesh = terrain_2.geoms[0].mesh - assert_allclose(terrain_mesh.verts, terrain_2_mesh.verts, tol=gs.EPS) + assert_allclose(terrain_mesh.verts, terrain_2_mesh.verts, tol=tol) @pytest.mark.required diff --git a/tests/utils.py b/tests/utils.py index cbf1dfc1c9..da999d704f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -36,7 +36,7 @@ DEFAULT_BRANCH_NAME = "main" HUGGINGFACE_ASSETS_REVISION = "701f78c1465f0a98f6540bae6c9daacaa551b7bf" -HUGGINGFACE_SNAPSHOT_REVISION = "f13f28423a8961072832ead74df5d5703e01923e" +HUGGINGFACE_SNAPSHOT_REVISION = "17d79e7627479ef836524d14449e2fdc4282973d" MESH_EXTENSIONS = (".mtl", *MESH_FORMATS, *GLTF_FORMATS, *USD_FORMATS) IMAGE_EXTENSIONS = (".png", ".jpg")