Repository navigation
Expand file tree
/
Copy pathrl.def
More file actions
100 lines (88 loc) · 4.07 KB
/
Copy pathrl.def
File metadata and controls
100 lines (88 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Bootstrap: docker
# Ubuntu 24.04 provides glibc 2.39. This is new enough for the driver-side
# EGL/GL libraries injected by the B200 cluster (which require GLIBC_2.38) and
# remains backward-compatible with driver libraries from the V100/A100 hosts.
From: nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04
%files
pyproject.toml /opt/vbrl-src/pyproject.toml
uv.lock /opt/vbrl-src/uv.lock
.python-version /opt/vbrl-src/.python-version
README.md /opt/vbrl-src/README.md
src/vbrl /opt/vbrl-src/src/vbrl
%environment
export PYTHONDONTWRITEBYTECODE=1
export PYTHONUNBUFFERED=1
export PYTHONNOUSERSITE=1
export PATH=/opt/venv/bin:$PATH
export MUJOCO_GL=egl
export MPLBACKEND=Agg
# $HOME is read-only during the build and shared or quota-limited on compute
# nodes; without this matplotlib warns and re-scans its font cache per job.
export MPLCONFIGDIR=/tmp/matplotlib
export PYOPENGL_PLATFORM=egl
export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1
%post
set -e
# uv creates and populates /opt/venv, so pip and venv are not needed; git is,
# for the pinned R3M source dependency.
apt-get update && apt-get install -y --no-install-recommends \
python3 python3-dev \
git curl ca-certificates ffmpeg \
libegl1 libgl1 libgles2 libglvnd0 libglx0 libopengl0 \
libosmesa6 libglfw3 \
&& rm -rf /var/lib/apt/lists/*
# pyproject.toml plus uv.lock is the single environment specification. uv
# installs the exact transitive closure the lockfile pins, with hashes, and a
# development host runs `uv sync` against the same file -- so the image and
# the workstation cannot drift. Bump a version by editing pyproject.toml,
# running `uv lock`, and rebuilding this image.
curl -LsSf https://astral.sh/uv/0.12.5/install.sh \
| env UV_INSTALL_DIR=/usr/local/bin INSTALLER_NO_MODIFY_PATH=1 sh
# --frozen refuses to re-resolve, so the build fails loudly if uv.lock is
# stale rather than quietly installing something else. --no-dev keeps ruff,
# mypy, and build out of the image. --no-editable installs vbrl as a regular
# wheel, which is what supplies the mjlab.tasks entry point that fresh
# TorchrunX workers discover; a bound checkout still wins via PYTHONPATH.
cd /opt/vbrl-src
UV_PROJECT_ENVIRONMENT=/opt/venv uv sync --frozen --no-dev --no-editable
export PATH="/opt/venv/bin:${PATH}"
# Bake the backbones in so a cluster job never touches the network. Each
# upstream caches in its own layout under one root; a development host runs
# the same command. %environment is not applied during %post, but set these
# explicitly so the build cannot be broken by a future export of them.
HF_HUB_OFFLINE=0 TRANSFORMERS_OFFLINE=0 vbrl-fetch-backbones /opt/vbrl-models
vbrl-fetch-backbones /opt/vbrl-models --verify
chmod -R a+rX /opt/vbrl-models
%test
# Validate the vendor-neutral graphics ABI without requiring a GPU during
# the build. Apptainer --nv supplies only the host-specific NVIDIA side.
python - <<'PY'
import ctypes
for library in ("libEGL.so.1", "libOpenGL.so.0", "libGL.so.1"):
ctypes.CDLL(library)
from OpenGL import EGL
import mjlab
import mujoco
assert EGL.eglQueryString is not None
# MJLab registers its own Mjlab-* tasks, so ownership comes from the
# registration delta vbrl.tasks records, never from a name prefix.
from vbrl.tasks import vbrl_task_ids
# One known ID per task family rather than a count, so registering a new
# architecture does not require editing this file. tests/test_task_registration
# pins the exact set.
task_ids = set(vbrl_task_ids())
expected = {
"Mjlab-LiftCube-CollisionCam-DinoV2ViTS14-LocalGrid7-Trossen",
"Mjlab-LiftCube-RealTexture-DinoV2ViTS14-LocalGrid7-Trossen",
"Mjlab-PushT-State-TrossenIdentified",
}
missing = expected - task_ids
assert not missing, (
"Installed VBRL task entry point did not populate the task-local "
f"registrations; missing: {sorted(missing)}"
)
print(f"MuJoCo {mujoco.__version__}: EGL/OpenGL available, {len(task_ids)} tasks")
PY
%runscript
exec "$@"