Real-space finite-element Kohn-Sham DFT (University of Michigan). GPU build
(WITH_GPU=ON GPU_LANG=cuda GPU_VENDOR=nvidia): Chebyshev-filtered subspace
iteration, dense linear algebra (cuBLAS), Poisson/Helmholtz solves and the
ELPA eigensolver with NVIDIA GPU kernels.
| Item | Value |
|---|---|
| DFT-FE | release 1.2.0, 7147faa51f7c9f3075fffaa5e48ba989bcd329c1 (branch release1.2), LGPL-2.1-or-later |
| Recipe | upstream install_DFTFE (branch frontierDevelop: dftfe2.sh + setupUser.sh) transcribed to this node's toolchain in build.sh; every dependency tarball is pinned by sha256 in fetch.sh |
| Dependencies (private, same profile) | OpenBLAS 0.3.30 (TARGET=SAPPHIRERAPIDS, single-threaded) -> ScaLAPACK 2.2.2 -> libxc 7.0.0 -> spglib 02159eef -> ALGLIB 4.06.0 -> p4est 2.8.7 (dftfe's p4est-setup.sh, FAST+DEBUG) -> Kokkos 4.6.00 (Serial, deal.II only) -> deal.II 9.6.2 (see decision below) (MPI, p4est, 64-bit indices, LAPACK=OpenBLAS, bundled Boost, no TBB/taskflow) -> ELPA 2026.02.001 (--enable-nvidia-gpu-kernels --with-NVIDIA-GPU-compute-capability=sm_100) -> DFT-FE real (CMAKE_CUDA_ARCHITECTURES=100 WITH_DCCL=OFF WITH_GPU_AWARE_MPI=OFF USE_64BIT_INT=ON); libxml2 from the system |
| Compilers | system GCC 14.2.1 (C/C++/Fortran) through the conda Open MPI 5.0.10 wrappers (OMPI_CC/CXX/FC), nvcc 13.2.78 with g++ 14.2.1 host |
| GPU target | sm_100 for DFT-FE and for the ELPA kernels (ELPA's generic --with-NVIDIA-GPU-compute-capability=sm_XX path; sm_100 never used upstream) |
| NCCL | not used (WITH_DCCL=OFF; DFT-FE's default all-reduce path) |
| Build strategy | NATIVE (no Spack: the dftfe recipe is 0.6/2019 without GPU variants; no container) |
| Profile | cuda132-gcc142-ompi5010 (HPCPERF_DFTFE_ELPA_GPU=OFF would build -elpacpu, a named CPU-ELPA diagnostic profile, not used for the results) |
- dftfe's
p4est-setup.shis written for Cray systems: it hardcodesCC=cc CXX=CC FC=ftn F77=ftn(no MPI on this node'scc), relies on the Cray wrappers' implicit-lm, and checks<build>/src/p4est_config.hwhile p4est 2.8.7 writes<build>/config/p4est_config.h. build.sh passesCC=mpicc CXX=mpicxx FC=mpifort F77=mpifort LIBS=-lmthrough the script's trailing configure arguments and seds the header path in its private copy. - The conda environment's
CFLAGS/LDFLAGS/AR/...are cleared for the system-GCC builds (l3_clean_conda_build_env); OpenBLAS 0.3.30 misdetects the Xeon Platinum 8570 and is built withTARGET=SAPPHIRERAPIDS. - ELPA's configure expects the host SIMD flags in
CFLAGS(it probes AVX-512 intrinsics with the given flags and aborts otherwise; EL10's GCC 14 defaults to x86-64-v3 = AVX2):-march=nativefor C/C++/Fortran -- a node-specific binary like OpenBLAS. Its later CUDA link checks (cublasDgemm) keepLIBS=-lscalapackbut replaceLDFLAGSby the CUDA path, so the ScaLAPACK/OpenBLAS-L/rpath entries are given inLDFLAGSas well.
Two lines in src/atom/AtomicCenteredNonLocalOperator.cc (785/791) call an
unqualified isnan( inside a template; GCC 14 (libstdc++ 14) no longer finds
it through <cmath>'s global fallback and stops with "there are no arguments to
'isnan' that depend on a template parameter". The patch qualifies both calls as
std::isnan( -- the same function, no numerical or algorithmic change (upstream
develop has the same spelling). Applied by build.sh with git apply (idempotent,
sha256 recorded in the fingerprint as DFTFE_PATCH_SHA).
Release 1.2.0 pins deal.II 9.5.2 in its own setupUser*.sh; the current
install_DFTFE recipe (frontierDevelop/master) builds deal.II 9.7.1 -- but
together with the develop branch (publicGithubDevelop), not with the release.
Attempt 1 here (1.2.0 + 9.7.1) failed to compile: 9.7 removed three APIs 1.2.0
still uses (Utilities::MPI::create_group, parallel::distributed::Triangulation::load(name, autopartition),
DataOutBase::VtkFlags::ZlibCompressionLevel; upstream develop already carries the
replacements). Rather than back-porting a growing set of develop changes into the
release, the profile uses deal.II 9.6.2, the newest deal.II that still provides
those (deprecated) APIs, so 1.2.0 builds unpatched; recorded as attempt 2. The
9.7.1 build and its install were removed from the profile
(.deps/level3/dftfe/<profile>/ATTEMPT-1-dealii-9.7.1.txt, logs attempt1-*).
ELPA's own test programs (validate_real_double_eigenvectors_{1stage,2stage_default_kernel}_gpu_analytic,
which call e%set("nvidia-gpu", 1); the real binaries in build/elpa/.libs/, the
top-level names being libtool relink wrappers) on 1, 2 and 4 GPUs (one rank per GPU
through the common launcher, na=2000 nev=1000 nblk=32) and their CPU counterparts on
1 rank when built (they are not, with the GPU configuration: SKIPPED, recorded).
The programs diagonalise the analytic test matrix of test/shared/test_analytic_template.F90
(known eigenpairs) and apply ELPA's own limits max |lambda - lambda_exact| <= 5e-14,
max |z - z_exact| <= 6e-10 (real double; stop 1 on violation); the probe re-parses the
printed "Maximum error in eigenvalues/eigenvectors", re-applies the limits, requires exit 0,
ELPA's GPU timers (trans_ev_real_double_gpu, gpublas_*) in the output and a launcher
audit with 0 mismatch; record <install>/elpa/ELPA_GPU_PROBE.txt, required PASS by
validate.sh. Two false starts, both recorded in the script header: the first pass
looked for ELPA's *_default wrapper-script names (MISSING), the second parsed the
%Error Residual/Orthogonality lines of the random-matrix programs, which the analytic
programs never print, and aborted under pipefail.
run.sh: al_md (upstream GPU regression deck testsGPU/pseudopotential/real/Input_MD_0.prm:
32-atom fcc Al, order-3 FE, 85 states, BOMD 1400 K, 4 steps, USE GPU = true,
REPRODUCIBLE OUTPUT = true) -- smoke/strong verbatim, weak = derived Al supercell
series (32 atoms per GPU; SYNTHETIC, same construction as upstream's
dftfe-benchmarks Mo series); llzo (parameterFile_LLZO.prm, 192 atoms, 720
states, ELPA) as the heavier fixed-size strong case. One MPI rank per GPU, 1
thread per rank (upstream's GPU job scripts), decks used verbatim except the
documented weak derivation and the output level: run.sh sets VERBOSITY = 1 in its copy
of the deck (HPCPERF_DFTFE_VERBOSITY, default 1; the decks ship 0; 0-4 accepted, 5 is
refused because it adds energy evaluations). That is output only -- it prints DFT-FE's own
per-SCF-iteration wall time and the per-MD-step updateAtomPositionsAndMoveMesh time that
tools/timing reads -- and is recorded in deck.diff and the manifest (verbosity=).
REPRODUCIBLE OUTPUT = true stays: besides the output format it fixes numerical settings
(pspCutOff = 30, src/dft/dft.cc:226-229; ONCV tolerances), and it is also why DFT-FE
does not time its force evaluation or print its per-MD-step timer in this deck.
Re-validated with VERBOSITY = 1 on 2026-09-29 (uv toolchain, 2 x B200): validate.sh
PASS at 1 GPU (223 s) and 2 GPUs (130 s, also vs the 1-GPU run), audit clean.
validate.sh: [0] ELPA GPU probe PASS; [1] al_md on N GPUs vs upstream's own GPU
reference accuracyBenchmarks/output_MD_0 through dftfe_check.py (pre-fixed:
ground-state energy 1e-5 Ha, per-step MD energies 2e-5 Ha, temperatures 0.1 K,
forces 2e-5 Ha/Bohr; SCF converged, MD completed, finite), launcher audit "N
verified, 0 mismatch"; N > 1 additionally vs the 1-GPU run under the same
tolerances.
| Run | GPUs | atoms / KS DOFs | wall (s) | check |
|---|---|---|---|---|
al_md smoke (= strong, verbatim deck) |
1 | 32 / 50 653 | 216 | vs upstream GPU reference: e0, 4 MD energies, temperatures, forces all identical at printed precision (max diff 0.0; SCF iterations 8/9/9/9 as upstream) |
al_md |
2 | 32 / 50 653 | 117 | identical to upstream reference and to the 1-GPU run |
al_md |
4 | 32 / 50 653 | 70 | identical to upstream reference and to the 1-GPU run |
| weak x1 (2x2x2 cells) | 1 | 32 / 50 653 | 213 | complete (same deck as smoke) |
| weak x2 (4x2x2 cells, derived) | 2 | 64 / 108 151 | 284 | complete, 4 MD steps |
| weak x4 (4x4x2 cells, derived) | 4 | 128 / 230 917 | 378 | complete, 4 MD steps |
llzo strong (192 atoms, 720 states, ELPA, verbatim deck) |
1 / 2 / 4 | 192 / 97 336 | 295 / 163 / 96 (1.81x, 3.07x) | ground state, 19 SCF iterations, E = -3579.26588980 Ha identical on 1, 2 and 4 GPUs |
ELPA GPU probe, 1-stage (validate_real_double_eigenvectors_1stage_gpu_analytic, na=2000 nev=1000) |
1 / 2 / 4 | -- | -- | PASS: max eigenvalue error 2.7e-15 / 2.4e-15 / 2.0e-15 (limit 5e-14), eigenvector error 1.5e-12 / 1.7e-12 / 1.5e-12 (limit 6e-10), exit 0, GPU timers, audit 0 mismatch |
ELPA GPU probe, 2-stage (..._2stage_default_kernel_gpu_analytic) |
1 / 2 / 4 | -- | -- | PASS: 5.8e-15 / 7.3e-15 / 6.9e-15; 1.0e-11 / 1.0e-11 / 8.1e-12; CPU counterparts SKIPPED (not built) |
VALIDATED_PASS at 1, 2 and 4 GPUs (validate.sh 2026-09-06 05:04-05:12 UTC: [0] probe
PASS, [1] al_md within the pre-fixed tolerances of upstream's reference and of the
1-GPU run, launcher audit N verified / 0 mismatch; the 05:01-05:03 UTC pass FAILED on
[0] only, with the aborted probe -- kept in validate.*.stdout history).
Strong scaling: 32-atom deck 1.85x / 3.1x on 2 / 4 GPUs (small problem, 50 k DOFs);
192-atom LLZO 1.81x / 3.07x. Dry-runs: 8/40/80 GPUs planned (HYPOTHETICAL) for the
strong decks; the weak series is defined for 1/2/4/8 GPUs only (40/80 refused by run.sh). The weak series is synthetic (32 atoms per GPU; the electronic-structure
cost grows faster than linearly with the cell, so constant wall time is not
expected -- reported, not "ideal"). Probe record: <install>/elpa/ELPA_GPU_PROBE.txt,
per-program logs build/level3/dftfe/<profile>/elpa_probe/.
The application source is not in git and not read from _upstream/: tools/prepare_benchmark.sh level3 dftfe materializes the frozen source artifact (<app>[-<variant>]-<source_version>.tar.zst, found in the local content-addressed cache .artifacts/sha256/ or downloaded from the immutable URL recorded in provenance/source.lock*.yaml once published; --artifact FILE for a local copy) into src/ (+ deps/), the only source build.sh/run.sh/validate.sh use. Archive size + sha256 and source_tree_sha256 are verified before anything is placed. Identity, patch series, licenses, redistribution status and the equivalence proof against the tree the results above were validated from are under provenance/ (source.lock*.yaml, patch_series*.txt, original_vs_baseline*.diff, LICENSES*.md, equivalence*.md, LOC*.md); benchmark.yaml is the machine-readable contract (entries, inputs, references, identity). The benchmark does not prescribe which part of the source an optimization agent may modify; the integrity layer only protects the harness and the validation assets. Remote status: see level3/SOURCE_ARTIFACTS.md.
| variant | artifact | source version | compressed / uncompressed | entries | source_tree_sha256 | archive sha256 | upstream | patches (pre-applied) | redistribution | equivalence | remote | LOC app-owned / bundled deps / benchmark deps / tests / total |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - | dftfe-hpcperf-l3-v1.tar.zst |
hpcperf-l3-v1 | 174.5 MB / 262.3 MB | 3525 | 54bea98826f91a4ce298fd247da5f5168f595bef5b5ddac629b74bdc82ffea30 |
0259dfec2c9459f7ddd824a5eef468d04f77638b0a3cdd323a2cc342fe637670 |
release 1.2.0 commit (2025-08-17) 7147faa51f7c |
0001-std-isnan.patch | cleared | src: EQUIVALENT, deps/spglib: EQUIVALENT | REMOTE_FETCH_VERIFIED | 107718 / 0 / 12784642 / 314 / 12896192 |
LOC = cloc 2.06 code lines of the materialized tree (no blank/comment lines, documentation and data excluded); source-ownership categories from provenance/source.lock*.yaml (source_scope, descriptive metadata written at freeze time). Dependencies are counted per benchmark, so totals overlap across benchmarks that ship the same dependency. The validated results recorded above were produced from trees proven content-equivalent to this artifact (provenance/equivalence*.md); they are not re-run by the migration.