Skip to content

CSCS Summer School 2026 event branch#215

Draft
brycelelbach wants to merge 37 commits into
mainfrom
event/2026-07-cscs-summer-school
Draft

CSCS Summer School 2026 event branch#215
brycelelbach wants to merge 37 commits into
mainfrom
event/2026-07-cscs-summer-school

Conversation

@brycelelbach

Copy link
Copy Markdown
Collaborator

Summary

  • merge the July 2026 CSCS Summer School event branch into main
  • add the PyHPC tutorial and CSCS rootless Slurm Container Engine support
  • build and publish the PyHPC image for AMD64 and ARM64 with GitHub Actions

Review

This is a draft so the complete event-branch diff can be reviewed before merge.

Related: #213, #214

aaronj0 and others added 27 commits June 19, 2026 14:22
Port exercises 01, 03, 05, 06, 40, 41, 60 from the accelerated-python
tutorial into tutorials/pyhpc/notebooks (flat, no subdirectories) and
renumber the full set 00-13 in the order:

  00 numpy_intro__ndarray_basics      (AP 01)
  01 numpy_to_cupy__ndarray_basics    (AP 03)
  02 memory_spaces__power_iteration   (AP 05)
  03 mpi4py__collectives              (AP 60)
  04 intro                            (SWE 00)
  05 swe_core__reference_solver       (SWE 01)
  06 jax__lax_scan                    (SWE 02)
  07 pyomp__parallel_for              (SWE 03)
  08 nanobind__cpp_kernel             (SWE 04)
  09 cppjit__gpu_thrust               (SWE 05)
  10 synthesis                        (SWE 06)
  11 asynchrony__power_iteration      (AP 06)
  12 kernel_authoring__copy           (AP 40)
  13 kernel_authoring__book_histogram (AP 41)

Give the SWE notebooks consistent NN__<tech>__<example> names and update
their titles and cross-references for the new numbering. Normalize all
notebooks to canonical format.

Co-Authored-By: Claude <noreply@anthropic.com>
- requirements.txt: add cupy-cuda13x, numba-cuda[cu13], cuda-cccl[test-cu13],
  nvtx, nsightful, mpi4py, and pytest alongside the existing jax/pyomp/
  nanobind/CppJIT stack. All resolve together under Python 3.12.
- dockerfile: rename ACH_TUTORIAL to pyhpc, add OpenMPI (mpirun for notebook
  03) and the OMPI-run-as-root / CuPy cache env vars.
- docker-compose.yml: rename tutorial, dockerfile path, image tag, working-dir.
- test_notebooks.py: expand the ordered ladder to all 14 notebooks (00-13),
  preferring solutions and falling back to exercises, with per-cell timing.
- test.bash + test_packages.py: new, mirroring accelerated-python, so the
  tutorial runs through the standard ACH entrypoint test machinery.
- Track the Shallow_water_waves.gif via Git LFS (was committed as a raw blob).

Co-Authored-By: Claude <noreply@anthropic.com>
- README: cover the full arc (NumPy/CuPy fundamentals, mpi4py, the SWE
  programming-models ladder, and CUDA kernel authoring), grouped into
  Fundamentals / Distributed / Programming models / Kernels with Colab
  badges pointing at the new pyhpc paths and 00-13 numbering. Add a
  Syllabi section and refresh the run instructions.
- Add notebooks/syllabi/pyhpc__numpy_cupy_jax_mpi4py_kernels__8_hours.ipynb
  in the accelerated-python syllabus style (Notebooks + Materials +
  Introduction).

Co-Authored-By: Claude <noreply@anthropic.com>
Notebooks 11-13 %%writefile helper .py scripts and emit Nsight reports,
a downloaded text corpus, and a rendered plot. Ignore those (keeping the
tracked swe_core.py) so a test run leaves the working tree clean.

Co-Authored-By: Claude <noreply@anthropic.com>
The SWE solution notebooks (06-09) import swe_core, but swe_core.py and
swe_step.cpp live in notebooks/ while the solutions execute from
notebooks/solutions/. Under nbclient/JupyterLab only the notebook's own
directory is on sys.path, so the import failed. Symlink both helpers into
solutions/ (swe_core.py resolves __file__ to notebooks/, so timings.json
and swe_step.cpp still resolve to the single shared copy).

