Skip to content

Commit 02a9357

Browse files
committed
enable scalapack lr_solver
1 parent 123a0d3 commit 02a9357

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4231,6 +4231,7 @@ Currently supported: `RPA`, `LDA`, `PBE`, `HSE`, `HF`.
42314231
- **Description**: The method to solve the Casida equation $AX=\Omega X$ in LR-TDDFT under Tamm-Dancoff approximation (TDA), where $A_{ai,bj}=(\epsilon_a-\epsilon_i)\delta_{ij}\delta_{ab}+(ai|f_{Hxc}|bj)+\alpha_{EX}(ab|ij)$ is the particle-hole excitation matrix and $X$ is the transition amplitude.
42324232
- `dav`/`dav_subspace`/ `cg`: Construct $AX$ and diagonalize the Hamiltonian matrix iteratively with Davidson/Non-ortho-Davidson/CG algorithm.
42334233
- `lapack`: Construct the full $A$ matrix and directly diagonalize with LAPACK.
4234+
- `scalapack`: Construct the full $A$ matrix and directly diagonalize with ScaLAPACK (needs MPI).
42344235
- `spectrum`: Calculate absorption spectrum only without solving Casida equation. The `OUT.${suffix}/` directory should contain the
42354236
files for LR-TDDFT eigenstates and eigenvalues, i.e. `Excitation_Energy.dat` and `Excitation_Amplitude_${processor_rank}.dat`
42364237
output by setting `out_wfc_lr` to true.

source/module_lr/esolver_lrtd_lcao.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ inline void setup_2center_table(TwoCenterBundle& two_center_bundle, LCAO_Orbital
8080
template<typename T, typename TR>
8181
void LR::ESolver_LR<T, TR>::parameter_check()const
8282
{
83-
const std::set<std::string> lr_solvers = { "dav", "lapack" , "spectrum", "dav_subspace", "cg" };
83+
const std::set<std::string> lr_solvers = { "dav", "lapack" , "scalapack", "spectrum", "dav_subspace", "cg" };
8484
const std::set<std::string> xc_kernels = { "rpa", "lda", "pwlda", "pbe", "hf" , "hse" };
8585
if (lr_solvers.find(this->input.lr_solver) == lr_solvers.end()) {
8686
throw std::invalid_argument("ESolver_LR: unknown type of lr_solver");

source/module_lr/hsolver_lrtd.hpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
#include "module_lr/utils/lr_util.h"
99
#include "module_lr/utils/lr_util_print.h"
1010
#include "module_base/module_container/ATen/core/tensor_map.h"
11-
11+
#include <chrono>
1212
namespace LR
1313
{
1414
template<typename T> using Real = typename GetTypeReal<T>::type;
15-
15+
using iclock = std::chrono::high_resolution_clock;
1616
namespace HSolver
1717
{
1818
template<typename T>
@@ -54,6 +54,9 @@ namespace LR
5454
std::vector<T> Amat_full = hm.matrix();
5555
const int gdim = std::sqrt(Amat_full.size());
5656
eigenvalue.resize(gdim);
57+
58+
iclock::time_point start_time = iclock::now();
59+
5760
if (hermitian) { LR_Util::diag_lapack(gdim, Amat_full.data(), eigenvalue.data()); }
5861
else
5962
{
@@ -64,7 +67,39 @@ namespace LR
6467
}
6568
// copy eigenvectors
6669
hm.global2local(psi, Amat_full.data(), nband);
70+
71+
iclock::time_point end_time = iclock::now();
72+
std::chrono::duration<double> elapsed_time
73+
= std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time);
74+
std::cout << " Time elapsed diagonalizing A matrix: " << elapsed_time.count() << std::endl;
75+
76+
}
77+
#ifdef __MPI
78+
else if (method == "scalapack")
79+
{
80+
std::vector<T> Amat_full = hm.matrix();
81+
const int gdim = std::sqrt(Amat_full.size());
82+
eigenvalue.resize(gdim);
83+
Parallel_2D para_cvk;
84+
LR_Util::setup_2d_division(para_cvk, 1, gdim, gdim);
85+
std::vector<T> Amat_local(para_cvk.get_local_size());
86+
LR_Util::set_local_from_global(para_cvk, Amat_full.data(), Amat_local.data());
87+
std::vector<T> eigvec_local_paracvk(para_cvk.get_local_size());
88+
89+
iclock::time_point start_time = iclock::now();
90+
91+
LR_Util::diag_scalapack(gdim, Amat_local.data(), eigenvalue.data(), eigvec_local_paracvk.data(), para_cvk.desc);
92+
// copy eigenvectors
93+
LR_Util::gather_2d_to_full(para_cvk, eigvec_local_paracvk.data(), Amat_full.data(), false, gdim, gdim);
94+
hm.global2local(psi, Amat_full.data(), nband);
95+
96+
iclock::time_point end_time = iclock::now();
97+
std::chrono::duration<double> elapsed_time
98+
= std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time);
99+
std::cout << " Time elapsed diagonalizing A matrix: " << elapsed_time.count() << std::endl;
100+
67101
}
102+
#endif
68103
else
69104
{
70105
// 3. set maxiter and funcs
@@ -156,6 +191,9 @@ namespace LR
156191
cg.diag(hpsi_func, spsi_func, psi_tensor, eigen_tensor, ethr_band, precon_tensor);
157192
}
158193
else { throw std::runtime_error("HSolverLR::solve: method not implemented"); }
194+
// output iters
195+
std::cout << "Average iterative diagonalization steps: " << hsolver::DiagoIterAssist<T>::avg_iter
196+
<< " ; where current threshold is: " << hsolver::DiagoIterAssist<T>::PW_DIAG_THR << " . " << std::endl;
159197
}
160198

161199
// 5. copy eigenvalues
@@ -180,10 +218,6 @@ namespace LR
180218
// }
181219
// std::cout << "state " << ist << ", norm2=" << norm2 << std::endl;
182220
// }
183-
184-
// output iters
185-
std::cout << "Average iterative diagonalization steps: " << hsolver::DiagoIterAssist<T>::avg_iter
186-
<< " ; where current threshold is: " << hsolver::DiagoIterAssist<T>::PW_DIAG_THR << " . " << std::endl;
187221
}
188222
}
189223
}

0 commit comments

Comments
 (0)