Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8a3aea7
Optimize PEXSI stage4 code path
JohnHe233 May 23, 2026
5978ae6
Enable complex multi-k PEXSI path
JohnHe233 May 24, 2026
a872a63
Optimize multi-k PEXSI execution path
JohnHe233 May 25, 2026
8eb4e6e
Add PEXSI multi-k trace hooks
JohnHe233 May 25, 2026
a1f21da
Trace PEXSI multi-k chemical potential search
JohnHe233 May 25, 2026
c287a02
Filter PEXSI trace output by category
JohnHe233 May 25, 2026
0602a18
Respect PEXSI mu guard in multi-k fallback
JohnHe233 May 25, 2026
be11350
Document PEXSI stage4 optimization results
JohnHe233 May 25, 2026
0e844d4
Add PEXSI section 5.1 scaling benchmark
JohnHe233 May 26, 2026
7b0863c
Parameterize PEXSI 5.1 benchmark accuracy
JohnHe233 May 26, 2026
36565e5
Expose PEXSI mu tolerance in 5.1 benchmark
JohnHe233 May 26, 2026
b3d5986
Expose PEXSI zero threshold in 5.1 benchmark
JohnHe233 May 26, 2026
7eef88d
Allow smearing override in PEXSI 5.1 benchmark
JohnHe233 May 26, 2026
1b331d3
Tune default smearing for PEXSI 5.1 systems
JohnHe233 May 26, 2026
b8e78ff
Tune metal smearing for PEXSI 5.1 benchmark
JohnHe233 May 26, 2026
fc44ba7
Fix PEXSI 5.1 benchmark timing tolerances
JohnHe233 May 26, 2026
bf0ff7a
Add summary refresh mode for PEXSI 5.1 benchmark
JohnHe233 May 26, 2026
fed73cd
Compare PEXSI 5.1 forces componentwise
JohnHe233 May 26, 2026
877b26e
Parse PEXSI trace timings in 5.1 benchmark
JohnHe233 May 26, 2026
8a2a370
Tune 5.1 benchmark kpar selection
JohnHe233 May 26, 2026
63b1d25
Fix PEXSI EDM ownership for force stress
JohnHe233 May 27, 2026
1d16a60
Reuse PEXSI complex setup conservatively
JohnHe233 May 27, 2026
88b0d8c
Keep Gamma PEXSI baseline performance
JohnHe233 May 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
649 changes: 649 additions & 0 deletions pexsi_kpoint_parallel_optimization_report.tex
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need your .tex file in this PR

Large diffs are not rendered by default.

737 changes: 737 additions & 0 deletions pexsi_stage4_code_refactor_report.tex
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need tex file in the code

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions source/source_esolver/esolver_ks_lcao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,13 @@ void ESolver_KS_LCAO<TK, TR>::hamilt2rho_single(UnitCell& ucell, int istep, int
// 3) run Hsolver
if (!skip_solve)
{
#ifdef __PEXSI
hsolver::HSolverLCAO<TK> hsolver_lcao_obj(&(this->pv),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, the code for solving the Kohn-Sham equations allows users to enable PEXSI optionally, or apply PEXSI for part of the computation — for instance, performing several PEXSI steps before switching to exact diagonalization. To maximize flexibility, macro definitions are not recommended for feature branching, as they tend to hardcode program logic.

PARAM.inp.ks_solver,
&this->pexsi_reuse_contexts_);
#else
hsolver::HSolverLCAO<TK> hsolver_lcao_obj(&(this->pv), PARAM.inp.ks_solver);
#endif
hsolver_lcao_obj.solve(static_cast<hamilt::Hamilt<TK>*>(this->p_hamilt), this->psi[0], this->pelec, *this->dmat.dm,
this->chr, PARAM.inp.nspin, skip_charge);
}
Expand Down
7 changes: 7 additions & 0 deletions source/source_esolver/esolver_ks_lcao.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
#include "source_lcao/setup_dm.h" // mohan add 2025-10-30

#include <memory>
#include <vector>

#ifdef __PEXSI
#include "source_hsolver/module_pexsi/simple_pexsi.h"
#endif

// for Linear Response
namespace LR
Expand Down Expand Up @@ -82,6 +86,9 @@ class ESolver_KS_LCAO : public ESolver_KS
//! Add density matrix class, mohan add 2025-10-30
LCAO_domain::Setup_DM<TK> dmat;

#ifdef __PEXSI
std::vector<pexsi::PexsiComplexReuseContext> pexsi_reuse_contexts_;
#endif

// For deepks method, mohan add 2025-10-08
Setup_DeePKS<TK> deepks;
Expand Down
6 changes: 6 additions & 0 deletions source/source_esolver/esolver_ks_lcao_tddft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,13 @@ void ESolver_KS_LCAO_TDDFT<TR, Device>::hamilt2rho_single(UnitCell& ucell,
if (this->psi != nullptr)
{
bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false;
#ifdef __PEXSI
hsolver::HSolverLCAO<std::complex<double>> hsolver_lcao_obj(&this->pv,
PARAM.inp.ks_solver,
&this->pexsi_reuse_contexts_);
#else
hsolver::HSolverLCAO<std::complex<double>> hsolver_lcao_obj(&this->pv, PARAM.inp.ks_solver);
#endif
hsolver_lcao_obj.solve(static_cast<hamilt::Hamilt<std::complex<double>>*>(this->p_hamilt),
this->psi[0],
this->pelec,
Expand Down
53 changes: 51 additions & 2 deletions source/source_estate/elecstate_lcao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void ElecStateLCAO<double>::dm2rho(std::vector<double*> pexsi_DM,
}

#ifdef __PEXSI
dm->pexsi_EDM = pexsi_EDM;
dm->set_pexsi_EDM_pointer(pexsi_EDM);
#endif

for (int is = 0; is < nspin; is++)
Expand Down Expand Up @@ -80,7 +80,56 @@ void ElecStateLCAO<std::complex<double>>::dm2rho(std::vector<std::complex<double
std::vector<std::complex<double>*> pexsi_EDM,
DensityMatrix<std::complex<double>, double>* dm)
{
ModuleBase::WARNING_QUIT("ElecStateLCAO", "pexsi is not completed for multi-k case");
ModuleBase::timer::start("ElecStateLCAO", "dm2rho");

const int dmk_size = dm->get_DMK_size();
if (static_cast<int>(pexsi_DM.size()) < dmk_size)
{
ModuleBase::WARNING_QUIT("ElecStateLCAO", "PEXSI multi-k density matrix buffer is smaller than DMK storage");
}

const int local_matrix_size = dm->get_DMK_nrow() * dm->get_DMK_ncol();
const double pexsi_spin_weight = PARAM.inp.nspin == 1 ? 0.5 : 1.0;
for (int ik = 0; ik < dmk_size; ++ik)
{
const double k_weight = ((this->klist != nullptr && ik < static_cast<int>(this->klist->wk.size()))
? this->klist->wk[ik]
: 1.0)
* pexsi_spin_weight;
for (int i = 0; i < local_matrix_size; ++i)
{
pexsi_DM[ik][i] *= k_weight;
pexsi_EDM[ik][i] *= k_weight;
}
dm->set_DMK_pointer(ik, pexsi_DM[ik]);
}

#ifdef __PEXSI
dm->set_pexsi_EDM_pointer(pexsi_EDM);
#endif

dm->cal_DMR();

for (int is = 0; is < PARAM.inp.nspin; is++)
{
ModuleBase::GlobalFunc::ZEROS(this->charge->rho[is], this->charge->nrxx);
}

ModuleBase::GlobalFunc::NOTE("Calculate the charge on real space grid!");
ModuleGint::cal_gint_rho(dm->get_DMR_vector(), PARAM.inp.nspin, this->charge->rho);
if (XC_Functional::get_ked_flag())
{
for (int is = 0; is < PARAM.inp.nspin; is++)
{
ModuleBase::GlobalFunc::ZEROS(this->charge->kin_r[0], this->charge->nrxx);
}
ModuleGint::cal_gint_tau(dm->get_DMR_vector(), PARAM.inp.nspin, this->charge->kin_r);
}

this->charge->renormalize_rho();

ModuleBase::timer::end("ElecStateLCAO", "dm2rho");
return;
}


Expand Down
25 changes: 25 additions & 0 deletions source/source_estate/module_dm/density_matrix.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#ifndef DENSITY_MATRIX_H
#define DENSITY_MATRIX_H

#include <algorithm>
#include <cstddef>
#include <string>
#include <vector>

#include "source_cell/module_neighbor/sltk_grid_driver.h"
#include "source_lcao/record_adj.h"
Expand Down Expand Up @@ -267,6 +270,24 @@ class DensityMatrix
std::vector<ModuleBase::ComplexMatrix> EDMK; // for TD-DFT

#ifdef __PEXSI
void set_pexsi_EDM_pointer(const std::vector<TK*>& pexsi_EDM_in)
{
const int local_size = this->_paraV->nrow * this->_paraV->ncol;
this->pexsi_EDM_storage_.resize(pexsi_EDM_in.size());
this->pexsi_EDM.resize(pexsi_EDM_in.size());
for (std::size_t ik = 0; ik < pexsi_EDM_in.size(); ++ik)
{
this->pexsi_EDM_storage_[ik].resize(local_size);
if (local_size > 0)
{
std::copy(pexsi_EDM_in[ik],
pexsi_EDM_in[ik] + local_size,
this->pexsi_EDM_storage_[ik].begin());
}
this->pexsi_EDM[ik] = this->pexsi_EDM_storage_[ik].data();
}
}

/**
* @brief EDM storage for PEXSI
* used in MD calculation
Expand Down Expand Up @@ -298,6 +319,10 @@ class DensityMatrix
// std::vector<ModuleBase::ComplexMatrix> _DMK;
std::vector<std::vector<TK>> _DMK;

#ifdef __PEXSI
std::vector<std::vector<TK>> pexsi_EDM_storage_;
#endif

/**
* @brief K_Vectors object, which is used to get k-point information
*/
Expand Down
22 changes: 22 additions & 0 deletions source/source_estate/module_dm/test/test_dm_constructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,28 @@ TEST_F(DMTest, DMConstructor_nspin2)
delete kv;
}

#ifdef __PEXSI
TEST_F(DMTest, PexsiEDMIsOwnedCopy)
{
elecstate::DensityMatrix<double, double> DM(paraV, 1);
const int local_size = paraV->nrow * paraV->ncol;
std::vector<double> external_edm(local_size);
for (int i = 0; i < local_size; ++i)
{
external_edm[i] = static_cast<double>(i + 1);
}

DM.set_pexsi_EDM_pointer({external_edm.data()});
std::fill(external_edm.begin(), external_edm.end(), -1.0);

ASSERT_EQ(DM.pexsi_EDM.size(), 1);
for (int i = 0; i < local_size; ++i)
{
EXPECT_DOUBLE_EQ(DM.pexsi_EDM[0][i], static_cast<double>(i + 1));
}
}
#endif

int main(int argc, char** argv)
{
#ifdef __MPI
Expand Down
Loading
Loading