From 0b8fc625579d3dd841e0513d0329f0606635aca5 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 10:45:20 +0200 Subject: [PATCH 01/10] test module skill with careless --- careless/README.md | 24 ++++++++++++++++++++++++ careless/build | 27 +++++++++++++++++++++++++++ careless/files/config.yaml | 11 +++++++++++ careless/modulefile | 16 ++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 careless/README.md create mode 100755 careless/build create mode 100644 careless/files/config.yaml create mode 100644 careless/modulefile diff --git a/careless/README.md b/careless/README.md new file mode 100644 index 0000000..9901225 --- /dev/null +++ b/careless/README.md @@ -0,0 +1,24 @@ +# careless + +Scaling and merging of X-ray diffraction data with approximate Bayesian +inference (variational merging), built on TensorFlow. + +- Upstream: https://github.com/rs-station/careless +- License: MIT + +## How it is built + +The build installs a private miniconda into `$PREFIX/miniconda`, creates a +`careless_` env with Python 3.12 (upstream supports >=3.9,<3.13), +and runs `pip install careless[cuda]==` inside it. The `[cuda]` +extra pulls the NVIDIA libraries as pip wheels, so the same install works +on GPU and CPU-only Ra nodes. + +Loading the module puts the env's `bin/` on `PATH` (the `careless` command +is directly available, no `conda activate` needed) and sets `CARELESS_ENV` +to the conda env path. + +## Adding a new version + +Add the version under `versions:` in `files/config.yaml`, then on a Ra +login node: `./build `. diff --git a/careless/build b/careless/build new file mode 100755 index 0000000..8869288 --- /dev/null +++ b/careless/build @@ -0,0 +1,27 @@ +#!/usr/bin/env modbuild + +pbuild::prep() { + : +} + +pbuild::configure() { + # careless is pip-installed, but upstream recommends a fresh conda env + # (TensorFlow dependency conflicts), so install a private miniconda in PREFIX + mkdir -p "$PREFIX/miniconda" + wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O "$PREFIX/miniconda/miniconda.sh" + bash "$PREFIX/miniconda/miniconda.sh" -b -u -p "$PREFIX/miniconda/" + "$PREFIX/miniconda/condabin/conda" create -y -n "careless_$V" python=3.12 +} + +pbuild::compile() { + : +} + +pbuild::install() { + source "$PREFIX/miniconda/etc/profile.d/conda.sh" + conda activate "careless_$V" + pip install --upgrade pip + # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too + pip install --no-cache-dir "careless[cuda]==${V_PKG}" + conda deactivate +} diff --git a/careless/files/config.yaml b/careless/files/config.yaml new file mode 100644 index 0000000..cfd5995 --- /dev/null +++ b/careless/files/config.yaml @@ -0,0 +1,11 @@ +--- +format: 1 +careless: + defaults: + group: MX + overlay: base + relstage: unstable + versions: + 0.5.4: + config: + relstage: unstable diff --git a/careless/modulefile b/careless/modulefile new file mode 100644 index 0000000..e2c2743 --- /dev/null +++ b/careless/modulefile @@ -0,0 +1,16 @@ +#%Module1.0 + +module-whatis "careless - merging crystallography data with variational inference" +module-url "https://github.com/rs-station/careless" +module-license "MIT" +module-maintainer "MX Data " + +module-help " +careless: scaling and merging of X-ray diffraction data using +approximate Bayesian inference (TensorFlow). Installed with the +[cuda] extra, so it uses NVIDIA GPUs when available and falls +back to CPU otherwise. +" + +setenv CARELESS_ENV $PREFIX/miniconda/envs/careless_$V +prepend-path PATH $PREFIX/miniconda/envs/careless_$V/bin From c0410dfe2d168e91ad8fd44dd7caed87bf62e706 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 10:51:44 +0200 Subject: [PATCH 02/10] careless: build venv with uv instead of conda (anaconda.com blocked on Ra) Co-Authored-By: Claude Fable 5 --- careless/README.md | 21 ++++++++++++--------- careless/build | 17 ++++++----------- careless/modulefile | 4 ++-- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/careless/README.md b/careless/README.md index 9901225..b2df471 100644 --- a/careless/README.md +++ b/careless/README.md @@ -8,17 +8,20 @@ inference (variational merging), built on TensorFlow. ## How it is built -The build installs a private miniconda into `$PREFIX/miniconda`, creates a -`careless_` env with Python 3.12 (upstream supports >=3.9,<3.13), -and runs `pip install careless[cuda]==` inside it. The `[cuda]` -extra pulls the NVIDIA libraries as pip wheels, so the same install works -on GPU and CPU-only Ra nodes. +Upstream recommends a fresh conda env, but repo.anaconda.com is not +reachable from Ra, so the build uses uv instead: it fetches a standalone +Python 3.12 into `$PREFIX/python` (upstream supports >=3.9,<3.13), creates +`$PREFIX/venv`, and runs `uv pip install careless[cuda]==` into +it. The `[cuda]` extra pulls the NVIDIA libraries as pip wheels, so the +same install works on GPU and CPU-only Ra nodes. -Loading the module puts the env's `bin/` on `PATH` (the `careless` command -is directly available, no `conda activate` needed) and sets `CARELESS_ENV` -to the conda env path. +`uv` must be on PATH on the build host (e.g. `pip install --user uv`). + +Loading the module puts the venv's `bin/` on `PATH` (the `careless` +command is directly available, no activation needed) and sets +`CARELESS_ENV` to the venv path. ## Adding a new version Add the version under `versions:` in `files/config.yaml`, then on a Ra -login node: `./build `. +login node: `modbuild build ` (modbuild/2.1.2). diff --git a/careless/build b/careless/build index 8869288..95a9d6c 100755 --- a/careless/build +++ b/careless/build @@ -5,12 +5,11 @@ pbuild::prep() { } pbuild::configure() { - # careless is pip-installed, but upstream recommends a fresh conda env - # (TensorFlow dependency conflicts), so install a private miniconda in PREFIX - mkdir -p "$PREFIX/miniconda" - wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O "$PREFIX/miniconda/miniconda.sh" - bash "$PREFIX/miniconda/miniconda.sh" -b -u -p "$PREFIX/miniconda/" - "$PREFIX/miniconda/condabin/conda" create -y -n "careless_$V" python=3.12 + # repo.anaconda.com is unreachable from Ra (GnuTLS error), so no conda. + # uv fetches a standalone CPython instead; keep it inside PREFIX so the + # venv's interpreter symlinks don't depend on the builder's home cache. + export UV_PYTHON_INSTALL_DIR="$PREFIX/python" + uv venv --python 3.12 "$PREFIX/venv" } pbuild::compile() { @@ -18,10 +17,6 @@ pbuild::compile() { } pbuild::install() { - source "$PREFIX/miniconda/etc/profile.d/conda.sh" - conda activate "careless_$V" - pip install --upgrade pip # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too - pip install --no-cache-dir "careless[cuda]==${V_PKG}" - conda deactivate + uv pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" } diff --git a/careless/modulefile b/careless/modulefile index e2c2743..54ec7d0 100644 --- a/careless/modulefile +++ b/careless/modulefile @@ -12,5 +12,5 @@ approximate Bayesian inference (TensorFlow). Installed with the back to CPU otherwise. " -setenv CARELESS_ENV $PREFIX/miniconda/envs/careless_$V -prepend-path PATH $PREFIX/miniconda/envs/careless_$V/bin +setenv CARELESS_ENV $PREFIX/venv +prepend-path PATH $PREFIX/venv/bin From 6f7523601b62612be078b21d42ea92c590706544 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 10:54:10 +0200 Subject: [PATCH 03/10] careless: call uv by explicit path, modbuild strips ~/.local/bin from PATH Co-Authored-By: Claude Fable 5 --- careless/build | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/careless/build b/careless/build index 95a9d6c..6af67fd 100755 --- a/careless/build +++ b/careless/build @@ -8,8 +8,10 @@ pbuild::configure() { # repo.anaconda.com is unreachable from Ra (GnuTLS error), so no conda. # uv fetches a standalone CPython instead; keep it inside PREFIX so the # venv's interpreter symlinks don't depend on the builder's home cache. + # modbuild's shell strips ~/.local/bin from PATH; override with UV=/path/to/uv if needed + UV="${UV:-$HOME/.local/bin/uv}" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" - uv venv --python 3.12 "$PREFIX/venv" + "$UV" venv --python 3.12 "$PREFIX/venv" } pbuild::compile() { @@ -17,6 +19,7 @@ pbuild::compile() { } pbuild::install() { + UV="${UV:-$HOME/.local/bin/uv}" # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too - uv pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" } From f983b0a174a89b5a8fc16699bdc58de566367755 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 10:55:59 +0200 Subject: [PATCH 04/10] careless: put uv cache under PREFIX, home quota too small for TF wheels Co-Authored-By: Claude Fable 5 --- careless/build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/careless/build b/careless/build index 6af67fd..189d84a 100755 --- a/careless/build +++ b/careless/build @@ -10,6 +10,8 @@ pbuild::configure() { # venv's interpreter symlinks don't depend on the builder's home cache. # modbuild's shell strips ~/.local/bin from PATH; override with UV=/path/to/uv if needed UV="${UV:-$HOME/.local/bin/uv}" + # ~/.cache/uv hits the home disk quota; cache under PREFIX (removed after install) + export UV_CACHE_DIR="$PREFIX/.uv-cache" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" } @@ -20,6 +22,8 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" + export UV_CACHE_DIR="$PREFIX/.uv-cache" # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" + rm -rf "$UV_CACHE_DIR" } From b55d6c1d91536f480b604c40dd8affe3d44307d8 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:07:12 +0200 Subject: [PATCH 05/10] Split careless into CPU module and careless-gpu using cuda/12.8.1 module careless installs plain careless (CPU). careless-gpu also installs plain careless but declares cuda/12.8.1 as build_requires/runtime_deps (jfjoch_viewer pattern) instead of pip-bundling CUDA via the [cuda] extra. Both builds honor UV_CACHE_DIR to share one download cache. Co-Authored-By: Claude Fable 5 --- careless-gpu/README.md | 28 ++++++++++++++++++++++++++++ careless-gpu/build | 26 ++++++++++++++++++++++++++ careless-gpu/files/config.yaml | 13 +++++++++++++ careless-gpu/modulefile | 16 ++++++++++++++++ careless/README.md | 11 ++++++++--- careless/build | 16 +++++++++------- careless/modulefile | 5 ++--- 7 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 careless-gpu/README.md create mode 100755 careless-gpu/build create mode 100644 careless-gpu/files/config.yaml create mode 100644 careless-gpu/modulefile diff --git a/careless-gpu/README.md b/careless-gpu/README.md new file mode 100644 index 0000000..fab39aa --- /dev/null +++ b/careless-gpu/README.md @@ -0,0 +1,28 @@ +# careless-gpu + +GPU build of careless (see `../careless/` for the CPU module and the full +background). Scaling and merging of X-ray diffraction data with approximate +Bayesian inference (variational merging), built on TensorFlow. + +- Upstream: https://github.com/rs-station/careless +- License: MIT + +## How it differs from the careless module + +- CUDA is not pip-installed (no `[cuda]` extra, saves several GB): the + cluster `cuda/12.8.1` module provides it instead, declared as + `build_requires`/`runtime_deps` (same pattern as `jfjoch_viewer`). + `runtime_deps` matters because TensorFlow dlopens the CUDA libraries + when careless runs, so cuda must auto-load with this module. +- If careless reports missing cuDNN at runtime, the cuda module does not + ship it; the fallback is installing `careless[cuda]` in `build` instead. + +The venv layout, uv usage, and cache handling are identical to `careless`. +To share one download cache between both builds, run each with +`UV_CACHE_DIR= modbuild build ` — a cache outside +PREFIX is kept, an in-PREFIX cache is removed after a successful install. + +## Adding a new version + +Add the version under `versions:` in `files/config.yaml`, then on a Ra +login node: `modbuild build ` (modbuild/2.1.2). diff --git a/careless-gpu/build b/careless-gpu/build new file mode 100755 index 0000000..49cb4e9 --- /dev/null +++ b/careless-gpu/build @@ -0,0 +1,26 @@ +#!/usr/bin/env modbuild + +pbuild::prep() { + : +} + +pbuild::configure() { + # same uv pattern as the careless (CPU) module; see that build for the whys + UV="${UV:-$HOME/.local/bin/uv}" + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + export UV_PYTHON_INSTALL_DIR="$PREFIX/python" + "$UV" venv --python 3.12 "$PREFIX/venv" +} + +pbuild::compile() { + : +} + +pbuild::install() { + UV="${UV:-$HOME/.local/bin/uv}" + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + # no [cuda] extra: CUDA comes from the cuda/12.8.1 module + # (build_requires/runtime_deps in files/config.yaml), not from pip wheels + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" + [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : +} diff --git a/careless-gpu/files/config.yaml b/careless-gpu/files/config.yaml new file mode 100644 index 0000000..1a7f199 --- /dev/null +++ b/careless-gpu/files/config.yaml @@ -0,0 +1,13 @@ +--- +format: 1 +careless-gpu: + defaults: + group: MX + overlay: base + relstage: unstable + versions: + 0.5.4: + config: + relstage: unstable + build_requires: ["cuda/12.8.1"] + runtime_deps: ["cuda/12.8.1"] diff --git a/careless-gpu/modulefile b/careless-gpu/modulefile new file mode 100644 index 0000000..486cb39 --- /dev/null +++ b/careless-gpu/modulefile @@ -0,0 +1,16 @@ +#%Module1.0 + +module-whatis "careless (GPU) - merging crystallography data with variational inference" +module-url "https://github.com/rs-station/careless" +module-license "MIT" +module-maintainer "MX Data " + +module-help " +careless: scaling and merging of X-ray diffraction data using +approximate Bayesian inference (TensorFlow). GPU build: CUDA is +provided by the cuda/12.8.1 module, auto-loaded as a runtime dep. +Use on nodes with an NVIDIA GPU; for CPU nodes load careless instead. +" + +setenv CARELESS_ENV $PREFIX/venv +prepend-path PATH $PREFIX/venv/bin diff --git a/careless/README.md b/careless/README.md index b2df471..757adc9 100644 --- a/careless/README.md +++ b/careless/README.md @@ -11,9 +11,14 @@ inference (variational merging), built on TensorFlow. Upstream recommends a fresh conda env, but repo.anaconda.com is not reachable from Ra, so the build uses uv instead: it fetches a standalone Python 3.12 into `$PREFIX/python` (upstream supports >=3.9,<3.13), creates -`$PREFIX/venv`, and runs `uv pip install careless[cuda]==` into -it. The `[cuda]` extra pulls the NVIDIA libraries as pip wheels, so the -same install works on GPU and CPU-only Ra nodes. +`$PREFIX/venv`, and runs `uv pip install careless==` into it. +This is the CPU build; the GPU build (with the `[cuda]` extra and the +cluster `cuda/12.8.1` module) is the separate `careless-gpu` module. + +To share one uv download cache between the careless and careless-gpu +builds, run each with `UV_CACHE_DIR= modbuild build ` +— a cache outside PREFIX is kept, an in-PREFIX cache is removed after a +successful install. `uv` must be on PATH on the build host (e.g. `pip install --user uv`). diff --git a/careless/build b/careless/build index 189d84a..d13569d 100755 --- a/careless/build +++ b/careless/build @@ -8,10 +8,11 @@ pbuild::configure() { # repo.anaconda.com is unreachable from Ra (GnuTLS error), so no conda. # uv fetches a standalone CPython instead; keep it inside PREFIX so the # venv's interpreter symlinks don't depend on the builder's home cache. - # modbuild's shell strips ~/.local/bin from PATH; override with UV=/path/to/uv if needed UV="${UV:-$HOME/.local/bin/uv}" - # ~/.cache/uv hits the home disk quota; cache under PREFIX (removed after install) - export UV_CACHE_DIR="$PREFIX/.uv-cache" + # ~/.cache/uv hits the home disk quota; default the cache into PREFIX. + # Overridable so careless and careless-gpu can share one cache: + # UV_CACHE_DIR= modbuild build + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" } @@ -22,8 +23,9 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="$PREFIX/.uv-cache" - # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" - rm -rf "$UV_CACHE_DIR" + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + # CPU version; the GPU build with the [cuda] extra is the careless-gpu module + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" + # only auto-remove the cache if it lives inside this PREFIX (never a shared one) + [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : } diff --git a/careless/modulefile b/careless/modulefile index 54ec7d0..852264c 100644 --- a/careless/modulefile +++ b/careless/modulefile @@ -7,9 +7,8 @@ module-maintainer "MX Data " module-help " careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). Installed with the -[cuda] extra, so it uses NVIDIA GPUs when available and falls -back to CPU otherwise. +approximate Bayesian inference (TensorFlow). CPU build; for +NVIDIA GPU nodes load careless-gpu instead. " setenv CARELESS_ENV $PREFIX/venv From f6c2f5a65046df8cde3cf6807963e5cef996b1ed Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:13:19 +0200 Subject: [PATCH 06/10] Drop careless-gpu: the [cuda] pip extra install covers GPU and CPU nodes The installed careless/0.5.4 venv already contains the NVIDIA wheels ([cuda] extra), which need only the node driver and fall back to CPU, so a separate GPU module and cuda module dep are unnecessary. Revert careless/build to careless[cuda] to match the actual install. Co-Authored-By: Claude Fable 5 --- careless-gpu/README.md | 28 ---------------------------- careless-gpu/build | 26 -------------------------- careless-gpu/files/config.yaml | 13 ------------- careless-gpu/modulefile | 16 ---------------- careless/README.md | 12 ++++-------- careless/build | 10 +++++----- careless/modulefile | 5 +++-- 7 files changed, 12 insertions(+), 98 deletions(-) delete mode 100644 careless-gpu/README.md delete mode 100755 careless-gpu/build delete mode 100644 careless-gpu/files/config.yaml delete mode 100644 careless-gpu/modulefile diff --git a/careless-gpu/README.md b/careless-gpu/README.md deleted file mode 100644 index fab39aa..0000000 --- a/careless-gpu/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# careless-gpu - -GPU build of careless (see `../careless/` for the CPU module and the full -background). Scaling and merging of X-ray diffraction data with approximate -Bayesian inference (variational merging), built on TensorFlow. - -- Upstream: https://github.com/rs-station/careless -- License: MIT - -## How it differs from the careless module - -- CUDA is not pip-installed (no `[cuda]` extra, saves several GB): the - cluster `cuda/12.8.1` module provides it instead, declared as - `build_requires`/`runtime_deps` (same pattern as `jfjoch_viewer`). - `runtime_deps` matters because TensorFlow dlopens the CUDA libraries - when careless runs, so cuda must auto-load with this module. -- If careless reports missing cuDNN at runtime, the cuda module does not - ship it; the fallback is installing `careless[cuda]` in `build` instead. - -The venv layout, uv usage, and cache handling are identical to `careless`. -To share one download cache between both builds, run each with -`UV_CACHE_DIR= modbuild build ` — a cache outside -PREFIX is kept, an in-PREFIX cache is removed after a successful install. - -## Adding a new version - -Add the version under `versions:` in `files/config.yaml`, then on a Ra -login node: `modbuild build ` (modbuild/2.1.2). diff --git a/careless-gpu/build b/careless-gpu/build deleted file mode 100755 index 49cb4e9..0000000 --- a/careless-gpu/build +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env modbuild - -pbuild::prep() { - : -} - -pbuild::configure() { - # same uv pattern as the careless (CPU) module; see that build for the whys - UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - export UV_PYTHON_INSTALL_DIR="$PREFIX/python" - "$UV" venv --python 3.12 "$PREFIX/venv" -} - -pbuild::compile() { - : -} - -pbuild::install() { - UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - # no [cuda] extra: CUDA comes from the cuda/12.8.1 module - # (build_requires/runtime_deps in files/config.yaml), not from pip wheels - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" - [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : -} diff --git a/careless-gpu/files/config.yaml b/careless-gpu/files/config.yaml deleted file mode 100644 index 1a7f199..0000000 --- a/careless-gpu/files/config.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -format: 1 -careless-gpu: - defaults: - group: MX - overlay: base - relstage: unstable - versions: - 0.5.4: - config: - relstage: unstable - build_requires: ["cuda/12.8.1"] - runtime_deps: ["cuda/12.8.1"] diff --git a/careless-gpu/modulefile b/careless-gpu/modulefile deleted file mode 100644 index 486cb39..0000000 --- a/careless-gpu/modulefile +++ /dev/null @@ -1,16 +0,0 @@ -#%Module1.0 - -module-whatis "careless (GPU) - merging crystallography data with variational inference" -module-url "https://github.com/rs-station/careless" -module-license "MIT" -module-maintainer "MX Data " - -module-help " -careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). GPU build: CUDA is -provided by the cuda/12.8.1 module, auto-loaded as a runtime dep. -Use on nodes with an NVIDIA GPU; for CPU nodes load careless instead. -" - -setenv CARELESS_ENV $PREFIX/venv -prepend-path PATH $PREFIX/venv/bin diff --git a/careless/README.md b/careless/README.md index 757adc9..084cb8a 100644 --- a/careless/README.md +++ b/careless/README.md @@ -11,14 +11,10 @@ inference (variational merging), built on TensorFlow. Upstream recommends a fresh conda env, but repo.anaconda.com is not reachable from Ra, so the build uses uv instead: it fetches a standalone Python 3.12 into `$PREFIX/python` (upstream supports >=3.9,<3.13), creates -`$PREFIX/venv`, and runs `uv pip install careless==` into it. -This is the CPU build; the GPU build (with the `[cuda]` extra and the -cluster `cuda/12.8.1` module) is the separate `careless-gpu` module. - -To share one uv download cache between the careless and careless-gpu -builds, run each with `UV_CACHE_DIR= modbuild build ` -— a cache outside PREFIX is kept, an in-PREFIX cache is removed after a -successful install. +`$PREFIX/venv`, and runs `uv pip install careless[cuda]==` into +it. The `[cuda]` extra ships the NVIDIA libraries (CUDA, cuDNN, ...) as +pip wheels, so the one install uses the GPU on GPU nodes (only the node's +NVIDIA driver is needed — no cuda module) and falls back to CPU elsewhere. `uv` must be on PATH on the build host (e.g. `pip install --user uv`). diff --git a/careless/build b/careless/build index d13569d..f5ae5b0 100755 --- a/careless/build +++ b/careless/build @@ -9,9 +9,8 @@ pbuild::configure() { # uv fetches a standalone CPython instead; keep it inside PREFIX so the # venv's interpreter symlinks don't depend on the builder's home cache. UV="${UV:-$HOME/.local/bin/uv}" - # ~/.cache/uv hits the home disk quota; default the cache into PREFIX. - # Overridable so careless and careless-gpu can share one cache: - # UV_CACHE_DIR= modbuild build + # ~/.cache/uv hits the home disk quota; default the cache into PREFIX + # (overridable: UV_CACHE_DIR= modbuild build ) export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" @@ -24,8 +23,9 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - # CPU version; the GPU build with the [cuda] extra is the careless-gpu module - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" + # [cuda] extra ships the NVIDIA stack (CUDA, cuDNN, ...) as pip wheels: + # uses the GPU when present (needs only the node driver), else falls back to CPU + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" # only auto-remove the cache if it lives inside this PREFIX (never a shared one) [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : } diff --git a/careless/modulefile b/careless/modulefile index 852264c..50cf9be 100644 --- a/careless/modulefile +++ b/careless/modulefile @@ -7,8 +7,9 @@ module-maintainer "MX Data " module-help " careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). CPU build; for -NVIDIA GPU nodes load careless-gpu instead. +approximate Bayesian inference (TensorFlow). Installed with the +[cuda] extra: uses NVIDIA GPUs when present (no cuda module +needed), falls back to CPU otherwise. " setenv CARELESS_ENV $PREFIX/venv From cc44565e353a4ed59dc2ba455cc69a6a16752e50 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:14:13 +0200 Subject: [PATCH 07/10] Revert "Drop careless-gpu: the [cuda] pip extra install covers GPU and CPU nodes" This reverts commit f6c2f5a65046df8cde3cf6807963e5cef996b1ed. --- careless-gpu/README.md | 28 ++++++++++++++++++++++++++++ careless-gpu/build | 26 ++++++++++++++++++++++++++ careless-gpu/files/config.yaml | 13 +++++++++++++ careless-gpu/modulefile | 16 ++++++++++++++++ careless/README.md | 12 ++++++++---- careless/build | 10 +++++----- careless/modulefile | 5 ++--- 7 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 careless-gpu/README.md create mode 100755 careless-gpu/build create mode 100644 careless-gpu/files/config.yaml create mode 100644 careless-gpu/modulefile diff --git a/careless-gpu/README.md b/careless-gpu/README.md new file mode 100644 index 0000000..fab39aa --- /dev/null +++ b/careless-gpu/README.md @@ -0,0 +1,28 @@ +# careless-gpu + +GPU build of careless (see `../careless/` for the CPU module and the full +background). Scaling and merging of X-ray diffraction data with approximate +Bayesian inference (variational merging), built on TensorFlow. + +- Upstream: https://github.com/rs-station/careless +- License: MIT + +## How it differs from the careless module + +- CUDA is not pip-installed (no `[cuda]` extra, saves several GB): the + cluster `cuda/12.8.1` module provides it instead, declared as + `build_requires`/`runtime_deps` (same pattern as `jfjoch_viewer`). + `runtime_deps` matters because TensorFlow dlopens the CUDA libraries + when careless runs, so cuda must auto-load with this module. +- If careless reports missing cuDNN at runtime, the cuda module does not + ship it; the fallback is installing `careless[cuda]` in `build` instead. + +The venv layout, uv usage, and cache handling are identical to `careless`. +To share one download cache between both builds, run each with +`UV_CACHE_DIR= modbuild build ` — a cache outside +PREFIX is kept, an in-PREFIX cache is removed after a successful install. + +## Adding a new version + +Add the version under `versions:` in `files/config.yaml`, then on a Ra +login node: `modbuild build ` (modbuild/2.1.2). diff --git a/careless-gpu/build b/careless-gpu/build new file mode 100755 index 0000000..49cb4e9 --- /dev/null +++ b/careless-gpu/build @@ -0,0 +1,26 @@ +#!/usr/bin/env modbuild + +pbuild::prep() { + : +} + +pbuild::configure() { + # same uv pattern as the careless (CPU) module; see that build for the whys + UV="${UV:-$HOME/.local/bin/uv}" + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + export UV_PYTHON_INSTALL_DIR="$PREFIX/python" + "$UV" venv --python 3.12 "$PREFIX/venv" +} + +pbuild::compile() { + : +} + +pbuild::install() { + UV="${UV:-$HOME/.local/bin/uv}" + export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + # no [cuda] extra: CUDA comes from the cuda/12.8.1 module + # (build_requires/runtime_deps in files/config.yaml), not from pip wheels + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" + [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : +} diff --git a/careless-gpu/files/config.yaml b/careless-gpu/files/config.yaml new file mode 100644 index 0000000..1a7f199 --- /dev/null +++ b/careless-gpu/files/config.yaml @@ -0,0 +1,13 @@ +--- +format: 1 +careless-gpu: + defaults: + group: MX + overlay: base + relstage: unstable + versions: + 0.5.4: + config: + relstage: unstable + build_requires: ["cuda/12.8.1"] + runtime_deps: ["cuda/12.8.1"] diff --git a/careless-gpu/modulefile b/careless-gpu/modulefile new file mode 100644 index 0000000..486cb39 --- /dev/null +++ b/careless-gpu/modulefile @@ -0,0 +1,16 @@ +#%Module1.0 + +module-whatis "careless (GPU) - merging crystallography data with variational inference" +module-url "https://github.com/rs-station/careless" +module-license "MIT" +module-maintainer "MX Data " + +module-help " +careless: scaling and merging of X-ray diffraction data using +approximate Bayesian inference (TensorFlow). GPU build: CUDA is +provided by the cuda/12.8.1 module, auto-loaded as a runtime dep. +Use on nodes with an NVIDIA GPU; for CPU nodes load careless instead. +" + +setenv CARELESS_ENV $PREFIX/venv +prepend-path PATH $PREFIX/venv/bin diff --git a/careless/README.md b/careless/README.md index 084cb8a..757adc9 100644 --- a/careless/README.md +++ b/careless/README.md @@ -11,10 +11,14 @@ inference (variational merging), built on TensorFlow. Upstream recommends a fresh conda env, but repo.anaconda.com is not reachable from Ra, so the build uses uv instead: it fetches a standalone Python 3.12 into `$PREFIX/python` (upstream supports >=3.9,<3.13), creates -`$PREFIX/venv`, and runs `uv pip install careless[cuda]==` into -it. The `[cuda]` extra ships the NVIDIA libraries (CUDA, cuDNN, ...) as -pip wheels, so the one install uses the GPU on GPU nodes (only the node's -NVIDIA driver is needed — no cuda module) and falls back to CPU elsewhere. +`$PREFIX/venv`, and runs `uv pip install careless==` into it. +This is the CPU build; the GPU build (with the `[cuda]` extra and the +cluster `cuda/12.8.1` module) is the separate `careless-gpu` module. + +To share one uv download cache between the careless and careless-gpu +builds, run each with `UV_CACHE_DIR= modbuild build ` +— a cache outside PREFIX is kept, an in-PREFIX cache is removed after a +successful install. `uv` must be on PATH on the build host (e.g. `pip install --user uv`). diff --git a/careless/build b/careless/build index f5ae5b0..d13569d 100755 --- a/careless/build +++ b/careless/build @@ -9,8 +9,9 @@ pbuild::configure() { # uv fetches a standalone CPython instead; keep it inside PREFIX so the # venv's interpreter symlinks don't depend on the builder's home cache. UV="${UV:-$HOME/.local/bin/uv}" - # ~/.cache/uv hits the home disk quota; default the cache into PREFIX - # (overridable: UV_CACHE_DIR= modbuild build ) + # ~/.cache/uv hits the home disk quota; default the cache into PREFIX. + # Overridable so careless and careless-gpu can share one cache: + # UV_CACHE_DIR= modbuild build export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" @@ -23,9 +24,8 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - # [cuda] extra ships the NVIDIA stack (CUDA, cuDNN, ...) as pip wheels: - # uses the GPU when present (needs only the node driver), else falls back to CPU - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" + # CPU version; the GPU build with the [cuda] extra is the careless-gpu module + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" # only auto-remove the cache if it lives inside this PREFIX (never a shared one) [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : } diff --git a/careless/modulefile b/careless/modulefile index 50cf9be..852264c 100644 --- a/careless/modulefile +++ b/careless/modulefile @@ -7,9 +7,8 @@ module-maintainer "MX Data " module-help " careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). Installed with the -[cuda] extra: uses NVIDIA GPUs when present (no cuda module -needed), falls back to CPU otherwise. +approximate Bayesian inference (TensorFlow). CPU build; for +NVIDIA GPU nodes load careless-gpu instead. " setenv CARELESS_ENV $PREFIX/venv From 7544d0d952f8c6d6e2099663c8e7366a6a73eea4 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:14:19 +0200 Subject: [PATCH 08/10] Revert "Split careless into CPU module and careless-gpu using cuda/12.8.1 module" This reverts commit b55d6c1d91536f480b604c40dd8affe3d44307d8. --- careless-gpu/README.md | 28 ---------------------------- careless-gpu/build | 26 -------------------------- careless-gpu/files/config.yaml | 13 ------------- careless-gpu/modulefile | 16 ---------------- careless/README.md | 11 +++-------- careless/build | 16 +++++++--------- careless/modulefile | 5 +++-- 7 files changed, 13 insertions(+), 102 deletions(-) delete mode 100644 careless-gpu/README.md delete mode 100755 careless-gpu/build delete mode 100644 careless-gpu/files/config.yaml delete mode 100644 careless-gpu/modulefile diff --git a/careless-gpu/README.md b/careless-gpu/README.md deleted file mode 100644 index fab39aa..0000000 --- a/careless-gpu/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# careless-gpu - -GPU build of careless (see `../careless/` for the CPU module and the full -background). Scaling and merging of X-ray diffraction data with approximate -Bayesian inference (variational merging), built on TensorFlow. - -- Upstream: https://github.com/rs-station/careless -- License: MIT - -## How it differs from the careless module - -- CUDA is not pip-installed (no `[cuda]` extra, saves several GB): the - cluster `cuda/12.8.1` module provides it instead, declared as - `build_requires`/`runtime_deps` (same pattern as `jfjoch_viewer`). - `runtime_deps` matters because TensorFlow dlopens the CUDA libraries - when careless runs, so cuda must auto-load with this module. -- If careless reports missing cuDNN at runtime, the cuda module does not - ship it; the fallback is installing `careless[cuda]` in `build` instead. - -The venv layout, uv usage, and cache handling are identical to `careless`. -To share one download cache between both builds, run each with -`UV_CACHE_DIR= modbuild build ` — a cache outside -PREFIX is kept, an in-PREFIX cache is removed after a successful install. - -## Adding a new version - -Add the version under `versions:` in `files/config.yaml`, then on a Ra -login node: `modbuild build ` (modbuild/2.1.2). diff --git a/careless-gpu/build b/careless-gpu/build deleted file mode 100755 index 49cb4e9..0000000 --- a/careless-gpu/build +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env modbuild - -pbuild::prep() { - : -} - -pbuild::configure() { - # same uv pattern as the careless (CPU) module; see that build for the whys - UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - export UV_PYTHON_INSTALL_DIR="$PREFIX/python" - "$UV" venv --python 3.12 "$PREFIX/venv" -} - -pbuild::compile() { - : -} - -pbuild::install() { - UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - # no [cuda] extra: CUDA comes from the cuda/12.8.1 module - # (build_requires/runtime_deps in files/config.yaml), not from pip wheels - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" - [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : -} diff --git a/careless-gpu/files/config.yaml b/careless-gpu/files/config.yaml deleted file mode 100644 index 1a7f199..0000000 --- a/careless-gpu/files/config.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -format: 1 -careless-gpu: - defaults: - group: MX - overlay: base - relstage: unstable - versions: - 0.5.4: - config: - relstage: unstable - build_requires: ["cuda/12.8.1"] - runtime_deps: ["cuda/12.8.1"] diff --git a/careless-gpu/modulefile b/careless-gpu/modulefile deleted file mode 100644 index 486cb39..0000000 --- a/careless-gpu/modulefile +++ /dev/null @@ -1,16 +0,0 @@ -#%Module1.0 - -module-whatis "careless (GPU) - merging crystallography data with variational inference" -module-url "https://github.com/rs-station/careless" -module-license "MIT" -module-maintainer "MX Data " - -module-help " -careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). GPU build: CUDA is -provided by the cuda/12.8.1 module, auto-loaded as a runtime dep. -Use on nodes with an NVIDIA GPU; for CPU nodes load careless instead. -" - -setenv CARELESS_ENV $PREFIX/venv -prepend-path PATH $PREFIX/venv/bin diff --git a/careless/README.md b/careless/README.md index 757adc9..b2df471 100644 --- a/careless/README.md +++ b/careless/README.md @@ -11,14 +11,9 @@ inference (variational merging), built on TensorFlow. Upstream recommends a fresh conda env, but repo.anaconda.com is not reachable from Ra, so the build uses uv instead: it fetches a standalone Python 3.12 into `$PREFIX/python` (upstream supports >=3.9,<3.13), creates -`$PREFIX/venv`, and runs `uv pip install careless==` into it. -This is the CPU build; the GPU build (with the `[cuda]` extra and the -cluster `cuda/12.8.1` module) is the separate `careless-gpu` module. - -To share one uv download cache between the careless and careless-gpu -builds, run each with `UV_CACHE_DIR= modbuild build ` -— a cache outside PREFIX is kept, an in-PREFIX cache is removed after a -successful install. +`$PREFIX/venv`, and runs `uv pip install careless[cuda]==` into +it. The `[cuda]` extra pulls the NVIDIA libraries as pip wheels, so the +same install works on GPU and CPU-only Ra nodes. `uv` must be on PATH on the build host (e.g. `pip install --user uv`). diff --git a/careless/build b/careless/build index d13569d..189d84a 100755 --- a/careless/build +++ b/careless/build @@ -8,11 +8,10 @@ pbuild::configure() { # repo.anaconda.com is unreachable from Ra (GnuTLS error), so no conda. # uv fetches a standalone CPython instead; keep it inside PREFIX so the # venv's interpreter symlinks don't depend on the builder's home cache. + # modbuild's shell strips ~/.local/bin from PATH; override with UV=/path/to/uv if needed UV="${UV:-$HOME/.local/bin/uv}" - # ~/.cache/uv hits the home disk quota; default the cache into PREFIX. - # Overridable so careless and careless-gpu can share one cache: - # UV_CACHE_DIR= modbuild build - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" + # ~/.cache/uv hits the home disk quota; cache under PREFIX (removed after install) + export UV_CACHE_DIR="$PREFIX/.uv-cache" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" } @@ -23,9 +22,8 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="${UV_CACHE_DIR:-$PREFIX/.uv-cache}" - # CPU version; the GPU build with the [cuda] extra is the careless-gpu module - "$UV" pip install --python "$PREFIX/venv/bin/python" "careless==${V_PKG}" - # only auto-remove the cache if it lives inside this PREFIX (never a shared one) - [[ "$UV_CACHE_DIR" == "$PREFIX"* ]] && rm -rf "$UV_CACHE_DIR" || : + export UV_CACHE_DIR="$PREFIX/.uv-cache" + # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too + "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" + rm -rf "$UV_CACHE_DIR" } diff --git a/careless/modulefile b/careless/modulefile index 852264c..54ec7d0 100644 --- a/careless/modulefile +++ b/careless/modulefile @@ -7,8 +7,9 @@ module-maintainer "MX Data " module-help " careless: scaling and merging of X-ray diffraction data using -approximate Bayesian inference (TensorFlow). CPU build; for -NVIDIA GPU nodes load careless-gpu instead. +approximate Bayesian inference (TensorFlow). Installed with the +[cuda] extra, so it uses NVIDIA GPUs when available and falls +back to CPU otherwise. " setenv CARELESS_ENV $PREFIX/venv From a1e15f765db809578270d3989f7afb3f8266209b Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:17:38 +0200 Subject: [PATCH 09/10] use common cache dir to save disk space and time --- careless/build | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/careless/build b/careless/build index 189d84a..99f5894 100755 --- a/careless/build +++ b/careless/build @@ -11,7 +11,7 @@ pbuild::configure() { # modbuild's shell strips ~/.local/bin from PATH; override with UV=/path/to/uv if needed UV="${UV:-$HOME/.local/bin/uv}" # ~/.cache/uv hits the home disk quota; cache under PREFIX (removed after install) - export UV_CACHE_DIR="$PREFIX/.uv-cache" + export UV_CACHE_DIR="/opt/psi/MX/.uv-cache" export UV_PYTHON_INSTALL_DIR="$PREFIX/python" "$UV" venv --python 3.12 "$PREFIX/venv" } @@ -22,8 +22,7 @@ pbuild::compile() { pbuild::install() { UV="${UV:-$HOME/.local/bin/uv}" - export UV_CACHE_DIR="$PREFIX/.uv-cache" + export UV_CACHE_DIR="/opt/psi/MX/.uv-cache" # [cuda] extra ships the NVIDIA libs via pip wheels; works on CPU-only nodes too "$UV" pip install --python "$PREFIX/venv/bin/python" "careless[cuda]==${V_PKG}" - rm -rf "$UV_CACHE_DIR" } From b02b3e36f3de7ea8f0c4531eb01ba7e2e509f2c9 Mon Sep 17 00:00:00 2001 From: Dawn Date: Tue, 18 Aug 2026 11:52:48 +0200 Subject: [PATCH 10/10] Document install verification checklist in careless README Co-Authored-By: Claude Fable 5 --- careless/README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/careless/README.md b/careless/README.md index b2df471..ff05205 100644 --- a/careless/README.md +++ b/careless/README.md @@ -21,6 +21,40 @@ Loading the module puts the venv's `bin/` on `PATH` (the `careless` command is directly available, no activation needed) and sets `CARELESS_ENV` to the venv path. +## Verifying the install + +Run on a Ra login node after building (in order, cheap to expensive): + +```sh +# 1. module is visible and loads +module search careless +module load careless/ + +# 2. modulefile wiring: PATH + CARELESS_ENV +which careless # -> .../careless//venv/bin/careless +echo $CARELESS_ENV # -> .../venv + +# 3. venv is self-contained: must resolve inside the module PREFIX, +# not the builder's home cache (which may be cleaned later) +readlink -f "$CARELESS_ENV/bin/python" + +# 4. CLI entry point; imports the full TensorFlow stack +careless --help # usage text, no traceback + +# 5. installed version matches the one requested +"$CARELESS_ENV/bin/python" -c "import careless; print(careless.__version__)" + +# 6. GPU pickup (GPU node only; [] on a CPU node is fine) +"$CARELESS_ENV/bin/python" -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))" +``` + +Optional end-to-end smoke test with a small unmerged mtz (a few seconds; +proves the TF graph builds and the optimizer steps): + +```sh +careless mono dHKL /tmp/careless_test --iterations 10 +``` + ## Adding a new version Add the version under `versions:` in `files/config.yaml`, then on a Ra