diff --git a/.gitmodules b/.gitmodules index bc360c9..d070312 100644 --- a/.gitmodules +++ b/.gitmodules @@ -58,3 +58,12 @@ [submodule "2026-HPCIC/tutorial-code/caliper-tutorial"] path = 2026-HPCIC/tutorial-code/caliper-tutorial url = https://github.com/daboehme/caliper-tutorial +[submodule "2026-PACT/tutorial-code/treescape-media"] + path = 2026-PACT/tutorial-code/treescape-media + url = https://github.com/llnl/treescape-media +[submodule "2026-PACT/tutorial-code/thicket-tutorial"] + path = 2026-PACT/tutorial-code/thicket-tutorial + url = https://github.com/llnl/thicket-tutorial +[submodule "2026-PACT/tutorial-code/caliper-tutorial"] + path = 2026-PACT/tutorial-code/caliper-tutorial + url = https://github.com/daboehme/caliper-tutorial diff --git a/2026-PACT/docker/Dockerfile.benchpark b/2026-PACT/docker/Dockerfile.benchpark new file mode 100644 index 0000000..23fe2af --- /dev/null +++ b/2026-PACT/docker/Dockerfile.benchpark @@ -0,0 +1,60 @@ +# Copyright 2025 Lawrence Livermore National Security, LLC and other +# Benchpark developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: Apache-2.0 + +# For testing +# FROM test-treescape + +FROM ghcr.io/llnl/treescape:pact-2026 + +USER root + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + wget \ + gzip \ + lsb-release \ + patch \ + tar \ + unzip \ + xz-utils \ + zstd \ + bzip2 \ + libatlas-base-dev \ + gettext \ + libncurses-dev \ + sqlite \ + && rm -rf /var/lib/apt/lists/* + +SHELL [ "/bin/bash", "-c" ] + +USER ${NB_USER} + +RUN git clone https://github.com/LLNL/benchpark.git ${HOME}/benchpark && \ + cd ${HOME}/benchpark && \ + git checkout -b develop-2026-10-15 develop-2026-10-15 && \ + git submodule update --init --recursive + +USER root + +RUN . /opt/global_py_venv/bin/activate && \ + python3 -m pip install -r ${HOME}/benchpark/requirements.txt + +RUN echo 'export PATH=${HOME}/benchpark/bin:$PATH' >> ${HOME}/.bashrc + +RUN echo 'export PATH=${HOME}/benchpark/bin:$PATH' >> ${HOME}/.bash_profile + +RUN chmod -R 777 ~/ ${HOME} + +WORKDIR ${HOME} + +RUN mkdir -p ${HOME}/.local/share && \ + chmod 777 ${HOME}/.local/share + +USER ${NB_USER} + +# Run this to trigger bootstrap +RUN . /opt/global_py_venv/bin/activate && \ + ${HOME}/benchpark/bin/benchpark bootstrap diff --git a/2026-PACT/docker/Dockerfile.caliper b/2026-PACT/docker/Dockerfile.caliper new file mode 100644 index 0000000..b964c84 --- /dev/null +++ b/2026-PACT/docker/Dockerfile.caliper @@ -0,0 +1,131 @@ +# Copyright 2025 Lawrence Livermore National Security, LLC and other +# Benchpark developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: Apache-2.0 + +# FROM ubuntu:noble +FROM fluxrm/flux-sched:jammy + +# ubuntu:noble added a new 'ubuntu' user in the container. +# Get rid of it! +# RUN userdel -r ubuntu + +USER root + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + adduser \ + vim \ + nano \ + emacs \ + build-essential \ + cmake \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv \ + git \ + util-linux \ + less \ + htop \ + zip \ + unzip \ + # NOTE: the flux-sched image already pulls and builds MPICH 4.2.2 + # WITHOUT PMIx support (this is important because PMIx is a pain, and + # requires extra setup with Flux). + # openmpi-bin \ + # openmpi-common \ + # libopenmpi-dev \ + && rm -rf /var/lib/apt/lists/* + +SHELL [ "/bin/bash", "-c" ] + +RUN python3 -m venv /opt/global_py_venv + +RUN . /opt/global_py_venv/bin/activate && \ + python3 -m pip install pybind11 + +ENV CALI_INSTALL_PREFIX=/usr \ + GIT_CLONE_STAGING_DIR=/tmp + +RUN git clone https://github.com/LLNL/Caliper.git ${GIT_CLONE_STAGING_DIR}/Caliper && \ + cd ${GIT_CLONE_STAGING_DIR}/Caliper && \ + git fetch origin && \ + git checkout v2.15.0 && \ + git submodule update --init --recursive && \ + git clone https://github.com/LLNL/Adiak.git ${GIT_CLONE_STAGING_DIR}/Adiak && \ + cd ${GIT_CLONE_STAGING_DIR}/Adiak && \ + git fetch origin && \ + git checkout v0.5.0 && \ + git submodule update --init --recursive + +RUN cd ${GIT_CLONE_STAGING_DIR}/Adiak && \ + mkdir build && \ + cd build && \ + cmake \ + -DENABLE_MPI=ON \ + -DCMAKE_C_COMPILER=$(which gcc) \ + -DCMAKE_CXX_COMPILER=$(which g++) \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX=${CALI_INSTALL_PREFIX} \ + .. && \ + make -j 4 && \ + make install + +RUN . /opt/global_py_venv/bin/activate && \ + cd ${GIT_CLONE_STAGING_DIR}/Caliper && \ + mkdir build && \ + cd build && \ + cmake \ + -DWITH_TOOLS=ON \ + -DWITH_MPI=ON \ + -DWITH_ADIAK=ON \ + -DWITH_PYTHON_BINDINGS=ON \ + -Dpybind11_DIR=$(pybind11-config --cmakedir) \ + -DCMAKE_PREFIX_PATH=${CALI_INSTALL_PREFIX} \ + -DCMAKE_C_COMPILER=$(which gcc) \ + -DCMAKE_CXX_COMPILER=$(which g++) \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX=${CALI_INSTALL_PREFIX} \ + .. && \ + make -j 4 && \ + make install + +RUN rm -rf ${GIT_CLONE_STAGING_DIR}/Caliper && rm -rf ${GIT_CLONE_STAGING_DIR}/Adiak + +ENV NB_USER=jovyan \ + NB_UID=1000 \ + HOME=/home/jovyan + +RUN adduser \ + --disabled-password \ + --gecos "Default user" \ + --uid ${NB_UID} \ + --home ${HOME} \ + --force-badname \ + ${NB_USER} + +# NOTE: this should NEVER be uncommented by the time we push to GHCR +RUN adduser ${NB_USER} sudo +RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +RUN chmod -R 777 ~/ ${HOME} + +ENV SHELL=/usr/bin/bash + +RUN mkdir -p ${HOME}/.local/share && \ + chmod 777 ${HOME}/.local/share + +RUN echo $(flux env) + +RUN echo 'export PATH=/usr/bin:$PATH' >> ${HOME}/.bashrc && \ + echo '. /opt/global_py_venv/bin/activate' >> ${HOME}/.bashrc && \ + echo 'export LD_LIBRARY_PATH=/usr/lib:/usr/lib64:$LD_LIBRARY_PATH' >> ${HOME}/.bashrc + +RUN echo 'export PATH=/usr/bin:$PATH' >> ${HOME}/.bash_profile && \ + echo '. /opt/global_py_venv/bin/activate' >> ${HOME}/.bash_profile && \ + echo 'export LD_LIBRARY_PATH=/usr/lib:/usr/lib64:$LD_LIBRARY_PATH' >> ${HOME}/.bash_profile + +USER ${NB_USER} +WORKDIR ${HOME} diff --git a/2026-PACT/docker/Dockerfile.init b/2026-PACT/docker/Dockerfile.init index a2d4b57..269a316 100644 --- a/2026-PACT/docker/Dockerfile.init +++ b/2026-PACT/docker/Dockerfile.init @@ -7,9 +7,9 @@ FROM alpine/git USER root -ENV NB_USER=fluxuser \ - NB_UID=1002 \ - HOME=/home/fluxuser +ENV NB_USER=jovyan \ + NB_UID=1000 \ + HOME=/home/jovyan RUN adduser \ -D \ diff --git a/2026-PACT/docker/Dockerfile.spawn b/2026-PACT/docker/Dockerfile.spawn index ca9c06d..fc35b69 100644 --- a/2026-PACT/docker/Dockerfile.spawn +++ b/2026-PACT/docker/Dockerfile.spawn @@ -6,51 +6,112 @@ # For testing # FROM test-benchpark -FROM ghcr.io/llnl/benchpark/benchpark-flux-el10:latest +FROM ghcr.io/llnl/benchpark:pact-2026 USER root -RUN dnf install -y --setopt=install_weak_deps=False \ +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ ca-certificates \ - bind-utils \ - iputils && \ - dnf clean all && \ - rm -rf /var/cache/dnf - -ENV TINI_VERSION v0.19.0 -ADD --chmod=755 https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini -RUN chmod +x /usr/bin/tini + dnsutils \ + iputils-ping \ + tini SHELL [ "/bin/bash", "-c" ] -#RUN . /opt/global_py_venv/bin/activate && \ -# /opt/global_py_venv/bin/python3 -m pip install plotly[express] && \ -# /opt/global_py_venv/bin/python3 -m pip install -U ipykernel && \ -# /opt/global_py_venv/bin/python3 -m ipykernel install --prefix=/usr/local --name 'benchpark-tutorial-kernel' +COPY ./docker/requirements.txt /requirements.txt -# if needed, update this to dnf archive -#COPY ./docker/kitware-archive.sh /tmp -# -#RUN /tmp/kitware-archive.sh && \ -# apt install -y cmake && \ -# which cmake && \ -# cmake --version && \ -# rm -rf /var/lib/apt/lists/* +RUN . /opt/global_py_venv/bin/activate && \ + # Needed for some viz in thicket-tutorial + /opt/global_py_venv/bin/python3 -m pip install plotly[express] && \ + /opt/global_py_venv/bin/python3 -m pip install -r /requirements.txt && \ + /opt/global_py_venv/bin/python3 -m pip install -U jupyter ipython ipykernel && \ + /opt/global_py_venv/bin/python3 -m ipykernel install --prefix=/usr/local --name 'benchpark-tutorial-kernel' + +COPY ./docker/kitware-archive.sh /tmp + +RUN /tmp/kitware-archive.sh && \ + apt install -y cmake && \ + which cmake && \ + cmake --version && \ + rm -rf /var/lib/apt/lists/* + +COPY ./tutorial-code/thicket-tutorial/requirements.txt /tmp/thicket-tutorial/requirements.txt + +RUN . /opt/global_py_venv/bin/activate && \ + python3 -m pip install extrap scikit-learn seaborn +# NOTE: we're not installing the dependencies for thicket-tutorial with +# requirements.txt because it hardcodes a version of IPython, which +# breaks all sorts of things. Instead, we extract the relevant dependencies +# and place them above. +# python3 -m pip install -r /tmp/thicket-tutorial/requirements.txt + +COPY ./tutorial-code/caliper-tutorial/apps /tmp/caliper-tutorial/apps/ +COPY ./tutorial-code/caliper-tutorial/cmake /tmp/caliper-tutorial/cmake/ + +ENV CALI_TUTORIAL_INSTALL_PREFIX=/usr + +RUN cmake \ + -B /tmp/build-basic-example \ + -C /tmp/caliper-tutorial/cmake/basic_example.cmake \ + -DCMAKE_INSTALL_PREFIX="${CALI_TUTORIAL_INSTALL_PREFIX}" \ + -S /tmp/caliper-tutorial/apps/basic_example && \ + cmake --build "/tmp/build-basic-example" && \ + cmake --install "/tmp/build-basic-example" +# && \ +# rm -rf /tmp/build-basic-example -WORKDIR /home/fluxuser/benchpark +RUN cmake \ + -B /tmp/build-lulesh \ + -C /tmp/caliper-tutorial/cmake/lulesh-mpi.cmake \ + -DCMAKE_INSTALL_PREFIX="${CALI_TUTORIAL_INSTALL_PREFIX}" \ + -S /tmp/caliper-tutorial/apps/LULESH && \ + cmake --build "/tmp/build-lulesh" && \ + cmake --install "/tmp/build-lulesh" +# && \ +# rm -rf /tmp/build-lulesh + +RUN cmake \ + -B /tmp/build-xsbench \ + -C /tmp/caliper-tutorial/cmake/xsbench-mpi.cmake \ + -DCMAKE_INSTALL_PREFIX="${CALI_TUTORIAL_INSTALL_PREFIX}" \ + -S /tmp/caliper-tutorial/apps/XSBench && \ + cmake --build "/tmp/build-xsbench" && \ + cmake --install "/tmp/build-xsbench" +# && \ +# rm -rf /tmp/build-xsbench + +COPY ./tutorial-code/caliper-tutorial/tutorial ${HOME}/caliper-tutorial/ +COPY ./tutorial-code/caliper-tutorial/apps ${HOME}/caliper-tutorial/apps + +COPY ./tutorial-code/thicket-tutorial/data/lassen ${HOME}/thicket-tutorial/data/lassen +COPY ./tutorial-code/thicket-tutorial/data/quartz ${HOME}/thicket-tutorial/data/quartz +COPY ./tutorial-code/thicket-tutorial/notebooks/01_thicket_tutorial.ipynb ${HOME}/thicket-tutorial/notebooks/01_thicket_tutorial.ipynb +COPY ./tutorial-code/thicket-tutorial/notebooks/02_thicket_rajaperf_clustering.ipynb ${HOME}/thicket-tutorial/notebooks/02_thicket_rajaperf_clustering.ipynb +COPY ./tutorial-code/thicket-tutorial/LICENSE ${HOME}/thicket-tutorial + +COPY ./tutorial-code/treescape-media/datasets/newdemo/test ${HOME}/treescape-media/datasets/newdemo/test +COPY ./tutorial-code/treescape-media/examples/NightlyTestDemo_local.ipynb ${HOME}/treescape-media/examples/NightlyTestDemo_local.ipynb +COPY ./tutorial-code/treescape-media/LICENSE ${HOME}/treescape-media + +COPY tutorial-code/system-description/aws-tutorial ${HOME}/benchpark/systems/aws-tutorial + +RUN chown -R jovyan ${HOME} +# RUN chmod -R 777 ~/ ${HOME} + +WORKDIR ${HOME} COPY ./docker/spawn-entrypoint.sh /entrypoint.sh COPY ./docker/spawn-local-entrypoint.sh /local-entrypoint.sh RUN chmod 777 /entrypoint.sh RUN chmod 777 /local-entrypoint.sh -RUN rm -f /home/fluxuser/.jupyter/jupyter_lab_config.py - -USER fluxuser +USER ${NB_USER} ENV SHELL=/usr/bin/bash ENV FLUX_URI_RESOLVE_LOCAL=t EXPOSE 8888 -ENTRYPOINT [ "/usr/bin/tini", "--" ] +ENTRYPOINT [ "tini", "--" ] CMD ["flux", "start", "jupyter", "lab"] diff --git a/2026-PACT/docker/Dockerfile.thicket b/2026-PACT/docker/Dockerfile.thicket new file mode 100644 index 0000000..041f14a --- /dev/null +++ b/2026-PACT/docker/Dockerfile.thicket @@ -0,0 +1,18 @@ +# Copyright 2025 Lawrence Livermore National Security, LLC and other +# Benchpark developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: Apache-2.0 + +# For testing +# FROM test-caliper + +FROM ghcr.io/llnl/caliper:pact-2026 + +USER root + +RUN . /opt/global_py_venv/bin/activate && \ + python3 -m pip install llnl-hatchet==2025.2.0 && \ + python3 -m pip install "llnl-thicket[plotting]==2026.1.0" +# python3 -m pip install llnl-thicket[extrap,plotting]==2024.2.1 + +USER ${NB_USER} diff --git a/2026-PACT/docker/Dockerfile.treescape b/2026-PACT/docker/Dockerfile.treescape new file mode 100644 index 0000000..40010d2 --- /dev/null +++ b/2026-PACT/docker/Dockerfile.treescape @@ -0,0 +1,21 @@ +# Copyright 2025 Lawrence Livermore National Security, LLC and other +# Benchpark developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: Apache-2.0 + +# For testing +# FROM test-thicket + +FROM ghcr.io/llnl/thicket:pact-2026 + +USER root + +RUN git clone https://github.com/LLNL/treescape ${GIT_CLONE_STAGING_DIR}/treescape && \ + cd ${GIT_CLONE_STAGING_DIR}/treescape && \ + git checkout main-2026-04-15 + +RUN . /opt/global_py_venv/bin/activate && \ + cd ${GIT_CLONE_STAGING_DIR}/treescape && \ + python3 -m pip install . + +USER ${NB_USER} diff --git a/2026-PACT/docker/build_and_upload_images.sh b/2026-PACT/docker/build_and_upload_images.sh new file mode 100755 index 0000000..b3591da --- /dev/null +++ b/2026-PACT/docker/build_and_upload_images.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +set -e + +function usage { + echo "Usage: ./build_and_upload_images.sh [image_to_build]" +} + +if [ $# -lt 1 ]; then + usage + exit 1 +fi + +if [ $1 == "-h" ] || [ $1 == "--help" ]; then + usage + exit 0 +fi + +TAG="$1" + +DOCKER_PLATFORMS="linux/amd64,linux/arm64" + +TO_BUILD_IDS=( "caliper" "thicket" "treescape" "benchpark" "init" "spawn" ) + +if [ $# -ge 2 ]; then + TO_BUILD_IDS=( "$2" ) +fi + +caliper_IMAGE="ghcr.io/ilumsden/pact-2026-caliper" +thicket_IMAGE="ghcr.io/ilumsden/pact-2026-thicket" +treescape_IMAGE="ghcr.io/ilumsden/pact-2026-treescape" +benchpark_IMAGE="ghcr.io/ilumsden/pact-2026-benchpark" +init_IMAGE="ghcr.io/ilumsden/pact-2026-test-init" +spawn_IMAGE="ghcr.io/ilumsden/pact-2026-test-spawn" + +if ! command -v gh >/dev/null 2>&1; then + echo "This script requires the GitHub CLI (i.e., the gh command)." + echo "Install the CLI and rerun this script." + exit 1 +fi + +if ! command -v docker >/dev/null 2>&1; then + echo "This script requires Docker." + echo "Install Docker and rerun this script." + exit 1 +fi + +echo $(gh auth token) | docker login ghcr.io -u $(gh api user --jq .login) --password-stdin + +for bid in ${TO_BUILD_IDS[@]}; do + CURR_IMAGE_NAME="${bid}_IMAGE" + docker build --platform $DOCKER_PLATFORMS -f Dockerfile.$bid -t ${!CURR_IMAGE_NAME}:$TAG . + docker push ${!CURR_IMAGE_NAME}:$TAG +done + +# docker build --platform $DOCKER_PLATFORMS -f Dockerfile.benchpark -t latest-benchpark:latest . +# docker tag latest-benchpark:latest $BENCHPARK_IMAGE:$TAG +# docker push $BENCHPARK_IMAGE:$TAG +# +# docker build --platform $DOCKER_PLATFORMS -f Dockerfile.init -t latest-init:latest . +# docker tag latest-init:latest $INIT_IMAGE:$TAG +# docker push $INIT_IMAGE:$TAG +# +# docker build --platform $DOCKER_PLATFORMS -f Dockerfile.spawn -t latest-spawn:latest . +# docker tag latest-spawn:latest $SPAWN_IMAGE:$TAG +# docker push $SPAWN_IMAGE:$TAG diff --git a/2026-PACT/docker/entrypoint.sh b/2026-PACT/docker/entrypoint.sh deleted file mode 100755 index 4272512..0000000 --- a/2026-PACT/docker/entrypoint.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# Source benchpark environment -source /home/fluxuser/benchpark/setup-env.sh - -# Start flux with bash -exec /usr/bin/flux start /bin/bash - -chown -R 1000 /home/fluxuser diff --git a/2026-PACT/docker/init-entrypoint.sh b/2026-PACT/docker/init-entrypoint.sh index df390bd..c99f82f 100755 --- a/2026-PACT/docker/init-entrypoint.sh +++ b/2026-PACT/docker/init-entrypoint.sh @@ -6,4 +6,4 @@ # NOTE: this script runs as root -chown -R 1000 /home/fluxuser +chown -R 1000 /home/jovyan diff --git a/2026-PACT/docker/kitware-archive.sh b/2026-PACT/docker/kitware-archive.sh new file mode 100755 index 0000000..4b37074 --- /dev/null +++ b/2026-PACT/docker/kitware-archive.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +set -eu + +help() { + echo "Usage: $0 [--release ] [--rc]" > /dev/stderr +} + +doing= +rc= +release= +help= +for opt in "$@" +do + case "${doing}" in + release) + release="${opt}" + doing= + ;; + "") + case "${opt}" in + --rc) + rc=1 + ;; + --release) + doing=release + ;; + --help) + help=1 + ;; + esac + ;; + esac +done + +if [ -n "${doing}" ] +then + echo "--${doing} option given no argument." > /dev/stderr + echo > /dev/stderr + help + exit 1 +fi + +if [ -n "${help}" ] +then + help + exit +fi + +if [ -z "${release}" ] +then + unset UBUNTU_CODENAME + . /etc/os-release + + if [ -z "${UBUNTU_CODENAME+x}" ] + then + echo "This is not an Ubuntu system. Aborting." > /dev/stderr + exit 1 + fi + + release="${UBUNTU_CODENAME}" +fi + +case "${release}" in +noble|jammy|focal) + packages= + keyring_packages="ca-certificates gpg wget" + ;; +*) + echo "Only Ubuntu Noble (24.04), Jammy (22.04), and Focal (20.04) are supported. Aborting." > /dev/stderr + exit 1 + ;; +esac + +get_keyring= +if [ ! -f /usr/share/doc/kitware-archive-keyring/copyright ] +then + packages="${packages} ${keyring_packages}" + get_keyring=1 +fi + +# Start the real work +set -x + +apt-get update +# shellcheck disable=SC2086 +apt-get install -y ${packages} + +test -n "${get_keyring}" && (wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - > /usr/share/keyrings/kitware-archive-keyring.gpg) + +echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${release} main" > /etc/apt/sources.list.d/kitware.list +if [ -n "${rc}" ] +then + echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${release}-rc main" >> /etc/apt/sources.list.d/kitware.list +fi + +apt-get update +test -n "${get_keyring}" && rm /usr/share/keyrings/kitware-archive-keyring.gpg +apt-get install -y kitware-archive-keyring \ No newline at end of file diff --git a/2026-PACT/docker/requirements.txt b/2026-PACT/docker/requirements.txt new file mode 100644 index 0000000..6cafa51 --- /dev/null +++ b/2026-PACT/docker/requirements.txt @@ -0,0 +1,269 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# Use the "Run workflow" button at https://github.com/jupyterhub/zero-to-jupyterhub-k8s/actions/workflows/watch-dependencies.yaml +# +aiohappyeyeballs==2.6.1 + # via aiohttp +aiohttp==3.11.16 + # via kubernetes-asyncio +aiosignal==1.3.2 + # via aiohttp +alembic==1.15.2 + # via jupyterhub +annotated-types==0.7.0 + # via pydantic +arrow==1.3.0 + # via isoduration +attrs==25.3.0 + # via + # aiohttp + # jsonschema + # referencing +bcrypt==4.3.0 + # via + # jupyterhub-firstuseauthenticator + # jupyterhub-nativeauthenticator +cachetools==5.5.2 + # via google-auth +certifi==2025.1.31 + # via + # kubernetes-asyncio + # requests +certipy==0.2.2 + # via jupyterhub +cffi==1.17.1 + # via cryptography +charset-normalizer==3.4.1 + # via requests +cryptography==44.0.2 + # via + # certipy + # pyjwt +escapism==1.0.1 + # via + # jupyterhub-kubespawner + # jupyterhub-ltiauthenticator +fqdn==1.5.1 + # via jsonschema +frozenlist==1.5.0 + # via + # aiohttp + # aiosignal +google-auth==2.39.0 + # via google-auth-oauthlib +google-auth-oauthlib==1.2.1 + # via oauthenticator +greenlet==3.1.1 + # via sqlalchemy +idna==3.10 + # via + # jsonschema + # jupyterhub + # requests + # yarl +isoduration==20.11.0 + # via jsonschema +jinja2==3.1.6 + # via + # jupyterhub + # jupyterhub-kubespawner +jsonpointer==3.0.0 + # via jsonschema +jsonschema==4.23.0 + # via + # jupyter-events + # oauthenticator +jsonschema-specifications==2024.10.1 + # via jsonschema +jupyter-events==0.12.0 + # via jupyterhub +jupyterhub==5.3.0 + # via + # -r unfrozen/requirements.txt + # jupyterhub-firstuseauthenticator + # jupyterhub-kubespawner + # jupyterhub-ldapauthenticator + # jupyterhub-ltiauthenticator + # jupyterhub-nativeauthenticator + # oauthenticator +jupyterhub-firstuseauthenticator==1.1.1 + # via -r unfrozen/requirements.txt +jupyterhub-hmacauthenticator==1.0 + # via -r unfrozen/requirements.txt +jupyterhub-idle-culler==1.4.0 + # via -r unfrozen/requirements.txt +jupyterhub-kubespawner==7.0.0 + # via -r unfrozen/requirements.txt +jupyterhub-ldapauthenticator==2.0.2 + # via -r unfrozen/requirements.txt +jupyterhub-ltiauthenticator==1.6.2 + # via -r unfrozen/requirements.txt +jupyterhub-nativeauthenticator==1.3.0 + # via -r unfrozen/requirements.txt +jupyterhub-tmpauthenticator==1.0.0 + # via -r unfrozen/requirements.txt +kubernetes-asyncio==32.3.0 + # via jupyterhub-kubespawner +ldap3==2.9.1 + # via jupyterhub-ldapauthenticator +mako==1.3.10 + # via alembic +markupsafe==3.0.2 + # via + # jinja2 + # mako +multidict==6.4.3 + # via + # aiohttp + # yarl +mwoauth==0.4.0 + # via oauthenticator +oauthenticator==17.3.0 + # via -r unfrozen/requirements.txt +oauthlib==3.2.2 + # via + # jupyterhub + # jupyterhub-ltiauthenticator + # mwoauth + # requests-oauthlib +onetimepass==1.0.1 + # via jupyterhub-nativeauthenticator +packaging==24.2 + # via + # jupyter-events + # jupyterhub + # jupyterhub-idle-culler +pamela==1.2.0 + # via jupyterhub +prometheus-client==0.21.1 + # via jupyterhub +propcache==0.3.1 + # via + # aiohttp + # yarl + # via -r unfrozen/requirements.txt +pyasn1==0.6.1 + # via + # ldap3 + # pyasn1-modules + # rsa +pyasn1-modules==0.4.2 + # via google-auth +pycparser==2.22 + # via cffi +pycurl==7.45.6 + # via -r unfrozen/requirements.txt +pydantic==2.11.3 + # via jupyterhub +pydantic-core==2.33.1 + # via pydantic +pyjwt==2.10.1 + # via + # jupyterhub-ltiauthenticator + # mwoauth + # oauthenticator +pymysql==1.1.1 + # via -r unfrozen/requirements.txt +python-dateutil==2.9.0.post0 + # via + # arrow + # jupyterhub + # jupyterhub-idle-culler + # kubernetes-asyncio +python-json-logger==3.3.0 + # via jupyter-events +python-slugify==8.0.4 + # via jupyterhub-kubespawner +pyyaml==6.0.2 + # via + # jupyter-events + # jupyterhub-kubespawner + # kubernetes-asyncio +referencing==0.36.2 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +requests==2.32.3 + # via + # jupyterhub + # mwoauth + # oauthenticator + # requests-oauthlib +requests-oauthlib==2.0.0 + # via + # google-auth-oauthlib + # mwoauth +rfc3339-validator==0.1.4 + # via + # jsonschema + # jupyter-events +rfc3986-validator==0.1.1 + # via + # jsonschema + # jupyter-events +rpds-py==0.24.0 + # via + # jsonschema + # referencing +rsa==4.9 + # via google-auth +ruamel-yaml==0.18.10 + # via oauthenticator +ruamel-yaml-clib==0.2.12 + # via ruamel-yaml +six==1.17.0 + # via + # kubernetes-asyncio + # onetimepass + # python-dateutil + # rfc3339-validator +sqlalchemy==2.0.40 + # via + # alembic + # jupyterhub + # sqlalchemy-cockroachdb +sqlalchemy-cockroachdb==2.0.2 + # via -r unfrozen/requirements.txt +statsd==4.0.1 + # via -r unfrozen/requirements.txt +text-unidecode==1.3 + # via python-slugify +tornado==6.4.2 + # via + # jupyterhub + # jupyterhub-idle-culler + # oauthenticator +traitlets==5.14.3 + # via + # jupyter-events + # jupyterhub + # jupyterhub-kubespawner + # jupyterhub-ldapauthenticator + # jupyterhub-ltiauthenticator + # oauthenticator +types-python-dateutil==2.9.0.20241206 + # via arrow +typing-extensions==4.13.2 + # via + # alembic + # pydantic + # pydantic-core + # referencing + # sqlalchemy + # typing-inspection +typing-inspection==0.4.0 + # via pydantic +uri-template==1.3.0 + # via jsonschema +urllib3==2.4.0 + # via + # jupyterhub-kubespawner + # kubernetes-asyncio + # requests +webcolors==24.11.1 + # via jsonschema +yarl==1.19.0 + # via aiohttp diff --git a/2026-PACT/docker/spawn-entrypoint.sh b/2026-PACT/docker/spawn-entrypoint.sh index 2fbffc9..de4c271 100755 --- a/2026-PACT/docker/spawn-entrypoint.sh +++ b/2026-PACT/docker/spawn-entrypoint.sh @@ -12,7 +12,7 @@ # NOTE: use this if we only want a single "node" if [[ $# -ne 1 ]]; then - /usr/bin/flux start /home/fluxuser/.local/bin/jupyterhub-singleuser + /usr/bin/flux start /opt/global_py_venv/bin/jupyterhub-singleuser else last_core_id=$(( $1 - 1 )) mkdir -p ${HOME}/.flux @@ -25,5 +25,5 @@ hosts = "$(hostname)" cores = "0-${last_core_id}" EOF /usr/bin/flux start -c ${HOME}/.flux/resource.toml \ - /home/fluxuser/.local/bin/jupyterhub-singleuser -fi + /opt/global_py_venv/bin/jupyterhub-singleuser +fi \ No newline at end of file diff --git a/2026-PACT/tutorial-code/system-description/aws-tutorial/system.py b/2026-PACT/tutorial-code/system-description/aws-tutorial/system.py new file mode 100644 index 0000000..f849c36 --- /dev/null +++ b/2026-PACT/tutorial-code/system-description/aws-tutorial/system.py @@ -0,0 +1,217 @@ +# Copyright 2023 Lawrence Livermore National Security, LLC and other +# Benchpark Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: Apache-2.0 + + +from benchpark.directives import maintainers, variant +from benchpark.openmpsystem import OpenMPCPUOnlySystem +from benchpark.paths import hardware_descriptions +from benchpark.system import System, compiler_def, compiler_section_for + + +class AwsTutorial(System): + # Taken from https://aws.amazon.com/ec2/instance-types/ + # With boto3, we could determine this dynamically vs. storing a static table + + maintainers("stephanielam3211") + + id_to_resources = { + "c7i.48xlarge": { + "cpu_arch": "sapphirerapids", + "sys_cores_per_node": 192, + "sys_mem_per_node_GB": 384, + }, + "c7i.metal-48xl": { + "cpu_arch": "sapphirerapids", + "sys_cores_per_node": 192, + "sys_mem_per_node_GB": 384, + }, + "c7i.24xlarge": { + "cpu_arch": "sapphirerapids", + "sys_cores_per_node": 96, + "sys_mem_per_node_GB": 192, + }, + "c7i.metal-24xl": { + "cpu_arch": "sapphirerapids", + "sys_cores_per_node": 96, + "sys_mem_per_node_GB": 192, + }, + "c7i.12xlarge": { + "cpu_arch": "sapphirerapids", + "sys_cores_per_node": 48, + "sys_mem_per_node_GB": 96, + }, + } + + variant( + "instance_type", + values=( + "c7i.48xlarge", + "c7i.metal-48xl", + "c7i.24xlarge", + "c7i.metal-24xl", + "c7i.12xlarge", + ), + default="c7i.24xlarge", + description="AWS instance type", + ) + + def __init__(self, spec): + super().__init__(spec) + + # Common attributes across instances + self.programming_models = [OpenMPCPUOnlySystem()] + self.system_site = "aws" + self.scheduler = "flux" + self.hardware_key = ( + str(hardware_descriptions) + + "/AWS_Tutorial-sapphirerapids-EFA/hardware_description.yaml" + ) + + attrs = self.id_to_resources.get(self.spec.variants["instance_type"][0]) + for k, v in attrs.items(): + setattr(self, k, v) + + def compute_packages_section(self): + return { + "packages": { + "tar": { + "externals": [{"spec": "tar@1.34", "prefix": "/usr"}], + "buildable": False, + }, + "gmake": {"externals": [{"spec": "gmake@4.3", "prefix": "/usr"}]}, + "blas": {"buildable": False}, + "lapack": {"buildable": False}, + "atlas": { + "externals": [{"spec": "atlas@3.10.3", "prefix": "/usr"}], + }, + "mpi": {"buildable": False}, + "openmpi": { + "externals": [ + { + "spec": "openmpi@4.0%gcc@11.4.0", + "prefix": "/usr", + } + ] + }, + "cmake": { + "externals": [{"spec": "cmake@4.1.1", "prefix": "/usr"}], + "buildable": False, + }, + "git": { + "externals": [{"spec": "git@2.34.1~tcltk", "prefix": "/usr"}], + "buildable": False, + }, + "openssl": { + "externals": [{"spec": "openssl@3.0.2", "prefix": "/usr"}], + "buildable": False, + }, + "automake": { + "externals": [{"spec": "automake@1.16.5", "prefix": "/usr"}], + "buildable": False, + }, + "openssh": { + "externals": [{"spec": "openssh@8.9p1", "prefix": "/usr"}], + "buildable": False, + }, + "m4": { + "externals": [{"spec": "m4@1.4.18", "prefix": "/usr"}], + "buildable": False, + }, + "sed": { + "externals": [{"spec": "sed@4.8", "prefix": "/usr"}], + "buildable": False, + }, + "autoconf": { + "externals": [{"spec": "autoconf@2.71", "prefix": "/usr"}], + "buildable": False, + }, + "diffutils": { + "externals": [{"spec": "diffutils@3.8", "prefix": "/usr"}], + "buildable": False, + }, + "coreutils": { + "externals": [{"spec": "coreutils@8.32", "prefix": "/usr"}], + "buildable": False, + }, + "findutils": { + "externals": [{"spec": "findutils@4.8.0", "prefix": "/usr"}], + "buildable": False, + }, + "binutils": { + "externals": [ + {"spec": "binutils@2.38+gold~headers", "prefix": "/usr"} + ], + "buildable": False, + }, + "perl": { + "externals": [ + { + "spec": "perl@5.34.0~cpanm+opcode+open+shared+threads", + "prefix": "/usr", + } + ], + "buildable": False, + }, + "groff": { + "externals": [{"spec": "groff@1.22.4", "prefix": "/usr"}], + "buildable": False, + }, + "curl": { + "externals": [ + {"spec": "curl@7.81.0+gssapi+ldap+nghttp2", "prefix": "/usr"} + ], + "buildable": False, + }, + "ccache": { + "externals": [{"spec": "ccache@4.5.1", "prefix": "/usr"}], + "buildable": False, + }, + "flex": { + "externals": [{"spec": "flex@2.6.4+lex", "prefix": "/usr"}], + "buildable": False, + }, + "pkg-config": { + "externals": [{"spec": "pkg-config@0.29.2", "prefix": "/usr"}], + "buildable": False, + }, + "zlib": { + "externals": [{"spec": "zlib@1.2.11", "prefix": "/usr"}], + "buildable": False, + }, + "ninja": { + "externals": [{"spec": "ninja@1.10.1", "prefix": "/usr"}], + "buildable": False, + }, + "libtool": { + "externals": [{"spec": "libtool@2.4.6", "prefix": "/usr"}], + "buildable": False, + }, + "gettext": { + "externals": [{"spec": "gettext@0.21", "prefix": "/usr"}], + "buildable": False, + }, + } + } + + def compute_compilers_section(self): + return compiler_section_for( + "gcc", + [ + compiler_def( + "gcc@11.4.0 languages=c,c++,fortran", + "/usr/", + {"c": "gcc", "cxx": "g++", "fortran": "gfortran-11"}, + ) + ], + ) + + def compute_software_section(self): + return { + "software": { + "packages": { + "default-compiler": {"pkg_spec": "gcc@11.4.0"}, + } + } + }