1
- // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1
+ // SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2
2
//
3
3
// SPDX-License-Identifier: BSD-3-Clause
4
4
21
21
#include " core/base/utils.hpp"
22
22
#include " core/config/config_helper.hpp"
23
23
#include " core/config/dispatch.hpp"
24
+ #include " core/factorization/factorization_kernels.hpp"
24
25
#include " core/preconditioner/jacobi_kernels.hpp"
25
26
#include " core/preconditioner/jacobi_utils.hpp"
26
27
@@ -45,7 +46,10 @@ GKO_REGISTER_OPERATION(convert_to_dense, jacobi::convert_to_dense);
45
46
GKO_REGISTER_OPERATION (scalar_convert_to_dense,
46
47
jacobi::scalar_convert_to_dense);
47
48
GKO_REGISTER_OPERATION (initialize_precisions, jacobi::initialize_precisions);
48
-
49
+ GKO_REGISTER_OPERATION (scalar_l1, jacobi::scalar_l1);
50
+ GKO_REGISTER_OPERATION (block_l1, jacobi::block_l1);
51
+ GKO_REGISTER_OPERATION (add_diagonal_elements,
52
+ factorization::add_diagonal_elements);
49
53
50
54
} // anonymous namespace
51
55
} // namespace jacobi
@@ -85,7 +89,9 @@ Jacobi<ValueType, IndexType>::parse(const config::pnode& config,
85
89
params.with_accuracy (
86
90
gko::config::get_value<remove_complex<ValueType>>(obj));
87
91
}
88
-
92
+ if (auto & obj = config.get (" aggregate_l1" )) {
93
+ params.with_aggregate_l1 (gko::config::get_value<bool >(obj));
94
+ }
89
95
return params;
90
96
}
91
97
@@ -326,8 +332,17 @@ void Jacobi<ValueType, IndexType>::generate(const LinOp* system_matrix,
326
332
using csr_type = matrix::Csr<ValueType, IndexType>;
327
333
const auto exec = this ->get_executor ();
328
334
if (parameters_.max_block_size == 1 ) {
329
- auto diag = share (as<DiagonalLinOpExtractable>(system_matrix)
330
- ->extract_diagonal_linop ());
335
+ std::shared_ptr<LinOp> diag = nullptr ;
336
+ if (this ->get_parameters ().aggregate_l1 ) {
337
+ auto csr_mtx = convert_to_with_sorting<const csr_type>(
338
+ exec, system_matrix, skip_sorting);
339
+ auto diagonal = share (csr_mtx->extract_diagonal ());
340
+ exec->run (jacobi::make_scalar_l1 (csr_mtx.get (), diagonal.get ()));
341
+ diag = diagonal;
342
+ } else {
343
+ diag = share (as<DiagonalLinOpExtractable>(system_matrix)
344
+ ->extract_diagonal_linop ());
345
+ }
331
346
auto diag_vt =
332
347
::gko::detail::temporary_conversion<matrix::Diagonal<ValueType>>::
333
348
template create<matrix::Diagonal<previous_precision<ValueType>>,
@@ -344,11 +359,26 @@ void Jacobi<ValueType, IndexType>::generate(const LinOp* system_matrix,
344
359
exec->run (jacobi::make_invert_diagonal (temp, this ->blocks_ ));
345
360
this ->num_blocks_ = diag_vt->get_size ()[0 ];
346
361
} else {
347
- auto csr_mtx = convert_to_with_sorting<csr_type>(exec, system_matrix,
348
- skip_sorting);
362
+ auto csr_mtx = share ( convert_to_with_sorting<csr_type>(
363
+ exec, system_matrix, skip_sorting) );
349
364
if (parameters_.block_pointers .get_data () == nullptr ) {
350
365
this ->detect_blocks (csr_mtx.get ());
351
366
}
367
+ if (this ->get_parameters ().aggregate_l1 ) {
368
+ // It should be sorted in the convert_to_with_sorting
369
+ // We only use it to generate the inversed block, so we do not need
370
+ // to rebuild srow
371
+ // Note: Does the diagonal make the find_block different?
372
+ // Because we change the matrix value, we clone it to avoid
373
+ // overwriting to the original matrix.
374
+ auto changed_mtx = share (csr_mtx->clone ());
375
+ exec->run (
376
+ jacobi::make_add_diagonal_elements (changed_mtx.get (), true ));
377
+ // block_pointers has larger size than actual num_blocks_
378
+ exec->run (jacobi::make_block_l1 (
379
+ num_blocks_, parameters_.block_pointers , changed_mtx.get ()));
380
+ csr_mtx = changed_mtx;
381
+ }
352
382
const auto all_block_opt =
353
383
parameters_.storage_optimization .of_all_blocks ;
354
384
auto & precisions = parameters_.storage_optimization .block_wise ;
0 commit comments