From 97a571e550f5f3630c5aa93e6fac0676d5282b35 Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Tue, 10 Feb 2026 19:11:26 +0100 Subject: [PATCH 1/6] Add CUDA Dockerfile with updated dependencies Fixes #3233 by providing an updated CUDA-enabled Docker container with: - Ubuntu 22.04 (updated from 20.04) - CUDA 12.6.1 (updated from 12.2.2) - fmt 11.0.2 (updated from 10.0.0, fixes missing fmt/base.h) - RAJA 2024.07.0 with CUDA support - Umpire 2024.07.0 for GPU memory management - Spack v0.23.0 for dependency management The Dockerfile includes proper CUDA configuration, comprehensive documentation, and a build script for easy container creation. Co-Authored-By: Claude Opus 4.5 --- .docker/cuda/.dockerignore | 18 +++++ .docker/cuda/Dockerfile | 134 +++++++++++++++++++++++++++++++++++++ .docker/cuda/README.md | 123 ++++++++++++++++++++++++++++++++++ .docker/cuda/build.sh | 105 +++++++++++++++++++++++++++++ 4 files changed, 380 insertions(+) create mode 100644 .docker/cuda/.dockerignore create mode 100644 .docker/cuda/Dockerfile create mode 100644 .docker/cuda/README.md create mode 100755 .docker/cuda/build.sh diff --git a/.docker/cuda/.dockerignore b/.docker/cuda/.dockerignore new file mode 100644 index 0000000000..2e3634efdc --- /dev/null +++ b/.docker/cuda/.dockerignore @@ -0,0 +1,18 @@ +# Ignore common files that shouldn't be in build context +*.md +*.swp +*.swo +*~ +.git +.gitignore +.github +build/ +*.o +*.so +*.a +__pycache__/ +*.pyc +.pytest_cache/ +.vscode/ +.idea/ +*.log diff --git a/.docker/cuda/Dockerfile b/.docker/cuda/Dockerfile new file mode 100644 index 0000000000..08b6b1eaba --- /dev/null +++ b/.docker/cuda/Dockerfile @@ -0,0 +1,134 @@ +# BOUT++ CUDA-enabled Docker container +# This Dockerfile builds BOUT++ with CUDA support using Spack for dependency management +# Fixes issue #3233 by using updated fmt library version + +FROM docker.io/nvidia/cuda:12.6.1-devel-ubuntu22.04 AS base +MAINTAINER BOUT++ Development Team +USER root + +# Install system dependencies +# Using Ubuntu 22.04 for more recent toolchain and better CUDA support +RUN \ + apt update &&\ + DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles apt install -y \ + build-essential \ + git \ + software-properties-common \ + python3 \ + python3-pip \ + wget \ + mpich \ + libmpich-dev \ + unzip \ + libnuma-dev \ + libncurses-dev \ + curl \ + libcurl4-openssl-dev \ + gfortran \ + ca-certificates &&\ + apt upgrade -y &&\ + apt clean + +FROM base AS setup-spack + +# Install Spack and set up environment +RUN \ + git clone --depth 1 --single-branch --branch v0.23.0 https://github.com/spack/spack.git &&\ + . /spack/share/spack/setup-env.sh &&\ + spack env create -d /spack-env &&\ + spack env activate /spack-env &&\ + spack add cmake@3.24: &&\ + spack add blt@0.6.2 &&\ + spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=80' &&\ + spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=80' &&\ + spack add fmt@11.0.2 &&\ + spack add netcdf-cxx4@4.3.1 &&\ + spack add fftw@3.3.10 &&\ + spack external find --not-buildable &&\ + spack external find perl cuda bzip2 pkgconfig ncurses mpich curl --not-buildable &&\ + spack install -j$(nproc) + +# Set up environment variables for the build +ENV SPACK_ROOT=/spack +ENV PATH="${SPACK_ROOT}/bin:${PATH}" + +FROM setup-spack AS bout-build + +# Create boutuser (for consistency with existing Docker setup) +RUN useradd -m -s /bin/bash boutuser && \ + echo "boutuser:boutforever" | chpasswd && \ + usermod -aG sudo boutuser + +USER boutuser +WORKDIR /home/boutuser + +# Clone and build BOUT++ +ARG BOUT_URL=https://github.com/boutproject/BOUT-dev.git +ARG BOUT_COMMIT=main + +RUN git clone ${BOUT_URL} BOUT-dev && \ + cd BOUT-dev && \ + git checkout ${BOUT_COMMIT} && \ + git submodule update --init --recursive + +WORKDIR /home/boutuser/BOUT-dev + +# Activate Spack environment and configure BOUT++ with CUDA +USER root +RUN . /spack/share/spack/setup-env.sh && \ + spack env activate /spack-env && \ + spack load cmake && \ + spack load fmt && \ + spack load raja && \ + spack load umpire && \ + spack load netcdf-cxx4 && \ + spack load fftw && \ + chown -R boutuser:boutuser /home/boutuser/BOUT-dev + +USER boutuser + +# Configure BOUT++ with CUDA support +# Note: cuda_arch=80 corresponds to Ampere architecture (A100) +# Adjust cuda_arch based on your target GPU architecture +RUN . /spack/share/spack/setup-env.sh && \ + spack env activate /spack-env && \ + spack load cmake fmt raja umpire netcdf-cxx4 fftw && \ + cmake -S . -B build \ + -DCMAKE_INSTALL_PREFIX=/opt/bout++ \ + -DCMAKE_BUILD_TYPE=Release \ + -DBOUT_ENABLE_CUDA=ON \ + -DCUDA_ARCH="compute_80,code=sm_80" \ + -DBOUT_ENABLE_RAJA=ON \ + -DBOUT_ENABLE_UMPIRE=ON \ + -DBOUT_USE_SYSTEM_FMT=ON \ + -DBOUT_GENERATE_FIELDOPS=OFF \ + -DBOUT_ENABLE_PYTHON=ON \ + || (cat /home/boutuser/BOUT-dev/build/CMakeFiles/CMake{Output,Error}.log ; exit 1) + +# Build BOUT++ +RUN . /spack/share/spack/setup-env.sh && \ + spack env activate /spack-env && \ + spack load cmake fmt raja umpire netcdf-cxx4 fftw && \ + cmake --build build -j$(nproc) + +# Install BOUT++ +USER root +RUN . /spack/share/spack/setup-env.sh && \ + spack env activate /spack-env && \ + spack load cmake && \ + cmake --install build + +# Create a helper script to activate the Spack environment +RUN echo '#!/bin/bash\n\ +. /spack/share/spack/setup-env.sh\n\ +spack env activate /spack-env\n\ +spack load cmake fmt raja umpire netcdf-cxx4 fftw\n\ +exec "$@"' > /usr/local/bin/bout-env.sh && \ + chmod +x /usr/local/bin/bout-env.sh + +USER boutuser +WORKDIR /home/boutuser/BOUT-dev + +# Default command activates Spack environment and drops to bash +ENTRYPOINT ["/usr/local/bin/bout-env.sh"] +CMD ["/bin/bash"] diff --git a/.docker/cuda/README.md b/.docker/cuda/README.md new file mode 100644 index 0000000000..7f86219700 --- /dev/null +++ b/.docker/cuda/README.md @@ -0,0 +1,123 @@ +# BOUT++ CUDA Docker Container + +This directory contains a Dockerfile for building BOUT++ with CUDA support. + +## Changes from Previous Version + +This Dockerfile addresses issue [#3233](https://github.com/boutproject/BOUT-dev/issues/3233) by updating dependencies: + +- **Ubuntu**: 20.04 → 22.04 (better toolchain and CUDA support) +- **CUDA**: 12.2.2 → 12.6.1 (latest stable release) +- **Spack**: v0.21.1 → v0.23.0 (improved package management) +- **fmt**: 10.0.0 → 11.0.2 (fixes missing `fmt/base.h` header) +- **RAJA**: 2022.10.4 → 2024.07.0 (improved CUDA support) +- **Umpire**: 2022.03.1 → 2024.07.0 (improved memory management) +- **BLT**: 0.5.3 → 0.6.2 (build system updates) + +## Prerequisites + +- Docker or Podman installed +- NVIDIA Docker runtime (nvidia-docker2) for GPU access +- NVIDIA GPU with Compute Capability 8.0+ (Ampere or newer) + - For other architectures, modify `cuda_arch` in the Dockerfile + +## Building the Container + +### Basic build: +```bash +cd .docker/cuda +docker build -t bout-cuda:latest . +``` + +### Build with specific BOUT++ commit: +```bash +docker build \ + --build-arg BOUT_URL=https://github.com/boutproject/BOUT-dev.git \ + --build-arg BOUT_COMMIT= \ + -t bout-cuda:custom . +``` + +## Running the Container + +### Interactive shell: +```bash +docker run --gpus all -it bout-cuda:latest +``` + +### Run with mounted directory: +```bash +docker run --gpus all -it \ + -v $(pwd):/workspace \ + -w /workspace \ + bout-cuda:latest +``` + +### Check CUDA availability: +```bash +docker run --gpus all -it bout-cuda:latest bash -c "nvidia-smi && nvcc --version" +``` + +## GPU Architecture Notes + +The Dockerfile is configured for NVIDIA A100 GPUs (Ampere, `cuda_arch=80`). + +For other GPU architectures, modify these lines in the Dockerfile: + +```dockerfile +# For Volta (V100): cuda_arch=70 +spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=70' +spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=70' +# And in CMake configuration: +-DCUDA_ARCH="compute_70,code=sm_70" + +# For Hopper (H100): cuda_arch=90 +spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=90' +spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=90' +# And in CMake configuration: +-DCUDA_ARCH="compute_90,code=sm_90" +``` + +Common CUDA architectures: +- **70**: Volta (V100) +- **75**: Turing (RTX 20 series, T4) +- **80**: Ampere (A100, RTX 30 series) +- **86**: Ampere (RTX 30 mobile, A10, A40) +- **89**: Ada Lovelace (RTX 40 series) +- **90**: Hopper (H100) + +## Troubleshooting + +### Spack build failures +If Spack fails to build packages, try increasing Docker memory allocation (minimum 8GB recommended). + +### CUDA runtime errors +Ensure nvidia-docker2 is properly installed: +```bash +# Test NVIDIA runtime +docker run --rm --gpus all nvidia/cuda:12.6.1-base-ubuntu22.04 nvidia-smi +``` + +### fmt header issues +If you encounter `fmt/base.h` not found errors, ensure you're using fmt 11.0+ (this is configured by default). + +## Container Layout + +- BOUT++ source: `/home/boutuser/BOUT-dev` +- BOUT++ install: `/opt/bout++` +- Spack environment: `/spack-env` +- Helper script: `/usr/local/bin/bout-env.sh` (loads Spack environment) + +## Environment Activation + +The container's entrypoint automatically activates the Spack environment. If you need to manually activate it: + +```bash +. /spack/share/spack/setup-env.sh +spack env activate /spack-env +spack load cmake fmt raja umpire netcdf-cxx4 fftw +``` + +Or simply use the helper script: +```bash +/usr/local/bin/bout-env.sh +``` diff --git a/.docker/cuda/build.sh b/.docker/cuda/build.sh new file mode 100755 index 0000000000..1970bb7a1b --- /dev/null +++ b/.docker/cuda/build.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# Build script for BOUT++ CUDA Docker container + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +REPO_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )" + +# Default values +IMAGE_NAME="bout-cuda" +IMAGE_TAG="latest" +BOUT_URL="https://github.com/boutproject/BOUT-dev.git" +BOUT_COMMIT="main" +CUDA_ARCH="80" # Default to Ampere (A100) +BUILD_ARGS="" + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -n|--name) + IMAGE_NAME="$2" + shift 2 + ;; + -t|--tag) + IMAGE_TAG="$2" + shift 2 + ;; + --url) + BOUT_URL="$2" + shift 2 + ;; + --commit) + BOUT_COMMIT="$2" + shift 2 + ;; + --cuda-arch) + CUDA_ARCH="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " -n, --name NAME Image name (default: bout-cuda)" + echo " -t, --tag TAG Image tag (default: latest)" + echo " --url URL BOUT++ repository URL" + echo " --commit COMMIT BOUT++ commit/branch to build (default: main)" + echo " --cuda-arch ARCH CUDA architecture (default: 80 for Ampere)" + echo " 70=Volta, 75=Turing, 80=Ampere, 86=Ampere(mobile)" + echo " 89=Ada, 90=Hopper" + echo " -h, --help Show this help message" + echo "" + echo "Examples:" + echo " $0 # Build with defaults" + echo " $0 --cuda-arch 70 # Build for Volta (V100)" + echo " $0 --commit v5.2.0 # Build specific version" + echo " $0 --name my-bout --tag dev # Custom image name and tag" + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Update Dockerfile with CUDA architecture if not default +if [ "$CUDA_ARCH" != "80" ]; then + echo "Note: Building for CUDA architecture $CUDA_ARCH" + echo " You may need to edit the Dockerfile to change cuda_arch in Spack commands" +fi + +BUILD_ARGS="--build-arg BOUT_URL=${BOUT_URL}" +BUILD_ARGS="${BUILD_ARGS} --build-arg BOUT_COMMIT=${BOUT_COMMIT}" + +echo "============================================" +echo "Building BOUT++ CUDA Docker Image" +echo "============================================" +echo "Image name: ${IMAGE_NAME}:${IMAGE_TAG}" +echo "BOUT++ URL: ${BOUT_URL}" +echo "BOUT++ commit: ${BOUT_COMMIT}" +echo "CUDA arch: ${CUDA_ARCH}" +echo "Build context: ${SCRIPT_DIR}" +echo "============================================" +echo "" + +# Build the image +cd "$SCRIPT_DIR" + +docker build \ + ${BUILD_ARGS} \ + -t "${IMAGE_NAME}:${IMAGE_TAG}" \ + -f Dockerfile \ + . + +echo "" +echo "============================================" +echo "Build complete!" +echo "============================================" +echo "Run with: docker run --gpus all -it ${IMAGE_NAME}:${IMAGE_TAG}" +echo "" +echo "To test CUDA:" +echo " docker run --gpus all -it ${IMAGE_NAME}:${IMAGE_TAG} bash -c 'nvidia-smi'" +echo "" From 896f9d06c5944f4071b028c351405649e9a5ad34 Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Tue, 10 Feb 2026 23:14:17 +0100 Subject: [PATCH 2/6] Fix CUDA Dockerfile and wire into CI - Replace deprecated MAINTAINER with LABEL maintainer - Fix default BOUT_COMMIT from main to master - Make CUDA_ARCH a build arg used throughout Dockerfile and build.sh - Add CUDA image build job to docker.yml workflow - Update tests.yml to use repo-owned GHCR image - Update README with build arg usage examples Co-Authored-By: Claude Opus 4.6 --- .docker/cuda/Dockerfile | 19 ++++++++++++------- .docker/cuda/README.md | 25 +++++++++++-------------- .docker/cuda/build.sh | 11 +++-------- .github/workflows/docker.yml | 27 +++++++++++++++++++++++++++ .github/workflows/tests.yml | 4 ++-- 5 files changed, 55 insertions(+), 31 deletions(-) diff --git a/.docker/cuda/Dockerfile b/.docker/cuda/Dockerfile index 08b6b1eaba..03fdc04402 100644 --- a/.docker/cuda/Dockerfile +++ b/.docker/cuda/Dockerfile @@ -3,7 +3,7 @@ # Fixes issue #3233 by using updated fmt library version FROM docker.io/nvidia/cuda:12.6.1-devel-ubuntu22.04 AS base -MAINTAINER BOUT++ Development Team +LABEL maintainer="BOUT++ Development Team" USER root # Install system dependencies @@ -31,6 +31,9 @@ RUN \ FROM base AS setup-spack +# CUDA architecture: 70=Volta, 75=Turing, 80=Ampere, 89=Ada, 90=Hopper +ARG CUDA_ARCH=80 + # Install Spack and set up environment RUN \ git clone --depth 1 --single-branch --branch v0.23.0 https://github.com/spack/spack.git &&\ @@ -39,8 +42,8 @@ RUN \ spack env activate /spack-env &&\ spack add cmake@3.24: &&\ spack add blt@0.6.2 &&\ - spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=80' &&\ - spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=80' &&\ + spack add "umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=${CUDA_ARCH}" &&\ + spack add "raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=${CUDA_ARCH}" &&\ spack add fmt@11.0.2 &&\ spack add netcdf-cxx4@4.3.1 &&\ spack add fftw@3.3.10 &&\ @@ -54,6 +57,8 @@ ENV PATH="${SPACK_ROOT}/bin:${PATH}" FROM setup-spack AS bout-build +ARG CUDA_ARCH=80 + # Create boutuser (for consistency with existing Docker setup) RUN useradd -m -s /bin/bash boutuser && \ echo "boutuser:boutforever" | chpasswd && \ @@ -64,7 +69,7 @@ WORKDIR /home/boutuser # Clone and build BOUT++ ARG BOUT_URL=https://github.com/boutproject/BOUT-dev.git -ARG BOUT_COMMIT=main +ARG BOUT_COMMIT=master RUN git clone ${BOUT_URL} BOUT-dev && \ cd BOUT-dev && \ @@ -88,8 +93,7 @@ RUN . /spack/share/spack/setup-env.sh && \ USER boutuser # Configure BOUT++ with CUDA support -# Note: cuda_arch=80 corresponds to Ampere architecture (A100) -# Adjust cuda_arch based on your target GPU architecture +# CUDA_ARCH is set via build arg (default: 80 for Ampere/A100) RUN . /spack/share/spack/setup-env.sh && \ spack env activate /spack-env && \ spack load cmake fmt raja umpire netcdf-cxx4 fftw && \ @@ -97,7 +101,8 @@ RUN . /spack/share/spack/setup-env.sh && \ -DCMAKE_INSTALL_PREFIX=/opt/bout++ \ -DCMAKE_BUILD_TYPE=Release \ -DBOUT_ENABLE_CUDA=ON \ - -DCUDA_ARCH="compute_80,code=sm_80" \ + -DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCH} \ + -DCUDA_ARCH="compute_${CUDA_ARCH},code=sm_${CUDA_ARCH}" \ -DBOUT_ENABLE_RAJA=ON \ -DBOUT_ENABLE_UMPIRE=ON \ -DBOUT_USE_SYSTEM_FMT=ON \ diff --git a/.docker/cuda/README.md b/.docker/cuda/README.md index 7f86219700..a180bb1b36 100644 --- a/.docker/cuda/README.md +++ b/.docker/cuda/README.md @@ -19,7 +19,7 @@ This Dockerfile addresses issue [#3233](https://github.com/boutproject/BOUT-dev/ - Docker or Podman installed - NVIDIA Docker runtime (nvidia-docker2) for GPU access - NVIDIA GPU with Compute Capability 8.0+ (Ampere or newer) - - For other architectures, modify `cuda_arch` in the Dockerfile + - For other architectures, use the `CUDA_ARCH` build arg (see below) ## Building the Container @@ -59,22 +59,19 @@ docker run --gpus all -it bout-cuda:latest bash -c "nvidia-smi && nvcc --version ## GPU Architecture Notes -The Dockerfile is configured for NVIDIA A100 GPUs (Ampere, `cuda_arch=80`). +The default build targets NVIDIA A100 GPUs (Ampere, `cuda_arch=80`). -For other GPU architectures, modify these lines in the Dockerfile: +For other GPU architectures, pass the `CUDA_ARCH` build arg: -```dockerfile -# For Volta (V100): cuda_arch=70 -spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=70' -spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=70' -# And in CMake configuration: --DCUDA_ARCH="compute_70,code=sm_70" +```bash +# For Volta (V100) +docker build --build-arg CUDA_ARCH=70 -t bout-cuda:volta . + +# For Hopper (H100) +docker build --build-arg CUDA_ARCH=90 -t bout-cuda:hopper . -# For Hopper (H100): cuda_arch=90 -spack add 'umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=90' -spack add 'raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=90' -# And in CMake configuration: --DCUDA_ARCH="compute_90,code=sm_90" +# Or using the build script +./build.sh --cuda-arch 70 ``` Common CUDA architectures: diff --git a/.docker/cuda/build.sh b/.docker/cuda/build.sh index 1970bb7a1b..81da0b5094 100755 --- a/.docker/cuda/build.sh +++ b/.docker/cuda/build.sh @@ -10,7 +10,7 @@ REPO_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )" IMAGE_NAME="bout-cuda" IMAGE_TAG="latest" BOUT_URL="https://github.com/boutproject/BOUT-dev.git" -BOUT_COMMIT="main" +BOUT_COMMIT="master" CUDA_ARCH="80" # Default to Ampere (A100) BUILD_ARGS="" @@ -44,7 +44,7 @@ while [[ $# -gt 0 ]]; do echo " -n, --name NAME Image name (default: bout-cuda)" echo " -t, --tag TAG Image tag (default: latest)" echo " --url URL BOUT++ repository URL" - echo " --commit COMMIT BOUT++ commit/branch to build (default: main)" + echo " --commit COMMIT BOUT++ commit/branch to build (default: master)" echo " --cuda-arch ARCH CUDA architecture (default: 80 for Ampere)" echo " 70=Volta, 75=Turing, 80=Ampere, 86=Ampere(mobile)" echo " 89=Ada, 90=Hopper" @@ -65,14 +65,9 @@ while [[ $# -gt 0 ]]; do esac done -# Update Dockerfile with CUDA architecture if not default -if [ "$CUDA_ARCH" != "80" ]; then - echo "Note: Building for CUDA architecture $CUDA_ARCH" - echo " You may need to edit the Dockerfile to change cuda_arch in Spack commands" -fi - BUILD_ARGS="--build-arg BOUT_URL=${BOUT_URL}" BUILD_ARGS="${BUILD_ARGS} --build-arg BOUT_COMMIT=${BOUT_COMMIT}" +BUILD_ARGS="${BUILD_ARGS} --build-arg CUDA_ARCH=${CUDA_ARCH}" echo "============================================" echo "Building BOUT++ CUDA Docker Image" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0b510c48e8..58f7ffc2ae 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,6 +8,7 @@ on: # Add your branch here if you want containers for it - db-WIP - docker-ci + workflow_dispatch: env: REGISTRY: ghcr.io @@ -82,3 +83,29 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + + build-cuda: + name: Build CUDA Container + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Log in to the Container registry + uses: docker/login-action@master + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push CUDA Docker image + uses: docker/build-push-action@master + with: + context: .docker/cuda/ + target: setup-spack + push: true + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/boutdev-cuda:latest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 82f3d6aea0..7f48ed3e77 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -216,13 +216,13 @@ jobs: CUDA: timeout-minutes: 60 runs-on: ubuntu-latest - container: ghcr.io/ggeorgakoudis/boutdev-cuda:latest + container: ghcr.io/boutproject/bout-dev/boutdev-cuda:latest steps: - uses: actions/checkout@v6 with: submodules: true - - name: Build minimal CUDA 12.2 @ GCC9.4.0 @ Ubuntu 20.04 + - name: Build minimal CUDA 12.6 @ Ubuntu 22.04 run: | . /spack/share/spack/setup-env.sh spack env activate -p /spack-env From 9b9f31bbdd8374fb6c054ee2a83ed6aae7cab133 Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Fri, 13 Feb 2026 09:05:35 +0100 Subject: [PATCH 3/6] Fix Spack build: add libssl-dev and constrain MPI provider - Add libssl-dev to system packages (libevent needs openssl headers) - Constrain fftw and netcdf-cxx4 to use system mpich instead of building openmpi from source - Add openssl to spack external find - Add --show-log-on-error for better debugging Co-Authored-By: Claude Opus 4.6 --- .docker/cuda/Dockerfile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.docker/cuda/Dockerfile b/.docker/cuda/Dockerfile index 03fdc04402..7315458108 100644 --- a/.docker/cuda/Dockerfile +++ b/.docker/cuda/Dockerfile @@ -25,7 +25,8 @@ RUN \ curl \ libcurl4-openssl-dev \ gfortran \ - ca-certificates &&\ + ca-certificates \ + libssl-dev &&\ apt upgrade -y &&\ apt clean @@ -45,11 +46,11 @@ RUN \ spack add "umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=${CUDA_ARCH}" &&\ spack add "raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=${CUDA_ARCH}" &&\ spack add fmt@11.0.2 &&\ - spack add netcdf-cxx4@4.3.1 &&\ - spack add fftw@3.3.10 &&\ + spack add 'netcdf-cxx4@4.3.1 ^mpich' &&\ + spack add 'fftw@3.3.10 ^mpich' &&\ spack external find --not-buildable &&\ - spack external find perl cuda bzip2 pkgconfig ncurses mpich curl --not-buildable &&\ - spack install -j$(nproc) + spack external find perl cuda bzip2 pkgconfig ncurses mpich curl openssl --not-buildable &&\ + spack install --show-log-on-error -j$(nproc) # Set up environment variables for the build ENV SPACK_ROOT=/spack From ebb28fc1803f78ba259b81f5ad90ba050940c1af Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Sun, 15 Feb 2026 22:26:30 +0100 Subject: [PATCH 4/6] Move CUDA base image to bout-container-base, update CI The CUDA Dockerfile now lives in boutproject/bout-container-base (PR #39). This commit removes the local copy and updates CI to pull the pre-built base image from ghcr.io/boutproject/bout-container-base:boutdev-cuda. - Remove .docker/cuda/ (Dockerfile, build.sh, README.md, .dockerignore) - Remove build-cuda job from docker.yml (built by container-base CI now) - Update CUDA CI job in tests.yml to use the new container image - Use bout-env.bash helper from the base image Fixes #3233 Co-Authored-By: Claude Opus 4.6 --- .docker/cuda/.dockerignore | 18 ----- .docker/cuda/Dockerfile | 140 ----------------------------------- .docker/cuda/README.md | 120 ------------------------------ .docker/cuda/build.sh | 100 ------------------------- .github/workflows/docker.yml | 26 ------- .github/workflows/tests.yml | 7 +- 6 files changed, 3 insertions(+), 408 deletions(-) delete mode 100644 .docker/cuda/.dockerignore delete mode 100644 .docker/cuda/Dockerfile delete mode 100644 .docker/cuda/README.md delete mode 100755 .docker/cuda/build.sh diff --git a/.docker/cuda/.dockerignore b/.docker/cuda/.dockerignore deleted file mode 100644 index 2e3634efdc..0000000000 --- a/.docker/cuda/.dockerignore +++ /dev/null @@ -1,18 +0,0 @@ -# Ignore common files that shouldn't be in build context -*.md -*.swp -*.swo -*~ -.git -.gitignore -.github -build/ -*.o -*.so -*.a -__pycache__/ -*.pyc -.pytest_cache/ -.vscode/ -.idea/ -*.log diff --git a/.docker/cuda/Dockerfile b/.docker/cuda/Dockerfile deleted file mode 100644 index 7315458108..0000000000 --- a/.docker/cuda/Dockerfile +++ /dev/null @@ -1,140 +0,0 @@ -# BOUT++ CUDA-enabled Docker container -# This Dockerfile builds BOUT++ with CUDA support using Spack for dependency management -# Fixes issue #3233 by using updated fmt library version - -FROM docker.io/nvidia/cuda:12.6.1-devel-ubuntu22.04 AS base -LABEL maintainer="BOUT++ Development Team" -USER root - -# Install system dependencies -# Using Ubuntu 22.04 for more recent toolchain and better CUDA support -RUN \ - apt update &&\ - DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles apt install -y \ - build-essential \ - git \ - software-properties-common \ - python3 \ - python3-pip \ - wget \ - mpich \ - libmpich-dev \ - unzip \ - libnuma-dev \ - libncurses-dev \ - curl \ - libcurl4-openssl-dev \ - gfortran \ - ca-certificates \ - libssl-dev &&\ - apt upgrade -y &&\ - apt clean - -FROM base AS setup-spack - -# CUDA architecture: 70=Volta, 75=Turing, 80=Ampere, 89=Ada, 90=Hopper -ARG CUDA_ARCH=80 - -# Install Spack and set up environment -RUN \ - git clone --depth 1 --single-branch --branch v0.23.0 https://github.com/spack/spack.git &&\ - . /spack/share/spack/setup-env.sh &&\ - spack env create -d /spack-env &&\ - spack env activate /spack-env &&\ - spack add cmake@3.24: &&\ - spack add blt@0.6.2 &&\ - spack add "umpire@2024.07.0+cuda~examples+numa+openmp cuda_arch=${CUDA_ARCH}" &&\ - spack add "raja@2024.07.0+cuda~examples~exercises+openmp cuda_arch=${CUDA_ARCH}" &&\ - spack add fmt@11.0.2 &&\ - spack add 'netcdf-cxx4@4.3.1 ^mpich' &&\ - spack add 'fftw@3.3.10 ^mpich' &&\ - spack external find --not-buildable &&\ - spack external find perl cuda bzip2 pkgconfig ncurses mpich curl openssl --not-buildable &&\ - spack install --show-log-on-error -j$(nproc) - -# Set up environment variables for the build -ENV SPACK_ROOT=/spack -ENV PATH="${SPACK_ROOT}/bin:${PATH}" - -FROM setup-spack AS bout-build - -ARG CUDA_ARCH=80 - -# Create boutuser (for consistency with existing Docker setup) -RUN useradd -m -s /bin/bash boutuser && \ - echo "boutuser:boutforever" | chpasswd && \ - usermod -aG sudo boutuser - -USER boutuser -WORKDIR /home/boutuser - -# Clone and build BOUT++ -ARG BOUT_URL=https://github.com/boutproject/BOUT-dev.git -ARG BOUT_COMMIT=master - -RUN git clone ${BOUT_URL} BOUT-dev && \ - cd BOUT-dev && \ - git checkout ${BOUT_COMMIT} && \ - git submodule update --init --recursive - -WORKDIR /home/boutuser/BOUT-dev - -# Activate Spack environment and configure BOUT++ with CUDA -USER root -RUN . /spack/share/spack/setup-env.sh && \ - spack env activate /spack-env && \ - spack load cmake && \ - spack load fmt && \ - spack load raja && \ - spack load umpire && \ - spack load netcdf-cxx4 && \ - spack load fftw && \ - chown -R boutuser:boutuser /home/boutuser/BOUT-dev - -USER boutuser - -# Configure BOUT++ with CUDA support -# CUDA_ARCH is set via build arg (default: 80 for Ampere/A100) -RUN . /spack/share/spack/setup-env.sh && \ - spack env activate /spack-env && \ - spack load cmake fmt raja umpire netcdf-cxx4 fftw && \ - cmake -S . -B build \ - -DCMAKE_INSTALL_PREFIX=/opt/bout++ \ - -DCMAKE_BUILD_TYPE=Release \ - -DBOUT_ENABLE_CUDA=ON \ - -DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCH} \ - -DCUDA_ARCH="compute_${CUDA_ARCH},code=sm_${CUDA_ARCH}" \ - -DBOUT_ENABLE_RAJA=ON \ - -DBOUT_ENABLE_UMPIRE=ON \ - -DBOUT_USE_SYSTEM_FMT=ON \ - -DBOUT_GENERATE_FIELDOPS=OFF \ - -DBOUT_ENABLE_PYTHON=ON \ - || (cat /home/boutuser/BOUT-dev/build/CMakeFiles/CMake{Output,Error}.log ; exit 1) - -# Build BOUT++ -RUN . /spack/share/spack/setup-env.sh && \ - spack env activate /spack-env && \ - spack load cmake fmt raja umpire netcdf-cxx4 fftw && \ - cmake --build build -j$(nproc) - -# Install BOUT++ -USER root -RUN . /spack/share/spack/setup-env.sh && \ - spack env activate /spack-env && \ - spack load cmake && \ - cmake --install build - -# Create a helper script to activate the Spack environment -RUN echo '#!/bin/bash\n\ -. /spack/share/spack/setup-env.sh\n\ -spack env activate /spack-env\n\ -spack load cmake fmt raja umpire netcdf-cxx4 fftw\n\ -exec "$@"' > /usr/local/bin/bout-env.sh && \ - chmod +x /usr/local/bin/bout-env.sh - -USER boutuser -WORKDIR /home/boutuser/BOUT-dev - -# Default command activates Spack environment and drops to bash -ENTRYPOINT ["/usr/local/bin/bout-env.sh"] -CMD ["/bin/bash"] diff --git a/.docker/cuda/README.md b/.docker/cuda/README.md deleted file mode 100644 index a180bb1b36..0000000000 --- a/.docker/cuda/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# BOUT++ CUDA Docker Container - -This directory contains a Dockerfile for building BOUT++ with CUDA support. - -## Changes from Previous Version - -This Dockerfile addresses issue [#3233](https://github.com/boutproject/BOUT-dev/issues/3233) by updating dependencies: - -- **Ubuntu**: 20.04 → 22.04 (better toolchain and CUDA support) -- **CUDA**: 12.2.2 → 12.6.1 (latest stable release) -- **Spack**: v0.21.1 → v0.23.0 (improved package management) -- **fmt**: 10.0.0 → 11.0.2 (fixes missing `fmt/base.h` header) -- **RAJA**: 2022.10.4 → 2024.07.0 (improved CUDA support) -- **Umpire**: 2022.03.1 → 2024.07.0 (improved memory management) -- **BLT**: 0.5.3 → 0.6.2 (build system updates) - -## Prerequisites - -- Docker or Podman installed -- NVIDIA Docker runtime (nvidia-docker2) for GPU access -- NVIDIA GPU with Compute Capability 8.0+ (Ampere or newer) - - For other architectures, use the `CUDA_ARCH` build arg (see below) - -## Building the Container - -### Basic build: -```bash -cd .docker/cuda -docker build -t bout-cuda:latest . -``` - -### Build with specific BOUT++ commit: -```bash -docker build \ - --build-arg BOUT_URL=https://github.com/boutproject/BOUT-dev.git \ - --build-arg BOUT_COMMIT= \ - -t bout-cuda:custom . -``` - -## Running the Container - -### Interactive shell: -```bash -docker run --gpus all -it bout-cuda:latest -``` - -### Run with mounted directory: -```bash -docker run --gpus all -it \ - -v $(pwd):/workspace \ - -w /workspace \ - bout-cuda:latest -``` - -### Check CUDA availability: -```bash -docker run --gpus all -it bout-cuda:latest bash -c "nvidia-smi && nvcc --version" -``` - -## GPU Architecture Notes - -The default build targets NVIDIA A100 GPUs (Ampere, `cuda_arch=80`). - -For other GPU architectures, pass the `CUDA_ARCH` build arg: - -```bash -# For Volta (V100) -docker build --build-arg CUDA_ARCH=70 -t bout-cuda:volta . - -# For Hopper (H100) -docker build --build-arg CUDA_ARCH=90 -t bout-cuda:hopper . - -# Or using the build script -./build.sh --cuda-arch 70 -``` - -Common CUDA architectures: -- **70**: Volta (V100) -- **75**: Turing (RTX 20 series, T4) -- **80**: Ampere (A100, RTX 30 series) -- **86**: Ampere (RTX 30 mobile, A10, A40) -- **89**: Ada Lovelace (RTX 40 series) -- **90**: Hopper (H100) - -## Troubleshooting - -### Spack build failures -If Spack fails to build packages, try increasing Docker memory allocation (minimum 8GB recommended). - -### CUDA runtime errors -Ensure nvidia-docker2 is properly installed: -```bash -# Test NVIDIA runtime -docker run --rm --gpus all nvidia/cuda:12.6.1-base-ubuntu22.04 nvidia-smi -``` - -### fmt header issues -If you encounter `fmt/base.h` not found errors, ensure you're using fmt 11.0+ (this is configured by default). - -## Container Layout - -- BOUT++ source: `/home/boutuser/BOUT-dev` -- BOUT++ install: `/opt/bout++` -- Spack environment: `/spack-env` -- Helper script: `/usr/local/bin/bout-env.sh` (loads Spack environment) - -## Environment Activation - -The container's entrypoint automatically activates the Spack environment. If you need to manually activate it: - -```bash -. /spack/share/spack/setup-env.sh -spack env activate /spack-env -spack load cmake fmt raja umpire netcdf-cxx4 fftw -``` - -Or simply use the helper script: -```bash -/usr/local/bin/bout-env.sh -``` diff --git a/.docker/cuda/build.sh b/.docker/cuda/build.sh deleted file mode 100755 index 81da0b5094..0000000000 --- a/.docker/cuda/build.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Build script for BOUT++ CUDA Docker container - -set -e - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )" - -# Default values -IMAGE_NAME="bout-cuda" -IMAGE_TAG="latest" -BOUT_URL="https://github.com/boutproject/BOUT-dev.git" -BOUT_COMMIT="master" -CUDA_ARCH="80" # Default to Ampere (A100) -BUILD_ARGS="" - -# Parse command line arguments -while [[ $# -gt 0 ]]; do - case $1 in - -n|--name) - IMAGE_NAME="$2" - shift 2 - ;; - -t|--tag) - IMAGE_TAG="$2" - shift 2 - ;; - --url) - BOUT_URL="$2" - shift 2 - ;; - --commit) - BOUT_COMMIT="$2" - shift 2 - ;; - --cuda-arch) - CUDA_ARCH="$2" - shift 2 - ;; - -h|--help) - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " -n, --name NAME Image name (default: bout-cuda)" - echo " -t, --tag TAG Image tag (default: latest)" - echo " --url URL BOUT++ repository URL" - echo " --commit COMMIT BOUT++ commit/branch to build (default: master)" - echo " --cuda-arch ARCH CUDA architecture (default: 80 for Ampere)" - echo " 70=Volta, 75=Turing, 80=Ampere, 86=Ampere(mobile)" - echo " 89=Ada, 90=Hopper" - echo " -h, --help Show this help message" - echo "" - echo "Examples:" - echo " $0 # Build with defaults" - echo " $0 --cuda-arch 70 # Build for Volta (V100)" - echo " $0 --commit v5.2.0 # Build specific version" - echo " $0 --name my-bout --tag dev # Custom image name and tag" - exit 0 - ;; - *) - echo "Unknown option: $1" - echo "Use -h or --help for usage information" - exit 1 - ;; - esac -done - -BUILD_ARGS="--build-arg BOUT_URL=${BOUT_URL}" -BUILD_ARGS="${BUILD_ARGS} --build-arg BOUT_COMMIT=${BOUT_COMMIT}" -BUILD_ARGS="${BUILD_ARGS} --build-arg CUDA_ARCH=${CUDA_ARCH}" - -echo "============================================" -echo "Building BOUT++ CUDA Docker Image" -echo "============================================" -echo "Image name: ${IMAGE_NAME}:${IMAGE_TAG}" -echo "BOUT++ URL: ${BOUT_URL}" -echo "BOUT++ commit: ${BOUT_COMMIT}" -echo "CUDA arch: ${CUDA_ARCH}" -echo "Build context: ${SCRIPT_DIR}" -echo "============================================" -echo "" - -# Build the image -cd "$SCRIPT_DIR" - -docker build \ - ${BUILD_ARGS} \ - -t "${IMAGE_NAME}:${IMAGE_TAG}" \ - -f Dockerfile \ - . - -echo "" -echo "============================================" -echo "Build complete!" -echo "============================================" -echo "Run with: docker run --gpus all -it ${IMAGE_NAME}:${IMAGE_TAG}" -echo "" -echo "To test CUDA:" -echo " docker run --gpus all -it ${IMAGE_NAME}:${IMAGE_TAG} bash -c 'nvidia-smi'" -echo "" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 58f7ffc2ae..921997299d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -83,29 +83,3 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - - build-cuda: - name: Build CUDA Container - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Log in to the Container registry - uses: docker/login-action@master - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push CUDA Docker image - uses: docker/build-push-action@master - with: - context: .docker/cuda/ - target: setup-spack - push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/boutdev-cuda:latest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7f48ed3e77..8099ddd4a8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -216,16 +216,15 @@ jobs: CUDA: timeout-minutes: 60 runs-on: ubuntu-latest - container: ghcr.io/boutproject/bout-dev/boutdev-cuda:latest + container: ghcr.io/boutproject/bout-container-base:boutdev-cuda steps: - uses: actions/checkout@v6 with: submodules: true - - name: Build minimal CUDA 12.6 @ Ubuntu 22.04 + - name: Build BOUT++ with CUDA 12.6 run: | - . /spack/share/spack/setup-env.sh - spack env activate -p /spack-env + . /usr/local/bin/bout-env.bash git config --global --add safe.directory $GITHUB_WORKSPACE rm -rf build cmake -S $GITHUB_WORKSPACE -B build \ From 627b23868487229df987fd5a0bfd00d7a69234da Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Wed, 18 Feb 2026 19:02:28 +0100 Subject: [PATCH 5/6] Update CUDA container tag to ci-cuda Match the tag rename in bout-container-base (ci-cuda instead of boutdev-cuda, consistent with the ci-fedora naming convention). Co-Authored-By: Claude Opus 4.6 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8099ddd4a8..b65f4f4fa5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -216,7 +216,7 @@ jobs: CUDA: timeout-minutes: 60 runs-on: ubuntu-latest - container: ghcr.io/boutproject/bout-container-base:boutdev-cuda + container: ghcr.io/boutproject/bout-container-base:ci-cuda steps: - uses: actions/checkout@v6 From cb731f14edcfed15406e6ddfb02823cc9d80b194 Mon Sep 17 00:00:00 2001 From: Yassine Alouini Date: Fri, 20 Feb 2026 09:15:46 +0100 Subject: [PATCH 6/6] Fix CUDA cmake: set CMAKE_CUDA_HOST_COMPILER before CUDA language init camp/BLT requires CMAKE_CUDA_HOST_COMPILER to be set before ENABLE_LANGUAGE(CUDA). Without it, the cmake configuration fails. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b65f4f4fa5..f1b1a6ce9f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -230,6 +230,7 @@ jobs: cmake -S $GITHUB_WORKSPACE -B build \ -DCMAKE_C_COMPILER=gcc \ -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_CUDA_HOST_COMPILER=gcc \ -DBOUT_ENABLE_RAJA=on \ -DBOUT_ENABLE_UMPIRE=on \ -DBOUT_ENABLE_CUDA=on \