From d0a280ca768f99a0a2ecee74bb222f6e8cbe5f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 31 Oct 2023 12:39:57 +0100 Subject: [PATCH 01/26] Allow up to 255 colors. --- Common/include/toolboxes/graph_toolbox.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index c5929e8f8da3..f1c0854ce27e 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); From 12c63c72133c13e14bf516443b27759ea73d31c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 31 Oct 2023 12:49:58 +0100 Subject: [PATCH 02/26] Report on the number of colors and the efficiency. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 40af46827be5..ccf939f1bf14 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -324,6 +324,9 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi << "\n The memory usage of the discrete adjoint solver is higher when using the fallback." #endif << endl; + } else { + cout << "Rank " << SU2_MPI::GetRank() << " uses " << coloring.getOuterSize() << " colors, " + << parallelEff << "efficiency." << endl; } } From 6d34de3428d8b703232d8a68397e71552010c53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 31 Oct 2023 16:47:53 +0100 Subject: [PATCH 03/26] Add space. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index ccf939f1bf14..bee63030f7d9 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -326,7 +326,7 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi << endl; } else { cout << "Rank " << SU2_MPI::GetRank() << " uses " << coloring.getOuterSize() << " colors, " - << parallelEff << "efficiency." << endl; + << parallelEff << " efficiency." << endl; } } From 766d7b1426ec980f06f84de25989073b1b3aa62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Fri, 27 Oct 2023 12:07:46 +0200 Subject: [PATCH 04/26] Maximize color group size per rank. --- Common/src/geometry/CGeometry.cpp | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 9ed1804186a1..e912c5aa68fa 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3637,6 +3637,42 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; + + /* find an efficient coloring with maximum possible color group size */ + auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that does not work */ + auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ + auto lowerEdgeColorGroupSize = 1; /* lower bound that is known to work */ + + while (true) { + auto currentEdgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + + /* if the coloring fails, reduce the color group size */ + if (currentEdgeColoring.empty()) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + continue; + } + + auto currentEfficiency = coloringEfficiency(currentEdgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + + /* if the coloring is not efficient, reduce the color group size */ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + } + /* otherwise, try to enlarge the color group size */ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + } + auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + + if (increment == 0) { + break; + } + + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + } + + edgeColorGroupSize = lowerEdgeColorGroupSize; edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); /*--- If the coloring fails use the natural coloring. This is a From c454bd84eedbb7101de50fdf8bfd62f4c59b7119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 31 Oct 2023 19:27:12 +0100 Subject: [PATCH 05/26] Add output about chosen color group size. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index bee63030f7d9..83eda4766139 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -325,8 +325,10 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi #endif << endl; } else { - cout << "Rank " << SU2_MPI::GetRank() << " uses " << coloring.getOuterSize() << " colors, " - << parallelEff << " efficiency." << endl; + cout << "Rank " << SU2_MPI::GetRank() << endl + << "\tnumber of colors " << coloring.getOuterSize() << endl + << "\tcolor group size " << geometry.GetEdgeColorGroupSize() << endl + << "\tefficiency " << parallelEff << endl; } } From 70bf19f28a541374563b0d72d67345f9ef995c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Mon, 13 Nov 2023 17:04:43 +0100 Subject: [PATCH 06/26] Aggregated output of coloring properties on master rank. --- .../include/solvers/CFVMFlowSolverBase.inl | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 83eda4766139..14368a547d6a 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -325,10 +325,28 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi #endif << endl; } else { - cout << "Rank " << SU2_MPI::GetRank() << endl - << "\tnumber of colors " << coloring.getOuterSize() << endl - << "\tcolor group size " << geometry.GetEdgeColorGroupSize() << endl - << "\tefficiency " << parallelEff << endl; + if (SU2_MPI::GetRank() == MASTER_NODE) { + cout << "All ranks use edge coloring." << endl; + } + } + + su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; + su2double minColoredParallelEff = 1.0; + SU2_MPI::Reduce(&coloredParallelEff, &minColoredParallelEff, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); + unsigned long maxColoredNumColors = 0; + SU2_MPI::Reduce(&coloredNumColors, &maxColoredNumColors, 1, MPI_UNSIGNED_LONG, MPI_MAX, MASTER_NODE, SU2_MPI::GetComm()); + + unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); + unsigned long minColoredEdgeColorGroupSize = 1 << 30; + SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + if (SU2_MPI::GetRank() == MASTER_NODE) { + cout << "Among the ranks that use edge coloring,\n" + << " the minimum efficiency is " << minColoredParallelEff << ",\n" + << " the maximum number of colors is " << maxColoredNumColors << ",\n" + << " the minimum edge color group size is " << minColoredEdgeColorGroupSize << "." << endl; } } From 8a155914c7065efc8cf70c84284b63f92213db91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 14 Nov 2023 13:32:13 +0100 Subject: [PATCH 07/26] Make adaptive edge color group sizes optional. --- Common/include/geometry/CGeometry.hpp | 6 ++- Common/src/geometry/CGeometry.cpp | 58 ++++++++++++++------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index f81110607252..4af65411cc23 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1720,10 +1720,14 @@ class CGeometry { /*! * \brief Get the edge coloring. * \note This method computes the coloring if that has not been done yet. + * \note Can be instructed to determine and use the maximum edge color group size between 1 and + * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. + * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. * \return Reference to the coloring. */ - const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr); + const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, + bool maximizeEdgeColorGroupSize = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index e912c5aa68fa..ffa6a37585cb 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,7 +3609,7 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3638,41 +3638,45 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - /* find an efficient coloring with maximum possible color group size */ - auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that does not work */ - auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ - auto lowerEdgeColorGroupSize = 1; /* lower bound that is known to work */ + /*--- if requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize) ---*/ + if (maximizeEdgeColorGroupSize) { + auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ + auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ + auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ - while (true) { - auto currentEdgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + while (true) { + auto currentEdgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); - /* if the coloring fails, reduce the color group size */ - if (currentEdgeColoring.empty()) { - upperEdgeColorGroupSize = nextEdgeColorGroupSize; - nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; - continue; - } + /*--- if the coloring fails, reduce the color group size ---*/ + if (currentEdgeColoring.empty()) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + continue; + } - auto currentEfficiency = coloringEfficiency(currentEdgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + su2double currentEfficiency = + coloringEfficiency(currentEdgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); - /* if the coloring is not efficient, reduce the color group size */ - if (currentEfficiency < COLORING_EFF_THRESH) { - upperEdgeColorGroupSize = nextEdgeColorGroupSize; - } - /* otherwise, try to enlarge the color group size */ - else { - lowerEdgeColorGroupSize = nextEdgeColorGroupSize; - } - auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + /*--- if the coloring is not efficient, reduce the color group size ---*/ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + } + /*--- otherwise, try to enlarge the color group size ---*/ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + } + auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; - if (increment == 0) { - break; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + + if (increment == 0) { + break; + } } - nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + edgeColorGroupSize = nextEdgeColorGroupSize; } - edgeColorGroupSize = lowerEdgeColorGroupSize; edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); /*--- If the coloring fails use the natural coloring. This is a From 21a0e4a52d399b7ae43b6eaf8d05b401eeb63cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 14 Nov 2023 13:54:38 +0100 Subject: [PATCH 08/26] Use adaptive edge color group sizes for the discrete adjoint. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 7 +++++++ SU2_CFD/include/solvers/CScalarSolver.inl | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 14368a547d6a..9d701789afc1 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -288,7 +288,14 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi * sum the fluxes for each cell and set the diagonal of the system matrix. ---*/ su2double parallelEff = 1.0; + +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. ---*/ + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true); +#else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); +#endif /*--- The decision to use the strategy is local to each rank. ---*/ ReducerStrategy = parallelEff < COLORING_EFF_THRESH; diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 5b6415d65b06..21eac22ead86 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -46,7 +46,13 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, #ifdef HAVE_OMP /*--- Get the edge coloring, see notes in CEulerSolver's constructor. ---*/ su2double parallelEff = 1.0; +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. ---*/ + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true); +#else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); +#endif ReducerStrategy = parallelEff < COLORING_EFF_THRESH; From d45447ada250c23ef700cf62c920c5e91c031f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 14 Nov 2023 13:56:19 +0100 Subject: [PATCH 09/26] Larger number of colors for the discrete adjoint. --- Common/include/toolboxes/graph_toolbox.hpp | 2 +- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 5 +++-- SU2_CFD/include/solvers/CScalarSolver.inl | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index f1c0854ce27e..c5929e8f8da3 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 9d701789afc1..6d6a76f4ba4a 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -291,8 +291,9 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi #ifdef CODI_REVERSE_TYPE /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color - * group size. Find the maximum edge color group size that yields an efficient coloring. ---*/ - const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true); + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true); #else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); #endif diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 21eac22ead86..3f68ff8d793f 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -48,8 +48,9 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, su2double parallelEff = 1.0; #ifdef CODI_REVERSE_TYPE /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color - * group size. Find the maximum edge color group size that yields an efficient coloring. ---*/ - const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true); + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true); #else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); #endif From f73946b4d7f91d919087f046e95bda933265520c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Wed, 15 Nov 2023 14:27:50 +0100 Subject: [PATCH 10/26] Switch between different numbers of colors. --- Common/include/geometry/CGeometry.hpp | 4 +++- Common/src/geometry/CGeometry.cpp | 16 +++++++++++++--- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 +- SU2_CFD/include/solvers/CScalarSolver.inl | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index 4af65411cc23..fc5c29310751 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1724,10 +1724,12 @@ class CGeometry { * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. + * \param[in] largeNumberOfColors - allow up to 255 colors instead of 64 (default) * \return Reference to the coloring. */ const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, - bool maximizeEdgeColorGroupSize = false); + bool maximizeEdgeColorGroupSize = false, + bool largeNumberOfColors = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index ffa6a37585cb..b88ef3d21981 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,7 +3609,8 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize, + bool largeNumberOfColors) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3638,6 +3639,15 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; + /*--- lambda to account for different numbers of colors ---*/ + auto getColorSparsePattern = [&](unsigned long edgeColorGroupSize) { + if (largeNumberOfColors) { + return colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } else { + return colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } + }; + /*--- if requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize) ---*/ if (maximizeEdgeColorGroupSize) { auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ @@ -3645,7 +3655,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ while (true) { - auto currentEdgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + auto currentEdgeColoring = getColorSparsePattern(nextEdgeColorGroupSize); /*--- if the coloring fails, reduce the color group size ---*/ if (currentEdgeColoring.empty()) { @@ -3677,7 +3687,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien edgeColorGroupSize = nextEdgeColorGroupSize; } - edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + edgeColoring = getColorSparsePattern(edgeColorGroupSize); /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 6d6a76f4ba4a..3710340d0a78 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -293,7 +293,7 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ - const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true, true); #else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); #endif diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 3f68ff8d793f..ea2d69250668 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -50,7 +50,7 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ - const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true, true); #else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); #endif From 3cc21215140d4be6d29d472101c82940e4acabaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Wed, 15 Nov 2023 16:21:56 +0100 Subject: [PATCH 11/26] Further relax hybrid AD python wrapper test tolerances. --- TestCases/hybrid_regression_AD.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index cf419bde4e9b..5ffeb5d71f0c 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -242,7 +242,7 @@ def main(): pywrapper_FEA_AD_FlowLoad.test_vals_aarch64 = [-0.131745, -0.553214, -0.000364, -0.003101] pywrapper_FEA_AD_FlowLoad.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_FEA_AD_FlowLoad.timeout = 1600 - pywrapper_FEA_AD_FlowLoad.tol = 1e-3 + pywrapper_FEA_AD_FlowLoad.tol = 1e-2 pywrapper_FEA_AD_FlowLoad.new_output = False pywrapper_FEA_AD_FlowLoad.enabled_with_tsan = False test_list.append(pywrapper_FEA_AD_FlowLoad) @@ -257,7 +257,7 @@ def main(): pywrapper_CFD_AD_MeshDisp.test_vals_aarch64 = [30.000000, -2.516536, 1.386443, 0.000000] pywrapper_CFD_AD_MeshDisp.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_CFD_AD_MeshDisp.timeout = 1600 - pywrapper_CFD_AD_MeshDisp.tol = 1e-3 + pywrapper_CFD_AD_MeshDisp.tol = 1e-2 pywrapper_CFD_AD_MeshDisp.new_output = False pywrapper_CFD_AD_MeshDisp.enabled_with_tsan = False test_list.append(pywrapper_CFD_AD_MeshDisp) From db1ef8bd4c917ca29305219cc4a647671c4ac46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Thu, 16 Nov 2023 15:46:25 +0100 Subject: [PATCH 12/26] Add config option for discrete adjoint coloring relaxation. --- Common/include/CConfig.hpp | 6 ++++++ Common/src/CConfig.cpp | 3 +++ SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 3 ++- SU2_CFD/include/solvers/CScalarSolver.inl | 3 ++- config_template.cfg | 8 ++++++++ 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index da11f9026067..c59990235151 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -1188,6 +1188,7 @@ class CConfig { string caseName; /*!< \brief Name of the current case */ unsigned long edgeColorGroupSize; /*!< \brief Size of the edge groups colored for OpenMP parallelization of edge loops. */ + bool edgeColoringRelaxDiscAdj; /*!< \brief Allow fallback to smaller edge color group sizes and use more colors for the discrete adjoint. */ INLET_SPANWISE_INTERP Kind_InletInterpolationFunction; /*!brief type of spanwise interpolation function to use for the inlet face. */ INLET_INTERP_TYPE Kind_Inlet_InterpolationType; /*!brief type of spanwise interpolation data to use for the inlet face. */ @@ -9738,6 +9739,11 @@ class CConfig { */ unsigned long GetEdgeColoringGroupSize(void) const { return edgeColorGroupSize; } + /*! + * \brief Check if the discrete adjoint is allowed to relax the coloring, that is, allow smaller edge color group sizes and allow more colors. + */ + bool GetEdgeColoringRelaxDiscAdj(void) const { return edgeColoringRelaxDiscAdj; } + /*! * \brief Get the ParMETIS load balancing tolerance. */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index a34902142cf4..2a82d959af75 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -2952,6 +2952,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); + /* DESCRIPTION: Allow fallback to smaller edge color group sizes for the discrete adjoint and allow more colors. */ + addBoolOption("EDGE_COLORING_RELAX_DISC_ADJ", edgeColoringRelaxDiscAdj, true); + /*--- options that are used for libROM ---*/ /*!\par CONFIG_CATEGORY:libROM options \ingroup Config*/ diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 3710340d0a78..db39cde78c0b 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -293,7 +293,8 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ - const auto& coloring = geometry.GetEdgeColoring(¶llelEff, true, true); + const bool relax = config.GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax, relax); #else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); #endif diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index ea2d69250668..d9f17d17e7b6 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -50,7 +50,8 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ - const auto& coloring = geometry->GetEdgeColoring(¶llelEff, true, true); + const bool relax = config->GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax, relax); #else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); #endif diff --git a/config_template.cfg b/config_template.cfg index 774d55875e8b..ff2862f3924c 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -1680,6 +1680,14 @@ UQ_DELTA_B= 1.0 % The optimum value/strategy is case-dependent. EDGE_COLORING_GROUP_SIZE= 512 % +% Coloring tends to perform better for the discrete adjoint than reductions because +% it uses less memory and enables the shared reading optimization for color loops. +% This option allows an automatic fallback to smaller edge color group sizes on ranks +% where the requested edge color group size is not efficient. Specifically, the largest +% edge color group size up to EDGE_COLORING_GROUP_SIZE is chosen that is at least +% 0.875 efficient. Also, this option allows using more colors, up to 255 instead of up to 64. +EDGE_COLORING_RELAX_DISC_ADJ= yes +% % Independent "threads per MPI rank" setting for LU-SGS and ILU preconditioners. % For problems where time is spend mostly in the solution of linear systems (e.g. elasticity, % very high CFL central schemes), AND, if the memory bandwidth of the machine is saturated From 88b127224064d6578d17b456a6f98aa2337ea9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Fri, 17 Nov 2023 13:43:15 +0100 Subject: [PATCH 13/26] Avoid void. --- Common/include/CConfig.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index c59990235151..2cb959fc3fc0 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -9742,7 +9742,7 @@ class CConfig { /*! * \brief Check if the discrete adjoint is allowed to relax the coloring, that is, allow smaller edge color group sizes and allow more colors. */ - bool GetEdgeColoringRelaxDiscAdj(void) const { return edgeColoringRelaxDiscAdj; } + bool GetEdgeColoringRelaxDiscAdj() const { return edgeColoringRelaxDiscAdj; } /*! * \brief Get the ParMETIS load balancing tolerance. From c6681e4e4a2cdfe9186916e2750dae65fa797dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Wed, 22 Nov 2023 14:10:22 +0100 Subject: [PATCH 14/26] Capitalization. --- config_template.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config_template.cfg b/config_template.cfg index de4cf72416e3..ea621b85e7e5 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -2146,7 +2146,7 @@ EDGE_COLORING_GROUP_SIZE= 512 % where the requested edge color group size is not efficient. Specifically, the largest % edge color group size up to EDGE_COLORING_GROUP_SIZE is chosen that is at least % 0.875 efficient. Also, this option allows using more colors, up to 255 instead of up to 64. -EDGE_COLORING_RELAX_DISC_ADJ= yes +EDGE_COLORING_RELAX_DISC_ADJ= YES % % Independent "threads per MPI rank" setting for LU-SGS and ILU preconditioners. % For problems where time is spend mostly in the solution of linear systems (e.g. elasticity, From 35fb9d2f9ee6dfc06c4a06d782a5cade1c954ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Thu, 30 Nov 2023 19:22:27 +0100 Subject: [PATCH 15/26] No output if all ranks use the reducer strategy. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index db39cde78c0b..fd2eb13328f1 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -351,7 +351,7 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi unsigned long minColoredEdgeColorGroupSize = 1 << 30; SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); - if (SU2_MPI::GetRank() == MASTER_NODE) { + if (SU2_MPI::GetRank() == MASTER_NODE && numRanksUsingReducer != SU2_MPI::GetSize()) { cout << "Among the ranks that use edge coloring,\n" << " the minimum efficiency is " << minColoredParallelEff << ",\n" << " the maximum number of colors is " << maxColoredNumColors << ",\n" From 90bc63b15fffa0b64903891d82fcdcdd8ec640d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= <55186095+jblueh@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:28:19 +0100 Subject: [PATCH 16/26] Update Common/src/geometry/CGeometry.cpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- Common/src/geometry/CGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index b88ef3d21981..fd6b2c92bd4e 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3639,7 +3639,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - /*--- lambda to account for different numbers of colors ---*/ + /*--- Lambda to account for different numbers of colors. ---*/ auto getColorSparsePattern = [&](unsigned long edgeColorGroupSize) { if (largeNumberOfColors) { return colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); From 39168b58e021e25b29ff148762389d8af3913df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Fri, 1 Dec 2023 16:36:33 +0100 Subject: [PATCH 17/26] Add const. --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index fd2eb13328f1..2f86931ac2b5 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -339,15 +339,15 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi } } - su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; + const su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; su2double minColoredParallelEff = 1.0; SU2_MPI::Reduce(&coloredParallelEff, &minColoredParallelEff, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); - unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); + const unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); unsigned long maxColoredNumColors = 0; SU2_MPI::Reduce(&coloredNumColors, &maxColoredNumColors, 1, MPI_UNSIGNED_LONG, MPI_MAX, MASTER_NODE, SU2_MPI::GetComm()); - unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); + const unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); unsigned long minColoredEdgeColorGroupSize = 1 << 30; SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); From e6ac3dbb06a6ca80ba81ef4f11be8f809b9b7e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Fri, 1 Dec 2023 16:43:52 +0100 Subject: [PATCH 18/26] More const. --- Common/src/geometry/CGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index fd6b2c92bd4e..eaafe9d49b55 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3664,7 +3664,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien continue; } - su2double currentEfficiency = + const su2double currentEfficiency = coloringEfficiency(currentEdgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); /*--- if the coloring is not efficient, reduce the color group size ---*/ From 09efb1ae7614fd988ddc83e9c8dd8c6b3fc39863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Fri, 1 Dec 2023 18:06:32 +0100 Subject: [PATCH 19/26] Increase the default number of colors. --- Common/include/geometry/CGeometry.hpp | 4 +--- Common/include/toolboxes/graph_toolbox.hpp | 2 +- Common/src/geometry/CGeometry.cpp | 18 ++++-------------- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 +- SU2_CFD/include/solvers/CScalarSolver.inl | 2 +- 5 files changed, 8 insertions(+), 20 deletions(-) diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index fc5c29310751..4af65411cc23 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1724,12 +1724,10 @@ class CGeometry { * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. - * \param[in] largeNumberOfColors - allow up to 255 colors instead of 64 (default) * \return Reference to the coloring. */ const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, - bool maximizeEdgeColorGroupSize = false, - bool largeNumberOfColors = false); + bool maximizeEdgeColorGroupSize = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index c5929e8f8da3..f1c0854ce27e 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index eaafe9d49b55..08d81daf59f0 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,8 +3609,7 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize, - bool largeNumberOfColors) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3639,15 +3638,6 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - /*--- Lambda to account for different numbers of colors. ---*/ - auto getColorSparsePattern = [&](unsigned long edgeColorGroupSize) { - if (largeNumberOfColors) { - return colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); - } else { - return colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); - } - }; - /*--- if requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize) ---*/ if (maximizeEdgeColorGroupSize) { auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ @@ -3655,7 +3645,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ while (true) { - auto currentEdgeColoring = getColorSparsePattern(nextEdgeColorGroupSize); + const auto currentEdgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); /*--- if the coloring fails, reduce the color group size ---*/ if (currentEdgeColoring.empty()) { @@ -3675,7 +3665,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien else { lowerEdgeColorGroupSize = nextEdgeColorGroupSize; } - auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; @@ -3687,7 +3677,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien edgeColorGroupSize = nextEdgeColorGroupSize; } - edgeColoring = getColorSparsePattern(edgeColorGroupSize); + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 2f86931ac2b5..c2af5a18d825 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -294,7 +294,7 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ const bool relax = config.GetEdgeColoringRelaxDiscAdj(); - const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax, relax); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax); #else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); #endif diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index d9f17d17e7b6..343944ebd6c6 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -51,7 +51,7 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers * of colors. ---*/ const bool relax = config->GetEdgeColoringRelaxDiscAdj(); - const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax, relax); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax); #else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); #endif From 224c5017cf3272f2121c7719d7973cb0bde1f856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 18:11:58 +0100 Subject: [PATCH 20/26] Avoid recomputation of final coloring. --- Common/src/geometry/CGeometry.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 08d81daf59f0..a3e92cf70458 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3645,17 +3645,17 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ while (true) { - const auto currentEdgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + const auto edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); /*--- if the coloring fails, reduce the color group size ---*/ - if (currentEdgeColoring.empty()) { + if (edgeColoring.empty()) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; continue; } const su2double currentEfficiency = - coloringEfficiency(currentEdgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); /*--- if the coloring is not efficient, reduce the color group size ---*/ if (currentEfficiency < COLORING_EFF_THRESH) { @@ -3675,10 +3675,10 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien } edgeColorGroupSize = nextEdgeColorGroupSize; + } else { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); } - edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); - /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected * downstream and a fallback strategy put in place. ---*/ From df30b2f0fc6dd7461cfedab7bcb27e0ad71da30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 18:12:52 +0100 Subject: [PATCH 21/26] Fix edge color group size. --- Common/src/geometry/CGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index a3e92cf70458..b603786dcaf0 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3645,7 +3645,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ while (true) { - const auto edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + const auto edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); /*--- if the coloring fails, reduce the color group size ---*/ if (edgeColoring.empty()) { From 81f834b2ddd708d655a8b0f6598797458e28c23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 18:55:02 +0100 Subject: [PATCH 22/26] Comment formatting. --- Common/src/geometry/CGeometry.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index b603786dcaf0..58fbfc42da6e 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3638,7 +3638,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - /*--- if requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize) ---*/ + /*--- If requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize). ---*/ if (maximizeEdgeColorGroupSize) { auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ @@ -3647,7 +3647,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien while (true) { const auto edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); - /*--- if the coloring fails, reduce the color group size ---*/ + /*--- If the coloring fails, reduce the color group size. ---*/ if (edgeColoring.empty()) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; @@ -3657,11 +3657,11 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien const su2double currentEfficiency = coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); - /*--- if the coloring is not efficient, reduce the color group size ---*/ + /*--- If the coloring is not efficient, reduce the color group size. ---*/ if (currentEfficiency < COLORING_EFF_THRESH) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; } - /*--- otherwise, try to enlarge the color group size ---*/ + /*--- Otherwise, enlarge the color group size. ---*/ else { lowerEdgeColorGroupSize = nextEdgeColorGroupSize; } From 799c9bb5555928091182f381d78b39799c5fc0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 19:00:20 +0100 Subject: [PATCH 23/26] Ensure that failed colorings reach the terminating condition. --- Common/src/geometry/CGeometry.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 58fbfc42da6e..a2b02ac27f92 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3650,23 +3650,23 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- If the coloring fails, reduce the color group size. ---*/ if (edgeColoring.empty()) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; - nextEdgeColorGroupSize = lowerEdgeColorGroupSize + (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; - continue; } - - const su2double currentEfficiency = - coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); - - /*--- If the coloring is not efficient, reduce the color group size. ---*/ - if (currentEfficiency < COLORING_EFF_THRESH) { - upperEdgeColorGroupSize = nextEdgeColorGroupSize; - } - /*--- Otherwise, enlarge the color group size. ---*/ + /*--- If the coloring succeeds, check the efficiency. ---*/ else { - lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + const su2double currentEfficiency = + coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + + /*--- If the coloring is not efficient, reduce the color group size. ---*/ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + } + /*--- Otherwise, enlarge the color group size. ---*/ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + } } - const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; if (increment == 0) { From de3b94e24b9c088067a47ae68454a80e133c41ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 19:03:17 +0100 Subject: [PATCH 24/26] Add comment. --- Common/src/geometry/CGeometry.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index a2b02ac27f92..404ff102c56b 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3669,6 +3669,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + /*--- Terminating condition. ---*/ if (increment == 0) { break; } From de941f3f28ba084bd09aabce9bf580ab29dd921f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Tue, 5 Dec 2023 19:17:24 +0100 Subject: [PATCH 25/26] Use member variable directly. --- Common/src/geometry/CGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 404ff102c56b..5ce438a33a8f 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3645,7 +3645,7 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ while (true) { - const auto edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); /*--- If the coloring fails, reduce the color group size. ---*/ if (edgeColoring.empty()) { From aec3aabae4539192154ad2cd6c47932ea4c0e504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bl=C3=BChdorn?= Date: Wed, 6 Dec 2023 16:46:10 +0100 Subject: [PATCH 26/26] Avoid recomputation if last coloring was admissible. --- Common/src/geometry/CGeometry.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 5ce438a33a8f..aeca64217636 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3644,12 +3644,15 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ + bool admissibleColoring = false; /* keep track wether the last tested coloring is admissible */ + while (true) { edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); /*--- If the coloring fails, reduce the color group size. ---*/ if (edgeColoring.empty()) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; } /*--- If the coloring succeeds, check the efficiency. ---*/ else { @@ -3659,10 +3662,12 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- If the coloring is not efficient, reduce the color group size. ---*/ if (currentEfficiency < COLORING_EFF_THRESH) { upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; } /*--- Otherwise, enlarge the color group size. ---*/ else { lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = true; } } @@ -3676,7 +3681,14 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien } edgeColorGroupSize = nextEdgeColorGroupSize; - } else { + + /*--- If the last tested coloring was not admissible, recompute the final coloring. ---*/ + if (!admissibleColoring) { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } + } + /*--- No adaptivity. ---*/ + else { edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); }