Repository navigation
feat(lcao): add optional LibRI GPU contractions through DDLA - #8169
Stardust0831 wants to merge 15 commits into
Conversation
|
the LibDDLA version which is compatible with LibRI GPU is https://github.com/userchba/LibDDLA/releases/tag/v0.0.4, current LibRI GPU can't correctly compute symmetry situation which LibRI CPU can compute correctly |
ABACUS-PR-BOT
left a comment
There was a problem hiding this comment.
Static review of f07d8d14f39d26782490cc4bc15d0a58c5700e62 with independent source review and adjudication. No build/runtime/MPI/GPU tests were run; CI diagnostics were unavailable.
| (default OFF), `USE_CUDA=ON`, and a CUDA build of DDLA. Like other dependent | ||
| options, GPU RI is disabled when its LibRI/CUDA prerequisites are disabled. | ||
| INPUT `exx_device` defaults to `cpu`, retaining CPU contractions even with | ||
| `device gpu`. To use GPU contractions, set both `device gpu` and `exx_device gpu`. |
There was a problem hiding this comment.
[P2] State the GPU visibility requirement for MPI runs
For two ranks on one node, exposing one different GPU per rank through CUDA_VISIBLE_DEVICES passes ABACUS device setup but makes the pinned LibRI validate_local_gpu_count() throw at the first GPU contraction (local_size=2 > device_count=1). This backend therefore requires each process to see at least as many GPUs as there are node-local ranks, a constraint missing here. Please document it with a compatible launch layout, or extend the compatibility patch to respect the existing per-rank binding.
| Exx_Info& exx_info) | ||
| { | ||
| #ifdef __EXX | ||
| const bool use_gpu = inp.exx_device == "gpu"; |
There was a problem hiding this comment.
Non-blocking: Please clarify the selector's scope for independent LR/RDMFT exchange engines. Standalone LR, fresh LR-kernel setup after KS, and RDMFT construct their own Exx_LRI objects, which retain CPU mode despite accepted exx_device=gpu; matching-kernel KS pointer reuse retains GPU mode. If those engines are in scope, pass the selection to them; otherwise document or reject the unsupported combinations. A follow-up after merge is fine for these additional workflows.
| { | ||
| return 1; | ||
| } | ||
| lri.cal_mode = RI::LRI_Cal_Mode::GPU; |
There was a problem hiding this comment.
Non-blocking: Consider an opt-in numerical regression for the patch's signed accumulation in a follow-up after merge. This consumer switches cal_mode but then executes only CPU nrm2, and the configure probe only compiles/links. Alongside the reported force/stress runs, a tiny real/complex CPU-versus-GPU case with nonempty output and repeated +1/-1 contractions would preserve the specific accumulation fix across dependency updates.
|
To be consistent, I think device_exx maybe better than exx_device |
Thank you for the review and suggestions; I’ve renamed exx_device to device_exx. |
|
@Growl1234 Could you check the cmake changes for this PR? |
| if(ENABLE_LIBRI_GPU) | ||
| message( | ||
| FATAL_ERROR | ||
| "ENABLE_LIBRI_GPU requires an explicitly supplied, patched LIBRI_DIR; " |
There was a problem hiding this comment.
Does it mean that LibRI master branch hasn't yet accepted the LibRI changes? If this is true then this PR should not be merged on abacus side first.
There was a problem hiding this comment.
LibDDLA has CMake config export, why is FindDDLA module needed here?
|
I have no further comment within this PR's scope. |
What's changed?
Enable optional GPU acceleration of LCAO exact-exchange RI tensor contractions through LibRI's DDLA CUDA backend, with a build option and a runtime INPUT keyword:
ENABLE_LIBRI_GPU: new CMake option, defaultOFF. Enable it together withENABLE_LIBRI=ONandUSE_CUDA=ONto build the DDLA GPU backend.device_exx: new INPUT keyword, defaultcpu. Setdevice_exx gputogether withdevice gputo run RI contractions on the GPU.device gpualone continues to use CPU RI, so the solver and RI backend can be selected separately.Build with compatible LibRI and DDLA installations:
Then select the GPU RI backend in INPUT:
The backend is experimental. Installation, dependency versions and runtime requirements are documented in
docs/advanced/install.md.Dependencies and supported scope
6ce3c84withtests/lcao_hse_gpu/libri-compat.patchand CUDA DDLAv0.0.4(9c404ac). The patch fixes API compatibility and accumulation needed for forces and stress. CMake locates DDLA throughDDLA_ROOTorCMAKE_PREFIX_PATHand checks GPU API compilation/linking.symmetry 1, usedevice_exx cpuor setexx_symmetry_realspace 0; unsupported combinations are rejected.Unit Tests and/or Case Tests for my changes
Functional checks used SAI V100 GPUs with
OMP_NUM_THREADS=1; the performance runs below tune MPI/OpenMP:3fa1f972b, after merging currentdevelop, a fresh GPU build, INPUT unit tests with GPU RI enabled and disabled (10 tests in each configuration), CPU/GPU dependency consumers and the optional numerical GPU test passed. CLI help, generated metadata and--check-inputusedevice_exx; the formerexx_devicekeyword is rejected.Si64 force benchmark
A displaced Si64 HSE/DZP Gamma-point case (832 orbitals) was tested at
63ca5efon SAI V100-SXM2 16 GB GPUs and an AMD Ryzen Threadripper PRO 5995WX CPU. These performance measurements predate the keyword rename; archived inputs useexx_device, while examples below usedevice_exx. The performance benchmark was not rerun for this rename. Each GPU is allocated 4 physical CPU cores / 8 SMT hardware threads. CPU-only and single-GPU runs use the same four physical cores; two-GPU runs use eight. Runs execute sequentially on the same node, with explicit CPU affinity.CPU-only uses ScaLAPACK and CPU RI; GPU runs use cuSOLVER and GPU RI. Seven CPU MPI/OpenMP ratios and single-GPU
1×4/1×8were tested (details below). The fastest CPU configurations are 1 MPI × 8 OpenMP for forces and 4 MPI × 2 OpenMP for the complete calculation; each row uses its corresponding CPU baseline. The selected GPU configuration uses 4 OpenMP threads per rank, with one rank per GPU. Selected configurations are run twice; the table shows their mean times.device_exx cputogpugives 3.87x for all force work and 1.49x overall. This uses one CPU-RI run and the mean of two GPU-RI runs; the CPU-only table also includes the solver change.EXX and all-force timings are nested ABACUS timers. Complete-calculation times include launch, initialization and SCF. These measurements cover one case on one node with the supplied ScaLAPACK/OpenBLAS build.
Verification commands and validation limits
Fresh validation of
3fa1f972bused the commands below (SAI job1868744).GPU_BUILD_DIRhas CUDA/GPU RI enabled;CPU_BUILD_DIRhas both disabled:From copies of
tests/08_RI, using the existing references:Variants cover CPU and GPU solvers with the default and explicit RI backend selections. Symmetry cases cover CPU RI with real-space symmetry enabled and CPU/GPU RI with it disabled.
Standalone dependency checks:
The numerical test requires one GPU and MPI and is off by default. The CPU consumer uses
ENABLE_LIBRI_GPU=OFFandENABLE_LIBRI_GPU_TESTS=OFF. Earlier MKL consumers additionally setMKL_ROOT,MKL_MPI=openmpiandMKL_LINK=staticordynamic.The Si64 hybrid sweep was launched with
sbatch control/run.sbatch(SAI job1862952, exit0:0). Each calculation runs:The launcher pins each rank to a recorded, disjoint subset of the scheduler cpuset and sets explicit
OMP_PLACES; an OpenMP probe verifies every thread's CPU before each run.OMP_DYNAMIC=FALSEandOMP_MAX_ACTIVE_LEVELS=1; BLAS stays single-threaded to avoid nested oversubscription. The physical-core sweep uses one hardware thread per core; the SMT sweep also uses its sibling. CPU-only runs have no visible GPU and no observed GPU process. GPU RI uses one rank per GPU and the same visible GPU list on all ranks.CPU-only INPUT:
device cpu,ks_solver scalapack_gvx,device_exx cpu. GPU RI INPUT:device gpu,ks_solver cusolver,device_exx gpu. Thecpu_ri_gpu_solvercontrol keeps the GPU settings and changes onlydevice_exx cpu.Settings:
cal_force=1,cal_stress=0,symmetry=0,exx_symmetry_realspace=0,ecutwfc=60,nbands=160,scf_thr=1e-9,scf_ene_thr=1e-8,exx_pca_threshold=1e-4andexx_ccp_rmesh_times=1. Each run starts from atomic density. Independent post-run checks of full force vectors, structures, numerical settings, asset hashes, executable hash and CPU/GPU placement passed at tolerances of 1e-4 eV/Angstrom for forces and 1e-6 eV/atom for energy. The one-pass sweep selects configurations for one additional repeat; this is a small tuning experiment, not an exhaustive CPU solver/library comparison.GPU regression builds used
ENABLE_NCCL_PARALLEL_DEVICE=OFFbecause the input-test target had unresolved NCCL symbols with it enabled. NCCL runtime behavior, full MKL application builds, multi-node execution, SOC and long MD runs remain unverified. GPU memory use increases; initialization remains largely on CPU. A Si32 comparison neededscf_ene_thr=1e-8for consistent outer-loop stopping, so default-threshold convergence needs further validation.Linked Issue
No linked issue; this adds optional support for an existing LibRI backend.
Governance Notes
device_exxincludes parser validation, MPI broadcast, help metadata, installation documentation and focused tests. Generated parameter documentation is not committed.LibRI::LibRIandDDLA::DDLACMake targets. No new global dependencies. GPU RI requires C++17; CPU RI retains C++14.Follow-up: add DDLA installation to the existing
toolchain/scripts/workflow.Contribution checklist
AGENTS.mdanddocs/developers_guide/agent_governance.md.source/changes.