Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the L1 jacobi #1310

Merged
merged 8 commits into from
Feb 20, 2025
Merged

Add the L1 jacobi #1310

merged 8 commits into from
Feb 20, 2025

Conversation

yhmtsai
Copy link
Member

@yhmtsai yhmtsai commented Mar 23, 2023

This add the L1 to Jacobi. The detail is shown in https://epubs.siam.org/doi/abs/10.1137/100798806
original preconditioner is on $M$ (which is diagonal of A for scalar Jacobi or diagonal block of A)
L1 smoother is on $M' = M + D^{\mathcal{l}_1}$ whose $D^{\mathcal{l}_1}$ is a diagonal matrix with

$$D_{ii}^{\mathcal{l}1} = \sum{j \in \text{the off-diagonal block of corresponding block of i}}{|A_{ij}|}$$

I am not sure whether the theorems in the paper still work for negative diagonal entries.

@yhmtsai yhmtsai added the 1:ST:ready-for-review This PR is ready for review label Mar 23, 2023
@yhmtsai yhmtsai self-assigned this Mar 23, 2023
@ginkgo-bot ginkgo-bot added reg:testing This is related to testing. mod:core This is related to the core module. mod:cuda This is related to the CUDA module. mod:reference This is related to the reference module. type:preconditioner This is related to the preconditioners mod:hip This is related to the HIP module. labels Mar 23, 2023
@MarcelKoch
Copy link
Member

I'm a bit confused. The paper talks about the L1 Jacobi only in a distributed setting, ie the off-diagonal entries you mentioned are the entries of our non-local matrix in the distributed matrix. But your implementation is for non-distributed matrices. Can you perhaps provide another reference for the non-distributed case?

@codecov
Copy link

codecov bot commented Mar 23, 2023

Codecov Report

Attention: Patch coverage is 98.37838% with 3 lines in your changes missing coverage. Please review.

Project coverage is 89.80%. Comparing base (01a3d35) to head (aa09f9b).
Report is 24 commits behind head on develop.

Files with missing lines Patch % Lines
core/device_hooks/common_kernels.inc.cpp 0.00% 2 Missing ⚠️
common/unified/preconditioner/jacobi_kernels.cpp 88.88% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1310      +/-   ##
===========================================
- Coverage    90.88%   89.80%   -1.08%     
===========================================
  Files          808      811       +3     
  Lines        66521    67254     +733     
===========================================
- Hits         60459    60400      -59     
- Misses        6062     6854     +792     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@yhmtsai
Copy link
Member Author

yhmtsai commented Mar 23, 2023

it's only based on the nonoverlapping partition.
we can also add the L1 to the Schwarz for the distributed local preconditioner.
6.2 in the paper mentioned the L1 scalar Jacobi

@MarcelKoch
Copy link
Member

I think sec. 6.2 means using the preconditioner from 6. M = M_H + D^l with M_H = D. The D^l is still build from the non-local columns. I'm not saying it still works for non-distributed matrices, just that the paper description applies to distributed matrices. (The L1 smoother for non-distributed matrices would just be the standard Jacobi.)

@yhmtsai
Copy link
Member Author

yhmtsai commented Mar 23, 2023

If the partition is only designed with the mpi (let me use the mpi here to distinguish), L1 is indeed normal Jacobi
i.e using Schwarz with L1 will give this behavior.
But the paper from second paragraph of section 5 makes me think it works for any distributed (any block partition). design the partition by the mpi is one example

@yhmtsai
Copy link
Member Author

yhmtsai commented Mar 23, 2023

there's one reference from precond. They use L1-scalar Jacobi
but they also use the absolute value of diagonal part
https://etna.math.kent.edu/vol.55.2022/pp687-705.dir/pp687-705.pdf

@MarcelKoch
Copy link
Member

The L1 smoother from sec. 6 is an improvement on the hybrid smoother from sec 5. The hybrid smoother applies a local smoother only on the local matrix block of a distributed matrix and ignores the non-local part. The L1 smoother than takes the non-local part into account through the D^l matrix.
Again, this might also work for non-distributed matrices, but maybe it would not be the L1 smoother people would expect. But from the other paper you linked, people seem to be not very careful about this definition.

@MarcelKoch
Copy link
Member

Perhaps naming it 'lumped-Jacobi' would be better suited to differentiate between those two variants. And I guess the L1 from the first paper could be implemented as another distributed preconditioner.
Also, the paper you mentioned does a full row sum, so it also includes the diagonal value.

@yhmtsai
Copy link
Member Author

yhmtsai commented Mar 23, 2023

The first paper considers the diagonal entries are positive, so they are equivalent.
Distributed on mpi or distributed on the block to me are the same thing, which are ways to cut the matrices.
Applying L1 to LocalPreconditioner and to Schwarz are enough to distinguish.
With lumped, we still need to indicate it is L1 in the comments

@MarcelKoch
Copy link
Member

My argument is that what is implemented in this PR is not the L1 from the paper, so we should not call it that. But honestly, I don't have a great overview of how the term L1 smoother is usually interpreted.

@MarcelKoch
Copy link
Member

MarcelKoch commented Mar 23, 2023

And in your interpretation, there are still the diagonal entries missing in the sum. The preconditioner is D + D^l. Sorry, I missed the part that initializes the array with the (block) diagonal.

