47 #ifndef PACKAGES_MUELU_SRC_REBALANCING_MUELU_REPARTITIONHEURISTICFACTORY_DEF_HPP_
48 #define PACKAGES_MUELU_SRC_REBALANCING_MUELU_REPARTITIONHEURISTICFACTORY_DEF_HPP_
56 #include <Teuchos_CommHelpers.hpp>
61 #include "MueLu_Utilities.hpp"
63 #include "MueLu_RAPFactory.hpp"
64 #include "MueLu_BlockedRAPFactory.hpp"
65 #include "MueLu_SubBlockAFactory.hpp"
70 #include "MueLu_RepartitionHeuristicFactory.hpp"
74 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
78 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
83 #undef SET_VALID_ENTRY
87 return validParamList;
90 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
92 Input(currentLevel,
"A");
95 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102 const int startLevel = pL.
get<
int> (
"repartition: start level");
103 const LO minRowsPerProcess = pL.
get<
LO> (
"repartition: min rows per proc");
104 LO targetRowsPerProcess = pL.
get<
LO> (
"repartition: target rows per proc");
105 const double nonzeroImbalance = pL.
get<
double>(
"repartition: max imbalance");
107 if (targetRowsPerProcess == 0)
108 targetRowsPerProcess = minRowsPerProcess;
111 if(!Afact.
is_null() && Teuchos::rcp_dynamic_cast<const RAPFactory>(Afact) == Teuchos::null &&
112 Teuchos::rcp_dynamic_cast<const BlockedRAPFactory>(Afact) == Teuchos::null &&
113 Teuchos::rcp_dynamic_cast<const SubBlockAFactory>(Afact) == Teuchos::null) {
115 "MueLu::RepartitionHeuristicFactory::Build: The generation factory for A must " \
116 "be a RAPFactory or a SubBlockAFactory providing the non-rebalanced matrix information! " \
117 "It specifically must not be of type Rebalance(Blocked)AcFactory or similar. " \
118 "Please check the input. Make also sure that \"number of partitions\" is provided to " \
119 "the Interface class and the RepartitionFactory instance. Instead, we have a "<<Afact->
description() << std::endl;
122 RCP<Matrix> A = Get< RCP<Matrix> >(currentLevel,
"A");
132 if (currentLevel.GetLevelID() < startLevel) {
133 GetOStream(
Statistics1) <<
"Repartitioning? NO:" <<
135 ", first level where repartitioning can happen is " +
Teuchos::toString(startLevel) << std::endl;
138 Set(currentLevel,
"number of partitions", -1);
152 int numActiveProcesses = 0;
153 MueLu_sumAll(comm, Teuchos::as<int>((A->getNodeNumRows() > 0) ? 1 : 0), numActiveProcesses);
155 if (numActiveProcesses == 1) {
156 GetOStream(
Statistics1) <<
"Repartitioning? NO:" <<
157 "\n # processes with rows = " <<
Teuchos::toString(numActiveProcesses) << std::endl;
159 Set(currentLevel,
"number of partitions", 1);
164 bool test3 =
false, test4 =
false;
165 std::string msg3, msg4;
169 if (minRowsPerProcess > 0) {
171 LO haveFewRows = (numMyRows < minRowsPerProcess ? 1 : 0), numWithFewRows = 0;
173 MueLu_minAll(comm, (numMyRows > 0 ? numMyRows : LOMAX), minNumRows);
178 if (numWithFewRows > 0)
186 GO minNnz, maxNnz, numMyNnz = Teuchos::as<GO>(A->getNodeNumEntries());
188 MueLu_minAll(comm, (numMyNnz > 0 ? numMyNnz : maxNnz), minNnz);
189 double imbalance = Teuchos::as<double>(maxNnz)/minNnz;
191 if (imbalance > nonzeroImbalance)
197 if (!test3 && !test4) {
198 GetOStream(
Statistics1) <<
"Repartitioning? NO:" << msg3 + msg4 << std::endl;
201 Set(currentLevel,
"number of partitions", -1);
205 GetOStream(
Statistics1) <<
"Repartitioning? YES:" << msg3 + msg4 << std::endl;
218 const auto globalNumRows = Teuchos::as<GO>(A->getGlobalNumRows());
219 int numPartitions = 1;
220 if (globalNumRows >= targetRowsPerProcess) {
223 int thread_per_mpi_rank = 1;
224 #if defined(HAVE_MUELU_KOKKOSCORE) && defined(KOKKOS_ENABLE_OPENMP)
225 using execution_space =
typename Node::device_type::execution_space;
226 if (std::is_same<execution_space, Kokkos::OpenMP>::value)
227 thread_per_mpi_rank = execution_space::concurrency();
230 numPartitions = std::max(Teuchos::as<int>(globalNumRows / (targetRowsPerProcess * thread_per_mpi_rank)), 1);
232 numPartitions = std::min(numPartitions, comm->getSize());
234 Set(currentLevel,
"number of partitions", numPartitions);
236 GetOStream(
Statistics1) <<
"Number of partitions to use = " << numPartitions << std::endl;
240 #endif //ifdef HAVE_MPI