Add WFN-history backend for Gamma-only NAO calculations - #7442
Add WFN-history backend for Gamma-only NAO calculations#7442Growl1234 wants to merge 22 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds Gamma-only LCAO wavefunction-history extrapolation (use_prev_wf) by snapshotting the previous step’s coefficients and reorthonormalizing them against the current overlap matrix before SCF.
Changes:
- Introduces LCAO wavefunction snapshot/history helpers and a Gamma-only reorthonormalization routine.
- Wires extrapolation into the LCAO ESolver flow and adds
wfc_extrapinput validation/handling (including skipping charge extrapolation when enabled). - Updates CMake to enforce a minimum C++ standard and adds a new
module_extrapsubdirectory target.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| source/source_lcao/module_extrap/wf_snapshot_lcao.h | Stores/restores full Psi coefficient snapshots plus occupations. |
| source/source_lcao/module_extrap/wf_orthonormalize_lcao.h | Declares Gamma-only reorthonormalization API + diagnostic result struct. |
| source/source_lcao/module_extrap/wf_orthonormalize_lcao.cpp | Implements MPI-aware assembly + Cholesky-based reorthonormalization. |
| source/source_lcao/module_extrap/wf_history_lcao.h | Defines wavefunction history class and apply-result diagnostics. |
| source/source_lcao/module_extrap/wf_history_lcao.cpp | Implements history management and use_prev_wf apply path. |
| source/source_lcao/module_extrap/wf_extrap_method.h | Adds extrapolation method/status enums and string conversions. |
| source/source_lcao/module_extrap/CMakeLists.txt | Adds lcao_extrap object library target for new module sources. |
| source/source_lcao/CMakeLists.txt | Enables module_extrap subdir and adds new sources to LCAO objects list. |
| source/source_io/module_parameter/read_input_item_system.cpp | Adds wfc_extrap input item, docs, and validation checks. |
| source/source_io/module_parameter/input_parameter.h | Adds wfc_extrap parameter with default "none". |
| source/source_esolver/esolver_ks_lcao.h | Adds wf_history_lcao_ member to ESolver. |
| source/source_esolver/esolver_ks_lcao.cpp | Initializes history, prepares overlap early, applies extrapolation, rebuilds density, updates history after SCF. |
| source/source_esolver/esolver_fp.cpp | Skips charge extrapolation when wfc_extrap is enabled (LCAO, istep>0). |
| CMakeLists.txt | Enforces a minimum C++ standard globally (now 14). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ddc1a25 to
375f25c
Compare
1fe84e8 to
8e662df
Compare
276a700 to
3faaf27
Compare
|
Thank you for your pull request. This PR presents a creative idea, and we are open to merging it, yet several issues need to be discussed first: |
|
Thank you for reviewing!
Those code is most likely for debugging and finding errors. Once further validation from maintainer's side is done, they could be considered dropped. |
This is not intended to introduce a "creative algorithm" or any "new method". It just implements the basic, lowest-order wavefunction-history initialization referred to as This basic idea is already used, in various forms, in many quantum-chemistry and electronic-structure packages, including Gaussian, ORCA, and CP2K. In particular, the CP2K implementation was the direct motivation for introducing this capability in ABACUS. Its Moreover, this low-level capability is also a necessary foundation for introducing formally published higher-order wavefunction-extrapolation methods, such as |
For the current Gamma-only NAO benchmark, the WFN-based initialization reduces the total number of SCF iterations from 44 to 35 and reduces the total runtime from about 32.7 s to 28.2 s, while preserving the final result. This is the result from small-cell test, but if tested with large cells, the improvements should be more significant. That said, since it is not yet implemented with k-points, this PR should not be regarded as broadly applicable or as demonstrating general performance improvements across all ABACUS workflows. |
I agree with this point. The current implementation leaves too much WFN-specific logic in Btw, the diagnostics part in the implementation most likely can be dropped. |
655bd29 to
daae910
Compare
|
It seems moving specific logic from |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
source/source_lcao/module_extrap/wf_density_init_lcao.cpp:115
- Rule: Do not increase cross-layer control through GlobalV, GlobalC, or PARAM
Severity: warning
Location: source/source_lcao/module_extrap/wf_density_init_lcao.cpp:113-115
Reason: New GlobalV::ofs_running usage is introduced in the new extrapolation backend, increasing reliance on global state in a reusable module.
Suggested action: Propagate success diagnostics (snapshot_istep, nactive_bands, max deviation) back to the ESolver layer and perform logging there, or accept and document a governance exception with reason/scope/risk/cleanup plan.
Exception: human approval required
GlobalV::ofs_running << " WFN extrapolation: use_prev_wf from ionic step " << result.snapshot_istep
<< ", active bands = " << result.nactive_bands
<< ", max |C^T S C - I| = " << result.max_orthonormality_deviation << std::endl;
source/source_lcao/module_extrap/wf_history_lcao.cpp:168
- reorthonormalize_gamma_lcao() uses the provided occupation matrix to decide how many bands to reorthonormalize (and leaves the rest untouched). Passing snapshot.wg (previous ionic step occupations) can be wrong when occupations change between steps (e.g., metallic systems / smearing), potentially leaving currently-occupied bands non-orthonormal and corrupting the DM rebuilt with wg_now.
const WfOrthonormalizeResult orth_result = reorthonormalize_gamma_lcao(current_overlap,
pv,
psi_trial,
snapshot.wg,
1.0e-12,
pivot_threshold,
check_tolerance);
source/source_esolver/esolver_ks_lcao.cpp:3
- source_base/global_function.h appears unused in this translation unit (no ModuleBase::GlobalFunc usage). Keeping it increases compile dependencies and can introduce avoidable coupling to global headers.
#include "esolver_ks_lcao.h"
#include "source_base/global_function.h"
#include "source_base/module_external/blacs_connector.h"
source/source_esolver/esolver_fp.cpp:198
- Skipping charge-density extrapolation solely based on wfc_extrap/istep can leave chr/sf in a stale state when the WFN-history path is unavailable (e.g., previous SCF not converged so no snapshot was stored, or history was cleared). In that case initialize_gamma_density() falls back and returns false, but charge extrapolation has already been skipped, so the SCF may start from an inconsistent density for the updated ionic positions.
const bool skip_charge_extrap_for_wfc = PARAM.inp.basis_type == "lcao"
&& PARAM.inp.wfc_extrap != "none"
&& istep > 0;
if (skip_charge_extrap_for_wfc)
{
this->sf.setup(&ucell, this->Pgrid, this->pw_rhod);
GlobalV::ofs_running << " charge density extrapolation is skipped because wfc_extrap = "
<< PARAM.inp.wfc_extrap << "." << std::endl;
}
else
{
this->CE.extrapolate_charge(&this->Pgrid, ucell, &this->chr, &this->sf,
GlobalV::ofs_running, GlobalV::ofs_warning);
}
| ModuleBase::timer::start("WFN_Extrap", "prepare_overlap"); | ||
| lcao_op->contributeHR(); | ||
| const int sk_layout = ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(ks_solver) ? 1 : 0; | ||
| hamilt_lcao->updateSk(0, sk_layout); | ||
| ModuleBase::timer::end("WFN_Extrap", "prepare_overlap"); | ||
|
|
||
| ModuleBase::timer::start("WFN_Extrap", "apply"); | ||
| const WfExtrapApplyResult result = this->try_use_prev_wf_gamma(hamilt_lcao->getSk(), pv, psi, wg_now); | ||
| ModuleBase::timer::end("WFN_Extrap", "apply"); |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
source/source_lcao/module_extrap/wf_orthonormalize_lcao.cpp:332
- Similar to overlap_global, coeff_global is materialized as a dense nactive_bands×nbasis_global array on every rank and combined via MPI_Allreduce. This can become a large O(nbands·nbasis) memory+bandwidth cost (in addition to the overlap gather) and may negate the runtime benefit of WFN-based initialization on bigger systems. Consider using a distributed representation/workflow (or adding a size guard and clear diagnostics) so wfc_extrap fails fast rather than risking memory exhaustion.
TimerGuard timer("WFN_Extrap", "assemble_coeff");
const int nbasis_global = pv.get_global_row_size();
if (coeff_local == nullptr || nbasis_global <= 0 || ncoeff_local <= 0 || nbasis_local <= 0
|| nactive_bands < 0 || pv.get_row_size() != nbasis_local)
{
return WfcExtrapStatus::DimensionMismatch;
}
coeff_global.assign(static_cast<std::size_t>(nactive_bands) * static_cast<std::size_t>(nbasis_global), 0.0);
| TimerGuard timer("WFN_Extrap", "assemble_overlap"); | ||
| const int nbasis_global = pv.get_global_row_size(); | ||
| if (overlap == nullptr || nbasis_global <= 0 || pv.get_global_col_size() != nbasis_global) | ||
| { | ||
| return WfcExtrapStatus::DimensionMismatch; | ||
| } | ||
|
|
||
| overlap_global.assign(static_cast<std::size_t>(nbasis_global) * static_cast<std::size_t>(nbasis_global), 0.0); |
This PR introduces an optional WFN-based initialization path for NAO calculations.
A new
wfc_extrap use_prev_wfpath is added. It stores the converged wavefunction from the previous ionic step, rebuilds the current overlap matrix, reorthonormalizes the previous wavefunction with the current overlap matrix, and then reconstructs the density matrix and charge density before entering the normal SCF cycle. When this path is enabled, the existing charge-density extrapolation is skipped, so the initial density is generated from the WFN-history backend instead of being extrapolated directly in real space.The implementation currently focuses on the Gamma-only backend, including MPI-distributed matrices. This is intended as a common backend for future improvements and more WFN-based predictors such as ASPC and GExt_PROJ.
Here's a simple test that shows the accuracy and effectiveness of the WFN-based path: test.zip. The regtesting is left for a next commit.
Still missing:
What's planned in the future:
Details
Linked Issue
None
Unit Tests and/or Case Tests for my changes
02_NAO_Gamma/relax_wfc_extrapExact Verification Performed
What's changed?
Governance Checklist
GlobalV,GlobalC, orPARAMcode references, or exception requested below with reason, scope, risk, and cleanup plan..hpppropagation, or rationale provided below..batand.cmduse CRLF.source/CMakeLists.txt, or rationale provided below.@coderabbitai review.INPUT Parameter Changes
wfc_extrap none/use_prev_wfdocs/parameters.yamlupdated: not yetdocs/advanced/input_files/input-main.mdupdated: not yetCore Module Impact
Governance Exception