diff --git a/.github/Dockerfile b/.github/Dockerfile index c7ddcd95a..c55d46bb5 100644 --- a/.github/Dockerfile +++ b/.github/Dockerfile @@ -2,26 +2,35 @@ ARG BASE_IMAGE FROM ${BASE_IMAGE} ARG TARGET +ARG INTERFACE ARG CC_COMPILER ARG CXX_COMPILER ARG FC_COMPILER ARG COMPILER_PATH ARG COMPILER_LD_LIBRARY_PATH +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -y software-properties-common wget && \ + add-apt-repository ppa:deadsnakes/ppa + RUN apt-get update -y && \ if [ "$TARGET" != "gpu" ]; then \ apt-get install -y \ - build-essential git make cmake gcc g++ gfortran bc\ - python3 python3-venv python3-pip \ + build-essential git make cmake gcc g++ gfortran bc \ + python3.14 python3.14-venv \ openmpi-bin libopenmpi-dev libfftw3-dev \ mpich libmpich-dev; \ else \ apt-get install -y \ - build-essential git make cmake bc\ - python3 python3-venv python3-pip \ + build-essential git make cmake bc \ + python3.14 python3.14-venv \ libfftw3-dev \ openmpi-bin libopenmpi-dev; \ fi && \ + update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.14 1 && \ + update-alternatives --set python3 /usr/bin/python3.14 && \ + python3 --version && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* ENV OMPI_ALLOW_RUN_AS_ROOT=1 @@ -30,6 +39,7 @@ ENV PATH="/opt/MFC:$PATH" COPY ../ /opt/MFC +ENV INTERFACE=${INTERFACE} ENV CC=${CC_COMPILER} ENV CXX=${CXX_COMPILER} ENV FC=${FC_COMPILER} @@ -39,17 +49,17 @@ ENV LD_LIBRARY_PATH="${COMPILER_LD_LIBRARY_PATH}:${LD_LIBRARY_PATH:-}" RUN echo "TARGET=$TARGET CC=$CC_COMPILER FC=$FC_COMPILER" && \ cd /opt/MFC && \ if [ "$TARGET" = "gpu" ]; then \ - ./mfc.sh build --gpu -j $(nproc); \ + ./mfc.sh build --gpu $INTERFACE -j $(nproc); \ else \ ./mfc.sh build -j $(nproc); \ fi RUN cd /opt/MFC && \ if [ "$TARGET" = "gpu" ]; then \ - ./mfc.sh test -a --dry-run --gpu -j $(nproc); \ + ./mfc.sh test -a --dry-run --gpu $INTERFACE -j $(nproc); \ else \ ./mfc.sh test -a --dry-run -j $(nproc); \ fi WORKDIR /opt/MFC -ENTRYPOINT ["tail", "-f", "/dev/null"] \ No newline at end of file +ENTRYPOINT ["tail", "-f", "/dev/null"] diff --git a/.github/docker_readme.md b/.github/docker_readme.md new file mode 100644 index 000000000..66f14452d --- /dev/null +++ b/.github/docker_readme.md @@ -0,0 +1,41 @@ +

+ + MFC Banner + +

+ + +

+ + + + + + + + + + + + + + + + + + +

+ + +

+ + + + + + + + +### **References:** [Official Documentation](https://mflowcode.github.io/), [GitHub Repository](https://github.com/MFlowCode/MFC). + +Please see the MFC documentation on [Docker use](https://mflowcode.github.io/documentation/md_docker.html) for more details. diff --git a/.github/workflows/docker-readme.yml b/.github/workflows/docker-readme.yml new file mode 100644 index 000000000..8a958c35e --- /dev/null +++ b/.github/workflows/docker-readme.yml @@ -0,0 +1,25 @@ +name: Docker Readme Update + +on: + pull_request: + types: [closed] + paths: + - '.github/docker_readme.md' + +jobs: + Container: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + path: pr + + - name: Docker Hub Description + uses: peter-evans/dockerhub-description@v5 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + repository: ${{ secrets.DOCKERHUB_USERNAME }}/mfc + readme-filepath: pr/.github/docker_readme.md diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml new file mode 100644 index 000000000..6c65a50dc --- /dev/null +++ b/.github/workflows/docker-test.yml @@ -0,0 +1,44 @@ +name: 'Test Docker Containers' + +on: + schedule: + - cron: '0 0 * * 5' # This runs every Friday at midnight UTC + +jobs: + self: + name: "${{ matrix.cluster_name }} (${{ matrix.device }}${{ matrix.interface != 'none' && format('-{0}', matrix.interface) || '' }})" + continue-on-error: false + timeout-minutes: 480 + strategy: + matrix: + include: + - lbl: 'gt' + cluster_name: 'Georgia Tech | Phoenix' + device: 'gpu' + interface: 'acc' + - lbl: 'gt' + cluster_name: 'Georgia Tech | Phoenix' + device: 'gpu' + interface: 'mp' + - lbl: 'gt' + cluster_name: 'Georgia Tech | Phoenix' + device: 'cpu' + interface: 'none' + runs-on: + group: phoenix + labels: ${{ matrix.lbl }} + env: + NODE_OPTIONS: ${{ matrix.lbl == 'gt' && '--max-old-space-size=2048' || '' }} + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + steps: + - name: Clone + uses: actions/checkout@v4 + + - name: Pull & Test + if: matrix.lbl == 'gt' + run: bash .github/workflows/phoenix/submit.sh .github/workflows/phoenix/container.sh ${{ matrix.device }} ${{ matrix.interface }} + + - name: Print Logs + if: always() + run: cat container-${{ matrix.device }}-${{ matrix.interface }}.out diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b12c6cdc5..66fe49efc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,9 +18,12 @@ jobs: strategy: matrix: config: - - { name: 'cpu', runner: 'ubuntu-22.04', base_image: 'ubuntu:22.04' } - - { name: 'gpu', runner: 'ubuntu-22.04', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } - - { name: 'gpu', runner: 'ubuntu-22.04-arm', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } + - { name: 'cpu', interface: 'none', runner: 'ubuntu-22.04', base_image: 'ubuntu:22.04' } + - { name: 'gpu', interface: 'acc', runner: 'ubuntu-22.04', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } + - { name: 'gpu', interface: 'acc', runner: 'ubuntu-22.04-arm', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } + - { name: 'gpu', interface: 'mp', runner: 'ubuntu-22.04', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } + - { name: 'gpu', interface: 'mp', runner: 'ubuntu-22.04-arm', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } + runs-on: ${{ matrix.config.runner }} outputs: tag: ${{ steps.clone.outputs.tag }} @@ -84,6 +87,7 @@ jobs: build-args: | BASE_IMAGE=${{ matrix.config.base_image }} TARGET=${{ matrix.config.name }} + INTERFACE=${{ matrix.config.interface }} CC_COMPILER=${{ 'gcc' }} CXX_COMPILER=${{ 'g++' }} FC_COMPILER=${{ 'gfortran' }} @@ -102,12 +106,13 @@ jobs: build-args: | BASE_IMAGE=${{ matrix.config.base_image }} TARGET=${{ matrix.config.name }} + INTERFACE=${{ matrix.config.interface }} CC_COMPILER=${{ 'nvc' }} CXX_COMPILER=${{ 'nvc++' }} FC_COMPILER=${{ 'nvfortran' }} COMPILER_PATH=${{ '/opt/nvidia/hpc_sdk/Linux_x86_64/compilers/bin' }} COMPILER_LD_LIBRARY_PATH=${{ '/opt/nvidia/hpc_sdk/Linux_x86_64/compilers/lib' }} - tags: ${{ secrets.DOCKERHUB_USERNAME }}/mfc:${{ env.TAG }}-${{ matrix.config.name }}-${{ matrix.config.runner}} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/mfc:${{ env.TAG }}-${{ matrix.config.name }}-${{ matrix.config.interface }}-${{ matrix.config.runner }} push: true manifests: @@ -125,8 +130,17 @@ jobs: TAG: ${{ needs.Container.outputs.tag }} REGISTRY: ${{ secrets.DOCKERHUB_USERNAME }}/mfc run: | + # CPU Manifest docker buildx imagetools create -t $REGISTRY:latest-cpu $REGISTRY:$TAG-cpu - docker manifest create $REGISTRY:$TAG-gpu $REGISTRY:$TAG-gpu-ubuntu-22.04 $REGISTRY:$TAG-gpu-ubuntu-22.04-arm - docker manifest create $REGISTRY:latest-gpu $REGISTRY:$TAG-gpu-ubuntu-22.04 $REGISTRY:$TAG-gpu-ubuntu-22.04-arm + + # GPU Manifest (ACC) + docker manifest create $REGISTRY:$TAG-gpu $REGISTRY:$TAG-gpu-acc-ubuntu-22.04 $REGISTRY:$TAG-gpu-acc-ubuntu-22.04-arm + docker manifest create $REGISTRY:latest-gpu $REGISTRY:$TAG-gpu-acc-ubuntu-22.04 $REGISTRY:$TAG-gpu-acc-ubuntu-22.04-arm docker manifest push $REGISTRY:$TAG-gpu - docker manifest push $REGISTRY:latest-gpu \ No newline at end of file + docker manifest push $REGISTRY:latest-gpu + + # GPU Manifest (OMP) + docker manifest create $REGISTRY:$TAG-mp-gpu $REGISTRY:$TAG-gpu-mp-ubuntu-22.04 $REGISTRY:$TAG-gpu-mp-ubuntu-22.04-arm + docker manifest create $REGISTRY:latest-mp-gpu $REGISTRY:$TAG-gpu-mp-ubuntu-22.04 $REGISTRY:$TAG-gpu-mp-ubuntu-22.04-arm + docker manifest push $REGISTRY:$TAG-mp-gpu + docker manifest push $REGISTRY:latest-mp-gpu diff --git a/.github/workflows/phoenix/container.sh b/.github/workflows/phoenix/container.sh new file mode 100644 index 000000000..554ef7564 --- /dev/null +++ b/.github/workflows/phoenix/container.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +if [ "$job_interface" = "mp" ]; then + apptainer build mfc:latest-$job_device.sif docker://sbryngelson/mfc:latest-mp-$job_device +else + apptainer build mfc:latest-$job_device.sif docker://sbryngelson/mfc:latest-$job_device +fi + +CONTAINER="mfc:latest-$job_device.sif" + +NV_FLAG="" +[ "$job_device" = "gpu" ] && NV_FLAG="--nv" + +# unset LD_PRELOAD + +apptainer exec $NV_FLAG --fakeroot --writable-tmpfs \ + --bind "$SCRATCH_DIR":/scratch \ + --env job_slug="$job_slug" \ + --env job_device="$job_device" \ + "$CONTAINER" \ + bash -c 'cd /opt/MFC && + +build_opts="" +if [ "$job_device" = "gpu" ]; then + build_opts="--gpu" + if [ "$job_interface" = "mp" ]; then + build_opts+=" mp" + elif [ "$job_interface" = "acc" ]; then + build_opts+=" acc" + fi +fi + +./mfc.sh test --dry-run -j 8 $build_opts + +n_test_threads=8 + +if [ "$job_device" = "gpu" ]; then + gpu_count=$(nvidia-smi -L | wc -l) # number of GPUs on node + gpu_ids=$(seq -s " " 0 $(($gpu_count-1))) # 0,1,2,...,gpu_count-1 + device_opts="-g $gpu_ids" + n_test_threads=`expr $gpu_count \* 2` +fi + +./mfc.sh test --no-build --max-attempts 3 -a -j $n_test_threads $device_opts -- -c phoenix + ' diff --git a/docs/documentation/docker.md b/docs/documentation/docker.md index 16e41c06f..908f19db0 100644 --- a/docs/documentation/docker.md +++ b/docs/documentation/docker.md @@ -148,12 +148,15 @@ In the above, ## Tag Details ### Base Images -- CPU images (v4.3.0-latest releases) are built on **Ubuntu 22.04**. -- GPU images (v4.3.0-latest releases) are built on **NVHPC SDK 23.11 (CUDA 12.3) & Ubuntu 22.04**. +- CPU images (v4.3.0-latest release) are built on **Ubuntu 22.04**. +- GPU images (v4.3.0-latest release) are built on **NVHPC SDK 23.11 (CUDA 12.3) & Ubuntu 22.04**. + - OpenACC images (v4.3.0-latest release). + - OpenMP images (v5.1.0-latest release). ### Tag Structure - **`vx.x.x`** - Official MFC release versions (recommended: use `latest` release) - **`cpu/gpu`** - Build configurations for CPU or GPU acceleration. +- **`acc/mp`** - Build configurations for OpenACC or OpenMP parallelization. - **`ubuntu-xx.xx`** - Base Ubuntu version (standard = `amd64`, `-arm` = `arm64`) ### Example Tags @@ -161,7 +164,8 @@ In the above, ```shell mfc:latest-xxx # Latest version (amd64 & arm64) mfc:vx.x.x-cpu # CPU version (amd64 & arm64) -mfc:vx.x.x-gpu # GPU version (amd64 & arm64) +mfc:vx.x.x-gpu # OpenACC-supported GPU version (amd64 & arm64) +mfc:vx.x.x-mp-gpu # OpenMP-supported GPU version (amd64 & arm64) mfc:vx.x.x-xxx-ubuntu-xx.xx # amd64 natively-supported version mfc:vx.x.x-xxx-ubuntu-xx.xx-arm # arm64 natively-supported version ```