Skip to content

Commit f049059

Browse files
ErjieWumohanchen
andauthored
Feature&Doc&Tests: Support for deepks_v_delta=-1&-2 (#6245)
* Move DeePKS printing message from screen to log file. * Add support for DeePKS Real space Hamiltonian. * Fix a merge bug. * Add DeePKS V_delta_R support in doc&value_check. * Add integrate test for deepks_v_delta<0. * Remove redundant code. * Fix the bug that DeePKS integrate test output 0/1 file. * Add UT for DeePKS H(R). * clang-format change. --------- Co-authored-by: Mohan Chen <[email protected]>
1 parent 867adf7 commit f049059

File tree

44 files changed

+1205
-107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1205
-107
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ Warning: this function is not robust enough for the current version. Please try
21452145
- **Description**: Print labels and descriptors for DeePKS in OUT.${suffix}. The names of these files start with "deepks".
21462146
- 0 : No output.
21472147
- 1 : Output intermediate files needed during DeePKS training.
2148-
- 2 : Output target labels for label preperation. The label files are named as `deepks_<property>.npy`, where the units and formats are the same as label files `<property>.npy` required for training, except that the first dimension (`nframes`) is excluded. System structrue files are also given in `deepks_atom.npy` and `deepks_box.npy` in the unit of *Bohr*, which means `lattice_constant` should be set to 1 when training.
2148+
- 2 : Output target labels for label preperation. The label files are named as `deepks_<property>.npy` or `deepks_<property>.csr`, where the units and formats are the same as label files `<property>.npy` or `<property>.csr` required for training, except that the first dimension (`nframes`) is excluded. System structrue files are also given in `deepks_atom.npy` and `deepks_box.npy` in the unit of *Bohr*, which means `lattice_constant` should be set to 1 when training.
21492149
- **Note**: When `deepks_out_labels` equals **1**, the path of a numerical descriptor (an `orb` file) is needed to be specified under the `NUMERICAL_DESCRIPTOR` tag in the `STRU` file. For example:
21502150

21512151
```text
@@ -2252,8 +2252,11 @@ Warning: this function is not robust enough for the current version. Please try
22522252

22532253
- **Type**: int
22542254
- **Availability**: numerical atomic orbital basis
2255-
- **Description**: Include V_delta label for DeePKS training. When `deepks_out_labels` is true and `deepks_v_delta` > 0, ABACUS will output h_base.npy, v_delta.npy and h_tot.npy(h_tot=h_base+v_delta).
2256-
Meanwhile, when `deepks_v_delta` equals 1, ABACUS will also output v_delta_precalc.npy, which is used to calculate V_delta during DeePKS training. However, when the number of atoms grows, the size of v_delta_precalc.npy will be very large. In this case, it's recommended to set `deepks_v_delta` as 2, and ABACUS will output phialpha.npy and grad_evdm.npy but not v_delta_precalc.npy. These two files are small and can be used to calculate v_delta_precalc in the procedure of training DeePKS.
2255+
- **Description**: Include V_delta/V_delta_R (Hamiltonian in k/real space) label for DeePKS training. When `deepks_out_labels` is true and `deepks_v_delta` > 0 (k space), ABACUS will output `deepks_hbase.npy`, `deepks_vdelta.npy` and `deepks_htot.npy`(htot=hbase+vdelta). When `deepks_out_labels` is true and `deepks_v_delta` < 0 (real space), ABACUS will output `deepks_hrtot.csr`, `deepks_hrdelta.csr`. Some more files output for different settings.
2256+
- `deepks_v_delta` = 1: `deepks_vdpre.npy`, which is used to calculate V_delta during DeePKS training.
2257+
- `deepks_v_delta` = 2: `deepks_phialpha.npy` and `deepks_gevdm.npy`, which can be used to calculate `deepks_vdpre.npy`. A recommanded method for memory saving.
2258+
- `deepks_v_delta` = -1: `deepks_vdrpre.npy`, which is used to calculate V_delta_R during DeePKS training.
2259+
- `deepks_v_delta` = -2: `deepks_phialpha_r.npy` and `deepks_gevdm.npy`, which can be used to calculate `deepks_vdrpre.npy`. A recommanded method for memory saving.
22572260
- **Default**: 0
22582261

22592262
### deepks_out_unittest

source/module_hamilt_lcao/module_deepks/LCAO_deepks_interface.cpp

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
#include "LCAO_deepks_interface.h"
33

44
#include "LCAO_deepks_io.h" // mohan add 2024-07-22
5-
#include "source_base/global_variable.h"
6-
#include "source_base/tool_title.h"
75
#include "module_elecstate/cal_dm.h"
86
#include "module_hamilt_lcao/module_hcontainer/hcontainer.h"
97
#include "module_hamilt_lcao/module_hcontainer/output_hcontainer.h"
108
#include "module_parameter/parameter.h"
9+
#include "source_base/global_variable.h"
10+
#include "source_base/tool_title.h"
1111

1212
template <typename TK, typename TR>
1313
LCAO_Deepks_Interface<TK, TR>::LCAO_Deepks_Interface(std::shared_ptr<LCAO_Deepks<TK>> ld_in) : ld(ld_in)
@@ -353,14 +353,15 @@ void LCAO_Deepks_Interface<TK, TR>::out_deepks_labels(const double& etot,
353353
} // end deepks_out_labels == 1
354354
}
355355

356-
// not add deepks_out_labels = 2 for HR yet
357356
// H(R) matrix part, for HR, base will not be calculated since they are HContainer objects
358357
if (PARAM.inp.deepks_v_delta < 0)
359358
{
360359
// set the output
361360
const double sparse_threshold = 1e-10;
362361
const int precision = 8;
363-
const std::string file_hrtot = PARAM.globalv.global_out_dir + "deepks_hrtot.csr";
362+
const std::string file_hrtot
363+
= PARAM.globalv.global_out_dir
364+
+ (PARAM.inp.deepks_out_labels == 1 ? "deepks_hrtot.csr" : "deepks_hamiltonian_r.csr");
364365
hamilt::HContainer<TR>* hR_tot = (p_ham->getHR());
365366

366367
if (rank == 0)
@@ -369,47 +370,75 @@ void LCAO_Deepks_Interface<TK, TR>::out_deepks_labels(const double& etot,
369370
ofs_hr << "Matrix Dimension of H(R): " << hR_tot->get_nbasis() << std::endl;
370371
ofs_hr << "Matrix number of H(R): " << hR_tot->size_R_loop() << std::endl;
371372
hamilt::Output_HContainer<TR> out_hr(hR_tot, ofs_hr, sparse_threshold, precision);
372-
out_hr.write();
373+
out_hr.write(true); // write all the matrices, including empty ones
373374
ofs_hr.close();
374375
}
375376

376377
if (PARAM.inp.deepks_scf)
377378
{
378-
const std::string file_vdeltar = PARAM.globalv.global_out_dir + "deepks_hrdelta.csr";
379-
hamilt::HContainer<TR>* h_deltaR = p_ham->get_V_delta_R();
380-
381-
if (rank == 0)
379+
if (PARAM.inp.deepks_out_labels == 1)
382380
{
383-
std::ofstream ofs_hr(file_vdeltar, std::ios::out);
384-
ofs_hr << "Matrix Dimension of H_delta(R): " << h_deltaR->get_nbasis() << std::endl;
385-
ofs_hr << "Matrix number of H_delta(R): " << h_deltaR->size_R_loop() << std::endl;
386-
hamilt::Output_HContainer<TR> out_hr(h_deltaR, ofs_hr, sparse_threshold, precision);
387-
out_hr.write();
388-
ofs_hr.close();
389-
}
381+
const std::string file_vdeltar = PARAM.globalv.global_out_dir + "deepks_hrdelta.csr";
382+
hamilt::HContainer<TR>* h_deltaR = p_ham->get_V_delta_R();
390383

391-
torch::Tensor phialpha_r_out;
392-
torch::Tensor R_query;
393-
DeePKS_domain::prepare_phialpha_r(nlocal,
394-
lmaxd,
395-
inlmax,
396-
nat,
397-
phialpha,
398-
ucell,
399-
orb,
400-
*ParaV,
401-
GridD,
402-
phialpha_r_out,
403-
R_query);
404-
const std::string file_phialpha_r = PARAM.globalv.global_out_dir + "deepks_phialpha_r.npy";
405-
const std::string file_R_query = PARAM.globalv.global_out_dir + "deepks_R_query.npy";
406-
LCAO_deepks_io::save_tensor2npy<double>(file_phialpha_r, phialpha_r_out, rank);
407-
LCAO_deepks_io::save_tensor2npy<int>(file_R_query, R_query, rank);
408-
409-
torch::Tensor gevdm_out;
410-
DeePKS_domain::prepare_gevdm(nat, lmaxd, inlmax, orb, gevdm, gevdm_out);
411-
const std::string file_gevdm = PARAM.globalv.global_out_dir + "deepks_gevdm.npy";
412-
LCAO_deepks_io::save_tensor2npy<double>(file_gevdm, gevdm_out, rank);
384+
if (rank == 0)
385+
{
386+
std::ofstream ofs_hr(file_vdeltar, std::ios::out);
387+
ofs_hr << "Matrix Dimension of H_delta(R): " << h_deltaR->get_nbasis() << std::endl;
388+
ofs_hr << "Matrix number of H_delta(R): " << h_deltaR->size_R_loop() << std::endl;
389+
hamilt::Output_HContainer<TR> out_hr(h_deltaR, ofs_hr, sparse_threshold, precision);
390+
out_hr.write(true); // write all the matrices, including empty ones
391+
ofs_hr.close();
392+
}
393+
394+
if (PARAM.inp.deepks_v_delta == -1)
395+
{
396+
int R_size = DeePKS_domain::get_R_size(*h_deltaR);
397+
torch::Tensor vdr_precalc;
398+
DeePKS_domain::cal_vdr_precalc(nlocal,
399+
lmaxd,
400+
inlmax,
401+
nat,
402+
nks,
403+
R_size,
404+
inl2l,
405+
kvec_d,
406+
phialpha,
407+
gevdm,
408+
inl_index,
409+
ucell,
410+
orb,
411+
*ParaV,
412+
GridD,
413+
vdr_precalc);
414+
415+
const std::string file_vdrpre = PARAM.globalv.global_out_dir + "deepks_vdrpre.npy";
416+
LCAO_deepks_io::save_tensor2npy<double>(file_vdrpre, vdr_precalc, rank);
417+
}
418+
else if (PARAM.inp.deepks_v_delta == -2)
419+
{
420+
int R_size = DeePKS_domain::get_R_size(*h_deltaR);
421+
torch::Tensor phialpha_r_out;
422+
DeePKS_domain::prepare_phialpha_r(nlocal,
423+
lmaxd,
424+
inlmax,
425+
nat,
426+
R_size,
427+
phialpha,
428+
ucell,
429+
orb,
430+
*ParaV,
431+
GridD,
432+
phialpha_r_out);
433+
const std::string file_phialpha_r = PARAM.globalv.global_out_dir + "deepks_phialpha_r.npy";
434+
LCAO_deepks_io::save_tensor2npy<double>(file_phialpha_r, phialpha_r_out, rank);
435+
436+
torch::Tensor gevdm_out;
437+
DeePKS_domain::prepare_gevdm(nat, lmaxd, inlmax, orb, gevdm, gevdm_out);
438+
const std::string file_gevdm = PARAM.globalv.global_out_dir + "deepks_gevdm.npy";
439+
LCAO_deepks_io::save_tensor2npy<double>(file_gevdm, gevdm_out, rank);
440+
}
441+
}
413442
}
414443
}
415444

@@ -544,7 +573,7 @@ void LCAO_Deepks_Interface<TK, TR>::out_deepks_labels(const double& etot,
544573
<< " = " << std::setprecision(8) << e_delta_band * ModuleBase::Ry_to_eV << " eV" << std::endl;
545574
ofs_running << " E_delta_NN = " << std::setprecision(8) << E_delta << " Ry"
546575
<< " = " << std::setprecision(8) << E_delta * ModuleBase::Ry_to_eV << " eV" << std::endl;
547-
ofs_running << " -----------------------------------------------" << std::endl;
576+
ofs_running << " -----------------------------------------------" << std::endl;
548577
}
549578
if (PARAM.inp.deepks_out_unittest)
550579
{

source/module_hamilt_lcao/module_deepks/LCAO_deepks_interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
#ifdef __MLALGO
55
#include "LCAO_deepks.h"
6+
#include "module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h"
67
#include "source_base/complexmatrix.h"
78
#include "source_base/matrix.h"
8-
#include "module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h"
99

1010
#include <memory>
1111

source/module_hamilt_lcao/module_deepks/deepks_check.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ void DeePKS_domain::check_tensor(const torch::Tensor& tensor, const std::string&
99
{
1010
return;
1111
}
12-
using T_tensor = typename std::conditional<std::is_same<T, std::complex<double>>::value, c10::complex<double>, T>::type;
12+
using T_tensor =
13+
typename std::conditional<std::is_same<T, std::complex<double>>::value, c10::complex<double>, T>::type;
1314

1415
std::ofstream ofs(filename.c_str());
1516
ofs << std::setprecision(10);
@@ -21,15 +22,18 @@ void DeePKS_domain::check_tensor(const torch::Tensor& tensor, const std::string&
2122

2223
// stride for each dimension
2324
std::vector<int64_t> strides(ndim, 1);
24-
for (int i = ndim - 2; i >= 0; --i) {
25+
for (int i = ndim - 2; i >= 0; --i)
26+
{
2527
strides[i] = strides[i + 1] * sizes[i + 1];
2628
}
2729

28-
for (int64_t idx = 0; idx < numel; ++idx) {
30+
for (int64_t idx = 0; idx < numel; ++idx)
31+
{
2932
// index to multi-dimensional indices
3033
std::vector<int64_t> indices(ndim);
3134
int64_t tmp = idx;
32-
for (int d = 0; d < ndim; ++d) {
35+
for (int d = 0; d < ndim; ++d)
36+
{
3337
indices[d] = tmp / strides[d];
3438
tmp = tmp % strides[d];
3539
}
@@ -39,16 +43,21 @@ void DeePKS_domain::check_tensor(const torch::Tensor& tensor, const std::string&
3943
ofs << *tmp_ptr;
4044

4145
// print space or newline
42-
if ( ( (idx+1) % sizes[ndim-1] ) == 0 ) {
46+
if (((idx + 1) % sizes[ndim - 1]) == 0)
47+
{
4348
ofs << std::endl;
44-
} else {
49+
}
50+
else
51+
{
4552
ofs << " ";
4653
}
4754
}
4855

4956
ofs.close();
5057
}
5158

59+
60+
5261
template void DeePKS_domain::check_tensor<int>(const torch::Tensor& tensor, const std::string& filename, const int rank);
5362
template void DeePKS_domain::check_tensor<double>(const torch::Tensor& tensor, const std::string& filename, const int rank);
5463
template void DeePKS_domain::check_tensor<std::complex<double>>(const torch::Tensor& tensor, const std::string& filename, const int rank);

0 commit comments

Comments
 (0)