diff --git a/cp2k/.gitignore b/cp2k/.gitignore
new file mode 100644
index 0000000..1870bb5
--- /dev/null
+++ b/cp2k/.gitignore
@@ -0,0 +1,11 @@
+# Build trees (Spack)
+cp2k-baremetal/
+
+# Cloned CP2K source (fetched by run scripts)
+/cp2k_repo/
+
+# Benchmark run outputs
+outputs/
+
+# Container images
+*.sif
diff --git a/cp2k/README.md b/cp2k/README.md
index e1d6975..38ff8ef 100644
--- a/cp2k/README.md
+++ b/cp2k/README.md
@@ -1,6 +1,7 @@
-# CP2K
+# CP2K on AMD GPUs — Spack-based recipe
## Overview
+
CP2K is a quantum chemistry and solid state physics software package that can perform atomistic simulations of solid state, liquid, molecular, periodic, material, crystal, and biological systems. CP2K provides a general framework for different modeling methods such as [DFT](http://en.wikipedia.org/wiki/Density_functional_theory) using the mixed [Gaussian and plane waves approaches GPW and GAPW](https://www.cp2k.org/quickstep#gpw). Supported theory levels include DFTB, LDA, GGA, MP2, RPA, semi-empirical methods (AM1, PM3, PM6, RM1, MNDO, …), and classical force fields (AMBER, CHARMM, …). CP2K can do simulations of molecular dynamics, metadynamics, Monte Carlo, Ehrenfest dynamics, vibrational analysis, core level spectroscopy, energy minimization, and transition state optimization using NEB or dimer method. Detailed overview of features may be found at the [CP2K site](https://www.cp2k.org/features).
CP2K is written in Fortran 2008 and can be run efficiently in parallel using a combination of multi-threading, MPI, and HIP/CUDA. The CP2K software package is [freely available](https://www.cp2k.org/download) under the GPL license at https://www.cp2k.org.
@@ -9,264 +10,256 @@ For more information about CP2K, see www.cp2k.org.
The latest CP2K review, as of **May 2020**, can be found at **[The Journal of Chemical Physics 10.1063/5.0007045](https://doi.org/10.1063/5.0007045).**
-## Single-Node Server Requirements
-[System Requirements](/README.md#single-node-server-requirements)
+This repository contains a build & run recipe for CP2K with **AMD ROCm**
+acceleration, in three flavors that share the same Spack-based build script:
+- [`baremetal/`](baremetal/) — direct host install via Spack
+- [`docker/`](docker/) — same recipe, packaged as a Docker image
+- [`singularity/`](singularity/) — same recipe as a Singularity image (for hosts with Singularity/Apptainer but no Docker)
-## Build Recipes
-- [Bare Metal build](/cp2k/baremetal/)
-- [Docker/Singularity Build](/cp2k/docker/)
+All flavors source their build logic from [`shared/cp2k_build.sh`](shared/cp2k_build.sh).
-## Running CP2K Benchmarks
+## Layout
-> **Note**: Convenient benchmark scripts are available in `docker/scripts/` and `baremetal/scripts/` directories. These scripts handle CP2K repository cloning, environment setup, CPU/GPU affinity, and output management. See the [Docker README](docker/README.md#running-benchmarks) and [Baremetal README](baremetal/README.md#running-benchmarks) for details.
+```
+.
+├── shared/
+│ ├── cp2k_build.sh # single source of truth for the Spack build
+│ ├── close.sh # GPU binder (ROCR_VISIBLE_DEVICES)
+│ └── patches/
+│ └── 0001-Add-AMD-MI350-gfx950-support-to-CP2K.patch
+├── baremetal/
+│ ├── build_cp2k.sh # thin wrapper around shared/cp2k_build.sh
+│ └── scripts/ # mpirun + SLURM launchers, NUMA-aware
+├── docker/
+│ ├── Dockerfile # ROCm base + shared/cp2k_build.sh
+│ ├── build_cp2k.sh # `docker build` wrapper
+│ └── scripts/ # `docker run` launchers
+└── singularity/
+ ├── cp2k.def # ROCm base + shared/cp2k_build.sh
+ ├── build_cp2k.sh # `singularity build` wrapper
+ └── scripts/ # `singularity exec` launchers
+```
-
-MI210/MI100 GPUs
+## System requirements
-### MI210/MI100 GPUs
+| CPUs | GPUs | Operating Systems | ROCm |
+|---|---|---|---|
+| x86_64 | AMD Instinct MI100 / MI200 / MI300 / MI350 | Ubuntu 22.04 / 24.04, RHEL 8 / 9, SLES 15 SP4 | ROCm 7.x |
-The following command can be used to run the [H2O-DFT-LS (NREP2)](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp) benchmark with 8 GPUs:
+For ROCm installation, see the [ROCm Documentation](https://rocm.docs.amd.com).
-```
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=8 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=8 \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np 16 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i /opt/cp2k/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp \
- -o /tmp/H2O-DFT-LS-NREP2-8GPU.txt
-```
+Recommended resources for a build: 50+ GB free disk, 32+ GB RAM, and
+internet access during the build (Spack and source tarballs). Build time is
+typically 1–3 hours. Flavor-specific prerequisites (host tooling, Docker,
+Singularity/Apptainer) are listed in each flavor's README.
-> **Note**: The `DBCSR_USE_ACC_G2G=1` environment variable enables GPU-to-GPU communication for improved performance for the DFT benchmark. This is included in the provided benchmark scripts.
+## What the build does
-In the above example, the H2O-DFT-LS (NREP2) benchmark is run on a dual socket server with 8 MI210 GPUs and 128 physical cores. The job in this example is run with 16 MPI ranks and 8 OpenMP threads per rank with two processes sharing a GPU. The `NUM_CPUS`, `NUM_GPUS` and `RANK_STRIDE` variables are used by the helper scripts that set GPU and CPU affinity for CP2K processes and their threads. The `RANK_STRIDE` option allows the processes and their threads to be spread out and pinned to physical cores across the two sockets. If your system has a different configuration, please adjust these parameters accordingly.
+`shared/cp2k_build.sh` produces a self-contained Spack tree that includes:
-A grep for `"CP2K "` in the output file `/tmp/H2O-DFT-LS-NREP2-8GPU.txt` will show the elapsed time for the run.
+- A pinned Spack (`v1.1.1`) and `spack-packages` repo (`v2026.03.0`)
+- A small in-tree patch that registers `gfx950`/Mi350 in the CP2K Spack
+ package (always applied; harmless on other targets)
+- `gcc@14.3.0` built by Spack and used to compile everything else
+- The full MPI stack (`ucx@1.20.0`, `ucc@1.7.0`, `openmpi@5.0.10`) built by
+ Spack with ROCm + OFED enabled
+- ROCm itself consumed as Spack externals from `${ROCM_PATH}` (no source
+ build of ROCm)
+- CP2K `2026.1` with all the usual GPU-accelerated dependencies:
+ `cosma`, `costa`, `dbcsr`, `fftw`, `hdf5`, `libvdwxc`, `netlib-scalapack`,
+ `sirius`, `spfft`, `spla`, `umpire`, plus `boost`, `dftd4`, `libint`,
+ `libxc`, `libxsmm@1.17`, `openblas`, `pugixml`, `simple-dftd3`, `spglib`,
+ `tiled-mm`, `toml-f`, etc.
-The following command can be used to run the [H2O-DFT-LS (NREP2)](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp) benchmark with 4 GPUs:
-```
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=4 \
- -x RANK_STRIDE=4 \
- -x OMP_NUM_THREADS=4 \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np 16 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i /opt/cp2k/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp \
- -o /tmp/H2O-DFT-LS-NREP2-4GPU.txt
-```
-In the above example, the H2O-DFT-LS (NREP2) benchmark is run a dual socket server that has 8 MI210 GPUs and 128 physical cores, but uses only 64 physical cores of one socket and 4 MI210 GPUs. The job in this example is run with 16 MPI ranks and 4 OpenMP threads per rank with two processes sharing a GPU. The `NUM_CPUS`, `NUM_GPUS` and `RANK_STRIDE` variables are used by the helper scripts that set GPU and CPU affinity for CP2K processes and their threads. Setting `RANK_STRIDE` to 4 allows the processes and their threads to be spread out and pinned to physical cores on the socket. If your system has a different configuration, please adjust the parameters accordingly.
+Defaults target an MI350X / Zen5 / ROCm 7.2 host.
-A grep for `"CP2K "` in the output file `/tmp/H2O-DFT-LS-NREP2-4GPU.txt` will show the elapsed time for the run.
+Configure a git identity first (`git config --global user.name`/`user.email`); it
+is used by `git am` when applying the gfx950 patch.
-The following commands can be used to run the [32-H2O-RPA](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/) benchmark. There are two steps involved in this benchmark namely the `init` and `solver` stages. The init stage will use the [H2O-32-PBE-TZ.inp](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-PBE-TZ.inp) input file and the solver stage will use the [H2O-32-RI-dRPA-TZ.inp](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-RI-dRPA-TZ.inp) input file.
+### Build configuration
->Note:
->For this benchmark it is necessary to run from the `/opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O` directory due to file dependencies between the two stages.
+All flavors read the same build knobs (environment variables consumed by
+`shared/cp2k_build.sh`). The most useful, shared across flavors:
-First run the init stage:
-```
-cd /opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O/
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=1 \
- -x RANK_STRIDE=4 \
- -x OMP_NUM_THREADS=4 \
- --oversubscribe \
- -np 4 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i H2O-32-PBE-TZ.inp \
- -o /tmp/32-H2O-RPA-init-1GPU.txt
+| Variable | Default | Notes |
+|---|---|---|
+| `GPU_ARCH` | `gfx950` | `gfx908` (MI100), `gfx90a` (MI200), `gfx942` (MI300), `gfx950` (MI350) |
+| `CPU_ARCH` | `zen5` | Any Spack microarch (e.g. `zen3`, `zen4`) |
+| `ROCM_VERSION` | `7.2.0` | Version reported to Spack for the ROCm externals |
+| `ROCM_PATH` | `/opt/rocm-${ROCM_VERSION}` | Filesystem path to ROCm |
+| `GCC_VERSION` | `14.3.0` | GCC built by Spack and used as the CP2K compiler |
+| `SPACK_BRANCH` | `v1.1.1` | Spack version |
+| `SPACK_PACKAGES_TAG` | `v2026.03.0` | `spack/spack-packages` tag |
+| `BUILD_JOBS` | `32` | `spack install -j` |
+
+```bash
+GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 ./baremetal/build_cp2k.sh
```
-Next, run the solver stage:
-```
-cd /opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O/
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=8 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=8 \
- --oversubscribe \
- -np 16 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i H2O-32-RI-dRPA-TZ.inp \
- -o /tmp/32-H2O-RPA-solver-8GPU.txt
-```
+Each flavor adds its own knobs (e.g. `BUILD_ROOT` for baremetal, `IMAGE_*`
+for docker, `SIF_IMAGE` for singularity) — see the flavor READMEs.
-In the above example, the two stages of the 32-H2O-RPA benchmark are run on a dual socket server with 8 MI210 GPUs and 128 physical cores. The init step is run with 4 MPI ranks and 4 OpenMP threads per rank on 1 GPU with all 4 ranks sharing the GPU. The solver step is run with 16 MPI ranks and 8 OpenMP threads per rank on 8 GPUs with two processes sharing a GPU. The `NUM_CPUS`, `NUM_GPUS` and `RANK_STRIDE` variables are used by the helper scripts that set GPU and CPU affinity for CP2K processes and their threads. The `RANK_STRIDE` option allows the processes and their threads to be spread out and pinned to physical cores across the two sockets. If your system has a different configuration, please adjust the parameters accordingly.
+> **Disclaimer**: This recipe has only been validated with the default
+> values. Different GPU targets, ROCm versions, or build options may cause
+> build failures or suboptimal performance.
-A grep for `"CP2K "` in the output files `/tmp/32-H2O-RPA-*.txt` will show the elapsed time for each run.
+## Build recipes
->Note:
->The above-mentioned commands can also be run verbatim on a dual socket server with 8 MI100/MI300X/MI325X GPUs and 128 physical CPU cores. If your system configuration is different, please adjust the parameters accordingly.
+- [Bare metal](baremetal/README.md)
+- [Docker](docker/README.md)
+- [Singularity / Apptainer](singularity/README.md)
-
-
-MI250 GPUs
-### MI250 GPUs
+## Running CP2K benchmarks
-An MI250 GPU contains two Graphics Compute Dies (GCDs) each of which is presented to the application
-as a separate GPU device. When running with MI250 GPUs, the scripts that set up CPU and GPU affinities,
-namely `set_cpu_affinity.sh` and `set_gpu_affinity.sh`, require
-`NUM_GPUS` to be set up with the number of GCDs we want to run with.
-In this section, we show how to run CP2K benchmarks on 1 and 4 MI250 GPUs which would translate
-to setting `NUM_GPUS` with 2 and 8 respectively.
+Each flavor ships the same two launcher scripts under its own `scripts/`
+directory for two reference benchmarks pulled from the upstream CP2K source
+tree:
-All the examples provided in this section show benchmarks run on a dual socket server with 4 MI250 GPUs and 128 physical cores.
+| Benchmark | Script name (identical across flavors) |
+|---|---|
+| [`QS_DM_LS / H2O-dft-ls.NREP2`](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp) | `cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run` |
+| [`QS_mp2_rpa / 32-H2O`](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/) ([init](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-PBE-TZ.inp) + [solver](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-RI-dRPA-TZ.inp)) | `cp2k_QS_mp2_rpa_32-H2O.run` |
-The following command can be used to run the [H2O-DFT-LS (NREP2)](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp) benchmark on 16 physical CPU cores and 1 MI250 GPU with 4 MPI ranks and 4 OpenMP threads per rank with two processes sharing each GCD:
-```
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=2 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=4 \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np 4 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i /opt/cp2k/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp \
- -o /tmp/H2O-DFT-LS-NREP2-1GPU.txt
-```
+The baremetal, docker, and singularity scripts share the same filenames,
+SBATCH headers, lowercase topology variables, and EXPNAME /
+output-directory layout. They double as SLURM batch jobs (`sbatch …`) and
+as plain interactive scripts (`./…`). All launchers use OpenMPI's
+NUMA-aware `--map-by ppr:N:numa:PE=T` mapping together with
+[`shared/close.sh`](shared/close.sh), which assigns one GPU per rank via
+`ROCR_VISIBLE_DEVICES`.
-The following command can be used to run the H2O-DFT-LS (NREP2) benchmark on 64 physical cores and 4 MI250 GPUs with 16 MPI ranks and 4 OpenMP threads per rank with two processes sharing each GCD:
-```
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=8 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=4 \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np 16 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i /opt/cp2k/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp \
- -o /tmp/H2O-DFT-LS-NREP2-4GPU.txt
-```
+### Topology variables
-The `NUM_CPUS`, `NUM_GPUS` and `RANK_STRIDE` variables are used by the helper scripts that set GPU and CPU affinity for CP2K processes and their threads. The `RANK_STRIDE` option allows the processes and their threads to be spread out and pinned to physical cores across the two sockets. If your system has a different configuration, please adjust these parameters accordingly.
+The defaults target a single node with 256 logical CPUs, 128 physical CPU
+cores, 8 NUMA domains, and 8 GPUs. Override via environment variables
+(lowercase, matching SLURM convention) before invoking the script:
-A grep for `"CP2K "` in the output file `/tmp/H2O-DFT-LS-NREP2-*.txt` will show the elapsed time for each run.
+| Variable | Default | Notes |
+|---|---|---|
+| `lcpus_per_node` | 256 | Logical CPUs on the node |
+| `physcpus_per_node` | 128 | Physical CPU cores |
+| `numa_per_node` | 8 | Must match `numactl -H`; a wrong value breaks the `--map-by ppr:N:numa` binding |
+| `gpus_per_node` (or `GPUS_PER_NODE`) | 8 | GPUs per node |
+| `nthreads_init` (RPA only) | `physcpus_per_node / numa_per_node` | Init-stage OpenMP threads |
+| `arch` | `mi350x` | Used in the output directory name |
+
+Per-rank counts come from `SLURM_NTASKS` / `SLURM_NTASKS_PER_NODE` /
+`SLURM_CPUS_PER_TASK` when available, otherwise from the SBATCH defaults.
+Set `numa_per_node` to the value reported by `numactl -H` if the node does
+not have the default 8 domains (for example `numa_per_node=2` on a 2-domain
+node):
+
+```bash
+SLURM_NTASKS=16 gpus_per_node=8 numa_per_node= \
+ ./baremetal/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+```
-The following commands can be used to run the [32-H2O-RPA](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/) benchmark on MI250 GPUs. There are two steps involved in this benchmark namely the `init` and `solver` stages. The init stage will use the [H2O-32-PBE-TZ.inp](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-PBE-TZ.inp) input file and the solver stage will use the [H2O-32-RI-dRPA-TZ.inp](https://github.com/cp2k/cp2k/blob/master/benchmarks/QS_mp2_rpa/32-H2O/H2O-32-RI-dRPA-TZ.inp) input file.
+### MPI / UCX defaults
->Note:
->For this benchmark it is necessary to run from the `/opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O` directory due to file dependencies between the two stages.*
+The launchers (and the container images) set the same OpenMPI/UCX runtime
+defaults:
-First, the init step is run with 4 MPI ranks and 4 OpenMP threads per rank on 1 MI250 GPU (2 GCDs) with 2 ranks sharing each GCD:
```
-cd /opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O/
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=2 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=4 \
- --oversubscribe \
- -np 4 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i H2O-32-PBE-TZ.inp \
- -o /tmp/32-H2O-RPA-init-1GPU.txt
+OMPI_MCA_pml=ucx
+OMPI_MCA_osc=ucx
+OMPI_MCA_coll_ucc_enable=1
+OMPI_MCA_coll_ucc_priority=100
+UCX_TLS=self,sm,rocm_copy,rocm_ipc,ud_x
+UCX_MAX_RNDV_RAILS=1
+HSA_ENABLE_SDMA=0
+HSA_ENABLE_IPC_MODE_LEGACY=1
+HIP_MEM_POOL_SUPPORT=1
```
-Next, the solver step may be run on 1 MI250 GPU with 8 MPI ranks and 2 OpenMP threads per rank with 4 processes sharing each GCD:
-```
-cd /opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O/
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=2 \
- -x RANK_STRIDE=4 \
- -x OMP_NUM_THREADS=2 \
- --oversubscribe \
- -np 8 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i H2O-32-RI-dRPA-TZ.inp \
- -o /tmp/32-H2O-RPA-solver-1GPU.txt
-```
+Override any of them via the environment (baremetal/singularity) or `-e VAR=...`
+on `docker run` (docker).
-Or the solver step may be run on 4 MI250 GPUs using 16 MPI ranks and 4 OpenMP threads per rank with 2 processes sharing each GCD:
-```
-cd /opt/cp2k/benchmarks/QS_mp2_rpa/32-H2O/
-mpirun \
- -x NUM_CPUS=128 \
- -x NUM_GPUS=8 \
- -x RANK_STRIDE=8 \
- -x OMP_NUM_THREADS=4 \
- --oversubscribe \
- -np 16 \
- --bind-to none \
- set_cpu_affinity.sh \
- set_gpu_affinity.sh \
- cp2k.psmp \
- -i H2O-32-RI-dRPA-TZ.inp \
- -o /tmp/32-H2O-RPA-solver-4GPU.txt
+### Figure of merit
+
+The figure of merit (FOM) is the total elapsed run time in seconds. Each
+launcher prints it as `FOM: seconds`, taken from the last field of the
+`CP2K` timing line in the output file. To read it manually:
+
+```bash
+grep 'CP2K ' .out | tail -n 1
```
-In the above-mentioned commands, the `NUM_CPUS`, `NUM_GPUS` and `RANK_STRIDE` variables are used by the helper scripts that set GPU and CPU affinity for CP2K processes and their threads. The `RANK_STRIDE` option allows the processes and their threads to be spread out and pinned to physical cores across the two sockets. If your system has a different configuration, please adjust the parameters accordingly.
+### GPU-to-GPU communication
-A grep for `"CP2K "` in the output files `/tmp/32-H2O-RPA-*.txt` will show the elapsed time for each run.
-
+The DFT launcher (`cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run`, in every flavor's
+`scripts/`) sets `DBCSR_USE_ACC_G2G=1`, which enables GPU-to-GPU
+communication and improves multi-GPU DFT performance. It is not set
+globally and is not used for the RPA benchmark. To disable it for a
+comparison run, pass `DBCSR_USE_ACC_G2G=0` before invoking the script.
## Licensing Information
-Your use of this application is subject to the terms of the applicable component-level license identified below. To the extent any subcomponent in this container requires an offer for corresponding source code, AMD hereby makes such an offer for corresponding source code form, which will be made available upon request. By accessing and using this application, you are agreeing to fully comply with the terms of this license. If you do not agree to the terms of this license, do not access or use this application.
+Your use of this application is subject to the terms of the applicable
+component-level license identified below. To the extent any subcomponent in
+this container requires an offer for corresponding source code, AMD hereby
+makes such an offer for corresponding source code form, which will be made
+available upon request. By accessing and using this application, you are
+agreeing to fully comply with the terms of this license. If you do not
+agree to the terms of this license, do not access or use this application.
-The application is provided in a container image format that includes the following separate and independent components:
-|Package | License | URL|
+| Package | License | URL |
|---|---|---|
-|Ubuntu| Creative Commons CC-BY-SA Version 3.0 UK License |[Ubuntu Legal](https://ubuntu.com/legal)|
-|CMAKE|OSI-approved BSD-3 clause|[CMake License](https://cmake.org/licensing/)|
-|OpenMPI|BSD 3-Clause|[OpenMPI License](https://www-lb.open-mpi.org/community/license.php)
[OpenMPI Dependencies Licenses](https://docs.open-mpi.org/en/v5.0.x/license/index.html)|
-|OpenUCX|BSD 3-Clause|[OpenUCX License](https://openucx.org/license/)|
-|ROCm|Custom/MIT/Apache V2.0/UIUC OSL|[ROCm Licensing Terms](https://rocm.docs.amd.com/en/latest/about/license.html)|
-|CP2K|GNU GPL Version 2|[CP2k](https://www.cp2k.org/)
[CP2K License](https://github.com/cp2k/cp2k/blob/master/LICENSE)|
-|OpenBlas|BSD 3-Clause|[OpenBlas](https://www.openblas.net/)
[OpenBlas License](https://github.com/xianyi/OpenBLAS/blob/develop/LICENSE)|
-|COSMA|BSD 3-Clause|[COSMA License](https://github.com/eth-cscs/COSMA/blob/master/LICENSE)|
-|Libxsmm|BSD 3-Classe|[Libxsmm License](https://libxsmm.readthedocs.io/en/latest/LICENSE/)|
-|Libxc|MPL v2.0|[Libxc License](https://github.com/ElectronicStructureLibrary/libxc)|
-|SpLA|BSD 3-Clause|[SpLA License](https://github.com/eth-cscs/spla/blob/master/LICENSE)|
-
-Additional third-party content in this container may be subject to additional licenses and restrictions. The components are licensed to you directly by the party that owns the content pursuant to the license terms included with such content and is not licensed to you by AMD. ALL LINKED THIRD-PARTY CONTENT IS MADE AVAILABLE BY AMD “AS IS” WITHOUT A WARRANTY OF ANY KIND. USE OF THE CONTAINER IS DONE AT YOUR SOLE DISCRETION AND UNDER NO CIRCUMSTANCES WILL AMD BE LIABLE TO YOU FOR ANY THIRD-PARTY CONTENT. YOU ASSUME ALL RISK AND ARE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY ARISE FROM YOUR USE OF THE CONTAINER.
-
+| Ubuntu | Creative Commons CC-BY-SA Version 3.0 UK License | [Ubuntu Legal](https://ubuntu.com/legal) |
+| CMAKE | OSI-approved BSD-3 clause | [CMake License](https://cmake.org/licensing/) |
+| OpenMPI | BSD 3-Clause | [OpenMPI License](https://www-lb.open-mpi.org/community/license.php) |
+| OpenUCX | BSD 3-Clause | [OpenUCX License](https://openucx.org/license/) |
+| ROCm | Custom/MIT/Apache V2.0/UIUC OSL | [ROCm Licensing Terms](https://rocm.docs.amd.com/en/latest/about/license.html) |
+| CP2K | GNU GPL Version 2 | [CP2k License](https://github.com/cp2k/cp2k/blob/master/LICENSE) |
+| Spack | Apache-2.0 OR MIT | [Spack License](https://github.com/spack/spack/blob/develop/LICENSE-APACHE) |
+| OpenBlas | BSD 3-Clause | [OpenBlas License](https://github.com/xianyi/OpenBLAS/blob/develop/LICENSE) |
+| COSMA | BSD 3-Clause | [COSMA License](https://github.com/eth-cscs/COSMA/blob/master/LICENSE) |
+| Libxsmm | BSD 3-Clause | [Libxsmm License](https://libxsmm.readthedocs.io/en/latest/LICENSE/) |
+| Libxc | MPL v2.0 | [Libxc License](https://github.com/ElectronicStructureLibrary/libxc) |
+| SpLA | BSD 3-Clause | [SpLA License](https://github.com/eth-cscs/spla/blob/master/LICENSE) |
+| DBCSR | GPL-2.0 | [DBCSR License](https://github.com/cp2k/dbcsr) |
+| SIRIUS | BSD 3-Clause | [SIRIUS License](https://github.com/electronic-structure/SIRIUS) |
+
+Additional third-party content in this container may be subject to
+additional licenses and restrictions. The components are licensed to you
+directly by the party that owns the content pursuant to the license terms
+included with such content and is not licensed to you by AMD. ALL LINKED
+THIRD-PARTY CONTENT IS MADE AVAILABLE BY AMD "AS IS" WITHOUT A WARRANTY OF
+ANY KIND. USE OF THE CONTAINER IS DONE AT YOUR SOLE DISCRETION AND UNDER NO
+CIRCUMSTANCES WILL AMD BE LIABLE TO YOU FOR ANY THIRD-PARTY CONTENT. YOU
+ASSUME ALL RISK AND ARE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY ARISE
+FROM YOUR USE OF THE CONTAINER.
+
## Disclaimer
-The information contained herein is for informational purposes only, and is subject to change without notice. In addition, any stated support is planned and is also subject to change. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein. No license, including implied or arising by estoppel, to any intellectual property rights is granted by this document. Terms and limitations applicable to the purchase or use of AMD’s products are as set forth in a signed agreement between the parties or in AMD's Standard Terms and Conditions of Sale.
-
+The information contained herein is for informational purposes only, and is
+subject to change without notice. In addition, any stated support is planned
+and is also subject to change. While every precaution has been taken in the
+preparation of this document, it may contain technical inaccuracies,
+omissions and typographical errors, and AMD is under no obligation to
+update or otherwise correct this information. Advanced Micro Devices, Inc.
+makes no representations or warranties with respect to the accuracy or
+completeness of the contents of this document, and assumes no liability of
+any kind, including the implied warranties of noninfringement,
+merchantability or fitness for particular purposes, with respect to the
+operation or use of AMD hardware, software or other products described
+herein. No license, including implied or arising by estoppel, to any
+intellectual property rights is granted by this document. Terms and
+limitations applicable to the purchase or use of AMD's products are as set
+forth in a signed agreement between the parties or in AMD's Standard Terms
+and Conditions of Sale.
+
## Notices and Attribution
-© 2022-2024 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD Arrow logo, Instinct, Radeon Instinct, ROCm, and combinations thereof are trademarks of Advanced Micro Devices, Inc.
-Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries. Docker, Inc. and other parties may also have trademark rights in other terms used herein. Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
+© 2022-2026 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD
+Arrow logo, Instinct, Radeon Instinct, ROCm, and combinations thereof are
+trademarks of Advanced Micro Devices, Inc.
-All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes.
+Docker and the Docker logo are trademarks or registered trademarks of
+Docker, Inc. in the United States and/or other countries. Docker, Inc. and
+other parties may also have trademark rights in other terms used herein.
+Linux® is the registered trademark of Linus Torvalds in the U.S. and other
+countries.
+All other trademarks and copyrights are property of their respective owners
+and are only mentioned for informative purposes.
diff --git a/cp2k/baremetal/README.md b/cp2k/baremetal/README.md
index fde8709..63b445f 100644
--- a/cp2k/baremetal/README.md
+++ b/cp2k/baremetal/README.md
@@ -1,460 +1,186 @@
-# CP2K Bare Metal Build Instructions
+# CP2K — Bare Metal Build
-This document provides instructions on how to build CP2K on bare metal using Spack for dependency management. This approach provides a reproducible installation of CP2K with all its scientific computing dependencies built with ROCm support.
+This document describes how to build CP2K with ROCm support directly on a
+host using Spack. The build is driven by
+[`../shared/cp2k_build.sh`](../shared/cp2k_build.sh); this directory just
+provides a thin wrapper and a set of NUMA-aware run scripts.
-## Build System Requirements
+## System requirements
-### Single-Node Server Requirements
+Supported CPUs/GPUs/OS and recommended resources are in the
+[main README](../README.md#system-requirements).
-| CPUs | GPUs | Operating Systems | ROCm™ Driver |
-| ---- | ---- | ----------------- | ------------ |
-| X86_64 CPU(s) | AMD Instinct MI200 GPU(s)
AMD Instinct MI100 GPU(s)
AMD Instinct MI300 GPU(s) | Ubuntu 20.04
Ubuntu 22.04
Ubuntu 24.04
RHEL8
RHEL9
SLES 15 sp4 | ROCm v7.x compatibility |
+### Tools the host must have
-For ROCm installation procedures and validation checks, see:
-* [ROCm Documentation](https://rocm.docs.amd.com)
-* [AMD Lab Notes ROCm installation notes](https://github.com/amd/amd-lab-notes/tree/release/rocm-installation).
-* [ROCm Examples](https://github.com/amd/rocm-examples)
+The build script bootstraps almost everything via Spack, including a fresh
+GCC toolchain. The host only needs the things Spack itself depends on:
-### Required Software
+| Tool | Why |
+|---|---|
+| `git` | Cloning Spack and `spack-packages` |
+| `make`, `patch`, `tar`, `gzip`, `bzip2`, `xz` | Spack's bootstrap |
+| `python3` | Spack |
+| A working C/C++ compiler (`gcc` or `clang`) | To bootstrap GCC 14.3.0 |
+| ROCm | Installed at `${ROCM_PATH}` (default `/opt/rocm-${ROCM_VERSION}`) |
-| Application | Minimum | Recommended |
-|---|---|---|
-| Git | Latest | Latest |
-| GCC | 11.3.0 | Latest |
-| GFortran | 11.3.0 | Latest |
-| CMake | 3.22 | Latest |
-| Make | Latest | Latest |
-| ROCm | 7.0.0 | Latest |
-| OpenMPI | 5.0.3 | 5.0.8+ |
-| Python | 3.6+ | 3.8+ |
-
-### Recommended Resources
-
-- **Disk Space**: 50+ GB for build artifacts and Spack installations
-- **Memory**: 32+ GB RAM
-- **Build Time**: 2-4 hours (depending on system and parallel jobs)
-
-## Overview
-
-This bare metal build uses **Spack** to build CP2K and its scientific computing dependencies. This is the **recommended build method from the CP2K developer community**, providing a robust and maintainable approach. System-installed packages (GCC, OpenMPI, ROCm) are detected as external packages and are not built by Spack.
-
-The build process:
-1. Installs and configures Spack package manager
-2. Uses a Spack environment (`../docker/cp2k_environment/spack.yaml`) to build CP2K and its Spack-managed dependencies
-3. Detects system-installed packages (GCC, ROCm, OpenMPI, etc.) as external packages
-4. Builds CP2K dependencies via Spack (SIRIUS, COSMA, DBCSR, libxc, libint, etc.)
-5. Compiles CP2K with ROCm GPU acceleration
-6. Creates setup scripts for easy environment activation
-
-> **Note**: GCC, OpenMPI, UCX, and UCC must be system-installed and are not built by this script. They are detected as external packages by Spack.
+UCX, UCC, OpenMPI, GCC, BLAS, FFT, etc. are **all built by Spack**.
-## Quick Start
-
-### 1. Navigate to Baremetal Directory
+Configure a git identity before building (used by `git am` for the gfx950 patch):
```bash
-cd /path/to/cp2k/baremetal
+git config --global user.name "Your Name"
+git config --global user.email "you@example.com"
```
-### 2. Run the Build Script
+## Quick start
```bash
-./build_cp2k.sh
-```
-
-This will:
-- Check prerequisites (ROCm, GCC, compilers, OpenMPI, etc.)
-- Install/configure Spack if needed
-- Create a Spack environment using the shared `cp2k_environment` configuration
-- Detect system-installed packages (GCC, OpenMPI, ROCm, etc.) as external packages
-- Build CP2K dependencies (SIRIUS, COSMA, DBCSR, etc.) and CP2K via Spack
-- Create setup scripts for environment activation
-- Save build logs to `build.log`
+cd /path/to/cp2k-recipe/baremetal
-### 3. Activate CP2K Environment
-
-After successful build:
+# Build everything (defaults: MI350X / Zen5 / ROCm 7.2)
+./build_cp2k.sh
-```bash
-source cp2k-baremetal/setup_cp2k.sh
+# Use it
+source cp2k-baremetal/spack_git/share/spack/setup-env.sh
+spack env activate cp2k
+spack load cp2k
cp2k.psmp --version
```
-## Build Script Options
-
-The `build_cp2k.sh` script supports the following options:
-
-| Option | Description | Default |
-|--------|-------------|---------|
-| `--install-prefix PATH` | Installation directory | `$PWD/cp2k-baremetal` |
-| `--spack-root PATH` | Spack installation directory | `~/spack` |
-| `--rocm-path PATH` | ROCm installation path | `$ROCM_PATH` or `/opt/rocm` |
-| `--gpu-target TARGET` | AMD GPU architecture | `gfx942` (MI300) |
-| `--jobs N` | Parallel build jobs | `16` |
-| `--help` | Show help message | - |
-
-### Custom Configuration Examples
-
-**Custom Installation Path:**
-```bash
-./build_cp2k.sh --install-prefix /opt/cp2k-mi300
-```
-
-**Specify Spack Location:**
-```bash
-./build_cp2k.sh --spack-root /path/to/spack
-```
-
-**Different GPU Target:**
-```bash
-# For MI300 series (gfx942)
-./build_cp2k.sh --gpu-target gfx942
-
-# For MI200 series (gfx90a)
-./build_cp2k.sh --gpu-target gfx90a
-
-# For MI100 series (gfx908)
-./build_cp2k.sh --gpu-target gfx908
-```
-
-**Control Build Parallelism:**
-```bash
-./build_cp2k.sh --jobs 32
-```
-
-**Complete Example:**
-```bash
-./build_cp2k.sh \
- --install-prefix /opt/cp2k-mi300 \
- --spack-root $HOME/spack \
- --rocm-path /opt/rocm-6.3.0 \
- --gpu-target gfx90a \
- --jobs 32
-```
-
-> **DISCLAIMER**: This bare metal build has only been validated using the default values. Using different GPU targets, ROCm versions, or build options may result in build failures or poor performance.
-
-## Spack Environment Configuration
-
-The CP2K build uses the shared Spack environment located in `../docker/cp2k_environment/`:
-
-- **`spack.yaml`**: Defines all package specifications, variants, and build options
-- **`repos/`**: Custom Spack package repositories (contains CP2K, DBCSR, libvdwxc packages)
-- **`config.yaml`**: Spack configuration settings
-
-### Key CP2K Variants
-
-The CP2K package is built with the following variants (see `spack.yaml`):
-- `+rocm`: ROCm GPU acceleration
-- `+cosma`: COSMA library for matrix operations
-- `+sirius`: SIRIUS library for electronic structure
-- `+spglib`: Space group library
-- `+hdf5`: HDF5 I/O support
-- `+mpi`: MPI parallelization
-- `+openmp`: OpenMP threading
-- `smm=libxsmm`: Small matrix multiplication via libxsmm
-
-### GPU Architecture Configuration
-
-The GPU architecture target is configured via the `--gpu-target` option and is set in the Spack environment via the `amdgpu_target` variant. Common targets:
-- `gfx908`: MI100 series
-- `gfx90a`: MI200 series
-- `gfx942`: MI300 series
+The build creates a single self-contained directory `./cp2k-baremetal/`
+with `spack_git/`, `spack-packages_git/`, `install/`, `environments/`,
+`spack_stage/`, plus a convenience symlink `cp2k -> `.
-### Modifying the Build
+## Configuration
-To change CP2K variants or dependencies:
+The shared build knobs (`GPU_ARCH`, `CPU_ARCH`, `ROCM_VERSION`, `ROCM_PATH`,
+`GCC_VERSION`, `SPACK_BRANCH`, `SPACK_PACKAGES_TAG`, `BUILD_JOBS`) and the
+validation disclaimer are documented in the
+[main README](../README.md#build-configuration). Baremetal-specific knobs:
-1. Edit `../docker/cp2k_environment/spack.yaml`
-2. Modify the `cp2k@2026.1` spec line with desired variants
-3. Rebuild: `./build_cp2k.sh`
-
-Example: To disable a feature, change `+feature` to `~feature` in the spec.
-
-## Build Process Details
-
-The build script follows these steps:
-
-1. **Prerequisite Checks**: Verifies ROCm installation, GCC, compilers, OpenMPI, and required tools
-2. **Spack Setup**: Clones Spack if needed and sources the environment
-3. **System Detection**: Finds system compilers (GCC) and external packages (ROCm, OpenMPI, UCX, UCC, etc.)
-4. **Environment Creation**: Creates a Spack environment using the shared `cp2k_environment`
-5. **Dependency Resolution**: Concretizes the dependency graph (using external GCC, OpenMPI, UCX, UCC)
-6. **Build**: Installs CP2K dependencies (SIRIUS, COSMA, DBCSR, etc.) and CP2K with parallel jobs
-7. **Setup Scripts**: Creates environment setup scripts and module files
-
-### Build Time
-
-Expected build times:
-- Spack setup and dependency resolution: ~5-10 minutes
-- Dependency builds (SIRIUS, COSMA, DBCSR, libxc, libint, etc.): ~30-60 minutes
-- CP2K compilation: ~10-20 minutes
-- **Total**: ~45-90 minutes (depending on system and parallel jobs)
-
-> **Note**: GCC, OpenMPI, UCX, and UCC are expected to be system-installed and are detected as external packages by Spack. They are not built by this script.
-
-## Running CP2K
-
-### Environment Setup
-
-Choose one of these methods:
-
-#### Method 1: Setup Script (Recommended)
-```bash
-source cp2k-baremetal/setup_cp2k.sh
-```
+| Variable | Default | Notes |
+|---|---|---|
+| `BUILD_ROOT` | `${PWD}/cp2k-baremetal` | Where the Spack tree is created |
+| `SPACK_FETCH_JOBS` | `4` | `spack install -p` |
-#### Method 2: Spack Environment
-```bash
-source ~/spack/share/spack/setup-env.sh
-spack env activate cp2k-baremetal
-```
+Examples:
-#### Method 3: Direct PATH
```bash
-export PATH=cp2k-baremetal/cp2k/bin:$PATH
-```
-
-### CP2K Executables
-
-The build provides CP2K executables via the Spack environment:
-
-- **`cp2k.psmp`**: Parallel SMP (Shared Memory Parallel) version
- - Built with MPI and OpenMP support
- - Includes ROCm GPU acceleration
- - Located at `cp2k-baremetal/cp2k/bin/cp2k.psmp` (also in PATH)
-
-The executable is accessible via:
-- Direct path: `cp2k-baremetal/cp2k/bin/cp2k.psmp`
-- PATH: `cp2k.psmp` (after sourcing setup script)
-- Spack environment: `spack load cp2k`
+# MI300X on Zen3 with ROCm 7.0
+GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 \
+ ./build_cp2k.sh
-### Running Benchmarks
+# Custom install location
+BUILD_ROOT=/opt/cp2k-baremetal ./build_cp2k.sh
-Example benchmark scripts are provided in `scripts/`:
-
-- **`run_dft_nrep2.sh`**: DFT benchmark with 16 MPI ranks
-- **`run_rpa32.sh`**: RPA benchmark with two stages (init + solver)
-- **`set_cpu_affinity.sh`** and **`set_gpu_affinity.sh`**: Affinity scripts that can be tuned for the system the benchmarks are run on
-
-> **DISCLAIMER**: The affinity scripts (`set_cpu_affinity.sh` and `set_gpu_affinity.sh`) must be tuned according to your specific system configuration to achieve maximum performance. The default settings may not be optimal for all hardware configurations.
-
-To run benchmarks:
-
-```bash
-cd /path/to/cp2k/baremetal
-source cp2k-baremetal/setup_cp2k.sh
-./scripts/run_dft_nrep2.sh
+# Smaller machine
+BUILD_JOBS=8 ./build_cp2k.sh
```
-These scripts handle:
-- CP2K repository cloning
-- CPU/GPU affinity setup
-- Output file management
-
-### SLURM Job Examples
-
-#### Single Node, 8 GPUs, 4 MPI Ranks
-```bash
-#!/bin/bash
-#SBATCH --job-name=cp2k_test
-#SBATCH --nodes=1
-#SBATCH --ntasks=4
-#SBATCH --cpus-per-task=16
-#SBATCH --gpus-per-node=8
-#SBATCH --time=01:00:00
-
-source cp2k-baremetal/setup_cp2k.sh
-
-srun --gpus-per-node=8 --ntasks=4 --cpus-per-task=16 \
- cp2k.psmp -i input.inp -o output.out
-```
+## Activating the environment afterwards
-#### Single Node, 8 GPUs, 8 MPI Ranks
```bash
-srun -N 1 --gpus-per-node=8 --ntasks=8 --cpus-per-task=8 \
- cp2k.psmp -i input.inp -o output.out
+source cp2k-baremetal/spack_git/share/spack/setup-env.sh
+spack env activate cp2k
+spack load cp2k
+which cp2k.psmp # cp2k-baremetal/install/.../cp2k.../bin/cp2k.psmp
```
-#### Multi-Node, 16 GPUs, 16 MPI Ranks
-```bash
-srun -N 2 --gpus-per-node=8 --ntasks-per-node=8 --cpus-per-task=8 \
- cp2k.psmp -i input.inp -o output.out
-```
+## Running benchmarks
-## Runtime Options
+The launchers in [`scripts/`](scripts/) use OpenMPI's NUMA-aware
+`--map-by ppr:N:numa:PE=T` mapping together with
+[`../shared/close.sh`](../shared/close.sh), which binds one GPU per rank
+via `ROCR_VISIBLE_DEVICES`.
-### GPU-to-GPU Communication (g2g)
+| Script | Benchmark |
+|---|---|
+| `scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run` | `QS_DM_LS / H2O-dft-ls.NREP2` |
+| `scripts/cp2k_QS_mp2_rpa_32-H2O.run` | `QS_mp2_rpa / 32-H2O` (init + solver) |
-To enable GPU-to-GPU communication in DBCSR, set the environment variable:
+Both scripts double as SLURM batch scripts (just `sbatch` them) and as
+plain interactive scripts (just `./` them) — the SBATCH directives are
+shell comments when run outside SLURM, and every `SLURM_*` variable has a
+sensible default. They will clone the CP2K source into `../cp2k_repo/` on
+first run to get the benchmark inputs.
-```bash
-export DBCSR_USE_ACC_G2G=1
-```
+Topology variables (`numa_per_node`, `gpus_per_node`, etc.), the MPI/UCX
+defaults, the figure of merit, and the `DBCSR_USE_ACC_G2G` option are shared
+across flavors and documented in the
+[main README](../README.md#running-cp2k-benchmarks). Set `numa_per_node` to
+your node's actual NUMA domain count (`numactl -H`).
-This can improve performance for multi-GPU runs. Example:
+Examples:
```bash
-export DBCSR_USE_ACC_G2G=1
-mpirun -np 16 -x DBCSR_USE_ACC_G2G=1 cp2k.psmp -i input.inp
-```
+# DFT, interactive
+./scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
-> **Note**: For g2g to work properly, the MPI implementation must be built with ROCm support. This includes UCX and OpenMPI being compiled with ROCm/GPU support enabled. Verify your MPI installation supports GPU communication before using this option.
+# DFT, smaller box (4 GPUs, 8 ranks)
+SLURM_NTASKS=8 numa_per_node=4 gpus_per_node=4 \
+ ./scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
-### MPI/UCX Configuration
+# RPA, interactive
+./scripts/cp2k_QS_mp2_rpa_32-H2O.run
-The setup script automatically configures OpenMPI to use UCX (if available):
-```bash
-export OMPI_MCA_pml=ucx
-export OMPI_MCA_pml_ucx_tls=any
-export OMPI_MCA_osc=ucx
-export OMPI_MCA_btl=^vader,tcp,uct
-export UCX_TLS=self,sm,tcp,rocm
+# Either as a SLURM job (set numa_per_node to the node's NUMA count)
+sbatch --export=ALL,numa_per_node= ./scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+sbatch --export=ALL,numa_per_node= ./scripts/cp2k_QS_mp2_rpa_32-H2O.run
```
-> **Note**: GCC, OpenMPI, and UCX should be system-installed. The build script detects them as external packages and does not build them.
+Output goes under
+`outputs///_N.n.t.g_/...`
+and each script prints the [figure of merit](../README.md#figure-of-merit)
+from the resulting `*.out`.
## Troubleshooting
-### Build Failures
-
-If the build fails during Spack installation:
-
-1. Check `build.log` for detailed error messages
-2. Verify network connectivity (Spack downloads packages)
-3. Ensure sufficient disk space (~50GB+ required)
-4. Verify ROCm installation: `rocminfo`
-5. Check compiler availability: `gcc --version`, `gfortran --version`
-6. Verify OpenMPI is installed: `mpirun --version` or `which mpirun`
-
-### Missing Executables
-
-If CP2K executable is not found:
-
-```bash
-# Verify installation
-ls -l cp2k-baremetal/cp2k/bin/
+### Build fails to find ROCm
-# Check environment
-source cp2k-baremetal/setup_cp2k.sh
-which cp2k.psmp
```
-
-### GPU Issues
-
-If GPU is not detected:
-
-- Verify ROCm installation: `rocm-smi`
-- Check GPU visibility: `echo $ROCR_VISIBLE_DEVICES`
-- Verify GPU architecture matches `--gpu-target` used during build
-- Check SLURM GPU allocation: `srun --gpus-per-node=8 rocm-smi`
-
-### Concretization Issues
-
-If Spack fails to resolve dependencies:
-
-```bash
-# View concretization log
-cat cp2k-baremetal/concretize.log
-
-# Try with more verbose output
-source ~/spack/share/spack/setup-env.sh
-spack env activate cp2k-baremetal
-spack concretize -f --fresh
+ERROR: ROCM_PATH=/opt/rocm-7.2.0 does not exist.
```
-### MPI Errors
-
-If MPI-related errors occur:
+Set `ROCM_PATH` (or `ROCM_VERSION`) to point to your ROCm install, e.g.:
```bash
-# Verify OpenMPI is installed and accessible
-mpirun --version
-which mpirun
-
-# Test MPI
-mpirun -np 4 hostname
-
-# Check UCX (if installed)
-ucx_info -v
+ROCM_PATH=/opt/rocm ROCM_VERSION=7.0.0 ./build_cp2k.sh
```
-> **Note**: GCC and OpenMPI must be system-installed before running the build script. UCX and UCC are optional but recommended for optimal performance.
+### Patch fails to apply
-## Updating the Build
+The gfx950 patch is applied to the upstream `spack-packages` checkout the
+first time the build runs. If you delete `BUILD_ROOT/spack-packages_git/`
+and re-run, it will be recloned and re-patched. If the upstream
+`spack-packages` tag has moved on and the patch context no longer matches,
+remove the patch from `shared/patches/` (gfx950 may already be supported
+upstream) and re-run.
-### Rebuild with New Options
+### `cp2k.psmp` not found after build
-```bash
-# Remove existing environment
-source ~/spack/share/spack/setup-env.sh
-spack env rm -y cp2k-baremetal
+Make sure you sourced the right `setup-env.sh`:
-# Run build script again
-./build_cp2k.sh [new options]
+```bash
+source cp2k-baremetal/spack_git/share/spack/setup-env.sh
+spack env activate cp2k
+spack load cp2k
```
-### Update Spack Environment
-
-To modify the package specifications:
+### Rebuilding from scratch
```bash
-# Edit the shared environment
-vim ../docker/cp2k_environment/spack.yaml
-
-# Rebuild
+rm -rf cp2k-baremetal
./build_cp2k.sh
```
-## Files Created by Build
+## Files created by the build
```
cp2k-baremetal/
-├── cp2k/ # Symlink to CP2K installation
-├── dist/ # Spack install tree
-├── setup_cp2k.sh # Environment setup script
-├── modulefiles/ # Environment module files
-│ └── cp2k-baremetal
-├── build.log # Complete build log
-├── concretize.log # Dependency resolution log
-└── INSTALL_SUMMARY.txt # Installation summary
+├── spack_git/ # Pinned Spack checkout
+├── spack-packages_git/ # Pinned spack-packages checkout (patched)
+├── install/ # Spack install tree (everything)
+├── environments/cp2k/ # Generated Spack env
+├── spack_stage/ # Build stage
+└── cp2k -> .../install/.../cp2k-2026.1-...
```
-
-> **Note**: The default installation directory is `$PWD/cp2k-baremetal` (relative to where you run the build script). If you run the script from `/path/to/cp2k/baremetal`, the installation will be at `/path/to/cp2k/baremetal/cp2k-baremetal`. You can specify a custom path using `--install-prefix`.
-
-## Licensing Information
-
-Your use of this application is subject to the terms of the applicable component-level license identified below. To the extent any subcomponent in this container requires an offer for corresponding source code, AMD hereby makes such an offer for corresponding source code form, which will be made available upon request. By accessing and using this application, you are agreeing to fully comply with the terms of this license. If you do not agree to the terms of this license, do not access or use this application.
-
-The application is provided in a container image format that includes the following separate and independent components:
-
-| Package | License | URL |
-|---|---|---|
-| Ubuntu | Creative Commons CC-BY-SA Version 3.0 UK License | [Ubuntu Legal](https://ubuntu.com/legal) |
-| CMAKE | OSI-approved BSD-3 clause | [CMake License](https://cmake.org/licensing/) |
-| OpenMPI | BSD 3-Clause | [OpenMPI License](https://www-lb.open-mpi.org/community/license.php)
[OpenMPI Dependencies Licenses](https://docs.open-mpi.org/en/v5.0.x/license/index.html) |
-| OpenUCX | BSD 3-Clause | [OpenUCX License](https://openucx.org/license/) |
-| ROCm | Custom/MIT/Apache V2.0/UIUC OSL | [ROCm Licensing Terms](https://rocm.docs.amd.com/en/latest/about/license.html) |
-| CP2K | GNU GPL Version 2 | [CP2k](https://www.cp2k.org/)
[CP2K License](https://github.com/cp2k/cp2k/blob/master/LICENSE) |
-| Spack | Apache-2.0 OR MIT | [Spack License](https://github.com/spack/spack/blob/develop/LICENSE-APACHE) |
-| OpenBlas | BSD 3-Clause | [OpenBlas](https://www.openblas.net/)
[OpenBlas License](https://github.com/xianyi/OpenBLAS/blob/develop/LICENSE) |
-| COSMA | BSD 3-Clause | [COSMA License](https://github.com/eth-cscs/COSMA/blob/master/LICENSE) |
-| Libxsmm | BSD 3-Clause | [Libxsmm License](https://libxsmm.readthedocs.io/en/latest/LICENSE/) |
-| Libxc | MPL v2.0 | [Libxc License](https://github.com/ElectronicStructureLibrary/libxc) |
-| SpLA | BSD 3-Clause | [SpLA License](https://github.com/eth-cscs/spla/blob/master/LICENSE) |
-| DBCSR | GPL-2.0 | [DBCSR License](https://github.com/cp2k/dbcsr) |
-| SIRIUS | BSD 3-Clause | [SIRIUS License](https://github.com/electronic-structure/SIRIUS) |
-
-Additional third-party content in this container may be subject to additional licenses and restrictions. The components are licensed to you directly by the party that owns the content pursuant to the license terms included with such content and is not licensed to you by AMD. ALL LINKED THIRD-PARTY CONTENT IS MADE AVAILABLE BY AMD "AS IS" WITHOUT A WARRANTY OF ANY KIND. USE OF THE CONTAINER IS DONE AT YOUR SOLE DISCRETION AND UNDER NO CIRCUMSTANCES WILL AMD BE LIABLE TO YOU FOR ANY THIRD-PARTY CONTENT. YOU ASSUME ALL RISK AND ARE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY ARISE FROM YOUR USE OF THE CONTAINER.
-
-## Disclaimer
-
-The information contained herein is for informational purposes only, and is subject to change without notice. In addition, any stated support is planned and is also subject to change. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein. No license, including implied or arising by estoppel, to any intellectual property rights is granted by this document. Terms and limitations applicable to the purchase or use of AMD's products are as set forth in a signed agreement between the parties or in AMD's Standard Terms and Conditions of Sale.
-
-## Notices and Attribution
-
-© 2022-26 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD Arrow logo, Instinct, Radeon Instinct, ROCm, and combinations thereof are trademarks of Advanced Micro Devices, Inc.
-
-Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries. Docker, Inc. and other parties may also have trademark rights in other terms used herein. Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
-
-All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes.
diff --git a/cp2k/baremetal/build_cp2k.sh b/cp2k/baremetal/build_cp2k.sh
index d531004..11b878c 100755
--- a/cp2k/baremetal/build_cp2k.sh
+++ b/cp2k/baremetal/build_cp2k.sh
@@ -1,564 +1,43 @@
#!/bin/bash
-
-# ============================================================================
-# CP2K Baremetal Build Script using Spack
-# ============================================================================
-# This script builds CP2K with ROCm support on bare metal using Spack
-# It mirrors the Docker build approach but for direct system installation
#
-# Usage:
-# ./build_cp2k.sh [OPTIONS]
+# Baremetal entry point for the shared CP2K Spack build.
#
-# Options:
-# --install-prefix PATH Installation directory (default: $PWD/cp2k-baremetal)
-# --spack-root PATH Spack installation directory (default: ~/spack)
-# --rocm-path PATH ROCm installation path (default: $ROCM_PATH or /opt/rocm)
-# --gpu-target TARGET AMD GPU target (default: gfx942)
-# --jobs N Number of parallel build jobs (default: 16)
-# --help Show this help message
-# ============================================================================
-
-set -e # Exit on error
-
-# ============================================================================
-# Default Configuration
-# ============================================================================
-
-# Set WORKDIR to current working directory
-WORKDIR="${PWD}"
-INSTALL_PREFIX="$WORKDIR/cp2k-baremetal"
-SPACK_ROOT="$HOME/spack"
-ROCM_PATH="${ROCM_PATH:-/opt/rocm}"
-AMDGPU_TARGET="gfx942"
-BUILD_JOBS=16
-
-# Get the directory where this script is located
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-CP2K_ENV_DIR="$SCRIPT_DIR/../docker/cp2k_environment"
-
-# ============================================================================
-# Parse Command Line Arguments
-# ============================================================================
-
-while [[ $# -gt 0 ]]; do
- case $1 in
- --install-prefix)
- INSTALL_PREFIX="$2"
- shift 2
- ;;
- --spack-root)
- SPACK_ROOT="$2"
- shift 2
- ;;
- --rocm-path)
- ROCM_PATH="$2"
- shift 2
- ;;
- --gpu-target)
- AMDGPU_TARGET="$2"
- shift 2
- ;;
- --jobs)
- BUILD_JOBS="$2"
- shift 2
- ;;
- --help)
- grep "^#" "$0" | grep -v "^#!/" | sed 's/^# //' | sed 's/^#//'
- exit 0
- ;;
- *)
- echo "Unknown option: $1"
- echo "Use --help for usage information"
- exit 1
- ;;
- esac
-done
-
-# ============================================================================
-# Color Output Functions
-# ============================================================================
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
-NC='\033[0m' # No Color
-
-info() { echo -e "${GREEN}[INFO]${NC} $1"; }
-warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
-error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
-section() { echo -e "\n${BLUE}========== $1 ==========${NC}\n"; }
-
-# ============================================================================
-# Banner
-# ============================================================================
-
-echo ""
-echo "============================================================================"
-echo " CP2K Baremetal Build Script"
-echo "============================================================================"
-echo " Working Directory: $WORKDIR"
-echo " Install Prefix: $INSTALL_PREFIX"
-echo " Spack Root: $SPACK_ROOT"
-echo " ROCm Path: $ROCM_PATH"
-echo " GPU Target: $AMDGPU_TARGET"
-echo " Build Jobs: $BUILD_JOBS"
-echo " Environment: $CP2K_ENV_DIR"
-echo "============================================================================"
-echo ""
-
-# ============================================================================
-# Prerequisite Checks
-# ============================================================================
-
-section "Checking Prerequisites"
-
-# Check for CP2K environment directory
-if [ ! -d "$CP2K_ENV_DIR" ]; then
- error "CP2K environment directory not found at: $CP2K_ENV_DIR"
-fi
-
-if [ ! -f "$CP2K_ENV_DIR/spack.yaml" ]; then
- error "spack.yaml not found in: $CP2K_ENV_DIR"
-fi
-
-info "CP2K environment found at: $CP2K_ENV_DIR"
-
-# Check for ROCm
-if [ ! -d "$ROCM_PATH" ]; then
- error "ROCm not found at $ROCM_PATH. Please set --rocm-path or install ROCm."
-fi
-
-info "ROCm found at: $ROCM_PATH"
-
-# Check for required tools
-MISSING_TOOLS=()
-for tool in git gcc gfortran cmake make; do
- if ! command -v $tool &> /dev/null; then
- MISSING_TOOLS+=($tool)
- fi
-done
-
-if [ ${#MISSING_TOOLS[@]} -gt 0 ]; then
- error "Missing required tools: ${MISSING_TOOLS[*]}"
-fi
-
-info "All required tools found: git, gcc, gfortran, cmake, make"
-
-# ============================================================================
-# Spack Installation
-# ============================================================================
-
-section "Setting Up Spack"
-
-if [ ! -d "$SPACK_ROOT" ]; then
- info "Spack not found. Cloning Spack to $SPACK_ROOT..."
- git clone https://github.com/spack/spack.git "$SPACK_ROOT"
- info "Spack cloned successfully"
-else
- info "Spack found at: $SPACK_ROOT"
-fi
-
-# Source Spack
-if [ ! -f "$SPACK_ROOT/share/spack/setup-env.sh" ]; then
- error "Spack setup script not found at: $SPACK_ROOT/share/spack/setup-env.sh"
-fi
-
-source "$SPACK_ROOT/share/spack/setup-env.sh"
-
-info "Spack version: $(spack --version)"
-
-# ============================================================================
-# System Package Detection
-# ============================================================================
-
-section "Detecting System Packages and Compilers"
-
-info "Finding compilers..."
-spack compiler find
-
-info "Finding external packages..."
-spack external find --all
-
-echo ""
-info "Detected compilers:"
-spack compiler list
-
-# ============================================================================
-# Create Spack Environment
-# ============================================================================
-
-section "Creating Spack Environment"
-
-ENV_NAME="cp2k-baremetal"
-BAREMETAL_ENV_DIR="$HOME/.spack/environments/$ENV_NAME"
-SPACK_ENV_DIR="$SPACK_ROOT/var/spack/environments/$ENV_NAME"
-
-# Check if environment already exists and remove it
-if spack env list | grep -qw "$ENV_NAME"; then
- warn "Spack environment '$ENV_NAME' already exists"
- info "Removing existing environment to recreate with updated configuration..."
- spack env rm -y $ENV_NAME 2>/dev/null || true
- rm -rf "$BAREMETAL_ENV_DIR" 2>/dev/null || true
- rm -rf "$SPACK_ENV_DIR" 2>/dev/null || true
- info "Environment removed"
-fi
-
-# Wait a moment to ensure cleanup is complete
-sleep 1
-
-# Create environment
-info "Creating Spack environment: $ENV_NAME"
-spack env create $ENV_NAME "$CP2K_ENV_DIR/spack.yaml" || {
- error "Failed to create Spack environment. Trying to remove and recreate..."
- rm -rf "$SPACK_ENV_DIR" 2>/dev/null || true
- rm -rf "$BAREMETAL_ENV_DIR" 2>/dev/null || true
- sleep 1
- spack env create $ENV_NAME "$CP2K_ENV_DIR/spack.yaml"
-}
-
-# Create/overwrite custom config for baremetal install path BEFORE activating
-info "Configuring install tree: $INSTALL_PREFIX/cp2k-dist"
-mkdir -p "$SPACK_ENV_DIR"
-
-# Write config.yaml directly to the environment directory
-cat > "$SPACK_ENV_DIR/config.yaml" </dev/null | grep -v "^--" | head -1 | sed 's/^[[:space:]]*root:[[:space:]]*//' || echo "")
-if [ -n "$INSTALL_ROOT" ]; then
- info "Verified install tree root: $INSTALL_ROOT"
-else
- warn "Could not verify install tree root, but config.yaml was written"
-fi
-
-# ============================================================================
-# Configure ROCm and Build Environment
-# ============================================================================
-
-section "Configuring Build Environment"
-
-info "Setting up ROCm environment variables..."
-
-export ROCM_PATH=$ROCM_PATH
-export PATH=$ROCM_PATH/bin:$PATH
-export LD_LIBRARY_PATH=$ROCM_PATH/lib:$ROCM_PATH/lib64:$ROCM_PATH/llvm/lib:$LD_LIBRARY_PATH
-export LIBRARY_PATH=$ROCM_PATH/lib:$ROCM_PATH/lib64:$LIBRARY_PATH
-export C_INCLUDE_PATH=$ROCM_PATH/include:$C_INCLUDE_PATH
-export CPLUS_INCLUDE_PATH=$ROCM_PATH/include:$CPLUS_INCLUDE_PATH
-export CMAKE_PREFIX_PATH=$ROCM_PATH/lib/cmake:$CMAKE_PREFIX_PATH
-
-# Additional ROCm library paths
-export LD_LIBRARY_PATH=$ROCM_PATH/lib/hipblas:$ROCM_PATH/lib/hipfft:$ROCM_PATH/lib/rocfft:$ROCM_PATH/lib/rocblas:$LD_LIBRARY_PATH
-export LIBRARY_PATH=$ROCM_PATH/lib/rocfft:$ROCM_PATH/lib/hipblas:$ROCM_PATH/lib/rocblas:$LIBRARY_PATH
-export C_INCLUDE_PATH=$ROCM_PATH/include/rocfft:$ROCM_PATH/include/hipblas:$ROCM_PATH/include/hipfft:$ROCM_PATH/include/rocblas:$C_INCLUDE_PATH
-export CPLUS_INCLUDE_PATH=$ROCM_PATH/include/rocfft:$ROCM_PATH/include/hipfft:$ROCM_PATH/include/hipblas:$ROCM_PATH/include/rocblas:$CPLUS_INCLUDE_PATH
-
-info "ROCm environment configured"
-info "GPU Target: $AMDGPU_TARGET"
-
-# Note: UCX, UCC, and OpenMPI will be detected as external packages by Spack
-# via 'spack external find --all' command below
-
-# ============================================================================
-# Concretize Dependencies
-# ============================================================================
-
-section "Concretizing Dependencies"
-
-info "Analyzing and resolving package dependencies..."
-info "This may take several minutes..."
-
-spack concretize -f 2>&1 | tee $INSTALL_PREFIX/concretize.log || {
- error "Concretization failed. Check $INSTALL_PREFIX/concretize.log for details"
-}
-
-info "Dependency tree:"
-spack find
-
-# ============================================================================
-# Build and Install
-# ============================================================================
-
-section "Building CP2K and Dependencies"
-
-warn "This will take a significant amount of time (2-4 hours depending on system)"
-warn "Build logs will be saved to: $INSTALL_PREFIX/build.log"
-
-info "Starting build with $BUILD_JOBS parallel jobs..."
-
-# Create install prefix
-mkdir -p "$INSTALL_PREFIX"
-
-START_TIME=$(date +%s)
-
-if spack install -j${BUILD_JOBS} --verbose 2>&1 | tee -a $INSTALL_PREFIX/build.log; then
- END_TIME=$(date +%s)
-else
- error "Build failed. Check $INSTALL_PREFIX/build.log for details"
- exit 1
-fi
-BUILD_DURATION=$((END_TIME - START_TIME))
-BUILD_HOURS=$((BUILD_DURATION / 3600))
-BUILD_MINUTES=$(((BUILD_DURATION % 3600) / 60))
-
-info "Build completed in ${BUILD_HOURS}h ${BUILD_MINUTES}m"
-
-# ============================================================================
-# Create Installation Links and Setup Scripts
-# ============================================================================
-
-section "Finalizing Installation"
-
-# Find CP2K installation path
-info "Locating CP2K installation..."
-CP2K_INSTALL_PATH=$(spack find -p cp2k@2026.1 | tail -n 1 | awk '{print $2}')
-
-if [ -z "$CP2K_INSTALL_PATH" ] || [ ! -d "$CP2K_INSTALL_PATH" ]; then
- error "Failed to find CP2K installation path"
-fi
-
-info "CP2K installed at: $CP2K_INSTALL_PATH"
-
-# Create symlink for easy access
-info "Creating convenience symlink..."
-ln -sf "$CP2K_INSTALL_PATH" "$INSTALL_PREFIX/cp2k"
-info "Symlink created: $INSTALL_PREFIX/cp2k -> $CP2K_INSTALL_PATH"
-
-# Create environment setup script
-info "Creating environment setup script..."
-
-cat > "$INSTALL_PREFIX/setup_cp2k.sh" <<'EOFSETUP'
-#!/bin/bash
-# ============================================================================
-# CP2K Environment Setup Script
-# ============================================================================
-# Source this file to use CP2K: source /setup_cp2k.sh
-# ============================================================================
-
-SPACK_ROOT="${SPACK_ROOT:-$HOME/spack}"
-INSTALL_PREFIX="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-
-# Source Spack
-if [ -f "$SPACK_ROOT/share/spack/setup-env.sh" ]; then
- source "$SPACK_ROOT/share/spack/setup-env.sh"
-else
- echo "Error: Spack not found at $SPACK_ROOT"
- return 1
-fi
-
-# Activate CP2K environment
-spack env activate cp2k-baremetal
-
-# Add CP2K to PATH
-export PATH=$INSTALL_PREFIX/cp2k/bin:$PATH
-
-# Set MPI/UCX environment for optimal performance
-export OMPI_MCA_pml=ucx
-export OMPI_MCA_pml_ucx_tls=any
-export OMPI_MCA_osc=ucx
-export OMPI_MCA_btl=^vader,tcp,uct
-export OMPI_MCA_pml_ucx_devices=any
-export UCX_TLS=self,sm,tcp,rocm
-
-echo "CP2K environment activated"
-echo "CP2K path: $INSTALL_PREFIX/cp2k"
-
-# Verify CP2K is available
-if command -v cp2k.psmp &> /dev/null; then
- echo "CP2K executable: $(which cp2k.psmp)"
-else
- echo "Warning: cp2k.psmp not found in PATH"
-fi
-EOFSETUP
-
-chmod +x "$INSTALL_PREFIX/setup_cp2k.sh"
-
-# Create a convenience module file for environment modules (if system uses modules)
-info "Creating environment module file..."
-
-MODULEFILE_DIR="$INSTALL_PREFIX/modulefiles"
-mkdir -p "$MODULEFILE_DIR"
-
-cat > "$MODULEFILE_DIR/cp2k-baremetal" < /dev/null 2>&1; then
- info "✓ CP2K version check passed"
- "$CP2K_INSTALL_PATH/bin/cp2k.psmp" --version | head -n 5
- else
- warn "CP2K executable found but version check failed"
- fi
-else
- error "CP2K executable not found at: $CP2K_INSTALL_PATH/bin/cp2k.psmp"
-fi
-
-# Check for benchmark directory
-BENCHMARK_DIR="$SCRIPT_DIR/../cp2k/benchmarks"
-if [ -d "$BENCHMARK_DIR" ]; then
- info "✓ Benchmark directory found: $BENCHMARK_DIR"
-else
- warn "Benchmark directory not found at: $BENCHMARK_DIR"
-fi
-
-# ============================================================================
-# Installation Summary
-# ============================================================================
-
-section "Installation Complete!"
-
-cat < "$INSTALL_PREFIX/INSTALL_SUMMARY.txt"
-CP2K Baremetal Installation Summary
-====================================
+# This script is a thin wrapper around ../shared/cp2k_build.sh that defaults
+# the build root to ./cp2k-baremetal so the entire Spack tree, install tree,
+# and environments live under a single self-contained directory.
+#
+# All configuration is done through environment variables (see
+# shared/cp2k_build.sh for the full list). The most common ones:
+#
+# CPU_ARCH Spack target microarch [zen5]
+# GPU_ARCH AMD GPU target [gfx950]
+# ROCM_VERSION ROCm version reported to Spack [7.2.0]
+# ROCM_PATH Path to the ROCm install [/opt/rocm-${ROCM_VERSION}]
+# BUILD_ROOT Where to put spack_git, install, etc. [./cp2k-baremetal]
+# BUILD_JOBS spack install -j [32]
+#
+# Examples:
+#
+# # Default (MI350X / Zen5 / ROCm 7.2):
+# ./build_cp2k.sh
+#
+# # MI300X on Zen3:
+# GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 ./build_cp2k.sh
+#
+# # Custom install location:
+# BUILD_ROOT=/opt/cp2k-baremetal ./build_cp2k.sh
-Installation Date: $(date)
-Host: $(hostname)
-User: $(whoami)
+set -eu
+set -o pipefail
-Configuration:
- Install Prefix: $INSTALL_PREFIX
- CP2K Path: $CP2K_INSTALL_PATH
- Spack Root: $SPACK_ROOT
- ROCm Path: $ROCM_PATH
- GPU Target: $AMDGPU_TARGET
- Build Jobs: $BUILD_JOBS
- Build Time: ${BUILD_HOURS}h ${BUILD_MINUTES}m
+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+SHARED_DIR=$(cd "${SCRIPT_DIR}/../shared" && pwd)
-Setup Script: $INSTALL_PREFIX/setup_cp2k.sh
-Module File: $MODULEFILE_DIR/cp2k-baremetal
-Build Log: $INSTALL_PREFIX/build.log
-EOF
+export BUILD_ROOT="${BUILD_ROOT:-${PWD}/cp2k-baremetal}"
+mkdir -p "${BUILD_ROOT}"
-info "Done!"
+echo "Baremetal CP2K build"
+echo " Shared script: ${SHARED_DIR}/cp2k_build.sh"
+echo " Build root: ${BUILD_ROOT}"
+exec "${SHARED_DIR}/cp2k_build.sh" "$@"
diff --git a/cp2k/baremetal/scripts/_run_common.sh b/cp2k/baremetal/scripts/_run_common.sh
new file mode 100755
index 0000000..c6bba9d
--- /dev/null
+++ b/cp2k/baremetal/scripts/_run_common.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# Helpers shared by the baremetal run scripts.
+#
+# Sources Spack, activates the cp2k environment, prepares CP2K binary path,
+# benchmark inputs, OpenMPI/UCX env vars, and exports an RPA-friendly
+# default mpirun layout. Sourced (not executed) by the launcher scripts.
+
+set -eu
+set -o pipefail
+
+# ---- Paths --------------------------------------------------------------
+RUN_COMMON_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+BAREMETAL_DIR="$(cd "${RUN_COMMON_SCRIPT_DIR}/.." && pwd)"
+PROJECT_ROOT="$(cd "${BAREMETAL_DIR}/.." && pwd)"
+SHARED_DIR="${PROJECT_ROOT}/shared"
+
+# Where the build script put everything (matches baremetal/build_cp2k.sh)
+BUILD_ROOT="${BUILD_ROOT:-${BAREMETAL_DIR}/cp2k-baremetal}"
+SPACK_GIT_DIR="${SPACK_GIT_DIR:-${BUILD_ROOT}/spack_git}"
+
+# Helper binaries
+GPU_SMI_BIN="${GPU_SMI_BIN:-/usr/bin/rocm-smi}"
+GPU_BIND_BIN="${GPU_BIND_BIN:-${SHARED_DIR}/close.sh}"
+
+# ---- Activate Spack environment ----------------------------------------
+activate_cp2k() {
+ if [ ! -f "${SPACK_GIT_DIR}/share/spack/setup-env.sh" ]; then
+ echo "ERROR: Spack not found at ${SPACK_GIT_DIR}" >&2
+ echo " Run baremetal/build_cp2k.sh first or set BUILD_ROOT." >&2
+ return 1
+ fi
+ # shellcheck disable=SC1091
+ source "${SPACK_GIT_DIR}/share/spack/setup-env.sh"
+ spack env activate cp2k
+ spack load cp2k
+}
+
+# ---- CP2K benchmark inputs ---------------------------------------------
+# Clones the CP2K source tree into ${PROJECT_ROOT}/cp2k_repo if needed and
+# echoes the absolute path to the benchmark directory passed as $1.
+cp2k_benchmark_dir() {
+ local rel="$1"
+ local cp2k_branch="${CP2K_BRANCH:-v2026.1}"
+ if [ ! -d "${PROJECT_ROOT}/cp2k_repo" ]; then
+ echo "INFO: Cloning CP2K (${cp2k_branch}) into ${PROJECT_ROOT}/cp2k_repo" >&2
+ git clone --recursive -b "${cp2k_branch}" \
+ https://github.com/cp2k/cp2k.git \
+ "${PROJECT_ROOT}/cp2k_repo" >&2
+ fi
+ echo "${PROJECT_ROOT}/cp2k_repo/benchmarks/${rel}"
+}
+
+# ---- Default OpenMPI / UCX runtime tuning -------------------------------
+# Sets OpenMP threading, ROCm / HSA, and UCX defaults that the launcher
+# scripts rely on, and exports OMPI_MCA_mca_base_env_list so mpirun
+# forwards them to all ranks. Per-benchmark vars (e.g. DBCSR_USE_ACC_G2G
+# for the DFT benchmark) are added explicitly via mpirun -x in the
+# relevant launcher script.
+export_runtime_env() {
+ export OMP_PROC_BIND="${OMP_PROC_BIND:-spread}"
+ export OMP_PLACES="${OMP_PLACES:-threads}"
+ export OMP_WAIT_POLICY="${OMP_WAIT_POLICY:-active}"
+ export OMP_STACKSIZE="${OMP_STACKSIZE:-256M}"
+
+ export HSA_ENABLE_SDMA="${HSA_ENABLE_SDMA:-0}"
+ export HSA_ENABLE_IPC_MODE_LEGACY="${HSA_ENABLE_IPC_MODE_LEGACY:-1}"
+ export HIP_MEM_POOL_SUPPORT="${HIP_MEM_POOL_SUPPORT:-1}"
+
+ export OMPI_MCA_pml="${OMPI_MCA_pml:-ucx}"
+ export OMPI_MCA_osc="${OMPI_MCA_osc:-ucx}"
+ export OMPI_MCA_coll_ucc_enable="${OMPI_MCA_coll_ucc_enable:-1}"
+ export OMPI_MCA_coll_ucc_priority="${OMPI_MCA_coll_ucc_priority:-100}"
+
+ export UCX_TLS="${UCX_TLS:-self,sm,rocm_copy,rocm_ipc,ud_x}"
+ export UCX_HANDLE_ERRORS="${UCX_HANDLE_ERRORS:-bt}"
+ export UCX_MAX_RNDV_RAILS="${UCX_MAX_RNDV_RAILS:-1}"
+
+ # Forward these env vars from mpirun to spawned ranks. Per-benchmark vars
+ # (e.g. DBCSR_USE_ACC_G2G for the DFT benchmark) are added explicitly via
+ # mpirun -x in the relevant launcher script.
+ export OMPI_MCA_mca_base_env_list="OMP_PROC_BIND;OMP_PLACES;OMP_NUM_THREADS;OMP_STACKSIZE;HSA_ENABLE_SDMA;HSA_ENABLE_IPC_MODE_LEGACY;HIP_MEM_POOL_SUPPORT;UCX_TLS;UCX_HANDLE_ERRORS;UCX_MAX_RNDV_RAILS;ROCM_PATH;HIP_PLATFORM;HIP_DEVICE_LIB_PATH"
+
+ ulimit -s unlimited || true
+ ulimit -c 0 || true
+}
+
+# ---- Locate cp2k.psmp ---------------------------------------------------
+require_cp2k_bin() {
+ local bin="${CP2K_BIN_BASENAME:-cp2k.psmp}"
+ local path
+ path=$(command -v "${bin}" || true)
+ if [ -z "${path}" ] || [ ! -x "${path}" ]; then
+ echo "ERROR: ${bin} not found in PATH after activating the Spack env." >&2
+ return 1
+ fi
+ echo "${path}"
+}
+
+# ---- Print FOM line(s) from a CP2K output file --------------------------
+report_fom() {
+ local out="$1"
+ echo
+ echo "FORCE_EVAL timing:"
+ grep 'FORCE_EVAL' "${out}" 2>/dev/null || echo " (none found)"
+ echo
+ echo "CP2K timing:"
+ grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || echo " (none found)"
+ local last
+ last=$(grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || true)
+ if [ -n "${last}" ]; then
+ echo
+ echo "FOM: $(echo "${last}" | awk '{print $NF}') seconds"
+ fi
+}
diff --git a/cp2k/baremetal/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run b/cp2k/baremetal/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
new file mode 100755
index 0000000..3ba4cc0
--- /dev/null
+++ b/cp2k/baremetal/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
@@ -0,0 +1,107 @@
+#!/usr/bin/bash
+#-----------------------------------------------------------------------------
+#SBATCH -p MI350x
+#SBATCH -t 00:30:00
+#SBATCH -N 1
+#SBATCH --ntasks-per-node=16
+#SBATCH --gres=gpu:8
+#SBATCH --exclusive
+#SBATCH -J cp2k_QS_DM_LS_H2O-dft-ls-NREP2
+#SBATCH -o cp2k_QS_DM_LS_H2O-dft-ls-NREP2-%j.out
+
+# SLURM batch script for the QS_DM_LS H2O-dft-ls.NREP2 benchmark.
+# Defaults to a single-node MI350X-class layout (256 logical CPUs, 128
+# physical CPUs, 8 NUMA domains, 8 GPUs); override the lowercase topology
+# vars below for other machines. Activates the Spack environment built by
+# ../build_cp2k.sh, then runs the benchmark with NUMA-aware OpenMPI
+# binding (--map-by ppr:N:numa:PE=T) and one GPU per rank via close.sh +
+# ROCR_VISIBLE_DEVICES. Sets DBCSR_USE_ACC_G2G=1 to enable DBCSR
+# GPU-to-GPU communication (DFT-specific tuning). Also runs interactively
+# (`./cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run`) — the SBATCH directives are
+# then treated as plain shell comments.
+
+set -eu
+set -o pipefail
+
+SCRIPT_NAME_FULL=${BASH_SOURCE[0]}
+if [ -n "${SLURM_JOB_ID:-}" ]; then
+ is_batch_job=$(scontrol show jobid="${SLURM_JOB_ID}" | grep -q BatchFlag=1 && echo yes || echo no)
+ if [ "${is_batch_job}" = "yes" ]; then
+ SCRIPT_NAME_FULL=$(scontrol show jobid="${SLURM_JOB_ID}" | grep "Command=" | cut -d= -f2 | cut -d' ' -f1)
+ fi
+fi
+
+SCRIPT_DIR=$(cd "$(dirname "${SCRIPT_NAME_FULL}")" && pwd)
+# shellcheck source=./_run_common.sh
+source "${SCRIPT_DIR}/_run_common.sh"
+
+ARCH="${arch:-mi350x}"
+CP2K_CONFIG=QS_DM_LS
+CP2K_EXPERIMENT=H2O-dft-ls-NREP2
+CP2K_INPUT=H2O-dft-ls.NREP2.inp
+CP2K_OUTPUT=H2O-dft-ls.NREP2.out
+
+# Cluster topology defaults (single-node MI350X-class: 256 logical CPUs /
+# 128 physical CPUs / 8 NUMA domains / 8 GPUs). Override via env vars.
+lcpus_per_node=${lcpus_per_node:-256}
+physcpus_per_node=${physcpus_per_node:-128}
+numa_per_node=${numa_per_node:-8}
+gpus_per_node=${GPUS_PER_NODE:-8}
+
+nnodes=${SLURM_NNODES:-1}
+ntasks=${SLURM_NTASKS:-$(( nnodes * 16 ))}
+ntasks_per_node=${SLURM_NTASKS_PER_NODE:-$(( ntasks / nnodes ))}
+ntasks_per_numa=$(( ntasks_per_node / numa_per_node ))
+nthreads=${SLURM_CPUS_PER_TASK:-$(( physcpus_per_node / ntasks_per_node ))}
+
+export GPUS_PER_NODE="${gpus_per_node}"
+export OMP_NUM_THREADS="${nthreads}"
+
+activate_cp2k
+export_runtime_env
+
+# Enable DBCSR GPU-to-GPU communication (improves DFT performance on multi-GPU)
+export DBCSR_USE_ACC_G2G="${DBCSR_USE_ACC_G2G:-1}"
+
+CP2K_BIN="$(require_cp2k_bin)"
+
+BENCH_DIR="$(cp2k_benchmark_dir "${CP2K_CONFIG}")"
+INPUT_PATH="${BENCH_DIR}/${CP2K_INPUT}"
+if [ ! -f "${INPUT_PATH}" ]; then
+ echo "ERROR: benchmark input not found: ${INPUT_PATH}" >&2
+ exit 1
+fi
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${BAREMETAL_DIR}/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+cd "${OUTPUT_DIR}"
+
+env > env.out
+ln -sfn "${CP2K_BIN}" "$(basename "${CP2K_BIN}")"
+ln -sfn "${BENCH_DIR}"/* .
+
+# Per-host node bindings for OpenMPI (-host)
+nodebind=""
+for nodename in $(scontrol show hostnames "${SLURM_NODELIST:-$(hostname -s)}" 2>/dev/null || hostname -s); do
+ nodebind+="${nodename}:${lcpus_per_node},"
+done
+nodebind="-host ${nodebind%,}"
+
+[ -x "${GPU_SMI_BIN}" ] && "${GPU_SMI_BIN}" || true
+
+echo "----- DFT benchmark: ${CP2K_INPUT} -----"
+echo " ranks/node: ${ntasks_per_node}"
+echo " threads/rank: ${nthreads}"
+echo " GPUs/node: ${gpus_per_node}"
+echo " ranks/NUMA: ${ntasks_per_numa}"
+date
+set -x
+mpirun --report-bindings -np "${ntasks}" ${nodebind} \
+ --map-by "ppr:${ntasks_per_numa}:numa:PE=${nthreads}" \
+ -x DBCSR_USE_ACC_G2G \
+ "${GPU_BIND_BIN}" \
+ "$(basename "${CP2K_BIN}")" -i "${CP2K_INPUT}" -o "${CP2K_OUTPUT}"
+set +x
+date
+report_fom "${OUTPUT_DIR}/${CP2K_OUTPUT}"
diff --git a/cp2k/baremetal/scripts/cp2k_QS_mp2_rpa_32-H2O.run b/cp2k/baremetal/scripts/cp2k_QS_mp2_rpa_32-H2O.run
new file mode 100755
index 0000000..fe3fe0a
--- /dev/null
+++ b/cp2k/baremetal/scripts/cp2k_QS_mp2_rpa_32-H2O.run
@@ -0,0 +1,110 @@
+#!/usr/bin/bash
+#-----------------------------------------------------------------------------
+#SBATCH -p MI350x
+#SBATCH -t 00:30:00
+#SBATCH -N 1
+#SBATCH --ntasks-per-node=32
+#SBATCH --gres=gpu:8
+#SBATCH --exclusive
+#SBATCH -J cp2k_QS_mp2_rpa_32-H2O
+#SBATCH -o cp2k_QS_mp2_rpa_32-H2O-%j.out
+
+# SLURM batch script for the QS_mp2_rpa 32-H2O benchmark. Defaults to a
+# single-node MI350X-class layout (256 logical CPUs, 128 physical CPUs,
+# 8 NUMA domains, 8 GPUs); override the lowercase topology vars below for
+# other machines. Activates the Spack environment built by
+# ../build_cp2k.sh, then runs the init and solver stages back to back with
+# NUMA-aware OpenMPI binding (--map-by ppr:N:numa:PE=T) and one GPU per
+# rank via close.sh + ROCR_VISIBLE_DEVICES. Also runs interactively
+# (`./cp2k_QS_mp2_rpa_32-H2O.run`) — the SBATCH directives are then
+# treated as plain shell comments.
+
+set -eu
+set -o pipefail
+
+SCRIPT_NAME_FULL=${BASH_SOURCE[0]}
+if [ -n "${SLURM_JOB_ID:-}" ]; then
+ is_batch_job=$(scontrol show jobid="${SLURM_JOB_ID}" | grep -q BatchFlag=1 && echo yes || echo no)
+ if [ "${is_batch_job}" = "yes" ]; then
+ SCRIPT_NAME_FULL=$(scontrol show jobid="${SLURM_JOB_ID}" | grep "Command=" | cut -d= -f2 | cut -d' ' -f1)
+ fi
+fi
+
+SCRIPT_DIR=$(cd "$(dirname "${SCRIPT_NAME_FULL}")" && pwd)
+# shellcheck source=./_run_common.sh
+source "${SCRIPT_DIR}/_run_common.sh"
+
+ARCH="${arch:-mi350x}"
+CP2K_CONFIG=QS_mp2_rpa
+CP2K_EXPERIMENT=32-H2O
+
+# Cluster topology defaults (single-node MI350X-class: 256 logical CPUs /
+# 128 physical CPUs / 8 NUMA domains / 8 GPUs). Override via env vars.
+lcpus_per_node=${lcpus_per_node:-256}
+physcpus_per_node=${physcpus_per_node:-128}
+numa_per_node=${numa_per_node:-8}
+gpus_per_node=${GPUS_PER_NODE:-8}
+
+nnodes=${SLURM_NNODES:-1}
+ntasks=${SLURM_NTASKS:-$(( nnodes * 32 ))}
+ntasks_per_node=${SLURM_NTASKS_PER_NODE:-$(( ntasks / nnodes ))}
+ntasks_per_numa=$(( ntasks_per_node / numa_per_node ))
+nthreads=${SLURM_CPUS_PER_TASK:-$(( physcpus_per_node / ntasks_per_node ))}
+ntasks_init=${ntasks_init:-1}
+nthreads_init=${nthreads_init:-$(( physcpus_per_node / numa_per_node ))}
+
+export GPUS_PER_NODE="${gpus_per_node}"
+export OMP_NUM_THREADS="${nthreads}"
+
+activate_cp2k
+export_runtime_env
+
+CP2K_BIN="$(require_cp2k_bin)"
+
+BENCH_DIR="$(cp2k_benchmark_dir "${CP2K_CONFIG}/${CP2K_EXPERIMENT}")"
+INIT_INPUT="${BENCH_DIR}/H2O-32-PBE-TZ.inp"
+SOLVER_INPUT="${BENCH_DIR}/H2O-32-RI-dRPA-TZ.inp"
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${BAREMETAL_DIR}/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+cd "${OUTPUT_DIR}"
+
+env > env.out
+ln -sfn "${CP2K_BIN}" "$(basename "${CP2K_BIN}")"
+ln -sfn "${BENCH_DIR}"/* .
+
+# Per-host node bindings for OpenMPI (-host)
+nodebind=""
+for nodename in $(scontrol show hostnames "${SLURM_NODELIST:-$(hostname -s)}" 2>/dev/null || hostname -s); do
+ nodebind+="${nodename}:${lcpus_per_node},"
+done
+nodebind="-host ${nodebind%,}"
+
+[ -x "${GPU_SMI_BIN}" ] && "${GPU_SMI_BIN}" || true
+
+# Stage 1: init
+export OMP_NUM_THREADS="${nthreads_init}"
+echo "----- Stage 1: init -----"
+date
+set -x
+mpirun --report-bindings -np "${ntasks_init}" ${nodebind} \
+ --map-by "ppr:1:node:PE=${nthreads_init}" \
+ "${GPU_BIND_BIN}" \
+ "$(basename "${CP2K_BIN}")" -i "$(basename "${INIT_INPUT}")" -o H2O-32-PBE-TZ.out
+set +x
+date
+report_fom "${OUTPUT_DIR}/H2O-32-PBE-TZ.out"
+
+# Stage 2: solver
+export OMP_NUM_THREADS="${nthreads}"
+echo "----- Stage 2: solver -----"
+date
+set -x
+mpirun --report-bindings -np "${ntasks}" ${nodebind} \
+ --map-by "ppr:${ntasks_per_numa}:numa:PE=${nthreads}" \
+ "${GPU_BIND_BIN}" \
+ "$(basename "${CP2K_BIN}")" -i "$(basename "${SOLVER_INPUT}")" -o H2O-32-RI-dRPA-TZ.out
+set +x
+date
+report_fom "${OUTPUT_DIR}/H2O-32-RI-dRPA-TZ.out"
diff --git a/cp2k/baremetal/scripts/run_dft_nrep2.sh b/cp2k/baremetal/scripts/run_dft_nrep2.sh
deleted file mode 100755
index b71af1b..0000000
--- a/cp2k/baremetal/scripts/run_dft_nrep2.sh
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/bash
-#
-# Run CP2K DFT benchmark with 16 MPI ranks on baremetal
-#
-
-set -e
-
-# Get the directory where this script is located
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-BAREMETAL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
-PROJECT_ROOT="$(cd "${BAREMETAL_DIR}/.." && pwd)"
-
-NUM_RANKS=16
-NUM_GPUS=${NUM_GPUS:-8}
-NUM_CPUS=${NUM_CPUS:-128}
-OMP_NUM_THREADS=${OMP_NUM_THREADS:-4}
-CP2K_BRANCH="v2026.1"
-BENCHMARK_INPUT="${PROJECT_ROOT}/cp2k_repo/benchmarks/QS_DM_LS/H2O-dft-ls.NREP2.inp"
-OUTPUT_FILE="${BAREMETAL_DIR}/H2O-DFT-LS-NREP2-16ranks.txt"
-CP2K_EXECUTABLE="cp2k.psmp"
-
-echo "=========================================="
-echo "Running CP2K DFT Benchmark - Baremetal"
-echo "MPI Ranks: $NUM_RANKS"
-echo "OpenMP Threads per rank: $OMP_NUM_THREADS"
-echo "Executable: $CP2K_EXECUTABLE"
-echo "CP2K Branch: $CP2K_BRANCH"
-echo "=========================================="
-
-# Source Spack environment
-SPACK_ROOT="${SPACK_ROOT:-$HOME/spack}"
-if [ -f "${SPACK_ROOT}/share/spack/setup-env.sh" ]; then
- source "${SPACK_ROOT}/share/spack/setup-env.sh"
-else
- echo "ERROR: Spack not found at ${SPACK_ROOT}/share/spack/setup-env.sh"
- echo "Please set SPACK_ROOT environment variable or ensure Spack is installed at ~/spack"
- exit 1
-fi
-
-# Activate Spack environment
-SPACK_ENV_DIR="${PROJECT_ROOT}/docker/cp2k_environment"
-if [ ! -d "$SPACK_ENV_DIR" ]; then
- echo "ERROR: Spack environment directory not found: $SPACK_ENV_DIR"
- exit 1
-fi
-
-cd "$SPACK_ENV_DIR" || exit 1
-# Activate Spack environment (suppress warnings but keep activation)
-spack env activate cp2k-baremetal 2>&1 | grep -v "Warning: package repository" || true
-# Ensure environment is actually activated
-eval $(spack env activate --sh cp2k-baremetal 2>&1 | grep -v "Warning: package repository")
-
-# Clone CP2K repository if not already present
-if [ ! -d "${PROJECT_ROOT}/cp2k_repo" ]; then
- echo "Cloning CP2K repository (branch ${CP2K_BRANCH})..."
- cd "$PROJECT_ROOT" || exit 1
- git clone --recursive -b ${CP2K_BRANCH} https://github.com/cp2k/cp2k.git cp2k_repo
-else
- echo "CP2K repository already exists, skipping clone..."
-fi
-
-# Ensure scripts have execute permission
-if [ -d "${SCRIPT_DIR}" ]; then
- echo "Setting execute permissions on scripts..."
- chmod +x "${SCRIPT_DIR}"/*.sh 2>/dev/null || true
-fi
-
-# Find the CP2K executable
-CP2K_PATH=$(which $CP2K_EXECUTABLE 2>/dev/null)
-if [ -z "$CP2K_PATH" ] || [ ! -x "$CP2K_PATH" ]; then
- echo "ERROR: CP2K executable not found in PATH: $CP2K_EXECUTABLE"
- echo "Current PATH: $PATH"
- exit 1
-fi
-echo "Found CP2K at: $CP2K_PATH"
-
-# Ensure benchmark input file exists
-if [ ! -f "$BENCHMARK_INPUT" ]; then
- echo "ERROR: Benchmark input file not found: $BENCHMARK_INPUT"
- exit 1
-fi
-
-echo "Using executable: $CP2K_EXECUTABLE"
-echo "Running benchmark with affinity scripts..."
-
-# Change to benchmark directory
-BENCHMARK_DIR=$(dirname "$BENCHMARK_INPUT")
-cd "$BENCHMARK_DIR" || exit 1
-echo "Working directory: $(pwd)"
-
-# Run with affinity scripts
-# Use UCX with shared memory and ROCm transports
-# Enable g2g (GPU-to-GPU) for DBCSR
-mpirun \
- -x UCX_TLS=sm,self,rocm \
- -x UCX_PROTO_ENABLE=n \
- -x UCX_ROCM_COPY_LAT=2e-6 \
- -x UCX_ROCM_IPC_MIN_ZCOPY=4096 \
- --mca pml ucx \
- --mca osc ucx \
- -x UCX_MM_SEG_SIZE=60k \
- -x UCX_ROCM_COPY_H2D_THRESH=256 \
- --mca coll_ucc_enable 1 \
- --mca coll_ucc_priority 100 \
- -x NUM_CPUS=$NUM_CPUS \
- -x NUM_GPUS=$NUM_GPUS \
- -x OMP_NUM_THREADS=$OMP_NUM_THREADS \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np $NUM_RANKS \
- --bind-to none \
- "${SCRIPT_DIR}/set_cpu_affinity.sh" \
- "${SCRIPT_DIR}/set_gpu_affinity.sh" \
- "$CP2K_PATH" \
- -i "$BENCHMARK_INPUT" \
- -o "$OUTPUT_FILE"
-
-if [ $? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Benchmark completed successfully!'
- echo '=========================================='
- echo "Output file: $OUTPUT_FILE"
- echo ''
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' "$OUTPUT_FILE" || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'All CP2K timing lines:'
- grep 'CP2K ' "$OUTPUT_FILE" || echo 'No timing information found'
- echo ''
-
- # Extract FOM: last time value from the last line matching 'CP2K '
- FOM_LINE=$(grep 'CP2K ' "$OUTPUT_FILE" | tail -n 1)
- if [ -n "$FOM_LINE" ]; then
- # Extract the last numeric value (time) from the line
- # This assumes the time is the last field/word in the line
- FOM=$(echo "$FOM_LINE" | awk '{print $NF}')
- echo '=========================================='
- echo "FOM (Figure of Merit): $FOM seconds"
- echo '=========================================='
- else
- echo 'Warning: Could not extract FOM from output file'
- fi
-else
- echo 'Benchmark failed!'
- exit 1
-fi
-
-echo ""
-echo "Output file saved to: $OUTPUT_FILE"
diff --git a/cp2k/baremetal/scripts/run_rpa32.sh b/cp2k/baremetal/scripts/run_rpa32.sh
deleted file mode 100755
index b8c8243..0000000
--- a/cp2k/baremetal/scripts/run_rpa32.sh
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/bin/bash
-#
-# Run CP2K RPA benchmark (32-H2O) with two stages on baremetal
-# Stage 1 (init): H2O-32-PBE-TZ.inp - 1 rank, 4 threads, 1 GPU
-# Stage 2 (solver): H2O-32-RI-dRPA-TZ.inp - 16 ranks, 8 threads, 8 GPUs
-#
-
-set -e
-
-# Get the directory where this script is located
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-BAREMETAL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
-PROJECT_ROOT="$(cd "${BAREMETAL_DIR}/.." && pwd)"
-
-CP2K_BRANCH="v2026.1"
-CP2K_EXECUTABLE="cp2k.psmp"
-BENCHMARK_DIR="${PROJECT_ROOT}/cp2k_repo/benchmarks/QS_mp2_rpa/32-H2O"
-
-# Stage 1: Init
-INIT_INPUT="${BENCHMARK_DIR}/H2O-32-PBE-TZ.inp"
-INIT_OUTPUT="${BAREMETAL_DIR}/H2O-32-PBE-TZ-output.txt"
-INIT_RANKS=1
-INIT_THREADS=4
-INIT_GPUS=1
-INIT_CPUS=128
-
-# Stage 2: Solver
-SOLVER_INPUT="${BENCHMARK_DIR}/H2O-32-RI-dRPA-TZ.inp"
-SOLVER_OUTPUT="${BAREMETAL_DIR}/H2O-32-RI-dRPA-TZ-output.txt"
-SOLVER_RANKS=16
-SOLVER_THREADS=8
-SOLVER_GPUS=8
-SOLVER_CPUS=128
-
-echo "=========================================="
-echo "CP2K RPA Benchmark (32-H2O) - Baremetal"
-echo "CP2K Branch: $CP2K_BRANCH"
-echo "=========================================="
-
-# Source Spack environment
-SPACK_ROOT="${SPACK_ROOT:-$HOME/spack}"
-if [ -f "${SPACK_ROOT}/share/spack/setup-env.sh" ]; then
- source "${SPACK_ROOT}/share/spack/setup-env.sh"
-else
- echo "ERROR: Spack not found at ${SPACK_ROOT}/share/spack/setup-env.sh"
- echo "Please set SPACK_ROOT environment variable or ensure Spack is installed at ~/spack"
- exit 1
-fi
-
-# Activate Spack environment
-SPACK_ENV_DIR="${PROJECT_ROOT}/docker/cp2k_environment"
-if [ ! -d "$SPACK_ENV_DIR" ]; then
- echo "ERROR: Spack environment directory not found: $SPACK_ENV_DIR"
- exit 1
-fi
-
-cd "$SPACK_ENV_DIR" || exit 1
-# Activate Spack environment (suppress warnings but keep activation)
-spack env activate cp2k-baremetal 2>&1 | grep -v "Warning: package repository" || true
-# Ensure environment is actually activated
-eval $(spack env activate --sh cp2k-baremetal 2>&1 | grep -v "Warning: package repository")
-
-# Clone CP2K repository if not already present
-if [ ! -d "${PROJECT_ROOT}/cp2k_repo" ]; then
- echo "Cloning CP2K repository (branch ${CP2K_BRANCH})..."
- cd "$PROJECT_ROOT" || exit 1
- git clone --recursive -b ${CP2K_BRANCH} https://github.com/cp2k/cp2k.git cp2k_repo
-else
- echo "CP2K repository already exists, skipping clone..."
-fi
-
-# Ensure scripts have execute permission
-if [ -d "${SCRIPT_DIR}" ]; then
- echo "Setting execute permissions on scripts..."
- chmod +x "${SCRIPT_DIR}"/*.sh 2>/dev/null || true
-fi
-
-# Find the CP2K executable
-CP2K_PATH=$(which $CP2K_EXECUTABLE 2>/dev/null)
-if [ -z "$CP2K_PATH" ] || [ ! -x "$CP2K_PATH" ]; then
- echo "ERROR: CP2K executable not found in PATH: $CP2K_EXECUTABLE"
- echo "Current PATH: $PATH"
- exit 1
-fi
-echo "Found CP2K at: $CP2K_PATH"
-
-# Ensure benchmark directory exists
-if [ ! -d "$BENCHMARK_DIR" ]; then
- echo "ERROR: Benchmark directory not found: $BENCHMARK_DIR"
- exit 1
-fi
-
-echo ""
-echo "=========================================="
-echo "STAGE 1: Init (H2O-32-PBE-TZ.inp)"
-echo "Ranks: $INIT_RANKS, Threads: $INIT_THREADS, GPUs: $INIT_GPUS"
-echo "=========================================="
-
-# Change to benchmark directory
-cd "$BENCHMARK_DIR" || exit 1
-echo "Working directory: $(pwd)"
-
-# Run init stage with affinity scripts
-# Use UCX with shared memory and ROCm transports
-mpirun \
- -x UCX_TLS=sm,self,rocm \
- -x UCX_PROTO_ENABLE=n \
- -x UCX_ROCM_COPY_LAT=2e-6 \
- -x UCX_ROCM_IPC_MIN_ZCOPY=4096 \
- --mca pml ucx \
- --mca osc ucx \
- -x UCX_MM_SEG_SIZE=60k \
- -x UCX_ROCM_COPY_H2D_THRESH=256 \
- --mca coll_ucc_enable 1 \
- --mca coll_ucc_priority 100 \
- -x NUM_CPUS=$INIT_CPUS \
- -x NUM_GPUS=$INIT_GPUS \
- -x OMP_NUM_THREADS=$INIT_THREADS \
- --oversubscribe \
- -np $INIT_RANKS \
- --bind-to none \
- "${SCRIPT_DIR}/set_cpu_affinity.sh" \
- "${SCRIPT_DIR}/set_gpu_affinity.sh" \
- "$CP2K_PATH" \
- -i "$INIT_INPUT" \
- -o "$INIT_OUTPUT"
-
-if [ $? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Init Stage completed successfully!'
- echo '=========================================='
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' "$INIT_OUTPUT" || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'CP2K timing:'
- grep 'CP2K ' "$INIT_OUTPUT" | tail -n 1 || echo 'No timing found'
-
- # Extract FOM
- FOM_LINE=$(grep 'CP2K ' "$INIT_OUTPUT" | tail -n 1)
- if [ -n "$FOM_LINE" ]; then
- FOM=$(echo "$FOM_LINE" | awk '{print $NF}')
- echo "Init Stage FOM: $FOM seconds"
- fi
-else
- echo 'Init stage failed!'
- exit 1
-fi
-
-echo ""
-echo "=========================================="
-echo "STAGE 2: Solver (H2O-32-RI-dRPA-TZ.inp)"
-echo "Ranks: $SOLVER_RANKS, Threads: $SOLVER_THREADS, GPUs: $SOLVER_GPUS"
-echo "=========================================="
-
-# Run solver stage with affinity scripts
-# Use UCX with shared memory and ROCm transports (disable InfiniBand)
-# Enable g2g (GPU-to-GPU) for DBCSR
-mpirun \
- -x UCX_TLS=sm,self,rocm \
- -x UCX_PROTO_ENABLE=n \
- -x UCX_ROCM_COPY_LAT=2e-6 \
- -x UCX_ROCM_IPC_MIN_ZCOPY=4096 \
- --mca pml ucx \
- --mca osc ucx \
- -x UCX_MM_SEG_SIZE=60k \
- -x UCX_ROCM_COPY_H2D_THRESH=256 \
- --mca coll_ucc_enable 1 \
- --mca coll_ucc_priority 100 \
- --mca btl ^openib \
- --mca pml_base_verbose 0 \
- -x NUM_CPUS=$SOLVER_CPUS \
- -x NUM_GPUS=$SOLVER_GPUS \
- -x OMP_NUM_THREADS=$SOLVER_THREADS \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np $SOLVER_RANKS \
- --bind-to none \
- "${SCRIPT_DIR}/set_cpu_affinity.sh" \
- "${SCRIPT_DIR}/set_gpu_affinity.sh" \
- "$CP2K_PATH" \
- -i "$SOLVER_INPUT" \
- -o "$SOLVER_OUTPUT"
-
-if [ $? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Solver Stage completed successfully!'
- echo '=========================================='
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' "$SOLVER_OUTPUT" || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'CP2K timing:'
- grep 'CP2K ' "$SOLVER_OUTPUT" | tail -n 1 || echo 'No timing found'
-
- # Extract FOM
- FOM_LINE=$(grep 'CP2K ' "$SOLVER_OUTPUT" | tail -n 1)
- if [ -n "$FOM_LINE" ]; then
- FOM=$(echo "$FOM_LINE" | awk '{print $NF}')
- echo "Solver Stage FOM: $FOM seconds"
- fi
-else
- echo 'Solver stage failed!'
- exit 1
-fi
-
-echo ""
-echo "=========================================="
-echo "RPA Benchmark Complete!"
-echo "=========================================="
-echo "Init output: $INIT_OUTPUT"
-echo "Solver output: $SOLVER_OUTPUT"
-echo ""
-echo "Summary:"
-echo "--------"
-echo "Init Stage:"
-grep 'FORCE_EVAL' "$INIT_OUTPUT" 2>/dev/null || echo " FORCE_EVAL: Not available"
-grep 'CP2K ' "$INIT_OUTPUT" 2>/dev/null | tail -n 1 | awk '{print " CP2K FOM: " $NF " seconds"}' || echo " FOM: Not available"
-echo ""
-echo "Solver Stage:"
-grep 'FORCE_EVAL' "$SOLVER_OUTPUT" 2>/dev/null || echo " FORCE_EVAL: Not available"
-grep 'CP2K ' "$SOLVER_OUTPUT" 2>/dev/null | tail -n 1 | awk '{print " CP2K FOM: " $NF " seconds"}' || echo " FOM: Not available"
diff --git a/cp2k/baremetal/scripts/set_cpu_affinity.sh b/cp2k/baremetal/scripts/set_cpu_affinity.sh
deleted file mode 100755
index 57b15da..0000000
--- a/cp2k/baremetal/scripts/set_cpu_affinity.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-if [[ -n ${OMPI_COMM_WORLD_RANK+x} ]]; then
- # ompi
- export global_rank=${OMPI_COMM_WORLD_RANK}
- export local_rank=${OMPI_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${OMPI_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${MV2_COMM_WORLD_RANK+x} ]]; then
- # mvapich2
- export global_rank=${MV2_COMM_WORLD_RANK}
- export local_rank=${MV2_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${MV2_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${SLURM_LOCALID+x} ]]; then
- # mpi via srun
- export global_rank=${SLURM_PROCID}
- export local_rank=${SLURM_LOCALID}
- export ranks_per_node=$(($SLURM_NTASKS/$SLURM_NNODES))
-fi
-
-# Set defaults
-let NUM_CPUS=${NUM_CPUS:-128}
-let RANK_STRIDE=${RANK_STRIDE:-${NUM_CPUS}/${ranks_per_node}}
-let OMP_STRIDE=${OMP_STRIDE:-1}
-let NUM_GPUS=${NUM_GPUS:-8}
-let GPU_START=${GPU_START:-0}
-let GPU_STRIDE=${GPU_STRIDE:-1}
-if [[ -z ${GPU+x} ]]; then
- let GPU="MI210"
-fi
-
-# Optimal ordering of CPU cores w.r.t. GPU devices is different for MI250X
-# Need GPU and NUM_CPUS to be set to MI250X and 64 respectively
-if [[ $GPU == "MI250X" && $NUM_CPUS == "64" ]]; then
- cpu_list=(48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47)
-else
- cpu_list=($(seq 0 127))
-fi
-
-let cpus_per_gpu=${NUM_CPUS}/${NUM_GPUS}
-let cpu_start_index=$(( ($RANK_STRIDE*${local_rank})+${GPU_START}*$cpus_per_gpu ))
-let cpu_start=${cpu_list[$cpu_start_index]}
-let cpu_stop=$(($cpu_start+$OMP_NUM_THREADS*$OMP_STRIDE-1))
-
-export GOMP_CPU_AFFINITY=$cpu_start-$cpu_stop:$OMP_STRIDE
-echo "rank_local= " $local_rank " GOMP_CPU_AFFINITY= " $GOMP_CPU_AFFINITY
-
-"$@"
diff --git a/cp2k/baremetal/scripts/set_gpu_affinity.sh b/cp2k/baremetal/scripts/set_gpu_affinity.sh
deleted file mode 100755
index 25425f8..0000000
--- a/cp2k/baremetal/scripts/set_gpu_affinity.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-##############################################
-# Script that just assigns GPUs/GCDs to ranks
-#
-# Relies on environment variables to be set
-# for cases other than default
-##############################################
-
-if [[ -n ${OMPI_COMM_WORLD_RANK+z} ]]; then
- # ompi
- export global_rank=${OMPI_COMM_WORLD_RANK}
- export local_rank=${OMPI_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${OMPI_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${MV2_COMM_WORLD_RANK+z} ]]; then
- # mvapich2
- export global_rank=${MV2_COMM_WORLD_RANK}
- export local_rank=${MV2_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${MV2_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${SLURM_LOCALID+z} ]]; then
- # mpich via srun
- export global_rank=${SLURM_PROCID}
- export local_rank=${SLURM_LOCALID}
- export ranks_per_node=$(($SLURM_NTASKS/$SLURM_NNODES))
-fi
-
-# Set defaults
-let NUM_CPUS=${NUM_CPUS:-128}
-let RANK_STRIDE=${RANK_STRIDE:-${NUM_CPUS}/${ranks_per_node}}
-let OMP_STRIDE=${OMP_STRIDE:-1}
-let NUM_GPUS=${NUM_GPUS:-8}
-let GPU_START=${GPU_START:-0}
-let GPU_STRIDE=${GPU_STRIDE:-1}
-
-let ranks_per_gpu=$(((${ranks_per_node}+${NUM_GPUS}-1)/${NUM_GPUS}))
-let my_gpu=$(($local_rank*$GPU_STRIDE/$ranks_per_gpu))+${GPU_START}
-
-arch=${GPU_ARCH_INP}
-export HIP_VISIBLE_DEVICES=$my_gpu
-echo "rank_local= " $local_rank " HIP_VISIBLE_DEVICES= " $HIP_VISIBLE_DEVICES
-
-"$@"
-
diff --git a/cp2k/docker/Dockerfile b/cp2k/docker/Dockerfile
index 06853ee..7dec572 100644
--- a/cp2k/docker/Dockerfile
+++ b/cp2k/docker/Dockerfile
@@ -1,188 +1,102 @@
-ARG IMAGE="rocm/dev-ubuntu-24.04:7.0-complete"
+ARG IMAGE="rocm/dev-ubuntu-24.04:7.2-complete"
FROM ${IMAGE}
-#ARG ROCM_URL="https://repo.radeon.com/amdgpu-install/7.0/ubuntu/noble/amdgpu-install_7.0.70000-1_all.deb"
-ARG UCX_BRANCH="v1.19.0"
-ARG UCC_BRANCH="v1.5.1"
-ARG OMPI_BRANCH="v5.0.8"
-ARG APT_GET_APPS=""
-ARG AMDGPU_TARGETS="gfx908,gfx90a,gfx942"
-
-# Update and Install basic Linux development tools
-RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
- ca-certificates \
- git \
- ssh \
- make \
- vim \
- nano \
- libtinfo-dev\
- initramfs-tools \
- libelf-dev \
- numactl \
- curl \
- wget \
- tmux \
- build-essential \
+# ---------------------------------------------------------------------------
+# Spack-based CP2K build. Unlike the previous recipe, this image does NOT
+# build UCX, UCC, or OpenMPI by hand. Spack builds them itself, along with
+# a fresh GCC toolchain, the full scientific stack, and CP2K. The Dockerfile
+# is intentionally a thin layer over shared/cp2k_build.sh so the build
+# recipe is identical for baremetal and container builds.
+# ---------------------------------------------------------------------------
+
+ARG GPU_ARCH=gfx950
+ARG CPU_ARCH=zen5
+ARG ROCM_VERSION=7.2.0
+ARG ROCM_PATH=/opt/rocm-${ROCM_VERSION}
+ARG GCC_VERSION=14.3.0
+ARG SPACK_BRANCH=v1.1.1
+ARG SPACK_PACKAGES_TAG=v2026.03.0
+ARG BUILD_JOBS=32
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+# System packages required to bootstrap Spack and build the GCC/MPI/CP2K
+# stack from source. ROCm itself is provided by the base image.
+RUN apt-get update \
+ && apt-get upgrade -y \
+ && apt-get install -y --no-install-recommends \
autoconf \
automake \
+ bzip2 \
+ build-essential \
+ ca-certificates \
cmake \
- gcc-12 \
- g++-12 \
- libtool \
- pkg-config \
- libnuma-dev \
- gfortran \
+ curl \
+ file \
flex \
- hwloc \
- gfortran-12 \
+ gfortran \
+ git \
+ gnupg \
+ gzip \
+ libelf-dev \
+ libnuma-dev \
libstdc++-12-dev \
+ libtool \
libxml2-dev \
+ m4 \
+ make \
+ nano \
+ numactl \
+ patch \
+ pkg-config \
+ python3 \
python3-dev \
python3-pip \
- unzip ${APT_GET_APPS}\
- && apt-get clean
-
-RUN rm /usr/bin/gcc /usr/bin/g++ /usr/bin/gfortran
-RUN ln -s /usr/bin/gcc-12 /usr/bin/gcc
-RUN ln -s /usr/bin/g++-12 /usr/bin/g++
-RUN ln -s /usr/bin/gfortran-12 /usr/bin/gfortran
-
-# RUN wget -qO- https://repo.radeon.com/rocm/rocm.gpg.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/rocm.gpg \
-# && wget -O rocm.deb ${ROCM_URL} \
-# && apt install -y ./rocm.deb \
-# && amdgpu-install --usecase=rocm,hiplibsdk --no-dkms -y
-
-# RUN bash -c """IFS=',' read -r -a ARCH <<<${AMDGPU_TARGETS} \
-# && for gpu_arch in \${ARCH[@]}; do \
-# echo \$gpu_arch >> /opt/rocm/bin/target.lst; \
-# done""" \
-# && chmod a+r /opt/rocm/bin/target.lst
-
-# # Requires cmake > 3.22
-# RUN mkdir -p /opt/cmake \
-# && wget --no-check-certificate --quiet -O - https://cmake.org/files/v3.30/cmake-3.30.5-linux-x86_64.tar.gz | tar --strip-components=1 -xz -C /opt/cmake
-
-ENV ROCM_PATH=/opt/rocm \
- UCX_PATH=/opt/ucx \
- UCC_PATH=/opt/ucc \
- OMPI_PATH=/opt/ompi \
- # FC=amdflang \
- # CC=amdclang \
- # CXX=amdclang++ \
- AMDGPU_TARGETS=${AMDGPU_TARGETS}
-
-# Adding rocm/cmake to the Environment
-ENV PATH=$ROCM_PATH/bin:/opt/cmake/bin:$PATH \
- LD_LIBRARY_PATH=$ROCM_PATH/lib:$ROCM_PATH/lib64:$ROCM_PATH/llvm/lib:$ROCM_PATH/lib/llvm/lib:$LD_LIBRARY_PATH \
- LIBRARY_PATH=$ROCM_PATH/lib:$ROCM_PATH/lib64:$LIBRARY_PATH \
- C_INCLUDE_PATH=$ROCM_PATH/include:$C_INCLUDE_PATH \
- CPLUS_INCLUDE_PATH=$ROCM_PATH/include:$CPLUS_INCLUDE_PATH \
- CMAKE_PREFIX_PATH=$ROCM_PATH/lib/cmake:$CMAKE_PREFIX_PATH
-
-
-WORKDIR /tmp
-
-# Install UCX
-RUN git clone https://github.com/openucx/ucx.git -b ${UCX_BRANCH} \
- && cd ucx \
- && ./autogen.sh \
- && mkdir build \
- && cd build \
- && ../contrib/configure-release --prefix=$UCX_PATH \
- --with-rocm=$ROCM_PATH \
- --without-knem \
- --without-xpmem \
- --without-cuda \
- --enable-optimizations \
- --disable-logging \
- --disable-debug \
- --disable-examples \
- && make -j $(nproc) \
- && make install
-
-# Install UCC
-RUN git clone -b ${UCC_BRANCH} https://github.com/openucx/ucc \
- && cd ucc \
- && ./autogen.sh \
- && mkdir build \
- && cd build \
- && ../configure --prefix=${UCC_PATH} --with-rocm=${ROCM_PATH} --with-ucx=${UCX_PATH} --with-rccl=no --with-rocm-arch=all-arch-no-native \
- && make -j $(nproc) \
- && make install
-
-
-# Install OpenMPI
-RUN git clone --recursive https://github.com/open-mpi/ompi.git -b ${OMPI_BRANCH} \
- && cd ompi \
- && ./autogen.pl \
- && mkdir build \
- && cd build \
- && ../configure --prefix=$OMPI_PATH --with-ucx=$UCX_PATH \
- --with-ucc=${UCC_PATH} \
- --enable-mca-no-build=btl-uct \
- --without-verbs \
- --with-pmix=internal \
- --enable-mpi \
- --enable-mpi-fortran=yes \
- --disable-man-pages \
- --disable-debug \
- && make -j $(nproc) \
- && make install
-
-# Adding OpenMPI, UCX, and UCC to Environment
-ENV PATH=$OMPI_PATH/bin:$UCX_PATH/bin:$UCC_PATH/bin:$PATH \
- LD_LIBRARY_PATH=$OMPI_PATH/lib:$UCX_PATH/lib:$UCC_PATH/lib:$LD_LIBRARY_PATH \
- LIBRARY_PATH=$OMPI_PATH/lib:$UCX_PATH/lib:$UCC_PATH/lib:$LIBRARY_PATH \
- C_INCLUDE_PATH=$OMPI_PATH/include:$UCX_PATH/include:$UCC_PATH/include:$C_INCLUDE_PATH \
- CPLUS_INCLUDE_PATH=$OMPI_PATH/include:$UCX_PATH/include:$UCC_PATH/include:$CPLUS_INCLUDE_PATH \
- PKG_CONFIG_PATH=$OMPI_PATH/lib/pkgconfig:$UCX_PATH/lib/pkgconfig/:$PKG_CONFIG_PATH \
- OMPI_ALLOW_RUN_AS_ROOT=1 \
+ ssh \
+ tar \
+ unzip \
+ vim \
+ wget \
+ xz-utils \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+ENV ROCM_PATH=${ROCM_PATH} \
+ PATH=${ROCM_PATH}/bin:/opt/cp2k/bin:${PATH} \
+ LD_LIBRARY_PATH=${ROCM_PATH}/lib:${ROCM_PATH}/lib64:${LD_LIBRARY_PATH:-}
+
+# Drop the shared build recipe into the image and run it. BUILD_ROOT lives
+# under /opt so the resulting Spack tree is self-contained and easy to find.
+WORKDIR /opt/cp2k-build
+COPY shared /opt/cp2k-build/shared
+
+RUN BUILD_ROOT=/opt/cp2k-build \
+ SPACK_BRANCH=${SPACK_BRANCH} \
+ SPACK_PACKAGES_TAG=${SPACK_PACKAGES_TAG} \
+ GCC_VERSION=${GCC_VERSION} \
+ CPU_ARCH=${CPU_ARCH} \
+ GPU_ARCH=${GPU_ARCH} \
+ ROCM_VERSION=${ROCM_VERSION} \
+ ROCM_PATH=${ROCM_PATH} \
+ BUILD_JOBS=${BUILD_JOBS} \
+ /opt/cp2k-build/shared/cp2k_build.sh \
+ && ln -sfn /opt/cp2k-build/cp2k /opt/cp2k
+
+# Runtime defaults that match the run scripts.
+ENV OMPI_ALLOW_RUN_AS_ROOT=1 \
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 \
- UCX_WARN_UNUSED_ENV_VARS=n
-
-# Install Additional Apps Below
-
-
-ARG CP2K_BRANCH="v2026.1"
-
-
-ENV LD_LIBRARY_PATH=$ROCM_PATH/lib/hipblas:$ROCM_PATH/lib/hipfft:$ROCM_PATH/lib/rocfft:$ROCM_PATH/lib/rocblas:$LD_LIBRARY_PATH \
- LIBRARY_PATH=$ROCM_PATH/lib/rocfft:$ROCM_PATH/lib/hipblas:$ROCM_PATH/lib/rocblas:$LIBRARY_PATH \
- C_INCLUDE_PATH=$ROCM_PATH/include/rocfft:$ROCM_PATH/include/hipblas:$ROCM_PATH/include/hipfft:$ROCM_PATH/include/rocblas:$C_INCLUDE_PATH \
- CPLUS_INCLUDE_PATH=$ROCM_PATH/include/rocfft:$ROCM_PATH/include/hipfft:$ROCM_PATH/include/hipblas:$ROCM_PATH/include/rocblas:$CPLUS_INCLUDE_PATH \
- CP2K_DIR=/opt/cp2k
-
-#SHELL [ "/bin/bash", "-c" ]
-
-WORKDIR /opt/
-
-# we do not need to clone cp2k but we still do it
-#RUN git clone https:://github.com/cp2k/cp2k.git
-
-# clone spack.
-RUN git clone https://github.com/spack/spack.git
-ENV PATH=$PATH:/opt/spack/bin
-RUN spack external find --all
-RUN gfortran --version
-RUN /opt/ompi/bin/mpif90 --version
-COPY ./cp2k_environment ./cp2k_environment
-COPY ./spack.sh ./spack.sh
-# compile cp2k and all its dependencies. See spack.yaml file the environment directory.
-# creates a link /opt/cp2k to avoid calling spack load cp2k which will not work as intended in the container
-
-RUN ./spack.sh
-# the entire configuration is treated externally using spack environments
-
-ENV PATH=$PATH:/opt/cp2k/bin:/scripts \
OMPI_MCA_pml=ucx \
- OMPI_MCA_pml_ucx_tls=any \
OMPI_MCA_osc=ucx \
- OMPI_MCA_btl=^vader,tcp,uct \
- OMPI_MCA_pml_ucx_devices=any \
- UCX_TLS=self,sm,tcp,rocm
+ OMPI_MCA_coll_ucc_enable=1 \
+ OMPI_MCA_coll_ucc_priority=100 \
+ UCX_TLS=self,sm,rocm_copy,rocm_ipc,ud_x \
+ UCX_HANDLE_ERRORS=bt \
+ UCX_MAX_RNDV_RAILS=1 \
+ HSA_ENABLE_SDMA=0 \
+ HSA_ENABLE_IPC_MODE_LEGACY=1 \
+ HIP_MEM_POOL_SUPPORT=1
+# Note: DBCSR_USE_ACC_G2G is not set image-wide. Per-benchmark launchers
+# (e.g. scripts/run_dft_nrep2.sh) set it explicitly when needed.
-# cp2k can be called with cp2k.psmp without without any spack knowledge
CMD ["/bin/bash"]
diff --git a/cp2k/docker/README.md b/cp2k/docker/README.md
index 848d45a..681925b 100644
--- a/cp2k/docker/README.md
+++ b/cp2k/docker/README.md
@@ -1,189 +1,125 @@
-# CP2K Container Build Instructions
+# CP2K — Container Build
-This document provides instructions on how to build CP2K into a Docker container using Spack for dependency management. The container is portable between environments and includes all CP2K dependencies built with ROCm support.
+This document describes how to build CP2K with ROCm support as a Docker
+container. The image is produced by [`../shared/cp2k_build.sh`](../shared/cp2k_build.sh)
+running inside a ROCm base image; the Dockerfile here is intentionally a
+thin layer over that script so the recipe is identical to the
+[`baremetal/`](../baremetal/) build.
-## Build System Requirements
+## Requirements
- Git
-- Docker (or Podman)
-- BuildKit (recommended for better caching)
+- Docker (or Podman) with BuildKit recommended
+- Internet access during the build (Spack and source tarballs)
+- ~50 GB free disk space (Spack build stage is large)
-## Overview
+Supported CPUs/GPUs/OS are in the
+[main README](../README.md#system-requirements).
-This Docker recipe uses **Spack** to build CP2K and all its dependencies. This is the **recommended build method from the CP2K developer community**, providing a robust and maintainable approach to building CP2K with all its scientific computing dependencies.
+## What the build does
-The build process:
-1. Sets up the base ROCm development environment
-2. Builds UCX, UCC, and OpenMPI with ROCm support
-3. Installs Spack package manager
-4. Uses a Spack environment (`cp2k_environment/spack.yaml`) to build CP2K and all dependencies
-5. Creates a symlink at `/opt/cp2k` for easy access to CP2K executables
+1. Starts from a ROCm base image (default: `rocm/dev-ubuntu-24.04:7.2-complete`).
+2. Installs the minimal system tooling Spack needs to bootstrap (no UCX,
+ UCC, OpenMPI, or GCC are pre-installed via apt — Spack builds them).
+3. COPYs `shared/` into the image and runs `shared/cp2k_build.sh`.
+4. Symlinks the resulting CP2K install at `/opt/cp2k`.
-## Inputs
+The complete build recipe (Spack version, GCC version, MPI stack,
+dependencies, gfx950 patch) lives in `shared/cp2k_build.sh` and is shared
+verbatim with the baremetal flow.
-### Build Arguments
+## Quick start
-Possible `build-arg` parameters for the Docker build command:
-
-- **IMAGE** (default: `rocm/dev-ubuntu-24.04:7.0-complete`)
- - Base container image with ROCm development tools
- - Must include ROCm 7.0+ support
-
-- **UCX_BRANCH** (default: `v1.19.0`)
- - UCX (Unified Communication X) version for MPI communication
-
-- **UCC_BRANCH** (default: `v1.5.1`)
- - UCC (Unified Collective Communication) version
-
-- **OMPI_BRANCH** (default: `v5.0.8`)
- - OpenMPI version
-
-- **AMDGPU_TARGETS** (default: `gfx908,gfx90a,gfx942`)
- - GPU architectures to target (comma-separated)
- - Common targets: `gfx908` (MI100), `gfx90a` (MI200), `gfx942` (MI300)
-
-- **CP2K_BRANCH** (default: `v2026.1`)
- - CP2K version to build (specified in `spack.yaml`)
-
-> **NOTE**
-> The GPU architecture targets are configured in the Spack environment file (`cp2k_environment/spack.yaml`) via the `amdgpu_target` variant. The default targets are set to `gfx942` (MI300).
-
-## Build Instructions
-
-### Quick Start
-
-Use the provided build script for convenience:
+Build from the repository root (the Dockerfile lives in `docker/` but the
+build context must be the repo root so `shared/` is available):
```bash
-cd /path/to/cp2k/docker
-./build_cp2k.sh --clean
+cd /path/to/cp2k-recipe
+./docker/build_cp2k.sh
```
-This will:
-- Clean up old containers/images
-- Build the CP2K Docker image
-- Save build logs to `build.log`
+That defaults to:
+- `gfx950` (MI350X) GPU target
+- `zen5` CPU microarch
+- ROCm `7.2.0`
+- `gcc@14.3.0`, `openmpi@5.0.10`, `ucx@1.20.0`, `ucc@1.7.0` — all built by
+ Spack
-### Manual Build
+## Configuration
-To build manually:
+The build wrapper forwards environment variables to the Dockerfile as
+`--build-arg`s. The shared build knobs (`GPU_ARCH`, `CPU_ARCH`,
+`ROCM_VERSION`, `ROCM_PATH`, `GCC_VERSION`, `SPACK_BRANCH`,
+`SPACK_PACKAGES_TAG`, `BUILD_JOBS`) and the validation disclaimer are in the
+[main README](../README.md#build-configuration). Docker-specific knobs:
-```bash
-cd /path/to/cp2k/docker
-docker build -t mycontainer/cp2k:latest .
-```
+| Variable | Default |
+|---|---|
+| `IMAGE_NAME` | `cp2k` |
+| `IMAGE_TAG` | `latest` |
+| `BASE_IMAGE` | `rocm/dev-ubuntu-24.04:7.2-complete` |
-> **Notes:**
-> - `mycontainer/cp2k:latest` will be the name of your local container
-> - The `.` at the end tells Docker where your build context is located
-> - Ensure you're in the `docker` directory (contains `Dockerfile`, `spack.sh`, and `cp2k_environment/`)
-
-### Custom Configuration
-
-To build with custom parameters:
+Example: build an MI300X / Zen3 image off a ROCm 7.0 base:
```bash
-docker build \
- -t mycontainer/cp2k:latest \
- --build-arg AMDGPU_TARGETS=gfx908,gfx90a \
- --build-arg IMAGE=rocm/dev-ubuntu-24.04:7.0-complete \
- .
+BASE_IMAGE=rocm/dev-ubuntu-24.04:7.0-complete \
+ GPU_ARCH=gfx942 \
+ CPU_ARCH=zen3 \
+ ROCM_VERSION=7.0.0 \
+ IMAGE_TAG=mi300x \
+ ./docker/build_cp2k.sh
```
-> **DISCLAIMER**: This Docker build has only been validated using the default values. Using a different base image or branch may result in build failures or poor performance.
+### Manual `docker build`
-### Using Build Cache
-
-For faster rebuilds after making changes:
+If you want to skip the wrapper:
```bash
-# Tag current image
-docker tag mycontainer/cp2k:latest mycontainer/cp2k:previous
-
-# Make your changes (edit spack.yaml, package.py, etc.)
-
-# Rebuild using cache
-./build_cp2k.sh --cache-from mycontainer/cp2k:previous
+cd /path/to/cp2k-recipe
+DOCKER_BUILDKIT=1 docker build \
+ -t cp2k:latest \
+ -f docker/Dockerfile \
+ --build-arg GPU_ARCH=gfx950 \
+ --build-arg CPU_ARCH=zen5 \
+ --build-arg ROCM_VERSION=7.2.0 \
+ .
```
-## Spack Environment Configuration
-
-The CP2K build is controlled by the Spack environment located in `cp2k_environment/`:
-
-- **`spack.yaml`**: Defines all package specifications, variants, and build options
-- **`repos/`**: Custom Spack package repositories (contains CP2K, DBCSR, libvdwxc packages)
-- **`config.yaml`**: Spack configuration settings
-
-### Key CP2K Variants
-
-The CP2K package is built with the following variants (see `spack.yaml`):
-- `+rocm`: ROCm GPU acceleration
-- `+cosma`: COSMA library for matrix operations
-- `+sirius`: SIRIUS library for electronic structure
-- `+spglib`: Space group library
-- `+hdf5`: HDF5 I/O support
-- `+mpi`: MPI parallelization
-- `+openmp`: OpenMP threading
-- `smm=libxsmm`: Small matrix multiplication via libxsmm
+The `.` at the end is critical — the build context must be the repo root
+so the `shared/` directory is available to `COPY`.
-### Modifying the Build
+### Build flags
-To change CP2K variants or dependencies:
+`build_cp2k.sh` accepts:
-1. Edit `cp2k_environment/spack.yaml`
-2. Modify the `cp2k@2026.1` spec line with desired variants
-3. Rebuild the container
+- `--clean` — remove old containers / images before building
+- `--no-cache` — bypass Docker cache
+- `--cache-from IMAGE` — use `IMAGE` as a cache source
-Example: To disable a feature, change `+feature` to `~feature` in the spec.
+> **Disclaimer**: This image has only been validated with the default
+> values. Different base images, GPU targets, or ROCm versions may cause
+> build failures or suboptimal performance.
-## Build Process Details
+## Running the container
-The Dockerfile follows these steps:
+The container exposes `cp2k.psmp` on `PATH` and bakes in sane OpenMPI/UCX
+runtime defaults (matching the run scripts). It needs the AMD KFD/DRI
+devices and `--ipc=host` for GPU IPC.
-1. **Base Image Setup**: Installs system packages and development tools
-2. **UCX/UCC/OpenMPI**: Builds communication libraries with ROCm support
-3. **Spack Installation**: Clones Spack from GitHub
-4. **Environment Setup**: Copies `cp2k_environment/` and `spack.sh` into container
-5. **Spack Build**: Runs `spack.sh` which:
- - Activates the Spack environment
- - Finds external packages (system-installed tools including GCC from the base image)
- - Concretizes the dependency graph
- - Installs all packages (including CP2K) with 16 parallel jobs
- - Creates symlink `/opt/cp2k` → Spack installation directory
-
-### Build Time
-
-Expected build times:
-- Base setup + UCX/UCC/OpenMPI: ~10-15 minutes
-- Spack dependency builds: ~20-30 minutes
-- CP2K compilation: ~5-10 minutes
-- **Total**: ~35-55 minutes (depending on system)
-
-## Run CP2K Container
-
-### Docker
-
-If you want access to any output files generated during the run, add `-v $(pwd):/tmp` before the container name.
-
-#### Docker Interactive
+### Interactive shell
```bash
-<<<<<<< cp2k_update
docker run --rm -it \
--device=/dev/kfd \
--device=/dev/dri \
--security-opt seccomp=unconfined \
--ipc=host \
-e PMIX_MCA_gds=^ds21 \
- -v $(pwd):/tmp \
- mycontainer/cp2k:latest \
- /bin/bash
-=======
-docker run --rm -it --device=/dev/kfd --device=/dev/dri --security-opt seccomp=unconfined --ipc=host -e PMIX_MCA_gds=^ds21 mycontainer/cp2k /bin/bash
->>>>>>> main
+ -v "$PWD":/workdir -w /workdir \
+ cp2k:latest /bin/bash
```
-#### Docker Single Command
+### One-off command
```bash
docker run --rm \
@@ -192,155 +128,139 @@ docker run --rm \
--security-opt seccomp=unconfined \
--ipc=host \
-e PMIX_MCA_gds=^ds21 \
- -v $(pwd):/tmp \
- mycontainer/cp2k:latest \
+ -v "$PWD":/workdir -w /workdir \
+ cp2k:latest \
bash -c "cp2k.psmp -i input.inp -o output.out"
```
-### CP2K Executables
-
-The container provides CP2K executables via the Spack environment:
+### Singularity / Apptainer
-- **`cp2k.psmp`**: Parallel SMP (Shared Memory Parallel) version
- - Built with MPI and OpenMP support
- - Includes ROCm GPU acceleration
- - Located at `/opt/cp2k/bin/cp2k.psmp` (also in PATH)
+Convert the local Docker image:
-The executable is accessible via:
-- Direct path: `/opt/cp2k/bin/cp2k.psmp`
-- PATH: `cp2k.psmp` (after sourcing Spack environment)
-- Symlink: `/opt/cp2k` → Spack installation directory
-
-### Running Benchmarks
+```bash
+singularity build cp2k.sif docker-daemon://cp2k:latest
+singularity shell --no-home --writable-tmpfs cp2k.sif
+```
-Example benchmark scripts are provided in `scripts/`:
+## Running benchmarks
-- **`run_dft_nrep2.sh`**: DFT benchmark with 16 MPI ranks
-- **`run_rpa32.sh`**: RPA benchmark with two stages (init + solver)
-- **`set_cpu_affinity.sh`** and **`set_gpu_affinity.sh`**: Affinity scripts that can be tuned for the system the benchmarks are run on
+The scripts in [`scripts/`](scripts/) mirror the corresponding files in
+[`baremetal/scripts/`](../baremetal/scripts/) — same filenames, same
+SBATCH header, same lowercase topology variables, same EXPNAME and output
+directory layout. The only difference is that the `mpirun` call is wrapped
+in `docker run` against the `cp2k` image. They mount the CP2K source
+benchmarks from the host (cloning them on first run if needed) and write
+outputs to `docker/outputs//...`.
-> **DISCLAIMER**: The affinity scripts (`set_cpu_affinity.sh` and `set_gpu_affinity.sh`) must be tuned according to your specific system configuration to achieve maximum performance. The default settings may not be optimal for all hardware configurations.
+| Script | Benchmark |
+|---|---|
+| `scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run` | `QS_DM_LS / H2O-dft-ls.NREP2` |
+| `scripts/cp2k_QS_mp2_rpa_32-H2O.run` | `QS_mp2_rpa / 32-H2O` (init + solver) |
-To run benchmarks:
+Both scripts double as SLURM batch jobs (just `sbatch` them on a system
+that allows running docker inside SLURM) and as plain interactive scripts
+(just `./` them) — the SBATCH directives are shell comments when run
+outside SLURM, and every `SLURM_*` variable has a sensible default.
-```bash
-<<<<<<< cp2k_update
-cd /path/to/cp2k/docker
-./scripts/run_dft_nrep2.sh
-=======
-docker run --rm --device=/dev/kfd --device=/dev/dri --security-opt seccomp=unconfined --ipc=host -e PMIX_MCA_gds=^ds21 mycontainer/cp2k bash -c ""
->>>>>>> main
-```
+The topology variables (`numa_per_node`, `gpus_per_node`, etc.), MPI/UCX
+defaults, figure of merit, and the `DBCSR_USE_ACC_G2G` option are shared
+across flavors and documented in the
+[main README](../README.md#running-cp2k-benchmarks). The docker launchers
+add one knob:
-These scripts handle:
-- CP2K repository cloning
-- CPU/GPU affinity setup
-- Output file management
+| Variable | Default |
+|---|---|
+| `CONTAINER_IMAGE` | `cp2k:latest` |
-### Singularity
+Set `numa_per_node` to your node's actual NUMA domain count (`numactl -H`).
-To build a Singularity image from the Docker image:
+Examples:
```bash
-singularity build cp2k.sif docker-daemon://mycontainer/cp2k:latest
-```
+# DFT, interactive
+./docker/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
-#### Singularity Interactive
+# DFT against a different image, smaller box
+CONTAINER_IMAGE=cp2k:mi300x SLURM_NTASKS=8 numa_per_node=4 gpus_per_node=4 \
+ ./docker/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
-```bash
-singularity shell --no-home --writable-tmpfs cp2k.sif
-```
+# RPA, interactive
+./docker/scripts/cp2k_QS_mp2_rpa_32-H2O.run
-#### Singularity Single Command
-
-```bash
-singularity run --no-home --writable-tmpfs cp2k.sif bash -c "cp2k.psmp -i input.inp -o output.out"
+# Either as a SLURM job (set numa_per_node to the node's NUMA count)
+sbatch --export=ALL,numa_per_node= ./docker/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+sbatch --export=ALL,numa_per_node= ./docker/scripts/cp2k_QS_mp2_rpa_32-H2O.run
```
-## Runtime Options
+Output goes under
+`docker/outputs///_N.n.t.g_/...`
+and each script prints the [figure of merit](../README.md#figure-of-merit)
+from the resulting `*.out`.
-### GPU-to-GPU Communication (g2g)
+The launchers internally:
+1. Clone CP2K source (for benchmark inputs) into `../cp2k_repo/` on first run.
+2. Run `docker run` with `--device=/dev/kfd --device=/dev/dri --ipc=host`,
+ bind-mounting the benchmark dir at `/benchmark` and the host output
+ directory at `/outputs`.
+3. Inside the container, source the Spack env, locate `cp2k.psmp` and
+ `close.sh`, then call `mpirun --map-by ppr:N:numa:PE=T close.sh cp2k.psmp ...`.
-To enable GPU-to-GPU communication in DBCSR, set the environment variable:
+## Runtime options
-```bash
-export DBCSR_USE_ACC_G2G=1
-```
+### GPU-to-GPU communication
-This can improve performance for multi-GPU runs. Example:
+The DFT launcher sets `DBCSR_USE_ACC_G2G=1`; it is not set image-wide. See
+[GPU-to-GPU communication](../README.md#gpu-to-gpu-communication) in the
+main README. To disable it for a comparison run:
```bash
-docker run --rm \
- --device=/dev/kfd \
- --device=/dev/dri \
- -e DBCSR_USE_ACC_G2G=1 \
- mycontainer/cp2k:latest \
- bash -c "mpirun -np 16 -x DBCSR_USE_ACC_G2G=1 cp2k.psmp -i input.inp"
+DBCSR_USE_ACC_G2G=0 ./docker/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
```
-## Troubleshooting
+### MPI / UCX
-### Build Failures
+The image bakes the same OpenMPI/UCX defaults listed in the
+[main README](../README.md#mpi--ucx-defaults). Override via `-e VAR=...` on
+`docker run`.
-If the build fails during Spack installation:
+## Troubleshooting
-1. Check `build.log` for detailed error messages
-2. Verify network connectivity (Spack downloads packages)
-3. Ensure sufficient disk space (~25GB+ required)
-4. Check that base image has ROCm support
+### Build fails
-### Missing Executables
+1. `cat docker/build.log` for the full Spack output.
+2. Make sure the build context is the repo root (`.`), not `docker/` —
+ `shared/` must be visible.
+3. Verify the base image has the matching ROCm version.
+4. Ensure ~50 GB free disk; Spack's build stage is large.
-If CP2K executable is not found:
+### `cp2k.psmp not found` inside the container
```bash
-# Inside container
-source /opt/spack/share/spack/setup-env.sh
-spack env activate /opt/cp2k_environment
+docker run --rm -it cp2k:latest bash
+source /opt/cp2k-build/spack_git/share/spack/setup-env.sh
+spack env activate cp2k
+spack load cp2k
which cp2k.psmp
```
-### GPU Issues
-
-If GPU is not detected:
-
-- Verify `/dev/kfd` and `/dev/dri` devices exist on host
-- Check ROCm installation in base image
-- Ensure GPU architecture matches `amdgpu_target` in `spack.yaml`
-
-## Licensing Information
-
-Your use of this application is subject to the terms of the applicable component-level license identified below. To the extent any subcomponent in this container requires an offer for corresponding source code, AMD hereby makes such an offer for corresponding source code form, which will be made available upon request. By accessing and using this application, you are agreeing to fully comply with the terms of this license. If you do not agree to the terms of this license, do not access or use this application.
+The image's `PATH` includes `/opt/cp2k/bin`, which symlinks to the Spack
+install prefix; this should normally just work.
-The application is provided in a container image format that includes the following separate and independent components:
+### GPU not detected
-| Package | License | URL |
-|---|---|---|
-| Ubuntu | Creative Commons CC-BY-SA Version 3.0 UK License | [Ubuntu Legal](https://ubuntu.com/legal) |
-| CMAKE | OSI-approved BSD-3 clause | [CMake License](https://cmake.org/licensing/) |
-| OpenMPI | BSD 3-Clause | [OpenMPI License](https://www-lb.open-mpi.org/community/license.php)
[OpenMPI Dependencies Licenses](https://docs.open-mpi.org/en/v5.0.x/license/index.html) |
-| OpenUCX | BSD 3-Clause | [OpenUCX License](https://openucx.org/license/) |
-| ROCm | Custom/MIT/Apache V2.0/UIUC OSL | [ROCm Licensing Terms](https://rocm.docs.amd.com/en/latest/about/license.html) |
-| CP2K | GNU GPL Version 2 | [CP2k](https://www.cp2k.org/)
[CP2K License](https://github.com/cp2k/cp2k/blob/master/LICENSE) |
-| Spack | Apache-2.0 OR MIT | [Spack License](https://github.com/spack/spack/blob/develop/LICENSE-APACHE) |
-| OpenBlas | BSD 3-Clause | [OpenBlas](https://www.openblas.net/)
[OpenBlas License](https://github.com/xianyi/OpenBLAS/blob/develop/LICENSE) |
-| COSMA | BSD 3-Clause | [COSMA License](https://github.com/eth-cscs/COSMA/blob/master/LICENSE) |
-| Libxsmm | BSD 3-Clause | [Libxsmm License](https://libxsmm.readthedocs.io/en/latest/LICENSE/) |
-| Libxc | MPL v2.0 | [Libxc License](https://github.com/ElectronicStructureLibrary/libxc) |
-| SpLA | BSD 3-Clause | [SpLA License](https://github.com/eth-cscs/spla/blob/master/LICENSE) |
-| DBCSR | GPL-2.0 | [DBCSR License](https://github.com/cp2k/dbcsr) |
-| SIRIUS | BSD 3-Clause | [SIRIUS License](https://github.com/electronic-structure/SIRIUS) |
+- Verify `/dev/kfd` and `/dev/dri` exist on the host.
+- `docker run --rm --device=/dev/kfd --device=/dev/dri cp2k:latest rocm-smi`
+- Confirm the `GPU_ARCH` baked into the image matches your hardware
+ (`gfx942` for MI300X, `gfx950` for MI350X, etc.).
-Additional third-party content in this container may be subject to additional licenses and restrictions. The components are licensed to you directly by the party that owns the content pursuant to the license terms included with such content and is not licensed to you by AMD. ALL LINKED THIRD-PARTY CONTENT IS MADE AVAILABLE BY AMD "AS IS" WITHOUT A WARRANTY OF ANY KIND. USE OF THE CONTAINER IS DONE AT YOUR SOLE DISCRETION AND UNDER NO CIRCUMSTANCES WILL AMD BE LIABLE TO YOU FOR ANY THIRD-PARTY CONTENT. YOU ASSUME ALL RISK AND ARE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY ARISE FROM YOUR USE OF THE CONTAINER.
+## Files in this directory
-## Disclaimer
-
-The information contained herein is for informational purposes only, and is subject to change without notice. In addition, any stated support is planned and is also subject to change. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein. No license, including implied or arising by estoppel, to any intellectual property rights is granted by this document. Terms and limitations applicable to the purchase or use of AMD's products are as set forth in a signed agreement between the parties or in AMD's Standard Terms and Conditions of Sale.
-
-## Notices and Attribution
-
-© 2022-26 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD Arrow logo, Instinct, Radeon Instinct, ROCm, and combinations thereof are trademarks of Advanced Micro Devices, Inc.
-
-Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries. Docker, Inc. and other parties may also have trademark rights in other terms used herein. Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
-
-All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes.
+```
+docker/
+├── Dockerfile # ROCm base + shared/cp2k_build.sh
+├── build_cp2k.sh # `docker build` wrapper
+└── scripts/
+ ├── _run_common.sh # docker run helpers (mirrors baremetal/scripts/_run_common.sh)
+ ├── cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+ └── cp2k_QS_mp2_rpa_32-H2O.run
+```
diff --git a/cp2k/docker/build_cp2k.sh b/cp2k/docker/build_cp2k.sh
index c008a5a..a81f7a7 100755
--- a/cp2k/docker/build_cp2k.sh
+++ b/cp2k/docker/build_cp2k.sh
@@ -1,174 +1,114 @@
#!/bin/bash
#
-# CP2K Docker Build Script
-# This script builds the CP2K Docker image with caching and image reuse support
+# Build the CP2K Docker image.
+#
+# The image is built from the repository root so that ./shared/ is part of
+# the build context (the Dockerfile COPYs shared/ into the image and runs
+# shared/cp2k_build.sh inside).
#
# Usage:
-# ./build_cp2k.sh [--clean] [--no-cache] [--cache-from IMAGE] [--dockerfile FILE]
+# ./build_cp2k.sh [--clean] [--no-cache] [--cache-from IMAGE]
#
-# Options:
-# --clean Clean up old containers and images before building
-# --no-cache Build without using Docker cache
-# --cache-from Use specified image as cache source
-# --dockerfile Use specified Dockerfile (default: Dockerfile)
+# Build target/version knobs are forwarded to the Dockerfile via build args
+# and default to an MI350X recipe (gfx950 / zen5 / ROCm 7.2). Override
+# them via environment variables before invoking this script:
#
+# GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 ./build_cp2k.sh
-set -e
+set -eu
+set -o pipefail
-# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
-# Ensure we're in the cp2k/docker directory
-cd "$SCRIPT_DIR"
+IMAGE_NAME="${IMAGE_NAME:-cp2k}"
+IMAGE_TAG="${IMAGE_TAG:-latest}"
+BASE_IMAGE="${BASE_IMAGE:-rocm/dev-ubuntu-24.04:7.2-complete}"
-# Verify we're in the right directory (cp2k/docker)
-if [ ! -f "Dockerfile" ] || [ ! -f "spack.sh" ] || [ ! -d "cp2k_environment" ]; then
- echo "Error: Required files not found. Please run this script from the cp2k/docker directory."
- echo "Current directory: $(pwd)"
- echo "Expected files: Dockerfile, spack.sh, cp2k_environment/"
- exit 1
-fi
+GPU_ARCH="${GPU_ARCH:-gfx950}"
+CPU_ARCH="${CPU_ARCH:-zen5}"
+ROCM_VERSION="${ROCM_VERSION:-7.2.0}"
+ROCM_PATH="${ROCM_PATH:-/opt/rocm-${ROCM_VERSION}}"
+GCC_VERSION="${GCC_VERSION:-14.3.0}"
+SPACK_BRANCH="${SPACK_BRANCH:-v1.1.1}"
+SPACK_PACKAGES_TAG="${SPACK_PACKAGES_TAG:-v2026.03.0}"
+BUILD_JOBS="${BUILD_JOBS:-32}"
-# Configuration
-IMAGE_NAME="cp2k"
-IMAGE_TAG="latest"
-BASE_IMAGE="rocm/dev-ubuntu-24.04:7.0-complete"
-CACHE_DIR="${SCRIPT_DIR}/cache"
-SPACK_CACHE_DIR="${CACHE_DIR}/spack"
BUILD_LOG="${SCRIPT_DIR}/build.log"
-DOCKERFILE="${SCRIPT_DIR}/Dockerfile"
-# Parse arguments
CLEAN=false
NO_CACHE=false
CACHE_FROM=""
while [[ $# -gt 0 ]]; do
case $1 in
- --clean)
- CLEAN=true
- shift
- ;;
- --no-cache)
- NO_CACHE=true
- shift
- ;;
- --cache-from)
- CACHE_FROM="$2"
- shift 2
- ;;
- --dockerfile)
- DOCKERFILE="$2"
- shift 2
+ --clean) CLEAN=true; shift ;;
+ --no-cache) NO_CACHE=true; shift ;;
+ --cache-from) CACHE_FROM="$2"; shift 2 ;;
+ --help|-h)
+ sed -n '2,/^set -eu/p' "$0" | sed 's/^# \{0,1\}//'
+ exit 0
;;
*)
- echo "Unknown option: $1"
- echo "Usage: $0 [--clean] [--no-cache] [--cache-from IMAGE] [--dockerfile FILE]"
- echo ""
- echo "Options:"
- echo " --clean Clean up old containers/images"
- echo " --no-cache Build without Docker cache"
- echo " --cache-from Use specified image as cache source"
- echo " --dockerfile Use specified Dockerfile (default: Dockerfile)"
+ echo "Unknown option: $1" >&2
+ echo "Usage: $0 [--clean] [--no-cache] [--cache-from IMAGE]" >&2
exit 1
;;
esac
done
-# Cleanup function
-cleanup() {
+if [ "${CLEAN}" = true ]; then
echo "=== Cleaning up old containers and images ==="
-
- # Stop and remove containers
- docker ps -a --filter "ancestor=${IMAGE_NAME}:${IMAGE_TAG}" --format "{{.ID}}" | xargs -r docker rm -f 2>/dev/null || true
-
- # Remove old images (keep the latest)
+ docker ps -a --filter "ancestor=${IMAGE_NAME}:${IMAGE_TAG}" --format "{{.ID}}" \
+ | xargs -r docker rm -f 2>/dev/null || true
OLD_IMAGES=$(docker images "${IMAGE_NAME}" --format "{{.ID}}" | tail -n +2)
- if [ -n "$OLD_IMAGES" ]; then
- echo "$OLD_IMAGES" | xargs -r docker rmi -f 2>/dev/null || true
+ if [ -n "${OLD_IMAGES}" ]; then
+ echo "${OLD_IMAGES}" | xargs -r docker rmi -f 2>/dev/null || true
fi
-
- echo "Cleanup complete"
-}
+fi
-# Create cache directories
-setup_cache() {
- echo "=== Setting up cache directories ==="
- mkdir -p "${SPACK_CACHE_DIR}"
- mkdir -p "${CACHE_DIR}/build"
- echo "Cache directory: ${CACHE_DIR}"
- echo "Spack cache: ${SPACK_CACHE_DIR}"
-}
+cat <&1 | tee "${BUILD_LOG}"; then
- echo ""
- echo "=== Build completed successfully at $(date) ==="
- docker images "${IMAGE_NAME}:${IMAGE_TAG}"
- return 0
- else
- echo ""
- echo "=== Build failed ==="
- echo "Check ${BUILD_LOG} for details"
- return 1
- fi
-}
+BUILD_ARGS=(
+ --tag "${IMAGE_NAME}:${IMAGE_TAG}"
+ --file "${SCRIPT_DIR}/Dockerfile"
+ --build-arg "IMAGE=${BASE_IMAGE}"
+ --build-arg "GPU_ARCH=${GPU_ARCH}"
+ --build-arg "CPU_ARCH=${CPU_ARCH}"
+ --build-arg "ROCM_VERSION=${ROCM_VERSION}"
+ --build-arg "ROCM_PATH=${ROCM_PATH}"
+ --build-arg "GCC_VERSION=${GCC_VERSION}"
+ --build-arg "SPACK_BRANCH=${SPACK_BRANCH}"
+ --build-arg "SPACK_PACKAGES_TAG=${SPACK_PACKAGES_TAG}"
+ --build-arg "BUILD_JOBS=${BUILD_JOBS}"
+)
+[ -n "${CACHE_FROM}" ] && BUILD_ARGS+=(--cache-from "${CACHE_FROM}")
+[ "${NO_CACHE}" = true ] && BUILD_ARGS+=(--no-cache)
-# Main execution
-main() {
- echo "=========================================="
- echo "CP2K Docker Build Script"
- echo "=========================================="
- echo ""
-
- if [ "$CLEAN" = true ]; then
- cleanup
- echo ""
- fi
-
- setup_cache
- echo ""
-
- build_image
-}
+export DOCKER_BUILDKIT=1
-# Run main function
-main "$@"
+echo "Starting build at $(date)"
+if docker build "${BUILD_ARGS[@]}" "${REPO_ROOT}" 2>&1 | tee "${BUILD_LOG}"; then
+ echo
+ echo "=== Build completed at $(date) ==="
+ docker images "${IMAGE_NAME}:${IMAGE_TAG}"
+else
+ echo
+ echo "=== Build failed; see ${BUILD_LOG} ===" >&2
+ exit 1
+fi
diff --git a/cp2k/docker/cp2k_environment/config.yaml b/cp2k/docker/cp2k_environment/config.yaml
deleted file mode 100644
index e4ffea8..0000000
--- a/cp2k/docker/cp2k_environment/config.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-config:
- # This is the path to the root of the Spack install tree.
- # You can use $spack here to refer to the root of the spack instance.
- install_tree:
- root: /opt/cp2k-dist
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_2022.x.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_2022.x.patch
deleted file mode 100644
index ecd3db9..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_2022.x.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff -Naru a/src/qs_kpp1_env_methods.F b/src/qs_kpp1_env_methods.F
---- a/src/qs_kpp1_env_methods.F 2022-10-03 01:14:25.720416300 +0530
-+++ b/src/qs_kpp1_env_methods.F 2023-06-14 02:33:05.205287205 +0530
-@@ -214,7 +214,6 @@
- output_unit
- LOGICAL :: gapw, gapw_xc, lsd, my_calc_forces
- REAL(KIND=dp) :: alpha, energy_hartree, energy_hartree_1c
-- REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: vxg
- TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
- TYPE(cp_logger_type), POINTER :: logger
- TYPE(cp_para_env_type), POINTER :: para_env
-@@ -373,7 +372,8 @@
-
- CALL xc_calc_2nd_deriv(v_xc, v_xc_tau, p_env%kpp1_env%deriv_set, p_env%kpp1_env%rho_set, &
- rho1_r_pw, rho1_g_pw, tau1_r_pw, auxbas_pw_pool, xc_section, .FALSE., &
-- NULL(vxg), lsd_singlets, do_excitations, do_triplet, do_tddft, &
-+ lsd_singlets=lsd_singlets, do_excitations=do_excitations, &
-+ do_triplet=do_triplet, do_tddft=do_tddft, &
- compute_virial=calc_virial, virial_xc=virial)
-
- DO ispin = 1, nspins
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_9.1.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_9.1.patch
deleted file mode 100644
index 7f580a0..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/backport_avoid_null_9.1.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff -Naru a/src/qs_kpp1_env_methods.F b/src/qs_kpp1_env_methods.F
---- a/src/qs_kpp1_env_methods.F 2021-11-20 14:35:36.103103400 +0530
-+++ b/src/qs_kpp1_env_methods.F 2023-06-14 12:00:52.350584708 +0530
-@@ -220,7 +220,6 @@
- output_unit
- LOGICAL :: gapw, gapw_xc, lsd, my_calc_forces
- REAL(KIND=dp) :: alpha, energy_hartree, energy_hartree_1c
-- REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: vxg
- TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
- TYPE(cp_logger_type), POINTER :: logger
- TYPE(cp_para_env_type), POINTER :: para_env
-@@ -361,7 +360,8 @@
-
- CALL xc_calc_2nd_deriv(v_xc, p_env%kpp1_env%deriv_set, p_env%kpp1_env%rho_set, &
- rho1_r_pw, rho1_g_pw, auxbas_pw_pool, xc_section, .FALSE., &
-- NULL(vxg), lsd_singlets, do_excitations, do_triplet, do_tddft, &
-+ lsd_singlets=lsd_singlets, do_excitations=do_excitations, &
-+ do_triplet=do_triplet, do_tddft=do_tddft, &
- compute_virial=calc_virial, virial_xc=virial)
-
- DO ispin = 1, nspins
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-fixes-2023.2.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-fixes-2023.2.patch
deleted file mode 100644
index 985edad..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-fixes-2023.2.patch
+++ /dev/null
@@ -1,714 +0,0 @@
-From b75eb217115820059aba26d1ff1a8657e3841e7d Mon Sep 17 00:00:00 2001
-From: Mathieu Taillefumier
-Date: Mon, 23 Oct 2023 15:50:44 +0200
-Subject: [PATCH] cmake-fixes-2023.2
-
----
- CMakeLists.txt | 63 +++++++-----
- cmake/FindBlas.cmake | 174 +++++++++++++++++-----------------
- cmake/FindLapack.cmake | 47 ++++-----
- cmake/cp2k.pc.in | 19 ----
- cmake/cp2kConfig.cmake.in | 195 ++++++++++++++++++++------------------
- cmake/libcp2k.pc.in | 11 +++
- src/CMakeLists.txt | 18 ++--
- 7 files changed, 276 insertions(+), 251 deletions(-)
- delete mode 100644 cmake/cp2k.pc.in
- create mode 100644 cmake/libcp2k.pc.in
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 3f81c7b52..f2d85d033 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -49,7 +49,8 @@ if(NOT DEFINED CMAKE_CUDA_STANDARD)
- endif()
-
- # set language and standard
--set(CMAKE_CXX_STANDARD 11)
-+set(CMAKE_CXX_STANDARD 14)
-+set(CMAKE_C_STANDARD 11)
-
- find_package(PkgConfig)
-
-@@ -108,6 +109,10 @@ option(CP2K_USE_LIBXSMM "Use libxsmm for small gemms (supports x86 platforms)"
- OFF)
- option(CP2K_BUILD_DBCSR "Duild dbcsr at the same time than cp2k." OFF)
- option(BUILD_SHARED_LIBS "Build cp2k shared library" ON)
-+option(
-+ CP2K_USE_FFTW3_WITH_MKL
-+ "If set to ON use the original implementation of fftw3 instead of the MKL implementation."
-+ OFF)
-
- cmake_dependent_option(CP2K_ENABLE_ELPA_OPENMP_SUPPORT
- "Enable elpa openmp support" ON "CP2K_USE_ELPA" OFF)
-@@ -115,8 +120,8 @@ cmake_dependent_option(CP2K_ENABLE_FFTW3_OPENMP_SUPPORT
- "Enable FFTW openmp support" ON "CP2K_USE_FFTW3" OFF)
- cmake_dependent_option(CP2K_ENABLE_FFTW3_THREADS_SUPPORT
- "Enable FFTW THREADS support" OFF "CP2K_USE_FFTW3" OFF)
--cmake_dependent_option(CP2K_ENABLE_F08_MPI "Enable MPI Fortran 2008 interface"
-- OFF "CP2K_USE_MPI" OFF)
-+cmake_dependent_option(CP2K_USE_MPI_F08 "Enable MPI Fortran 2008 interface" OFF
-+ "CP2K_USE_MPI" OFF)
-
- cmake_dependent_option(
- DBCSR_USE_ACCEL
-@@ -527,7 +532,7 @@ if(CP2K_USE_ACCEL MATCHES "CUDA")
- endif()
-
- set(CP2K_USE_CUDA ON)
-- message(STATUS ``"-- CUDA compiler and libraries found")
-+ message(STATUS "-- CUDA compiler and libraries found")
- elseif(CP2K_USE_ACCEL MATCHES "HIP")
- enable_language(HIP)
- # Find hip
-@@ -620,27 +625,36 @@ endif()
-
- # FFTW3
-
-+set(CP2K_USE_FFTW3_ OFF)
- if(CP2K_USE_FFTW3)
-- find_package(Fftw REQUIRED)
-- if(CP2K_ENABLE_FFTW3_THREADS_SUPPORT AND CP2K_ENABLE_FFTW3_OPENMP_SUPPORT)
-- message(
-- FATAL_ERROR
-- "Fftw3 threads and openmp supports can not be used at the same time")
-- endif()
-+ if(CP2K_USE_FFTW3_WITH_MKL OR NOT CP2K_BLAS_VENDOR MATCHES "MKL")
-+ find_package(Fftw REQUIRED)
-+ if(CP2K_ENABLE_FFTW3_THREADS_SUPPORT AND CP2K_ENABLE_FFTW3_OPENMP_SUPPORT)
-+ message(
-+ FATAL_ERROR
-+ "Fftw3 threads and openmp supports can not be used at the same time")
-+ endif()
-
-- if((CP2K_ENABLE_FFTW3_THREADS_SUPPORT) AND (NOT TARGET
-- CP2K::FFTW3::fftw3_threads))
-- message(
-- FATAL_ERROR
-- "fftw3 was compiled without multithreading support (--enable-threads option in fftw build system)."
-- )
-- endif()
-+ if((CP2K_ENABLE_FFTW3_THREADS_SUPPORT) AND (NOT TARGET
-+ CP2K::FFTW3::fftw3_threads))
-+ message(
-+ FATAL_ERROR
-+ "fftw3 was compiled without multithreading support (--enable-threads option in fftw build system)."
-+ )
-+ endif()
-
-- if((CP2K_ENABLE_FFTW3_OPENMP_SUPPORT) AND (NOT TARGET CP2K::FFTW3::fftw3_omp))
-- message(
-- FATAL_ERROR
-- "fftw3 was compiled without openmp support (--enable-openmp option in fftw build system)."
-- )
-+ if((CP2K_ENABLE_FFTW3_OPENMP_SUPPORT) AND (NOT TARGET CP2K::FFTW3::fftw3_omp
-+ ))
-+ message(
-+ FATAL_ERROR
-+ "fftw3 was compiled without openmp support (--enable-openmp option in fftw build system)."
-+ )
-+ endif()
-+ # we use this variable later on to include the fftw target whenever mkl is
-+ # found or not
-+ set(CP2K_USE_FFTW3_ ON)
-+ else()
-+ message("-- Using the MKL implementation of FFTW3.")
- endif()
- endif()
-
-@@ -748,7 +762,7 @@ add_subdirectory(src)
- include(GNUInstallDirs)
-
- get_target_property(CP2K_LIBS cp2k_link_libs INTERFACE_LINK_LIBRARIES)
--configure_file(cmake/cp2k.pc.in cp2k.pc @ONLY)
-+configure_file(cmake/libcp2k.pc.in libcp2k.pc @ONLY)
-
- message(
- STATUS "--------------------------------------------------------------------")
-@@ -1039,6 +1053,9 @@ install(FILES "${PROJECT_BINARY_DIR}/cp2kConfig.cmake"
- "${PROJECT_BINARY_DIR}/cp2kConfigVersion.cmake"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cp2k")
-
-+install(FILES "${PROJECT_BINARY_DIR}/libcp2k.pc"
-+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
-+
- install(
- DIRECTORY "${PROJECT_SOURCE_DIR}/cmake"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cp2k"
-diff --git a/cmake/FindBlas.cmake b/cmake/FindBlas.cmake
-index 6e5fb7824..335cbd964 100644
---- a/cmake/FindBlas.cmake
-+++ b/cmake/FindBlas.cmake
-@@ -15,104 +15,108 @@ if(NOT
- OR CMAKE_Fortran_COMPILER_LOADED))
- message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
- endif()
-+if(NOT CP2K_CONFIG_PACKAGE)
-+ set(CP2K_BLAS_VENDOR_LIST
-+ "auto"
-+ "MKL"
-+ "OpenBLAS"
-+ "SCI"
-+ "GenericBLAS"
-+ "Armpl"
-+ "FlexiBLAS"
-+ "Atlas"
-+ "NVHPCBlas"
-+ "CUSTOM")
-+
-+ set(__BLAS_VENDOR_LIST ${CP2K_BLAS_VENDOR_LIST})
-+ list(REMOVE_ITEM __BLAS_VENDOR_LIST "auto")
-+ list(REMOVE_ITEM __BLAS_VENDOR_LIST "CUSTOM")
-+
-+ # set(CP2K_BLAS_VENDOR "auto" CACHE STRING "Blas library for computations on
-+ # host")
-+ set_property(CACHE CP2K_BLAS_VENDOR PROPERTY STRINGS ${CP2K_BLAS_VENDOR_LIST})
-+
-+ if(NOT ${CP2K_BLAS_VENDOR} IN_LIST CP2K_BLAS_VENDOR_LIST)
-+ message(FATAL_ERROR "Invalid Host BLAS backend")
-+ endif()
-
--set(CP2K_BLAS_VENDOR_LIST
-- "auto"
-- "MKL"
-- "OpenBLAS"
-- "SCI"
-- "GenericBLAS"
-- "Armpl"
-- "FlexiBLAS"
-- "Atlas"
-- "NVHPCBlas"
-- "CUSTOM")
--
--set(__BLAS_VENDOR_LIST ${CP2K_BLAS_VENDOR_LIST})
--list(REMOVE_ITEM __BLAS_VENDOR_LIST "auto")
--list(REMOVE_ITEM __BLAS_VENDOR_LIST "CUSTOM")
--
--# set(CP2K_BLAS_VENDOR "auto" CACHE STRING "Blas library for computations on
--# host")
--set_property(CACHE CP2K_BLAS_VENDOR PROPERTY STRINGS ${CP2K_BLAS_VENDOR_LIST})
--
--if(NOT ${CP2K_BLAS_VENDOR} IN_LIST CP2K_BLAS_VENDOR_LIST)
-- message(FATAL_ERROR "Invalid Host BLAS backend")
--endif()
--
--set(CP2K_BLAS_THREAD_LIST "sequential" "thread" "gnu-thread" "intel-thread"
-- "tbb-thread" "openmp")
--
--set(CP2K_BLAS_THREADING
-- "sequential"
-- CACHE STRING "threaded blas library")
--set_property(CACHE CP2K_BLAS_THREADING PROPERTY STRINGS
-- ${CP2K_BLAS_THREAD_LIST})
--
--if(NOT ${CP2K_BLAS_THREADING} IN_LIST CP2K_BLAS_THREAD_LIST)
-- message(FATAL_ERROR "Invalid threaded BLAS backend")
--endif()
-+ set(CP2K_BLAS_THREAD_LIST "sequential" "thread" "gnu-thread" "intel-thread"
-+ "tbb-thread" "openmp")
-
--set(CP2K_BLAS_INTERFACE_BITS_LIST "32bits" "64bits")
--set(CP2K_BLAS_INTERFACE
-- "32bits"
-- CACHE STRING
-- "32 bits integers are used for indices, matrices and vectors sizes")
--set_property(CACHE CP2K_BLAS_INTERFACE
-- PROPERTY STRINGS ${CP2K_BLAS_INTERFACE_BITS_LIST})
--
--if(NOT ${CP2K_BLAS_INTERFACE} IN_LIST CP2K_BLAS_INTERFACE_BITS_LIST)
-- message(
-- FATAL_ERROR
-- "Invalid parameters. Blas and lapack can exist in two flavors 32 or 64 bits interfaces (relevant mostly for mkl)"
-- )
--endif()
-+ set(CP2K_BLAS_THREADING
-+ "sequential"
-+ CACHE STRING "threaded blas library")
-+ set_property(CACHE CP2K_BLAS_THREADING PROPERTY STRINGS
-+ ${CP2K_BLAS_THREAD_LIST})
-
--set(CP2K_BLAS_FOUND FALSE)
-+ if(NOT ${CP2K_BLAS_THREADING} IN_LIST CP2K_BLAS_THREAD_LIST)
-+ message(FATAL_ERROR "Invalid threaded BLAS backend")
-+ endif()
-
--# first check for a specific implementation if requested
-+ set(CP2K_BLAS_INTERFACE_BITS_LIST "32bits" "64bits")
-+ set(CP2K_BLAS_INTERFACE
-+ "32bits"
-+ CACHE STRING
-+ "32 bits integers are used for indices, matrices and vectors sizes")
-+ set_property(CACHE CP2K_BLAS_INTERFACE
-+ PROPERTY STRINGS ${CP2K_BLAS_INTERFACE_BITS_LIST})
-
--if(NOT CP2K_BLAS_VENDOR MATCHES "auto|CUSTOM")
-- find_package(${CP2K_BLAS_VENDOR} REQUIRED)
-- if(TARGET CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas)
-- get_target_property(
-- CP2K_BLAS_INCLUDE_DIRS CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas
-- INTERFACE_INCLUDE_DIRECTORIES)
-- get_target_property(
-- CP2K_BLAS_LINK_LIBRARIES CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas
-- INTERFACE_LINK_LIBRARIES)
-- set(CP2K_BLAS_FOUND TRUE)
-- endif()
--else()
-- if(CP2K_BLAS_VENDOR MATCHES "CUSTOM" AND NOT DEFINED CP2K_BLAS_LINK_LIBRARIES)
-+ if(NOT ${CP2K_BLAS_INTERFACE} IN_LIST CP2K_BLAS_INTERFACE_BITS_LIST)
- message(
- FATAL_ERROR
-- "Setting CP2K_BLAS_VENDOR=CUSTOM imply setting CP2K_BLAS_LINK_LIBRARIES\n and CP2K_LAPACK_LINK_LIBRARIES to the right libraries. See the README_cmake.md for more details"
-+ "Invalid parameters. Blas and lapack can exist in two flavors 32 or 64 bits interfaces (relevant mostly for mkl)"
- )
- endif()
-
-- if(DEFINED CP2K_BLAS_LINK_LIBRARIES)
-- set(CP2K_BLAS_FOUND TRUE)
-+ set(CP2K_BLAS_FOUND FALSE)
-+
-+ # first check for a specific implementation if requested
-+
-+ if(NOT CP2K_BLAS_VENDOR MATCHES "auto|CUSTOM")
-+ find_package(${CP2K_BLAS_VENDOR} REQUIRED)
-+ if(TARGET CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas)
-+ get_target_property(
-+ CP2K_BLAS_INCLUDE_DIRS CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas
-+ INTERFACE_INCLUDE_DIRECTORIES)
-+ get_target_property(
-+ CP2K_BLAS_LINK_LIBRARIES CP2K::BLAS::${CP2K_BLAS_VENDOR}::blas
-+ INTERFACE_LINK_LIBRARIES)
-+ set(CP2K_BLAS_FOUND TRUE)
-+ endif()
- else()
-- # search for any blas implementation and exit immediately if one is found.
-- # we could also give a full list of found implementation and let the user
-- # choose which implementation to use
-- foreach(_libs ${__BLAS_VENDOR_LIST})
-- # I exclude the first item of the list
-- find_package(${_libs})
-- if(TARGET CP2K::BLAS::${_libs}::blas)
-- get_target_property(CP2K_BLAS_INCLUDE_DIRS CP2K::BLAS::${_libs}::blas
-- INTERFACE_INCLUDE_DIRECTORIES)
-- get_target_property(CP2K_BLAS_LINK_LIBRARIES CP2K::BLAS::${_libs}::blas
-- INTERFACE_LINK_LIBRARIES)
-- set(CP2K_BLAS_VENDOR "${_libs}")
-- set(CP2K_BLAS_FOUND TRUE)
-- break()
-- endif()
-- endforeach()
-+ if(CP2K_BLAS_VENDOR MATCHES "CUSTOM" AND NOT DEFINED
-+ CP2K_BLAS_LINK_LIBRARIES)
-+ message(
-+ FATAL_ERROR
-+ "Setting CP2K_BLAS_VENDOR=CUSTOM imply setting CP2K_BLAS_LINK_LIBRARIES\n and CP2K_LAPACK_LINK_LIBRARIES to the right libraries. See the README_cmake.md for more details"
-+ )
-+ endif()
-+
-+ if(DEFINED CP2K_BLAS_LINK_LIBRARIES)
-+ set(CP2K_BLAS_FOUND TRUE)
-+ else()
-+ # search for any blas implementation and exit immediately if one is found.
-+ # we could also give a full list of found implementation and let the user
-+ # choose which implementation to use
-+ foreach(_libs ${__BLAS_VENDOR_LIST})
-+ # I exclude the first item of the list
-+ find_package(${_libs})
-+ if(TARGET CP2K::BLAS::${_libs}::blas)
-+ get_target_property(CP2K_BLAS_INCLUDE_DIRS CP2K::BLAS::${_libs}::blas
-+ INTERFACE_INCLUDE_DIRECTORIES)
-+ get_target_property(
-+ CP2K_BLAS_LINK_LIBRARIES CP2K::BLAS::${_libs}::blas
-+ INTERFACE_LINK_LIBRARIES)
-+ set(CP2K_BLAS_VENDOR "${_libs}")
-+ set(CP2K_BLAS_FOUND TRUE)
-+ break()
-+ endif()
-+ endforeach()
-+ endif()
- endif()
-+else()
-+ set(CP2K_BLAS_FOUND ON)
- endif()
--
- # we exclude the CP2K_BLAS_INCLUDE_DIRS from the list of mandatory variables as
- # having the fortran interface is usually enough. C, C++ and others languages
- # might require this information though
-diff --git a/cmake/FindLapack.cmake b/cmake/FindLapack.cmake
-index 966e0d78d..77a1e0425 100644
---- a/cmake/FindLapack.cmake
-+++ b/cmake/FindLapack.cmake
-@@ -20,33 +20,34 @@ include(FindPackageHandleStandardArgs)
- find_package(PkgConfig)
- find_package(Blas REQUIRED)
-
--if(CP2K_BLAS_FOUND)
-- # LAPACK in the Intel MKL 10+ library?
-- if(CP2K_BLAS_VENDOR MATCHES "MKL|OpenBLAS|Armpl|SCI|FlexiBLAS|NVHPC")
-- # we just need to create the interface that's all
-- set(CP2K_LAPACK_FOUND TRUE)
-- get_target_property(CP2K_LAPACK_INCLUDE_DIRS CP2K::BLAS::blas
-- INTERFACE_INCLUDE_DIRECTORIES)
-- get_target_property(CP2K_LAPACK_LINK_LIBRARIES CP2K::BLAS::blas
-- INTERFACE_LINK_LIBRARIES)
-- else()
-- # we might get lucky to find a pkgconfig package for lapack (fedora provides
-- # one for instance)
-- if(PKG_CONFIG_FOUND)
-- pkg_check_modules(CP2K_LAPACK lapack)
-- endif()
-+if(NOT CP2K_CONFIG_PACKAGE)
-+ if(CP2K_BLAS_FOUND)
-+ # LAPACK in the Intel MKL 10+ library?
-+ if(CP2K_BLAS_VENDOR MATCHES "MKL|OpenBLAS|Armpl|SCI|FlexiBLAS|NVHPC")
-+ # we just need to create the interface that's all
-+ set(CP2K_LAPACK_FOUND TRUE)
-+ get_target_property(CP2K_LAPACK_INCLUDE_DIRS CP2K::BLAS::blas
-+ INTERFACE_INCLUDE_DIRECTORIES)
-+ get_target_property(CP2K_LAPACK_LINK_LIBRARIES CP2K::BLAS::blas
-+ INTERFACE_LINK_LIBRARIES)
-+ else()
-+ # we might get lucky to find a pkgconfig package for lapack (fedora
-+ # provides one for instance)
-+ if(PKG_CONFIG_FOUND)
-+ pkg_check_modules(CP2K_LAPACK lapack)
-+ endif()
-
-- if(NOT CP2K_LAPACK_FOUND)
-- find_library(
-- CP2K_LAPACK_LINK_LIBRARIES
-- NAMES "lapack" "lapack64"
-- PATH_SUFFIXES "openblas" "openblas64" "openblas-pthread"
-- "openblas-openmp" "lib" "lib64"
-- NO_DEFAULT_PATH)
-+ if(NOT CP2K_LAPACK_FOUND)
-+ find_library(
-+ CP2K_LAPACK_LINK_LIBRARIES
-+ NAMES "lapack" "lapack64"
-+ PATH_SUFFIXES "openblas" "openblas64" "openblas-pthread"
-+ "openblas-openmp" "lib" "lib64"
-+ NO_DEFAULT_PATH)
-+ endif()
- endif()
- endif()
- endif()
--
- # check if found
- find_package_handle_standard_args(Lapack
- REQUIRED_VARS CP2K_LAPACK_LINK_LIBRARIES)
-diff --git a/cmake/cp2k.pc.in b/cmake/cp2k.pc.in
-deleted file mode 100644
-index 5b4a09566..000000000
---- a/cmake/cp2k.pc.in
-+++ /dev/null
-@@ -1,19 +0,0 @@
--# this template is filled-in by CMake `configure_file(... @ONLY)`
--# the `@....@` are filled in by CMake configure_file(),
--# from variables set in your CMakeLists.txt or by CMake itself
--#
--# Good tutoral for understanding .pc files:
--# https://people.freedesktop.org/~dbn/pkg-config-guide.html
--
--prefix="@CMAKE_INSTALL_PREFIX@"
--exec_prefix="${prefix}"
--libdir="${prefix}/lib"
--includedir="${prefix}/include"
--
--Name: @PROJECT_NAME@
--Description: @CMAKE_PROJECT_DESCRIPTION@
--URL: @CMAKE_PROJECT_HOMEPAGE_URL@
--Version: @PROJECT_VERSION@
--Cflags: -I"${includedir}"
--Libs: -L"${libdir}" -lcp2k -lcp2k_dbm -lcp2k_grid -lcp2k_offload
--#Libs.private: -L"${libdir}" @CP2K_LIBS@
-\ No newline at end of file
-diff --git a/cmake/cp2kConfig.cmake.in b/cmake/cp2kConfig.cmake.in
-index a3acd4744..1c310e19b 100644
---- a/cmake/cp2kConfig.cmake.in
-+++ b/cmake/cp2kConfig.cmake.in
-@@ -5,112 +5,121 @@
- #! SPDX-License-Identifier: GPL-2.0-or-later !
- #!-------------------------------------------------------------------------------------------------!
-
--
- cmake_minimum_required(VERSION 3.22)
-+include(CMakeFindDependencyMacro)
-+
-+if(NOT TARGET cp2k::cp2k)
-+ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules"
-+ ${CMAKE_MODULE_PATH})
-+
-+ # store CXX compiler id. Used in MKL package.
-+ set(CP2K_CXX_COMPILER_ID @CMAKE_CXX_COMPILER_ID@)
-+ if(NOT ${CMAKE_CXX_COMPILER_ID})
-+ set(CMAKE_CXX_COMPILER_ID ${CP2K_CXX_COMPILER_ID})
-+ endif()
-+
-+ set(CP2K_BLAS_VENDOR @CP2K_BLAS_VENDOR@)
-+ set(CP2K_SCALAPACK_VENDOR @CP2K_SCALAPACK_VENDOR@)
-+ set(CP2K_BLAS_LINK_LIBRARIES @CP2K_BLAS_LINK_LIBRARIES@)
-+ set(CP2K_LAPACK_LINK_LIBRARIES @CP2K_LAPACK_LINK_LIBRARIES@)
-+ set(CP2K_SCALAPACK_LINK_LIBRARIES @CP2K_SCALAPACK_LINK_LIBRARIES@)
-+
-+ set(CP2K_CONFIG_PACKAGE ON)
-+ find_dependency(Lapack REQUIRED)
-+
-+ # define lapack and blas TARGETS
-+
-+ if(@CP2K_USE_MPI@)
-+ find_dependency(SCALAPACK REQUIRED)
-+ endif()
-+ unset(CP2K_CONFIG_PACKAGE)
-+
-+ set(cp2k_VERSION @cp2k_VERSION@)
-+
-+ find_dependency(DBCSR 2.5 REQUIRED)
-+
-+ if(@CP2K_USE_LIBXSMM@)
-+ find_dependency(LibXSMM REQUIRED)
-+ endif()
-+
-+ if(@CP2K_USE_HIP@)
-+ # Find hip
-+ find_dependency(hipfft REQUIRED IMPORTED CONFIG)
-+ find_dependency(hipblas REQUIRED IMPORTED CONFIG)
-+ endif()
-+
-+ if(@CP2K_USE_CUDA@)
-+ find_dependency(CUDAToolkit REQUIRED)
-+ endif()
-+ if(@CP2K_USE_ELPA@)
-+ find_dependency(Elpa REQUIRED)
-+ endif()
-+
-+ if(@CP2K_USE_LIBXC@)
-+ find_dependency(LibXC 6 REQUIRED EXACT)
-+ endif()
-+
-+ if(@CP2K_USE_COSMA@)
-+ find_dependency(cosma REQUIRED)
-+ endif()
-+
-+ if(@CP2K_USE_MPI@)
-+ find_dependency(MPI REQUIRED)
-+ endif()
-+
-+ if(@CP2K_USE_FFTW3@ OR @CP2K_USE_FFTW3_WITH_MKL@)
-+ find_dependency(Fftw REQUIRED)
-+ endif()
-+
-+ # QUIP
-+ if(@CP2K_USE_QUIP@)
-+ find_dependency(Quip REQUIRED)
-+ endif()
-
--# store CXX compiler id. Used in MKL package.
--set(SIRIUS_CXX_COMPILER_ID @CMAKE_CXX_COMPILER_ID@)
--if(NOT ${CMAKE_CXX_COMPILER_ID})
-- set(CMAKE_CXX_COMPILER_ID ${SIRIUS_CXX_COMPILER_ID})
--endif()
--
--set(CP2K_BLAS_VENDOR @CP2K_BLAS_VENDOR@)
--set(CP2K_SCALAPACK_VENDOR @CP2K_SCALAPACK_VENDOR@)
--
--if (@CP2K_BLAS_VENDOR@ MATCHES "CUSTOM")
-- set(CP2K_BLAS_LINK_LIBRARIES @CP2K_BLAS_LINK_LIBRARIES@)
-- set(CP2K_LAPACK_LINK_LIBRARIES @CP2K_LAPACK_LINK_LIBRARIES@)
--endif()
--
--if (@CP2K_SCALAPACK_VENDOR@ MATCHES "CUSTOM")
-- set(CP2K_SCALAPACK_LINK_LIBRARIES @CP2K_SCALAPACK_LINK_LIBRARIES@)
--endif()
--
--find_package(Lapack REQUIRED)
--find_package(DBCSR 2.4 REQUIRED)
--
--if(@CP2K_USE_LIBXSMM@
-- find_package(LibXSMM REQUIRED)
--endif()
--
--if (@@CP2K_USE_HIP@)
-- # Find hip
-- find_package(hipfft REQUIRED IMPORTED CONFIG)
-- find_package(hipblas REQUIRED IMPORTED CONFIG)
--endif()
--
--if (@@CP2K_USE_CUDA@)
-- find_package(CUDAToolkit REQUIRED)
--endif()
--if(@CP2K_USE_ELPA@)
-- find_package(Elpa REQUIRED)
--endif()
--
--if(@CP2K_USE_LIBXC@)
-- find_package(LibXC 6 REQUIRED EXACT)
--endif()
--
--if(@CP2K_USE_COSMA@)
-- find_package(cosma REQUIRED)
--endif()
-+ # libint
-
--if (@@CP2K_USE_MPI@)
-- find_package(MPI REQUIRED)
-- find_package(SCALAPACK REQUIRED)
--endif()
-+ if(@CP2K_USE_LIBINT2@)
-+ find_dependency(Libint2 REQUIRED)
-+ endif()
-
--if(@CP2K_USE_FFTW3@)
-- find_package(Fftw REQUIRED)
--endif()
-- # QUIP
--if(@CP2K_USE_QUIP@)
-- find_package(Quip REQUIRED)
--endif()
-+ # spglib
-
--# libint
-+ if(@CP2K_USE_SPGLIB@)
-+ find_dependency(LibSPG REQUIRED)
-+ endif()
-
--if(@CP2K_USE_LIBINT2@)
-- find_package(Libint2 REQUIRED)
--endif()
-+ if(@CP2K_USE_SPLA@)
-+ find_dependency(SPLA REQUIRED)
-+ endif()
-
--# spglib
-+ if(@CP2K_USE_SIRIUS@)
-+ find_dependency(sirius REQUIRED)
-+ endif()
-
--if(@CP2K_USE_SPGLIB@)
-- find_package(LibSPG REQUIRED)
--endif()
-+ if(@CP2K_USE_SUPERLU@)
-+ find_dependency(SuperLU REQUIRED)
-+ endif()
-
--if(@CP2K_USE_SPLA@)
-- find_package(SPLA REQUIRED)
--endif()
-+ if(@CP2K_USE_METIS@)
-+ find_dependency(Metis)
-+ endif()
-
--if(@CP2K_USE_SIRIUS@)
-- find_package(sirius REQUIRED)
--endif()
--
--if(@CP2K_USE_SUPERLU@)
-- find_package(SuperLU REQUIRED)
--endif()
-+ if(@CP2K_USE_PEXSI@)
-+ # PEXSI 1.2 uses cmake as build system
-+ find_dependency(PEXSI REQUIRED)
-+ endif()
-
--if(@CP2K_USE_PARMETIS@)
-- find_package(Metis)
--endif()
-+ if(@CP2K_USE_PLUMED@)
-+ find_dependency(Plumed REQUIRED)
-+ endif()
-
--if(@CP2K_USE_PTSCOTCH@)
-- find_package(Ptscotch REQUIRED)
--endif()
-+ if(@CP2K_USE_LIBTORCH@)
-+ find_dependency(Torch REQUIRED)
-+ endif()
-
--if(@CP2K_USE_PEXSI@)
-- # PEXSI 1.2 uses cmake as build system
-- find_package(PEXSI REQUIRED)
--endif()
-+ include("${CMAKE_CURRENT_LIST_DIR}/cp2kTargets.cmake")
-
--if(@CP2K_USE_PLUMED@)
-- find_package(Plumed REQUIRED)
--endif()
-+ # Clean-up module path.
-+ list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
-
--if(@CP2K_USE_LIBTORCH@)
-- find_package(Torch REQUIRED)
- endif()
--
--# Include SIRIUS target
--include("${CMAKE_CURRENT_LIST_DIR}/cp2kTargets.cmake")
-diff --git a/cmake/libcp2k.pc.in b/cmake/libcp2k.pc.in
-new file mode 100644
-index 000000000..618af55e2
---- /dev/null
-+++ b/cmake/libcp2k.pc.in
-@@ -0,0 +1,11 @@
-+prefix="@CMAKE_INSTALL_PREFIX@"
-+exec_prefix="${prefix}"
-+libdir="${prefix}/@CMAKE_INSTALL_LIBDIR@"
-+includedir="${prefix}/@CMAKE_INSTALL_INCLUDEDIR@"
-+
-+Name: @PROJECT_NAME@
-+Description: @CMAKE_PROJECT_DESCRIPTION@
-+URL: @CMAKE_PROJECT_HOMEPAGE_URL@
-+Version: @PROJECT_VERSION@
-+Cflags: -I"${includedir}/cp2k" -I"${includedir}/cp2k/@CMAKE_Fortran_COMPILER_ID@-@CMAKE_Fortran_COMPILER_VERSION@"
-+Libs: -L"${libdir}" -lcp2k
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index dbc955885..1178101ad 100644
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -1536,9 +1536,9 @@ target_link_libraries(
- $<$:CP2K::LIBSPG::libspg>
- $<$:CP2K::Libxc::xc>
- $<$:CP2K::ELPA::elpa>
-- $<$:CP2K::FFTW3::fftw3>
-- $<$:CP2K::FFTW3::fftw3_threads>
-- $<$:CP2K::FFTW3::fftw3_omp>
-+ $<$:CP2K::FFTW3::fftw3>
-+ $<$,$>:CP2K::FFTW3::fftw3_threads>
-+ $<$,$>:CP2K::FFTW3::fftw3_omp>
- $<$:SPLA::spla>
- $<$:CP2K::Libint2::int2>
- $<$:${TORCH_LIBRARIES}>
-@@ -1555,7 +1555,7 @@ target_compile_definitions(
- cp2k
- PUBLIC $<$:__parallel>
- $<$:__SCALAPACK>
-- $<$:__MPI_08>
-+ $<$:__MPI_F08>
- __COMPILE_DATE=\"${CP2K_TIMESTAMP}\"
- __COMPILE_HOST=\"${CP2K_HOST_NAME}\"
- __COMPILE_REVISION=\"${CP2K_GIT_HASH}\"
-@@ -1577,7 +1577,7 @@ target_compile_definitions(
- $<$:__OFFLOAD_GEMM>
- $<$:__ELPA>
- $<$:__LIBXC>
-- $<$:__FFTW3>
-+ $<$:__FFTW3>
- $<$:__LIBINT>
- $<$:__LIBPEXSI>
- $<$:__LIBTORCH>
-@@ -1774,12 +1774,14 @@ install(
- EXPORT cp2k_targets
- FILE cp2kTargets.cmake
- NAMESPACE cp2k::
-- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cp2k")
-+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
-
--install(FILES start/libcp2k.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cp2k")
-+install(FILES start/libcp2k.h
-+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}")
-
- install(
- DIRECTORY "${PROJECT_BINARY_DIR}/src/mod_files"
-- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cp2k"
-+ DESTINATION
-+ "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}"
- FILES_MATCHING
- PATTERN "*.mod")
---
-2.41.0
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-relwithdebinfo-2024.1.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-relwithdebinfo-2024.1.patch
deleted file mode 100644
index b974527..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/cmake-relwithdebinfo-2024.1.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 4526160ad..8218a7a3d 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -63,6 +63,18 @@ string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
- string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
- string(REPLACE "-DNDEBUG" "" CMAKE_Fortran_FLAGS_RELEASE
- ${CMAKE_Fortran_FLAGS_RELEASE})
-+string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO
-+ ${CMAKE_C_FLAGS_RELWITHDEBINFO})
-+string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO
-+ ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
-+string(REPLACE "-DNDEBUG" "" CMAKE_Fortran_FLAGS_RELWITHDEBINFO
-+ ${CMAKE_Fortran_FLAGS_RELWITHDEBINFO})
-+string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_MINSIZEREL
-+ ${CMAKE_C_FLAGS_MINSIZEREL})
-+string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_MINSIZEREL
-+ ${CMAKE_CXX_FLAGS_MINSIZEREL})
-+string(REPLACE "-DNDEBUG" "" CMAKE_Fortran_FLAGS_MINSIZEREL
-+ ${CMAKE_Fortran_FLAGS_MINSIZEREL})
-
- find_package(PkgConfig)
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/d4-dispersion-bugfix-2024.3.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/d4-dispersion-bugfix-2024.3.patch
deleted file mode 100644
index 36613ab..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/d4-dispersion-bugfix-2024.3.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-diff --git a/src/qs_dispersion_d4.F b/src/qs_dispersion_d4.F
-index 74df989b4..e513ed435 100644
---- a/src/qs_dispersion_d4.F
-+++ b/src/qs_dispersion_d4.F
-@@ -26,6 +26,7 @@ MODULE qs_dispersion_d4
- #endif
- USE kinds, ONLY: dp
- USE particle_types, ONLY: particle_type
-+ USE periodic_table, ONLY: get_ptable_info, ptable
- USE qs_dispersion_types, ONLY: qs_dispersion_type
- USE qs_force_types, ONLY: qs_force_type
- USE message_passing, ONLY: mp_para_env_type
-@@ -76,7 +77,8 @@ CONTAINS
- TYPE(structure_type) :: mol
- TYPE(realspace_cutoff) :: cutoff
-
-- INTEGER :: iatom, natom, ind_atom
-+ LOGICAL :: found
-+ INTEGER :: iatom, natom, ind_atom, zatom
- INTEGER, ALLOCATABLE, DIMENSION(:) :: el_num
- REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: gradient, xyz
- REAL(KIND=dp), DIMENSION(3, 3) :: stress
-@@ -94,7 +96,9 @@ CONTAINS
- DO iatom = 1, natom
- xyz(:, iatom) = particle_set(iatom)%r(:)
- CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
-- el_num(iatom) = ikind
-+ CALL get_ptable_info(particle_set(iatom)%atomic_kind%element_symbol, &
-+ ielement=zatom, found=found)
-+ el_num(iatom) = zatom
- END DO
-
- !get information about cell / lattice
-@@ -125,7 +129,7 @@ CONTAINS
- IF (para_env%num_pe > 1 .AND. para_env%mepos > 0) virial = 0.00_dp
- END IF
- DO iatom = 1, natom
-- ikind = el_num(iatom)
-+ CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
- ind_atom = atom_of_kind(iatom)
- force(ikind)%dispersion(:, ind_atom) = force(ikind)%dispersion(:, ind_atom) + gradient(:, iatom)
- END DO
-diff --git a/tests/QS/regtest-dft-vdw-corr-4/TEST_FILES b/tests/QS/regtest-dft-vdw-corr-4/TEST_FILES
-index 047421204..c817677df 100644
---- a/tests/QS/regtest-dft-vdw-corr-4/TEST_FILES
-+++ b/tests/QS/regtest-dft-vdw-corr-4/TEST_FILES
-@@ -3,7 +3,7 @@
- # e.g. 0 means do not compare anything, running is enough
- # 1 compares the last total energy in the file
- # for details see cp2k/tools/do_regtest
--pbe_dftd4.inp 33 1.0E-14 -0.00141644869634
-+pbe_dftd4.inp 33 1.0E-14 -0.00283102230260
- pbe_dftd4_force.inp 72 1.0E-07 0.00007217
--pbe_dftd4_stress.inp 31 1.0E-07 -5.16289312880E-03
-+pbe_dftd4_stress.inp 31 1.0E-07 -2.14003785359E-02
- #EOF
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/package.py b/cp2k/docker/cp2k_environment/repos/packages/cp2k/package.py
deleted file mode 100644
index ddf7378..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/package.py
+++ /dev/null
@@ -1,1242 +0,0 @@
-# Copyright Spack Project Developers. See COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import os
-import sys
-
-from spack_repo.builtin.build_systems import cmake, makefile
-from spack_repo.builtin.build_systems.cmake import CMakePackage, generator
-from spack_repo.builtin.build_systems.cuda import CudaPackage
-from spack_repo.builtin.build_systems.makefile import MakefilePackage
-from spack_repo.builtin.build_systems.rocm import ROCmPackage
-
-from spack.package import *
-
-GPU_MAP = {
- "35": "K40",
- "37": "K80",
- "60": "P100",
- "70": "V100",
- "80": "A100",
- "90": "H100",
- "gfx906": "Mi50",
- "gfx908": "Mi100",
- "gfx90a": "Mi250",
- "gfx90a:xnack-": "Mi250",
- "gfx90a:xnack+": "Mi250",
- "gfx942": "Mi300",
-}
-
-
-class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
- """CP2K is a quantum chemistry and solid state physics software package
- that can perform atomistic simulations of solid state, liquid, molecular,
- periodic, material, crystal, and biological systems
- """
-
- build_system(
- conditional("cmake", when="@2023.2:"),
- conditional("makefile", when="@:2025.2"),
- default="cmake",
- )
-
- homepage = "https://www.cp2k.org"
- url = "https://github.com/cp2k/cp2k/releases/download/v2025.2/cp2k-2025.2.tar.bz2"
- git = "https://github.com/cp2k/cp2k.git"
- list_url = "https://github.com/cp2k/cp2k/releases"
-
- maintainers("dev-zero", "mtaillefumier", "RMeli", "abussy", "hfp")
-
- tags = ["e4s"]
-
- license("GPL-2.0-or-later")
-
- version("2026.1", sha256="4364c74bcffaa474bc234e11686b09550e4d06932acf2147a341e4f7679dd88e")
- version("2025.2", sha256="c8392a4e123304644ec8d241443796277c6ed7ae977452317e779f3c387c2e19")
- version("2025.1", sha256="65c8ad5488897b0f995919b9fa77f2aba4b61677ba1e3c19bb093d5c08a8ce1d")
- version("2024.3", sha256="a6eeee773b6b1fb417def576e4049a89a08a0ed5feffcd7f0b33c7d7b48f19ba")
- version("2024.2", sha256="cc3e56c971dee9e89b705a1103765aba57bf41ad39a11c89d3de04c8b8cdf473")
- version("2024.1", sha256="a7abf149a278dfd5283dc592a2c4ae803b37d040df25d62a5e35af5c4557668f")
- version("2023.2", sha256="adbcc903c1a78cba98f49fe6905a62b49f12e3dfd7cedea00616d1a5f50550db")
- version("2023.1", sha256="dff343b4a80c3a79363b805429bdb3320d3e1db48e0ff7d20a3dfd1c946a51ce")
- version("2022.2", sha256="1a473dea512fe264bb45419f83de432d441f90404f829d89cbc3a03f723b8354")
- version("2022.1", sha256="2c34f1a7972973c62d471cd35856f444f11ab22f2ff930f6ead20f3454fd228b")
- version("9.1", sha256="fedb4c684a98ad857cd49b69a3ae51a73f85a9c36e9cb63e3b02320c74454ce6")
- version("8.2", sha256="2e24768720efed1a5a4a58e83e2aca502cd8b95544c21695eb0de71ed652f20a")
- version("8.1", sha256="7f37aead120730234a60b2989d0547ae5e5498d93b1e9b5eb548c041ee8e7772")
- version("7.1", sha256="ccd711a09a426145440e666310dd01cc5772ab103493c4ae6a3470898cd0addb")
- version("master", branch="master", submodules=True)
-
- generator("ninja")
-
- variant("mpi", default=True, description="Enable MPI support")
- variant("openmp", default=True, description="Enable OpenMP support")
- variant(
- "smm",
- default="libxsmm",
- values=("libxsmm", "libsmm", "blas"),
- description="Library for small matrix multiplications",
- )
- variant("opencl", default=False, description="Enable OpenCL backend")
- variant("plumed", default=False, description="Enable PLUMED support")
- variant(
- "libint", default=True, description="Use libint, required for HFX (and possibly others)"
- )
- variant("libxc", default=True, description="Support additional functionals via libxc")
- variant(
- "pexsi",
- default=False,
- description="Enable the alternative PEXSI method for density matrix evaluation",
- when="+mpi",
- )
- variant(
- "elpa",
- default=False,
- description="Enable optimised diagonalisation routines from ELPA",
- when="+mpi",
- )
- variant(
- "dlaf",
- default=False,
- description="Enable DLA-Future eigensolver and Cholesky decomposition",
- when="@2024.1: build_system=cmake +mpi",
- )
- # sirius support was introduced in 7, but effectively usable starting from CP2K 9
- variant(
- "sirius",
- default=False,
- description="Enable planewave electronic structure calculations via SIRIUS",
- when="@9: +mpi",
- )
- variant("cosma", default=False, description="Use COSMA for p?gemm", when="@8: +mpi")
- variant(
- "libvori",
- default=False,
- description="Enable support for Voronoi integration and BQB compression",
- when="@8:",
- )
- variant("spglib", default=False, description="Enable support for spglib")
- variant(
- "spla",
- default=False,
- description="Use SPLA off-loading functionality. Only relevant when CUDA or ROCM"
- " are enabled",
- )
- variant("pytorch", default=False, description="Enable libtorch support")
- variant(
- "openpmd-api",
- default=False,
- description="Enable openPMD support",
- when="@2026.1: build_system=cmake",
- )
- variant("quip", default=False, when="@:2025.2", description="Enable quip support")
- variant("dftd4", when="@2024.2:", default=False, description="Enable DFT-D4 support")
- variant("mpi_f08", default=False, description="Use MPI F08 module", when="+mpi")
- variant("smeagol", default=False, description="Enable libsmeagol support", when="@2025.2:")
- variant("dbm_gpu", default=True, description="Enable DBM GPU backend", when="@2025.2:")
- variant("grid_gpu", default=True, description="Enable grid GPU backend", when="@2025.2:")
- variant(
- "grid_gpu", default=False, description="Enable grid GPU backend", when="@2025.2: +opencl"
- )
- variant(
- "pw_gpu", default=True, description="Enable FFT calculations on GPU", when="@2025.2: +cuda"
- )
- variant(
- "pw_gpu",
- default=False,
- description="Enable FFT calculations on GPU",
- when="@2025.2: +rocm",
- )
- variant(
- "pw_gpu",
- default=False,
- description="Enable FFT calculations on GPU",
- when="@2025.2: +opencl",
- )
- variant(
- "hip_backend_cuda",
- default=False,
- description="Enable HIP backend on Nvidia GPU",
- when="@2025.2: +cuda",
- )
- variant(
- "enable_regtests",
- default=False,
- description="Configure cp2k to run the regtests afterwards."
- " It build cp2k normally but put the executables in exe/cmake-build-* instead of the"
- " conventional location. This option is only relevant when regtests need to be run.",
- )
- variant(
- "grpp",
- default=False,
- description="Enable GRPP psuedo potentials",
- when="@2025.2: build_system=cmake",
- )
- variant(
- "hdf5",
- default=False,
- description="Enable HDF5 support",
- when="@2025.2: build_system=cmake",
- )
- variant(
- "trexio",
- default=False,
- description="Enable TrexIO support",
- when="@2025.2: build_system=cmake",
- )
- variant(
- "greenx",
- default=False,
- description="Enable green X support",
- when="@2025.2: build_system=cmake",
- )
-
- variant("vdwxc", default=False, description="Enable VDW support in SIRIUS.", when="+sirius")
- variant("deepmd", default=False, description="Enable DeepMD-kit support")
- variant("tblite", default=False, description="Enable tblite support", when="@2025.2:")
- variant("nlcg", default=False, description="Enable nlcg support in sirius", when="+sirius")
- variant("vcsqnm", default=False, description="Enable VCSQNM support in sirius", when="+sirius")
-
- conflicts("+deepmd", msg="DeepMD-kit is not yet available in Spack")
-
- with when("+cuda"):
- variant(
- "cuda_arch_35_k20x",
- default=False,
- description=(
- "CP2K (resp. DBCSR) has specific parameter sets for"
- " different GPU models. Enable this when building"
- " with cuda_arch=35 for a K20x instead of a K40"
- ),
- )
- variant(
- "cuda_fft", default=False, description="Use CUDA also for FFTs in the PW part of CP2K"
- )
- variant(
- "cuda_blas",
- default=False,
- when="@:7", # req in CP2K v8+
- description="Use CUBLAS for general matrix operations in DBCSR",
- )
-
- with when("+hip_backend_cuda"):
- depends_on("hipcc")
- depends_on("hip+cuda")
- depends_on("hipfft+cuda")
- depends_on("hipblas+cuda")
-
- HFX_LMAX_RANGE = range(4, 8)
-
- variant(
- "lmax",
- description="Maximum supported angular momentum (HFX and others)",
- default="5",
- values=[str(x) for x in HFX_LMAX_RANGE],
- multi=False,
- )
-
- depends_on("c", type="build")
- depends_on("cxx", type="build")
- depends_on("fortran", type="build")
-
- depends_on("python@3", type="build")
- depends_on("pkgconfig", type="build", when="build_system=cmake")
-
- depends_on("blas")
- depends_on("lapack")
- depends_on("fftw-api@3")
- depends_on("greenx", when="+greenx")
- depends_on("hdf5+hl+fortran", when="+hdf5")
- depends_on("trexio", when="+trexio")
-
- depends_on("tblite build_system=cmake", when="+tblite")
- # Force openmp propagation on some providers of blas / fftw-api
- with when("+openmp"):
- depends_on("fftw+openmp", when="^[virtuals=fftw-api] fftw")
- depends_on("amdfftw+openmp", when="^[virtuals=fftw-api] amdfftw")
- depends_on("cray-fftw+openmp", when="^[virtuals=fftw-api] cray-fftw")
- depends_on("armpl-gcc threads=openmp", when="^[virtuals=blas] armpl-gcc")
- depends_on("openblas threads=openmp", when="^[virtuals=blas] openblas")
- depends_on("intel-oneapi-mkl threads=openmp", when="^[virtuals=fftw-api] intel-oneapi-mkl")
- depends_on(
- "intel-oneapi-mkl+gfortran threads=openmp",
- when="^[virtuals=blas] intel-oneapi-mkl %gcc",
- )
- depends_on("intel-oneapi-mkl threads=openmp", when="^[virtuals=blas] intel-oneapi-mkl")
- # The Cray compiler wrappers will automatically add libsci_mp with
- # -fopenmp. Since CP2K unconditionally links blas/lapack/scalapack
- # we have to be consistent.
- depends_on("cray-libsci+openmp", when="^[virtuals=blas] cray-libsci")
-
- with when("smm=libxsmm"):
- # require libxsmm-1.11+ since 1.10 can leak file descriptors in Fortran
- depends_on("libxsmm@1.11:")
- depends_on("libxsmm@1.17:", when="@9.1:")
- # use pkg-config (support added in libxsmm-1.10) to link to libxsmm
- depends_on("pkgconfig", type="build")
-
- # Several packages provide "opencl" (incl. ICD/loader), e.g., "cuda"
- with when("+opencl"):
- depends_on("opencl", when="+opencl")
- opencl_loader_header_version = "2022.10.24"
- depends_on(f"opencl-c-headers@{opencl_loader_header_version}:")
- requires(f"%opencl=opencl-icd-loader@{opencl_loader_header_version}:")
- # OpenCL backend implementation relies on LIBXSMM
- requires("smm=libxsmm")
-
- with when("+libint"):
- depends_on("pkgconfig", type="build", when="@7.0:")
- for lmax in HFX_LMAX_RANGE:
- depends_on(f"libint@2.6.0:+fortran tune=cp2k-lmax-{lmax}", when=f"@7.0: lmax={lmax}")
- # AOCC only works with libint@2.6.0
- depends_on(
- f"libint@=2.6.0+fortran tune=cp2k-lmax-{lmax}", when=f"@7.0: lmax={lmax} %aocc"
- )
-
- with when("+libxc"):
- depends_on("pkgconfig", type="build", when="@7.0: ^libxc@:6")
- depends_on("libxc@4.0.3:4", when="@7.0:8.1")
- depends_on("libxc@5.1.3:5.1", when="@8.2:8")
- depends_on("libxc@5.1.7:5.1", when="@9:2022.2")
- depends_on("libxc@6.1:", when="@2023.1:")
- depends_on("libxc@6.2:", when="@2023.2:")
- depends_on("libxc@:6", when="@:2024.3")
- depends_on("libxc@7 build_system=cmake", when="@2025.2:")
-
- with when("+spla"):
- depends_on("spla+cuda+fortran", when="+cuda")
- depends_on("spla+rocm+fortran", when="+rocm")
-
- with when("+mpi"):
- depends_on("mpi@2:")
- depends_on("mpi@3:", when="@2023.1:")
- depends_on("scalapack")
- depends_on("mpich+fortran", when="^[virtuals=mpi] mpich")
- depends_on("intel-oneapi-mkl +cluster", when="^[virtuals=scalapack] intel-oneapi-mkl")
- conflicts("~mpi_f08", when="^mpich@4.1:")
-
- with when("+cosma"):
- depends_on("cosma+scalapack")
- depends_on("cosma@2.5.1:", when="@9:")
- depends_on("cosma@2.6.3:", when="@2023.2:")
- depends_on("cosma+cuda", when="+cuda")
- depends_on("cosma+rocm", when="+rocm")
-
- with when("+elpa"):
- depends_on("elpa+openmp", when="+openmp")
- depends_on("elpa~openmp", when="~openmp")
- depends_on("elpa+cuda", when="+cuda")
- depends_on("elpa~cuda", when="~cuda")
- depends_on("elpa+rocm", when="+rocm")
- depends_on("elpa~rocm", when="~rocm")
- depends_on("elpa@2021.05:", when="@8.3:")
- depends_on("elpa@2021.11.001:", when="@9.1:")
- depends_on("elpa@2023.05.001:", when="@2023.2:")
-
- with when("+dlaf"):
- with when("@:2024.1"):
- depends_on("dla-future@0.2.1: +scalapack")
- depends_on("dla-future ~cuda", when="~cuda")
- depends_on("dla-future ~rocm", when="~rocm")
- depends_on("dla-future +cuda", when="+cuda")
- depends_on("dla-future +rocm", when="+rocm")
-
- with when("@2024.2:"):
- depends_on("dla-future-fortran@0.1.0:")
- depends_on("dla-future-fortran@0.2.0:", when="@2025.1:")
-
- # Use a direct dependency on dla-future so that constraints can be expressed
- # WARN: In the concretizer output, dla-future will appear as dependency of CP2K
- # instead of dla-future-fortran
- depends_on("dla-future ~cuda", when="~cuda")
- depends_on("dla-future ~rocm", when="~rocm")
- depends_on("dla-future +cuda", when="+cuda")
- depends_on("dla-future +rocm", when="+rocm")
-
- conflicts(
- "+plumed",
- when="@:2024.1 build_system=cmake",
- msg="PLUMED support is broken in cp2k@:2024.1 with CMake",
- )
- with when("+plumed"):
- depends_on("plumed+shared")
- depends_on("plumed+mpi", when="+mpi")
- depends_on("plumed~mpi", when="~mpi")
-
- depends_on("libsmeagol", when="+smeagol")
-
- # while we link statically against PEXSI, its own deps may be linked in
- # dynamically, therefore can't set this as pure build-type dependency.
- depends_on("pexsi+fortran@0.10.0:", when="+pexsi")
-
- # only OpenMP should be consistently used, all other common things
- # like ELPA, SCALAPACK are independent and Spack will ensure that
- # a consistent/compatible combination is pulled into the dependency graph.
- with when("+sirius"):
- depends_on("sirius+fortran+shared+scalapack")
- depends_on("sirius+cuda", when="+cuda")
- depends_on("sirius+rocm", when="+rocm")
- depends_on("sirius+openmp", when="+openmp")
- depends_on("sirius~openmp", when="~openmp")
- depends_on("sirius@7.3:", when="@9.1")
- depends_on("sirius@7.4:", when="@2023.2")
- depends_on("sirius@7.5:", when="@2024.1:")
- depends_on("sirius@7.6:+pugixml", when="@2024.2:")
- depends_on("sirius@7.7:+pugixml", when="@2025.2:")
- depends_on("sirius+vdwxc", when="+vdwxc")
- depends_on("sirius+nlcglib", when="@2025.2:+nlcg")
- depends_on("sirius+vcsqnm", when="@2025.2:+vcsqnm")
- depends_on("sirius@7.8.1:+dftd3+dftd4", when="@2025.2:+dftd4")
- depends_on("sirius@7.5.0:+dlaf", when="+dlaf")
-
- with when("+libvori"):
- depends_on("libvori@201219:", when="@8.1")
- depends_on("libvori@210412:", when="@8.2:")
- depends_on("libvori@220621:", when="@2023.1:")
-
- with when("+openpmd-api"):
- depends_on("openpmd-api@0.16.1:")
-
- # the bundled libcusmm uses numpy in the parameter prediction (v7+)
- # which is written using Python 3
- depends_on("py-numpy", when="@7:+cuda")
- depends_on("python@3.6:", when="@7:+cuda")
- depends_on("py-fypp")
-
- depends_on("py-torch", when="+pytorch")
-
- depends_on("spglib", when="+spglib")
-
- depends_on("dftd4@3.6.0: build_system=cmake", when="+dftd4")
-
- with when("build_system=cmake"):
- depends_on("cmake@3.22:", type="build")
-
- # DBCSR as external dependency
- depends_on("dbcsr@2.6: ~examples")
- depends_on("dbcsr@2.8:", when="@2025.1:")
- depends_on("dbcsr+openmp", when="+openmp")
- depends_on("dbcsr+opencl", when="+opencl")
- depends_on("dbcsr+mpi", when="+mpi")
- depends_on("dbcsr+rocm", when="+rocm")
- depends_on("dbcsr+cuda", when="+cuda")
-
- depends_on("dbcsr smm=libxsmm", when="smm=libxsmm")
- depends_on("dbcsr smm=blas", when="smm=blas")
-
- with when("@2022: +rocm"):
- depends_on("hipblas")
- depends_on("hipfft")
-
- # The CMake build system and AOCC are not compatible as of AOCC 5
- requires("build_system=makefile", when="%aocc")
-
- # CP2K needs compiler specific compilation flags, e.g. optflags
- conflicts("%apple-clang")
- conflicts("%clang")
- conflicts("%nag")
- conflicts(
- "%aocc@:3.2",
- msg="Please use AOCC 4.0+ that better support modern Fortran features CP2K requires",
- )
-
- conflicts("~openmp", when="@8:", msg="Building without OpenMP is not supported in CP2K 8+")
-
- # We only support specific cuda_archs for which we have parameter files
- # for optimal kernels. Note that we don't override the cuda_archs property
- # from the parent class, since the parent class defines constraints for all
- # versions. Instead just mark all unsupported cuda archs as conflicting.
-
- supported_cuda_arch_list = ("35", "37", "60", "70", "80", "90")
- supported_rocm_arch_list = (
- "gfx906",
- "gfx908",
- "gfx90a",
- "gfx90a:xnack-",
- "gfx90a:xnack+",
- "gfx942",
- )
- cuda_msg = "cp2k only supports cuda_arch {0}".format(supported_cuda_arch_list)
- rocm_msg = "cp2k only supports amdgpu_target {0}".format(supported_rocm_arch_list)
-
- conflicts("+cuda", when="cuda_arch=none")
-
- # ROCm already emits an error if +rocm amdgpu_target=none is given
-
- with when("+cuda"):
- for arch in CudaPackage.cuda_arch_values:
- if arch not in supported_cuda_arch_list:
- conflicts("+cuda", when="cuda_arch={0}".format(arch), msg=cuda_msg)
-
- with when("+rocm"):
- for arch in ROCmPackage.amdgpu_targets:
- if arch not in supported_rocm_arch_list:
- conflicts("+rocm", when="amdgpu_target={0}".format(arch), msg=rocm_msg)
-
- # Fix 2- and 3-center integral calls to libint
- patch(
- "https://github.com/cp2k/cp2k/commit/5eaf864ed2bd21fb1b05a9173bb77a815ad4deda.patch?full_index=1",
- sha256="3617abb877812c4b933f601438c70f95e21c6161bea177277b1d4125fd1c0bf9",
- when="@8.2",
- )
-
- # Patch for compilers with stricter C99 checks
- patch("posix_c_source.patch", when="@7.1%aocc@4.0:")
- patch("posix_c_source.patch", when="@7.1%gcc@13:")
-
- # Fix missing variable in OpenMP private clause
- patch(
- "https://github.com/cp2k/cp2k/commit/be86bd7f6cd6af7d68f8957dcdb67e7c3d586741.patch?full_index=1",
- sha256="1bb5a8e80603684a743e7821d24d41b31b60ccbb7d4257df1d2da53a3630e5bf",
- when="@2022.1:2022.2",
- )
-
- # Avoid using NULL() as subroutine argument as doing so breaks some versions of AOCC compiler
- # These patches backport 2023.x fixes to previous versions
- patch("backport_avoid_null_2022.x.patch", when="@2022.1:2022.2 %aocc@:4.0")
- patch("backport_avoid_null_9.1.patch", when="@9.1 %aocc@:4.0")
-
- patch("cmake-fixes-2023.2.patch", when="@2023.2 build_system=cmake")
-
- # Allow compilation with build_type=RelWithDebInfo and build_type=MinSizeRel
- # after NDEBUG support was dropped in https://github.com/cp2k/cp2k/pull/3172
- # The patch applies https://github.com/cp2k/cp2k/pull/3251 to version 2024.1
- patch("cmake-relwithdebinfo-2024.1.patch", when="@2024.1 build_system=cmake")
-
- # Bugfix for D4 dispersion correction in CP2K 2024.3
- # https://github.com/cp2k/cp2k/issues/3688
- patch("d4-dispersion-bugfix-2024.3.patch", when="@2024.3")
-
- # Fix segmentation faults caused by accessing unallocated arrays
- # https://github.com/cp2k/cp2k/pull/3733
- patch(
- "https://github.com/cp2k/cp2k/commit/7a99649828ecf7d5dc53d952a1bf7be6970deabe.patch?full_index=1",
- sha256="37f4f1a76634ff4a5617fe0c670e6acfe2afa2b2cfc5b2875e438a54baa4525e",
- when="@2024.2:2024.3",
- )
- # Follow api change of sirius, deleted unrelated tools part.
- # https://github.com/cp2k/cp2k/commit/9ae0441d1aa760e247a8a389793207ec65a35775
- # https://github.com/electronic-structure/SIRIUS/pull/1048
- patch("sirius-api-7.7.0.patch", when="@2024.2:2025.1 ^sirius@7.7.0")
-
- # Fix missing S in data/BASIS_MOLOPT_UZH
- # https://github.com/cp2k/cp2k/pull/4140
- patch(
- "https://github.com/cp2k/cp2k/commit/da03128481adf8f78a8a04ebeae0490480c03b89.patch?full_index=1",
- sha256="0d542c414216866953c95e642d2590b3d313717dfaebbf12cfafedbdd3bf54a3",
- when="@=2025.1",
- )
-
- def patch(self):
- # Patch for an undefined constant due to incompatible changes in ELPA
- if self.spec.satisfies("@9.1:2022.2 +elpa"):
- if self.spec["elpa"].satisfies("@2022.05.001:"):
- filter_file(
- r"ELPA_2STAGE_REAL_INTEL_GPU",
- "ELPA_2STAGE_REAL_INTEL_GPU_SYCL",
- "src/fm/cp_fm_elpa.F",
- )
-
- # Patch for resolving .mod file conflicts in ROCm by implementing 'USE, INTRINSIC'
- # This patch triggers compilation errors on some systems as rocm install these
- # modules files in rocm/include/llvm and this directory is given to gcc
-
- if self.spec.satisfies("+rocm"):
- for directory, subdirectory, files in os.walk(os.getcwd()):
- for i in files:
- file_path = os.path.join(directory, i)
- filter_file("USE ISO_C_BINDING", "USE,INTRINSIC :: ISO_C_BINDING", file_path)
- filter_file(
- "USE ISO_FORTRAN_ENV", "USE,INTRINSIC :: ISO_FORTRAN_ENV", file_path
- )
- filter_file("USE omp_lib", "USE,INTRINSIC :: omp_lib", file_path)
- filter_file("USE OMP_LIB", "USE,INTRINSIC :: OMP_LIB", file_path)
- filter_file("USE iso_c_binding", "USE,INTRINSIC :: iso_c_binding", file_path)
- filter_file(
- "USE iso_fortran_env", "USE,INTRINSIC :: iso_fortran_env", file_path
- )
-
- def url_for_version(self, version):
- url = "https://github.com/cp2k/cp2k/releases/download/v{0}/cp2k-{0}.tar.bz2"
- return url.format(version)
-
-
-class MakefileBuilder(makefile.MakefileBuilder):
- def edit(self, pkg, spec, prefix):
- pkgconf = which("pkg-config", required=True)
-
- fftw = spec["fftw-api:openmp" if "+openmp" in spec else "fftw-api"]
- fftw_header_dir = fftw.headers.directories[0]
-
- # some providers (mainly Intel) keep the fftw headers in a subdirectory, find it
- for incdir in [join_path(f, "fftw") for f in fftw.headers.directories]:
- if os.path.exists(incdir):
- fftw_header_dir = incdir
- break
-
- optimization_flags = {
- "gcc": ["-O2", "-funroll-loops", "-ftree-vectorize"],
- "intel-oneapi-compilers": ["-O2", "-fp-model precise"],
- "intel": ["-g", "-O2", "-fp-model precise"],
- "nvhpc": ["-fast"],
- "cce": ["-O2"],
- "xl": ["-O3"],
- "aocc": ["-O2"],
- "rocmcc": ["-O1"],
- }
-
- dflags = ["-DNDEBUG"] if spec.satisfies("@:2023.2") else []
- if fftw.name == "intel-oneapi-mkl":
- cppflags = ["-D__FFTW3_MKL", "-I{0}".format(fftw_header_dir)]
- else:
- cppflags = ["-D__FFTW3", "-I{0}".format(fftw_header_dir)]
-
- # CP2K requires MPI 3 starting at version 2023.1
- # and __MPI_VERSION is not supported anymore.
- if spec.satisfies("@:2022.2"):
- if spec.satisfies("^mpi@3:"):
- cppflags.append("-D__MPI_VERSION=3")
- elif spec.satisfies("^mpi@2:"):
- cppflags.append("-D__MPI_VERSION=2")
-
- cflags = optimization_flags[spec.compiler.name][:]
- cxxflags = optimization_flags[spec.compiler.name][:]
- fcflags = optimization_flags[spec.compiler.name][:]
- nvflags = ["-O3"]
- ldflags = []
- libs = []
- dso_suffix = shared_library_suffix(spec)
-
- # CP2K Makefile doesn't set C standard
- if spec.satisfies("@2023.2:"):
- # Use of DBL_DECIMAL_DIG
- cflags.append(pkg.compiler.c11_flag)
- else:
- # C99-style for-loops with inline definition of iterating variable.
- cflags.append(pkg.compiler.c99_flag)
-
- if spec.satisfies("%intel") or spec.satisfies("%intel-oneapi-compilers"):
- fcflags += ["-traceback"] # -heap-arrays 64
- elif spec.satisfies("%gcc"):
- fcflags += [
- "-ffree-form",
- "-ffree-line-length-none",
- "-ggdb", # make sure we get proper Fortran backtraces
- ]
- elif spec.satisfies("%aocc") or spec.satisfies("%rocmcc"):
- fcflags += ["-ffree-form", "-Mbackslash"]
- elif spec.satisfies("%nvhpc"):
- fcflags += ["-Mfreeform", "-Mextend"]
- elif spec.satisfies("%cce"):
- fcflags += ["-emf", "-ffree", "-hflex_mp=strict"]
- elif spec.satisfies("%xl"):
- fcflags += ["-qpreprocess", "-qstrict", "-q64"]
- ldflags += ["-Wl,--allow-multiple-definition"]
-
- if "+mpi %gcc@10:" in spec and spec["mpi"].name in ["mpich", "cray-mpich"]:
- fcflags += [
- "-fallow-argument-mismatch"
- ] # https://github.com/pmodels/mpich/issues/4300
- if spec.satisfies("@7.1%gcc@13:"):
- fcflags.append("-fallow-argument-mismatch")
-
- if spec.satisfies("+openmp"):
- cflags.append(pkg.compiler.openmp_flag)
- cxxflags.append(pkg.compiler.openmp_flag)
- fcflags.append(pkg.compiler.openmp_flag)
- ldflags.append(pkg.compiler.openmp_flag)
- nvflags.append('-Xcompiler="{0}"'.format(pkg.compiler.openmp_flag))
- elif spec.satisfies("%cce"): # Cray enables OpenMP by default
- cflags += ["-hnoomp"]
- cxxflags += ["-hnoomp"]
- fcflags += ["-hnoomp"]
- ldflags += ["-hnoomp"]
-
- if spec.satisfies("@7:"): # recent versions of CP2K use C++14 CUDA code
- cxxflags.append(pkg.compiler.cxx14_flag)
- nvflags.append(pkg.compiler.cxx14_flag)
-
- ldflags.append(fftw.libs.search_flags)
-
- if spec.satisfies("^superlu-dist@4.3"):
- ldflags.insert(0, "-Wl,--allow-multiple-definition")
-
- if spec.satisfies("+libint"):
- cppflags += ["-D__LIBINT"]
-
- if spec.satisfies("@:6.9"):
- cppflags += ["-D__LIBINT_MAX_AM=6", "-D__LIBDERIV_MAX_AM1=5"]
-
- # libint-1.x.y has to be linked statically to work around
- # inconsistencies in its Fortran interface definition
- # (short-int vs int) which otherwise causes segfaults at
- # runtime due to wrong offsets into the shared library
- # symbols.
- libs += [
- join_path(spec["libint"].libs.directories[0], "libderiv.a"),
- join_path(spec["libint"].libs.directories[0], "libint.a"),
- ]
-
- else:
- fcflags += pkgconf("--cflags", "libint2", output=str).split()
- libs += pkgconf("--libs", "libint2", output=str).split()
-
- if spec.satisfies("+libxc"):
- cppflags += ["-D__LIBXC"]
-
- if spec.satisfies("@:6.9"):
- libxc = spec["libxc:fortran,static"]
- cppflags += [libxc.headers.cpp_flags]
- ldflags.append(libxc.libs.search_flags)
- libs.append(str(libxc.libs))
- else:
- fcflags += pkgconf("--cflags", "libxcf03", output=str).split()
- # some Fortran functions seem to be direct wrappers of the
- # C functions such that we get a direct dependency on them,
- # requiring `-lxc` to be present in addition to `-lxcf03`
- libs += pkgconf("--libs", "libxcf03", "libxc", output=str).split()
-
- if spec.satisfies("+pexsi"):
- cppflags.append("-D__LIBPEXSI")
- fcflags.append("-I" + join_path(spec["pexsi"].prefix, "fortran"))
- libs += [
- join_path(spec["pexsi"].libs.directories[0], "libpexsi.a"),
- join_path(spec["superlu-dist"].libs.directories[0], "libsuperlu_dist.a"),
- join_path(spec["parmetis"].libs.directories[0], f"libparmetis.{dso_suffix}"),
- join_path(spec["metis"].libs.directories[0], f"libmetis.{dso_suffix}"),
- ]
-
- if spec.satisfies("+elpa"):
- elpa = spec["elpa"]
- elpa_suffix = "_openmp" if "+openmp" in elpa else ""
- elpa_incdir = elpa.headers.directories[0]
-
- fcflags += ["-I{0}".format(join_path(elpa_incdir, "modules"))]
-
- # Currently AOCC support only static libraries of ELPA
- if spec.satisfies("%aocc"):
- libs.append(
- join_path(
- elpa.prefix.lib, ("libelpa{elpa_suffix}.a".format(elpa_suffix=elpa_suffix))
- )
- )
- else:
- libs.append(elpa.libs.ld_flags)
- if spec.satisfies("@:4"):
- if elpa.satisfies("@:2014.5"):
- cppflags.append("-D__ELPA")
- elif elpa.satisfies("@2014.6:2015.10"):
- cppflags.append("-D__ELPA2")
- else:
- cppflags.append("-D__ELPA3")
- else:
- cppflags.append(
- "-D__ELPA={0}{1:02d}".format(elpa.version[0], int(elpa.version[1]))
- )
- fcflags += ["-I{0}".format(join_path(elpa_incdir, "elpa"))]
-
- if "+cuda" in spec and "+cuda" in elpa:
- cppflags += ["-D__ELPA_NVIDIA_GPU"]
-
- if spec.satisfies("+sirius"):
- sirius = spec["sirius"]
- cppflags.append("-D__SIRIUS")
- fcflags += ["-I{0}".format(sirius.prefix.include.sirius)]
- libs += list(sirius.libs)
-
- if spec.satisfies("+plumed"):
- dflags.extend(["-D__PLUMED2"])
- cppflags.extend(["-D__PLUMED2"])
- libs += [join_path(spec["plumed"].prefix.lib, f"libplumed.{dso_suffix}")]
-
- if spec.satisfies("+libvori"):
- cppflags += ["-D__LIBVORI"]
- libvori = spec["libvori"].libs
- ldflags += [libvori.search_flags]
- libs.append(libvori.ld_flags)
- libs += ["-lstdc++"]
-
- if spec.satisfies("+spglib"):
- cppflags += ["-D__SPGLIB"]
- spglib = spec["spglib"].libs
- ldflags += [spglib.search_flags]
- libs.append(spglib.ld_flags)
-
- if spec.satisfies("+dftd4"):
- cppflags += ["-D__DFTD4"]
- dftd4 = spec["dftd4"].libs
- ldflags += [dftd4.search_flags]
- libs.append(dftd4.ld_flags)
-
- if spec.satisfies("+smeagol"):
- cppflags += ["-D__SMEAGOL"]
- smeagol = spec["libsmeagol"].libs
- ldflags += [smeagol.search_flags]
- libs.append(smeagol.ld_flags)
-
- cc = spack_cc if "~mpi" in spec else spec["mpi"].mpicc
- cxx = spack_cxx if "~mpi" in spec else spec["mpi"].mpicxx
- fc = spack_fc if "~mpi" in spec else spec["mpi"].mpifc
-
- # Intel
- if spec.satisfies("%intel") or spec.satisfies("%intel-oneapi-compilers"):
- cppflags.extend(
- [
- "-D__INTEL",
- "-D__HAS_IEEE_EXCEPTIONS",
- "-D__HAS_ISO_C_BINDING",
- "-D__USE_CP2K_TRACE",
- ]
- )
- fcflags.extend(["-free", "-fpp", "-diag-disable 8290,8291,10010,10212,11060"])
-
- # FFTW, LAPACK, BLAS
- lapack = spec["lapack"].libs
- blas = spec["blas"].libs
- ldflags.append((lapack + blas).search_flags)
- libs += [str(x) for x in (fftw.libs, lapack, blas)]
-
- if spec.satisfies("platform=darwin"):
- cppflags.extend(["-D__NO_STATM_ACCESS"])
-
- if spec["blas"].name == "intel-oneapi-mkl":
- cppflags += ["-D__MKL"]
- elif spec["blas"].name == "accelerate":
- cppflags += ["-D__ACCELERATE"]
-
- if spec.satisfies("+cosma"):
- # add before ScaLAPACK to override the p?gemm symbols
- cosma = spec["cosma"].libs
- ldflags.append(cosma.search_flags)
- libs += cosma
-
- # MPI
- if spec.satisfies("+mpi"):
- cppflags.extend(["-D__parallel", "-D__SCALAPACK"])
-
- if spec["mpi"].name == "intel-oneapi-mpi":
- mpi = [join_path(spec["intel-oneapi-mpi"].libs.directories[0], "libmpi.so")]
- else:
- mpi = spec["mpi:cxx"].libs
-
- if spec["scalapack"].name == "intel-oneapi-mkl":
- mpi_impl = "openmpi" if spec["mpi"].name in ["openmpi", "hpcx-mpi"] else "intelmpi"
- scalapack = [
- join_path(
- spec["intel-oneapi-mkl"].libs.directories[0], "libmkl_scalapack_lp64.so"
- ),
- join_path(
- spec["intel-oneapi-mkl"].libs.directories[0],
- "libmkl_blacs_{0}_lp64.so".format(mpi_impl),
- ),
- ]
- else:
- scalapack = spec["scalapack"].libs
- ldflags.append(scalapack.search_flags)
-
- libs += scalapack
- libs += mpi
- libs += pkg.compiler.stdcxx_libs
-
- if spec.satisfies("+mpi_f08"):
- cppflags.append("-D__MPI_F08")
-
- if spec.satisfies("^wannier90"):
- cppflags.append("-D__WANNIER90")
- wannier = join_path(spec["wannier90"].libs.directories[0], "libwannier.a")
- libs.append(wannier)
-
- gpuver = ""
- if spec.satisfies("+cuda"):
- libs += [
- "-L{}".format(spec["cuda"].libs.directories[0]),
- "-L{}/stubs".format(spec["cuda"].libs.directories[0]),
- "-lcuda",
- "-lcudart",
- "-lnvrtc",
- "-lstdc++",
- ]
-
- if spec.satisfies("@9:"):
- if spec.satisfies("@2022:"):
- cppflags += ["-D__OFFLOAD_CUDA"]
-
- acc_compiler_var = "OFFLOAD_CC"
- acc_flags_var = "OFFLOAD_FLAGS"
- cppflags += ["-D__DBCSR_ACC", "-D__GRID_CUDA", "-DOFFLOAD_TARGET=cuda"]
- libs += ["-lcublas"]
-
- if spec.satisfies("+cuda_fft"):
- if spec.satisfies("@:9"):
- cppflags += ["-D__PW_CUDA"]
-
- libs += ["-lcufft"]
- else:
- if spec.satisfies("@2022:"):
- cppflags += ["-D__NO_OFFLOAD_PW"]
- else:
- acc_compiler_var = "NVCC"
- acc_flags_var = "NVFLAGS"
- cppflags += ["-D__ACC"]
- if spec.satisfies("+cuda_blas"):
- cppflags += ["-D__DBCSR_ACC=2"]
- libs += ["-lcublas"]
- else:
- cppflags += ["-D__DBCSR_ACC"]
-
- if spec.satisfies("+cuda_fft"):
- cppflags += ["-D__PW_CUDA"]
- libs += ["-lcufft", "-lcublas"]
-
- cuda_arch = spec.variants["cuda_arch"].value[0]
- gpuver = GPU_MAP[cuda_arch]
- if cuda_arch == "35" and spec.satisfies("+cuda_arch_35_k20x"):
- gpuver = "K20X"
-
- if spec.satisfies("@2022: +rocm"):
- libs += [
- "-L{}".format(spec["hip"].prefix.lib),
- "-lamdhip64",
- "-lhipblas",
- "-lhipfft",
- "-lstdc++",
- ]
-
- acc_compiler_var = "hipcc"
- acc_flags_var = "NVFLAGS"
- cppflags += ["-D__ACC"]
- cppflags += ["-D__DBCSR_ACC"]
- cppflags += ["-D__HIP_PLATFORM_AMD__"]
- cppflags += ["-D__GRID_HIP"]
-
- gpuver = GPU_MAP[spec.variants["amdgpu_target"].value[0]]
-
- if spec.satisfies("smm=libsmm"):
- lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
- mkdirp(lib_dir)
- try:
- copy(env["LIBSMM_PATH"], join_path(lib_dir, "libsmm.a"))
- except KeyError:
- raise KeyError(
- "Point environment variable LIBSMM_PATH to "
- "the absolute path of the libsmm.a file"
- )
- except OSError:
- raise OSError(
- "The file LIBSMM_PATH pointed to does not "
- "exist. Note that it must be absolute path."
- )
- cppflags.extend(["-D__HAS_smm_dnn", "-D__HAS_smm_vec"])
- libs.append("-lsmm")
-
- elif spec.satisfies("smm=libxsmm"):
- cppflags += ["-D__LIBXSMM"]
- cppflags += pkgconf("--cflags-only-other", "libxsmmf", output=str).split()
- fcflags += pkgconf("--cflags-only-I", "libxsmmf", output=str).split()
- libs += pkgconf("--libs", "libxsmmf", output=str).split()
-
- dflags.extend(cppflags)
- cflags.extend(cppflags)
- cxxflags.extend(cppflags)
- fcflags.extend(cppflags)
- nvflags.extend(cppflags)
-
- with open(self.makefile, "w") as mkf:
- if spec.satisfies("+plumed"):
- mkf.write(
- "# include Plumed.inc as recommended by PLUMED to include libraries and flags"
- )
- mkf.write("include {0}\n".format(self.pkg["plumed"].plumed_inc))
-
- mkf.write("\n# COMPILER, LINKER, TOOLS\n\n")
- mkf.write("FC = {0}\nCC = {1}\nCXX = {2}\nLD = {3}\n".format(fc, cc, cxx, fc))
-
- if spec.satisfies("%intel"):
- intel_bin_dir = ancestor(pkg.compiler.cc)
- # CPP is a commented command in Intel arch of CP2K
- # This is the hack through which cp2k developers avoid doing :
- #
- # ${CPP} .F > .f90
- #
- # and use `-fpp` instead
- mkf.write("CPP = # {0} -P\n".format(spack_cc))
- mkf.write("AR = {0}/xiar -qs\n".format(intel_bin_dir))
- else: # incl. spec.satisfies("%intel-oneapi-compilers")
- mkf.write("CPP = # {0} -E\n".format(spack_cc))
- mkf.write("AR = ar -qs\n") # r = qs is a GNU extension
-
- if spec.satisfies("+cuda"):
- mkf.write(
- "{0} = {1}\n".format(
- acc_compiler_var, join_path(spec["cuda"].prefix, "bin", "nvcc")
- )
- )
-
- # Write compiler flags to file
- def fflags(var, lst):
- return "{0} = {1}\n\n".format(var, " \\\n\t".join(lst))
-
- mkf.write("\n# FLAGS & LIBRARIES\n")
- mkf.write(fflags("DFLAGS", dflags))
- mkf.write(fflags("CPPFLAGS", cppflags))
- mkf.write(fflags("CFLAGS", cflags))
- mkf.write(fflags("CXXFLAGS", cxxflags))
- if spec.satisfies("+cuda"):
- mkf.write(fflags(acc_flags_var, nvflags))
- if "+rocm" in spec:
- mkf.write("OFFLOAD_TARGET = hip\n")
-
- mkf.write(fflags("FCFLAGS", fcflags))
- mkf.write(fflags("LDFLAGS", ldflags))
- mkf.write(fflags("LIBS", libs))
-
- if spec.satisfies("%intel") or spec.satisfies("%intel-oneapi-compilers"):
- mkf.write(fflags("LDFLAGS_C", ldflags + ["-nofor-main"]))
-
- if spec.satisfies("%aocc@5:"):
- # ensure C based applications can be build properly
- mkf.write(fflags("LDFLAGS_C", ldflags + ["-fno-fortran-main"]))
- # This flag is required for the correct runtime behaviour of the code with aocc@5.0
- mkf.write(fflags("FCFLAGS", fcflags + ["-mllvm -enable-newgvn=true"]))
-
- mkf.write("# CP2K-specific flags\n\n")
- mkf.write("GPUVER = {0}\n".format(gpuver))
- mkf.write("DATA_DIR = {0}\n".format(prefix.share.data))
-
- def build(self, pkg, spec, prefix):
- if "+cuda" in spec and len(spec.variants["cuda_arch"].value) > 1:
- raise InstallError("cp2k supports only one cuda_arch at a time")
-
- # Apparently the Makefile bases its paths on PWD
- # so we need to set PWD = self.build_directory
- with set_env(PWD=self.build_directory):
- super().build(pkg, spec, prefix)
-
- with working_dir(self.build_directory):
- make("libcp2k", *self.build_targets)
-
- def install(self, pkg, spec, prefix):
- exe_dir = join_path("exe", self.makefile_architecture)
- lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
-
- install_tree(exe_dir, self.prefix.bin)
- install_tree("data", self.prefix.share.data)
- install_tree(lib_dir, self.prefix.lib)
-
- mkdirp(self.prefix.include)
- install("src/start/libcp2k.h", join_path(self.prefix.include, "libcp2k.h"))
-
- @property
- def build_directory(self):
- build_dir = self.pkg.stage.source_path
-
- if self.spec.satisfies("@:6"):
- # prior to version 7.1 was the Makefile located in makefiles/
- build_dir = join_path(build_dir, "makefiles")
-
- return build_dir
-
- @property
- def build_targets(self):
- return [
- "ARCH={0}".format(self.makefile_architecture),
- "VERSION={0}".format(self.makefile_version),
- ]
-
- @property
- def makefile(self):
- makefile_basename = ".".join([self.makefile_architecture, self.makefile_version])
- return join_path("arch", makefile_basename)
-
- @property
- def makefile_architecture(self):
- return "{0.architecture}-{0.compiler.name}".format(self.spec)
-
- @property
- def makefile_version(self):
- return "{prefix}{suffix}".format(
- prefix="p" if "+mpi" in self.spec else "s",
- suffix="smp" if "+openmp" in self.spec else "opt",
- )
-
- @property
- def archive_files(self):
- return [join_path(self.pkg.stage.source_path, self.makefile)]
-
- def check(self):
- data_dir = join_path(self.pkg.stage.source_path, "data")
-
- # CP2K < 7 still uses $PWD to detect the current working dir
- # and Makefile is in a subdir, account for both facts here:
- with set_env(CP2K_DATA_DIR=data_dir, PWD=self.build_directory):
- with working_dir(self.build_directory):
- make("test", *self.build_targets)
-
- @run_after("install", when="@9.1:")
- def fix_package_config(self):
- """
- Default build procedure generates libcp2k.pc with invalid paths,
- because they are collected from temporary directory.
-
- Ignoring invalid paths, most library-related switches are correct
- except for fftw and openblas.
-
- This procedure is appending two missing switches (tested with GROMACS 2022.2 + CP2K).
-
- In case such approach causes issues in the future, it might be necessary
- to generate and override entire libcp2k.pc.
- """
- pkgconfig_file = join_path(self.prefix.lib.pkgconfig, "libcp2k.pc")
- filter_file(r"(^includedir=).*", r"\1{0}".format(self.prefix.include), pkgconfig_file)
- filter_file(r"(^libdir=).*", r"\1{0}".format(self.prefix.lib), pkgconfig_file)
-
- with open(pkgconfig_file, "r+") as handle:
- content = handle.read().rstrip()
-
- content += " " + self.spec["blas"].libs.ld_flags
- content += " " + self.spec["lapack"].libs.ld_flags
- content += " " + self.spec["fftw-api"].libs.ld_flags
-
- fftw = self.spec["fftw-api"]
- if fftw.name in ["fftw", "amdfftw", "cray-fftw"] and fftw.satisfies("+openmp"):
- content += " -lfftw3_omp"
-
- content += "\n"
-
- handle.seek(0)
- handle.write(content)
-
-
-class CMakeBuilder(cmake.CMakeBuilder):
- def cmake_args(self):
- spec = self.spec
- args = []
-
- if spec.satisfies("+opencl"):
- args += [self.define("CP2K_USE_ACCEL", "OPENCL")]
-
- if spec.satisfies("+cuda"):
- if (len(spec.variants["cuda_arch"].value) > 1) or spec.satisfies("cuda_arch=none"):
- raise InstallError("CP2K supports only one cuda_arch at a time.")
- else:
- gpu_ver = GPU_MAP[spec.variants["cuda_arch"].value[0]]
- if spec.satisfies("+hip_backend_cuda"):
- args += [
- self.define("CP2K_USE_ACCEL", "HIP"),
- self.define("CMAKE_HIP_PLATFORM", "nvidia"),
- ]
- else:
- args += [self.define("CP2K_USE_ACCEL", "CUDA")]
-
- args += [self.define("CP2K_WITH_GPU", gpu_ver)]
-
- if spec.satisfies("+rocm"):
- if len(spec.variants["amdgpu_target"].value) > 1:
- raise InstallError("CP2K supports only one amdgpu_target at a time.")
- else:
- gpu_ver = GPU_MAP[spec.variants["amdgpu_target"].value[0]]
- args += [
- self.define("CP2K_USE_ACCEL", "HIP"),
- self.define("CP2K_WITH_GPU", gpu_ver),
- ]
-
- args += [
- "-DCP2K_USE_FFTW3=ON",
- self.define_from_variant("CP2K_USE_MPI", "mpi"),
- self.define_from_variant("CP2K_ENABLE_REGTESTS", "enable_regtests"),
- self.define_from_variant("CP2K_USE_ELPA", "elpa"),
- self.define_from_variant("CP2K_USE_DLAF", "dlaf"),
- self.define_from_variant("CP2K_USE_LIBINT2", "libint"),
- self.define_from_variant("CP2K_USE_SIRIUS", "sirius"),
- self.define_from_variant("CP2K_USE_SPLA", "spla"),
- self.define_from_variant("CP2K_USE_COSMA", "cosma"),
- self.define_from_variant("CP2K_USE_LIBXC", "libxc"),
- self.define_from_variant("CP2K_USE_LIBTORCH", "pytorch"),
- self.define_from_variant("CP2K_USE_OPENPMD", "openpmd-api"),
- self.define_from_variant("CP2K_USE_METIS", "pexsi"),
- self.define_from_variant("CP2K_USE_SUPERLU", "pexsi"),
- self.define_from_variant("CP2K_USE_PLUMED", "plumed"),
- self.define_from_variant("CP2K_USE_SPGLIB", "spglib"),
- self.define_from_variant("CP2K_USE_VORI", "libvori"),
- self.define_from_variant("CP2K_USE_SPLA", "spla"),
- self.define_from_variant("CP2K_USE_QUIP", "quip"),
- self.define_from_variant("CP2K_USE_DFTD4", "dftd4"),
- self.define_from_variant("CP2K_USE_MPI_F08", "mpi_f08"),
- self.define_from_variant("CP2K_USE_LIBSMEAGOL", "smeagol"),
- self.define_from_variant("CP2K_ENABLE_GRID_GPU", "grid_gpu"),
- self.define_from_variant("CP2K_ENABLE_DBM_GPU", "dbm_gpu"),
- self.define_from_variant("CP2K_ENABLE_PW_GPU", "pw_gpu"),
- self.define_from_variant("CP2K_USE_GRPP", "grpp"),
- self.define_from_variant("CP2K_USE_HDF5", "hdf5"),
- self.define_from_variant("CP2K_USE_DEEPMD", "deepmd"),
- self.define_from_variant("CP2K_USE_TREXIO", "trexio"),
- self.define_from_variant("CP2K_USE_GREENX", "greenx"),
- self.define_from_variant("CP2K_USE_LIBVDWXC", "vdwxc"),
- self.define_from_variant("CP2K_USE_TBLITE", "tblite"),
- ]
-
- if spec.satisfies("+sirius"):
- args += [
- self.define_from_variant("CP2K_USE_SIRIUS_DFTD4", "dftd4"),
- self.define_from_variant("CP2K_USE_SIRIUS_VCSQNM", "vcsqnm"),
- self.define_from_variant("CP2K_USE_SIRIUS_NLCG", "nlcg"),
- ]
- if spec.satisfies("^[virtuals=fftw-api] fftw+openmp"):
- args += ["-DCP2K_USE_FFTW3_WITH_OPENMP=ON"]
-
- # we force the use elpa openmp threading support. might need to be revisited though
- args += [
- self.define(
- "CP2K_ENABLE_ELPA_OPENMP_SUPPORT",
- ("+elpa +openmp" in spec) or ("^elpa +openmp" in spec),
- )
- ]
-
- if "spla" in spec and (spec.satisfies("+cuda") or spec.satisfies("+rocm")):
- args += ["-DCP2K_USE_SPLA_GEMM_OFFLOADING=ON"]
-
- if spec.satisfies("smm=libxsmm"):
- args += ["-DCP2K_USE_LIBXSMM=ON"]
- else:
- args += ["-DCP2K_USE_LIBXSMM=OFF"]
-
- lapack = spec["lapack"]
- blas = spec["blas"]
-
- if blas.name == "intel-oneapi-mkl":
- args += ["-DCP2K_BLAS_VENDOR=MKL"]
-
- if spec.satisfies("+openmp"):
- mkl_thread = "thread" if spec.satisfies("%gcc") else "intel-thread"
- args += [f"-DCP2K_BLAS_THREADING={mkl_thread}"]
- else:
- args += ["-DCP2K_BLAS_THREADING=sequential"]
-
- if sys.platform == "darwin":
- args += [
- self.define("CP2K_BLAS_VENDOR", "CUSTOM"),
- self.define("CP2K_SCALAPACK_VENDOR", "GENERIC"),
- self.define(
- "CP2K_SCALAPACK_LINK_LIBRARIES", spec["scalapack"].libs.joined(";")
- ),
- ]
- else:
- args += ["-DCP2K_SCALAPACK_VENDOR=MKL"]
- else:
- args.extend(
- [
- self.define("CP2K_LAPACK_FOUND", True),
- self.define("CP2K_LAPACK_LINK_LIBRARIES", lapack.libs.joined(";")),
- self.define("CP2K_BLAS_FOUND", True),
- self.define("CP2K_BLAS_LINK_LIBRARIES", blas.libs.joined(";")),
- self.define("CP2K_SCALAPACK_FOUND", True),
- self.define("CP2K_SCALAPACK_INCLUDE_DIRS", spec["scalapack"].prefix.include),
- self.define("CP2K_BLAS_VENDOR", "CUSTOM"),
- self.define("CP2K_SCALAPACK_VENDOR", "GENERIC"),
- self.define(
- "CP2K_SCALAPACK_LINK_LIBRARIES", spec["scalapack"].libs.joined(";")
- ),
- ]
- )
-
- return args
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/posix_c_source.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/posix_c_source.patch
deleted file mode 100644
index 87a544a..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/posix_c_source.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/src/sockets.c 2019-12-24 01:41:57.000000000 +0530
-+++ b/src/sockets.c 2023-05-15 18:35:33.941236292 +0530
-@@ -35,6 +35,7 @@
- */
- #ifndef __NO_IPI_DRIVER
-
-+#define _POSIX_C_SOURCE 200112L
- #include
- #include
- #include
-
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius-api-7.7.0.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius-api-7.7.0.patch
deleted file mode 100644
index f63b880..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius-api-7.7.0.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index b9e660fbfd2..06ccb802a9b 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -692,7 +692,7 @@ endif()
-
- # SIRIUS
- if(CP2K_USE_SIRIUS)
-- find_package(sirius REQUIRED)
-+ find_package(sirius 7.7.0 REQUIRED)
- endif()
-
- if(CP2K_USE_PLUMED)
-diff --git a/src/sirius_interface.F b/src/sirius_interface.F
-index f6dc257c5d4..a84223d2433 100644
---- a/src/sirius_interface.F
-+++ b/src/sirius_interface.F
-@@ -145,7 +145,7 @@ SUBROUTINE cp_sirius_create_env(pwdft_env)
- magnetization, mass, pf, rl, zeff, alpha_u, beta_u, &
- J0_u, J_u, U_u, occ_u, u_minus_J
- REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: beta, corden, ef, fe, locpot, rc, rp
-- REAL(KIND=dp), DIMENSION(3) :: vr, vs
-+ REAL(KIND=dp), DIMENSION(3) :: vr, vs, j_t
- REAL(KIND=dp), DIMENSION(:), POINTER :: density
- REAL(KIND=dp), DIMENSION(:, :), POINTER :: wavefunction, wfninfo
- TYPE(atom_gthpot_type), POINTER :: gth_atompot
-@@ -464,12 +464,14 @@ SUBROUTINE cp_sirius_create_env(pwdft_env)
- CPABORT("CP2K/SIRIUS (hubbard): the occupation number can not be negative.")
- END IF
-
-+ j_t(:) = 0.0
- IF (ABS(u_minus_j) < 1e-8) THEN
-+ j_t(1) = J_u
- CALL sirius_set_atom_type_hubbard(sctx, label, lu, nu, &
-- occ_u, U_u, J_u, alpha_u, beta_u, J0_u)
-+ occ_u, U_u, j_t, alpha_u, beta_u, J0_u)
- ELSE
- CALL sirius_set_atom_type_hubbard(sctx, label, lu, nu, &
-- occ_u, u_minus_j, 0.0_dp, alpha_u, beta_u, J0_u)
-+ occ_u, u_minus_j, j_t, alpha_u, beta_u, J0_u)
- END IF
- END IF
-
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius_dftd4.patch b/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius_dftd4.patch
deleted file mode 100644
index 40c0753..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/cp2k/sirius_dftd4.patch
+++ /dev/null
@@ -1,416 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 8ba3d8c857..15d1b79b77 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -23,7 +23,6 @@ endif()
- # =================================================================================================
- # PROJECT AND VERSION
- include(CMakeDependentOption)
--include(GitSubmodule)
- include(CustomTargets)
-
- cmake_policy(SET CMP0048 NEW)
-@@ -55,7 +54,7 @@ if(NOT DEFINED CMAKE_CUDA_STANDARD)
- endif()
-
- if(NOT DEFINED CMAKE_CXX_STANDARD)
-- set(CMAKE_CXX_STANDARD 14)
-+ set(CMAKE_CXX_STANDARD 17)
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
- endif()
-
-@@ -185,18 +184,18 @@ cmake_dependent_option(CP2K_USE_SIRIUS_NLCG "Enable nlcg method in SIRIUS" OFF
-
- cmake_dependent_option(
- CP2K_DBCSR_USE_CPU_ONLY "Disable the DBCSR accelerated backend" OFF
-- "NOT CP2K_USE_ACCEL MATCHES \"OPENCL\"" OFF)
-+ "NOT CP2K_USE_ACCEL MATCHES \"OPENCL|HIP|CUDA\"" OFF)
-
- cmake_dependent_option(
-- CP2K_ENABLE_DBM_GPU "Disable the dbm accelerated backend (mostly GPU)." ON
-+ CP2K_ENABLE_DBM_GPU "Enable the dbm accelerated backend (mostly GPU)." ON
- "CP2K_USE_ACCEL" OFF)
-
- cmake_dependent_option(
-- CP2K_ENABLE_GRID_GPU "Disable acceleration for grid related functions." ON
-+ CP2K_ENABLE_GRID_GPU "Enable acceleration for grid related functions." ON
- "CP2K_USE_ACCEL MATCHES \"HIP|CUDA\"" OFF)
-
- cmake_dependent_option(
-- CP2K_ENABLE_PW_GPU "Disable the ffts accelerated backend (mostly GPU)." ON
-+ CP2K_ENABLE_PW_GPU "Enable the ffts accelerated backend (mostly GPU)." ON
- "CP2K_USE_ACCEL MATCHES \"HIP|CUDA\"" OFF)
-
- cmake_dependent_option(
-@@ -230,7 +229,21 @@ cmake_dependent_option(
-
- set(CP2K_BLAS_VENDOR
- "auto"
-- CACHE STRING "BLAS library for computations on host")
-+ CACHE STRING "blas vendor/generic libraries")
-+
-+set_property(
-+ CACHE CP2K_BLAS_VENDOR
-+ PROPERTY STRINGS
-+ "auto"
-+ "MKL"
-+ "OpenBLAS"
-+ "SCI"
-+ "GenericBLAS"
-+ "Armpl"
-+ "FlexiBLAS"
-+ "Atlas"
-+ "NVHPCBlas"
-+ "CUSTOM")
-
- set(CP2K_SCALAPACK_VENDOR_LIST "MKL" "SCI" "GENERIC" "auto")
- set(CP2K_SCALAPACK_VENDOR
-@@ -761,14 +774,10 @@ endif()
-
- if(CP2K_USE_ACE)
- find_package(ACE REQUIRED)
-- get_target_property(CP2K_ACE_INCLUDE_DIRS ACE::pace
-+ get_target_property(CP2K_ACE_INCLUDE_DIRS cp2k::ACE
- INTERFACE_INCLUDE_DIRECTORIES)
-- get_target_property(CP2K_ACE_LINK_LIBRARIES ACE::pace
-+ get_target_property(CP2K_ACE_LINK_LIBRARIES cp2k::ACE
- INTERFACE_LINK_LIBRARIES)
-- get_target_property(LIB_PATH ACE::yaml-cpp-pace INTERFACE_LINK_LIBRARIES)
-- list(APPEND CP2K_ACE_LINK_LIBRARIES ${LIB_PATH})
-- get_target_property(LIB_PATH ACE::cnpy INTERFACE_LINK_LIBRARIES)
-- list(APPEND CP2K_ACE_LINK_LIBRARIES ${LIB_PATH})
- endif()
-
- if(CP2K_USE_TBLITE)
-@@ -776,9 +785,10 @@ if(CP2K_USE_TBLITE)
- find_package(toml-f REQUIRED)
- find_package(s-dftd3 REQUIRED)
- find_package(tblite REQUIRED)
-+ add_library(cp2k::tblite INTERFACE IMPORTED)
- target_link_libraries(
-- tblite::tblite INTERFACE mctc-lib::mctc-lib dftd4::dftd4 toml-f::toml-f
-- s-dftd3::s-dftd3)
-+ cp2k::tblite INTERFACE tblite::tblite mctc-lib::mctc-lib dftd4::dftd4
-+ toml-f::toml-f s-dftd3::s-dftd3)
- endif()
-
- # SIRIUS
-@@ -825,6 +835,9 @@ if(CP2K_USE_GREENX)
- set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-L${GMP_LIBRARY_PATH}")
- set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}
- "-L${GMP_LIBRARY_PATH}")
-+
-+ add_library(cp2k::greenx INTERFACE greenX::GXCommon greenX::LibGXAC
-+ greenX::LibGXMiniMax cp2k::trexio::trexio)
- endif()
-
- # OPTION HANDLING
-diff --git a/cmake/CompilerConfiguration.cmake b/cmake/CompilerConfiguration.cmake
-index 6469558f56..93b946fa58 100644
---- a/cmake/CompilerConfiguration.cmake
-+++ b/cmake/CompilerConfiguration.cmake
-@@ -37,16 +37,14 @@ endif()
- add_compile_options(
- "$<$:-std=f2008;-ffree-form;-ffree-line-length-none;-fimplicit-none>"
- "$<$:-g;-fno-omit-frame-pointer;-fbacktrace>"
-- "$<$:$<$:-fallow-argument-mismatch>>"
-+ "$<$:$<$,10>:-fallow-argument-mismatch>>"
- "$<$:-Wno-deprecated-declarations;-Wno-maybe-uninitialized;-Wuninitialized;-Wuse-without-only>"
- )
- add_compile_options(
-- "$<$:--std=c++17>"
- "$<$:-g;-fno-omit-frame-pointer>"
- "$<$:-Wno-deprecated-declarations;-Wno-vla-parameter>"
- )
- add_compile_options(
-- "$<$:-std=c11>"
- "$<$:-g;-fno-omit-frame-pointer>"
- "$<$:-Wno-deprecated-declarations;-Wno-vla-parameter>"
- )
-diff --git a/cmake/GitSubmodule.cmake b/cmake/GitSubmodule.cmake
-deleted file mode 100644
-index b9ca6a2fe1..0000000000
---- a/cmake/GitSubmodule.cmake
-+++ /dev/null
-@@ -1,30 +0,0 @@
--#!-------------------------------------------------------------------------------------------------!
--#! CP2K: A general program to perform molecular dynamics simulations !
--#! Copyright 2000-2025 CP2K developers group !
--#! !
--#! SPDX-License-Identifier: GPL-2.0-or-later !
--#!-------------------------------------------------------------------------------------------------!
--
--# Call to ensure that the git submodule in location `path` is loaded. If the
--# submodule is not loaded, an error message that describes how to update the
--# submodules is printed. Sets the variable name_avail to `ON` if the submodule
--# is available, or `OFF` otherwise. copyright github.com/arbor-sim
--
--function(check_git_submodule name path)
-- set(success_var "${name}_avail")
-- set(${success_var}
-- ON
-- PARENT_SCOPE)
--
-- get_filename_component(dotgit "${path}/.git" ABSOLUTE)
-- if(NOT EXISTS ${dotgit})
-- message(
-- FATAL_ERROR
-- "\nThe git submodule for ${name} is not available.\n"
-- "To check out all submodules use the following commands:\n"
-- " git submodule init\n"
-- " git submodule update\n"
-- "Or download submodules recursively when checking out:\n"
-- " git clone --recursive https://github.com/cp2k/cp2k.git\n")
-- endif()
--endfunction()
-diff --git a/cmake/modules/FindACE.cmake b/cmake/modules/FindACE.cmake
-index 4dfabcae18..9b69ea9109 100644
---- a/cmake/modules/FindACE.cmake
-+++ b/cmake/modules/FindACE.cmake
-@@ -24,30 +24,18 @@ cp2k_find_libraries(ACE_CNPY "cnpy")
- find_package_handle_standard_args(ACE DEFAULT_MSG CP2K_ACE_CNPY_LINK_LIBRARIES)
-
- if(CP2K_ACE_FOUND)
-- if(NOT TARGET ACE::pace)
-- add_library(ACE::pace INTERFACE IMPORTED)
-+ if(NOT TARGET cp2k::ACE)
-+ add_library(cp2k::ACE INTERFACE IMPORTED)
- endif()
- set_target_properties(
-- ACE::pace
-+ cp2k::ACE
- PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CP2K_ACE_INCLUDE_DIRS}"
- INTERFACE_LINK_LIBRARIES "${CP2K_ACE_LINK_LIBRARIES}")
--endif()
--
--if(CP2K_ACE_YAML_FOUND)
-- if(NOT TARGET ACE::yaml-cpp-pace)
-- add_library(ACE::yaml-cpp-pace INTERFACE IMPORTED)
-- endif()
-- set_target_properties(
-- ACE::yaml-cpp-pace PROPERTIES INTERFACE_LINK_LIBRARIES
-- "${CP2K_ACE_YAML_LINK_LIBRARIES}")
--endif()
-
--if(CP2K_ACE_CNPY_FOUND)
-- if(NOT TARGET ACE::cnpy)
-- add_library(ACE::cnpy INTERFACE IMPORTED)
-- endif()
-- set_target_properties(ACE::cnpy PROPERTIES INTERFACE_LINK_LIBRARIES
-- "${CP2K_ACE_CNPY_LINK_LIBRARIES}")
-+ target_link_libraries(
-+ cp2k::ACE PROPERTIES INTERFACE_LINK_LIBRARIES
-+ "$:${CP2K_ACE_YAML_LINK_LIBRARIES}>"
-+ "$:${CP2K_ACE_CNPY_LINK_LIBRARIES}>")
- endif()
-
- mark_as_advanced(CP2K_ACE_FOUND CP2K_ACE_INCLUDE_DIRS CP2K_ACE_LINK_LIBRARIES
-diff --git a/cmake/modules/FindBlas.cmake b/cmake/modules/FindBlas.cmake
-index deb67cff96..369233cae3 100644
---- a/cmake/modules/FindBlas.cmake
-+++ b/cmake/modules/FindBlas.cmake
-@@ -9,13 +9,6 @@
- #
- # authors : Mathieu Taillefumier
-
--if(NOT
-- (CMAKE_C_COMPILER_LOADED
-- OR CMAKE_CXX_COMPILER_LOADED
-- OR CMAKE_Fortran_COMPILER_LOADED))
-- message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
--endif()
--
- if(NOT CP2K_CONFIG_PACKAGE)
- set(CP2K_BLAS_VENDOR_LIST
- # cmake-format: sortable
-@@ -34,8 +27,6 @@ if(NOT CP2K_CONFIG_PACKAGE)
- list(REMOVE_ITEM __BLAS_VENDOR_LIST "auto")
- list(REMOVE_ITEM __BLAS_VENDOR_LIST "CUSTOM")
-
-- # set(CP2K_BLAS_VENDOR "auto" CACHE STRING "Blas library for computations on
-- # host")
- set_property(CACHE CP2K_BLAS_VENDOR PROPERTY STRINGS ${CP2K_BLAS_VENDOR_LIST})
-
- if(NOT ${CP2K_BLAS_VENDOR} IN_LIST CP2K_BLAS_VENDOR_LIST)
-@@ -152,3 +143,4 @@ mark_as_advanced(CP2K_BLAS_INCLUDE_DIRS)
- mark_as_advanced(CP2K_BLAS_LINK_LIBRARIES)
- mark_as_advanced(CP2K_BLAS_VENDOR)
- mark_as_advanced(CP2K_BLAS_FOUND)
-+mark_as_advanced(CP2K_BLAS_VENDOR_LIST)
-diff --git a/cmake/modules/FindLibXSMM.cmake b/cmake/modules/FindLibXSMM.cmake
-index 60fe8c836d..4d0fe8f2eb 100644
---- a/cmake/modules/FindLibXSMM.cmake
-+++ b/cmake/modules/FindLibXSMM.cmake
-@@ -75,26 +75,28 @@ else()
- CP2K_LIBXSMM_LINK_LIBRARIES)
- endif()
-
--if(NOT TARGET cp2k::LibXSMM::libxsmm)
-- foreach(__lib libxsmm libxsmmf libxsmmext libxsmmnoblas)
-+if(NOT TARGET cp2k::LibXSMM)
-+ add_library(cp2k::LibXSMM INTERFACE IMPORTED)
-+ foreach(__lib libxsmmf libxsmmext libxsmm libxsmmnoblas)
- string(TOUPPER "CP2K_${__lib}" __lib_search_up)
-
- if(${__lib_search_up}_FOUND AND NOT TARGET cp2k::LibXSMM::${__lib})
- add_library(cp2k::LibXSMM::${__lib} INTERFACE IMPORTED)
- target_link_directories(cp2k::LibXSMM::${__lib} INTERFACE
- ${${__lib_search_up}_LIBRARY_DIRS})
-- endif()
--
-- set_target_properties(
-- cp2k::LibXSMM::${__lib} PROPERTIES INTERFACE_LINK_LIBRARIES
-- "${${__lib_search_up}_LINK_LIBRARIES}")
--
-- if(CP2K_LIBXSMM_INCLUDE_DIRS)
- set_target_properties(
- cp2k::LibXSMM::${__lib}
-- PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-- "${CP2K_LIBXSMM_INCLUDE_DIRS};${CP2K_LIBXSMM_PREFIX}/include"
-- )
-+ PROPERTIES INTERFACE_LINK_LIBRARIES
-+ "${${__lib_search_up}_LINK_LIBRARIES}")
-+
-+ if(CP2K_LIBXSMM_INCLUDE_DIRS)
-+ set_target_properties(
-+ cp2k::LibXSMM::${__lib}
-+ PROPERTIES
-+ INTERFACE_INCLUDE_DIRECTORIES
-+ "${CP2K_LIBXSMM_INCLUDE_DIRS};${CP2K_LIBXSMM_PREFIX}/include")
-+ endif()
-+ target_link_libraries(cp2k::LibXSMM INTERFACE cp2k::LibXSMM::${__lib})
- endif()
- endforeach()
- endif()
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index d2baf2a32b..ab2e674807 100644
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -1635,14 +1635,13 @@ set(CP2K_GPU_DFLAGS
- # ##############################################################################
-
- add_fypp_sources(CP2K_SRCS ${CP2K_SRCS_F})
--
--# TODO Add __SHORT_FILE__ also to program files, e.g. metadyn_tools/graph.F
-+add_fypp_sources(CP2K_PROGS_F_FYPP ${CP2K_PROGS_F})
-
- # set the __SHORT_FILE__ per file for CP2K sources
--foreach(cp2k_src ${CP2K_SRCS})
-- # add_fypp_sources returns a path in the current binary dir
-- file(RELATIVE_PATH short_file "${CMAKE_BINARY_DIR}/src" "${cp2k_src}")
-- set_source_files_properties(
-+foreach(cp2k_src ${CP2K_SRCS} ${CP2K_PROGS_F_FYPP})
-+# add_fypp_sources returns a path in the current binary dir
-+file(RELATIVE_PATH short_file "${CMAKE_BINARY_DIR}/src" "${cp2k_src}")
-+set_source_files_properties(
- ${cp2k_src} PROPERTIES COMPILE_DEFINITIONS __SHORT_FILE__="${short_file}")
- endforeach()
-
-diff --git a/src/input_cp2k_pwdft.F b/src/input_cp2k_pwdft.F
-index 0a86c14b9f..507c89efa5 100644
---- a/src/input_cp2k_pwdft.F
-+++ b/src/input_cp2k_pwdft.F
-@@ -18,7 +18,7 @@ MODULE input_cp2k_pwdft
- USE SIRIUS, ONLY: &
- sirius_option_get, &
- sirius_option_get_section_length, sirius_option_get_info, &
-- SIRIUS_INTEGER_TYPE, SIRIUS_NUMBER_TYPE, SIRIUS_STRING_TYPE, &
-+ SIRIUS_INTEGER_TYPE, SIRIUS_NUMBER_TYPE, SIRIUS_STRING_TYPE, SIRIUS_OBJECT_TYPE, &
- SIRIUS_LOGICAL_TYPE, SIRIUS_ARRAY_TYPE, SIRIUS_INTEGER_ARRAY_TYPE, SIRIUS_LOGICAL_ARRAY_TYPE, &
- SIRIUS_NUMBER_ARRAY_TYPE, SIRIUS_STRING_ARRAY_TYPE, string_f2c
- #endif
-@@ -186,13 +186,13 @@ CONTAINS
- CHARACTER(len=*), INTENT(in) :: section_name
-
- CHARACTER(len=128) :: name
-- CHARACTER(len=128), TARGET :: possible_values(1:16)
-+ CHARACTER(len=128), TARGET :: possible_values(1:256)
- CHARACTER(len=4096) :: description, usage
-- INTEGER :: ctype, enum_i_val(1:16), enum_length, i, &
-- j, length, num_possible_values
-- INTEGER, ALLOCATABLE, DIMENSION(:), TARGET :: ivec
-+ INTEGER :: ctype, enum_length, i, j, length, &
-+ num_possible_values
-+ INTEGER, ALLOCATABLE, DIMENSION(:), TARGET :: enum_i_val, ivec
- INTEGER, TARGET :: dummy_i
-- LOGICAL :: lvecl(1:16)
-+ LOGICAL :: jump_dft_parameters, lvecl(1:16)
- LOGICAL(4), ALLOCATABLE, DIMENSION(:), TARGET :: lvec
- LOGICAL(4), TARGET :: dummy_l
- REAL(kind=dp), ALLOCATABLE, DIMENSION(:), TARGET :: rvec
-@@ -202,7 +202,8 @@ CONTAINS
- ALLOCATE (ivec(1:16))
- ALLOCATE (rvec(1:16))
- ALLOCATE (lvec(1:16))
--
-+ ALLOCATE (enum_i_val(1:256))
-+ jump_dft_parameters = .FALSE.
- #ifdef __LIBVDWXC
- IF (section_name == "parameters") THEN
- NULLIFY (keyword)
-@@ -238,10 +239,18 @@ CONTAINS
- 4096, &
- usage, &
- 4096)
-+
- ! description and usage are ignored here
- ! it is a minor inconvenience from the api.
--
- name = TRIM(ADJUSTL(name))
-+
-+#if defined(__SIRIUS_DFTD4)
-+ ! need to implement the object case within a section
-+ IF (((section_name == 'dftd3') .OR. (section_name == 'dftd4')) .AND. (name == 'parameters')) THEN
-+ CYCLE
-+ END IF
-+#endif
-+
- ! I exclude these three keywords because one of them is for debugging
- ! purpose the other are replaced by a dedicated call in cp2k
- !
-@@ -403,10 +412,19 @@ CONTAINS
- END IF
- CALL section_add_keyword(section, keyword)
- CALL keyword_release(keyword)
-+ !CASE (SIRIUS_OBJECT_TYPE)
-+ ! create a subsection for the dftd3/dftd4 parameters
-+ !CALL create_sirius_section(sub_section, sub_section_name)
-+ !CALL section_add_subsection(section, sub_section)
-+ !CALL section_release(sub_section)
- CASE default
- END SELECT
- END IF
- END DO
-+ DEALLOCATE (ivec)
-+ DEALLOCATE (rvec)
-+ DEALLOCATE (lvec)
-+ DEALLOCATE (enum_i_val)
- END SUBROUTINE fill_in_section
-
- ! **************************************************************************************************
-diff --git a/src/sirius_interface.F b/src/sirius_interface.F
-index 120998477f..f3b18804df 100644
---- a/src/sirius_interface.F
-+++ b/src/sirius_interface.F
-@@ -229,7 +229,7 @@ CONTAINS
- CASE (SIRIUS_FUNC_VDWDF2)
- CALL sirius_add_xc_functional(sctx, "XC_FUNC_VDWDF2")
- CASE (SIRIUS_FUNC_VDWDFCX)
-- CALL sirius_add_xc_functional(sctx, "XC_FUNC_VDWDF2")
-+ CALL sirius_add_xc_functional(sctx, "XC_FUNC_VDWDFCX")
- CASE default
- END SELECT
- #endif
-@@ -671,6 +671,12 @@ CONTAINS
- 4096, &
- usage, &
- 4096)
-+
-+ ! ignore the keyword parametes for sections dftd3 and dftd4.
-+ IF (((section_name == 'dftd3') .OR. (section_name == 'dftd4')) .AND. (option_name == 'parameters')) THEN
-+ CYCLE
-+ END IF
-+
- IF ((option_name /= 'memory_usage') .AND. (option_name /= 'xc_functionals') .AND. (option_name /= 'vk')) THEN
- CALL section_vals_val_get(section, option_name, explicit=found)
- IF (found) THEN
diff --git a/cp2k/docker/cp2k_environment/repos/packages/dbcsr/0001-Update-c-standard.patch b/cp2k/docker/cp2k_environment/repos/packages/dbcsr/0001-Update-c-standard.patch
deleted file mode 100644
index 2184d8b..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/dbcsr/0001-Update-c-standard.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From ec31484c3848cfa4baaf98e55ad2f035be044f29 Mon Sep 17 00:00:00 2001
-From: Mathieu Taillefumier
-Date: Thu, 13 Feb 2025 12:39:23 +0100
-Subject: [PATCH] Update c++ standard
-
----
- CMakeLists.txt | 30 ++++++++++++++++++++-------
- src/acc/libsmm_acc/tune/tune_setup.py | 2 +-
- 2 files changed, 24 insertions(+), 8 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 601570c24ab..2124756ad22 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -77,6 +77,8 @@ option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
- option(USE_OPENMP "Build with OpenMP support" ON)
- option(USE_MPI "Build with MPI support" ON)
- option(USE_MPI_F08 "Build with the mpi_f08 module support" OFF)
-+option(BUILD_TESTING "build dbcsr unit tests" OFF)
-+
- cmake_dependent_option(
- WITH_C_API "Build the C API (ISO_C_BINDINGS)" ON "USE_MPI" OFF
- )# the ISO_C_BINDINGS require MPI unconditionally
-@@ -126,14 +128,28 @@ option(WITH_HIP_PROFILING "Enable profiling within HIP" OFF)
- # =================================================================================================
- # LANGUAGES AND TESTING
- enable_language(Fortran)
-+enable_language(CXX)
-+enable_language(C)
-
--if (WITH_C_API AND WITH_EXAMPLES)
-- enable_language(CXX)
-- enable_language(C)
--endif ()
-+if(NOT DEFINED CMAKE_CUDA_STANDARD)
-+ set(CMAKE_CUDA_STANDARD 14)
-+ set(CMAKE_CUDA_STANDARD_REQUIRED ON)
-+endif()
-+
-+if(NOT DEFINED CMAKE_CXX_STANDARD)
-+ set(CMAKE_CXX_STANDARD 14)
-+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
-+endif()
-+
-+if(NOT DEFINED CMAKE_C_STANDARD)
-+ set(CMAKE_C_STANDARD 11)
-+ set(CMAKE_C_STANDARD_REQUIRED ON)
-+endif()
-
--# always use at least C++11
--set(CMAKE_CXX_STANDARD 11)
-+if(NOT DEFINED CMAKE_HIP_STANDARD)
-+ set(CMAKE_HIP_STANDARD 14)
-+ set(CMAKE_HIP_STANDARD_REQUIRED ON)
-+endif()
-
- # =================================== OpenMP
- if (USE_OPENMP)
-@@ -365,8 +381,8 @@ include(CheckCompilerSupport)
- # subdirectories
- add_subdirectory(${DBCSR_SOURCE_DIR})
-
--include(CTest)
- if (BUILD_TESTING)
-+ include(CTest)
- add_subdirectory(tests)
- endif ()
-
-diff --git a/src/acc/libsmm_acc/tune/tune_setup.py b/src/acc/libsmm_acc/tune/tune_setup.py
-index deb8a10011e..9a430509dc5 100755
---- a/src/acc/libsmm_acc/tune/tune_setup.py
-+++ b/src/acc/libsmm_acc/tune/tune_setup.py
-@@ -361,7 +361,7 @@ def gen_makefile(outdir, compiler, arch):
- output += (
- "\tnvcc -O3 -D__TUNING -D__CUDA -arch="
- + str(arch)
-- + " -w -c -o $@ -std=c++11 $<\n\n"
-+ + " -w -c -o $@ -std=c++14 $<\n\n"
- )
- else:
- output += (
---
-2.51.0
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/dbcsr/package.py b/cp2k/docker/cp2k_environment/repos/packages/dbcsr/package.py
deleted file mode 100644
index fe2b3dc..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/dbcsr/package.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# Copyright Spack Project Developers. See COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-import os
-
-from spack_repo.builtin.build_systems.cmake import CMakePackage, generator
-from spack_repo.builtin.build_systems.cuda import CudaPackage
-from spack_repo.builtin.build_systems.rocm import ROCmPackage
-
-from spack.package import *
-
-
-class Dbcsr(CMakePackage, CudaPackage, ROCmPackage):
- """Distributed Block Compressed Sparse Row matrix library."""
-
- homepage = "https://github.com/cp2k/dbcsr"
- git = "https://github.com/cp2k/dbcsr.git"
- url = "https://github.com/cp2k/dbcsr/releases/download/v2.2.0/dbcsr-2.2.0.tar.gz"
- list_url = "https://github.com/cp2k/dbcsr/releases"
-
- maintainers("dev-zero", "mtaillefumier", "RMeli", "hfp")
-
- license("GPL-2.0-or-later")
-
- version("develop", branch="develop")
- version("2.9.1", sha256="fa5a4aeba0a07761511af2c26c779bd811b5ea0ef06a5d94535b6dd7b2e0ce59")
- version("2.9.0", sha256="a04cacd2203bd97a31ac993f9ab84237a48191140bba29efadbc27db544bbcd6")
- version("2.8.0", sha256="d55e4f052f28d1ed0faeaa07557241439243287a184d1fd27f875c8b9ca6bd96")
- version("2.7.0", sha256="25c367b49fb108c5230bcfb127f05fc16deff2bb467f437023dfa6045aff66f6")
- version("2.6.0", sha256="c67b02ff9abc7c1f529af446a9f01f3ef9e5b0574f220259128da8d5ca7e9dc6")
- version("2.5.0", sha256="91fda9b2502e5d0a2a6cdd5a73ef096253cc7e75bd01ba5189a4726ad86aef08")
- version("2.4.1", sha256="b3d5ae62ca582b72707a2c932e8074a4f2f61d61085d97bd374213c70b8dbdcf")
- version("2.4.0", sha256="cf2b774328c9a30677501f49b79955841bd08915a7ca53c8533bfdf14a8f9bd4")
- version("2.3.0", sha256="f750de586cffa66852b646f7f85eb831eeb64fa2d25ce50ed10e1df016dd3364")
- version("2.2.0", sha256="245b0382ddc7b80f85af8288f75bd03d56ec51cdfb6968acb4931529b35173ec")
- version("2.1.0", sha256="9e58fd998f224632f356e479d18b5032570d00d87b86736b6a6ac2d03f8d4b3c")
- version("2.0.1", sha256="61d5531b661e1dab043353a1d67939ddcde3893d3dc7b0ab3d05074d448b485c")
-
- variant("tests", default=False, description="Build DBCSR unit tests")
- variant("tests", default=True, description="Build DBCSR unit tests", when="@2.1:2.2")
- variant("mpi", default=True, description="Compile with MPI")
- variant("openmp", default=True, description="Build with OpenMP support")
- variant("shared", default=True, description="Build shared library")
- variant(
- "smm",
- default="libxsmm",
- values=("libxsmm", "blas"),
- description="Library for small matrix multiplications",
- )
- variant(
- "cuda_arch_35_k20x",
- default=False,
- description=(
- "CP2K (resp. DBCSR) has specific parameter sets for"
- " different GPU models. Enable this when building"
- " with cuda_arch=35 for a K20x instead of a K40"
- ),
- )
- variant("examples", default=True, description="Build examples")
-
- variant("opencl", default=False, description="Enable OpenCL backend")
- variant("mpi_f08", default=False, when="@2.6:", description="Use mpi F08 module")
-
- variant("g2g", default=False, when="@:2.8", description="GPU-aware MPI with CUDA/HIP")
- conflicts("+g2g", when="~cuda ~rocm", msg="GPU-aware MPI requires +cuda or +rocm")
-
- depends_on("c", type="build") # generated
- depends_on("cxx", type="build") # generated
- depends_on("fortran", type="build") # generated
-
- depends_on("blas")
- depends_on("lapack")
- depends_on("mpi", when="+mpi")
-
- with when("smm=libxsmm"):
- depends_on("libxsmm@1.11:")
-
- depends_on("cmake@3.10:", type="build")
- depends_on("cmake@3.12:", type="build", when="@2.1:")
- depends_on("cmake@3.17:", type="build", when="@2.2:")
- depends_on("cmake@3.22:", type="build", when="@2.3:")
-
- depends_on("py-fypp", type="build")
- depends_on("py-fypp@3.1:", type="build", when="@2.6:")
- depends_on("pkgconfig", type="build")
- depends_on("python@3.6:", type="build", when="+cuda")
-
- depends_on("hipblas", when="+rocm")
-
- # Several packages provide "opencl" (incl. ICD/loader), e.g., "cuda"
- depends_on("opencl", when="+opencl")
- opencl_loader_header_version = "2022.10.24"
- depends_on(f"opencl-c-headers@{opencl_loader_header_version}:", when="+opencl")
- requires(f"%opencl=opencl-icd-loader@{opencl_loader_header_version}:", when="+opencl")
-
- # All examples require MPI
- conflicts("+examples", when="~mpi", msg="Examples require MPI")
-
- # We only support specific gpu archs for which we have parameter files
- # for optimal kernels. Note that we don't override the parent class arch
- # properties, since the parent class defines constraints for different archs
- # Instead just mark all unsupported cuda archs as conflicting.
- dbcsr_cuda_archs = ("35", "37", "60", "70", "80", "90")
- cuda_msg = f"dbcsr only supports cuda_arch {dbcsr_cuda_archs}"
-
- for arch in CudaPackage.cuda_arch_values:
- if arch not in dbcsr_cuda_archs:
- conflicts("+cuda", when=f"cuda_arch={arch}", msg=cuda_msg)
-
- conflicts("+cuda", when="cuda_arch=none", msg=cuda_msg)
-
- dbcsr_amdgpu_targets = (
- "gfx906",
- "gfx910",
- "gfx90a",
- "gfx90a:xnack-",
- "gfx90a:xnack+",
- "gfx942",
- "gfx950",
- )
- amd_msg = f"""DBCSR supports these AMD gpu targets: {', '.join(dbcsr_amdgpu_targets)}.
- Set amdgpu_target explicitly to one of the supported targets"""
-
- for arch in ROCmPackage.amdgpu_targets:
- if arch not in dbcsr_amdgpu_targets:
- conflicts("+rocm", when=f"amdgpu_target={arch}", msg=amd_msg)
-
- # GPU runtimes are usually mutually exclusive
- accel_msg = "CUDA and ROCm are mutually exlusive"
- conflicts("+cuda", when="+rocm", msg=accel_msg)
- conflicts("+cuda", when="+opencl", msg=accel_msg)
- conflicts("+rocm", when="+opencl", msg=accel_msg)
-
- # Require OpenMP threading by making other options conflict
- conflicts("^intel-oneapi-mkl threads=none", when="+openmp")
- conflicts("^intel-oneapi-mkl threads=tbb", when="+openmp")
- conflicts("^openblas threads=pthreads", when="+openmp")
- conflicts("^openblas threads=none", when="+openmp")
-
- # OpenCL backend implementation relies on LIBXSMM
- requires("smm=libxsmm", when="+opencl")
-
- with when("+mpi"):
- # When using mpich 4.1 or higher, mpi_f08 has to be used, otherwise:
- # Error: Type mismatch in argument 'baseptr' at (1); passed TYPE(c_ptr)
- # to INTEGER(8)
- conflicts("^mpich@4.1:", when="@:2.5")
- conflicts("~mpi_f08", when="^mpich@4.1:")
- depends_on("mpich+fortran", when="^[virtuals=mpi] mpich")
-
- generator("ninja")
- depends_on("ninja@1.10:", type="build")
-
- @when("+rocm")
- def patch(self):
- for directory, subdirectory, files in os.walk(os.getcwd()):
- for i in files:
- file_path = os.path.join(directory, i)
- filter_file("USE ISO_C_BINDING", "USE,INTRINSIC :: ISO_C_BINDING", file_path)
- filter_file("USE ISO_FORTRAN_ENV", "USE,INTRINSIC :: ISO_FORTRAN_ENV", file_path)
- filter_file("USE omp_lib", "USE,INTRINSIC :: omp_lib", file_path)
- filter_file("USE OMP_LIB", "USE,INTRINSIC :: OMP_LIB", file_path)
- filter_file("USE iso_c_binding", "USE,INTRINSIC :: iso_c_binding", file_path)
- filter_file("USE iso_fortran_env", "USE,INTRINSIC :: iso_fortran_env", file_path)
-
- def cmake_args(self):
- spec = self.spec
-
- if "+cuda" in spec and len(spec.variants["cuda_arch"].value) > 1:
- raise InstallError("dbcsr supports only one cuda_arch at a time")
-
- if "+rocm" in spec and len(spec.variants["amdgpu_target"].value) > 1:
- raise InstallError("DBCSR supports only one amdgpu_arch at a time")
-
- args = [
- "-DUSE_SMM=%s" % ("libxsmm" if "smm=libxsmm" in spec else "blas"),
- self.define_from_variant("USE_MPI", "mpi"),
- self.define_from_variant("USE_OPENMP", "openmp"),
- # C API needs MPI
- self.define_from_variant("WITH_C_API", "mpi"),
- self.define_from_variant("BUILD_SHARED_LIBS", "shared"),
- self.define_from_variant("WITH_EXAMPLES", "examples"),
- self.define_from_variant("WITH_G2G", "g2g"),
- self.define_from_variant("BUILD_TESTING", "tests"),
- ]
-
- lapack, blas = spec["lapack"], spec["blas"]
- if blas.name != "intel-oneapi-mkl":
- args += [
- "-DBLAS_FOUND=true",
- "-DBLAS_LIBRARIES=%s" % (blas.libs.joined(";")),
- "-DLAPACK_FOUND=true",
- "-DLAPACK_LIBRARIES=%s" % (lapack.libs.joined(";")),
- ]
-
- if self.spec.satisfies("+cuda"):
- cuda_arch = self.spec.variants["cuda_arch"].value[0]
-
- gpu_map = {
- "35": "K40",
- "37": "K80",
- "60": "P100",
- "70": "V100",
- "80": "A100",
- "90": "H100",
- }
-
- gpuver = gpu_map[cuda_arch]
- if cuda_arch == "35" and self.spec.satisfies("+cuda_arch_35_k20x"):
- gpuver = "K20X"
-
- args += ["-DWITH_GPU=%s" % gpuver, "-DUSE_ACCEL=cuda"]
-
- if self.spec.satisfies("+rocm"):
- amd_arch = self.spec.variants["amdgpu_target"].value[0]
- gpuver = {
- "gfx906": "Mi50",
- "gfx908": "Mi100",
- "gfx90a": "Mi250",
- "gfx90a:xnack-": "Mi250",
- "gfx90a:xnack+": "Mi250",
- "gfx942": "Mi300",
- "gfx950": "Mi350",
- }[amd_arch]
-
- args += [f"-DWITH_GPU={gpuver}", "-DUSE_ACCEL=hip"]
-
- if self.spec.satisfies("+opencl"):
- args += ["-DUSE_ACCEL=opencl"]
-
- if self.spec.satisfies("+mpi_f08"):
- args += ["-DUSE_MPI_F08=ON"]
-
- return args
-
- def check(self):
- """Override CMakePackage's check() to enforce seralized test runs
- since they are already parallelized"""
- with working_dir(self.build_directory):
- self._if_ninja_target_execute("test", parallel=False)
diff --git a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/0001-fix-mpi-detection-in-configure.patch b/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/0001-fix-mpi-detection-in-configure.patch
deleted file mode 100644
index 58fff99..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/0001-fix-mpi-detection-in-configure.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 8b46c6b74753fbe8596e65bf29d24b15e561ca70 Mon Sep 17 00:00:00 2001
-From: Simon Pintarelli
-Date: Thu, 8 Jan 2026 17:24:09 +0100
-Subject: [PATCH] fix mpi detection in configure
-
----
- configure | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/configure b/configure
-index 7305e6d..4b1b697 100755
---- a/configure
-+++ b/configure
-@@ -21917,7 +21917,7 @@ main (void)
-
- int *argc;
- char **argv;
-- MPI_Init(argc, argv);
-+ MPI_Init(argc, &argv);
-
- ;
- return 0;
---
-2.52.0
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/fftw-detection.patch b/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/fftw-detection.patch
deleted file mode 100644
index f009188..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/fftw-detection.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/configure b/configure
-index 494ea9f..1ca6516 100755
---- a/configure
-+++ b/configure
-@@ -17006,7 +17006,7 @@ int
- main ()
- {
-
-- fftw_plan *plan;
-+ fftw_plan plan;
- fftw_complex *a1, *a2;
- fftw_execute_dft(plan, a1, a2);
-
diff --git a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/package.py b/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/package.py
deleted file mode 100644
index c676d2b..0000000
--- a/cp2k/docker/cp2k_environment/repos/packages/libvdwxc/package.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright Spack Project Developers. See COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-
-from spack_repo.builtin.build_systems.autotools import AutotoolsPackage
-
-from spack.package import *
-
-
-class Libvdwxc(AutotoolsPackage):
- """Portable C library of density functionals with van der Waals
- interactions for density functional theory"""
-
- homepage = "https://libvdwxc.gitlab.io/libvdwxc/"
- url = "https://launchpad.net/libvdwxc/stable/0.5.0/+download/libvdwxc-0.5.0.tar.gz"
- git = "https://gitlab.com/libvdwxc/libvdwxc"
-
- license("GPL-3.0-or-later")
- maintainers("mtaillefumier")
-
- version("master", branch="master", submodules=False)
- version("0.5.0", sha256="29fb70efd58aff51524d2172a87e8f88e760b696b0ddb9aa5878432bdffa3c2f")
- version("0.4.0", sha256="3524feb5bb2be86b4688f71653502146b181e66f3f75b8bdaf23dd1ae4a56b33")
-
- variant("mpi", default=True, description="Enable MPI support")
- variant("pfft", default=False, description="Enable support for PFFT")
-
- depends_on("c", type="build") # generated
- depends_on("fortran", type="build") # generated
-
- depends_on("fftw-api@3")
- depends_on("mpi@2:", when="+mpi")
- depends_on("pfft", when="+pfft")
-
- depends_on("autoconf@2.71:", type="build", when="@master")
- depends_on("automake", type="build", when="@master")
- depends_on("libtool", type="build", when="@master")
-
- # pfft needs MPI
- conflicts("~mpi", "+pfft")
- conflicts("^fftw~mpi", "+mpi")
-
- def configure_args(self):
- spec = self.spec
-
- args = [
- "--with-fftw3={0}".format(self["fftw"].prefix), # make sure that fftw path is given
- "--{0}-pfft".format("with" if self.spec.satisfies("+pfft") else "without"),
- "MPICC=", # make sure both variables are always unset
- "MPIFC=", # otherwise the configure scripts complains
- ]
-
- if spec.satisfies("+mpi"):
- # work around b0rken MPI detection: the MPI detection tests are
- # run with CC instead of MPICC, triggering an error. So, setting
- # CC/FC to the MPI compiler wrappers.
- args += [
- "--with-mpi",
- "CC={0}".format(spec["mpi"].mpicc),
- "FC={0}".format(spec["mpi"].mpifc),
- ]
- else:
- args += ["--without-mpi"]
-
- return args
-
- # misuse of fftw_plan in m4 for fftw detection (configure fails with gcc 14)
- # Only the configure script is patched, NOT the m4 macro (to avoid depending on aclocal),
- # so running autoreconf is not supported.
- # The relevant upstream fix for the m4 would be:
- # https://gitlab.com/libvdwxc/libvdwxc/-/commit/9340f857515c4a2e56d2aa7cf3a21c41ba8559c3.diff
- patch("fftw-detection.patch", when="@:0.4.0")
-
- # fix a mpi detection error
- patch(
- "0001-fix-mpi-detection-in-configure.patch",
- sha256="b1818ef7f984e398ab07f2a693ac7b2488955356645910d74a627159df97b932",
- when="@0.5.0",
- )
diff --git a/cp2k/docker/cp2k_environment/repos/repo.yaml b/cp2k/docker/cp2k_environment/repos/repo.yaml
deleted file mode 100644
index 15785ad..0000000
--- a/cp2k/docker/cp2k_environment/repos/repo.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-repo:
- namespace: cp2k
diff --git a/cp2k/docker/cp2k_environment/spack.yaml b/cp2k/docker/cp2k_environment/spack.yaml
deleted file mode 100644
index 973af33..0000000
--- a/cp2k/docker/cp2k_environment/spack.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-# This is a Spack Environment file.
-#
-# It describes a set of packages to be installed, along with
-# configuration settings.
-spack:
- repos:
- - repos
- include: [./config.yaml]
- # add package specs to the `specs` list
-# This is a Spack Environment file.
-#
- specs:
- - sirius@develop+rocm+fortran+vdwxc+dftd4+dftd3+pugixml+openmp+scalapack
- - libxc@7+fortran build_system=cmake
- - libint
- - cosma+rocm
- - netlib-scalapack+pic+shared
- - spla+rocm+fortran
- - spfft+rocm
- - libxsmm@1.17
- - binutils
- - fftw+openmp
- - openmpi
- - autoconf@2.72
- - libvori
- - spglib
- - dftd4
- - hdf5
- - hip
- - hipblas
- - hipfft
- - hipcc
- - trexio
- - gcc@12
- - dbcsr@2.9.1+mpi+rocm+openmp~tests~examples
- - openblas
- - libvdwxc@master
- - cp2k@2026.1+cosma~cuda+dbm_gpu+dftd4+grid_gpu+grpp+hdf5~ipo+libint+libxc+mpi+mpi_f08+openmp+pw_gpu+rocm+sirius+spglib+spla+tblite+trexio+vdwxc build_type=Release smm=libxsmm
- concretizer:
- unify: true
- packages:
- all:
- variants: +shared amdgpu_target=gfx942 amdgpu_target_sram_ecc=gfx942
- target: [zen3]
-
diff --git a/cp2k/docker/scripts/_run_common.sh b/cp2k/docker/scripts/_run_common.sh
new file mode 100755
index 0000000..e97355f
--- /dev/null
+++ b/cp2k/docker/scripts/_run_common.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+#
+# Helpers shared by the Docker run scripts.
+#
+# The docker scripts mirror the baremetal scripts under
+# baremetal/scripts/ as closely as possible: same .run filenames, same
+# SBATCH directives, same lowercase topology variables, same EXPNAME and
+# output directory layout. The only essential difference is that the
+# benchmark mpirun is wrapped in `docker run` against the cp2k image.
+#
+# This file provides the docker counterparts to baremetal's _run_common.sh
+# helpers:
+#
+# cp2k_benchmark_dir - clone CP2K source on the host so we can
+# bind-mount its benchmark inputs into the
+# container (same signature as baremetal)
+# report_fom - extract CP2K timing FOM from the output
+# file (same signature as baremetal)
+# docker_run_args - common docker run flags (ROCm + IPC)
+# container_command - bash snippet that activates the Spack
+# environment inside the container, locates
+# cp2k.psmp + close.sh, then evals
+# (replaces baremetal's activate_cp2k +
+# require_cp2k_bin, which run on the host)
+
+set -eu
+set -o pipefail
+
+RUN_COMMON_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+DOCKER_DIR="$(cd "${RUN_COMMON_SCRIPT_DIR}/.." && pwd)"
+PROJECT_ROOT="$(cd "${DOCKER_DIR}/.." && pwd)"
+
+CONTAINER_IMAGE="${CONTAINER_IMAGE:-cp2k:latest}"
+HOST_OUTPUT_ROOT="${HOST_OUTPUT_ROOT:-${DOCKER_DIR}/outputs}"
+mkdir -p "${HOST_OUTPUT_ROOT}"
+
+# ---- CP2K benchmark inputs (host side) ---------------------------------
+# Clones the CP2K source tree into ${PROJECT_ROOT}/cp2k_repo if needed and
+# echoes the absolute path to the benchmark directory passed as $1. This
+# is host-side because the docker scripts bind-mount the directory into
+# the container at /benchmark.
+cp2k_benchmark_dir() {
+ local rel="$1"
+ local cp2k_branch="${CP2K_BRANCH:-v2026.1}"
+ if [ ! -d "${PROJECT_ROOT}/cp2k_repo" ]; then
+ echo "INFO: Cloning CP2K (${cp2k_branch}) into ${PROJECT_ROOT}/cp2k_repo" >&2
+ git clone --recursive -b "${cp2k_branch}" \
+ https://github.com/cp2k/cp2k.git \
+ "${PROJECT_ROOT}/cp2k_repo" >&2
+ fi
+ echo "${PROJECT_ROOT}/cp2k_repo/benchmarks/${rel}"
+}
+
+# ---- Print FOM line(s) from a CP2K output file -------------------------
+report_fom() {
+ local out="$1"
+ echo
+ echo "FORCE_EVAL timing:"
+ grep 'FORCE_EVAL' "${out}" 2>/dev/null || echo " (none found)"
+ echo
+ echo "CP2K timing:"
+ grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || echo " (none found)"
+ local last
+ last=$(grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || true)
+ if [ -n "${last}" ]; then
+ echo
+ echo "FOM: $(echo "${last}" | awk '{print $NF}') seconds"
+ fi
+}
+
+# ---- Common docker run flags -------------------------------------------
+# ROCm device passthrough, IPC for GPU peer access, host output mount.
+docker_run_args() {
+ cat <&2
+ exit 1
+fi
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${HOST_OUTPUT_ROOT}/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+CONTAINER_OUT="/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+
+cat <&2
+ exit 1
+ fi
+done
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${HOST_OUTPUT_ROOT}/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+CONTAINER_OUT="/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+
+cat </dev/null || true
-fi
-
-docker run --rm \
- --device=/dev/kfd \
- --device=/dev/dri \
- --security-opt seccomp=unconfined \
- --ipc=host \
- -e PMIX_MCA_gds=^ds21 \
- -v "$BASE_DIR":/tmp \
- -v "$BASE_DIR/cp2k_repo":/cp2k_source \
- -v "$SCRIPT_DIR":/scripts \
- $CONTAINER_IMAGE \
- bash -c "
- echo \"Using executable: $CP2K_EXECUTABLE\"
- echo \"Running benchmark with affinity scripts...\"
-
- # Ensure scripts have execute permission inside container
- chmod +x /scripts/*.sh 2>/dev/null || true
-
- # The container has CP2K installed via Spack with symlink at /opt/cp2k
- # Find the CP2K executable using the symlink
- CP2K_PATH=\$(which $CP2K_EXECUTABLE 2>/dev/null)
- if [ -z \"\$CP2K_PATH\" ] || [ ! -x \"\$CP2K_PATH\" ]; then
- echo \"ERROR: CP2K executable not found in PATH: $CP2K_EXECUTABLE\"
- echo \"Current PATH: \$PATH\"
- ls -la /opt/cp2k/bin/ 2>/dev/null || echo \"/opt/cp2k/bin not found\"
- exit 1
- fi
- echo \"Found CP2K at: \$CP2K_PATH\"
-
- # Run with affinity scripts
- # Enable g2g (GPU-to-GPU) for DBCSR
- mpirun \
- -x NUM_CPUS=$NUM_CPUS \
- -x NUM_GPUS=$NUM_GPUS \
- -x OMP_NUM_THREADS=$OMP_NUM_THREADS \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np $NUM_RANKS \
- --bind-to none \
- /scripts/set_cpu_affinity.sh \
- /scripts/set_gpu_affinity.sh \
- \$CP2K_PATH \
- -i $BENCHMARK_INPUT \
- -o $OUTPUT_FILE
-
- if [ \$? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Benchmark completed successfully!'
- echo '=========================================='
- echo \"Output file: $OUTPUT_FILE\"
- echo ''
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' $OUTPUT_FILE || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'All CP2K timing lines:'
- grep 'CP2K ' $OUTPUT_FILE || echo 'No timing information found'
- echo ''
-
- # Extract FOM: last time value from the last line matching 'CP2K '
- FOM_LINE=\$(grep 'CP2K ' $OUTPUT_FILE | tail -n 1)
- if [ -n \"\$FOM_LINE\" ]; then
- # Extract the last numeric value (time) from the line
- # This assumes the time is the last field/word in the line
- FOM=\$(echo \"\$FOM_LINE\" | awk '{print \$NF}')
- echo '=========================================='
- echo \"FOM (Figure of Merit): \$FOM seconds\"
- echo '=========================================='
- else
- echo 'Warning: Could not extract FOM from output file'
- fi
- else
- echo 'Benchmark failed!'
- exit 1
- fi
- "
-
-echo ""
-echo "Output file saved to: $BASE_DIR/H2O-DFT-LS-NREP2-16ranks.txt"
diff --git a/cp2k/docker/scripts/run_rpa32.sh b/cp2k/docker/scripts/run_rpa32.sh
deleted file mode 100755
index 1430fd5..0000000
--- a/cp2k/docker/scripts/run_rpa32.sh
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/bin/bash
-#
-# Run CP2K RPA benchmark (32-H2O) with two stages using ssitaram/cp2k:pr22 container
-# Stage 1 (init): H2O-32-PBE-TZ.inp - 1 rank, 4 threads, 1 GPU
-# Stage 2 (solver): H2O-32-RI-dRPA-TZ.inp - 16 ranks, 8 threads, 8 GPUs
-#
-
-set -e
-
-CONTAINER_IMAGE="localhost/cp2k:latest"
-CP2K_BRANCH="v2026.1"
-CP2K_EXECUTABLE="cp2k.psmp"
-BENCHMARK_DIR="/cp2k_source/benchmarks/QS_mp2_rpa/32-H2O"
-
-# Stage 1: Init
-INIT_INPUT="${BENCHMARK_DIR}/H2O-32-PBE-TZ.inp"
-INIT_OUTPUT="/tmp/H2O-32-PBE-TZ-output.txt"
-INIT_RANKS=1
-INIT_THREADS=4
-INIT_GPUS=1
-INIT_CPUS=128
-
-# Stage 2: Solver
-SOLVER_INPUT="${BENCHMARK_DIR}/H2O-32-RI-dRPA-TZ.inp"
-SOLVER_OUTPUT="/tmp/H2O-32-RI-dRPA-TZ-output.txt"
-SOLVER_RANKS=16
-SOLVER_THREADS=8
-SOLVER_GPUS=8
-SOLVER_CPUS=128
-
-echo "=========================================="
-echo "CP2K RPA Benchmark (32-H2O)"
-echo "Container: $CONTAINER_IMAGE"
-echo "CP2K Branch: $CP2K_BRANCH"
-echo "=========================================="
-
-# Get the script directory (where this script is located)
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-# Get the docker directory (parent of scripts)
-DOCKER_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
-# Get the base directory (parent of docker)
-BASE_DIR="$(cd "$DOCKER_DIR/.." && pwd)"
-
-# Clone CP2K repository if not already present
-if [ ! -d "$BASE_DIR/cp2k_repo" ]; then
- echo "Cloning CP2K repository (branch ${CP2K_BRANCH})..."
- cd "$BASE_DIR"
- git clone --recursive -b ${CP2K_BRANCH} https://github.com/cp2k/cp2k.git cp2k_repo
-else
- echo "CP2K repository already exists, skipping clone..."
-fi
-
-# Ensure scripts have execute permission
-if [ -d "$SCRIPT_DIR" ]; then
- echo "Setting execute permissions on scripts..."
- chmod +x "$SCRIPT_DIR"/*.sh 2>/dev/null || true
-fi
-
-echo ""
-echo "=========================================="
-echo "STAGE 1: Init (H2O-32-PBE-TZ.inp)"
-echo "Ranks: $INIT_RANKS, Threads: $INIT_THREADS, GPUs: $INIT_GPUS"
-echo "=========================================="
-
-docker run --rm \
- --device=/dev/kfd \
- --device=/dev/dri \
- --security-opt seccomp=unconfined \
- --ipc=host \
- -e PMIX_MCA_gds=^ds21 \
- -v "$BASE_DIR":/tmp \
- -v "$BASE_DIR/cp2k_repo":/cp2k_source \
- -v "$SCRIPT_DIR":/scripts \
- $CONTAINER_IMAGE \
- bash -c "
- echo \"Running Init Stage...\"
-
- # Ensure scripts have execute permission inside container
- chmod +x /scripts/*.sh 2>/dev/null || true
-
- # Find the CP2K executable
- CP2K_PATH=\$(which $CP2K_EXECUTABLE 2>/dev/null)
- if [ -z \"\$CP2K_PATH\" ] || [ ! -x \"\$CP2K_PATH\" ]; then
- echo \"ERROR: CP2K executable not found in PATH: $CP2K_EXECUTABLE\"
- exit 1
- fi
- echo \"Found CP2K at: \$CP2K_PATH\"
-
- # Change to benchmark directory
- cd $BENCHMARK_DIR || exit 1
- echo \"Working directory: \$(pwd)\"
-
- # Run init stage with affinity scripts
- mpirun \
- -x NUM_CPUS=$INIT_CPUS \
- -x NUM_GPUS=$INIT_GPUS \
- -x OMP_NUM_THREADS=$INIT_THREADS \
- --oversubscribe \
- -np $INIT_RANKS \
- --bind-to none \
- /scripts/set_cpu_affinity.sh \
- /scripts/set_gpu_affinity.sh \
- \$CP2K_PATH \
- -i $INIT_INPUT \
- -o $INIT_OUTPUT
-
- if [ \$? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Init Stage completed successfully!'
- echo '=========================================='
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' $INIT_OUTPUT || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'CP2K timing:'
- grep 'CP2K ' $INIT_OUTPUT | tail -n 1 || echo 'No timing found'
-
- # Extract FOM
- FOM_LINE=\$(grep 'CP2K ' $INIT_OUTPUT | tail -n 1)
- if [ -n \"\$FOM_LINE\" ]; then
- FOM=\$(echo \"\$FOM_LINE\" | awk '{print \$NF}')
- echo \"Init Stage FOM: \$FOM seconds\"
- fi
- else
- echo 'Init stage failed!'
- exit 1
- fi
- "
-
-if [ $? -ne 0 ]; then
- echo "Init stage failed, aborting solver stage"
- exit 1
-fi
-
-echo ""
-echo "=========================================="
-echo "STAGE 2: Solver (H2O-32-RI-dRPA-TZ.inp)"
-echo "Ranks: $SOLVER_RANKS, Threads: $SOLVER_THREADS, GPUs: $SOLVER_GPUS"
-echo "=========================================="
-
-docker run --rm \
- --device=/dev/kfd \
- --device=/dev/dri \
- --security-opt seccomp=unconfined \
- --ipc=host \
- -e PMIX_MCA_gds=^ds21 \
- -v "$BASE_DIR":/tmp \
- -v "$BASE_DIR/cp2k_repo":/cp2k_source \
- -v "$SCRIPT_DIR":/scripts \
- $CONTAINER_IMAGE \
- bash -c "
- echo \"Running Solver Stage...\"
-
- # Ensure scripts have execute permission inside container
- chmod +x /scripts/*.sh 2>/dev/null || true
-
- # Find the CP2K executable
- CP2K_PATH=\$(which $CP2K_EXECUTABLE 2>/dev/null)
- if [ -z \"\$CP2K_PATH\" ] || [ ! -x \"\$CP2K_PATH\" ]; then
- echo \"ERROR: CP2K executable not found in PATH: $CP2K_EXECUTABLE\"
- exit 1
- fi
- echo \"Found CP2K at: \$CP2K_PATH\"
-
- # Change to benchmark directory
- cd $BENCHMARK_DIR || exit 1
- echo \"Working directory: \$(pwd)\"
-
- # Run solver stage with affinity scripts
- # Enable g2g (GPU-to-GPU) for DBCSR
- mpirun \
- -x NUM_CPUS=$SOLVER_CPUS \
- -x NUM_GPUS=$SOLVER_GPUS \
- -x OMP_NUM_THREADS=$SOLVER_THREADS \
- -x DBCSR_USE_ACC_G2G=1 \
- --oversubscribe \
- -np $SOLVER_RANKS \
- --bind-to none \
- /scripts/set_cpu_affinity.sh \
- /scripts/set_gpu_affinity.sh \
- \$CP2K_PATH \
- -i $SOLVER_INPUT \
- -o $SOLVER_OUTPUT
-
- if [ \$? -eq 0 ]; then
- echo ''
- echo '=========================================='
- echo 'Solver Stage completed successfully!'
- echo '=========================================='
- echo 'FORCE_EVAL timing:'
- grep 'FORCE_EVAL' $SOLVER_OUTPUT || echo 'No FORCE_EVAL timing found'
- echo ''
- echo 'CP2K timing:'
- grep 'CP2K ' $SOLVER_OUTPUT | tail -n 1 || echo 'No timing found'
-
- # Extract FOM
- FOM_LINE=\$(grep 'CP2K ' $SOLVER_OUTPUT | tail -n 1)
- if [ -n \"\$FOM_LINE\" ]; then
- FOM=\$(echo \"\$FOM_LINE\" | awk '{print \$NF}')
- echo \"Solver Stage FOM: \$FOM seconds\"
- fi
- else
- echo 'Solver stage failed!'
- exit 1
- fi
- "
-
-echo ""
-echo "=========================================="
-echo "RPA Benchmark Complete!"
-echo "=========================================="
-echo "Init output: $BASE_DIR/H2O-32-PBE-TZ-output.txt"
-echo "Solver output: $BASE_DIR/H2O-32-RI-dRPA-TZ-output.txt"
-echo ""
-echo "Summary:"
-echo "--------"
-echo "Init Stage:"
-grep 'FORCE_EVAL' "$BASE_DIR/H2O-32-PBE-TZ-output.txt" 2>/dev/null || echo " FORCE_EVAL: Not available"
-grep 'CP2K ' "$BASE_DIR/H2O-32-PBE-TZ-output.txt" 2>/dev/null | tail -n 1 | awk '{print " CP2K FOM: " $NF " seconds"}' || echo " FOM: Not available"
-echo ""
-echo "Solver Stage:"
-grep 'FORCE_EVAL' "$BASE_DIR/H2O-32-RI-dRPA-TZ-output.txt" 2>/dev/null || echo " FORCE_EVAL: Not available"
-grep 'CP2K ' "$BASE_DIR/H2O-32-RI-dRPA-TZ-output.txt" 2>/dev/null | tail -n 1 | awk '{print " CP2K FOM: " $NF " seconds"}' || echo " FOM: Not available"
-
diff --git a/cp2k/docker/scripts/set_cpu_affinity.sh b/cp2k/docker/scripts/set_cpu_affinity.sh
deleted file mode 100755
index 57b15da..0000000
--- a/cp2k/docker/scripts/set_cpu_affinity.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-if [[ -n ${OMPI_COMM_WORLD_RANK+x} ]]; then
- # ompi
- export global_rank=${OMPI_COMM_WORLD_RANK}
- export local_rank=${OMPI_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${OMPI_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${MV2_COMM_WORLD_RANK+x} ]]; then
- # mvapich2
- export global_rank=${MV2_COMM_WORLD_RANK}
- export local_rank=${MV2_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${MV2_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${SLURM_LOCALID+x} ]]; then
- # mpi via srun
- export global_rank=${SLURM_PROCID}
- export local_rank=${SLURM_LOCALID}
- export ranks_per_node=$(($SLURM_NTASKS/$SLURM_NNODES))
-fi
-
-# Set defaults
-let NUM_CPUS=${NUM_CPUS:-128}
-let RANK_STRIDE=${RANK_STRIDE:-${NUM_CPUS}/${ranks_per_node}}
-let OMP_STRIDE=${OMP_STRIDE:-1}
-let NUM_GPUS=${NUM_GPUS:-8}
-let GPU_START=${GPU_START:-0}
-let GPU_STRIDE=${GPU_STRIDE:-1}
-if [[ -z ${GPU+x} ]]; then
- let GPU="MI210"
-fi
-
-# Optimal ordering of CPU cores w.r.t. GPU devices is different for MI250X
-# Need GPU and NUM_CPUS to be set to MI250X and 64 respectively
-if [[ $GPU == "MI250X" && $NUM_CPUS == "64" ]]; then
- cpu_list=(48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47)
-else
- cpu_list=($(seq 0 127))
-fi
-
-let cpus_per_gpu=${NUM_CPUS}/${NUM_GPUS}
-let cpu_start_index=$(( ($RANK_STRIDE*${local_rank})+${GPU_START}*$cpus_per_gpu ))
-let cpu_start=${cpu_list[$cpu_start_index]}
-let cpu_stop=$(($cpu_start+$OMP_NUM_THREADS*$OMP_STRIDE-1))
-
-export GOMP_CPU_AFFINITY=$cpu_start-$cpu_stop:$OMP_STRIDE
-echo "rank_local= " $local_rank " GOMP_CPU_AFFINITY= " $GOMP_CPU_AFFINITY
-
-"$@"
diff --git a/cp2k/docker/scripts/set_gpu_affinity.sh b/cp2k/docker/scripts/set_gpu_affinity.sh
deleted file mode 100755
index 25425f8..0000000
--- a/cp2k/docker/scripts/set_gpu_affinity.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-##############################################
-# Script that just assigns GPUs/GCDs to ranks
-#
-# Relies on environment variables to be set
-# for cases other than default
-##############################################
-
-if [[ -n ${OMPI_COMM_WORLD_RANK+z} ]]; then
- # ompi
- export global_rank=${OMPI_COMM_WORLD_RANK}
- export local_rank=${OMPI_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${OMPI_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${MV2_COMM_WORLD_RANK+z} ]]; then
- # mvapich2
- export global_rank=${MV2_COMM_WORLD_RANK}
- export local_rank=${MV2_COMM_WORLD_LOCAL_RANK}
- export ranks_per_node=${MV2_COMM_WORLD_LOCAL_SIZE}
-elif [[ -n ${SLURM_LOCALID+z} ]]; then
- # mpich via srun
- export global_rank=${SLURM_PROCID}
- export local_rank=${SLURM_LOCALID}
- export ranks_per_node=$(($SLURM_NTASKS/$SLURM_NNODES))
-fi
-
-# Set defaults
-let NUM_CPUS=${NUM_CPUS:-128}
-let RANK_STRIDE=${RANK_STRIDE:-${NUM_CPUS}/${ranks_per_node}}
-let OMP_STRIDE=${OMP_STRIDE:-1}
-let NUM_GPUS=${NUM_GPUS:-8}
-let GPU_START=${GPU_START:-0}
-let GPU_STRIDE=${GPU_STRIDE:-1}
-
-let ranks_per_gpu=$(((${ranks_per_node}+${NUM_GPUS}-1)/${NUM_GPUS}))
-let my_gpu=$(($local_rank*$GPU_STRIDE/$ranks_per_gpu))+${GPU_START}
-
-arch=${GPU_ARCH_INP}
-export HIP_VISIBLE_DEVICES=$my_gpu
-echo "rank_local= " $local_rank " HIP_VISIBLE_DEVICES= " $HIP_VISIBLE_DEVICES
-
-"$@"
-
diff --git a/cp2k/docker/spack.sh b/cp2k/docker/spack.sh
deleted file mode 100755
index 78d27b7..0000000
--- a/cp2k/docker/spack.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-source /opt/spack/share/spack/setup-env.sh
-
-spack env activate /opt/cp2k_environment
-spack external find --all
-spack concretize -f
-spack install -j16
-
-ln -s `spack find -p cp2k@2026.1 | tail -n 1 | awk 'BEGIN{FS=" "} {print $2}'` /opt/cp2k
-
diff --git a/cp2k/shared/close.sh b/cp2k/shared/close.sh
new file mode 100755
index 0000000..ddedaa7
--- /dev/null
+++ b/cp2k/shared/close.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Bind one MPI rank to one GPU using ROCR_VISIBLE_DEVICES.
+#
+# Wrap a CP2K (or other) command with this script after mpirun, e.g.:
+# mpirun -np N --map-by ppr:K:numa:PE=T close.sh cp2k.psmp -i in.inp
+#
+# Works with OpenMPI (OMPI_COMM_WORLD_*) and falls back to MPICH-style
+# MPI_LOCALNRANKS / MPI_LOCALRANKID variables.
+
+if [ -n "${OMPI_COMM_WORLD_SIZE:-}" ]; then
+ mpi_size=${OMPI_COMM_WORLD_SIZE}
+ mpi_rank=${OMPI_COMM_WORLD_RANK}
+ mpi_node_size=${OMPI_COMM_WORLD_LOCAL_SIZE}
+ mpi_node_rank=${OMPI_COMM_WORLD_LOCAL_RANK}
+else
+ mpi_size=-1
+ mpi_rank=-1
+ mpi_node_size=${MPI_LOCALNRANKS:-1}
+ mpi_node_rank=${MPI_LOCALRANKID:-0}
+fi
+
+gpus_per_node=${GPUS_PER_NODE:-8}
+gpus_per_rank=$(( gpus_per_node / mpi_node_size ))
+if [ "${gpus_per_node}" -le "${mpi_node_size}" ]; then
+ ranks_per_gpu=$(( mpi_node_size / gpus_per_node ))
+else
+ ranks_per_gpu=1
+fi
+devid=$(( mpi_node_rank / ranks_per_gpu ))
+
+ROCR_VISIBLE_DEVICES=${devid}
+export ROCR_VISIBLE_DEVICES
+
+echo "host=$(hostname -s) ngpus=${gpus_per_node} nprocs=${mpi_size} rank=${mpi_rank} nprocs_local=${mpi_node_size} rank_local=${mpi_node_rank} ROCR_VISIBLE_DEVICES=${ROCR_VISIBLE_DEVICES}"
+
+exec "$@"
diff --git a/cp2k/shared/cp2k_build.sh b/cp2k/shared/cp2k_build.sh
new file mode 100755
index 0000000..7fcaaa9
--- /dev/null
+++ b/cp2k/shared/cp2k_build.sh
@@ -0,0 +1,487 @@
+#!/bin/bash
+#
+# Build CP2K with ROCm support using Spack.
+#
+# This script is the single source of truth for the build recipe and is used
+# by the baremetal flow (baremetal/build_cp2k.sh), the Docker flow
+# (docker/Dockerfile), and the Singularity flow (singularity/cp2k.def). It
+# pins Spack and the spack-packages repo to known
+# tags, applies a small upstream patch to add AMD MI350 (gfx950) support to
+# the CP2K Spack package, generates a Spack environment, and builds CP2K.
+#
+# Behaviour can be tuned via environment variables (with sensible defaults
+# for an MI350X / Zen5 / ROCm 7.2 host):
+#
+# SPACK_BRANCH git branch/tag of spack/spack [v1.1.1]
+# SPACK_PACKAGES_TAG git tag of spack/spack-packages [v2026.03.0]
+# GCC_VERSION GCC built with Spack and used as [14.3.0]
+# the CP2K compiler
+# CPU_ARCH Spack target= microarch [zen5]
+# GPU_ARCH AMD GPU target (amdgpu_target=...) [gfx950]
+# ROCM_VERSION ROCm version reported to Spack [7.2.0]
+# ROCM_PATH Filesystem path to the ROCm install [/opt/rocm-${ROCM_VERSION}]
+# BUILD_ROOT Where Spack tree, install tree, [script dir]
+# environments etc. live
+# BUILD_JOBS spack install -j [32]
+# SPACK_FETCH_JOBS spack install -p [4]
+#
+# Defaults target an MI350X / Zen5 / ROCm 7.2 single-node host.
+
+set -eu
+set -o pipefail
+
+SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
+
+SPACK_BRANCH="${SPACK_BRANCH:-v1.1.1}"
+SPACK_PACKAGES_TAG="${SPACK_PACKAGES_TAG:-v2026.03.0}"
+GCC_VERSION="${GCC_VERSION:-14.3.0}"
+CPU_ARCH="${CPU_ARCH:-zen5}"
+GPU_ARCH="${GPU_ARCH:-gfx950}"
+ROCM_VERSION="${ROCM_VERSION:-7.2.0}"
+ROCM_PATH="${ROCM_PATH:-/opt/rocm-${ROCM_VERSION}}"
+BUILD_ROOT="${BUILD_ROOT:-${SCRIPT_DIR}}"
+BUILD_JOBS="${BUILD_JOBS:-32}"
+SPACK_FETCH_JOBS="${SPACK_FETCH_JOBS:-4}"
+
+SPACK_GIT_DIR="${BUILD_ROOT}/spack_git"
+SPACK_PACKAGES_GIT_DIR="spack-packages_git"
+
+cat <&2
+ echo " Set ROCM_PATH or ROCM_VERSION before running this script." >&2
+ exit 1
+fi
+
+mkdir -p "${BUILD_ROOT}/environments" "${BUILD_ROOT}/install" "${BUILD_ROOT}/spack_stage"
+
+# ---------------------------------------------------------------------------
+# 1. Clone Spack itself
+# ---------------------------------------------------------------------------
+if [ ! -d "${SPACK_GIT_DIR}" ]; then
+ echo "INFO: Cloning Spack ${SPACK_BRANCH} into ${SPACK_GIT_DIR}"
+ git clone https://github.com/spack/spack.git \
+ --branch "${SPACK_BRANCH}" --single-branch "${SPACK_GIT_DIR}"
+fi
+
+# Source Spack
+# shellcheck disable=SC1091
+source "${SPACK_GIT_DIR}/share/spack/setup-env.sh"
+
+# ---------------------------------------------------------------------------
+# 2. config.yaml: redirect install tree, build stage, environments and
+# caches under BUILD_ROOT so a single directory contains everything.
+# ---------------------------------------------------------------------------
+SPACK_CONFIG_YAML="${SPACK_GIT_DIR}/etc/spack/config.yaml"
+if [ ! -f "${SPACK_CONFIG_YAML}" ]; then
+ echo "INFO: Writing Spack config to ${SPACK_CONFIG_YAML}"
+ cat > "${SPACK_CONFIG_YAML}" < "${SPACK_REPOS_YAML}" </dev/null 2>&1; then
+ echo "ERROR: git not found; required to apply the gfx950 patch." >&2
+ exit 1
+ fi
+ git_user="$(git config --get user.name || true)"
+ git_email="$(git config --get user.email || true)"
+ if [ -z "${git_user}" ] || [ -z "${git_email}" ]; then
+ echo "ERROR: git identity not configured; 'git am' will fail." >&2
+ echo " Set it before building, e.g.:" >&2
+ echo " git config --global user.name \"Your Name\"" >&2
+ echo " git config --global user.email \"you@example.com\"" >&2
+ exit 1
+ fi
+ echo "INFO: Applying gfx950 patch from ${SPACK_MI350_PATCH}"
+ pushd "${SPACK_PACKAGES_PATH}" >/dev/null
+ # If we're rerunning into a partially-applied tree, skip silently.
+ git am --keep-cr "${SPACK_MI350_PATCH}" >/dev/null 2>&1 || \
+ git am --abort >/dev/null 2>&1 || true
+ popd >/dev/null
+ else
+ echo "WARN: ${SPACK_MI350_PATCH} not found; skipping gfx950 patch." >&2
+ fi
+
+ if ! spack find "gcc@${GCC_VERSION}" >/dev/null 2>&1; then
+ echo "INFO: Installing gcc@${GCC_VERSION} with Spack"
+ spack install -p"${SPACK_FETCH_JOBS}" "gcc@${GCC_VERSION}"
+ fi
+fi
+
+# ---------------------------------------------------------------------------
+# 4. Spack environment definition (cp2k)
+# ---------------------------------------------------------------------------
+SPACK_CP2K_ENV="${BUILD_ROOT}/environments/cp2k/spack.yaml"
+if [ ! -f "${SPACK_CP2K_ENV}" ]; then
+ echo "INFO: Writing CP2K Spack environment to ${SPACK_CP2K_ENV}"
+ mkdir -p "$(dirname "${SPACK_CP2K_ENV}")"
+
+ cat > "${SPACK_CP2K_ENV}" < CP2K install prefix)
+CP2K_PREFIX=$(spack -e cp2k location -i cp2k 2>/dev/null || true)
+if [ -n "${CP2K_PREFIX}" ] && [ -d "${CP2K_PREFIX}" ]; then
+ ln -sfn "${CP2K_PREFIX}" "${BUILD_ROOT}/cp2k"
+ echo "INFO: Installed CP2K at ${CP2K_PREFIX}"
+ echo "INFO: Symlink created: ${BUILD_ROOT}/cp2k -> ${CP2K_PREFIX}"
+fi
+
+cat <}
+
+To use CP2K:
+ source ${SPACK_GIT_DIR}/share/spack/setup-env.sh
+ spack env activate cp2k
+ spack load cp2k
+ cp2k.psmp --version
+============================================================================
+EOF
diff --git a/cp2k/shared/patches/0001-Add-AMD-MI350-gfx950-support-to-CP2K.patch b/cp2k/shared/patches/0001-Add-AMD-MI350-gfx950-support-to-CP2K.patch
new file mode 100644
index 0000000..9a0f997
--- /dev/null
+++ b/cp2k/shared/patches/0001-Add-AMD-MI350-gfx950-support-to-CP2K.patch
@@ -0,0 +1,68 @@
+From 7fc2a089415079d9b9b994ce09281a6bf86b4325 Mon Sep 17 00:00:00 2001
+From: Mikko Byckling
+Date: Wed, 22 Apr 2026 01:48:14 -0500
+Subject: [PATCH] Add AMD MI350 (gfx950) support to CP2K
+
+---
+ .../builtin/packages/cp2k/package.py | 5 +++++
+ .../builtin/packages/cp2k/rocm-Mi350.patch | 18 ++++++++++++++++++
+ 2 files changed, 23 insertions(+)
+ create mode 100644 repos/spack_repo/builtin/packages/cp2k/rocm-Mi350.patch
+
+diff --git a/repos/spack_repo/builtin/packages/cp2k/package.py b/repos/spack_repo/builtin/packages/cp2k/package.py
+index 9ff9a5257e..b41bcbb2d4 100644
+--- a/repos/spack_repo/builtin/packages/cp2k/package.py
++++ b/repos/spack_repo/builtin/packages/cp2k/package.py
+@@ -25,6 +25,7 @@ GPU_MAP = {
+ "gfx90a:xnack-": "Mi250",
+ "gfx90a:xnack+": "Mi250",
+ "gfx942": "Mi300",
++ "gfx950": "Mi350",
+ }
+
+
+@@ -455,6 +456,7 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
+ "gfx90a:xnack-",
+ "gfx90a:xnack+",
+ "gfx942",
++ "gfx950"
+ )
+ cuda_msg = "cp2k only supports cuda_arch {0}".format(supported_cuda_arch_list)
+ rocm_msg = "cp2k only supports amdgpu_target {0}".format(supported_rocm_arch_list)
+@@ -526,6 +528,9 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
+ sha256="0d542c414216866953c95e642d2590b3d313717dfaebbf12cfafedbdd3bf54a3",
+ when="@=2025.1",
+ )
++ patch("rocm-Mi350.patch",
++ sha256="504f2b03fd501cbe33ce1db51cd25a7ca8da85a89fe6479f0d2fb841e96c125a",
++ when="@=2026.1")
+
+ def patch(self):
+ # Patch for an undefined constant due to incompatible changes in ELPA
+diff --git a/repos/spack_repo/builtin/packages/cp2k/rocm-Mi350.patch b/repos/spack_repo/builtin/packages/cp2k/rocm-Mi350.patch
+new file mode 100644
+index 0000000000..69e9662856
+--- /dev/null
++++ b/repos/spack_repo/builtin/packages/cp2k/rocm-Mi350.patch
+@@ -0,0 +1,18 @@
++--- a/CMakeLists.txt 2026-01-06 03:30:44.750963200 -0600
+++++ b/CMakeLists.txt 2026-04-22 01:42:58.494570023 -0500
++@@ -287,6 +287,7 @@
++ Mi210
++ Mi250
++ Mi300
+++ Mi350
++ K20X
++ K40
++ K80
++@@ -461,6 +462,7 @@
++ set(CP2K_GPU_ARCH_NUMBER_Mi200 gfx90a)
++ set(CP2K_GPU_ARCH_NUMBER_Mi250 gfx90a)
++ set(CP2K_GPU_ARCH_NUMBER_Mi300 gfx942)
+++ set(CP2K_GPU_ARCH_NUMBER_Mi350 gfx950)
++
++ # CMAKE_HIP_ARCHITECTURES and CMAKE_CUDA_ARCHITECTURES are the prefered
++ # mechanism to set the GPU architecture. We still offer the CP2K_WITH_GPU
+--
+2.43.0
+
diff --git a/cp2k/singularity/README.md b/cp2k/singularity/README.md
new file mode 100644
index 0000000..8e48c04
--- /dev/null
+++ b/cp2k/singularity/README.md
@@ -0,0 +1,108 @@
+# CP2K — Singularity / Apptainer Build
+
+Same Spack recipe as [`../baremetal/`](../baremetal/) and [`../docker/`](../docker/),
+packaged as a Singularity image. Use this on hosts (e.g. HPC/SLURM clusters)
+that have Singularity/Apptainer but not Docker.
+
+## Requirements
+
+- Singularity CE / Apptainer (4.x recommended) on `PATH`. On clusters that
+ expose it as a module, load it first (e.g. `module load singularity`); the
+ run scripts also try `module load ${SINGULARITY_MODULE:-singularity}`
+ automatically if `singularity` is not found.
+- `--fakeroot` capability for an unprivileged build (subuid/subgid mapping or a
+ site fakeroot config). If unavailable, build where you have it and copy the
+ `.sif`.
+- Git, ~50 GB free disk, internet during the build.
+
+Supported CPUs/GPUs/OS are in the
+[main README](../README.md#system-requirements).
+
+## Build
+
+Run from the repo root so `shared/` is in the build context:
+
+```bash
+./singularity/build_cp2k.sh
+```
+
+Produces `singularity/cp2k.sif`. Defaults: `gfx950` / `zen5` / ROCm `7.2.0`.
+
+The shared build knobs (`GPU_ARCH`, `CPU_ARCH`, `ROCM_VERSION`, `ROCM_PATH`,
+`GCC_VERSION`, `SPACK_BRANCH`, `SPACK_PACKAGES_TAG`, `BUILD_JOBS`) and the
+validation disclaimer are in the
+[main README](../README.md#build-configuration). Singularity-specific knobs:
+`BASE_IMAGE` (ROCm base image), `SIF_IMAGE` (output/run image path), and
+`FAKEROOT` (set `0` if fakeroot is unavailable). Override via env vars
+(forwarded as `--build-arg`):
+
+```bash
+GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 \
+ BASE_IMAGE=rocm/dev-ubuntu-24.04:7.0-complete \
+ ./singularity/build_cp2k.sh
+
+# If fakeroot is not available:
+FAKEROOT=0 ./singularity/build_cp2k.sh
+```
+
+## Running benchmarks
+
+Same filenames, SBATCH headers, topology vars, and output layout as
+[`../docker/scripts/`](../docker/scripts/); launch via `singularity exec --rocm`.
+
+| Script | Benchmark |
+|---|---|
+| `scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run` | `QS_DM_LS / H2O-dft-ls.NREP2` |
+| `scripts/cp2k_QS_mp2_rpa_32-H2O.run` | `QS_mp2_rpa / 32-H2O` (init + solver) |
+
+Both scripts double as SLURM batch jobs (just `sbatch` them) and as plain
+interactive scripts (just `./` them) — the SBATCH directives are shell
+comments when run outside SLURM, and every `SLURM_*` variable has a sensible
+default. They clone the CP2K source into `../cp2k_repo/` on first run to get
+the benchmark inputs.
+
+The topology variables (`numa_per_node`, `gpus_per_node`, etc.), MPI/UCX
+defaults, figure of merit, and the `DBCSR_USE_ACC_G2G` option are shared
+across flavors and documented in the
+[main README](../README.md#running-cp2k-benchmarks). The singularity
+launchers add `SIF_IMAGE` (path to the `.sif` to run). Set `numa_per_node`
+to your node's actual NUMA domain count (`numactl -H`).
+
+```bash
+# Interactive
+./singularity/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+./singularity/scripts/cp2k_QS_mp2_rpa_32-H2O.run
+
+# SLURM (set numa_per_node to the node's NUMA count)
+sbatch --export=ALL,numa_per_node= ./singularity/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+
+# Override the image or topology via env vars
+SIF_IMAGE=/path/to/cp2k.sif SLURM_NTASKS=8 numa_per_node=4 gpus_per_node=4 \
+ ./singularity/scripts/cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+```
+
+Outputs go to `singularity/outputs//...` and each script prints
+the [figure of merit](../README.md#figure-of-merit) from the resulting
+`*.out`.
+
+## Troubleshooting
+
+- **`singularity: command not found`** — load the module first
+ (`module load ${SINGULARITY_MODULE:-singularity}`); the run scripts also
+ attempt this automatically.
+- **Build fails without fakeroot** — pass `FAKEROOT=0`, or build on a host
+ where you have fakeroot and copy the resulting `.sif`.
+- **GPU not detected** — ensure `/dev/kfd` and `/dev/dri` exist and that the
+ `GPU_ARCH` baked into the image matches your hardware.
+
+## Files in this directory
+
+```
+singularity/
+├── cp2k.def # ROCm base + shared/cp2k_build.sh
+├── build_cp2k.sh # `singularity build` wrapper
+└── scripts/
+ ├── _run_common.sh # singularity exec helpers (mirrors baremetal/scripts/_run_common.sh)
+ ├── cp2k_QS_DM_LS_H2O-dft-ls-NREP2.run
+ └── cp2k_QS_mp2_rpa_32-H2O.run
+```
diff --git a/cp2k/singularity/build_cp2k.sh b/cp2k/singularity/build_cp2k.sh
new file mode 100755
index 0000000..1411afd
--- /dev/null
+++ b/cp2k/singularity/build_cp2k.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Build the CP2K Singularity image (cp2k.sif).
+#
+# Run from the repo root so shared/ is in the build context:
+# ./singularity/build_cp2k.sh
+#
+# Override defaults (MI350X/MI355X gfx950 / zen5 / ROCm 7.2) via env vars:
+# GPU_ARCH=gfx942 CPU_ARCH=zen3 ROCM_VERSION=7.0.0 ./singularity/build_cp2k.sh
+
+set -eu
+set -o pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+
+DEF="${SCRIPT_DIR}/cp2k.def"
+SIF="${SIF:-${SCRIPT_DIR}/cp2k.sif}"
+
+BASE_IMAGE="${BASE_IMAGE:-rocm/dev-ubuntu-24.04:7.2-complete}"
+GPU_ARCH="${GPU_ARCH:-gfx950}"
+CPU_ARCH="${CPU_ARCH:-zen5}"
+ROCM_VERSION="${ROCM_VERSION:-7.2.0}"
+ROCM_PATH="${ROCM_PATH:-/opt/rocm-${ROCM_VERSION}}"
+GCC_VERSION="${GCC_VERSION:-14.3.0}"
+SPACK_BRANCH="${SPACK_BRANCH:-v1.1.1}"
+SPACK_PACKAGES_TAG="${SPACK_PACKAGES_TAG:-v2026.03.0}"
+BUILD_JOBS="${BUILD_JOBS:-32}"
+
+# Unprivileged builds need fakeroot; disable with FAKEROOT=0.
+FAKEROOT_FLAG="--fakeroot"
+[ "${FAKEROOT:-1}" = "0" ] && FAKEROOT_FLAG=""
+
+cd "${REPO_ROOT}"
+singularity build ${FAKEROOT_FLAG} \
+ --build-arg "BASE_IMAGE=${BASE_IMAGE}" \
+ --build-arg "GPU_ARCH=${GPU_ARCH}" \
+ --build-arg "CPU_ARCH=${CPU_ARCH}" \
+ --build-arg "ROCM_VERSION=${ROCM_VERSION}" \
+ --build-arg "ROCM_PATH=${ROCM_PATH}" \
+ --build-arg "GCC_VERSION=${GCC_VERSION}" \
+ --build-arg "SPACK_BRANCH=${SPACK_BRANCH}" \
+ --build-arg "SPACK_PACKAGES_TAG=${SPACK_PACKAGES_TAG}" \
+ --build-arg "BUILD_JOBS=${BUILD_JOBS}" \
+ "${SIF}" "${DEF}"
+
+echo "Built ${SIF}"
diff --git a/cp2k/singularity/cp2k.def b/cp2k/singularity/cp2k.def
new file mode 100644
index 0000000..ed89a03
--- /dev/null
+++ b/cp2k/singularity/cp2k.def
@@ -0,0 +1,58 @@
+Bootstrap: docker
+From: {{ BASE_IMAGE }}
+
+# Build: ../singularity/build_cp2k.sh (run from the repo root)
+# Recipe is shared with baremetal/docker via shared/cp2k_build.sh.
+
+%arguments
+ BASE_IMAGE=rocm/dev-ubuntu-24.04:7.2-complete
+ GPU_ARCH=gfx950
+ CPU_ARCH=zen5
+ ROCM_VERSION=7.2.0
+ ROCM_PATH=/opt/rocm-7.2.0
+ GCC_VERSION=14.3.0
+ SPACK_BRANCH=v1.1.1
+ SPACK_PACKAGES_TAG=v2026.03.0
+ BUILD_JOBS=32
+
+%files
+ shared /opt/cp2k-build/shared
+
+%post
+ export DEBIAN_FRONTEND=noninteractive
+ apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends \
+ autoconf automake bzip2 build-essential ca-certificates cmake curl file \
+ flex gfortran git gnupg gzip libelf-dev libnuma-dev libstdc++-12-dev \
+ libtool libxml2-dev m4 make nano numactl patch pkg-config python3 \
+ python3-dev python3-pip ssh tar unzip vim wget xz-utils
+ apt-get clean && rm -rf /var/lib/apt/lists/*
+
+ export BUILD_ROOT=/opt/cp2k-build
+ export SPACK_BRANCH={{ SPACK_BRANCH }}
+ export SPACK_PACKAGES_TAG={{ SPACK_PACKAGES_TAG }}
+ export GCC_VERSION={{ GCC_VERSION }}
+ export CPU_ARCH={{ CPU_ARCH }}
+ export GPU_ARCH={{ GPU_ARCH }}
+ export ROCM_VERSION={{ ROCM_VERSION }}
+ export ROCM_PATH={{ ROCM_PATH }}
+ export BUILD_JOBS={{ BUILD_JOBS }}
+ /opt/cp2k-build/shared/cp2k_build.sh
+ ln -sfn /opt/cp2k-build/cp2k /opt/cp2k
+
+%environment
+ export ROCM_PATH={{ ROCM_PATH }}
+ export PATH=${ROCM_PATH}/bin:/opt/cp2k/bin:$PATH
+ export LD_LIBRARY_PATH=${ROCM_PATH}/lib:${ROCM_PATH}/lib64:$LD_LIBRARY_PATH
+ export OMPI_MCA_pml=ucx
+ export OMPI_MCA_osc=ucx
+ export OMPI_MCA_coll_ucc_enable=1
+ export OMPI_MCA_coll_ucc_priority=100
+ export UCX_TLS=self,sm,rocm_copy,rocm_ipc,ud_x
+ export UCX_HANDLE_ERRORS=bt
+ export UCX_MAX_RNDV_RAILS=1
+ export HSA_ENABLE_SDMA=0
+ export HSA_ENABLE_IPC_MODE_LEGACY=1
+ export HIP_MEM_POOL_SUPPORT=1
+
+%runscript
+ exec /bin/bash "$@"
diff --git a/cp2k/singularity/scripts/_run_common.sh b/cp2k/singularity/scripts/_run_common.sh
new file mode 100644
index 0000000..d199527
--- /dev/null
+++ b/cp2k/singularity/scripts/_run_common.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# Helpers shared by the Singularity run scripts. Mirror docker/scripts/
+# but launch via `singularity exec --rocm` instead of `docker run`.
+
+set -eu
+set -o pipefail
+
+RUN_COMMON_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+SING_DIR="$(cd "${RUN_COMMON_SCRIPT_DIR}/.." && pwd)"
+PROJECT_ROOT="$(cd "${SING_DIR}/.." && pwd)"
+
+SIF_IMAGE="${SIF_IMAGE:-${SING_DIR}/cp2k.sif}"
+HOST_OUTPUT_ROOT="${HOST_OUTPUT_ROOT:-${SING_DIR}/outputs}"
+mkdir -p "${HOST_OUTPUT_ROOT}"
+
+# Put singularity on PATH; load a module if needed (override the module
+# name with SINGULARITY_MODULE, e.g. SINGULARITY_MODULE=apptainer).
+ensure_singularity() {
+ if ! command -v singularity >/dev/null 2>&1; then
+ module load "${SINGULARITY_MODULE:-singularity}" >/dev/null 2>&1 || true
+ fi
+ if ! command -v singularity >/dev/null 2>&1; then
+ echo "ERROR: 'singularity' not found. Add it to PATH or set SINGULARITY_MODULE." >&2
+ exit 1
+ fi
+}
+
+# Clone CP2K on the host for benchmark inputs; echo the benchmark dir.
+cp2k_benchmark_dir() {
+ local rel="$1"
+ local cp2k_branch="${CP2K_BRANCH:-v2026.1}"
+ if [ ! -d "${PROJECT_ROOT}/cp2k_repo" ]; then
+ echo "INFO: Cloning CP2K (${cp2k_branch}) into ${PROJECT_ROOT}/cp2k_repo" >&2
+ git clone --recursive -b "${cp2k_branch}" \
+ https://github.com/cp2k/cp2k.git \
+ "${PROJECT_ROOT}/cp2k_repo" >&2
+ fi
+ echo "${PROJECT_ROOT}/cp2k_repo/benchmarks/${rel}"
+}
+
+report_fom() {
+ local out="$1"
+ echo
+ echo "FORCE_EVAL timing:"
+ grep 'FORCE_EVAL' "${out}" 2>/dev/null || echo " (none found)"
+ echo
+ echo "CP2K timing:"
+ grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || echo " (none found)"
+ local last
+ last=$(grep 'CP2K ' "${out}" 2>/dev/null | tail -n 1 || true)
+ if [ -n "${last}" ]; then
+ echo
+ echo "FOM: $(echo "${last}" | awk '{print $NF}') seconds"
+ fi
+}
+
+# bash snippet run inside the container: activate Spack, locate binaries,
+# then eval the supplied launch command.
+container_command() {
+ local launch_cmd="$1"
+ cat <&2
+ exit 1
+fi
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${HOST_OUTPUT_ROOT}/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+CONTAINER_OUT="/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+
+cat <&2
+ exit 1
+ fi
+done
+
+EXPNAME="${ARCH}_N${nnodes}.n${ntasks}.t${nthreads}.g${gpus_per_node}_${SLURM_JOB_ID:-local}"
+OUTPUT_DIR="${HOST_OUTPUT_ROOT}/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+CONTAINER_OUT="/outputs/${CP2K_CONFIG}/${CP2K_EXPERIMENT}/${EXPNAME}"
+mkdir -p "${OUTPUT_DIR}"
+
+cat <