77 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
79 RCP<Matrix> originalAc = Get<RCP<Matrix> >(coarseLevel,
"A");
81 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalAc);
82 TEUCHOS_TEST_FOR_EXCEPTION(bA == Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockAcFactory::Build: input matrix A is not of type BlockedCrsMatrix! error.");
83 TEUCHOS_TEST_FOR_EXCEPTION(bA->Rows() != bA->Cols(),
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Blocked operator has " << bA->Rows() <<
" and " << bA->Cols() <<
". We only support square matrices (with same number of blocks and columns).");
86 std::vector<GO> fullRangeMapVector;
87 std::vector<GO> fullDomainMapVector;
88 std::vector<RCP<const Map> > subBlockARangeMaps;
89 std::vector<RCP<const Map> > subBlockADomainMaps;
90 subBlockARangeMaps.reserve(bA->Rows());
91 subBlockADomainMaps.reserve(bA->Cols());
94 RCP<const MapExtractor> rangeMapExtractor = bA->getRangeMapExtractor();
95 RCP<const MapExtractor> domainMapExtractor = bA->getDomainMapExtractor();
104 bool bThyraRangeGIDs = rangeMapExtractor->getThyraMode();
105 bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
108 std::vector<RCP<Matrix> > subBlockRebA =
109 std::vector<RCP<Matrix> >(bA->Cols() * bA->Rows(), Teuchos::null);
113 std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bA->Rows(), Teuchos::null);
114 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
116 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
120 RCP<const Import> rebalanceImporter = coarseLevel.
Get<RCP<const Import> >(
"Importer", (*it)->GetFactory(
"Importer").get());
121 importers[idx] = rebalanceImporter;
124 if (FactManager_.size() == 0) {
125 importers = Get<std::vector<RCP<const Import> > >(coarseLevel,
"SubImporters");
129 bool bRestrictComm =
false;
130 const ParameterList &pL = GetParameterList();
131 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
132 bRestrictComm =
true;
134 RCP<ParameterList> XpetraList = Teuchos::rcp(
new ParameterList());
136 XpetraList->set(
"Restrict Communicator",
true);
138 XpetraList->set(
"Restrict Communicator",
false);
142 RCP<const Teuchos::Comm<int> > rebalancedComm = Teuchos::null;
147 for (
size_t i = 0; i < bA->Rows(); i++) {
148 for (
size_t j = 0; j < bA->Cols(); j++) {
150 RCP<Matrix> Aij = bA->getMatrix(i, j);
152 std::stringstream ss;
153 ss <<
"Rebalancing matrix block A(" << i <<
"," << j <<
")";
156 RCP<Matrix> rebAij = Teuchos::null;
158 if (importers[i] != Teuchos::null &&
159 importers[j] != Teuchos::null &&
160 Aij != Teuchos::null) {
161 RCP<const Map> targetRangeMap = importers[i]->getTargetMap();
162 RCP<const Map> targetDomainMap = importers[j]->getTargetMap();
169 RCP<Matrix> cAij = Aij;
172 Teuchos::RCP<const Import> rebAijImport = ImportFactory::Build(importers[j]->getTargetMap(), cAij->getColMap());
173 TEUCHOS_TEST_FOR_EXCEPTION(rebAijImport.is_null() ==
true,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Importer associated with block " << j <<
" is null.");
175 Teuchos::RCP<const CrsMatrixWrap> cAwij = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(cAij);
176 TEUCHOS_TEST_FOR_EXCEPTION(cAwij.is_null() ==
true,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Block (" << i <<
"," << j <<
") is not of type CrsMatrix. We cannot rebalanced (nested) operators.");
177 Teuchos::RCP<CrsMatrix> cAmij = cAwij->getCrsMatrix();
184 rebAij = MatrixFactory::Build(cAij, *(importers[i]), *(importers[j]), targetDomainMap, targetRangeMap, XpetraList);
191 subBlockRebA[i * bA->Cols() + j] = rebAij;
193 if (!rebAij.is_null()) {
195 if (rebalancedComm.is_null()) rebalancedComm = rebAij->getRowMap()->getComm();
198 RCP<ParameterList> params = rcp(
new ParameterList());
199 params->set(
"printLoadBalancingInfo",
true);
200 std::stringstream ss2;
201 ss2 <<
"A(" << i <<
"," << j <<
") rebalanced:";
211 if (subBlockRebA[i * bA->Cols() + i].is_null() ==
false) {
212 RCP<Matrix> rebAii = subBlockRebA[i * bA->Cols() + i];
213 Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(i, rangeMapExtractor->getThyraMode()));
214 Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
215 if (orig_stridedRgMap != Teuchos::null) {
216 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
217 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = rebAii->getRangeMap()->getLocalElementList();
218 stridedRgMap = StridedMapFactory::Build(
219 bA->getRangeMap()->lib(),
220 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
222 rebAii->getRangeMap()->getIndexBase(),
225 orig_stridedRgMap->getStridedBlockId(),
226 orig_stridedRgMap->getOffset());
228 Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(i, domainMapExtractor->getThyraMode()));
229 Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
230 if (orig_stridedDoMap != Teuchos::null) {
231 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
232 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = rebAii->getDomainMap()->getLocalElementList();
233 stridedDoMap = StridedMapFactory::Build(
234 bA->getDomainMap()->lib(),
235 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
237 rebAii->getDomainMap()->getIndexBase(),
240 orig_stridedDoMap->getStridedBlockId(),
241 orig_stridedDoMap->getOffset());
245 stridedRgMap->removeEmptyProcesses();
246 stridedDoMap->removeEmptyProcesses();
249 TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
250 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
253 if (rebAii->IsView(
"stridedMaps")) rebAii->RemoveView(
"stridedMaps");
254 rebAii->CreateView(
"stridedMaps", stridedRgMap, stridedDoMap);
256 subBlockARangeMaps.push_back(rebAii->getRowMap(
"stridedMaps"));
257 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMap = rebAii->getRangeMap()->getLocalElementList();
259 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMap.begin(), nodeRangeMap.end());
260 if (bThyraRangeGIDs ==
false)
261 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
263 subBlockADomainMaps.push_back(rebAii->getColMap(
"stridedMaps"));
264 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMap = rebAii->getDomainMap()->getLocalElementList();
266 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMap.begin(), nodeDomainMap.end());
267 if (bThyraDomainGIDs ==
false)
268 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
275 if (rebalancedComm == Teuchos::null) {
276 GetOStream(
Debug, -1) <<
"RebalanceBlockedAc: deactivate proc " << originalAc->getRowMap()->getComm()->getRank() << std::endl;
278 Teuchos::RCP<BlockedCrsMatrix> reb_bA = Teuchos::null;
279 coarseLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA),
this);
285 GO rangeIndexBase = bA->getRangeMap()->getIndexBase();
286 GO domainIndexBase = bA->getDomainMap()->getIndexBase();
288 Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0, fullRangeMapVector.size());
289 Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getFullMap());
290 Teuchos::RCP<const Map> fullRangeMap = Teuchos::null;
291 if (stridedRgFullMap != Teuchos::null) {
292 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
294 StridedMapFactory::Build(
295 bA->getRangeMap()->lib(),
296 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
301 stridedRgFullMap->getStridedBlockId(),
302 stridedRgFullMap->getOffset());
306 bA->getRangeMap()->lib(),
307 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
312 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0, fullDomainMapVector.size());
314 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getFullMap());
315 Teuchos::RCP<const Map> fullDomainMap = Teuchos::null;
316 if (stridedDoFullMap != Teuchos::null) {
317 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap == Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockedAc::Build: full map in domain map extractor has no striding information! error.");
318 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
320 StridedMapFactory::Build(
321 bA->getDomainMap()->lib(),
322 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
327 stridedDoFullMap->getStridedBlockId(),
328 stridedDoFullMap->getOffset());
332 bA->getDomainMap()->lib(),
333 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
340 fullRangeMap->removeEmptyProcesses();
341 fullDomainMap->removeEmptyProcesses();
345 RCP<const MapExtractor> rebRangeMapExtractor = MapExtractorFactory::Build(fullRangeMap, subBlockARangeMaps, bThyraRangeGIDs);
346 RCP<const MapExtractor> rebDomainMapExtractor = MapExtractorFactory::Build(fullDomainMap, subBlockADomainMaps, bThyraDomainGIDs);
348 TEUCHOS_TEST_FOR_EXCEPTION(rangeMapExtractor->NumMaps() != rebRangeMapExtractor->NumMaps(),
Exceptions::RuntimeError,
349 "MueLu::RebalanceBlockedAc::Build: Rebalanced RangeMapExtractor has " << rebRangeMapExtractor->NumMaps()
350 <<
" sub maps. Original RangeMapExtractor has " << rangeMapExtractor->NumMaps() <<
". They must match!");
351 TEUCHOS_TEST_FOR_EXCEPTION(domainMapExtractor->NumMaps() != rebDomainMapExtractor->NumMaps(),
Exceptions::RuntimeError,
352 "MueLu::RebalanceBlockedAc::Build: Rebalanced DomainMapExtractor has " << rebDomainMapExtractor->NumMaps()
353 <<
" sub maps. Original DomainMapExtractor has " << domainMapExtractor->NumMaps() <<
". They must match!");
355 Teuchos::RCP<BlockedCrsMatrix> reb_bA = Teuchos::rcp(
new BlockedCrsMatrix(rebRangeMapExtractor, rebDomainMapExtractor, 10));
356 for (
size_t i = 0; i < bA->Rows(); i++) {
357 for (
size_t j = 0; j < bA->Cols(); j++) {
358 reb_bA->setMatrix(i, j, subBlockRebA[i * bA->Cols() + j]);
362 reb_bA->fillComplete();
364 coarseLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA),
this);
369 if (rebalanceFacts_.begin() != rebalanceFacts_.end()) {
373 for (std::vector<RCP<const FactoryBase> >::const_iterator it2 = rebalanceFacts_.begin(); it2 != rebalanceFacts_.end(); ++it2) {
374 GetOStream(
Runtime0) <<
"RebalanceBlockedAc: call rebalance factory " << (*it2).get() <<
": " << (*it2)->description() << std::endl;
375 (*it2)->CallBuild(coarseLevel);