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");
155 if (implicit || importer.is_null()) {
156 GetOStream(
Runtime0) <<
"Using original prolongator" << std::endl;
157 Set(coarseLevel,
"P", originalP);
183 RCP<Matrix> rebalancedP;
184 if (reallyExplicit) {
185 size_t totalMaxPerRow = 0;
186 ArrayRCP<size_t> nnzPerRow(originalP->getRowMap()->getLocalNumElements(), 0);
187 for (
size_t i = 0; i < originalP->getRowMap()->getLocalNumElements(); ++i) {
188 nnzPerRow[i] = originalP->getNumEntriesInLocalRow(i);
189 if (nnzPerRow[i] > totalMaxPerRow) totalMaxPerRow = nnzPerRow[i];
192 rebalancedP = MatrixFactory::Build(originalP->getRowMap(), totalMaxPerRow);
195 RCP<Import> trivialImporter = ImportFactory::Build(originalP->getRowMap(), originalP->getRowMap());
197 std::string monitorLabel{
"Rebalancing prolongator -- import only"};
198 if (
auto sendType = pL.get<std::string>(
"repartition: send type"); sendType !=
"") {
199 auto sendTypeList = Teuchos::rcp(
new Teuchos::ParameterList());
200 sendTypeList->set(
"Send type", sendType);
201 trivialImporter->setDistributorParameters(sendTypeList);
202 monitorLabel +=
" [" + sendType +
"]";
206 rebalancedP->doImport(*originalP, *trivialImporter, Xpetra::INSERT);
208 rebalancedP->fillComplete(importer->getTargetMap(), originalP->getRangeMap());
211 rebalancedP = originalP;
212 RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(originalP);
213 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null,
Exceptions::BadCast,
"Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
215 RCP<CrsMatrix> rebalancedP2 = crsOp->getCrsMatrix();
216 TEUCHOS_TEST_FOR_EXCEPTION(rebalancedP2 == Teuchos::null, std::runtime_error,
"Xpetra::CrsMatrixWrap doesn't have a CrsMatrix");
219 SubFactoryMonitor subM(*
this,
"Rebalancing prolongator -- fast map replacement", coarseLevel);
221 RCP<const Import> newImporter;
224 newImporter = ImportFactory::Build(importer->getTargetMap(), rebalancedP->getColMap());
226 rebalancedP2->replaceDomainMapAndImporter(importer->getTargetMap(), newImporter);
235 if (!rebalancedP.is_null()) {
236 std::ostringstream oss;
237 oss <<
"P_" << coarseLevel.GetLevelID();
238 rebalancedP->setObjectLabel(oss.str());
240 Set(coarseLevel,
"P", rebalancedP);
247 if (importer.is_null()) {
248 if (IsAvailable(coarseLevel,
"Nullspace"))
249 Set(coarseLevel,
"Nullspace", Get<RCP<MultiVector> >(coarseLevel,
"Nullspace"));
251 if (pL.isParameter(
"Coordinates") && pL.get<RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null)
252 if (IsAvailable(coarseLevel,
"Coordinates"))
253 Set(coarseLevel,
"Coordinates", Get<RCP<xdMV> >(coarseLevel,
"Coordinates"));
255 if (pL.isParameter(
"Material") && pL.get<RCP<const FactoryBase> >(
"Material") != Teuchos::null)
256 if (IsAvailable(coarseLevel,
"Material"))
257 Set(coarseLevel,
"Material", Get<RCP<MultiVector> >(coarseLevel,
"Material"));
259 if (pL.isParameter(
"BlockNumber") && pL.get<RCP<const FactoryBase> >(
"BlockNumber") != Teuchos::null)
260 if (IsAvailable(coarseLevel,
"BlockNumber"))
261 Set(coarseLevel,
"BlockNumber", Get<RCP<LocalOrdinalVector> >(coarseLevel,
"BlockNumber"));
266 if (pL.isParameter(
"Coordinates") &&
267 pL.get<RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null &&
268 IsAvailable(coarseLevel,
"Coordinates")) {
269 RCP<xdMV> coords = Get<RCP<xdMV> >(coarseLevel,
"Coordinates");
275 LO nodeNumElts = coords->getMap()->getLocalNumElements();
276 LO myBlkSize = 0, blkSize = 0;
278 myBlkSize = importer->getSourceMap()->getLocalNumElements() / nodeNumElts;
279 MueLu_maxAll(coords->getMap()->getComm(), myBlkSize, blkSize);
281 RCP<const Import> coordImporter;
284 coordImporter = importer;
286 RCP<const Map> origMap = coords->getMap();
287 std::vector<size_t> stridingInfo{Teuchos::as<size_t>(blkSize)};
288 RCP<const Map> targetMap = StridedMapFactory::Build(origMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
289 importer->getTargetMap()->getLocalElementList(), origMap->getIndexBase(), stridingInfo, origMap->getComm());
290 RCP<const Map> targetVectorMap;
293 coordImporter = ImportFactory::Build(origMap, targetVectorMap);
296 RCP<xdMV> permutedCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), coords->getNumVectors());
297 permutedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
299 if (pL.isParameter(
"repartition: use subcommunicators") ==
true && pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
300 permutedCoords->replaceMap(permutedCoords->getMap()->removeEmptyProcesses());
302 if (permutedCoords->getMap() == Teuchos::null)
303 permutedCoords = Teuchos::null;
305 Set(coarseLevel,
"Coordinates", permutedCoords);
307 std::string fileName =
"rebalanced_coordinates_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
308 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd && permutedCoords->getMap() != Teuchos::null)
309 Xpetra::IO<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Write(fileName, *permutedCoords);
312 if (IsAvailable(coarseLevel,
"Material")) {
313 RCP<MultiVector> material = Get<RCP<MultiVector> >(coarseLevel,
"Material");
319 LO nodeNumElts = material->getMap()->getLocalNumElements();
320 LO myBlkSize = 0, blkSize = 0;
322 myBlkSize = importer->getSourceMap()->getLocalNumElements() / nodeNumElts;
323 MueLu_maxAll(material->getMap()->getComm(), myBlkSize, blkSize);
325 RCP<const Import> materialImporter;
328 materialImporter = importer;
330 RCP<const Map> origMap = material->getMap();
331 std::vector<size_t> stridingInfo{Teuchos::as<size_t>(blkSize)};
332 RCP<const Map> targetMap = StridedMapFactory::Build(origMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
333 importer->getTargetMap()->getLocalElementList(), origMap->getIndexBase(), stridingInfo, origMap->getComm());
334 RCP<const Map> targetVectorMap;
337 materialImporter = ImportFactory::Build(origMap, targetVectorMap);
340 RCP<MultiVector> permutedMaterial = MultiVectorFactory::Build(materialImporter->getTargetMap(), material->getNumVectors());
341 permutedMaterial->doImport(*material, *materialImporter, Xpetra::INSERT);
343 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
344 permutedMaterial->replaceMap(permutedMaterial->getMap()->removeEmptyProcesses());
346 if (permutedMaterial->getMap() == Teuchos::null)
347 permutedMaterial = Teuchos::null;
349 Set(coarseLevel,
"Material", permutedMaterial);
352 if (pL.isParameter(
"BlockNumber") &&
353 pL.get<RCP<const FactoryBase> >(
"BlockNumber") != Teuchos::null &&
354 IsAvailable(coarseLevel,
"BlockNumber")) {
355 RCP<LocalOrdinalVector> BlockNumber = Get<RCP<LocalOrdinalVector> >(coarseLevel,
"BlockNumber");
360 RCP<LocalOrdinalVector> permutedBlockNumber = LocalOrdinalVectorFactory::Build(importer->getTargetMap(),
false);
361 permutedBlockNumber->doImport(*BlockNumber, *importer, Xpetra::INSERT);
363 if (pL.isParameter(
"repartition: use subcommunicators") ==
true && pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
364 permutedBlockNumber->replaceMap(permutedBlockNumber->getMap()->removeEmptyProcesses());
366 if (permutedBlockNumber->getMap() == Teuchos::null)
367 permutedBlockNumber = Teuchos::null;
369 Set(coarseLevel,
"BlockNumber", permutedBlockNumber);
371 std::string fileName =
"rebalanced_BlockNumber_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
372 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd && permutedBlockNumber->getMap() != Teuchos::null)
373 Xpetra::IO<SC, LO, GO, NO>::WriteLOMV(fileName, *permutedBlockNumber);
376 if (IsAvailable(coarseLevel,
"Nullspace")) {
377 RCP<MultiVector> nullspace = Get<RCP<MultiVector> >(coarseLevel,
"Nullspace");
382 RCP<MultiVector> permutedNullspace = MultiVectorFactory::Build(importer->getTargetMap(), nullspace->getNumVectors());
383 permutedNullspace->doImport(*nullspace, *importer, Xpetra::INSERT);
385 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
386 permutedNullspace->replaceMap(permutedNullspace->getMap()->removeEmptyProcesses());
388 if (permutedNullspace->getMap() == Teuchos::null)
389 permutedNullspace = Teuchos::null;
391 Set(coarseLevel,
"Nullspace", permutedNullspace);
395 if (pL.get<
bool>(
"transpose: use implicit") ==
false) {
396 RCP<Matrix> originalR = Get<RCP<Matrix> >(coarseLevel,
"R");
400 if (implicit || importer.is_null()) {
401 GetOStream(
Runtime0) <<
"Using original restrictor" << std::endl;
402 Set(coarseLevel,
"R", originalR);
405 RCP<Matrix> rebalancedR;
407 SubFactoryMonitor subM(*
this,
"Rebalancing restriction -- fusedImport", coarseLevel);
410 Teuchos::ParameterList listLabel;
411 listLabel.set(
"Timer Label",
"MueLu::RebalanceR-" + Teuchos::toString(coarseLevel.GetLevelID()));
412 rebalancedR = MatrixFactory::Build(originalR, *importer, dummy, importer->getTargetMap(), Teuchos::rcp(&listLabel,
false));
414 if (!rebalancedR.is_null()) {
415 std::ostringstream oss;
416 oss <<
"R_" << coarseLevel.GetLevelID();
417 rebalancedR->setObjectLabel(oss.str());
419 Set(coarseLevel,
"R", rebalancedR);