Skip to content

Commit b2e3a37

Browse files
authored
Refactor(io): modularize sparse matrix writer interface (deepmodeling#7468)
* Test(io): freeze write_HS_R compatibility behavior Add a Phase 0 compatibility test suite for write_HS_R-related output contracts and save the refactor plan. Tests: ctest --test-dir build-phase0 -R MODULE_IO_write_hs_r_compat_test -V * Fix(io): address module_hs phase 1 issues Fix sparse binary header writing, non-MPI save_mat stream opening, Vxc(R) ownership, and AngularMomentumCalculator null logging. Extend write_HS_R compatibility coverage for legacy binary sparse headers and update the refactor plan with Phase 1 status. Tests: ctest --test-dir build-phase0 -R MODULE_IO_write_hs_r_compat_test -V Tests: ctest --test-dir build-phase0 -R MODULE_IO_cal_pLpR_test -V Tests: ctest --test-dir build-phase0 -R MODULE_IO_single_R_test -V Tests: ctest --test-dir build-phase0 -R MODULE_IO_sparse_matrix_test -V Builds: cmake --build build-phase0 --target io_advanced -j8 Builds: cmake -B build-phase1-nompi -DBUILD_TESTING=OFF -DENABLE_MPI=OFF && cmake --build build-phase1-nompi --target io_advanced -j8 * Docs: remove write_HS_R refactor plan from repository Keep the local markdown file untracked while removing it from the remote branch contents. * Fix(io): pass sparse matrix dimension explicitly * Fix(io): derive sparse matrix dimension from pv * Revert "Fix(io): derive sparse matrix dimension from pv" This reverts commit fa0347e. * Revert "Fix(io): pass sparse matrix dimension explicitly" This reverts commit 644fdd9. * Refactor(io): modularize sparse matrix writer interface
1 parent d4efc84 commit b2e3a37

14 files changed

Lines changed: 707 additions & 250 deletions

source/source_io/module_hs/cal_pLpR.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,13 @@ ModuleIO::AngularMomentumCalculator::AngularMomentumCalculator(
180180
const int rank)
181181
{
182182

183-
// ofs_running
184183
this->ofs_ = ptr_log;
184+
if (this->ofs_ == nullptr)
185+
{
186+
this->fallback_ofs_.open("/dev/null");
187+
this->ofs_ = &this->fallback_ofs_;
188+
}
189+
185190
*ofs_ << "\n\n\n\n";
186191
*ofs_ << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
187192
*ofs_ << " | |" << std::endl;
@@ -259,7 +264,7 @@ void ModuleIO::AngularMomentumCalculator::kernel(
259264
const char dir,
260265
const int precision)
261266
{
262-
if (!ofs->is_open())
267+
if (ofs == nullptr || !ofs->is_open())
263268
{
264269
return;
265270
}
@@ -381,4 +386,4 @@ void ModuleIO::AngularMomentumCalculator::calculate(
381386
this->kernel(&ofout, ucell, d, precision);
382387
ofout.close();
383388
}
384-
}
389+
}

source/source_io/module_hs/cal_pLpR.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include <map>
8989
#include <tuple>
9090
#include <complex>
91+
#include <fstream>
9192
#include <memory>
9293
#include "source_cell/unitcell.h"
9394
#include "source_basis/module_nao/two_center_integrator.h"
@@ -218,8 +219,9 @@ namespace ModuleIO
218219
const int rank = 0);
219220

220221
private:
222+
std::ofstream fallback_ofs_;
221223
// ofsrunning
222-
std::ofstream* ofs_;
224+
std::ofstream* ofs_ = nullptr;
223225
// the two-center-integrator
224226
std::unique_ptr<TwoCenterIntegrator> calculator_;
225227
// the spherical bessel transformer
@@ -246,4 +248,4 @@ namespace ModuleIO
246248
const char dir = 'x',
247249
const int precision = 10);
248250
};
249-
} // namespace ModuleIO
251+
} // namespace ModuleIO

source/source_io/module_hs/cal_r_overlap_R.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,11 @@ void cal_r_overlap_R::out_rR(const UnitCell& ucell, const Grid_Driver& gd, const
628628
ModuleBase::Vector3<double> origin_point(0.0, 0.0, 0.0);
629629
double factor = sqrt(ModuleBase::FOUR_PI / 3.0);
630630
int output_R_number = 0;
631+
ModuleIO::SparseWriteOptions single_R_options;
632+
single_R_options.threshold = sparse_threshold;
633+
single_R_options.binary = binary;
634+
single_R_options.reduce = true;
635+
single_R_options.temp_dir = PARAM.globalv.global_out_dir;
631636

632637
std::stringstream tem1;
633638
tem1 << PARAM.globalv.global_out_dir << "tmp-rr.csr";
@@ -789,9 +794,8 @@ void cal_r_overlap_R::out_rR(const UnitCell& ucell, const Grid_Driver& gd, const
789794
{
790795
ModuleIO::output_single_R(ofs_tem1,
791796
psi_r_psi_sparse[direction],
792-
sparse_threshold,
793-
binary,
794-
*(this->ParaV));
797+
*(this->ParaV),
798+
single_R_options);
795799
}
796800
else
797801
{
@@ -875,6 +879,11 @@ void cal_r_overlap_R::out_rR_other(const UnitCell& ucell, const int& istep, cons
875879
double factor = sqrt(ModuleBase::FOUR_PI / 3.0);
876880
int output_R_number = output_R_coor.size();
877881
int step = istep;
882+
ModuleIO::SparseWriteOptions single_R_options;
883+
single_R_options.threshold = sparse_threshold;
884+
single_R_options.binary = binary;
885+
single_R_options.reduce = true;
886+
single_R_options.temp_dir = PARAM.globalv.global_out_dir;
878887

879888
std::ofstream out_r;
880889
std::stringstream ssr;
@@ -1059,7 +1068,10 @@ void cal_r_overlap_R::out_rR_other(const UnitCell& ucell, const int& istep, cons
10591068

10601069
if (rR_nonzero_num[direction])
10611070
{
1062-
ModuleIO::output_single_R(out_r, psi_r_psi_sparse[direction], sparse_threshold, binary, *(this->ParaV));
1071+
ModuleIO::output_single_R(out_r,
1072+
psi_r_psi_sparse[direction],
1073+
*(this->ParaV),
1074+
single_R_options);
10631075
}
10641076
else
10651077
{

source/source_io/module_hs/single_R_io.cpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#include "single_R_io.h"
22
#include "source_base/parallel_reduce.h"
3-
#include "source_io/module_parameter/parameter.h"
43
#include "source_base/global_function.h"
54
#include "source_base/global_variable.h"
65

6+
#include <complex>
7+
#include <cstdio>
8+
#include <iomanip>
9+
#include <sstream>
10+
#include <vector>
11+
712
inline void write_data(std::ofstream& ofs, const double& data)
813
{
914
ofs << " " << std::fixed << std::scientific << std::setprecision(16) << data;
@@ -15,25 +20,30 @@ inline void write_data(std::ofstream& ofs, const std::complex<double>& data)
1520

1621
template<typename T>
1722
void ModuleIO::output_single_R(std::ofstream& ofs,
18-
const std::map<size_t, std::map<size_t, T>>& XR,
19-
const double& sparse_threshold,
20-
const bool& binary,
23+
const SparseRBlock<T>& XR,
2124
const Parallel_Orbitals& pv,
22-
const bool& reduce)
25+
const SparseWriteOptions& options)
2326
{
24-
T* line = nullptr;
27+
const int nlocal = pv.get_global_row_size();
28+
if (nlocal <= 0)
29+
{
30+
ModuleBase::WARNING_QUIT("ModuleIO::output_single_R",
31+
"Parallel_Orbitals global row size must be positive.");
32+
}
33+
2534
std::vector<long long> indptr;
26-
indptr.reserve(PARAM.globalv.nlocal + 1);
35+
indptr.reserve(nlocal + 1);
2736
indptr.push_back(0);
2837

2938
std::stringstream tem1;
30-
tem1 << PARAM.globalv.global_out_dir << std::to_string(GlobalV::DRANK) + "temp_sparse_indices.dat";
39+
tem1 << options.temp_dir << std::to_string(GlobalV::DRANK)
40+
<< "temp_sparse_indices.dat";
3141
std::ofstream ofs_tem1;
3242
std::ifstream ifs_tem1;
3343

34-
if (!reduce || GlobalV::DRANK == 0)
44+
if (!options.reduce || GlobalV::DRANK == 0)
3545
{
36-
if (binary)
46+
if (options.binary)
3747
{
3848
ofs_tem1.open(tem1.str().c_str(), std::ios::binary);
3949
}
@@ -43,12 +53,12 @@ void ModuleIO::output_single_R(std::ofstream& ofs,
4353
}
4454
}
4555

46-
line = new T[PARAM.globalv.nlocal];
47-
for(int row = 0; row < PARAM.globalv.nlocal; ++row)
56+
std::vector<T> line(nlocal);
57+
for(int row = 0; row < nlocal; ++row)
4858
{
49-
ModuleBase::GlobalFunc::ZEROS(line, PARAM.globalv.nlocal);
59+
ModuleBase::GlobalFunc::ZEROS(line.data(), nlocal);
5060

51-
if (!reduce || pv.global2local_row(row) >= 0)
61+
if (!options.reduce || pv.global2local_row(row) >= 0)
5262
{
5363
auto iter = XR.find(row);
5464
if (iter != XR.end())
@@ -60,19 +70,19 @@ void ModuleIO::output_single_R(std::ofstream& ofs,
6070
}
6171
}
6272

63-
if (reduce)
64-
{
65-
Parallel_Reduce::reduce_all(line, PARAM.globalv.nlocal);
66-
}
73+
if (options.reduce)
74+
{
75+
Parallel_Reduce::reduce_all(line.data(), nlocal);
76+
}
6777

68-
if (!reduce || GlobalV::DRANK == 0)
78+
if (!options.reduce || GlobalV::DRANK == 0)
6979
{
7080
long long nonzeros_count = 0;
71-
for (int col = 0; col < PARAM.globalv.nlocal; ++col)
81+
for (int col = 0; col < nlocal; ++col)
7282
{
73-
if (std::abs(line[col]) > sparse_threshold)
83+
if (std::abs(line[col]) > options.threshold)
7484
{
75-
if (binary)
85+
if (options.binary)
7686
{
7787
ofs.write(reinterpret_cast<char*>(&line[col]), sizeof(T));
7888
ofs_tem1.write(reinterpret_cast<char *>(&col), sizeof(int));
@@ -93,11 +103,9 @@ void ModuleIO::output_single_R(std::ofstream& ofs,
93103
}
94104
}
95105

96-
delete[] line;
97-
98-
if (!reduce || GlobalV::DRANK == 0)
106+
if (!options.reduce || GlobalV::DRANK == 0)
99107
{
100-
if (binary)
108+
if (options.binary)
101109
{
102110
ofs_tem1.close();
103111
ifs_tem1.open(tem1.str().c_str(), std::ios::binary);
@@ -128,15 +136,11 @@ void ModuleIO::output_single_R(std::ofstream& ofs,
128136
}
129137

130138
template void ModuleIO::output_single_R<double>(std::ofstream& ofs,
131-
const std::map<size_t, std::map<size_t, double>>& XR,
132-
const double& sparse_threshold,
133-
const bool& binary,
139+
const SparseRBlock<double>& XR,
134140
const Parallel_Orbitals& pv,
135-
const bool& reduce);
141+
const SparseWriteOptions& options);
136142

137143
template void ModuleIO::output_single_R<std::complex<double>>(std::ofstream& ofs,
138-
const std::map<size_t, std::map<size_t, std::complex<double>>>& XR,
139-
const double& sparse_threshold,
140-
const bool& binary,
144+
const SparseRBlock<std::complex<double>>& XR,
141145
const Parallel_Orbitals& pv,
142-
const bool& reduce);
146+
const SparseWriteOptions& options);
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
#ifndef SINGLE_R_IO_H
22
#define SINGLE_R_IO_H
33

4-
#include "source_basis/module_ao/parallel_orbitals.h"
5-
#include <map>
4+
#include "write_HS_sparse.h"
5+
6+
#include <fstream>
67

78
namespace ModuleIO
89
{
910
template <typename T>
1011
void output_single_R(std::ofstream& ofs,
11-
const std::map<size_t, std::map<size_t, T>>& XR,
12-
const double& sparse_threshold,
13-
const bool& binary,
12+
const SparseRBlock<T>& XR,
1413
const Parallel_Orbitals& pv,
15-
const bool& reduce = true);
14+
const SparseWriteOptions& options);
1615
}
1716

1817
#endif

source/source_io/module_hs/write_HS.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,11 @@ void ModuleIO::save_mat(const int istep,
280280
#else
281281
if (app)
282282
{
283-
std::ofstream out_matrix(filename.c_str(), std::ofstream::app);
283+
out_matrix.open(filename.c_str(), std::ofstream::app);
284284
}
285285
else
286286
{
287-
std::ofstream out_matrix(filename.c_str());
287+
out_matrix.open(filename.c_str());
288288
}
289289

290290
out_matrix << dim;

source/source_io/module_hs/write_HS_R.cpp

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,6 @@
88
#include "source_lcao/spar_st.h"
99
#include "write_HS_sparse.h"
1010

11-
namespace {
12-
// Helper: Convert sparse map to HContainer
13-
template <typename T>
14-
hamilt::HContainer<T>* sparse_map_to_hcontainer(
15-
const std::map<Abfs::Vector3_Order<int>, std::map<size_t, std::map<size_t, T>>>& sparse_map,
16-
const Parallel_Orbitals& pv,
17-
const int nbasis)
18-
{
19-
hamilt::HContainer<T>* hc = new hamilt::HContainer<T>(&pv);
20-
hc->set_zero();
21-
22-
for (const auto& r_entry : sparse_map)
23-
{
24-
const auto& R = r_entry.first;
25-
for (const auto& row_entry : r_entry.second)
26-
{
27-
const size_t row = row_entry.first;
28-
for (const auto& col_entry : row_entry.second)
29-
{
30-
hc->set_value(R.x, R.y, R.z, row, col_entry.first, col_entry.second);
31-
}
32-
}
33-
}
34-
35-
return hc;
36-
}
37-
} // anonymous namespace
38-
3911
// if 'binary=true', output binary file.
4012
// The 'sparse_thr' is the accuracy of the sparse matrix.
4113
// If the absolute value of the matrix element is less than or equal to the
@@ -143,28 +115,28 @@ void ModuleIO::output_SR(Parallel_Orbitals& pv,
143115
p_ham);
144116

145117
const int istep = 0;
118+
ModuleIO::SparseWriteOptions options;
119+
options.filename = SR_filename;
120+
options.label = "S";
121+
options.threshold = sparse_thr;
122+
options.binary = binary;
123+
options.istep = istep;
124+
options.reduce = true;
125+
options.temp_dir = PARAM.globalv.global_out_dir;
146126

147127
if (PARAM.inp.nspin == 4)
148128
{
149129
ModuleIO::save_sparse(HS_Arrays.SR_soc_sparse,
150130
HS_Arrays.all_R_coor,
151-
sparse_thr,
152-
binary,
153-
SR_filename,
154131
pv,
155-
"S",
156-
istep);
132+
options);
157133
}
158134
else
159135
{
160136
ModuleIO::save_sparse(HS_Arrays.SR_sparse,
161137
HS_Arrays.all_R_coor,
162-
sparse_thr,
163-
binary,
164-
SR_filename,
165138
pv,
166-
"S",
167-
istep);
139+
options);
168140
}
169141

170142
sparse_format::destroy_HS_R_sparse(HS_Arrays);
@@ -206,15 +178,19 @@ void ModuleIO::output_TR(const int istep,
206178
}
207179

208180
sparse_format::cal_TR(ucell, pv, HS_Arrays, grid, two_center_bundle, orb, sparse_thr);
181+
ModuleIO::SparseWriteOptions options;
182+
options.filename = sst.str();
183+
options.label = "T";
184+
options.threshold = sparse_thr;
185+
options.binary = binary;
186+
options.istep = istep;
187+
options.reduce = true;
188+
options.temp_dir = PARAM.globalv.global_out_dir;
209189

210190
ModuleIO::save_sparse(HS_Arrays.TR_sparse,
211191
HS_Arrays.all_R_coor,
212-
sparse_thr,
213-
binary,
214-
sst.str().c_str(),
215192
pv,
216-
"T",
217-
istep);
193+
options);
218194

219195
sparse_format::destroy_T_R_sparse(HS_Arrays);
220196

0 commit comments

Comments
 (0)