MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_RebalanceAcFactory_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_REBALANCEACFACTORY_DEF_HPP
11#define MUELU_REBALANCEACFACTORY_DEF_HPP
12
13#include <Xpetra_Matrix.hpp>
14#include <Xpetra_CrsMatrix.hpp>
15#include <Xpetra_CrsMatrixWrap.hpp>
16#include <Xpetra_MatrixFactory.hpp>
17
19
20#include "MueLu_MasterList.hpp"
21#include "MueLu_Monitor.hpp"
22#include "MueLu_PerfUtils.hpp"
23#include "MueLu_RAPFactory.hpp"
24
25namespace MueLu {
26
27template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
29
30template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
32
33template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
35 RCP<ParameterList> validParamList = rcp(new ParameterList());
36
37#define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
38 SET_VALID_ENTRY("repartition: use subcommunicators");
39 SET_VALID_ENTRY("repartition: use subcommunicators in place");
40#undef SET_VALID_ENTRY
41
42 validParamList->set<std::string>("Matrix name", "A", "Name of the matrix that will be transferred on the coarse grid (level key)");
43
44 validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A for rebalancing");
45 validParamList->set<RCP<const FactoryBase> >("Importer", Teuchos::null, "Generating factory of the importer");
46 validParamList->set<RCP<const FactoryBase> >("InPlaceMap", Teuchos::null, "Generating factory of the InPlaceMap");
47
48 return validParamList;
49}
50
51template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
53 const Teuchos::ParameterList &pL = GetParameterList();
54 std::string matrixName = pL.get<std::string>("Matrix name");
55 coarseLevel.DeclareInput(matrixName, GetFactory("A").get(), this);
56 if (pL.isParameter("repartition: use subcommunicators in place") && pL.get<bool>("repartition: use subcommunicators in place") == true) {
57 Input(coarseLevel, "InPlaceMap");
58 } else
59 Input(coarseLevel, "Importer");
60}
61
62template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
64 const Teuchos::ParameterList &pL = GetParameterList();
65 auto matrixName = pL.get<std::string>("Matrix name");
66 std::string coarseMatrixName;
67 if (matrixName.size() == 1)
68 coarseMatrixName = matrixName + "c";
69 else
70 coarseMatrixName = matrixName + "_coarse";
71
72 FactoryMonitor m(*this, "Computing " + coarseMatrixName, coarseLevel);
73
74 RCP<Matrix> originalAc = coarseLevel.Get<RCP<Matrix> >(matrixName, GetFactory("A").get());
75
76 // This is a short-circuit for if we want to leave A where it is, but restrict its communicator
77 // to something corresponding to a given map. Maxwell1 is the prime customer for this.
78 bool inPlace = pL.get<bool>("repartition: use subcommunicators in place");
79 if (inPlace) {
80 SubFactoryMonitor subM(*this, "Rebalancing existing " + coarseMatrixName + " in-place", coarseLevel);
81 RCP<const Map> newMap = Get<RCP<const Map> >(coarseLevel, "InPlaceMap");
82
83 originalAc->removeEmptyProcessesInPlace(newMap);
84
85 // The "in place" still leaves a dummy matrix here. That needs to go
86 if (newMap.is_null()) originalAc = Teuchos::null;
87
88 Set(coarseLevel, matrixName, originalAc);
89 return;
90 }
91
92 RCP<const Import> rebalanceImporter = Get<RCP<const Import> >(coarseLevel, "Importer");
93
94 if (rebalanceImporter != Teuchos::null) {
95 RCP<Matrix> rebalancedAc;
96 {
97 SubFactoryMonitor subM(*this, "Rebalancing existing " + coarseMatrixName, coarseLevel);
98 RCP<const Map> targetMap = rebalanceImporter->getTargetMap();
99
100 ParameterList XpetraList;
101 if (pL.get<bool>("repartition: use subcommunicators") == true) {
102 GetOStream(Runtime0) << "Replacing maps with a subcommunicator" << std::endl;
103 XpetraList.set("Restrict Communicator", true);
104 }
105 // NOTE: If the communicator is restricted away, Build returns Teuchos::null.
106 XpetraList.set("Timer Label", "MueLu::RebalanceAc-" + Teuchos::toString(coarseLevel.GetLevelID()));
107 {
108 SubFactoryMonitor subM2(*this, "Rebalancing existing " + coarseMatrixName + ": MatrixFactory::Build", coarseLevel);
109 rebalancedAc = MatrixFactory::Build(originalAc, *rebalanceImporter, *rebalanceImporter, targetMap, targetMap, rcp(&XpetraList, false));
110 }
111
112 if (!rebalancedAc.is_null()) {
113 if (originalAc->IsFixedBlockSizeSet())
114 rebalancedAc->SetFixedBlockSize(originalAc->GetFixedBlockSize());
115 std::ostringstream oss;
116 oss << "A_" << coarseLevel.GetLevelID();
117 rebalancedAc->setObjectLabel(oss.str());
118 }
119 Set(coarseLevel, matrixName, rebalancedAc);
120 }
121 if (!rebalancedAc.is_null() && IsPrint(Statistics2)) {
122 int oldRank = SetProcRankVerbose(rebalancedAc->getRowMap()->getComm()->getRank());
123
124 RCP<ParameterList> params = rcp(new ParameterList());
125 params->set("printLoadBalancingInfo", true);
126 params->set("printCommInfo", true);
127 GetOStream(Statistics2) << PerfUtils::PrintMatrixInfo(*rebalancedAc, coarseMatrixName + " (rebalanced)", params);
128
129 SetProcRankVerbose(oldRank);
130 }
131
132 } else {
133 // Ac already built by the load balancing process and no load balancing needed
134 GetOStream(Runtime1) << "No rebalancing" << std::endl;
135 Set(coarseLevel, matrixName, originalAc);
136 }
137
138 if (rebalanceFacts_.begin() != rebalanceFacts_.end()) {
139 SubFactoryMonitor m2(*this, "Rebalance additional data", coarseLevel);
140
141 // call Build of all user-given transfer factories
142 for (std::vector<RCP<const FactoryBase> >::const_iterator it = rebalanceFacts_.begin(); it != rebalanceFacts_.end(); ++it) {
143 GetOStream(Runtime0) << "RebalanceAc: call rebalance factory " << (*it).get() << ": " << (*it)->description() << std::endl;
144 (*it)->CallBuild(coarseLevel);
145 }
146 }
147} // Build()
148
149template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
151 /*TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::rcp_dynamic_cast<const TwoLevelFactoryBase>(factory) == Teuchos::null, Exceptions::BadCast,
152 "MueLu::RAPFactory::AddTransferFactory: Transfer factory is not derived from TwoLevelFactoryBase. "
153 "This is very strange. (Note: you can remove this exception if there's a good reason for)");
154 TEUCHOS_TEST_FOR_EXCEPTION(hasDeclaredInput_, Exceptions::RuntimeError, "MueLu::RAPFactory::AddTransferFactory: Factory is being added after we have already declared input");*/
155 rebalanceFacts_.push_back(factory);
156} // AddRebalanceFactory()
157
158} // namespace MueLu
159
160#endif // MUELU_REBALANCEACFACTORY_DEF_HPP
#define SET_VALID_ENTRY(name)
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
int GetLevelID() const
Return level number.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void AddRebalanceFactory(const RCP< const FactoryBase > &factory)
Add rebalancing factory in the end of list of rebalancing factories in RebalanceAcFactory.
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.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.
@ Runtime0
One-liner description of what is happening.
@ Runtime1
Description of what is happening (more verbose)