Skip to content

Commit a5c35d9

Browse files
dyzhengdyzhengpre-commit-ci-lite[bot]
authored
Feature: update new version of dav_subspace with higher performance (#5199)
* Feature: update new version of dav_subspace * Fix: UnitTest error * [pre-commit.ci lite] apply automatic fixes * Fix: UnitTest HSolver_PW * Fix: comments in PR * Fix: error in UT --------- Co-authored-by: dyzheng <[email protected]> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent c51bf82 commit a5c35d9

File tree

25 files changed

+222
-457
lines changed

25 files changed

+222
-457
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
- [pw\_diag\_thr](#pw_diag_thr)
4040
- [pw\_diag\_nmax](#pw_diag_nmax)
4141
- [pw\_diag\_ndim](#pw_diag_ndim)
42-
- [diago\_full\_acc](#diago_full_acc)
4342
- [erf\_ecut](#erf_ecut)
4443
- [fft\_mode](#fft_mode)
4544
- [erf\_height](#erf_height)
@@ -779,12 +778,6 @@ These variables are used to control the plane wave related parameters.
779778
- **Description**: Only useful when you use `ks_solver = dav` or `ks_solver = dav_subspace`. It indicates dimension of workspace(number of wavefunction packets, at least 2 needed) for the Davidson method. A larger value may yield a smaller number of iterations in the algorithm but uses more memory and more CPU time in subspace diagonalization.
780779
- **Default**: 4
781780

782-
### diago_full_acc
783-
784-
- **Type**: bool
785-
- **Description**: Only useful when you use `ks_solver = dav_subspace`. If `TRUE`, all the empty states are diagonalized at the same level of accuracy of the occupied ones. Otherwise the empty states are diagonalized using a larger threshold (10-5) (this should not affect total energy, forces, and other ground-state properties).
786-
- **Default**: false
787-
788781
### erf_ecut
789782

790783
- **Type**: Real
@@ -925,7 +918,7 @@ calculations.
925918
- **cg**: cg method.
926919
- **bpcg**: bpcg method, which is a block-parallel Conjugate Gradient (CG) method, typically exhibits higher acceleration in a GPU environment.
927920
- **dav**: the Davidson algorithm.
928-
- **dav_subspace**: subspace Davidson algorithm
921+
- **dav_subspace**: Davidson algorithm without orthogonalization operation, this method is the most recommended for efficiency. `pw_diag_ndim` can be set to 2 for this method.
929922

930923
For atomic orbitals basis,
931924

examples/lr-tddft/lcao_Si2/INPUT

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,3 @@ out_alllog 1
3737

3838
nvirt 19
3939
abs_wavelen_range 100 175
40-
#diago_full_acc 1

python/pyabacus/src/py_diago_dav_subspace.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class PyDiagoDavSubspace
106106
double tol,
107107
int max_iter,
108108
bool need_subspace,
109-
std::vector<bool> is_occupied,
109+
std::vector<double> diag_ethr,
110110
bool scf_type,
111111
hsolver::diag_comm_info comm_info
112112
) {
@@ -141,7 +141,7 @@ class PyDiagoDavSubspace
141141
comm_info
142142
);
143143

144-
return obj->diag(hpsi_func, psi, nbasis, eigenvalue, is_occupied, scf_type);
144+
return obj->diag(hpsi_func, psi, nbasis, eigenvalue, diag_ethr.data(), scf_type);
145145
}
146146

147147
private:

python/pyabacus/src/py_hsolver.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ void bind_hsolver(py::module& m)
5959
The maximum number of iterations.
6060
need_subspace : bool
6161
Whether to use the subspace function.
62-
is_occupied : list[bool]
63-
A list of boolean values indicating whether the band is occupied,
62+
diag_ethr : list[float]
63+
A list of float values indicating the thresholds of each band for the diagonalization,
6464
meaning that the corresponding eigenvalue is to be calculated.
6565
scf_type : bool
6666
Whether to use the SCF type, which is used to determine the
@@ -76,7 +76,7 @@ void bind_hsolver(py::module& m)
7676
"tol"_a,
7777
"max_iter"_a,
7878
"need_subspace"_a,
79-
"is_occupied"_a,
79+
"diag_ethr"_a,
8080
"scf_type"_a,
8181
"comm_info"_a)
8282
.def("set_psi", &py_hsolver::PyDiagoDavSubspace::set_psi, R"pbdoc(

python/pyabacus/src/pyabacus/hsolver/_hsolver.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def dav_subspace(
2525
tol: float = 1e-2,
2626
max_iter: int = 1000,
2727
need_subspace: bool = False,
28-
is_occupied: Union[List[bool], None] = None,
28+
diag_ethr: Union[List[float], None] = None,
2929
scf_type: bool = False
3030
) -> Tuple[NDArray[np.float64], NDArray[np.complex128]]:
3131
""" A function to diagonalize a matrix using the Davidson-Subspace method.
@@ -52,10 +52,8 @@ def dav_subspace(
5252
The maximum number of iterations, by default 1000.
5353
need_subspace : bool, optional
5454
Whether to use subspace function, by default False.
55-
is_occupied : List[bool] | None, optional
56-
The list of occupied bands, by default None. This indicates how many eigenvalues
57-
need to be calculated, starting from the smallest eigenvalue. Only the energy levels
58-
occupied by electrons (occupied) need to be calculated.
55+
diag_ethr : List[float] | None, optional
56+
The list of thresholds of bands, by default None.
5957
scf_type : bool, optional
6058
Indicates whether the calculation is a self-consistent field (SCF) calculation.
6159
If True, the initial precision of eigenvalue calculation can be coarse.
@@ -72,8 +70,8 @@ def dav_subspace(
7270
if not callable(mvv_op):
7371
raise TypeError("mvv_op must be a callable object.")
7472

75-
if is_occupied is None:
76-
is_occupied = [True] * num_eigs
73+
if diag_ethr is None:
74+
diag_ethr = [tol] * num_eigs
7775

7876
if init_v.ndim != 1 or init_v.dtype != np.complex128:
7977
init_v = init_v.flatten().astype(np.complex128, order='C')
@@ -93,7 +91,7 @@ def dav_subspace(
9391
tol,
9492
max_iter,
9593
need_subspace,
96-
is_occupied,
94+
diag_ethr,
9795
scf_type,
9896
comm_info
9997
)
@@ -113,7 +111,6 @@ def davidson(
113111
tol: float = 1e-2,
114112
max_iter: int = 1000,
115113
use_paw: bool = False,
116-
# is_occupied: Union[List[bool], None] = None,
117114
# scf_type: bool = False
118115
) -> Tuple[NDArray[np.float64], NDArray[np.complex128]]:
119116
""" A function to diagonalize a matrix using the Davidson-Subspace method.

source/module_elecstate/elecstate.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -252,31 +252,6 @@ void ElecState::init_ks(Charge* chg_in, // pointer for class Charge
252252
this->wg.create(nk_in, PARAM.inp.nbands);
253253
}
254254

255-
void set_is_occupied(std::vector<bool>& is_occupied,
256-
elecstate::ElecState* pes,
257-
const int i_scf,
258-
const int nk,
259-
const int nband,
260-
const bool diago_full_acc)
261-
{
262-
if (i_scf != 0 && diago_full_acc == false)
263-
{
264-
for (int i = 0; i < nk; i++)
265-
{
266-
if (pes->klist->wk[i] > 0.0)
267-
{
268-
for (int j = 0; j < nband; j++)
269-
{
270-
if (pes->wg(i, j) / pes->klist->wk[i] < 0.01)
271-
{
272-
is_occupied[i * nband + j] = false;
273-
}
274-
}
275-
}
276-
}
277-
}
278-
};
279-
280255

281256

282257
} // namespace elecstate

source/module_elecstate/elecstate.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,5 @@ class ElecState
194194
bool skip_weights = false;
195195
};
196196

197-
// This is an independent function under the elecstate namespace and does not depend on any class.
198-
void set_is_occupied(std::vector<bool>& is_occupied,
199-
elecstate::ElecState* pes,
200-
const int i_scf,
201-
const int nk,
202-
const int nband,
203-
const bool diago_full_acc);
204-
205197
} // namespace elecstate
206198
#endif

source/module_elecstate/potentials/pot_local.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ void PotLocal::cal_fixed_v(double *vl_pseudo // store the local pseudopotential
2929
}
3030
}
3131

32+
/// save the V_local at G=0
33+
if(this->rho_basis_->npw > 0)
34+
{
35+
*vl_of_0_ = vg[0].real();
36+
}
37+
3238
// recip2real should be a const function, but now it isn't
3339
// a dangerous usage appears here, which should be fix in the future.
3440
const_cast<ModulePW::PW_Basis *>(this->rho_basis_)->recip2real(vg, vl_pseudo);

source/module_elecstate/potentials/pot_local.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ class PotLocal : public PotBase
1212
public:
1313
PotLocal(const ModuleBase::matrix* vloc_in, // local pseduopotentials
1414
const ModuleBase::ComplexMatrix* sf_in,
15-
const ModulePW::PW_Basis* rho_basis_in)
16-
: vloc_(vloc_in), sf_(sf_in)
15+
const ModulePW::PW_Basis* rho_basis_in,
16+
double& vl_of_0)
17+
: vloc_(vloc_in), sf_(sf_in), vl_of_0_(&vl_of_0)
1718
{
1819
assert(this->vloc_->nr == this->sf_->nr);
1920
this->rho_basis_ = rho_basis_in;
@@ -24,6 +25,11 @@ class PotLocal : public PotBase
2425

2526
void cal_fixed_v(double* vl_pseudo) override;
2627

28+
private:
29+
30+
/// @brief save the value of vloc at G=0; this is a static member because there is only one vl(0) for all instances
31+
double* vl_of_0_ = nullptr;
32+
2733
// std::vector<double> vltot;
2834

2935
const ModuleBase::matrix* vloc_ = nullptr; // local pseduopotentials

source/module_elecstate/potentials/potential_new.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ class Potential : public PotBase
169169
return this->v_effective_fixed.data();
170170
}
171171

172+
173+
/// @brief get the value of vloc at G=0;
174+
/// @return vl(0)
175+
double get_vl_of_0() const
176+
{
177+
return this->vl_of_0;
178+
}
179+
172180
private:
173181
void cal_v_eff(const Charge*const chg, const UnitCell*const ucell, ModuleBase::matrix& v_eff) override;
174182
void cal_fixed_v(double* vl_pseudo) override;
@@ -196,6 +204,8 @@ class Potential : public PotBase
196204
double* etxc_ = nullptr;
197205
double* vtxc_ = nullptr;
198206

207+
double vl_of_0 = 0.0;
208+
199209
std::vector<PotBase*> components;
200210

201211
const UnitCell* ucell_ = nullptr;

0 commit comments

Comments
 (0)