diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.packit.yaml b/.packit.yaml index 9526f6bd57..2251c5dd34 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -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: diff --git a/tests/do_regtest.py b/tests/do_regtest.py index 7d8a7b6308..0556a353ee 100755 --- a/tests/do_regtest.py +++ b/tests/do_regtest.py @@ -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 diff --git a/tools/fedora/cp2k.spec b/tools/fedora/cp2k.spec index 7dcd6f7471..60747f1ea9 100644 --- a/tools/fedora/cp2k.spec +++ b/tools/fedora/cp2k.spec @@ -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 diff --git a/tools/fedora/plans/main.fmf.dist-git b/tools/fedora/plans/main.fmf.dist-git new file mode 100644 index 0000000000..5e2b9318b1 --- /dev/null +++ b/tools/fedora/plans/main.fmf.dist-git @@ -0,0 +1,4 @@ +discover: + how: fmf + dist-git-source: true + dist-git-extract: cp2k-*/ diff --git a/tools/fedora/plans/regression.fmf b/tools/fedora/plans/regression.fmf new file mode 100644 index 0000000000..4f2bdc31e0 --- /dev/null +++ b/tools/fedora/plans/regression.fmf @@ -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 diff --git a/tools/fedora/tests/do_regtest.sh b/tools/fedora/tests/do_regtest.sh new file mode 100755 index 0000000000..59a6ea2e1a --- /dev/null +++ b/tools/fedora/tests/do_regtest.sh @@ -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 diff --git a/tools/fedora/tests/regression.fmf b/tools/fedora/tests/regression.fmf new file mode 100644 index 0000000000..4ebd4abd3d --- /dev/null +++ b/tools/fedora/tests/regression.fmf @@ -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 diff --git a/tools/precommit/precommit.py b/tools/precommit/precommit.py index 81991ba08b..93979ed6fb 100755 --- a/tools/precommit/precommit.py +++ b/tools/precommit/precommit.py @@ -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"):