@yhmtsai
Copy link
Member Author

yhmtsai commented Mar 23, 2023

It should be theorically L1 smoother. otherwise, I just add some random Jacobi.
(I need to use [] not {} to represent row index set because I can not display {} with github latex)
scalar Jacobi: $\Omega_k = [k]$
block Jacobi: $\Omega_k = [row \in \text{block}_k]$

@MarcelKoch
Copy link
Member

The L1 smoother (Jacobi or GS) explicitly references distributed matrices. I still think that if we want to follow the naming of the paper, the variant implemented here should not be called L1. Instead, we should add a new distributed preconditioner which consists of a local solver (Jacobi, or in the future perhaps GS) and a diagonal matrix with the row-wise sum of the non-local part.

@MarcelKoch MarcelKoch self-requested a review April 6, 2023 15:53
@upsj upsj requested a review from pratikvn April 6, 2023 15:54
@pratikvn
Copy link
Member

pratikvn commented Apr 6, 2023

Maybe I am misunderstanding something, but in the non-distributed case, this is basically diagonal relaxation with weights equal to row sums, right ? So, I think it definitely makes sense to have as a smoother as an alternative to the scalar Jacobi smoother.

I think the name L1 is well suited because you are taking the L1 norm on the row space vectors ? $|v| = \sum_{n}|v_i|$.

Not sure if there is some mathematical basis for this yet, we could also try seeing if any other p-norms also make sense, Particularly with $p=\infty$, $p=2$.

@MarcelKoch
Copy link
Member

If we go with @pratikvn suggestion, and base this version on the L1 row norm, then we need to take the absolute value of the diagonal.

@yhmtsai
Copy link
Member Author

yhmtsai commented May 25, 2023

I am not sure whether to take the absolute value of the diagonal value.
It might make sense for the scalar version but not for the block version.
What's the meeting of the absolute of diagonal block to the diagonal value?

@MarcelKoch
Copy link
Member

Taking the absolute value is the only way for this preconditioner to make sense. And for blocks, I would just go with taking the absolute value component-wise. I think then it makes the most sense to add up these block-wise. Currently, you seem to only update the diagonal values of the diagonal block, or maybe I'm mistaken.

@yhmtsai
Copy link
Member Author

yhmtsai commented May 30, 2023

Yes, from the block-version, it only updates the diagonal value.
I think l1 is mostly from taking the summation of the absolute value in non-local block's row, not the entire row.
(l1 norm of non-local-block rows) L1 does not apply to the local block.
From the formula, it does not change the other values in the block.
In the smoother paper, they only consider the positive value in diagonal (see 5.5), although they have additional properties more than positive diagonal values.
In another paper, they consider the SPD cases, so the diagonal values are also positive.
When the diagonal value is positive, it does not change the result no matter whether we take the absolute value of the diagonal value or not.
Another treatment is to $A_{ii} + sign(A_{ii}) D^{l_1}$ if -A is SPD for scalar Jacobi,

From the paper or formula perspective, I prefer only adding values on the diagonal value without take absolute on the diagonal value first.
For the negative diagonal value, we do not know whether it works or not from the papers currently.

@yhmtsai yhmtsai force-pushed the l1_jacobi branch 2 times, most recently from 803333e to 5fc569a Compare July 1, 2024 09:47
Copy link

sonarqubecloud bot commented Jul 3, 2024

@MarcelKoch MarcelKoch self-requested a review July 11, 2024 13:16
@MarcelKoch MarcelKoch added this to the Ginkgo 1.9.0 milestone Aug 26, 2024
Copy link
Member

@pratikvn pratikvn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some doc suggestions, otherwise LGTM!

Comment on lines 377 to 378
* If it is true, it generates the preconditioner on A + Diag(sum_{k in
* off diagonal block of i} A_ik) not A.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think two things are missing:

  1. You should mention that you take the absolute values of the elements.
  2. Maybe also add a note for the scalar case: "When block_size=1, this will be equivalent to taking the inverse of the row-sums as the preconditioner."

Copy link
Member

@MarcelKoch MarcelKoch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for changing the name, for me the name is fine now.
I do have some questions about the block version though.

Copy link
Member

@MarcelKoch MarcelKoch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only smaller nits left on the documentation.

@yhmtsai yhmtsai added 1:ST:ready-to-merge This PR is ready to merge. and removed 1:ST:ready-for-review This PR is ready for review labels Feb 19, 2025
yhmtsai and others added 8 commits February 20, 2025 17:17
nvhpc 23.3 may optimize the formula in different way for scaled_value in make_diag_dominant, which lead the updated value is slightly different
Co-authored-by: Marcel Koch <[email protected]>
Co-authored-by: Pratik Nayak <[email protected]>
@yhmtsai yhmtsai merged commit 2816a56 into develop Feb 20, 2025
8 of 11 checks passed
@yhmtsai yhmtsai deleted the l1_jacobi branch February 20, 2025 16:18
@ginkgo-bot
Copy link
Member

Error: PR already merged!

@MarcelKoch MarcelKoch mentioned this pull request Mar 14, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1:ST:ready-to-merge This PR is ready to merge. mod:core This is related to the core module. mod:cuda This is related to the CUDA module. mod:hip This is related to the HIP module. mod:reference This is related to the reference module. reg:testing This is related to testing. type:preconditioner This is related to the preconditioners
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants