Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/build-brev-tutorial-docker-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ jobs:
--type all

- name: Generate CSCS EDF
if: contains(matrix.architectures, 'arm64')
run: |
brev/generate-cscs-edf.bash \
--output "artifacts/branch-latest/${TUTORIAL_NAME}/brev/cscs.toml" \
Expand Down
6 changes: 6 additions & 0 deletions brev/dev-shell.bash
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ echo "🚀 Starting interactive shell as ${ACH_USER}..."
echo " (Type 'exit' or press Ctrl+D to exit the shell)"
echo ""

# Podman development consumes the published image. Pull it before `run` so a
# missing image cannot make podman-compose fall back to the build stanza.
if [ "${ACH_CONTAINER_ENGINE}" = "podman" ]; then
compose -f "${COMPOSE_FILE}" pull base "${SERVICE}"
fi

compose -f "${COMPOSE_FILE}" run --rm -it \
--entrypoint "/accelerated-computing-hub/brev/entrypoint.bash" \
"${SERVICE}" shell
Expand Down
7 changes: 6 additions & 1 deletion brev/dev-start.bash
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ DOCKER_COMPOSE=$(prepare_compose_file "${DOCKER_COMPOSE}")
sed 's/127\.0\.0\.1:/0.0.0.0:/g' "${DOCKER_COMPOSE}" > "${DOCKER_COMPOSE_DEV}"

# Filter out the "volume already exists" warning while preserving all other warnings/errors on stderr
compose -f ${DOCKER_COMPOSE_DEV} up -d 2> >(grep -v "already exists but was not created by Docker Compose" >&2)
UP_ARGS=(up -d)
if [ "${ACH_CONTAINER_ENGINE}" = "podman" ]; then
UP_ARGS+=(--no-build)
fi
compose -f "${DOCKER_COMPOSE_DEV}" "${UP_ARGS[@]}" \
2> >(grep -v "already exists but was not created by Docker Compose" >&2)

echo "Tutorial ${ACH_TUTORIAL} started successfully!"
12 changes: 0 additions & 12 deletions brev/entrypoint-nsight.bash
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,5 @@ for VAR in "${VARS[@]}"; do
fi
done

