diff --git a/.github/workflows/docker_build_tpls.yml b/.github/workflows/docker_build_tpls.yml index 2f4151e6..2520af8f 100644 --- a/.github/workflows/docker_build_tpls.yml +++ b/.github/workflows/docker_build_tpls.yml @@ -7,6 +7,13 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# The TPL images now build on top of the base images produced by +# https://github.com/GEOS-DEV/docker_base_images, so each matrix entry only +# needs to point at one of those tags. Update DOCKER_BASE_IMAGE_SHA below to +# bump the toolchain across every row in lockstep. +env: + DOCKER_BASE_IMAGE_SHA: 47ddae2621f6fc0c2da8bf36305d3fd3730a7db7 + jobs: build_images: name: ${{ matrix.name }} @@ -19,73 +26,169 @@ jobs: matrix: include: - - name: Ubuntu (20.04, gcc 9.4.0, open-mpi 4.0.3) - DOCKER_REPOSITORY: geosx/ubuntu20.04-gcc9 - TPL_DOCKERFILE: docker/tpl-ubuntu-gcc.Dockerfile - DOCKER_ROOT_IMAGE: ubuntu:20.04 - DOCKER_COMPILER_BUILD_ARG: "--build-arg GCC_MAJOR_VERSION=9" + # ---------- Ubuntu 24.04, host (no CUDA) ---------- + - name: Ubuntu 24.04 - gcc 12 + RUNS_ON: ubuntu-latest + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-gcc12 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-gcc12 + GCC_VERSION: 12 + SPEC: "~pygeosx +docs %%gcc-12" + + - name: Ubuntu 24.04 - gcc 13 RUNS_ON: ubuntu-latest - - name: Ubuntu (20.04, gcc 10.5.0, open-mpi 4.0.3) - github codespaces - DOCKER_REPOSITORY: geosx/ubuntu20.04-gcc10 - TPL_DOCKERFILE: docker/tpl-ubuntu-gcc.Dockerfile - DOCKER_ROOT_IMAGE: mcr.microsoft.com/devcontainers/base:ubuntu-20.04 - DOCKER_COMPILER_BUILD_ARG: "--build-arg GCC_MAJOR_VERSION=10" + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-gcc13 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-gcc13 + GCC_VERSION: 13 + SPEC: "~pygeosx +docs %%gcc-13" + + - name: Ubuntu 24.04 - clang 19 RUNS_ON: ubuntu-latest - - name: Ubuntu (22.04, gcc 11.4.0, open-mpi 4.1.2) - DOCKER_ROOT_IMAGE: ubuntu:22.04 - DOCKER_REPOSITORY: geosx/ubuntu22.04-gcc11 - TPL_DOCKERFILE: docker/tpl-ubuntu-gcc.Dockerfile - DOCKER_COMPILER_BUILD_ARG: "--build-arg GCC_MAJOR_VERSION=11" + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-clang19 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-clang19 + GCC_VERSION: 13 + CLANG_VERSION: 19 + SPEC: "~shared~openmp +docs %%clang-19 ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Ubuntu 24.04 - clang 20 RUNS_ON: ubuntu-latest - - name: Ubuntu (22.04, gcc 12.3.0, open-mpi 4.1.2) - DOCKER_ROOT_IMAGE: ubuntu:22.04 - DOCKER_REPOSITORY: geosx/ubuntu22.04-gcc12 - TPL_DOCKERFILE: docker/tpl-ubuntu-gcc.Dockerfile - DOCKER_COMPILER_BUILD_ARG: "--build-arg GCC_MAJOR_VERSION=12" + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-clang20 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-clang20 + GCC_VERSION: 13 + CLANG_VERSION: 20 + SPEC: "~shared~openmp +docs %%clang-20 ^caliper~gotcha~sampler~libunwind~libdw~papi" + + # ---------- Rocky Linux 8 / 9, host (no CUDA) ---------- + - name: Rocky Linux 8 - gcc 12 RUNS_ON: ubuntu-latest - - name: Ubuntu (22.04, gcc 12.3.0, open-mpi 4.1.2, +hypredrive) - DOCKER_ROOT_IMAGE: ubuntu:22.04 - DOCKER_REPOSITORY: geosx/ubuntu22.04-gcc12-hypredrive - TPL_DOCKERFILE: docker/tpl-ubuntu-gcc.Dockerfile - DOCKER_COMPILER_BUILD_ARG: "--build-arg GCC_MAJOR_VERSION=12" - SPEC: "~pygeosx +docs +hypredrive %gcc-12" + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 8-gcc12 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux8-gcc12 + GCC_VERSION: 12 + SPEC: "~pygeosx +docs %%gcc-12" + + - name: Rocky Linux 8 - gcc 13 RUNS_ON: ubuntu-latest - - name: Ubuntu (22.04, clang 15.0.7 + gcc 11.4.0, open-mpi 4.1.2) - DOCKER_ROOT_IMAGE: ubuntu:22.04 - DOCKER_REPOSITORY: geosx/ubuntu22.04-clang15 - TPL_DOCKERFILE: docker/tpl-ubuntu-clang.Dockerfile - DOCKER_COMPILER_BUILD_ARG: "--build-arg CLANG_MAJOR_VERSION=15 --build-arg GCC_MAJOR_VERSION=11" + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 8-gcc13 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux8-gcc13 + GCC_VERSION: 13 + SPEC: "~pygeosx +docs %%gcc-13" + + - name: Rocky Linux 8 - clang 19 RUNS_ON: ubuntu-latest - - name: Ubuntu (20.04, clang 10.0.0 + gcc 9.4.0, open-mpi 4.0.3, cuda-11.8.89) - DOCKER_REPOSITORY: geosx/ubuntu20.04-clang10.0.0-cuda11.8.89 - TPL_DOCKERFILE: docker/tpl-ubuntu-clang-cuda.Dockerfile + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 8-clang19 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux8-clang19 + GCC_VERSION: 13 + CLANG_VERSION: 19 + SPEC: "~shared~openmp +docs %%clang-19 ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Rocky Linux 9 - clang 22 + RUNS_ON: ubuntu-latest + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 9-clang22 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux9-clang22 + GCC_VERSION: 15 + CLANG_VERSION: 22 + SPEC: "~shared~openmp +docs %%clang-22 ^caliper~gotcha~sampler~libunwind~libdw~papi" + + # ---------- Ubuntu 24.04 + CUDA ---------- + - name: Ubuntu 24.04 - gcc 13 + CUDA 12.9.1 + RUNS_ON: ubuntu-latest + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-gcc13-cuda12.9.1 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-gcc13-cuda12.9.1 + GCC_VERSION: 13 + SPEC: "+cuda~uncrustify~openmp~pygeosx lai=hypre cuda_arch=86 %%gcc-13 ^cuda@12.9.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Ubuntu 24.04 - gcc 14 + CUDA 13.2.1 + RUNS_ON: ubuntu-latest + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-gcc14-cuda13.2.1 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-gcc14-cuda13.2.1 + GCC_VERSION: 14 + SPEC: "+cuda~uncrustify~openmp~pygeosx lai=hypre cuda_arch=86 %%gcc-14 ^cuda@13.2.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Ubuntu 24.04 - clang 19 + CUDA 12.9.1 RUNS_ON: ubuntu-latest - - name: Rockylinux (8, gcc 13.3, cuda 12.9.1) + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-clang19-cuda12.9.1 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-clang19-cuda12.9.1 + GCC_VERSION: 13 + CLANG_VERSION: 19 + SPEC: "+cuda~uncrustify~openmp~pygeosx cuda_arch=86 %%clang-19 ^cuda@12.9.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Ubuntu 24.04 - clang 20 + CUDA 13.2.1 + RUNS_ON: ubuntu-latest + TPL_DOCKERFILE: docker/tpl-ubuntu.Dockerfile + DOCKER_BASE_IMAGE_TAG: 24.04-clang20-cuda13.2.1 + DOCKER_BASE_IMAGE_REPO: geosx/ubuntu + DOCKER_REPOSITORY: geosx/ubuntu24.04-clang20-cuda13.2.1 + GCC_VERSION: 15 + CLANG_VERSION: 20 + SPEC: "+cuda~uncrustify~openmp~pygeosx cuda_arch=86 %%clang-20 ^cuda@13.2.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + # ---------- Rocky Linux + CUDA ---------- + - name: Rocky Linux 8 - gcc 13 + CUDA 12.9.1 + RUNS_ON: streak2 + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 8-gcc13-cuda12.9.1 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux DOCKER_REPOSITORY: geosx/rockylinux8-gcc13-cuda12.9.1 - TPL_DOCKERFILE: docker/tpl-rockylinux-gcc-cuda-12.Dockerfile + NPROC: 8 + GCC_VERSION: 13 + DOCKER_RUN_ARGS: "--cpus=8 --memory=128g --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -v /etc/pki/tls/certs/ca-bundle.crt:/etc/pki/tls/certs/ca-bundle.crt:ro -v /etc/pki/tls/certs/ca-bundle.crt:/certs/ca-bundle.crt:ro" + SPEC: "+cuda~uncrustify~openmp~pygeosx lai=hypre cuda_arch=86 %%gcc-13 ^cuda@12.9.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Rocky Linux 9 - gcc 15 + CUDA 13.2.1 RUNS_ON: streak2 + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 9-gcc15-cuda13.2.1 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux9-gcc15-cuda13.2.1 NPROC: 8 + GCC_VERSION: 15 DOCKER_RUN_ARGS: "--cpus=8 --memory=128g --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -v /etc/pki/tls/certs/ca-bundle.crt:/etc/pki/tls/certs/ca-bundle.crt:ro -v /etc/pki/tls/certs/ca-bundle.crt:/certs/ca-bundle.crt:ro" - - name: Rockylinux (8, clang 17.0.6, cuda 12.9.1) - DOCKER_REPOSITORY: geosx/rockylinux8-clang17-cuda12.9.1 - TPL_DOCKERFILE: docker/tpl-rockylinux-clang-cuda-12.Dockerfile + SPEC: "+cuda~uncrustify~openmp~pygeosx lai=hypre cuda_arch=86 %%gcc-15 ^cuda@13.2.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Rocky Linux 8 - clang 19 + CUDA 12.9.1 RUNS_ON: streak2 + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 8-clang19-cuda12.9.1 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux8-clang19-cuda12.9.1 NPROC: 8 + GCC_VERSION: 13 + CLANG_VERSION: 19 DOCKER_RUN_ARGS: "--cpus=8 --memory=128g --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -v /etc/pki/tls/certs/ca-bundle.crt:/etc/pki/tls/certs/ca-bundle.crt:ro -v /etc/pki/tls/certs/ca-bundle.crt:/certs/ca-bundle.crt:ro" - # - name: Sherlock CPU (centos 7.9.2009, gcc 10.1.0, open-mpi 4.1.2, openblas 0.3.10, zlib 1.2.11) - # DOCKER_REPOSITORY: geosx/sherlock-gcc10.1.0-openmpi4.1.2-openblas0.3.10-zlib1.2.11 - # TPL_DOCKERFILE: docker/Stanford/Dockerfile - # DOCKER_ROOT_IMAGE: matteofrigo5/sherlock-gcc10.1.0-openmpi4.1.2-cuda12.4.0-openblas0.3.10-zlib1.2.11-cmake3.31.4-no-geosx:0.0.1 - # SPEC: "~pygeosx~openmp %gcc@10.1.0" - # INSTALL_DIR_ROOT: /oak/stanford/groups/tchelepi/geos-sherlock/CPU - # RUNS_ON: ubuntu-latest - # - name: Sherlock GPU (centos 7.9.2009, gcc 10.1.0, open-mpi 4.1.2, cuda 12.4.0, openblas 0.3.10, zlib 1.2.11) - # DOCKER_REPOSITORY: geosx/sherlock-gcc10.1.0-openmpi4.1.2-cuda12.4.0-openblas0.3.10-zlib1.2.11 - # TPL_DOCKERFILE: docker/Stanford/Dockerfile - # DOCKER_ROOT_IMAGE: matteofrigo5/sherlock-gcc10.1.0-openmpi4.1.2-cuda12.4.0-openblas0.3.10-zlib1.2.11-cmake3.31.4-no-geosx:0.0.1 - # SPEC: "~pygeosx~openmp cuda_arch=86 %gcc@10.1.0 ^cuda@12.4.0+allow-unsupported-compilers" - # INSTALL_DIR_ROOT: /oak/stanford/groups/tchelepi/geos-sherlock/GPU - # RUNS_ON: ubuntu-latest + SPEC: "+cuda~uncrustify~openmp~pygeosx cuda_arch=86 %%clang-19 ^cuda@12.9.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" + + - name: Rocky Linux 9 - clang 20 + CUDA 13.2.1 + RUNS_ON: streak2 + TPL_DOCKERFILE: docker/tpl-rockylinux.Dockerfile + DOCKER_BASE_IMAGE_TAG: 9-clang20-cuda13.2.1 + DOCKER_BASE_IMAGE_REPO: geosx/rockylinux + DOCKER_REPOSITORY: geosx/rockylinux9-clang20-cuda13.2.1 + NPROC: 8 + GCC_VERSION: 15 + CLANG_VERSION: 20 + DOCKER_RUN_ARGS: "--cpus=8 --memory=128g --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -v /etc/pki/tls/certs/ca-bundle.crt:/etc/pki/tls/certs/ca-bundle.crt:ro -v /etc/pki/tls/certs/ca-bundle.crt:/certs/ca-bundle.crt:ro" + SPEC: "+cuda~uncrustify~openmp~pygeosx cuda_arch=86 %%clang-20 ^cuda@13.2.1+allow-unsupported-compilers ^caliper~gotcha~sampler~libunwind~libdw~papi" steps: - name: Checkout @@ -100,6 +203,11 @@ jobs: - name: Print environment run: printenv + - name: Compose DOCKER_BASE_IMAGE + id: base + run: | + echo "DOCKER_BASE_IMAGE=${{ matrix.DOCKER_BASE_IMAGE_REPO }}:${{ matrix.DOCKER_BASE_IMAGE_TAG }}-${DOCKER_BASE_IMAGE_SHA}" >> "$GITHUB_OUTPUT" + - name: Inject CA certificate into Docker build if: matrix.RUNS_ON == 'streak2' run: | @@ -113,11 +221,12 @@ jobs: env: TPL_DOCKERFILE: ${{ matrix.TPL_DOCKERFILE }} DOCKER_REPOSITORY: ${{ matrix.DOCKER_REPOSITORY }} - DOCKER_COMPILER_BUILD_ARG: ${{ matrix.DOCKER_COMPILER_BUILD_ARG }} + DOCKER_BASE_IMAGE: ${{ steps.base.outputs.DOCKER_BASE_IMAGE }} + GCC_VERSION: ${{ matrix.GCC_VERSION }} + CLANG_VERSION: ${{ matrix.CLANG_VERSION }} INSTALL_DIR_ROOT: ${{ matrix.INSTALL_DIR_ROOT || '/opt/GEOS' }} - HOST_CONFIG: ${{ matrix.HOST_CONFIG || 'host-configs/environment.cmake'}} + HOST_CONFIG: ${{ matrix.HOST_CONFIG || 'host-configs/environment.cmake' }} SPEC: ${{ matrix.SPEC || 'undefined' }} - DOCKER_ROOT_IMAGE: ${{ matrix.DOCKER_ROOT_IMAGE || 'undefined' }} COMMIT: ${{ github.sha }} BUILD_DIR: ${{ github.workspace }} DOCKER_TAG: ${{ github.event.number }}-${{ github.run_number }} diff --git a/docker/rocky-spack.yaml b/docker/rocky-spack.yaml index b8f4d457..74fda393 100644 --- a/docker/rocky-spack.yaml +++ b/docker/rocky-spack.yaml @@ -17,28 +17,83 @@ spack: - ../defaults.yaml - ../versions.yaml + # --------------------------------------------------------------------------- + # Toolchains + # + # Aligned with the geosx/rockylinux:* base images produced by + # https://github.com/GEOS-DEV/docker_base_images. Each base image installs + # exactly one of these toolchains; the matrix in + # .github/workflows/docker_build_tpls.yml picks the matching '%' + # selector via the SPEC build-arg. + # --------------------------------------------------------------------------- toolchains: + gcc-12: + - spec: cxxflags='-fPIC -pthread' + - spec: cflags='-fPIC -pthread' + - spec: '%c=gcc@12' + when: '%c' + - spec: '%cxx=gcc@12' + when: '%cxx' + - spec: '%fortran=gcc@12' + when: '%fortran' + - spec: '%openmpi' + when: '%mpi' gcc-13: - spec: cxxflags='-fPIC -pthread' - spec: cflags='-fPIC -pthread' - - spec: '%c=gcc@13.3.1' + - spec: '%c=gcc@13' when: '%c' - - spec: '%cxx=gcc@13.3.1' + - spec: '%cxx=gcc@13' when: '%cxx' - - spec: '%fortran=gcc@13.3.1' + - spec: '%fortran=gcc@13' when: '%fortran' - - spec: '%openmpi@4.1.1' + - spec: '%openmpi' when: '%mpi' - clang-17: + gcc-15: - spec: cxxflags='-fPIC -pthread' - spec: cflags='-fPIC -pthread' - - spec: '%[virtuals=c]llvm@17.0.6+clang~flang~lld~lldb' + - spec: '%c=gcc@15' when: '%c' - - spec: '%[virtuals=cxx]llvm@17.0.6+clang~flang~lld~lldb' + - spec: '%cxx=gcc@15' when: '%cxx' - - spec: '%[virtuals=fortran]gcc@13.3.1' + - spec: '%fortran=gcc@15' when: '%fortran' - - spec: '%openmpi@4.1.1' + - spec: '%openmpi' + when: '%mpi' + # clang base images provide clang/clang++ as CC/CXX and gfortran from the + # paired GCC version. + clang-19: + - spec: cxxflags='-fPIC -pthread' + - spec: cflags='-fPIC -pthread' + - spec: '%[virtuals=c]llvm@19+clang~flang~lld~lldb' + when: '%c' + - spec: '%[virtuals=cxx]llvm@19+clang~flang~lld~lldb' + when: '%cxx' + - spec: '%[virtuals=fortran]gcc@13' + when: '%fortran' + - spec: '%openmpi' + when: '%mpi' + clang-20: + - spec: cxxflags='-fPIC -pthread' + - spec: cflags='-fPIC -pthread' + - spec: '%[virtuals=c]llvm@20+clang~flang~lld~lldb' + when: '%c' + - spec: '%[virtuals=cxx]llvm@20+clang~flang~lld~lldb' + when: '%cxx' + - spec: '%[virtuals=fortran]gcc@15' + when: '%fortran' + - spec: '%openmpi' + when: '%mpi' + clang-22: + - spec: cxxflags='-fPIC -pthread' + - spec: cflags='-fPIC -pthread' + - spec: '%[virtuals=c]llvm@22+clang~flang~lld~lldb' + when: '%c' + - spec: '%[virtuals=cxx]llvm@22+clang~flang~lld~lldb' + when: '%cxx' + - spec: '%[virtuals=fortran]gcc@15' + when: '%fortran' + - spec: '%openmpi' when: '%mpi' packages: @@ -47,9 +102,12 @@ spack: providers: zlib-api: [zlib] + # Rocky 8 ships OpenMPI 4.1.1; Rocky 9 ships 4.1.5. Same install prefix on + # both. We declare both externals; Spack resolves whichever matches the + # toolchain pin in the SPEC. mpi: require: - - openmpi@4.1.1 + - openmpi blas: require: @@ -58,26 +116,80 @@ spack: require: - "netlib-lapack" + # ---- Compilers ---- + # Point Spack directly at the clang/clang++ binaries from the base image. llvm: externals: - - spec: llvm@17.0.6+clang~flang~lld~lldb + - spec: llvm@19+clang~flang~lld~lldb + prefix: /usr + extra_attributes: + compilers: + c: /usr/bin/clang + cxx: /usr/bin/clang++ + - spec: llvm@20+clang~flang~lld~lldb + prefix: /usr + extra_attributes: + compilers: + c: /usr/bin/clang + cxx: /usr/bin/clang++ + - spec: llvm@22+clang~flang~lld~lldb prefix: /usr extra_attributes: compilers: - # Use wrappers that bake in --gcc-toolchain for gcc-toolset-13, so NVCC's -ccbin - # doesn't accidentally pick GCC 8 headers when compiling CUDA sources. - c: /usr/local/bin/clang-gcc13 - cxx: /usr/local/bin/clang++-gcc13 + c: /usr/bin/clang + cxx: /usr/bin/clang++ + gcc: externals: - - spec: gcc@13.3.1 languages:='c,c++,fortran' + - spec: gcc@12 languages:='c,c++,fortran' + prefix: /opt/rh/gcc-toolset-12/root/usr + extra_attributes: + compilers: + c: /opt/rh/gcc-toolset-12/root/usr/bin/gcc + cxx: /opt/rh/gcc-toolset-12/root/usr/bin/g++ + fortran: /opt/rh/gcc-toolset-12/root/usr/bin/gfortran + - spec: gcc@13 languages:='c,c++,fortran' prefix: /opt/rh/gcc-toolset-13/root/usr extra_attributes: compilers: c: /opt/rh/gcc-toolset-13/root/usr/bin/gcc cxx: /opt/rh/gcc-toolset-13/root/usr/bin/g++ fortran: /opt/rh/gcc-toolset-13/root/usr/bin/gfortran + - spec: gcc@15 languages:='c,c++,fortran' + prefix: /opt/rh/gcc-toolset-15/root/usr + extra_attributes: + compilers: + c: /opt/rh/gcc-toolset-15/root/usr/bin/gcc + cxx: /opt/rh/gcc-toolset-15/root/usr/bin/g++ + fortran: /opt/rh/gcc-toolset-15/root/usr/bin/gfortran + + # OpenMPI: same install prefix on every Rocky version, version differs. + # Spack picks whichever matches the toolchain pin (we don't %-pin here + # because the toolchains intentionally use bare `%openmpi`). + openmpi: + buildable: false + externals: + - spec: openmpi@4.1.1 + prefix: /usr/lib64/openmpi + - spec: openmpi@4.1.5 + prefix: /usr/lib64/openmpi + + doxygen: + buildable: false + externals: + - spec: doxygen@1.8.20 + prefix: /usr + + # ---- CUDA ---- + cuda: + buildable: False + externals: + - spec: cuda@12.9.1 +allow-unsupported-compilers + prefix: /usr/local/cuda + - spec: cuda@13.2.1 +allow-unsupported-compilers + prefix: /usr/local/cuda + # ---- System tools provided by the base image ---- autoconf: version: [2.71] buildable: false @@ -91,22 +203,16 @@ spack: - spec: automake@1.16.5 prefix: /usr cmake: - version: [3.28.6] + version: [3.31.9] buildable: false externals: - - spec: cmake@3.28.6 + - spec: cmake@3.31.9 prefix: /usr/local - cuda: - buildable: False - externals: - - spec: cuda@12.9.1 +allow-unsupported-compilers - prefix: /usr/local/cuda m4: buildable: false externals: - spec: m4@1.4.18 prefix: /usr - netlib-lapack: buildable: false externals: @@ -117,11 +223,6 @@ spack: externals: - spec: netlib-blas@3.8.0 prefix: /usr - openmpi: - buildable: false - externals: - - spec: openmpi@4.1.1 - prefix: /usr/lib64/openmpi perl: buildable: false externals: @@ -137,6 +238,8 @@ spack: externals: - spec: python@3.6.8 prefix: /usr + - spec: python@3.9.18 + prefix: /usr tar: buildable: false externals: diff --git a/docker/spack.yaml b/docker/spack.yaml index 50c71756..4e478202 100644 --- a/docker/spack.yaml +++ b/docker/spack.yaml @@ -17,77 +17,105 @@ spack: - ../defaults.yaml - ../versions.yaml + # --------------------------------------------------------------------------- + # Toolchains + # + # Aligned with the geosx/ubuntu:* base images produced by + # https://github.com/GEOS-DEV/docker_base_images. Each base image installs + # exactly one of these toolchains; the matrix in + # .github/workflows/docker_build_tpls.yml picks the matching '%' + # selector via the SPEC build-arg. + # --------------------------------------------------------------------------- toolchains: - clang-15: - - spec: '%[virtuals=c]llvm@15.0.7+clang~flang~lld~lldb' + gcc-12: + - spec: cxxflags='-pthread' + - spec: cflags='-pthread' + - spec: '%c=gcc@12' when: '%c' - - spec: '%[virtuals=cxx]llvm@15.0.7+clang~flang~lld~lldb' + - spec: '%cxx=gcc@12' when: '%cxx' - - spec: '%[virtuals=fortran]gcc@11.4.0' + - spec: '%fortran=gcc@12' when: '%fortran' - - spec: '%openmpi' + - spec: '%openmpi %gcc@12' when: '%mpi' - clang-10: - - spec: '%[virtuals=c]llvm@10.0.0+clang~flang~lld~lldb openmp=project' + gcc-13: + - spec: cxxflags='-pthread' + - spec: cflags='-pthread' + - spec: '%c=gcc@13' when: '%c' - - spec: '%[virtuals=cxx]llvm@10.0.0+clang~flang~lld~lldb openmp=project' + - spec: '%cxx=gcc@13' when: '%cxx' - - spec: '%[virtuals=fortran]gcc@9.4.0' + - spec: '%fortran=gcc@13' when: '%fortran' - - spec: '%openmpi' + - spec: '%openmpi %gcc@13' when: '%mpi' - gcc-9: + gcc-14: - spec: cxxflags='-pthread' - spec: cflags='-pthread' - - spec: '%c=gcc@9.4.0' + - spec: '%c=gcc@14' when: '%c' - - spec: '%cxx=gcc@9.4.0' + - spec: '%cxx=gcc@14' when: '%cxx' - - spec: '%fortran=gcc@9.4.0' + - spec: '%fortran=gcc@14' when: '%fortran' - - spec: '%openmpi %gcc@9.4.0' + - spec: '%openmpi %gcc@14' when: '%mpi' - gcc-10: + gcc-15: - spec: cxxflags='-pthread' - spec: cflags='-pthread' - - spec: '%c=gcc@10.5.0' + - spec: '%c=gcc@15' when: '%c' - - spec: '%cxx=gcc@10.5.0' + - spec: '%cxx=gcc@15' when: '%cxx' - - spec: '%fortran=gcc@10.5.0' + - spec: '%fortran=gcc@15' when: '%fortran' - - spec: '%openmpi %gcc@10.5.0' + - spec: '%openmpi %gcc@15' when: '%mpi' - gcc-11: + # clang base images install gfortran from a paired GCC version. + # Ubuntu 24.04 clang-19/20/22 images currently pair with GCC 13. + clang-19: - spec: cxxflags='-pthread' - spec: cflags='-pthread' - - spec: '%c=gcc@11.4.0' + - spec: '%[virtuals=c]llvm@19+clang~flang~lld~lldb' when: '%c' - - spec: '%cxx=gcc@11.4.0' + - spec: '%[virtuals=cxx]llvm@19+clang~flang~lld~lldb' when: '%cxx' - - spec: '%fortran=gcc@11.4.0' + - spec: '%[virtuals=fortran]gcc@13' when: '%fortran' - - spec: '%openmpi %gcc@11.4.0' + - spec: '%openmpi' when: '%mpi' - gcc-12: + clang-20: - spec: cxxflags='-pthread' - spec: cflags='-pthread' - - spec: '%c=gcc@12.3.0' + - spec: '%[virtuals=c]llvm@20+clang~flang~lld~lldb' when: '%c' - - spec: '%cxx=gcc@12.3.0' + - spec: '%[virtuals=cxx]llvm@20+clang~flang~lld~lldb' when: '%cxx' - - spec: '%fortran=gcc@12.3.0' + - spec: '%[virtuals=fortran]gcc@13' when: '%fortran' - - spec: '%openmpi %gcc@12.3.0' + - spec: '%openmpi' + when: '%mpi' + clang-22: + - spec: cxxflags='-pthread' + - spec: cflags='-pthread' + - spec: '%[virtuals=c]llvm@22+clang~flang~lld~lldb' + when: '%c' + - spec: '%[virtuals=cxx]llvm@22+clang~flang~lld~lldb' + when: '%cxx' + - spec: '%[virtuals=fortran]gcc@13' + when: '%fortran' + - spec: '%openmpi' when: '%mpi' - packages: all: target: [x86_64] + # Ubuntu 24.04 ships OpenMPI 4.1.6 in apt; we treat it as external for all + # toolchains to prevent Spack from building OpenMPI (which may otherwise + # drift to v5). mpi: require: - - openmpi@4.1.2 + - openmpi@4.1.6 zlib-api: require: @@ -100,52 +128,96 @@ spack: require: - "netlib-lapack" + # ---- Compilers (point at the actual binaries in /usr/bin) ---- llvm: externals: - - spec: llvm@10.0.0+clang~flang~lld~lldb openmp=project + - spec: llvm@19+clang~flang~lld~lldb + prefix: /usr + extra_attributes: + compilers: + c: /usr/bin/clang-19 + cxx: /usr/bin/clang++-19 + - spec: llvm@20+clang~flang~lld~lldb prefix: /usr extra_attributes: compilers: - c: /usr/bin/clang - cxx: /usr/bin/clang++ - - spec: llvm@15.0.7+clang~flang~lld~lldb + c: /usr/bin/clang-20 + cxx: /usr/bin/clang++-20 + - spec: llvm@22+clang~flang~lld~lldb prefix: /usr extra_attributes: compilers: - c: /usr/bin/clang-15 - cxx: /usr/bin/clang++-15 + c: /usr/bin/clang-22 + cxx: /usr/bin/clang++-22 gcc: externals: - - spec: gcc@9.4.0 languages:='c,c++,fortran' + - spec: gcc@12 languages:='c,c++,fortran' prefix: /usr extra_attributes: compilers: - c: /usr/bin/gcc-9 - cxx: /usr/bin/g++-9 - fortran: /usr/bin/gfortran-9 - - spec: gcc@10.5.0 languages:='c,c++,fortran' + c: /usr/bin/gcc-12 + cxx: /usr/bin/g++-12 + fortran: /usr/bin/gfortran-12 + - spec: gcc@13 languages:='c,c++,fortran' prefix: /usr extra_attributes: compilers: - c: /usr/bin/gcc-10 - cxx: /usr/bin/g++-10 - fortran: /usr/bin/gfortran-10 - - spec: gcc@11.4.0 languages:='c,c++,fortran' + c: /usr/bin/gcc-13 + cxx: /usr/bin/g++-13 + fortran: /usr/bin/gfortran-13 + - spec: gcc@14 languages:='c,c++,fortran' prefix: /usr extra_attributes: compilers: - c: /usr/bin/gcc-11 - cxx: /usr/bin/g++-11 - fortran: /usr/bin/gfortran-11 - - spec: gcc@12.3.0 languages:='c,c++,fortran' + c: /usr/bin/gcc-14 + cxx: /usr/bin/g++-14 + fortran: /usr/bin/gfortran-14 + - spec: gcc@15 languages:='c,c++,fortran' prefix: /usr extra_attributes: compilers: - c: /usr/bin/gcc-12 - cxx: /usr/bin/g++-12 - fortran: /usr/bin/gfortran-12 + c: /usr/bin/gcc-15 + cxx: /usr/bin/g++-15 + fortran: /usr/bin/gfortran-15 + + # ---- OpenMPI: same prefix for every compiler binding (Ubuntu 24.04 ships one) + openmpi: + buildable: false + externals: + - spec: openmpi@4.1.6 %clang@19 + prefix: /usr + - spec: openmpi@4.1.6 %clang@20 + prefix: /usr + - spec: openmpi@4.1.6 %clang@22 + prefix: /usr + - spec: openmpi@4.1.6 %gcc@12 + prefix: /usr + - spec: openmpi@4.1.6 %gcc@13 + prefix: /usr + - spec: openmpi@4.1.6 %gcc@14 + prefix: /usr + - spec: openmpi@4.1.6 %gcc@15 + prefix: /usr + + doxygen: + buildable: false + externals: + - spec: doxygen@1.8.20 + prefix: /usr + # ---- CUDA: declared so that the +cuda matrix rows can resolve `^cuda@`. + # Both versions point at /usr/local/cuda because each container only ever + # has one cuda installed; Spack will pick the external matching the SPEC. + cuda: + buildable: False + externals: + - spec: cuda@12.9.1 +allow-unsupported-compilers + prefix: /usr/local/cuda + - spec: cuda@13.2.1 +allow-unsupported-compilers + prefix: /usr/local/cuda + + # ---- System tools provided by the base image ---- autoconf: version: [2.71] buildable: false @@ -159,21 +231,16 @@ spack: - spec: automake@1.16.5 prefix: /usr cmake: - version: [3.28.3] + version: [3.31.9] buildable: false externals: - - spec: cmake@3.28.3 + - spec: cmake@3.31.9 prefix: /usr/local - cuda: - buildable: False - externals: - - spec: cuda@11.8.0 +allow-unsupported-compilers - prefix: /usr/local/cuda findutils: - version: [4.7.0] + version: [4.9.0] buildable: false externals: - - spec: findutils@4.7.0 + - spec: findutils@4.9.0 prefix: /usr m4: buildable: false @@ -183,42 +250,22 @@ spack: mpfr: buildable: false externals: - - spec: mpfr@6.0.2 + - spec: mpfr@4.2.0 prefix: /usr - netlib-lapack: buildable: false externals: - - spec: netlib-lapack@3.10.0 + - spec: netlib-lapack@3.12.0 prefix: /usr netlib-blas: buildable: false externals: - - spec: netlib-blas@3.10.0 - prefix: /usr - openmpi: - buildable: false - externals: - # Ubuntu 22.04 (apt) provides OpenMPI 4.1.2. We treat it as external for all toolchains - # to prevent Spack from building OpenMPI (which may otherwise drift to v5). - - spec: openmpi@4.1.2 %clang@15.0.7 - prefix: /usr - modules: [mpi] - - spec: openmpi@4.1.2 %clang@10.0.0 - prefix: /usr - modules: [mpi] - - spec: openmpi@4.1.2 %gcc@9.4.0 - prefix: /usr - - spec: openmpi@4.1.2 %gcc@10.5.0 - prefix: /usr - - spec: openmpi@4.1.2 %gcc@11.4.0 - prefix: /usr - - spec: openmpi@4.1.2 %gcc@12.3.0 + - spec: netlib-blas@3.12.0 prefix: /usr perl: buildable: false externals: - - spec: perl@5.34.0 + - spec: perl@5.38.2 prefix: /usr pkg-config: buildable: false @@ -228,22 +275,22 @@ spack: py-sphinx: buildable: false externals: - - spec: py-sphinx@4.3.2 + - spec: py-sphinx@7.4.7 prefix: /usr python: buildable: false externals: - - spec: python@3.10.12 + - spec: python@3.12.3 prefix: /usr readline: buildable: false externals: - - spec: readline@8.0 + - spec: readline@8.2 prefix: /usr tar: buildable: false externals: - - spec: tar@1.34 + - spec: tar@1.35 prefix: /usr unzip: buildable: false @@ -253,10 +300,10 @@ spack: xz: buildable: false externals: - - spec: xz@5.2.5 + - spec: xz@5.6.1 prefix: /usr zlib: buildable: false externals: - - spec: zlib@1.2.11 + - spec: zlib@1.3 prefix: /usr diff --git a/docker/tpl-rockylinux.Dockerfile b/docker/tpl-rockylinux.Dockerfile new file mode 100644 index 00000000..49d2a695 --- /dev/null +++ b/docker/tpl-rockylinux.Dockerfile @@ -0,0 +1,172 @@ +# TPL build Dockerfile for Rocky Linux-based images. +# +# This Dockerfile expects DOCKER_BASE_IMAGE to point at one of the +# geosx/rockylinux:* images produced by +# https://github.com/GEOS-DEV/docker_base_images. Those images already provide: +# * the toolchain (gcc-toolset-N or clang) under /opt/compiler/bin/, with +# CC/CXX/FC set +# * cmake (under /usr/local) +# * the upstream NVIDIA CUDA toolkit when DOCKER_BASE_IMAGE is a CUDA variant +# +# Temporary local variables dedicated to the TPL build +ARG TMP_DIR=/tmp +ARG SRC_DIR=$TMP_DIR/thirdPartyLibs +ARG BLD_DIR=$TMP_DIR/build + +ARG DOCKER_BASE_IMAGE=rockylinux:8 +FROM ${DOCKER_BASE_IMAGE} AS tpl_toolchain_intersect_geosx_toolchain +ARG SRC_DIR + +ARG INSTALL_DIR +ENV GEOSX_TPL_DIR=$INSTALL_DIR + +ARG GCC_VERSION + +# Packages needed both for the TPL build and for the downstream GEOS build. +# Some Rocky 8 vs 9 differences are handled by the base image already +# (curl vs curl-minimal, etc.); here we only add things the base images +# don't preinstall. +RUN dnf clean all && \ + dnf -y install dnf-plugins-core || true && \ + (dnf config-manager --set-enabled powertools 2>/dev/null || \ + dnf config-manager --set-enabled crb 2>/dev/null || \ + dnf config-manager --set-enabled devel 2>/dev/null || true) && \ + dnf -y install \ + which \ + zlib-devel \ + tbb \ + doxygen \ + openmpi \ + openmpi-devel \ + python3-pip \ + unzip \ + mpfr-devel \ + bzip2 \ + gnupg2 \ + xz && \ + (dnf -y install python3-virtualenv || \ + python3 -m pip install --no-cache-dir virtualenv) && \ + dnf clean all && rm -rf /var/cache/dnf /var/lib/dnf + +# Install clingo for Spack +RUN python3 -m pip install --upgrade pip && \ + python3 -m pip install clingo + +# Make `mpicc`/`mpicxx` resolve without a `module load` step. +ENV PATH="/usr/lib64/openmpi/bin:${PATH}" \ + MPICC=/usr/lib64/openmpi/bin/mpicc \ + MPICXX=/usr/lib64/openmpi/bin/mpicxx \ + MPIEXEC=/usr/lib64/openmpi/bin/mpirun +ENV OMPI_CC=${CC} \ + OMPI_CXX=${CXX} + +# Some downstream builds expect /usr/lib64/openmpi/include to point at the +# headers; on Rocky those live under /usr/include/openmpi-x86_64. +RUN if [ -d /usr/include/openmpi-x86_64 ] && [ ! -e /usr/lib64/openmpi/include ]; then \ + mkdir -p /usr/lib64/openmpi && \ + ln -s /usr/include/openmpi-x86_64 /usr/lib64/openmpi/include ; \ + fi && \ + if [ -e /usr/lib64/libblas.so.3 ] && [ ! -e /usr/lib64/libblas.so ]; then ln -s /usr/lib64/libblas.so.3 /usr/lib64/libblas.so ; fi && \ + if [ -e /usr/lib64/liblapack.so.3 ] && [ ! -e /usr/lib64/liblapack.so ]; then ln -s /usr/lib64/liblapack.so.3 /usr/lib64/liblapack.so ; fi + +# Rocky OpenMPI defaults wrappers to gcc/g++. For clang-based base images we +# retarget the wrappers to clang/clang++ so mpi wrapper compilers are aligned +# with the image toolchain contract. +RUN if echo "${CC:-}" | grep -q "clang"; then \ + for f in /usr/share/openmpi/mpicc-wrapper-data.txt /usr/share/openmpi/mpicc.openmpi-wrapper-data.txt; do \ + if [ -f "${f}" ]; then sed -i "s|^compiler=.*$|compiler=${CC}|" "${f}" ; fi ; \ + done && \ + for f in /usr/share/openmpi/mpic++-wrapper-data.txt /usr/share/openmpi/mpic++.openmpi-wrapper-data.txt /usr/share/openmpi/mpicxx-wrapper-data.txt /usr/share/openmpi/mpicxx.openmpi-wrapper-data.txt /usr/share/openmpi/mpiCC-wrapper-data.txt /usr/share/openmpi/mpiCC.openmpi-wrapper-data.txt; do \ + if [ -f "${f}" ]; then sed -i "s|^compiler=.*$|compiler=${CXX}|" "${f}" ; fi ; \ + done && \ + mpicc --showme:command && \ + mpic++ --showme:command ; \ + fi + +# ----- TPL build stage ----- +FROM tpl_toolchain_intersect_geosx_toolchain AS tpl_toolchain +ARG SRC_DIR +ARG BLD_DIR +ARG SPEC + +RUN dnf -y install \ + tbb-devel \ + bc \ + file \ + patch \ + ca-certificates \ + autoconf \ + automake \ + make \ + m4 \ + git && \ + dnf clean all && rm -rf /var/cache/dnf /var/lib/dnf + +# Run uberenv. The SPEC is supplied by the matrix because the spack toolchain +# tag depends on the compiler+version baked into the base image. +# +# GCC toolset rows wrap the build in `scl enable gcc-toolset-${GCC_VERSION}` so +# direct compiler invocations resolve to that toolset. Clang rows do not enable +# the GCC toolset; their generated Spack config leaves GCC available only as +# the explicit Fortran compiler. +RUN --mount=src=.,dst=$SRC_DIR,readwrite cd ${SRC_DIR} && \ + mkdir -p ${GEOSX_TPL_DIR} && \ + GEOSX_SPEC="${SPEC}" && \ + if [ -z "${GEOSX_SPEC}" ] || [ "${GEOSX_SPEC}" = "undefined" ]; then \ + echo "ERROR: SPEC build-arg must be supplied" >&2 ; \ + exit 1 ; \ + fi && \ + GEOSX_SPACK_ENV_FILE=${SRC_DIR}/docker/rocky-spack.yaml && \ + if echo "${CC:-}" | grep -q "clang"; then \ + GEOSX_SPACK_ENV_FILE=/tmp/geosx-rocky-spack.yaml && \ + cp ${SRC_DIR}/docker/rocky-spack.yaml ${GEOSX_SPACK_ENV_FILE} && \ + sed -i -E "s/gcc@([0-9]+) languages:='c,c\\+\\+,fortran'/gcc@\\1 languages:='fortran'/g" ${GEOSX_SPACK_ENV_FILE} && \ + sed -i -E '/c: \/opt\/rh\/gcc-toolset-[0-9]+\/root\/usr\/bin\/gcc$/d; /cxx: \/opt\/rh\/gcc-toolset-[0-9]+\/root\/usr\/bin\/g\+\+$/d' ${GEOSX_SPACK_ENV_FILE} ; \ + fi && \ + if [ -n "${GCC_VERSION}" ] && [ -d "/opt/rh/gcc-toolset-${GCC_VERSION}" ] && ! echo "${CC:-}" | grep -q "clang"; then \ + scl enable "gcc-toolset-${GCC_VERSION}" " \ + ./scripts/uberenv/uberenv.py \ + --spec '${GEOSX_SPEC}' \ + --spack-env-file=${GEOSX_SPACK_ENV_FILE} \ + --project-json=${SRC_DIR}/.uberenv_config.json \ + --prefix ${GEOSX_TPL_DIR} \ + -k " ; \ + else \ + ./scripts/uberenv/uberenv.py \ + --spec "${GEOSX_SPEC}" \ + --spack-env-file=${GEOSX_SPACK_ENV_FILE} \ + --project-json=${SRC_DIR}/.uberenv_config.json \ + --prefix ${GEOSX_TPL_DIR} \ + -k ; \ + fi && \ + rm -f lvarray* && \ + cp *.cmake /spack-generated.cmake && \ + cd ${GEOSX_TPL_DIR} && \ + rm -rf bin/ build_stage/ builtin_spack_packages_repo/ misc_cache/ spack/ spack_env/ .spack-db/ + +# ----- Final GEOS-build image ----- +FROM tpl_toolchain_intersect_geosx_toolchain AS geosx_toolchain +ARG SRC_DIR +COPY --from=tpl_toolchain $GEOSX_TPL_DIR $GEOSX_TPL_DIR +COPY --from=tpl_toolchain /spack-generated.cmake / + +RUN dnf -y install \ + openssh-clients \ + ca-certificates \ + curl \ + python3 \ + texlive \ + graphviz \ + ninja-build \ + git && \ + dnf clean all && rm -rf /var/cache/dnf /var/lib/dnf && \ + if [ -d /usr/include/openmpi-x86_64 ] && [ ! -e /usr/lib64/openmpi/include ]; then \ + mkdir -p /usr/lib64/openmpi && \ + ln -s /usr/include/openmpi-x86_64 /usr/lib64/openmpi/include ; \ + fi && \ + if [ -e /usr/lib64/libblas.so.3 ] && [ ! -e /usr/lib64/libblas.so ]; then ln -s /usr/lib64/libblas.so.3 /usr/lib64/libblas.so ; fi && \ + if [ -e /usr/lib64/liblapack.so.3 ] && [ ! -e /usr/lib64/liblapack.so ]; then ln -s /usr/lib64/liblapack.so.3 /usr/lib64/liblapack.so ; fi + +# Install sccache to speed up downstream GEOS builds +RUN --mount=src=.,dst=$SRC_DIR $SRC_DIR/docker/install-sccache.sh +ENV SCCACHE=/opt/sccache/bin/sccache diff --git a/docker/tpl-ubuntu.Dockerfile b/docker/tpl-ubuntu.Dockerfile new file mode 100644 index 00000000..b97ba843 --- /dev/null +++ b/docker/tpl-ubuntu.Dockerfile @@ -0,0 +1,155 @@ +# TPL build Dockerfile for Ubuntu-based images. +# +# This Dockerfile expects DOCKER_BASE_IMAGE to point at one of the geosx/ubuntu:* +# images produced by https://github.com/GEOS-DEV/docker_base_images. Those images +# already provide: +# * the toolchain (gcc or clang) under /opt/compiler/bin/, with CC/CXX/FC set +# * cmake (under /usr/local) +# * the upstream NVIDIA CUDA toolkit when DOCKER_BASE_IMAGE is a CUDA variant +# +# This file is intentionally agnostic of compiler vendor and CUDA-or-not: those +# choices are baked into DOCKER_BASE_IMAGE. The matrix in +# .github/workflows/docker_build_tpls.yml selects the right base image for each +# build. + +# Temporary local variables dedicated to the TPL build +ARG TMP_DIR=/tmp +ARG SRC_DIR=$TMP_DIR/thirdPartyLibs +ARG BLD_DIR=$TMP_DIR/build + +ARG DOCKER_BASE_IMAGE=ubuntu:24.04 +FROM ${DOCKER_BASE_IMAGE} AS tpl_toolchain_intersect_geosx_toolchain +ARG SRC_DIR + +# Install directory provided as a docker build argument; forwarded via ENV +# (GEOSX_TPL_DIR is part of the image contract consumed by GEOS). +ARG INSTALL_DIR +ENV GEOSX_TPL_DIR=$INSTALL_DIR + +# Packages needed both for the TPL build and for the downstream GEOS build. +# We avoid reinstalling anything already present in the base image (compiler, +# cmake, doxygen, blas/lapack-dev when included by base PACKAGES, etc.). +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + libtbb12 \ + libgfortran5 \ + zlib1g-dev \ + doxygen \ + openmpi-bin \ + libopenmpi-dev \ + python3 \ + python3-pip \ + python3-sphinx \ + python3-dev \ + python3-venv \ + python3-virtualenv \ + pkg-config \ + xz-utils \ + unzip \ + libmpfr-dev \ + lbzip2 \ + bzip2 \ + gnupg && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install clingo for Spack. Do not upgrade Ubuntu's Debian-managed pip in +# place; Ubuntu 24.04's pip package cannot be uninstalled by pip. +RUN python3 -m pip install --break-system-packages clingo + +# MPI environment. CC/CXX/FC come from the base image. +ENV MPICC=/usr/bin/mpicc \ + MPICXX=/usr/bin/mpicxx \ + MPIEXEC=/usr/bin/mpirun +ENV OMPI_CC=${CC} \ + OMPI_CXX=${CXX} + +# Ubuntu OpenMPI defaults wrappers to gcc/g++. For clang-based base images we +# retarget the wrappers to clang/clang++ so mpi wrapper compilers are aligned +# with the image toolchain contract. +RUN if echo "${CC}" | grep -q "clang"; then \ + for f in /usr/share/openmpi/mpicc-wrapper-data.txt /usr/share/openmpi/mpicc.openmpi-wrapper-data.txt; do \ + if [ -f "${f}" ]; then sed -i "s|^compiler=.*$|compiler=${CC}|" "${f}" ; fi ; \ + done && \ + for f in /usr/share/openmpi/mpic++-wrapper-data.txt /usr/share/openmpi/mpic++.openmpi-wrapper-data.txt /usr/share/openmpi/mpicxx-wrapper-data.txt /usr/share/openmpi/mpicxx.openmpi-wrapper-data.txt /usr/share/openmpi/mpiCC-wrapper-data.txt /usr/share/openmpi/mpiCC.openmpi-wrapper-data.txt; do \ + if [ -f "${f}" ]; then sed -i "s|^compiler=.*$|compiler=${CXX}|" "${f}" ; fi ; \ + done && \ + mpicc --showme:command && \ + mpic++ --showme:command ; \ + fi + +# ----- TPL build stage ----- +FROM tpl_toolchain_intersect_geosx_toolchain AS tpl_toolchain +ARG SRC_DIR +ARG BLD_DIR +ARG SPEC + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles \ + apt-get install -y --no-install-recommends \ + libtbb-dev \ + make \ + bc \ + file \ + patch \ + git \ + autoconf \ + automake \ + m4 && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Run uberenv. The SPEC is supplied by the matrix because the spack toolchain +# tag depends on the compiler+version baked into the base image. +RUN --mount=src=.,dst=$SRC_DIR,readwrite cd ${SRC_DIR} && \ + mkdir -p ${GEOSX_TPL_DIR} && \ + GEOSX_SPEC="${SPEC}" && \ + if [ -z "${GEOSX_SPEC}" ] || [ "${GEOSX_SPEC}" = "undefined" ]; then \ + echo "ERROR: SPEC build-arg must be supplied" >&2 ; \ + exit 1 ; \ + fi && \ + GEOSX_SPACK_ENV_FILE=${SRC_DIR}/docker/spack.yaml && \ + if echo "${CC:-}" | grep -q "clang"; then \ + GEOSX_SPACK_ENV_FILE=/tmp/geosx-spack.yaml && \ + cp ${SRC_DIR}/docker/spack.yaml ${GEOSX_SPACK_ENV_FILE} && \ + sed -i -E "s/gcc@([0-9]+) languages:='c,c\\+\\+,fortran'/gcc@\\1 languages:='fortran'/g" ${GEOSX_SPACK_ENV_FILE} && \ + sed -i -E '/c: \/usr\/bin\/gcc-[0-9]+/d; /cxx: \/usr\/bin\/g\+\+-[0-9]+/d' ${GEOSX_SPACK_ENV_FILE} ; \ + fi && \ + ./scripts/uberenv/uberenv.py \ + --spec "${GEOSX_SPEC}" \ + --spack-env-file=${GEOSX_SPACK_ENV_FILE} \ + --project-json=${SRC_DIR}/.uberenv_config.json \ + --prefix ${GEOSX_TPL_DIR} \ + -k && \ + rm -f lvarray* && \ + cp *.cmake /spack-generated.cmake && \ + cd ${GEOSX_TPL_DIR} && \ + rm -rf bin/ build_stage/ builtin_spack_packages_repo/ misc_cache/ spack/ spack_env/ .spack-db/ + +# ----- Final GEOS-build image ----- +FROM tpl_toolchain_intersect_geosx_toolchain AS geosx_toolchain +ARG SRC_DIR +COPY --from=tpl_toolchain $GEOSX_TPL_DIR $GEOSX_TPL_DIR +COPY --from=tpl_toolchain /spack-generated.cmake / + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles \ + apt-get install -y --no-install-recommends \ + openssh-client \ + git \ + texlive \ + texlive-latex-extra \ + graphviz \ + libxml2-utils \ + ghostscript \ + ninja-build \ + python3-mpi4py \ + python3-scipy \ + python3-matplotlib \ + python3-pytest && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install sccache to speed up downstream GEOS builds +RUN --mount=src=.,dst=$SRC_DIR $SRC_DIR/docker/install-sccache.sh +ENV SCCACHE=/opt/sccache/bin/sccache diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh index 8cd56c39..9ab6a3f5 100644 --- a/scripts/docker-build.sh +++ b/scripts/docker-build.sh @@ -8,27 +8,40 @@ echo .git > .dockerignore git submodule update --init scripts/uberenv -# This script will build an image from TPL_DOCKERFILE -# with (optional) DOCKER_COMPILER_BUILD_ARG build arguments. -# This image will be tagged with the DOCKER_REPOSITORY:DOCKER_TAG tag +# This script will build an image from TPL_DOCKERFILE. +# The new TPL Dockerfiles (docker/tpl-ubuntu.Dockerfile, +# docker/tpl-rockylinux.Dockerfile) layer on top of one of the geosx/: +# base images produced by https://github.com/GEOS-DEV/docker_base_images. The +# matrix in .github/workflows/docker_build_tpls.yml selects which base image +# (DOCKER_BASE_IMAGE) and which spack toolchain (SPEC) to use. +# +# This image will be tagged with the DOCKER_REPOSITORY:DOCKER_TAG tag. # A specific host-config file can be defined through variable HOST_CONFIG. -# For the case of Total cluster only, DOCKER_ROOT_IMAGE is used to define docker base image. -# Where the TPL are installed in the docker can be specified by parameter INSTALL_DIR. -# These variables shall be defined by the "yaml derived classes" in a stage prior to `script` stage. +# Where the TPL are installed in the docker can be specified by parameter +# INSTALL_DIR. echo "Docker tag is ${DOCKER_REPOSITORY}:${DOCKER_TAG}" INSTALL_DIR=${INSTALL_DIR_ROOT}/GEOS_TPL-${DOCKER_TAG}-${COMMIT:0:7} echo "Installation directory is ${INSTALL_DIR}" +echo "Docker base image is ${DOCKER_BASE_IMAGE}" -docker build --progress=plain ${DOCKER_COMPILER_BUILD_ARG} \ ---build-arg HOST_CONFIG=${HOST_CONFIG} \ ---build-arg DOCKER_ROOT_IMAGE=${DOCKER_ROOT_IMAGE} \ ---build-arg INSTALL_DIR=${INSTALL_DIR} \ ---build-arg SPEC="${SPEC}" \ ---tag ${DOCKER_REPOSITORY}:${DOCKER_TAG} \ ---file ${TPL_DOCKERFILE} \ ---label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \ ---label "org.opencontainers.image.source=https://github.com/GEOS-DEV/thirdPartyLibs" \ ---label "org.opencontainers.image.revision=${COMMIT}" \ ---label "org.opencontainers.image.title=Building environment for GEOS" \ -. +# Optional build-args are only forwarded when set, so the Dockerfiles can rely +# on `[ -z "${ARG}" ]` checks. +EXTRA_BUILD_ARGS=() +if [ -n "${GCC_VERSION}" ]; then EXTRA_BUILD_ARGS+=(--build-arg "GCC_VERSION=${GCC_VERSION}"); fi +if [ -n "${CLANG_VERSION}" ]; then EXTRA_BUILD_ARGS+=(--build-arg "CLANG_VERSION=${CLANG_VERSION}"); fi + +docker build --progress=plain \ + --build-arg HOST_CONFIG=${HOST_CONFIG} \ + --build-arg DOCKER_BASE_IMAGE=${DOCKER_BASE_IMAGE} \ + --build-arg INSTALL_DIR=${INSTALL_DIR} \ + --build-arg SPEC="${SPEC}" \ + "${EXTRA_BUILD_ARGS[@]}" \ + --tag ${DOCKER_REPOSITORY}:${DOCKER_TAG} \ + --file ${TPL_DOCKERFILE} \ + --label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \ + --label "org.opencontainers.image.source=https://github.com/GEOS-DEV/thirdPartyLibs" \ + --label "org.opencontainers.image.revision=${COMMIT}" \ + --label "org.opencontainers.image.base.name=${DOCKER_BASE_IMAGE}" \ + --label "org.opencontainers.image.title=Building environment for GEOS" \ + .