Skip to content

Linear solver changes to support hybrid parallel AD - #1228

Merged
pcarruscag merged 17 commits into
developfrom
linsol_fixes
Mar 22, 2021
Merged

Linear solver changes to support hybrid parallel AD#1228
pcarruscag merged 17 commits into
developfrom
linsol_fixes

Conversation

@pcarruscag

@pcarruscag pcarruscag commented Mar 11, 2021

Copy link
Copy Markdown
Member

Proposed Changes

Instead of computing transposed matrix vector products, which are harder to parallelize with OpenMP, and having special handling for transposed preconditioners, the matrix is transposed in place, then any preconditioner can be applied.
Some tweaks to support better Krylov discrete adjoint.

Related Work

#1214

PR Checklist

  • I am submitting my contribution to the develop branch.
  • My contribution generates no new compiler warnings (try with the '-Wall -Wextra -Wno-unused-parameter -Wno-empty-body' compiler flags, or simply --warnlevel=2 when using meson).
  • My contribution is commented and consistent with SU2 style.
  • I have added a test case that demonstrates my contribution, if necessary.
  • I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp) , if necessary.

@pcarruscag pcarruscag changed the title [WIP] Linear solver changes to support hybrid parallel AD Linear solver changes to support hybrid parallel AD Mar 14, 2021
@pcarruscag
pcarruscag marked this pull request as ready for review March 14, 2021 23:40
Comment on lines 938 to +941
/*--- Build preconditioner for the transposed Jacobian ---*/

if (RequiresTranspose) Jacobian.TransposeInPlace();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The transposition happens here.
Things that could go wrong with this approach:

  • Solving the same system multiple times, without clearing the matrix or reverting the transposition in between. It does not happen atm.

I think it is worth the risk, since all preconditioners can be used now, and re-transposing the matrix if necessary is not very expensive (probably the same as applying the ILU once).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not that I used a preconditioner besides ILU for DA cases yet, but that is a nice thing 👍

@TobiKattmann TobiKattmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well, the code looks nice as always 💐 but I cannot really say much about the changes in general because I am not exactly familiar with that code :(

LinearToleranceType tol_type = LinearToleranceType::RELATIVE; /*!< \brief How the linear solvers interpret the tolerance. */
bool xIsZero = false; /*!< \brief If true assume the initial solution is always 0. */
mutable LinearToleranceType tol_type = LinearToleranceType::ABSOLUTE; /*!< \brief How the linear solvers interpret the tolerance. */
mutable bool xIsZero = false; /*!< \brief If true assume the initial solution is always 0. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Where there is const, there must be mutable somewhere

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Restarted FGMRES (which I put in a function) needs to force those values. But I'll do it some other way, mutable in this case is misleading as relevant state can be different after the solver is called.
I try to reserve mutable for variables that do not change the behavior of the object.

Comment on lines +916 to +917
/*--- To keep the behavior of SU2_DOT, but not strictly required since jacobian is symmetric(?). ---*/
const bool RequiresTranspose = !mesh_deform || (config->GetKind_SU2() == SU2_DOT);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess SU2_DOT does a mesh deformation using the linear solvers so that is what the question mark refers to in the comment? Or am I missing sth here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Well the Jacobian is not symmetric because of how we do the boundary conditions but conjugate gradient still works so... 🤷

Comment on lines 938 to +941
/*--- Build preconditioner for the transposed Jacobian ---*/

if (RequiresTranspose) Jacobian.TransposeInPlace();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not that I used a preconditioner besides ILU for DA cases yet, but that is a nice thing 👍

Comment thread TestCases/parallel_regression_AD.py Outdated
da_sp_pinArray_cht_2d_dp_hf.cfg_file = "DA_configMaster.cfg"
da_sp_pinArray_cht_2d_dp_hf.test_iter = 100
da_sp_pinArray_cht_2d_dp_hf.test_vals = [-4.793283, -4.065832, -4.137121] #last 4 lines
da_sp_pinArray_cht_2d_dp_hf.test_vals = [-4.800583, -4.065533, -4.137185] #last 4 lines

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well the deviations are really tiny but both inc cases have INC_ENERGY_EQUATION= YES but discadj_cht is not here as the third case that has that... Not that I am worried but if you have an explanation why exactly those cases differ, I'd be interested?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The common denominator seemed to be cases that had a significant number of linear iterations.
I ran them to convergence and there is 0 difference in final results.
I will still test these changes in my optimization cases before merging.

Comment on lines 1877 to +1884
enum ENUM_LINEAR_SOLVER {
STEEPEST_DESCENT = 1, /*!< \brief Steepest descent method for point inversion algoritm (Free-Form). */
NEWTON = 2, /*!< \brief Newton method for point inversion algorithm (Free-Form). */
QUASI_NEWTON = 3, /*!< \brief Quasi Newton method for point inversion algorithm (Free-Form). */
CONJUGATE_GRADIENT = 4, /*!< \brief Preconditionated conjugate gradient method for grid deformation. */
FGMRES = 5, /*!< \brief Flexible Generalized Minimal Residual method. */
BCGSTAB = 6, /*!< \brief BCGSTAB - Biconjugate Gradient Stabilized Method (main solver). */
RESTARTED_FGMRES = 7, /*!< \brief Flexible Generalized Minimal Residual method with restart. */
SMOOTHER = 8, /*!< \brief Iterative smoother. */
PASTIX_LDLT = 9, /*!< \brief PaStiX LDLT (complete) factorization. */
PASTIX_LU = 10, /*!< \brief PaStiX LU (complete) factorization. */
CONJUGATE_GRADIENT, /*!< \brief Preconditionated conjugate gradient method for grid deformation. */
FGMRES, /*!< \brief Flexible Generalized Minimal Residual method. */
BCGSTAB, /*!< \brief BCGSTAB - Biconjugate Gradient Stabilized Method (main solver). */
RESTARTED_FGMRES, /*!< \brief Flexible Generalized Minimal Residual method with restart. */
SMOOTHER, /*!< \brief Iterative smoother. */
PASTIX_LDLT, /*!< \brief PaStiX LDLT (complete) factorization. */
PASTIX_LU, /*!< \brief PaStiX LU (complete) factorization. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@bigfooted likes that :D

@pcarruscag
pcarruscag merged commit 949f4e5 into develop Mar 22, 2021
@pcarruscag
pcarruscag deleted the linsol_fixes branch March 22, 2021 23:01
Comment on lines +310 to +315
/*--- Reduce across all mpi ranks, only master thread communicates. ---*/
SU2_OMP_BARRIER
SU2_OMP_MASTER {
sum = dotRes;
const auto mpi_type = (sizeof(ScalarType) < sizeof(double)) ? MPI_FLOAT : MPI_DOUBLE;
SelectMPIWrapper<ScalarType>::W::Allreduce(&sum, &dotRes, 1, mpi_type, MPI_SUM, SU2_MPI::GetComm());

@TobiKattmann TobiKattmann Mar 23, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Resolves #1241 👍

Comment on lines 1261 to 1263
sp_pinArray_cht_2d_dp_hf.test_iter = 100
sp_pinArray_cht_2d_dp_hf.test_vals = [0.247022, -0.812199, -0.974877, -0.753315, 208.023676, 349.950000] #last 7 lines
sp_pinArray_cht_2d_dp_hf.test_vals = [0.247026, -0.811632, -0.982066, -0.753312, 208.023676, 350.180000] #last 7 lines
sp_pinArray_cht_2d_dp_hf.su2_exec = "mpirun -n 2 SU2_CFD"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I will redo the gradient validation on my side... and I like that commit message 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants