fedora: Optimize builds (#3268)

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
This commit is contained in:
Cristian Le 2024-03-28 21:07:23 +01:00 committed by GitHub
parent 30f14bb71c
commit 58e3e09bda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 228 additions and 143 deletions

1
.fmf/version Normal file
View file

@ -0,0 +1 @@
1

View file

@ -1,13 +1,23 @@
specfile_path: tools/fedora/cp2k.spec
files_to_sync:
- src: tools/fedora/cp2k.spec
dest: cp2k.spec
- src: tools/fedora/
dest: ./
filters:
- "- plans/main.fmf.dist-git"
- src: tools/fedora/plans/main.fmf.dist-git
dest: plans/main.fmf
- src: .fmf/
dest: .fmf/
- .packit.yaml
upstream_package_name: cp2k
downstream_package_name: cp2k
update_release: false
upstream_tag_template: v{version}
# Run only smoke tests by default
test_command:
default_identifier: smoke
jobs:
- job: copr_build
trigger: commit
@ -17,15 +27,47 @@ jobs:
additional_repos:
- copr://@scikit-build/release
targets:
- fedora-all-x86_64
- fedora-all-aarch64
- fedora-development-x86_64
- fedora-development-aarch64
- job: tests
trigger: commit
targets:
- fedora-development-x86_64
- fedora-development-aarch64
tmt_plan: .*/smoke
- job: copr_build
trigger: release
owner: lecris
project: release
targets:
- fedora-all-x86_64
- fedora-all-aarch64
- fedora-development-x86_64
- fedora-development-aarch64
- job: copr_build
trigger: pull_request
manual_trigger: true
owner: lecris
project: cp2k
update_release: true
release_suffix: "{PACKIT_RPMSPEC_RELEASE}"
targets:
- fedora-development-x86_64
- fedora-development-aarch64
- job: tests
identifier: smoke
trigger: pull_request
manual_trigger: true
targets:
- fedora-development-x86_64
- fedora-development-aarch64
tmt_plan: .*/smoke
- job: tests
identifier: full
trigger: pull_request
manual_trigger: true
targets:
- fedora-development-x86_64
- fedora-development-aarch64
tmt_plan: .*/full
- job: propose_downstream
trigger: release
dist_git_branches:

View file

@ -42,6 +42,10 @@ KEEPALIVE_SKIP_DIRS = [
]
def cp2k_stem() -> str:
return os.getenv("CP2K_STEM", "cp2k")
# ======================================================================================
async def main() -> None:
parser = argparse.ArgumentParser(description="Runs CP2K regression test suite.")
@ -64,6 +68,8 @@ async def main() -> None:
parser.add_argument("--restrictdir", action="append")
parser.add_argument("--skipdir", action="append")
parser.add_argument("--workbasedir", type=Path)
parser.add_argument("--skip_unittests", action="store_true")
parser.add_argument("--skip_regtests", action="store_true")
parser.add_argument("arch")
parser.add_argument("version")
cfg = Config(parser.parse_args())
@ -72,7 +78,9 @@ async def main() -> None:
start_time = time.perf_counter()
# Query CP2K binary for feature flags.
version_bytes, _ = await (await cfg.launch_exe("cp2k", "--version")).communicate()
version_bytes, _ = await (
await cfg.launch_exe(cp2k_stem(), "--version")
).communicate()
version_output = version_bytes.decode("utf8", errors="replace")
flags_line = re.search(r" cp2kflags:(.*)\n", version_output)
if not flags_line:
@ -252,6 +260,8 @@ class Config:
self.max_errors = args.maxerrors
self.restrictdirs = args.restrictdir if args.restrictdir else [".*"]
self.skipdirs = args.skipdir if args.skipdir else []
self.skip_unittests = args.skip_unittests
self.skip_regtests = args.skip_regtests
datestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
leaf_dir = f"TEST-{args.arch}-{args.version}-{datestamp}"
self.work_base_dir = (
@ -294,7 +304,13 @@ class Config:
env["CUDA_VISIBLE_DEVICES"] = ",".join(visible_gpu_devices)
env["HIP_VISIBLE_DEVICES"] = ",".join(visible_gpu_devices)
env["OMP_NUM_THREADS"] = str(self.ompthreads)
cmd = [str(self.cp2k_root / "exe" / self.arch / f"{exe_stem}.{self.version}")]
exe_path = Path(f"{exe_stem}.{self.version}")
if exe_path.is_absolute():
cmd = [str(exe_path)]
else:
cmd = [
str(self.cp2k_root / "exe" / self.arch / f"{exe_stem}.{self.version}")
]
if self.valgrind:
cmd = ["valgrind", "--error-exitcode=42", "--exit-on-first-error=yes"] + cmd
if self.use_mpi:
@ -430,7 +446,9 @@ class Cp2kShell:
async def start(self) -> None:
assert self._child is None
self._child = await self.cfg.launch_exe("cp2k", "--shell", cwd=self.workdir)
self._child = await self.cfg.launch_exe(
cp2k_stem(), "--shell", cwd=self.workdir
)
await self.ready()
await self.sendline("HARSH") # With harsh mode any error leads to an abort.
await self.ready()
@ -496,7 +514,11 @@ async def wait_for_child_process(
# ======================================================================================
async def run_batch(batch: Batch, cfg: Config) -> BatchResult:
async with cfg.workers:
results = (await run_unittests(batch, cfg)) + (await run_regtests(batch, cfg))
results = []
if not cfg.skip_unittests:
results += await run_unittests(batch, cfg)
if not cfg.skip_regtests:
results += await run_regtests(batch, cfg)
return BatchResult(batch, results)
@ -571,7 +593,7 @@ async def run_regtests_classic(batch: Batch, cfg: Config) -> List[TestResult]:
for test in batch.regtests:
start_time = time.perf_counter()
start_dirsize = dirsize(batch.workdir)
child = await cfg.launch_exe("cp2k", test.inp_fn, cwd=batch.workdir)
child = await cfg.launch_exe(cp2k_stem(), test.inp_fn, cwd=batch.workdir)
output, returncode, timed_out = await wait_for_child_process(child, cfg.timeout)
test.out_path.write_bytes(output)
duration = time.perf_counter() - start_time

View file

@ -12,6 +12,13 @@
%bcond_without openmpi
%endif
%ifarch x86_64
%bcond_without libxsmm
%else
# See https://bugzilla.redhat.com/show_bug.cgi?id=1515404
%bcond_with libxsmm
%endif
# Disable LTO due to https://bugzilla.redhat.com/show_bug.cgi?id=2243158
%global _lto_cflags %nil
@ -34,12 +41,11 @@ BuildRequires: bc
BuildRequires: fftw-devel
BuildRequires: gcc-c++
BuildRequires: gcc-gfortran
BuildRequires: ninja-build
BuildRequires: glibc-langpack-en
BuildRequires: dbcsr-devel >= %{dbcsr_version}
BuildRequires: libint2-devel
BuildRequires: libxc-devel >= 5.1.0
%ifarch x86_64
# See https://bugzilla.redhat.com/show_bug.cgi?id=1515404
%if %{with libxsmm}
BuildRequires: libxsmm-devel >= 1.8.1-3
%endif
BuildRequires: python3-fypp
@ -47,9 +53,6 @@ BuildRequires: spglib-devel
BuildRequires: /usr/bin/hostname
BuildRequires: python3-devel
# Libint can break the API between releases
Requires: libint2(api)%{?_isa}
Requires: %{name}-common = %{version}-%{release}
%global _description %{expand:
@ -83,20 +86,12 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
The %{name}-devel package contains libraries and header files for
developing applications that use %{name}.
%package testing
Summary: Tests for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}
%description testing
The %{name}-testing package contains executables for testing %{name}.
%if %{with openmpi}
%package openmpi
Summary: Molecular simulations software - openmpi version
BuildRequires: openmpi-devel
BuildRequires: blacs-openmpi-devel
BuildRequires: dbcsr-openmpi-devel >= %{dbcsr_version}
BuildRequires: elpa-openmpi-devel >= 2018.05.001
BuildRequires: scalapack-openmpi-devel
Requires: %{name}-common = %{version}-%{release}
# Libint may have API breakage
@ -116,13 +111,6 @@ Requires: %{name}-openmpi%{?_isa} = %{version}-%{release}
The %{name}-devel package contains libraries and header files for
developing applications that use %{name}.
%package openmpi-testing
Summary: Tests for %{name}
Requires: %{name}-openmpi%{?_isa} = %{version}-%{release}
%description openmpi-testing
The %{name}-openmpi-testing package contains executables for testing
%{name} with OpenMPI.
%endif
%package mpich
@ -130,7 +118,6 @@ Summary: Molecular simulations software - mpich version
BuildRequires: mpich-devel
BuildRequires: blacs-mpich-devel
BuildRequires: dbcsr-mpich-devel >= %{dbcsr_version}
BuildRequires: elpa-mpich-devel >= 2018.05.001
BuildRequires: scalapack-mpich-devel
BuildRequires: make
Requires: %{name}-common = %{version}-%{release}
@ -151,13 +138,6 @@ Requires: %{name}-mpich%{?_isa} = %{version}-%{release}
The %{name}-devel package contains libraries and header files for
developing applications that use %{name}.
%package mpich-testing
Summary: Tests for %{name}
Requires: %{name}-mpich%{?_isa} = %{version}-%{release}
%description mpich-testing
The %{name}-mpich-testing package contains executables for testing
%{name} with mpich.
%prep
%autosetup -p1
@ -168,91 +148,82 @@ rm -r exts/dbcsr
# $MPI_SUFFIX will be evaluated in the loops below, set by mpi modules
%global _vpath_builddir %{_vendor}-%{_target_os}-build${MPI_SUFFIX:-_serial}
# We are running the module load/unload manually until there is a macro-like way to expand this
. /etc/profile.d/modules.sh
%build
CMAKE_COMMON="-DCP2K_BLAS_VENDOR=FlexiBLAS %{?with_check:-DCP2K_ENABLE_REGTESTS=ON}"
%cmake $CMAKE_COMMON \
-DCP2K_USE_MPI=OFF \
-DCMAKE_INSTALL_Fortran_MODULES:PATH=%{_fmoddir}/cp2k
%cmake_build
%if %{with openmpi}
%{_openmpi_load}
%cmake $CMAKE_COMMON \
-DCMAKE_PREFIX_PATH:PATH=$MPI_HOME \
-DCMAKE_INSTALL_PREFIX:PATH=$MPI_HOME \
-DCMAKE_INSTALL_Fortran_MODULES:PATH=${MPI_FORTRAN_MOD_DIR}/cp2k \
-DCMAKE_INSTALL_LIBDIR:PATH=lib \
-DCP2K_CMAKE_SUFFIX=$MPI_SUFFIX \
-DCP2K_DATA_DIR:PATH=%{_datadir}/cp2k/data \
-DCP2K_USE_MPI_F08:BOOL=ON
%cmake_build
%{_openmpi_unload}
%endif
%{_mpich_load}
%cmake $CMAKE_COMMON \
-DCMAKE_PREFIX_PATH:PATH=$MPI_HOME \
-DCMAKE_INSTALL_PREFIX:PATH=$MPI_HOME \
-DCMAKE_INSTALL_Fortran_MODULES:PATH=${MPI_FORTRAN_MOD_DIR}/cp2k \
-DCMAKE_INSTALL_LIBDIR:PATH=lib \
-DCP2K_CMAKE_SUFFIX=$MPI_SUFFIX \
-DCP2K_DATA_DIR:PATH=%{_datadir}/cp2k/data \
-DCP2K_USE_MPI_F08:BOOL=ON
%cmake_build
%{_mpich_unload}
%install
%cmake_install
%if %{with openmpi}
%{_openmpi_load}
%cmake_install
%{_openmpi_unload}
%endif
%{_mpich_load}
%cmake_install
%{_mpich_unload}
%if %{with check}
# regtests take ~12 hours on aarch64 and ~48h on s390x
%check
. /etc/profile.d/modules.sh
export CP2K_DATA_DIR=%{buildroot}%{_datadir}/cp2k/data
status=0
for mpi in '' mpich %{?with_openmpi:openmpi} ; do
# A couple tests fail on ppc64le - https://github.com/cp2k/cp2k/issues/3077
%ifarch ppc64le
fail=0
%else
# Do not fail for now
fail=0
%endif
# TODO - set maxtasks based on # cores?
cmake_common_args=(
"-G Ninja"
"-DCP2K_DEBUG_MODE:BOOL=OFF"
"-DCP2K_BLAS_VENDOR:STRING=FlexiBLAS"
"-DCP2K_USE_STATIC_BLAS:BOOL=OFF"
"-DCP2K_ENABLE_REGTESTS:BOOL=%{?with_check:ON}%{?without_check:OFF}"
# Dependencies already packaged
"-DCP2K_USE_SPGLIB:BOOL=ON"
"-DCP2K_USE_LIBXC:BOOL=ON"
"-DCP2K_USE_FFTW3:BOOL=ON"
# TODO: Fix Libint2 detection
"-DCP2K_USE_LIBINT2:BOOL=OFF"
"-DCP2K_USE_LIBXSMM:BOOL=%{?with_libxsmm:ON}%{?without_libxsmm:OFF}"
# Missing dependencies
"-DCP2K_USE_ELPA:BOOL=OFF"
"-DCP2K_USE_PEXSI:BOOL=OFF"
"-DCP2K_USE_SUPERLU:BOOL=OFF"
"-DCP2K_USE_COSMA:BOOL=OFF"
"-DCP2K_USE_PLUMED:BOOL=OFF"
"-DCP2K_USE_VORI:BOOL=OFF"
"-DCP2K_USE_PEXSI:BOOL=OFF"
"-DCP2K_USE_QUIP:BOOL=OFF"
"-DCP2K_USE_LIBTORCH:BOOL=OFF"
"-DCP2K_USE_SPLA:BOOL=OFF"
"-DCP2K_USE_METIS:BOOL=OFF"
"-DCP2K_USE_DLAF:BOOL=OFF"
)
for mpi in '' mpich %{?with_openmpi:openmpi}; do
if [ -n "$mpi" ]; then
module load mpi/${mpi}-%{_arch}
libdir=${MPI_LIB}/cp2k
mpiopts="--maxtasks 4 --mpiranks 2 --ompthreads 2"
par=p
suf="-${mpi}"
cmake_mpi_args=(
"-DCMAKE_INSTALL_PREFIX:PATH=${MPI_HOME}"
"-DCMAKE_INSTALL_Fortran_MODULES:PATH=${MPI_FORTRAN_MOD_DIR}/cp2k"
"-DCMAKE_INSTALL_LIBDIR:PATH=lib"
"-DCP2K_CMAKE_SUFFIX:STRING=${MPI_SUFFIX}"
"-DCP2K_DATA_DIR:PATH=%{_datadir}/cp2k/data"
"-DCP2K_USE_MPI_F08:BOOL=ON"
)
else
libdir=%{_libdir}/cp2k
mpiopts="--maxtasks 4 --ompthreads 2"
par=s
suf=""
cmake_mpi_args=(
"-DCP2K_USE_MPI:BOOL=OFF"
"-DCMAKE_INSTALL_Fortran_MODULES:PATH=%{_fmoddir}/cp2k"
)
fi
export LD_LIBRARY_PATH=%{buildroot}${libdir}
tests/do_regtest.py %{!?with_check_full:--smoketest} --workbasedir %{_builddir} ${mpiopts} \
local${MPI_SUFFIX} ${par}smp || status=$(( $status + $fail ))
if [ -n "$mpi" ]; then
module unload mpi/${mpi}-%{_arch}
fi
%cmake \
${cmake_common_args[@]} \
${cmake_mpi_args[@]}
%cmake_build
[ -n "$mpi" ] && module unload mpi/${mpi}-%{_arch}
done
exit $status
%install
for mpi in '' mpich %{?with_openmpi:openmpi}; do
[ -n "$mpi" ] && module load mpi/${mpi}-%{_arch}
%cmake_install
[ -n "$mpi" ] && module unload mpi/${mpi}-%{_arch}
done
# TODO: Properly separate the installation of unit tests
rm -f %{_buildrootdir}/**/%{_bindir}/*_unittest.*
%if %{with openmpi}
rm -f %{_buildrootdir}/**/%{_libdir}/openmpi/bin/*_unittest.*
%endif
rm -f %{_buildrootdir}/**/%{_libdir}/mpich/bin/*_unittest.*
%check
# Tests are done in the tmt envrionment
%files common
%license LICENSE
@ -275,15 +246,6 @@ exit $status
%{_libdir}/libcp2k.so
%{_libdir}/pkgconfig/libcp2k.pc
%files testing
%{_bindir}/dbt_tas_unittest.ssmp
%{_bindir}/dbt_unittest.ssmp
%{_bindir}/grid_unittest.ssmp
%{_bindir}/libcp2k_unittest.ssmp
%{_bindir}/memory_utilities_unittest.ssmp
%{_bindir}/nequip_unittest.ssmp
%{_bindir}/parallel_rng_types_unittest.ssmp
%if %{with openmpi}
%files openmpi
%{_libdir}/openmpi/bin/cp2k.psmp
@ -300,15 +262,6 @@ exit $status
%{_libdir}/openmpi/lib/cmake/cp2k/
%{_libdir}/openmpi/lib/libcp2k.so
%{_libdir}/openmpi/lib/pkgconfig/libcp2k.pc
%files openmpi-testing
%{_libdir}/openmpi/bin/dbt_tas_unittest.psmp
%{_libdir}/openmpi/bin/dbt_unittest.psmp
%{_libdir}/openmpi/bin/grid_unittest.psmp
%{_libdir}/openmpi/bin/libcp2k_unittest.psmp
%{_libdir}/openmpi/bin/memory_utilities_unittest.psmp
%{_libdir}/openmpi/bin/nequip_unittest.psmp
%{_libdir}/openmpi/bin/parallel_rng_types_unittest.psmp
%endif
%files mpich
@ -327,14 +280,5 @@ exit $status
%{_libdir}/mpich/lib/libcp2k.so
%{_libdir}/mpich/lib/pkgconfig/libcp2k.pc
%files mpich-testing
%{_libdir}/mpich/bin/dbt_tas_unittest.psmp
%{_libdir}/mpich/bin/dbt_unittest.psmp
%{_libdir}/mpich/bin/grid_unittest.psmp
%{_libdir}/mpich/bin/libcp2k_unittest.psmp
%{_libdir}/mpich/bin/memory_utilities_unittest.psmp
%{_libdir}/mpich/bin/nequip_unittest.psmp
%{_libdir}/mpich/bin/parallel_rng_types_unittest.psmp
%changelog
%autochangelog

View file

@ -0,0 +1,4 @@
discover:
how: fmf
dist-git-source: true
dist-git-extract: cp2k-*/

View file

@ -0,0 +1,20 @@
summary:
Test the bundled tests
discover+:
how: fmf
execute:
how: tmt
# Currently using testing-farm/artemis which allows setting hardware requirements
# Virtual and other providers should be available at some point as well
provision:
hardware:
cpu:
processors: ">=4"
/full:
summary+: (Full)
/smoke:
summary+: (Smoke)
environment:
CP2K_SMOKE_ONLY: true

View file

@ -0,0 +1,27 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# shellcheck disable=all
source /usr/share/beakerlib/beakerlib.sh || exit 1
rlJournalStart
rlPhaseStartTest
[[ -z "${CP2K_VARIANT}" ]] && rlDie "No CP2K_VARIANT environment variable set"
rlRun "cd ../../../tests" 0 "cd to cp2k tests folder"
rlRun "args=\"--maxtasks $(nproc) --ompthreads 2 --skip_unittests\"" 0 "Set base arguments"
[[ "${CP2K_SMOKE_ONLY,,}" == "true" ]] && rlRun "args=\"\$args --smoketest\"" 0 "Set smoketest flag"
if [[ "${CP2K_VARIANT}" != "serial" ]]; then
rlRun "module avail" 0 "Show available modules"
rlRun "module load mpi/${CP2K_VARIANT}" 0 "Load MPI module: ${CP2K_VARIANT}"
rlRun "export CP2K_STEM=$MPI_BIN/cp2k" 0 "Export CP2K_STEM"
rlRun "args=\"\$args --mpiranks 2\"" 0 "Set MPI arguments"
rlRun "args=\"\$args local-${CP2K_VARIANT} psmp\"" 0 "Set run specific arguments"
else
rlRun "export CP2K_STEM=/usr/bin/cp2k" 0 "Export CP2K_STEM"
rlRun "args=\"\$args local ssmp\"" 0 "Set run specific arguments"
fi
rlRun "./do_regtest.py $args" 0 "Run regression tests"
rlPhaseEnd
rlJournalEnd

View file

@ -0,0 +1,23 @@
summary: Run regression tests
framework: beakerlib
test: ./do_regtest.sh
# TODO: Reduce the tests duration
duration: 2h
/serial:
summary+: (serial)
environment+:
CP2K_VARIANT: serial
/openmpi:
summary+: (openmpi)
environment+:
CP2K_VARIANT: openmpi
# prterun blocks running mpiexec as root. Set some environment variables to workaround it
OMPI_ALLOW_RUN_AS_ROOT: 1
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1
# TODO: Investigate why openmpi tests are significantly slower
duration: 6h
/mpich:
summary+: (mpich)
environment+:
CP2K_VARIANT: mpich

View file

@ -92,6 +92,8 @@ def main() -> None:
continue
if root.startswith("./tools/minimax_tools/1_xData"):
continue
if root.startswith("./tools/fedora"):
continue
if root.startswith("./data/DFTB/scc"):
continue
if root.startswith("./arch"):