# Workaround: The Nsight Streamer container isn't restartable because it unconditionally creates
# symlinks every time it starts, which fails if the symlinks already exist.
for libnvrtc in /usr/lib/*-linux-gnu/libnvrtc.so /usr/lib64/libnvrtc.so; do
if test -e "${libnvrtc}"; then
rm -f "${libnvrtc}"
fi
done

if test -e /mnt/persist/home/host; then
rm -rf /mnt/persist/home/host
fi

# Hand off to nsight streamer's entrypoint (which handles user switching via USER env var)
source /setup/entrypoint.sh "$@"
10 changes: 9 additions & 1 deletion brev/prepare-podman-compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
def strip_podman_incompatible(value):
"""Remove Compose keys unsupported by the rootless Podman setup."""
if isinstance(value, dict):
for key in ("build", "privileged", "ulimits", "deploy"):
for key in ("privileged", "ulimits", "deploy"):
value.pop(key, None)
volumes = value.get("volumes")
if isinstance(volumes, list):
Expand Down Expand Up @@ -141,12 +141,20 @@ def add_rootless_gpu_access(data):
service["environment"] = environment


def use_host_network_for_base(data):
"""Avoid rootless veth creation for the one-shot Podman test service."""
base = (data.get("services") or {}).get("base")
if base is not None:
base["network_mode"] = "host"


def prepare(source, destination, repo_root="", bind_repo=False):
"""Write a Podman-compatible copy of source to destination."""
with open(source, "r", encoding="utf-8") as handle:
data = yaml.safe_load(handle)

strip_podman_incompatible(data)
use_host_network_for_base(data)
if bind_repo and repo_root:
replace_repo_volume(data, repo_root)
add_rootless_gpu_access(data)
Expand Down
4 changes: 1 addition & 3 deletions brev/wrappers/ncu
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
UID_="$(id -u)"
GID_="$(id -g)"

if [ "${ACH_ROOTLESS_PODMAN:-}" = "1" ]; then
exec "${ACH_NCU_PATH}" "$@"
elif sudo -E -n true >/dev/null 2>&1; then
if [ "${ACH_ROOTLESS_PODMAN:-}" != "1" ] && sudo -E -n true >/dev/null 2>&1; then
exec sudo -E -n setpriv \
--reuid="$UID_" --regid="$GID_" --init-groups \
--inh-caps=+sys_admin,+sys_ptrace \
Expand Down
4 changes: 1 addition & 3 deletions brev/wrappers/nsys
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
UID_="$(id -u)"
GID_="$(id -g)"

if [ "${ACH_ROOTLESS_PODMAN:-}" = "1" ]; then
exec "${ACH_NSYS_PATH}" "$@"
elif sudo -E -n true >/dev/null 2>&1; then
if [ "${ACH_ROOTLESS_PODMAN:-}" != "1" ] && sudo -E -n true >/dev/null 2>&1; then
exec sudo -E -n setpriv \
--reuid="$UID_" --regid="$GID_" --init-groups \
--inh-caps=+sys_admin,+sys_ptrace \
Expand Down
16 changes: 10 additions & 6 deletions docs/cscs.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@ workflow to succeed before starting a Daint run.

## Use the published image on Daint

From the repository checkout, set the account and EDF path:
From the repository checkout, download the branch-specific EDF published by
GitHub CI, then set the account and EDF path:

```bash
export CSCS_ACCOUNT="YOUR_ACCOUNT"
export ACH_REPO="$(git rev-parse --show-toplevel)"
export CSCS_EDF="${ACH_REPO}/tutorials/pyhpc/brev/cscs.toml"
export ACH_BRANCH="event/2026-07-cscs-summer-school"
export CSCS_EDF="${SCRATCH}/pyhpc-${ACH_BRANCH//\//-}.toml"
curl -fsSL \
"https://raw.githubusercontent.com/NVIDIA/accelerated-computing-hub/generated/${ACH_BRANCH}/tutorials/pyhpc/brev/cscs.toml" \
--output "${CSCS_EDF}"
```

The committed EDF selects the public event image without bind-mounting the
The generated EDF selects the public event image without bind-mounting a
checkout, so the source and dependencies always come from the same CI build.
Slurm Container Engine selects and caches the ARM64 manifest automatically.

Expand All @@ -45,9 +50,8 @@ For a reproducible run, generate a no-mount EDF pinned to the CI commit tag:
pyhpc
```

The committed and generated EDFs set `PMIX_MCA_gds=hash` and
`PMIX_MCA_psec=native`, which are the PMIx settings used for clean Slurm MPI
runs on Daint.
The generated EDF sets `PMIX_MCA_gds=hash` and `PMIX_MCA_psec=native`, which
are the PMIx settings used for clean Slurm MPI runs on Daint.

## Run tests

Expand Down
11 changes: 0 additions & 11 deletions tutorials/accelerated-python/brev/cscs.toml

This file was deleted.

11 changes: 0 additions & 11 deletions tutorials/cuda-cpp/brev/cscs.toml

This file was deleted.

11 changes: 0 additions & 11 deletions tutorials/cuda-tile/brev/cscs.toml

This file was deleted.

11 changes: 0 additions & 11 deletions tutorials/floating-point-emulation/brev/cscs.toml

This file was deleted.

11 changes: 0 additions & 11 deletions tutorials/nvmath-python/brev/cscs.toml

This file was deleted.

14 changes: 0 additions & 14 deletions tutorials/pyhpc/brev/cscs.toml

This file was deleted.

9 changes: 4 additions & 5 deletions tutorials/pyhpc/brev/test-cscs.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@
#
# Run the PyHPC tutorial validation suite on CSCS Slurm Container Engine.
#
# This script is intended to run on a CSCS login node using the committed EDF
# or a caller-provided CSCS_EDF override.
# This script is intended to run on a CSCS login node using an EDF published
# to the generated branch by GitHub CI.

set -euo pipefail

SCRIPT_PATH=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)

if [ -z "${CSCS_ACCOUNT:-}" ]; then
echo "Error: set CSCS_ACCOUNT to the CSCS project/account for srun." >&2
exit 2
fi

if [ -z "${CSCS_EDF:-}" ]; then
CSCS_EDF="${SCRIPT_PATH}/cscs.toml"
echo "Error: set CSCS_EDF to a generated-branch EDF file." >&2
exit 2
fi

if [ ! -f "${CSCS_EDF}" ]; then
Expand Down
11 changes: 0 additions & 11 deletions tutorials/stdpar/brev/cscs.toml

This file was deleted.

Loading