This was a latent bug inherited from the original tutorial, whose
solutions were never executed in CI (it shipped no test.bash).

Verified: full suite now passes on an L4 -- test_packages (9) and all 14
notebooks (00-13) green.

Co-Authored-By: Claude <noreply@anthropic.com>
Adapt the build workflow for this fork:
- Trigger on event/** branches (in addition to main and pull-request/N).
- Add a tutorials_filter input (default 'pyhpc') and filter the build
  matrix accordingly, so the fork builds only the pyhpc image rather than
  every tutorial. An empty filter restores the build-everything behavior.

The runner labels (linux-amd64-cpu4 build, linux-amd64-gpu-l4-latest-1
test) are satisfied by a self-hosted L4 runner registered on the fork.

Co-Authored-By: Claude <noreply@anthropic.com>
The build bake uses context ../../.. (repo root), which reads outside the
bake directory and requires an fs.read entitlement. The hardcoded
--allow=fs.read=/home/runner only covers NVIDIA's self-hosted runner home;
on other runners the checkout path differs, so buildx denied it with
'additional privileges requested'. Use --allow=fs.read=* so the build
works regardless of the runner's workspace layout.

Co-Authored-By: Claude <noreply@anthropic.com>
The test job pulls the image from the generated docker-compose, whose
image: anchor is committed as ghcr.io/nvidia/...  The build job, however,
pushes to ghcr.io/<repo_owner>/...  (derived from github.repository_owner).
On a fork these differ, so the test failed pre-pull with 'not found'.

Add an --image-owner option to generate-tagged-docker-composes.py that
rewrites the GHCR owner of the &image anchor, and pass
github.repository_owner from the build workflow. Empty owner is a no-op,
so upstream and sibling tutorials are unaffected.

Co-Authored-By: Claude <noreply@anthropic.com>
…cheme

Rename all PyHPC exercise and solution notebooks to the new
<NN>[__<EXAMPLE>][__<TECH>][__<CONCEPT>] naming scheme and merge the
standalone intro into the reference-solver notebook.

- Merge 04__intro into 05__swe_core__reference_solver as 04__swe__intro
  (framing + NumPy baseline in one notebook); the SWE ladder and the
  kernel/async notebooks shift down by one (05-13 -> 04-12).
- Renumber in-notebook titles, "Next:" pointers, and cross-references.
- Update README tables/prose, the 8-hour syllabus, test_notebooks.py
  ladder, and .gitignore comments to the new names and numbers.

Co-Authored-By: Claude <noreply@anthropic.com>
- Rename the 8-hour syllabus to drop "numpy" and add "cppinterop"
  (pyhpc__cupy_jax_mpi4py_cppinterop_kernels__8_hours.ipynb); update its
  title, internal generated-compose link, and the README Syllabi entry.
- Strip the leading notebook number from the title cells of notebooks
  04-09 and their solutions (titles no longer carry "NN." / "NN ·").
- Add brev/docker-compose.deploy.yml: publishes JupyterLab on 0.0.0.0:8888
  and opens Lab on the renamed syllabus.

Co-Authored-By: Claude <noreply@anthropic.com>
Set each notebook's H1 (and solution H1) to the readable form of its new
<NN>[__EXAMPLE][__TECH][__CONCEPT] filename, in the same component order
(e.g. "Memory Spaces - Power Iteration" -> "Power Iteration - CuPy -
Memory Spaces"; "Kernel Authoring - Copy" -> "Copy - Kernel Authoring";
SWE ladder titled "SWE - <tool>"). Update the matching titles in the
README Notebook column and the syllabus Topic column.

Co-Authored-By: Claude <noreply@anthropic.com>
Merge aaronj0:pyhpc-cppjit-and-interop (PR #2) into the event branch.
The PR branched before our rename/restructure, so on conflicts we keep
our structure and conform the incoming content:

- New interop notebook 14__python_cpp_interop -> 13__cpp_interop (+ solution),
  title set to our scheme ("C++ Interop"); added to README and the syllabus.
- README + test_notebooks ladder conflicts resolved to our numbering/names;
  kept Aaron's CppInterOp beta-release note.
- Preserved Aaron's non-conflicting work: swe_thrust_solver.cpp extraction,
  cppjit notebook edits (now in 08__swe__cppjit__thrust), dockerfile
  python3-config + include path, cffi/memory_profiler deps and package tests,
  swe_core SWE_THRUST_CPP constant.
- docker-compose.deploy.yml: add ?file-browser-path so Lab opens the syllabus
  but the file browser lands in the notebooks dir, not syllabi/.

Co-Authored-By: Aaron Jomy <aaronj0@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Reorder the syllabus filename tokens to match the tutorial's actual
progression (CuPy @01 -> mpi4py @03 -> JAX @05):
  pyhpc__cupy_jax_mpi4py_cppinterop_kernels__8_hours
  -> pyhpc__cupy_mpi4py_jax_cppinterop_kernels__8_hours

Updates the syllabus H1 title, its internal generated-compose link, the
README Syllabi entry, and the local deploy compose default URL to match.

Co-Authored-By: Claude <noreply@anthropic.com>
Executing the solution notebooks (e.g. in CI) writes the same generated
artifacts the notebooks/ patterns already ignore — %%writefile scripts,
Nsight reports (.nsys-rep/.sqlite/.ncu-rep), the downloaded corpus, and
generated C/C++ — but into notebooks/solutions/, which the existing
patterns didn't cover. Mirror the patterns there, re-including the
checked-in tutorial source (swe_step.cpp, swe_thrust_solver.cpp).

Co-Authored-By: Claude <noreply@anthropic.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Comment thread tutorials/pyhpc/test/test_packages.py Fixed
Comment thread .github/workflows/build-brev-tutorial-docker-images.yml
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

❌ Git Signature Check Failed

🔗 View workflow run logs

Found 19 unsigned commit(s):

Unsigned commits
  • f8adc0a: Use HTTP for CSCS web services (unsigned)
  • 2697936: Stream CSCS helpers and discover project (unsigned)
  • 5c02432: Default CSCS identity and suffix helpers (unsigned)
  • f463357: Clarify CSCS event branch default (unsigned)
  • f4bbb8d: Simplify CSCS tutorial bootstrap (unsigned)
  • caeeaf5: Harden CSCS web deployment on Daint (unsigned)
  • 20fe285: Add scripted CSCS web deployment workflow (unsigned)
  • 235cec0: Address CSCS review feedback and add web deployment (unsigned)
  • c55763d: Address follow-up CSCS review feedback (unsigned)
  • 9d09380: Address CSCS event branch review feedback (unsigned)
  • fa03125: Make multi-architecture builds tutorial-driven (unsigned)
  • 433c1b5: Build PyHPC images for ARM64 in GitHub CI (unsigned)
  • f559db5: Keep base image mirroring changes on main (unsigned)
  • 184eed9: Document and automate CSCS PyHPC validation (unsigned)
  • a098b28: Stabilize PyHPC notebooks on CSCS ARM64 (unsigned)
  • 65c89c8: Run PyHPC MPI notebooks under CSCS Slurm (unsigned)
  • e26f0a7: Harden rootless runtime support on ARM64 (unsigned)
  • 30f02e8: Make PyHPC container builds architecture-aware (unsigned)
  • 000d03f: Add Python-HPC libraries/programming-models tutorial: SWE solver (unsigned)

How to fix:

  1. Configure commit signing (if not already done):

    # For GPG signing
    git config --global commit.gpgsign true
    
    # Or for SSH signing (Git 2.34+)
    git config --global gpg.format ssh
    git config --global user.signingkey ~/.ssh/id_ed25519.pub
  2. Re-sign your commits:

    git rebase -i origin/main --exec "git commit --amend --no-edit -S"
    git push --force-with-lease

📚 GitHub documentation on signing commits

Comment thread brev/wrappers/nsys Outdated
Comment on lines +6 to +17
if [ "${ACH_ROOTLESS_PODMAN:-}" = "1" ]; then
exec "${ACH_NSYS_PATH}" "$@"
elif 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 \
--ambient-caps=+sys_admin,+sys_ptrace \
-- \
"$ACH_NSYS_PATH" "$@"
else
exec "$ACH_NSYS_PATH" "$@"
fi

@brycelelbach brycelelbach Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

....
....

Seriously why are you failing so hard here?

You have three branches, two of which are identical. There should be only two branches.

How is this going to work? Did you actually test that NCU and NSYS profiling works on CSCS Daint?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4afe7da / #218: both wrappers now have exactly two branches—privileged sudo setpriv when available outside rootless Podman, otherwise one direct exec. I also tested the CI-built ARM64 image live on Daint GH200. All 14 notebooks passed, including the nsys/ncu notebooks; the manual validation ran exactly one nsys profile plus export and exactly one ncu profile plus import, and both produced valid reports.

@@ -0,0 +1,11 @@
# Generated by accelerated-computing-hub/brev/generate-cscs-edf.bash

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought these were now going to be automatically placed on the generated branch. If so, then you can delete these local files.

Could we just generate this on the fly when we run the container? We already have to do a transform/preprocessing for the docker compose file anyways

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 4afe7da / #218: all seven committed EDF copies are deleted, and the workflow now publishes an EDF for every tutorial to the generated branch. The CSCS docs download that branch-specific file before srun, and test-cscs.bash requires that generated file. Generating it inside the container would be too late—Slurm Container Engine must read the EDF before the container starts—and the Podman Compose transform is a separate runtime path.

@robobryce

Copy link
Copy Markdown

The signature failure cannot be repaired by merging another commit into this head: the ten unsigned commits would remain in main..HEAD, and this account does not have permission to force-update the upstream event branch.

I created draft #219 as the signature-safe replacement. It is based directly on current main, contains the complete reviewed event change plus the #218 follow-ups as exactly one commit (87547a3), and GitHub reports that commit signature as verified. This also avoids carrying any unsigned event-branch ancestors into the check.

Copilot AI review requested due to automatic review settings July 22, 2026 13:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR merges the July 2026 CSCS Summer School event branch into main, introducing the PyHPC tutorial (notebooks + tests + image build), adding CSCS Slurm Container Engine validation support, and extending the Brev tooling to support rootless Podman workflows and multi-architecture image publishing.

Changes:

  • Adds the new tutorials/pyhpc tutorial (notebooks, tests, Brev image/compose, CSCS validation scripts, and documentation).
  • Updates Brev tooling to support Docker and rootless Podman (compose adaptation, entrypoint behavior, Nsight wrapper behavior).
  • Updates CI (build-brev-tutorial-docker-images.yml) to build/publish per-architecture images and then publish verified multi-arch manifests for event/** branches.

Reviewed changes

Copilot reviewed 64 out of 68 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tutorials/stdpar/brev/test.bash Makes GPU checks resilient when nvidia-smi is missing.
tutorials/pyhpc/test/test_packages.py Adds PyHPC package stack smoke tests (GPU/MPI/tooling).
tutorials/pyhpc/test/test_notebooks.py Adds notebook execution test ladder for PyHPC notebooks.
tutorials/pyhpc/test/pytest.ini Sets pytest defaults for verbose, unbuffered output and durations.
tutorials/pyhpc/README.md Adds PyHPC tutorial overview, running instructions, and notebook index.
tutorials/pyhpc/notebooks/syllabi/pyhpc__cupy_mpi4py_jax_cppinterop_kernels__8_hours.ipynb Adds an 8-hour syllabus notebook for PyHPC.
tutorials/pyhpc/notebooks/swe_thrust_solver.cpp Adds Thrust-based GPU SWE solver source for CppJIT notebook.
tutorials/pyhpc/notebooks/swe_step.cpp Adds nanobind C++ SWE step module source.
tutorials/pyhpc/notebooks/swe_core.py Adds NumPy SWE reference implementation + timing harness utilities.
tutorials/pyhpc/notebooks/solutions/07__swe__nanobind__SOLUTION.ipynb Adds solution notebook for nanobind SWE rung.
tutorials/pyhpc/notebooks/10__power_iteraiton__cupy__asynchrony.ipynb Adds CuPy asynchrony/profiling notebook (Nsight Systems/NVTX).
tutorials/pyhpc/notebooks/08__swe__cppjit__thrust.ipynb Adds CppJIT+Thrust GPU SWE notebook rung.
tutorials/pyhpc/notebooks/07__swe__nanobind.ipynb Adds nanobind SWE notebook rung.
tutorials/pyhpc/notebooks/06__swe__pyomp.ipynb Adds PyOMP SWE notebook rung.
tutorials/pyhpc/notebooks/05__swe__jax.ipynb Adds JAX SWE notebook rung.
tutorials/pyhpc/notebooks/00__numpy.ipynb Adds NumPy fundamentals notebook for PyHPC ladder.
tutorials/pyhpc/brev/test.bash Adds a PyHPC test runner supporting package + notebook suites and filters.
tutorials/pyhpc/brev/test-cscs.bash Adds CSCS SCE validation driver using srun --environment=<edf>.
tutorials/pyhpc/brev/requirements.txt Pins PyHPC tutorial Python dependencies (Jupyter, CuPy, JAX, MPI, etc.).
tutorials/pyhpc/brev/dockerfile Builds the PyHPC tutorial image (LLVM/CppJIT toolchain + Nsight tools).
tutorials/pyhpc/brev/docker-compose.yml Adds multi-arch, GPU-enabled compose stack for PyHPC (jupyter/nsys/ncu).
tutorials/pyhpc/assets/Shallow_water_waves.gif Adds tutorial asset via Git LFS pointer.
tutorials/pyhpc/.gitignore Ignores runtime-generated artifacts (build/, timings, profiler outputs, etc.).
tutorials/nvmath-python/brev/test.bash Makes GPU checks resilient when nvidia-smi is missing.
tutorials/floating-point-emulation/brev/test.bash Makes GPU checks resilient when nvidia-smi is missing.
tutorials/cuda-cpp/brev/test.bash Makes GPU checks resilient when nvidia-smi is missing.
tutorials/accelerated-python/brev/test.bash Makes GPU checks resilient when nvidia-smi is missing.
README.md Updates the top-level tutorial listing table (but currently adds a broken link).
docs/cscs.md Adds CSCS-specific documentation for using the published multi-arch PyHPC image.
brev/wrappers/nsys Allows Nsight Systems wrapper to run without sudo for rootless Podman.
brev/wrappers/ncu Allows Nsight Compute wrapper to run without sudo for rootless Podman.
brev/test-docker-compose.bash Extends compose test harness to support Docker and Podman variants.
brev/prepare-podman-compose.py Adds a converter to adapt ACH compose files for rootless Podman.
brev/generate-cscs-edf.bash Adds EDF generator for CSCS Slurm Container Engine runs (optionally pinned tags).
brev/entrypoint.bash Adjusts entrypoint to behave correctly for root and non-root (rootless) contexts.
brev/entrypoint-shell.bash Handles user switching only when running as root.
brev/entrypoint-nsight.bash Removes restart workaround logic from Nsight streamer entrypoint wrapper.
brev/entrypoint-jupyter.bash Handles user switching only when running as root.
brev/entrypoint-base.bash Handles user switching only when running as root.
brev/entrypoint-base-user.bash Fixes test argument forwarding by splitting env var into an argv array.
brev/dev-test.bash Updates documentation text to cover Docker/Podman compose.
brev/dev-stop.bash Switches dev stop to use selected compose engine rather than hard-coded docker.
brev/dev-start.bash Supports Podman dev start by using --no-build and adapted compose file.
brev/dev-shell.bash Supports Podman dev shells (pull first; use prepared compose).
brev/dev-common.bash Introduces container engine selection helpers and compose-file preparation.
brev/dev-build.bash Uses selected compose engine for image builds.
.github/workflows/build-brev-tutorial-docker-images.yml Enables event/** builds and switches to native per-arch build + manifest publish flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
| [CUDA C++ Tutorial](tutorials/cuda-cpp/README.md) | [docker-compose.yml](tutorials/cuda-cpp/brev/docker-compose.yml) | L40S, L4, or T4 | Crusoe or any other with Flexible Ports |
| [Standard Parallelism Tutorial](tutorials/stdpar/README.md) | [docker-compose.yml](tutorials/stdpar/brev/docker-compose.yml) | 4xL4, 2xL4, 2xL40S, or 1x L40S | GCP, AWS, or any other with Flexible Ports and Linux 6.1.24+, 6.2.11+, or 6.3+ (for HMM) |
| [Accelerated Python Tutorial](tutorials/accelerated-python/README.md) | [docker-compose.yml](tutorials/accelerated-python/brev/docker-compose.yml) | L40S, L4, or T4; 4xL4 or 2xL4 for distributed | Crusoe or any other with Flexible Ports |
| [Python HPC Libraries (SWE) Tutorial](tutorials/python-hpc-libraries-swe/README.md) | [docker-compose.yml](tutorials/python-hpc-libraries-swe/brev/docker-compose.yml) | 1xL40S, L4, or RTX | Crusoe or any other with Flexible Ports; host driver must support CUDA 13 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #220. The top-level row now names the PyHPC tutorial and links to tutorials/pyhpc/README.md and its Docker Compose file. I also corrected its hardware guidance. The full link check reports 87 valid links and 0 errors.

" print(\"Installing Nsight Systems package.\")\n",
" !dpkg -i NsightSystems-linux-cli-public-2025.3.1.90-3582212.deb > /dev/null\n",
" print(\"Installing PIP packages.\")\n",
" !pip install \"nvtx\" \"nsightful[notebook] \"@\" \"git+https://github.com/brycelelbach/nsightful.git\"\" > /dev/null 2>&1\n",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #220. The direct reference is now one quoted pip argument (nsightful[notebook] @ git+https://…), and I corrected all six matching exercise/solution Colab cells. They now pin the same tested nsightful commit as the image requirements; all 26 notebook-format and install-consistency checks pass.

Comment on lines +7 to +11
#include <cuda_runtime.h>
#include <thrust/execution_policy.h>
#include <thrust/for_each.h>
#include <thrust/iterator/counting_iterator.h>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #220: swe_thrust_solver.cpp now includes <cmath>. CUDA 13.3 compile validation passes.

Comment thread tutorials/pyhpc/notebooks/swe_thrust_solver.cpp Outdated
Comment on lines +39 to +45
const double* h = h_in.data();
const double* hu = hu_in.data();
double* h_new = h_out.data();
double* hu_new = hu_out.data();
const size_t Np2 = h_in.shape(0);
const size_t N = Np2 - 2;
const double inv = dt / dx;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #220. cpp_step now accepts only 1-D, C-contiguous, CPU-resident double arrays with implicit conversion disabled; it validates equal lengths and the two-ghost-cell minimum before dereferencing. The exercise and solution notebook sources match, and compile/runtime guard tests pass.

Comment on lines +48 to +51
"09__swe__synthesis",
"10__power_iteraiton__cupy__asynchrony",
"11__copy__kernel_authoring",
"12__book_histogram__kernel_authoring",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #220. Both exercise and solution files are renamed to power_iteration, with the README, syllabus, and test ladder updated consistently. A repository search finds no remaining power_iteraiton references.

Comment thread docs/cscs.md
@@ -0,0 +1,131 @@
# CSCS containers

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need instructions on how to deploy the container for 10 hours and connect to the JupyterLab, nsys, and ncu services from a web browser. Those instructions should mount the checked out repo so students solutions will persist. Add them to cscs.md

I have a feeling we'll need to do SSH port forwarding. Will that cause issues with the responsiveness/interactivity of the nsys/ncu services that use WebRTC?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented and live-tested in #220. docs/cscs.md now gives the checkout/update, 10-hour sbatch, browser tunnel, service URLs, reconnect, cancellation, and cleanup commands. The launcher pulls only the GitHub-CI tutorial image plus the NVIDIA Streamer images and bind-mounts the $SCRATCH checkout so student work persists.

The working tunnel forwards five ports: Jupyter HTTPS 8888; Nsight Systems HTTPS/signaling 8080 plus TURN/TCP 3478; and Nsight Compute HTTPS/signaling 8081 plus TURN/TCP 3479. The two TURN forwards are required for WebRTC video/input. TURN/TCP works through SSH, with the documented TCP-over-TCP responsiveness tradeoff on lossy links.

I tested from this node against Daint job 4258261 on nid006001: all three HTTPS applications loaded; both Streamers selected connected, nominated TURN/TCP relay pairs, opened their input data channels, and delivered advancing 1280x800 video with zero dropped frames in the samples. A file written through Jupyter HTTPS appeared in the bind-mounted $SCRATCH checkout. Graceful TERM cleanup removed containers, listeners, private TLS/TURN state, and job-local image stores while preserving student work.

Copilot AI review requested due to automatic review settings July 24, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 69 out of 73 changed files in this pull request and generated 5 comments.

Comment on lines +79 to +84
client = NotebookClient(
nb,
timeout=900, # seconds per cell
kernel_name=kernel_name,
resources={"metadata": {"path": str(notebook_path.parent)}},
)
echo -e "${RED}❌ Could not find the base service container${NC}"
return 1
fi
if ! container wait --condition=stopped "${BASE_CONTAINER}" >/dev/null; then
Comment on lines +89 to +91
if [ -z "${IMAGE}" ] || [ -z "${WORKDIR}" ]; then
COMPOSE_CONFIG=$(docker compose -f "${COMPOSE_FILE}" config --format json)
fi
Comment thread docs/cscs.md
bash -lc 'test "$(dpkg --print-architecture)" = arm64'
```

For a reproducible run, generate a no-mount EDF pinned to the CI commit tag:
Comment on lines +32 to +36
double *h, *hu, *hn, *hun;
cudaMallocManaged(&h, Np2 * sizeof(double));
cudaMallocManaged(&hu, Np2 * sizeof(double));
cudaMallocManaged(&hn, Np2 * sizeof(double));
cudaMallocManaged(&hun, Np2 * sizeof(double));
Copilot AI review requested due to automatic review settings July 24, 2026 12:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 69 out of 73 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

brev/generate-cscs-edf.bash:91

  • generate-cscs-edf.bash shells out to docker compose ... config to read x-config values. That hard-requires a working Docker CLI/daemon even though this script is meant for CSCS/rootless environments where Podman is used. Since the repo already provides brev/dev-common.bash with setup_container_engine + compose, use those helpers here so the EDF generator works with either engine.
if [ -z "${IMAGE}" ] || [ -z "${WORKDIR}" ]; then
    COMPOSE_CONFIG=$(docker compose -f "${COMPOSE_FILE}" config --format json)
fi

tutorials/pyhpc/notebooks/swe_thrust_solver.cpp:36

  • CUDA API calls here ignore return codes (cudaMallocManaged, cudaDeviceSynchronize, cudaFree), so allocation/sync failures can lead to undefined behavior or silent wrong results (especially since the output buffers are then copied back unconditionally). Add explicit cudaError_t checks (and ideally capture/report errors after the Thrust launches as well) so failures surface clearly to the Python caller.

Comment on lines +54 to +56
ladder = [(stem, _runnable_notebook(stem)) for stem in LADDER_STEMS]
ladder = [(stem, nb) for stem, nb in ladder if nb is not None]
ladder_ids = [stem for stem, _ in ladder]
Copilot AI review requested due to automatic review settings July 24, 2026 13:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 69 out of 73 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

brev/generate-cscs-edf.bash:91

  • This script shells out to docker compose ... config, which will fail on CSCS-style environments that intentionally lack a Docker daemon/client (but do have rootless Podman). Since the repo now provides brev/dev-common.bash helpers to select Docker vs Podman, use them here so EDF generation works in both environments.
if [ -z "${IMAGE}" ] || [ -z "${WORKDIR}" ]; then
    COMPOSE_CONFIG=$(docker compose -f "${COMPOSE_FILE}" config --format json)
fi

tutorials/pyhpc/notebooks/swe_thrust_solver.cpp:36

  • cudaMallocManaged return codes are ignored. If any allocation fails, the function will dereference null pointers (or leak earlier allocations) and likely crash the notebook kernel. Check allocation status and clean up on failure so the error is handled predictably.

Comment on lines +64 to +67
cudaDeviceSynchronize();
for (long i = 0; i < Np2; ++i) { h_out[i] = h[i]; hu_out[i] = hu[i]; }
// add cudaError checks
cudaFree(h); cudaFree(hu); cudaFree(hn); cudaFree(hun);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants