@@ -43,45 +43,12 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
43
43
std::unique_ptr<Matrix<CoefficientPrecision>> m_dense_data{nullptr };
44
44
std::unique_ptr<LowRankMatrix<CoefficientPrecision, CoordinatePrecision>> m_low_rank_data{nullptr };
45
45
46
- // Cached leaves
47
- mutable std::vector<const HMatrix *> m_leaves{};
48
- mutable std::vector<const HMatrix *> m_leaves_for_symmetry{};
49
- mutable char m_symmetry_type_for_leaves{' N' };
50
- mutable char m_UPLO_for_leaves{' N' };
46
+ //
47
+ char m_symmetry_type_for_leaves{' N' };
48
+ char m_UPLO_for_leaves{' N' };
51
49
52
50
StorageType m_storage_type{StorageType::Hierarchical};
53
51
54
- void set_leaves_in_cache () const {
55
- if (m_leaves.empty ()) {
56
- std::stack<std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >> hmatrix_stack;
57
- hmatrix_stack.push (std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >(this , m_symmetry != ' N' ));
58
-
59
- while (!hmatrix_stack.empty ()) {
60
- auto ¤t_element = hmatrix_stack.top ();
61
- hmatrix_stack.pop ();
62
- const HMatrix<CoefficientPrecision, CoordinatePrecision> *current_hmatrix = current_element.first ;
63
- bool has_symmetric_ancestor = current_element.second ;
64
-
65
- if (current_hmatrix->is_leaf ()) {
66
- m_leaves.push_back (current_hmatrix);
67
-
68
- if (has_symmetric_ancestor && current_hmatrix->get_target_cluster ().get_offset () != current_hmatrix->get_source_cluster ().get_offset ()) {
69
- m_leaves_for_symmetry.push_back (current_hmatrix);
70
- }
71
- }
72
-
73
- if (m_symmetry_type_for_leaves == ' N' && current_hmatrix->get_symmetry () != ' N' ) {
74
- m_symmetry_type_for_leaves = current_hmatrix->get_symmetry ();
75
- m_UPLO_for_leaves = current_hmatrix->get_UPLO ();
76
- }
77
-
78
- for (const auto &child : current_hmatrix->get_children ()) {
79
- hmatrix_stack.push (std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >(child.get (), current_hmatrix->get_symmetry () != ' N' || has_symmetric_ancestor));
80
- }
81
- }
82
- }
83
- }
84
-
85
52
public:
86
53
// Root constructor
87
54
HMatrix (const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster) : TreeNode<HMatrix, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(), m_target_cluster(&target_cluster), m_source_cluster(&source_cluster) {
@@ -90,7 +57,7 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
90
57
// Child constructor
91
58
HMatrix (const HMatrix &parent, const Cluster<CoordinatePrecision> *target_cluster, const Cluster<CoordinatePrecision> *source_cluster) : TreeNode<HMatrix, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(parent), m_target_cluster(target_cluster), m_source_cluster(source_cluster) {}
92
59
93
- HMatrix (const HMatrix &rhs) : TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecision>, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(rhs), m_target_cluster(rhs.m_target_cluster), m_source_cluster(rhs.m_source_cluster), m_symmetry(rhs.m_symmetry), m_UPLO(rhs.m_UPLO), m_leaves(), m_leaves_for_symmetry(), m_symmetry_type_for_leaves(), m_storage_type(rhs.m_storage_type) {
60
+ HMatrix (const HMatrix &rhs) : TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecision>, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(rhs), m_target_cluster(rhs.m_target_cluster), m_source_cluster(rhs.m_source_cluster), m_symmetry(rhs.m_symmetry), m_UPLO(rhs.m_UPLO), m_symmetry_type_for_leaves(), m_storage_type(rhs.m_storage_type) {
94
61
if (m_target_cluster->is_root () or is_cluster_on_partition (*m_target_cluster)) {
95
62
Logger::get_instance ().log (LogLevel::INFO, " Deep copy of HMatrix" );
96
63
}
@@ -120,20 +87,20 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
120
87
for (auto &child : rhs.m_children ) {
121
88
this ->m_children .emplace_back (std::make_unique<HMatrix<CoefficientPrecision, CoordinatePrecision>>(*child));
122
89
}
123
- m_target_cluster = rhs.m_target_cluster ;
124
- m_source_cluster = rhs.m_source_cluster ;
125
- m_symmetry = rhs.m_symmetry ;
126
- m_UPLO = rhs.m_UPLO ;
127
- m_storage_type = rhs.m_storage_type ;
90
+ m_target_cluster = rhs.m_target_cluster ;
91
+ m_source_cluster = rhs.m_source_cluster ;
92
+ m_symmetry = rhs.m_symmetry ;
93
+ m_UPLO = rhs.m_UPLO ;
94
+ m_storage_type = rhs.m_storage_type ;
95
+ m_symmetry_type_for_leaves = rhs.m_symmetry_type_for_leaves ;
96
+ m_UPLO_for_leaves = rhs.m_UPLO_for_leaves ;
128
97
129
98
if (rhs.m_dense_data ) {
130
99
m_dense_data = std::make_unique<Matrix<CoefficientPrecision>>(*rhs.m_dense_data );
131
100
}
132
101
if (rhs.m_low_rank_data ) {
133
102
m_low_rank_data = std::make_unique<LowRankMatrix<CoefficientPrecision, CoordinatePrecision>>(*rhs.m_low_rank_data );
134
103
}
135
- m_leaves.clear ();
136
- m_leaves_for_symmetry.clear ();
137
104
return *this ;
138
105
}
139
106
@@ -175,14 +142,7 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
175
142
int get_rank () const {
176
143
return m_storage_type == StorageType::LowRank ? m_low_rank_data->rank_of () : -1 ;
177
144
}
178
- const std::vector<const HMatrix *> &get_leaves () const {
179
- set_leaves_in_cache ();
180
- return m_leaves;
181
- }
182
- const std::vector<const HMatrix *> &get_leaves_for_symmetry () const {
183
- set_leaves_in_cache ();
184
- return m_leaves_for_symmetry;
185
- }
145
+
186
146
const Matrix<CoefficientPrecision> *get_dense_data () const { return m_dense_data.get (); }
187
147
Matrix<CoefficientPrecision> *get_dense_data () { return m_dense_data.get (); }
188
148
const LowRankMatrix<CoefficientPrecision, CoordinatePrecision> *get_low_rank_data () const { return m_low_rank_data.get (); }
@@ -233,6 +193,8 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
233
193
// HMatrix node setters
234
194
void set_symmetry (char symmetry) { m_symmetry = symmetry; }
235
195
void set_UPLO (char UPLO) { m_UPLO = UPLO; }
196
+ void set_symmetry_for_leaves (char symmetry) const { m_symmetry_type_for_leaves = symmetry; }
197
+ void set_UPLO_for_leaves (char UPLO) const { m_UPLO_for_leaves = UPLO; }
236
198
void set_target_cluster (const Cluster<CoordinatePrecision> *new_target_cluster) { m_target_cluster = new_target_cluster; }
237
199
238
200
// Test properties
@@ -267,23 +229,52 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
267
229
268
230
void set_dense_data (std::unique_ptr<Matrix<CoefficientPrecision>> dense_matrix_ptr) {
269
231
this ->delete_children ();
270
- m_leaves.clear ();
271
- m_leaves_for_symmetry.clear ();
272
- m_dense_data = std::move (dense_matrix_ptr);
273
- // m_dense_data = std::make_unique<Matrix<CoefficientPrecision>>();
274
- // m_dense_data->assign(dense_matrix.nb_rows(), dense_matrix.nb_cols(), dense_matrix.release(), true);
232
+ m_dense_data = std::move (dense_matrix_ptr);
275
233
m_storage_type = StorageType::Dense;
276
234
}
277
235
};
278
236
237
+ template <typename CoefficientPrecision, typename CoordinatePrecision = underlying_type<CoefficientPrecision>>
238
+ std::pair<std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *>, std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *>> get_leaves_from (const HMatrix<CoefficientPrecision, CoordinatePrecision> &hmatrix) {
239
+ std::pair<std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *>, std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *>> result;
240
+ auto &leaves = result.first ;
241
+ auto &leaves_for_symmetry = result.second ;
242
+ std::stack<std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >> hmatrix_stack;
243
+ hmatrix_stack.push (std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >(&hmatrix, hmatrix.get_symmetry () != ' N' ));
244
+
245
+ while (!hmatrix_stack.empty ()) {
246
+ auto ¤t_element = hmatrix_stack.top ();
247
+ hmatrix_stack.pop ();
248
+ const HMatrix<CoefficientPrecision, CoordinatePrecision> *current_hmatrix = current_element.first ;
249
+ bool has_symmetric_ancestor = current_element.second ;
250
+
251
+ if (current_hmatrix->is_leaf ()) {
252
+ leaves.push_back (current_hmatrix);
253
+
254
+ if (has_symmetric_ancestor && current_hmatrix->get_target_cluster ().get_offset () != current_hmatrix->get_source_cluster ().get_offset ()) {
255
+ leaves_for_symmetry.push_back (current_hmatrix);
256
+ }
257
+ }
258
+
259
+ for (const auto &child : current_hmatrix->get_children ()) {
260
+ hmatrix_stack.push (std::pair<const HMatrix<CoefficientPrecision, CoordinatePrecision> *, bool >(child.get (), current_hmatrix->get_symmetry () != ' N' || has_symmetric_ancestor));
261
+ }
262
+ }
263
+ return result;
264
+ }
265
+
279
266
template <typename CoefficientPrecision, typename CoordinatePrecision = underlying_type<CoefficientPrecision>>
280
267
void copy_to_dense (const HMatrix<CoefficientPrecision, CoordinatePrecision> &hmatrix, CoefficientPrecision *ptr) {
281
268
282
269
int target_offset = hmatrix.get_target_cluster ().get_offset ();
283
270
int source_offset = hmatrix.get_source_cluster ().get_offset ();
284
271
int target_size = hmatrix.get_target_cluster ().get_size ();
285
272
286
- for (auto leaf : hmatrix.get_leaves ()) {
273
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves;
274
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves_for_symmetry;
275
+ std::tie (leaves, leaves_for_symmetry) = get_leaves_from (hmatrix); // C++17 structured binding
276
+
277
+ for (auto leaf : leaves) {
287
278
int local_nr = leaf->get_target_cluster ().get_size ();
288
279
int local_nc = leaf->get_source_cluster ().get_size ();
289
280
int row_offset = leaf->get_target_cluster ().get_offset () - target_offset;
@@ -332,8 +323,11 @@ void copy_to_dense_in_user_numbering(const HMatrix<CoefficientPrecision, Coordin
332
323
int target_size = target_cluster.get_size ();
333
324
const auto &target_permutation = target_cluster.get_permutation ();
334
325
const auto &source_permutation = source_cluster.get_permutation ();
326
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves;
327
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves_for_symmetry;
328
+ std::tie (leaves, leaves_for_symmetry) = get_leaves_from (hmatrix); // C++17 structured binding
335
329
336
- for (auto leaf : hmatrix. get_leaves () ) {
330
+ for (auto leaf : leaves ) {
337
331
int local_nr = leaf->get_target_cluster ().get_size ();
338
332
int local_nc = leaf->get_source_cluster ().get_size ();
339
333
int row_offset = leaf->get_target_cluster ().get_offset ();
@@ -357,7 +351,7 @@ void copy_to_dense_in_user_numbering(const HMatrix<CoefficientPrecision, Coordin
357
351
}
358
352
}
359
353
if (hmatrix.get_symmetry_for_leaves () != ' N' ) {
360
- for (auto leaf : hmatrix. get_leaves_for_symmetry () ) {
354
+ for (auto leaf : leaves_for_symmetry ) {
361
355
int local_nr = leaf->get_target_cluster ().get_size ();
362
356
int local_nc = leaf->get_source_cluster ().get_size ();
363
357
int row_offset = leaf->get_target_cluster ().get_offset ();
@@ -381,8 +375,11 @@ void copy_diagonal(const HMatrix<CoefficientPrecision, CoordinatePrecision> &hma
381
375
382
376
int target_offset = hmatrix.get_target_cluster ().get_offset ();
383
377
int source_offset = hmatrix.get_source_cluster ().get_offset ();
378
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves;
379
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves_for_symmetry;
380
+ std::tie (leaves, leaves_for_symmetry) = get_leaves_from (hmatrix); // C++17 structured binding
384
381
385
- for (auto leaf : hmatrix. get_leaves () ) {
382
+ for (auto leaf : leaves ) {
386
383
int local_nr = leaf->get_target_cluster ().get_size ();
387
384
int local_nc = leaf->get_source_cluster ().get_size ();
388
385
int offset_i = leaf->get_target_cluster ().get_offset () - target_offset;
@@ -418,8 +415,11 @@ void copy_diagonal_in_user_numbering(const HMatrix<CoefficientPrecision, Coordin
418
415
const auto &permutation = hmatrix.get_target_cluster ().get_permutation ();
419
416
int target_offset = hmatrix.get_target_cluster ().get_offset ();
420
417
// int source_offset = hmatrix.get_source_cluster().get_offset();
418
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves;
419
+ std::vector<const HMatrix<CoefficientPrecision, CoordinatePrecision> *> leaves_for_symmetry;
420
+ std::tie (leaves, leaves_for_symmetry) = get_leaves_from (hmatrix); // C++17 structured binding
421
421
422
- for (auto leaf : hmatrix. get_leaves () ) {
422
+ for (auto leaf : leaves ) {
423
423
int local_nr = leaf->get_target_cluster ().get_size ();
424
424
int local_nc = leaf->get_source_cluster ().get_size ();
425
425
int offset_i = leaf->get_target_cluster ().get_offset ();
0 commit comments