Skip to content

Commit ff23741

Browse files
authored
Feature: Support native binary output for out_hsk (deepmodeling#7778)
* feat: support native binary out_hsk output * docs: synchronize generated out_hsk parameter docs
1 parent 1ed4802 commit ff23741

18 files changed

Lines changed: 418 additions & 25 deletions

File tree

docs/advanced/elec_properties/hs_matrix.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Use [out_hsk](../input_files/input-main.md#out_hsk) to print the upper triangula
1818
| --- | --- |
1919
| `0` | Disabled |
2020
| `1` | Text; an optional second value controls precision, for example `out_hsk 1 12` |
21-
| `2` | Reserved for future binary output; not implemented |
21+
| `2` | Native binary `.dat` output |
2222
| `3` | Reserved for H(k)/S(k) NPZ output; not implemented |
2323

2424
The legacy keyword `out_mat_hs 1 [precision]` remains supported as an alias for `out_hsk 1 [precision]`. If both names are present, `out_hsk` takes precedence.
@@ -45,6 +45,18 @@ Each output block starts with a comment header containing the one-based ionic-st
4545

4646
For multi-k calculations, the matrices are Hermitian and each matrix element is written as `(real,imag)`. For gamma-only calculations, the matrices are symmetric and the matrix elements are written as real numbers.
4747

48+
### Native Binary Format
49+
50+
For `out_hsk 2`, the filenames in the table above use `.dat` instead of `.txt`. Each matrix record is written without padding or a self-describing header:
51+
52+
1. the matrix dimension as a native C++ `int`;
53+
2. the upper-triangular elements in row-major order, from `(0,0)` through `(0,N-1)`, then `(1,1)` through `(1,N-1)`, and so on;
54+
3. each gamma-only element as one native `double`, or each multi-k/spinor element as two consecutive native `double` values containing the real and imaginary parts.
55+
56+
The file therefore contains `sizeof(int) + N(N+1)/2 * sizeof(double)` bytes for a gamma-only record and `sizeof(int) + N(N+1) * sizeof(double)` bytes for a multi-k or spinor record. The format uses the host integer representation and byte order and is intended for readers using a compatible ABI.
57+
58+
When `out_app_flag` is true, the first ionic step truncates the shared file and every later step appends another complete record. When it is false, each ionic step has a separate filename containing `g${step}` before `_nao`.
59+
4860
## out_hsr
4961

5062
The output of $H(R)$ and $S(R)$ matrices is controlled by [out_hsr](../input_files/input-main.md#out_hsr). It is available for both gamma-only and multi-k LCAO calculations:

docs/advanced/input_files/input-main.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2003,7 +2003,7 @@
20032003
- **Description**: Output the upper triangular part of the Hamiltonian and overlap matrices in reciprocal space for each k-point into files in the directory OUT.${suffix}. The first integer selects the format:
20042004
- 0: disabled;
20052005
- 1: text output; the optional second integer controls precision and defaults to 8;
2006-
- 2: reserved for binary output, which is not implemented yet;
2006+
- 2: binary output in the native ABACUS .dat format;
20072007
- 3: NPZ output, which is not implemented for H(k)/S(k).
20082008

20092009
The output is also controlled by out_freq_ion and out_app_flag. For more information, refer to hs_matrix.md.
@@ -2014,6 +2014,8 @@
20142014
- Multi-k, nspin = 1: hk1_nao.txt for the Hamiltonian matrix and sk1_nao.txt for the overlap matrix at the first k-point.
20152015
- Multi-k, nspin = 2: hk1s1_nao.txt and hk1s2_nao.txt for the two spin channels of the Hamiltonian matrix, and sk1_nao.txt for the overlap matrix at the first k-point. Only one overlap matrix is written because it is identical for both spin channels.
20162016
- Multi-k, nspin = 4: hk1s4_nao.txt for the spinor Hamiltonian matrix and sk1_nao.txt for the spinor overlap matrix at the first k-point.
2017+
For binary output, the same names use the .dat suffix. Each native binary record contains the matrix dimension as an int followed by the row-major upper triangle. Gamma-only elements are doubles; multi-k and spinor elements are pairs of doubles containing the real and imaginary parts. Native integer representation and byte order are used.
2018+
When out_app_flag is true, the first ionic step truncates the file and later steps append complete records.
20172019
When out_app_flag is false, g followed by the one-based ionic-step index is inserted before _nao, for example hk1s1g1_nao.txt.
20182020

20192021
> Note: In the 3.10-LTS version, the file names are data-0-H and data-0-S, etc.

docs/parameters.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3112,7 +3112,7 @@ parameters:
31123112
Output the upper triangular part of the Hamiltonian and overlap matrices in reciprocal space for each k-point into files in the directory OUT.${suffix}. The first integer selects the format:
31133113
* 0: disabled;
31143114
* 1: text output; the optional second integer controls precision and defaults to 8;
3115-
* 2: reserved for binary output, which is not implemented yet;
3115+
* 2: binary output in the native ABACUS .dat format;
31163116
* 3: NPZ output, which is not implemented for H(k)/S(k).
31173117
31183118
The output is also controlled by out_freq_ion and out_app_flag. For more information, refer to hs_matrix.md.
@@ -3122,6 +3122,8 @@ parameters:
31223122
* Multi-k, nspin = 1: hk1_nao.txt for the Hamiltonian matrix and sk1_nao.txt for the overlap matrix at the first k-point.
31233123
* Multi-k, nspin = 2: hk1s1_nao.txt and hk1s2_nao.txt for the two spin channels of the Hamiltonian matrix, and sk1_nao.txt for the overlap matrix at the first k-point. Only one overlap matrix is written because it is identical for both spin channels.
31243124
* Multi-k, nspin = 4: hk1s4_nao.txt for the spinor Hamiltonian matrix and sk1_nao.txt for the spinor overlap matrix at the first k-point.
3125+
For binary output, the same names use the .dat suffix. Each native binary record contains the matrix dimension as an int followed by the row-major upper triangle. Gamma-only elements are doubles; multi-k and spinor elements are pairs of doubles containing the real and imaginary parts. Native integer representation and byte order are used.
3126+
When out_app_flag is true, the first ionic step truncates the file and later steps append complete records.
31253127
When out_app_flag is false, g followed by the one-based ionic-step index is inserted before _nao, for example hk1s1g1_nao.txt.
31263128
31273129
[NOTE] In the 3.10-LTS version, the file names are data-0-H and data-0-S, etc.

source/source_io/module_ctrl/ctrl_scf_lcao.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell,
199199
//------------------------------------------------------------------
200200
// 4) Output H(k) and S(k) matrices for each k-point
201201
//------------------------------------------------------------------
202-
if (inp.out_hsk[0] == 1)
202+
const int hsk_out_type = inp.out_hsk[0];
203+
if (hsk_out_type == 1 || hsk_out_type == 2)
203204
{
204205
const int precision = inp.out_hsk[1];
205206
ModuleIO::write_hsk(global_out_dir,
@@ -213,6 +214,7 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell,
213214
gamma_only,
214215
out_app_flag,
215216
istep,
217+
hsk_out_type,
216218
precision,
217219
GlobalV::ofs_running);
218220
}

source/source_io/module_hs/write_HS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace ModuleIO
2626
const bool gamma_only,
2727
const bool out_app_flag,
2828
const int istep,
29+
const int out_type,
2930
const int precision,
3031
std::ofstream &ofs_running);
3132

source/source_io/module_hs/write_HS.hpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ void ModuleIO::write_hsk(
2121
const bool gamma_only,
2222
const bool out_app_flag,
2323
const int istep,
24+
const int out_type,
2425
const int precision,
2526
std::ofstream &ofs_running)
2627
{
@@ -40,25 +41,21 @@ void ModuleIO::write_hsk(
4041
for (int ik = 0; ik < nks; ++ik)
4142
{
4243
p_hamilt->updateHk(ik);
43-
bool bit = false; // LiuXh, 2017-03-21
44-
// if set bit = true, there would be error in soc-multi-core
45-
// calculation, noted by zhengdy-soc
44+
const bool binary = (out_type == 2);
4645

4746
hamilt::MatrixBlock<T> h_mat;
4847
hamilt::MatrixBlock<T> s_mat;
4948

5049
p_hamilt->matrix(h_mat, s_mat);
5150

52-
const int out_label=1; // 1: .txt, 2: .dat
53-
5451
std::string h_fn = ModuleIO::filename_output(global_out_dir,
5552
"hk","nao",ik,ik2iktot,nspin,nkstot,
56-
out_label,out_app_flag,gamma_only,istep);
53+
out_type,out_app_flag,gamma_only,istep);
5754

5855
ModuleIO::save_mat(istep,
5956
h_mat.p,
6057
PARAM.globalv.nlocal,
61-
bit,
58+
binary,
6259
precision,
6360
1,
6461
out_app_flag,
@@ -77,14 +74,14 @@ void ModuleIO::write_hsk(
7774

7875
std::string s_fn = ModuleIO::filename_output(global_out_dir,
7976
"sk","nao",ik,ik2iktot,nspin,nkstot,
80-
out_label,out_app_flag,gamma_only,istep);
77+
out_type,out_app_flag,gamma_only,istep);
8178

8279
ofs_running << " The output filename is " << s_fn << std::endl;
8380

8481
ModuleIO::save_mat(istep,
8582
s_mat.p,
8683
PARAM.globalv.nlocal,
87-
bit,
84+
binary,
8885
precision,
8986
1,
9087
out_app_flag,
@@ -123,7 +120,8 @@ void ModuleIO::save_mat(const int istep,
123120

124121
if (drank == 0)
125122
{
126-
out_matrix = fopen(filename.c_str(), "wb");
123+
const char* mode = (app && istep > 0) ? "ab" : "wb";
124+
out_matrix = fopen(filename.c_str(), mode);
127125
if (out_matrix == nullptr)
128126
{
129127
ModuleBase::WARNING_QUIT("ModuleIO::save_mat", "Cannot open matrix file: " + filename);
@@ -184,7 +182,8 @@ void ModuleIO::save_mat(const int istep,
184182
}
185183
// write .dat file without MPI
186184
#else
187-
FILE* out_matrix = fopen(filename.c_str(), "wb");
185+
const char* mode = (app && istep > 0) ? "ab" : "wb";
186+
FILE* out_matrix = fopen(filename.c_str(), mode);
188187
if (out_matrix == nullptr)
189188
{
190189
ModuleBase::WARNING_QUIT("ModuleIO::save_mat", "Cannot open matrix file: " + filename);

source/source_io/module_parameter/read_input_item_output.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ Also controled by out_freq_ion and out_app_flag.
534534
item.description = R"(Output the upper triangular part of the Hamiltonian and overlap matrices in reciprocal space for each k-point into files in the directory OUT.${suffix}. The first integer selects the format:
535535
* 0: disabled;
536536
* 1: text output; the optional second integer controls precision and defaults to 8;
537-
* 2: reserved for binary output, which is not implemented yet;
537+
* 2: binary output in the native ABACUS .dat format;
538538
* 3: NPZ output, which is not implemented for H(k)/S(k).
539539
540540
The output is also controlled by out_freq_ion and out_app_flag. For more information, refer to hs_matrix.md.
@@ -544,6 +544,8 @@ The output is also controlled by out_freq_ion and out_app_flag. For more informa
544544
* Multi-k, nspin = 1: hk1_nao.txt for the Hamiltonian matrix and sk1_nao.txt for the overlap matrix at the first k-point.
545545
* Multi-k, nspin = 2: hk1s1_nao.txt and hk1s2_nao.txt for the two spin channels of the Hamiltonian matrix, and sk1_nao.txt for the overlap matrix at the first k-point. Only one overlap matrix is written because it is identical for both spin channels.
546546
* Multi-k, nspin = 4: hk1s4_nao.txt for the spinor Hamiltonian matrix and sk1_nao.txt for the spinor overlap matrix at the first k-point.
547+
For binary output, the same names use the .dat suffix. Each native binary record contains the matrix dimension as an int followed by the row-major upper triangle. Gamma-only elements are doubles; multi-k and spinor elements are pairs of doubles containing the real and imaginary parts. Native integer representation and byte order are used.
548+
When out_app_flag is true, the first ionic step truncates the file and later steps append complete records.
547549
When out_app_flag is false, g followed by the one-based ionic-step index is inserted before _nao, for example hk1s1g1_nao.txt.
548550
549551
[NOTE] In the 3.10-LTS version, the file names are data-0-H and data-0-S, etc.)";
@@ -576,10 +578,6 @@ When out_app_flag is false, g followed by the one-based ionic-step index is inse
576578
{
577579
ModuleBase::WARNING_QUIT("ReadInput", "out_hsk format must be 0, 1, 2, or 3");
578580
}
579-
if (format == 2)
580-
{
581-
ModuleBase::WARNING_QUIT("ReadInput", "out_hsk binary output is reserved but not implemented");
582-
}
583581
if (format == 3)
584582
{
585583
ModuleBase::WARNING_QUIT("ReadInput", "out_hsk NPZ output is not implemented");

source/source_io/test/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ AddTest(
5353
SOURCES binstream_test.cpp ../module_output/binstream.cpp
5454
)
5555

56+
AddTest(
57+
TARGET MODULE_IO_write_hsk_binary_test
58+
LIBS parameter base device
59+
SOURCES write_hsk_binary_test.cpp ../../source_basis/module_ao/parallel_orbitals.cpp
60+
)
61+
62+
add_test(
63+
NAME MODULE_IO_write_hsk_binary_test_parallel
64+
COMMAND mpirun -np 2 ./MODULE_IO_write_hsk_binary_test
65+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
66+
)
67+
5668
AddTest(
5769
TARGET MODULE_IO_write_eig_occ_test
5870
LIBS parameter base device symmetry

0 commit comments

Comments
 (0)