105 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> xdMV;
107 const ParameterList& pL = GetParameterList();
109 RCP<Matrix> originalP = Get<RCP<Matrix> >(coarseLevel,
"P");
112 if (originalP == Teuchos::null) {
113 Set(coarseLevel,
"P", originalP);
116 int implicit = !pL.get<
bool>(
"repartition: rebalance P and R");
117 int reallyExplicit = pL.get<
bool>(
"repartition: explicit via new copy rebalance P and R");
118 int writeStart = pL.get<
int>(
"write start");
119 int writeEnd = pL.get<
int>(
"write end");
121 if (writeStart == 0 && fineLevel.
GetLevelID() == 0 && writeStart <= writeEnd && IsAvailable(fineLevel,
"Coordinates")) {
122 std::string fileName =
"coordinates_level_0.m";
123 RCP<xdMV> fineCoords = fineLevel.
Get<RCP<xdMV> >(
"Coordinates");
124 if (fineCoords != Teuchos::null)
125 Xpetra::IO<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Write(fileName, *fineCoords);
128 if (writeStart == 0 && fineLevel.
GetLevelID() == 0 && writeStart <= writeEnd && IsAvailable(fineLevel,
"BlockNumber")) {
129 std::string fileName =
"BlockNumber_level_0.m";
130 RCP<LocalOrdinalVector> fineBlockNumber = fineLevel.
Get<RCP<LocalOrdinalVector> >(
"BlockNumber");
131 if (fineBlockNumber != Teuchos::null)
132 Xpetra::IO<SC, LO, GO, NO>::WriteLOMV(fileName, *fineBlockNumber);
135 RCP<const Import> importer = Get<RCP<const Import> >(coarseLevel,
"Importer");
141 RCP<ParameterList> params = rcp(
new ParameterList());
143 params->set(
"printLoadBalancingInfo",
true);
144 params->set(
"printCommInfo",
true);
147 std::string transferType = pL.get<std::string>(
"type");
148 if (transferType ==
"Interpolation") {
149 originalP = Get<RCP<Matrix> >(coarseLevel,
"P");
153 if (implicit || importer.is_null()) {
154 GetOStream(
Runtime0) <<
"Using original prolongator" << std::endl;
155 Set(coarseLevel,
"P", originalP);
182 RCP<Matrix> rebalancedP;
183 if (reallyExplicit) {
184 size_t totalMaxPerRow = 0;
185 ArrayRCP<size_t> nnzPerRow(originalP->getRowMap()->getLocalNumElements(), 0);
186 for (
size_t i = 0; i < originalP->getRowMap()->getLocalNumElements(); ++i) {
187 nnzPerRow[i] = originalP->getNumEntriesInLocalRow(i);
188 if (nnzPerRow[i] > totalMaxPerRow) totalMaxPerRow = nnzPerRow[i];
191 rebalancedP = MatrixFactory::Build(originalP->getRowMap(), totalMaxPerRow);
194 RCP<Import> trivialImporter = ImportFactory::Build(originalP->getRowMap(), originalP->getRowMap());
196 std::string monitorLabel{
"Rebalancing prolongator -- import only"};
197 if (
auto sendType = pL.get<std::string>(
"repartition: send type"); sendType !=
"") {
198 auto sendTypeList = Teuchos::rcp(
new Teuchos::ParameterList());
199 sendTypeList->set(
"Send type", sendType);
200 trivialImporter->setDistributorParameters(sendTypeList);
201 monitorLabel +=
" [" + sendType +
"]";
205 rebalancedP->doImport(*originalP, *trivialImporter, Xpetra::INSERT);
207 rebalancedP->fillComplete(importer->getTargetMap(), originalP->getRangeMap());
210 rebalancedP = originalP;
211 RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(originalP);
212 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null,
Exceptions::BadCast,
"Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
214 RCP<CrsMatrix> rebalancedP2 = crsOp->getCrsMatrix();
215 TEUCHOS_TEST_FOR_EXCEPTION(rebalancedP2 == Teuchos::null, std::runtime_error,
"Xpetra::CrsMatrixWrap doesn't have a CrsMatrix");
218 SubFactoryMonitor subM(*
this,
"Rebalancing prolongator -- fast map replacement", coarseLevel);
220 RCP<const Import> newImporter;
223 newImporter = ImportFactory::Build(importer->getTargetMap(), rebalancedP->getColMap());
225 rebalancedP2->replaceDomainMapAndImporter(importer->getTargetMap(), newImporter);
234 if (!rebalancedP.is_null()) {
235 std::ostringstream oss;
236 oss <<
"P_" << coarseLevel.GetLevelID();
237 rebalancedP->setObjectLabel(oss.str());
239 Set(coarseLevel,
"P", rebalancedP);
246 if (importer.is_null()) {
247 if (IsAvailable(coarseLevel,
"Nullspace"))
248 Set(coarseLevel,
"Nullspace", Get<RCP<MultiVector> >(coarseLevel,
"Nullspace"));
250 if (pL.isParameter(
"Coordinates") && pL.get<RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null)
251 if (IsAvailable(coarseLevel,
"Coordinates"))
252 Set(coarseLevel,
"Coordinates", Get<RCP<xdMV> >(coarseLevel,
"Coordinates"));
254 if (pL.isParameter(
"Material") && pL.get<RCP<const FactoryBase> >(
"Material") != Teuchos::null)
255 if (IsAvailable(coarseLevel,
"Material"))
256 Set(coarseLevel,
"Material", Get<RCP<MultiVector> >(coarseLevel,
"Material"));
258 if (pL.isParameter(
"BlockNumber") && pL.get<RCP<const FactoryBase> >(
"BlockNumber") != Teuchos::null)
259 if (IsAvailable(coarseLevel,
"BlockNumber"))
260 Set(coarseLevel,
"BlockNumber", Get<RCP<LocalOrdinalVector> >(coarseLevel,
"BlockNumber"));
265 RCP<const Map> subCommMap;
266 bool subCommMapConstructed =
false;
268 if (pL.isParameter(
"Coordinates") &&
269 pL.get<RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null &&
270 IsAvailable(coarseLevel,
"Coordinates")) {
271 RCP<xdMV> coords = Get<RCP<xdMV> >(coarseLevel,
"Coordinates");
276 GO numElts = coords->getMap()->getGlobalNumElements();
277 LO blkSize = Teuchos::as<LO>(importer->getSourceMap()->getGlobalNumElements() / numElts);
279 RCP<const Import> coordImporter;
282 coordImporter = importer;
284 RCP<const Map> origMap = coords->getMap();
285 std::vector<size_t> stridingInfo{Teuchos::as<size_t>(blkSize)};
286 RCP<const Map> targetMap = StridedMapFactory::Build(origMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
287 importer->getTargetMap()->getLocalElementList(), origMap->getIndexBase(), stridingInfo, origMap->getComm());
288 RCP<const Map> targetVectorMap;
291 coordImporter = ImportFactory::Build(origMap, targetVectorMap);
294 RCP<xdMV> permutedCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), coords->getNumVectors(),
false);
295 permutedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
297 if (pL.isParameter(
"repartition: use subcommunicators") && pL.get<
bool>(
"repartition: use subcommunicators")) {
299 if (!subCommMapConstructed) {
300 subCommMap = permutedCoords->getMap()->removeEmptyProcesses();
301 subCommMapConstructed =
true;
303 permutedCoords->replaceMap(subCommMap);
305 permutedCoords->replaceMap(permutedCoords->getMap()->removeEmptyProcesses());
309 if (permutedCoords->getMap() == Teuchos::null)
310 permutedCoords = Teuchos::null;
312 Set(coarseLevel,
"Coordinates", permutedCoords);
314 std::string fileName =
"rebalanced_coordinates_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
315 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd && permutedCoords->getMap() != Teuchos::null)
316 Xpetra::IO<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Write(fileName, *permutedCoords);
319 if (IsAvailable(coarseLevel,
"Material")) {
320 RCP<MultiVector> material = Get<RCP<MultiVector> >(coarseLevel,
"Material");
325 GO numElts = material->getMap()->getGlobalNumElements();
326 LO blkSize = Teuchos::as<LO>(importer->getSourceMap()->getGlobalNumElements() / numElts);
328 RCP<const Import> materialImporter;
331 materialImporter = importer;
333 RCP<const Map> origMap = material->getMap();
334 std::vector<size_t> stridingInfo{Teuchos::as<size_t>(blkSize)};
335 RCP<const Map> targetMap = StridedMapFactory::Build(origMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
336 importer->getTargetMap()->getLocalElementList(), origMap->getIndexBase(), stridingInfo, origMap->getComm());
337 RCP<const Map> targetVectorMap;
340 materialImporter = ImportFactory::Build(origMap, targetVectorMap);
343 RCP<MultiVector> permutedMaterial = MultiVectorFactory::Build(materialImporter->getTargetMap(), material->getNumVectors(),
false);
344 permutedMaterial->doImport(*material, *materialImporter, Xpetra::INSERT);
346 if (pL.get<
bool>(
"repartition: use subcommunicators")) {
348 if (!subCommMapConstructed) {
349 subCommMap = permutedMaterial->getMap()->removeEmptyProcesses();
350 subCommMapConstructed =
true;
352 permutedMaterial->replaceMap(subCommMap);
354 permutedMaterial->replaceMap(permutedMaterial->getMap()->removeEmptyProcesses());
358 if (permutedMaterial->getMap() == Teuchos::null)
359 permutedMaterial = Teuchos::null;
361 Set(coarseLevel,
"Material", permutedMaterial);
364 if (pL.isParameter(
"BlockNumber") &&
365 pL.get<RCP<const FactoryBase> >(
"BlockNumber") != Teuchos::null &&
366 IsAvailable(coarseLevel,
"BlockNumber")) {
367 RCP<LocalOrdinalVector> BlockNumber = Get<RCP<LocalOrdinalVector> >(coarseLevel,
"BlockNumber");
372 RCP<LocalOrdinalVector> permutedBlockNumber = LocalOrdinalVectorFactory::Build(importer->getTargetMap(),
false);
373 permutedBlockNumber->doImport(*BlockNumber, *importer, Xpetra::INSERT);
375 if (pL.isParameter(
"repartition: use subcommunicators") && pL.get<
bool>(
"repartition: use subcommunicators")) {
376 if (!subCommMapConstructed) {
377 subCommMap = permutedBlockNumber->getMap()->removeEmptyProcesses();
378 subCommMapConstructed =
true;
380 permutedBlockNumber->replaceMap(subCommMap);
383 if (permutedBlockNumber->getMap() == Teuchos::null)
384 permutedBlockNumber = Teuchos::null;
386 Set(coarseLevel,
"BlockNumber", permutedBlockNumber);
388 std::string fileName =
"rebalanced_BlockNumber_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
389 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd && permutedBlockNumber->getMap() != Teuchos::null)
390 Xpetra::IO<SC, LO, GO, NO>::WriteLOMV(fileName, *permutedBlockNumber);
393 if (IsAvailable(coarseLevel,
"Nullspace")) {
394 RCP<MultiVector> nullspace = Get<RCP<MultiVector> >(coarseLevel,
"Nullspace");
399 RCP<MultiVector> permutedNullspace = MultiVectorFactory::Build(importer->getTargetMap(), nullspace->getNumVectors(),
false);
400 permutedNullspace->doImport(*nullspace, *importer, Xpetra::INSERT);
402 if (pL.get<
bool>(
"repartition: use subcommunicators")) {
403 if (!subCommMapConstructed) {
404 subCommMap = permutedNullspace->getMap()->removeEmptyProcesses();
405 subCommMapConstructed =
true;
407 permutedNullspace->replaceMap(subCommMap);
410 if (permutedNullspace->getMap() == Teuchos::null)
411 permutedNullspace = Teuchos::null;
413 Set(coarseLevel,
"Nullspace", permutedNullspace);
417 if (!pL.get<
bool>(
"transpose: use implicit")) {
418 RCP<Matrix> originalR = Get<RCP<Matrix> >(coarseLevel,
"R");
420 if (implicit || importer.is_null()) {
421 GetOStream(
Runtime0) <<
"Using original restrictor" << std::endl;
422 Set(coarseLevel,
"R", originalR);
427 RCP<Matrix> rebalancedR;
429 SubFactoryMonitor subM(*
this,
"Rebalancing restriction -- fusedImport", coarseLevel);
432 Teuchos::ParameterList listLabel;
433 listLabel.set(
"Timer Label",
"MueLu::RebalanceR-" + Teuchos::toString(coarseLevel.GetLevelID()));
434 rebalancedR = MatrixFactory::Build(originalR, *importer, dummy, importer->getTargetMap(), Teuchos::rcp(&listLabel,
false));
436 if (!rebalancedR.is_null()) {
437 std::ostringstream oss;
438 oss <<
"R_" << coarseLevel.GetLevelID();
439 rebalancedR->setObjectLabel(oss.str());
441 Set(coarseLevel,
"R", rebalancedR);