bartulem/usv-playpen: v0.11.4
Authors/Creators
- 1. Princeton Neuroscience Institute
- 2. Princeton University
Description
v0.11.4
Build-environment fix release. Every GPU job that used a JAX engine — the multinomial, bivariate/continuous, and CNN modeling runners — was failing on the cluster, and the failure was not in the modeling code at all: torch's PyPI wheels had silently migrated to CUDA 13, which collides with the CUDA-12 wheels jax[cuda12] requires. This release pins the whole GPU stack to CUDA 12, fixes a second (independent) bug where SLURM never actually bound a GPU to array-job tasks, and floors three Dependabot advisories. No behavioural changes to processing or analysis; no data-integrity fixes. v0.11.3 results are unaffected.
⚠️ Who is affected
- Anyone running GPU modeling jobs (
main_univariate_dispatcher/main_model_selection_dispatcherwith the JAX engines). These were failing outright. - Anyone who re-syncs their environment.
torchnow resolves from PyTorch's CUDA-12.8 index rather than PyPI (see Upgrading). - Anyone with a deployed cluster checkout. A
git pullalone is not sufficient — see Upgrading.
Fixed
The CUDA-13 / CUDA-12 cuDNN collision that broke every JAX GPU job.
torch's PyPI wheels now default to a CUDA 13 build, dragging innvidia-cudnn-cu13,nvidia-cublas13,nvidia-cusparselt-cu13,nvidia-nccl-cu13andcuda-toolkit13.jax[cuda12]needs the CUDA-12 wheels. Both sets installlibcudnn.so.9into the samenvidia/cudnn/namespace directory, so the cu13-built cuDNN wins the file and JAX's cu12 process cannot create a cuDNN handle. The job died at the very first GPU op (jnp.array) with:Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED RET_CHECK failure (gpu_compiler.cc:2641) dnn_support != nullptrtorchandtorchvisionare now pinned to PyTorch's cu128 index (torch 2.11.0+cu128,torchvision 0.26.0+cu128), so the entire GPU stack stays on CUDA 12 and no*-cu13wheel is installed at all.The pin is scoped to Linux (
marker = "sys_platform == 'linux'"). There is no CUDA on macOS and the cu128 index ships no macOS wheel, so an unscoped pin makes the package uninstallable there; macOS and Windows fall back to PyPI, where no cu12/cu13 collision can occur. The CUDA-12 pin is only meaningful on Linux anyway — that is wherejax[cuda12]and the GPU cluster live.Two notes on the diagnosis, because both cost real time:
- XLA's accompanying
Possibly insufficient driver version: 575.57.8is a red herring — driver 575 is perfectly adequate for CUDA 12. The message is XLA's generic fallback whenever cuDNN init fails for any reason. - CUDA 13 is not a viable target here. The cluster is heterogeneous: some GPU nodes run driver 575 (CUDA 12.9), others 580 (CUDA 13.0). CUDA 12 runs on both; a CUDA-13 stack would fail whenever SLURM landed the job on a 575 node. CUDA 12 is the only safe common target.
- XLA's accompanying
torchvisionpromoted to a direct dependency. It was transitive-only, so the[tool.uv.sources]cu128 pin did not apply to it and it kept resolving from PyPI — a build whose compiled ops do not match a cu128torch. Anything importing it (sam2 box-prompt masks, vocalocator, QLVM training) failed with:RuntimeError: operator torchvision::nms does not existThis was invisible to the multinomial job (it never imports
torchvision) and was only caught by running the full suite against the actual locked environment.SLURM never bound a GPU to array-job tasks (
--gpusvs--gres). The modeling scripts requested#SBATCH --gpus=1. That accounts a GPU — it duly appears inAllocTRESasgres/gpu=1— but it does not reliably bind the device into an array task's cgroup.CUDA_VISIBLE_DEVICESwas left unset, and the JAX engines died withCUDA_ERROR_NO_DEVICEon a node that visibly had an idle GPU. Both scripts now use#SBATCH --gres=gpu:1, which actually binds it. The gotcha is documented inline so it does not get "fixed" back.
Security
Three Dependabot advisories closed by flooring two transitive dependencies ([tool.uv] constraint-dependencies):
| alert | package | was | now | issue |
|---|---|---|---|---|
| #54 | mistune | 3.2.1 | 3.3.3 | quadratic-time DoS in parse_link_text (CWE-400) |
| #53 | soupsieve | 2.8 | 2.8.4 | unbounded memory on comma-separated selector lists |
| #52 | soupsieve | 2.8 | 2.8.4 | ReDoS via catastrophic backtracking in the attribute-selector VALUE regex |
Both are docs-only transitive dependencies (mistune via nbsphinx/jupyterlab, soupsieve via furo/nbsphinx/jupyterlab), and usv-playpen never parses untrusted Markdown or user-supplied CSS selectors — so practical exposure is nil. They are floored anyway because uv's lock is sticky: regenerating uv.lock for an unrelated change (the torch pin, in this very release) leaves transitive deps untouched, so a patched version is only ever picked up if it is explicitly pinned.
Cluster scripts (housekeeping — no behavioural change)
model_selection_behavior.shandunivariate_modeling_behavior.shmoved fromother/cluster/modeling/toother/cluster/usv_playpen/, alongside every other cluster job script. The now-emptymodeling/directory is gone.- XLA log spam silenced.
TF_CPP_MIN_LOG_LEVEL=3+GLOG_minloglevel=2suppress XLA's ERROR-leveldevice_type: DEVICE_TYPE_INVALIDTriton-GEMM messages, which otherwise bury the real output in.err. Verified on the cluster: cosmetic only — no change to the computation, the results, or the runtime. - GPU provenance line. Every job now logs its node,
CUDA_VISIBLE_DEVICES, andnvidia-smi -L. An emptyCUDA_VISIBLE_DEVICESis the immediate tell for the binding bug above, and recording which GPU ran the job matters on a heterogeneous cluster (A100-40G vs L40S-46G). Informational only — the pyGAM analysis types (onset/params/category) are CPU-only and are never failed by it.
Upgrading
uv sync --extra gpu --group docs
On Linux, torch and torchvision now come from https://download.pytorch.org/whl/cu128 instead of PyPI: expect torch 2.11.0+cu128 and torchvision 0.26.0+cu128, and every nvidia-*-cu13 wheel to disappear. On macOS and Windows nothing changes — they continue to resolve from PyPI (CPU/MPS builds), since the CUDA pin is Linux-scoped.
On a deployed cluster checkout, git pull alone is not enough — the environment still holds the mismatched PyPI torchvision until you re-sync:
git pull
uv sync --extra gpu # <- required; installs torchvision 0.26.0+cu128
Without it, any job importing torchvision (sam2, vocalocator, QLVM training) still hits torchvision::nms does not exist.
If you copy the modeling job scripts by path, note they now live under other/cluster/usv_playpen/, and adopt --gres=gpu:1 in any local copy you maintain.
Full suite green (2184 passed).
Full changelog: v0.11.3...v0.11.4
Files
bartulem/usv-playpen-v0.11.4.zip
Files
(55.0 MB)
| Name | Size | Download all |
|---|---|---|
|
md5:09d95ae31584fda908c28d2aa06bb5a6
|
55.0 MB | Preview Download |
Additional details
Related works
- Is supplement to
- Software: https://github.com/bartulem/usv-playpen/tree/v0.11.4 (URL)
Software
- Repository URL
- https://github.com/bartulem/usv-playpen