10 #ifndef MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_
11 #define MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_
15 #include <Xpetra_CrsMatrixWrap.hpp>
17 #include <Xpetra_MapExtractor.hpp>
19 #include <Xpetra_StridedMap.hpp>
20 #include <Xpetra_StridedMapFactory.hpp>
28 #include "MueLu_HierarchyUtils.hpp"
31 #include "MueLu_PerfUtils.hpp"
35 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
39 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
41 #undef SET_VALID_ENTRY
44 validParamList->
set<
RCP<const FactoryBase> >(
"Importer", Teuchos::null,
"Generating factory of the matrix Importer for rebalancing");
45 validParamList->
set<
RCP<const FactoryBase> >(
"SubImporters", Teuchos::null,
"Generating factory of the matrix sub-Importers for rebalancing");
47 return validParamList;
50 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
52 FactManager_.push_back(FactManager);
55 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
57 Input(coarseLevel,
"A");
59 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
60 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
64 coarseLevel.
DeclareInput(
"Importer", (*it)->GetFactory(
"Importer").get(),
this);
68 if (FactManager_.size() == 0) {
69 Input(coarseLevel,
"SubImporters");
73 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
79 RCP<Matrix> originalAc = Get<RCP<Matrix> >(coarseLevel,
"A");
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());
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) {
121 importers[idx] = rebalanceImporter;
124 if (FactManager_.size() == 0) {
125 importers = Get<std::vector<RCP<const Import> > >(coarseLevel,
"SubImporters");
129 bool bRestrictComm =
false;
131 if (pL.
get<
bool>(
"repartition: use subcommunicators") ==
true)
132 bRestrictComm =
true;
136 XpetraList->
set(
"Restrict Communicator",
true);
138 XpetraList->
set(
"Restrict Communicator",
false);
147 for (
size_t i = 0; i < bA->Rows(); i++) {
148 for (
size_t j = 0; j < bA->Cols(); j++) {
152 std::stringstream ss;
153 ss <<
"Rebalancing matrix block A(" << i <<
"," << j <<
")";
158 if (importers[i] != Teuchos::null &&
159 importers[j] != Teuchos::null &&
160 Aij != Teuchos::null) {
173 TEUCHOS_TEST_FOR_EXCEPTION(rebAijImport.
is_null() ==
true,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Importer associated with block " << j <<
" is null.");
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.");
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();
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()));
215 if (orig_stridedRgMap != Teuchos::null) {
216 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
218 stridedRgMap = StridedMapFactory::Build(
219 bA->getRangeMap()->lib(),
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()));
230 if (orig_stridedDoMap != Teuchos::null) {
231 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
233 stridedDoMap = StridedMapFactory::Build(
234 bA->getDomainMap()->lib(),
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"));
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"));
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;
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());
291 if (stridedRgFullMap != Teuchos::null) {
292 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
294 StridedMapFactory::Build(
295 bA->getRangeMap()->lib(),
301 stridedRgFullMap->getStridedBlockId(),
302 stridedRgFullMap->getOffset());
306 bA->getRangeMap()->lib(),
312 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0, fullDomainMapVector.size());
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(),
327 stridedDoFullMap->getStridedBlockId(),
328 stridedDoFullMap->getOffset());
332 bA->getDomainMap()->lib(),
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!");
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);
380 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
382 rebalanceFacts_.push_back(factory);
Exception indicating invalid cast attempted.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager)
Add a factory manager.
T & get(const std::string &name, T def_value)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define SET_VALID_ENTRY(name)
Print additional debugging information.
One-liner description of what is happening.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void sort(View &view, const size_t &size)
Print statistics that do not involve significant additional computation.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void AddRebalanceFactory(const RCP< const FactoryBase > &factory)
Add rebalancing factory in the end of list of rebalancing factories in RebalanceAcFactory.
Class that holds all level-specific information.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Exception throws to report errors in the internal logical of the program.
An exception safe way to call the method 'Level::SetFactoryManager()'.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()