From 1777e781e7807446035f4aca446f64eb9ebba369 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Mon, 13 Jan 2025 15:24:56 -0700 Subject: [PATCH] MueLu UncoupledAggregationFactory: Add hidden option "aggregation: backend" The option allows to select the aggregation code path: - "default": do whatever matches the input graph, - "host": old, host-only aggregation code path, - "kokkos": Kokkos code path. Signed-off-by: Christian Glusa --- packages/muelu/doc/UsersGuide/masterList.xml | 9 +++ .../muelu/doc/UsersGuide/paramlist_hidden.tex | 2 + .../Graph/Containers/MueLu_LWGraph_decl.hpp | 3 + .../Graph/Containers/MueLu_LWGraph_def.hpp | 25 +++++++++ .../MueLu_UncoupledAggregationFactory_def.hpp | 55 +++++++++++++++---- .../MueLu_ParameterListInterpreter_def.hpp | 10 ++-- .../muelu/src/MueCentral/MueLu_MasterList.cpp | 3 + .../Output/operator_solve_1_np1_tpetra.gold | 3 + .../Output/operator_solve_1_np4_tpetra.gold | 3 + .../Output/operator_solve_5_np1_tpetra.gold | 2 + .../Output/operator_solve_5_np4_tpetra.gold | 2 + .../Output/operator_solve_6_np1_tpetra.gold | 2 + .../Output/operator_solve_6_np4_tpetra.gold | 2 + 13 files changed, 105 insertions(+), 16 deletions(-) diff --git a/packages/muelu/doc/UsersGuide/masterList.xml b/packages/muelu/doc/UsersGuide/masterList.xml index 04b1d385cd71..de556ee82fdf 100644 --- a/packages/muelu/doc/UsersGuide/masterList.xml +++ b/packages/muelu/doc/UsersGuide/masterList.xml @@ -376,6 +376,15 @@ + + aggregation: backend + string + "default" + Aggregation scheme. Possible values: "default", "host", "kokkos" + false + parameter not existing in ML + + aggregation: type string diff --git a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex index 29a87f236d62..3129ac57ee43 100644 --- a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex +++ b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex @@ -62,6 +62,8 @@ \cbb{coarse: overlap}{int}{0}{Coarse solver subdomain overlap.} +\cbb{aggregation: backend}{string}{"default"}{Aggregation scheme. Possible values: "default", "host", "kokkos"} + \cbb{aggregation: type}{string}{"uncoupled"}{Aggregation scheme. Possible values: see Table~\ref{t:aggregation}.} \cbb{aggregation: mode}{string}{"uncoupled"}{Controls whether aggregates are allowed to cross processor boundaries. Possible values: "coupled" aggregates can cross processor boundaries, "uncoupled" aggregates cannot cross processor boundaries.} diff --git a/packages/muelu/src/Graph/Containers/MueLu_LWGraph_decl.hpp b/packages/muelu/src/Graph/Containers/MueLu_LWGraph_decl.hpp index d229903bd6a5..6775fac4f1e2 100644 --- a/packages/muelu/src/Graph/Containers/MueLu_LWGraph_decl.hpp +++ b/packages/muelu/src/Graph/Containers/MueLu_LWGraph_decl.hpp @@ -15,6 +15,7 @@ #include "MueLu_LWGraph_fwd.hpp" #include "MueLu_LWGraphBase.hpp" +#include "MueLu_LWGraph_kokkos_fwd.hpp" namespace MueLu { @@ -32,6 +33,8 @@ template { public: using LWGraphBase::LWGraphBase; + + RCP > copyToDevice(); }; } // namespace MueLu diff --git a/packages/muelu/src/Graph/Containers/MueLu_LWGraph_def.hpp b/packages/muelu/src/Graph/Containers/MueLu_LWGraph_def.hpp index 8600be87d667..c11784d7b8d2 100644 --- a/packages/muelu/src/Graph/Containers/MueLu_LWGraph_def.hpp +++ b/packages/muelu/src/Graph/Containers/MueLu_LWGraph_def.hpp @@ -10,10 +10,35 @@ #ifndef MUELU_LWGRAPH_DEF_HPP #define MUELU_LWGRAPH_DEF_HPP +#include "MueLu_LWGraph_kokkos.hpp" #include "MueLu_LWGraph_decl.hpp" namespace MueLu { +template +RCP > MueLu::LWGraph::copyToDevice() { + auto graph = this->getGraph(); + + auto row_map_d = Kokkos::create_mirror_view(graph.row_map); + auto entries_d = Kokkos::create_mirror_view(graph.entries); + Kokkos::deep_copy(row_map_d, graph.row_map); + Kokkos::deep_copy(entries_d, graph.entries); + + using local_graph_type_device = typename MueLu::LWGraphBase::local_graph_type; + auto graph_d = local_graph_type_device(entries_d, row_map_d); + + auto lw_d = rcp(new MueLu::LWGraph_kokkos(graph_d, this->GetDomainMap(), this->GetImportMap(), this->getObjectLabel())); + + using bndry_nodes_type = typename MueLu::LWGraphBase::boundary_nodes_type; + + auto bndry = this->GetBoundaryNodeMap(); + auto bndry_d = bndry_nodes_type("boundary_nodes", bndry.extent(0)); + Kokkos::deep_copy(bndry_d, bndry); + lw_d->SetBoundaryNodeMap(bndry_d); + + return lw_d; +} + } // namespace MueLu #endif // MUELU_LWGRAPH_DEF_HPP diff --git a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp index 170506f48d39..1c8aebe78005 100644 --- a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp +++ b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp @@ -76,6 +76,8 @@ RCP UncoupledAggregationFactorygetEntry("aggregation: backend").setValidator(rcp(new Teuchos::StringValidator(Teuchos::tuple("default", "host", "kokkos")))); #undef SET_VALID_ENTRY // general variables needed in AggregationFactory @@ -175,20 +177,53 @@ void UncoupledAggregationFactory::Build(Level RCP aggregates; RCP> comm; LO numRows; + + const std::string aggregationBackend = pL.get("aggregation: backend"); + + // "Graph" can have type "LWGraph" or "LWGraph_kokkos". + // The aggregation phases can call either "BuildAggregatesNonKokkos" or "BuildAggregates". + + // "aggregation: backend" can take values "default", "non-Kokkos" or "Kokkos". + // "default": run depending on the type of "Graph" + // "non-Kokkos": run the non-Kokkos aggregation, moving "Graph" to host if necessary + // "Kokkos": run the Kokkos aggregation, potentially move "Graph", moving "Graph" to device if necessary + bool runOnHost; if (IsType>(currentLevel, "Graph")) { - graph = Get>(currentLevel, "Graph"); - aggregates = rcp(new Aggregates(*graph)); - comm = graph->GetComm(); - numRows = graph->GetNodeNumVertices(); - runOnHost = true; + if ((aggregationBackend == "default") || (aggregationBackend == "non-Kokkos")) { + graph = Get>(currentLevel, "Graph"); + aggregates = rcp(new Aggregates(*graph)); + comm = graph->GetComm(); + numRows = graph->GetNodeNumVertices(); + runOnHost = true; + } else { + RCP tmp_graph = Get>(currentLevel, "Graph"); + graph_kokkos = tmp_graph->copyToDevice(); + aggregates = rcp(new Aggregates(*graph_kokkos)); + comm = graph_kokkos->GetComm(); + numRows = graph_kokkos->GetNodeNumVertices(); + runOnHost = false; + } + } else if (IsType>(currentLevel, "Graph")) { + if ((aggregationBackend == "default") || (aggregationBackend == "Kokkos")) { + graph_kokkos = Get>(currentLevel, "Graph"); + aggregates = rcp(new Aggregates(*graph_kokkos)); + comm = graph_kokkos->GetComm(); + numRows = graph_kokkos->GetNodeNumVertices(); + runOnHost = false; + } else { + RCP tmp_graph_kokkos = Get>(currentLevel, "Graph"); + graph = tmp_graph_kokkos->copyToHost(); + aggregates = rcp(new Aggregates(*graph)); + comm = graph->GetComm(); + numRows = graph->GetNodeNumVertices(); + runOnHost = true; + } } else { - graph_kokkos = Get>(currentLevel, "Graph"); - aggregates = rcp(new Aggregates(*graph_kokkos)); - comm = graph_kokkos->GetComm(); - numRows = graph_kokkos->GetNodeNumVertices(); - runOnHost = false; + TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Graph has bad type."); + } + if (!runOnHost) { TEUCHOS_TEST_FOR_EXCEPTION(pL.get("aggregation: use interface aggregation"), std::invalid_argument, "Option: 'aggregation: use interface aggregation' is not supported in the Kokkos version of uncoupled aggregation"); // Sanity Checking: match ML behavior is not supported in UncoupledAggregation_Kokkos in Phase 1 , but it is in 2a and 2b TEUCHOS_TEST_FOR_EXCEPTION(pL.get("aggregation: match ML phase1"), std::invalid_argument, "Option: 'aggregation: match ML phase1' is not supported in the Kokkos version of uncoupled aggregation"); diff --git a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp index 69a0d55a4280..2f082b4195b3 100644 --- a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp @@ -1099,12 +1099,10 @@ void ParameterListInterpreter:: MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: min agg size", int, aggParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: max agg size", int, aggParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: max selected neighbors", int, aggParams); - if (useKokkos_) { - // if not using kokkos refactor Uncoupled, there is no algorithm option (always Serial) - MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: phase 1 algorithm", std::string, aggParams); - MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: deterministic", bool, aggParams); - MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: coloring algorithm", std::string, aggParams); - } + MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: backend", std::string, aggParams); + MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: phase 1 algorithm", std::string, aggParams); + MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: deterministic", bool, aggParams); + MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: coloring algorithm", std::string, aggParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: enable phase 1", bool, aggParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: enable phase 2a", bool, aggParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: enable phase 2b", bool, aggParams); diff --git a/packages/muelu/src/MueCentral/MueLu_MasterList.cpp b/packages/muelu/src/MueCentral/MueLu_MasterList.cpp index 30c1d8176ddc..f2e040c8cb9a 100644 --- a/packages/muelu/src/MueCentral/MueLu_MasterList.cpp +++ b/packages/muelu/src/MueCentral/MueLu_MasterList.cpp @@ -164,6 +164,7 @@ namespace MueLu { "" "" "" + "" "" "" "" @@ -597,6 +598,8 @@ namespace MueLu { ("coarse: overlap","coarse: overlap") + ("aggregation: backend","aggregation: backend") + ("aggregation: type","aggregation: type") ("aggregation: mode","aggregation: mode") diff --git a/packages/muelu/test/interface/default/Output/operator_solve_1_np1_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_1_np1_tpetra.gold index 034946edf632..101a2513fe71 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_1_np1_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_1_np1_tpetra.gold @@ -24,6 +24,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) @@ -60,6 +61,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) @@ -96,6 +98,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) diff --git a/packages/muelu/test/interface/default/Output/operator_solve_1_np4_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_1_np4_tpetra.gold index a85f68f15ce0..b24be8a53ef1 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_1_np4_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_1_np4_tpetra.gold @@ -24,6 +24,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) @@ -60,6 +61,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) @@ -96,6 +98,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) diff --git a/packages/muelu/test/interface/default/Output/operator_solve_5_np1_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_5_np1_tpetra.gold index 17c0f097f0fe..4e14b58460ba 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_5_np1_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_5_np1_tpetra.gold @@ -35,6 +35,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Build (MueLu::CoarseMapFactory) matrixmatrix: kernel params -> [empty list] @@ -69,6 +70,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) diff --git a/packages/muelu/test/interface/default/Output/operator_solve_5_np4_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_5_np4_tpetra.gold index 0aa423687a22..00ff22903ebd 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_5_np4_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_5_np4_tpetra.gold @@ -35,6 +35,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Build (MueLu::CoarseMapFactory) matrixmatrix: kernel params -> [empty list] @@ -69,6 +70,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) diff --git a/packages/muelu/test/interface/default/Output/operator_solve_6_np1_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_6_np1_tpetra.gold index a7977126fef5..5b5c6de6d91e 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_6_np1_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_6_np1_tpetra.gold @@ -39,6 +39,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Build (MueLu::CoarseMapFactory) matrixmatrix: kernel params -> [empty list] @@ -74,6 +75,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory) diff --git a/packages/muelu/test/interface/default/Output/operator_solve_6_np4_tpetra.gold b/packages/muelu/test/interface/default/Output/operator_solve_6_np4_tpetra.gold index b3a587461679..bfc80e8f5450 100644 --- a/packages/muelu/test/interface/default/Output/operator_solve_6_np4_tpetra.gold +++ b/packages/muelu/test/interface/default/Output/operator_solve_6_np4_tpetra.gold @@ -39,6 +39,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Build (MueLu::CoarseMapFactory) matrixmatrix: kernel params -> [empty list] @@ -74,6 +75,7 @@ BuildAggregatesNonKokkos (Phase 1 (main)) BuildAggregatesNonKokkos (Phase 2a (secondary)) BuildAggregatesNonKokkos (Phase 2b (expansion)) BuildAggregatesNonKokkos (Phase 3 (cleanup)) +aggregation: deterministic = 0 [unused] Nullspace factory (MueLu::NullspaceFactory) Fine level nullspace = Nullspace Build (MueLu::CoarseMapFactory)