46 #ifndef MUELU_REBALANCETRANSFERFACTORY_DEF_HPP
47 #define MUELU_REBALANCETRANSFERFACTORY_DEF_HPP
49 #include <Teuchos_Tuple.hpp>
51 #include "Xpetra_MultiVector.hpp"
52 #include "Xpetra_MultiVectorFactory.hpp"
53 #include "Xpetra_Vector.hpp"
54 #include "Xpetra_VectorFactory.hpp"
55 #include <Xpetra_Matrix.hpp>
56 #include <Xpetra_MapFactory.hpp>
57 #include <Xpetra_MatrixFactory.hpp>
58 #include <Xpetra_Import.hpp>
59 #include <Xpetra_ImportFactory.hpp>
60 #include <Xpetra_IO.hpp>
67 #include "MueLu_PerfUtils.hpp"
71 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
73 RCP<ParameterList> validParamList = rcp(
new ParameterList());
75 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
79 #undef SET_VALID_ENTRY
82 typedef Teuchos::StringToIntegralParameterEntryValidator<int> validatorType;
83 RCP<validatorType> typeValidator = rcp (
new validatorType(Teuchos::tuple<std::string>(
"Interpolation",
"Restriction"),
"type"));
84 validParamList->set(
"type",
"Interpolation",
"Type of the transfer operator that need to be rebalanced (Interpolation or Restriction)", typeValidator);
87 validParamList->set< RCP<const FactoryBase> >(
"P",
null,
"Factory of the prolongation operator that need to be rebalanced (only used if type=Interpolation)");
88 validParamList->set< RCP<const FactoryBase> >(
"R",
null,
"Factory of the restriction operator that need to be rebalanced (only used if type=Restriction)");
89 validParamList->set< RCP<const FactoryBase> >(
"Nullspace",
null,
"Factory of the nullspace that need to be rebalanced (only used if type=Interpolation)");
90 validParamList->set< RCP<const FactoryBase> >(
"Coordinates",
null,
"Factory of the coordinates that need to be rebalanced (only used if type=Interpolation)");
91 validParamList->set< RCP<const FactoryBase> >(
"Importer",
null,
"Factory of the importer object used for the rebalancing");
92 validParamList->set<
int > (
"write start", -1,
"First level at which coordinates should be written to file");
93 validParamList->set<
int > (
"write end", -1,
"Last level at which coordinates should be written to file");
99 return validParamList;
102 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
104 const ParameterList& pL = GetParameterList();
106 if (pL.get<std::string>(
"type") ==
"Interpolation") {
107 Input(coarseLevel,
"P");
108 Input(coarseLevel,
"Nullspace");
109 if (pL.get< RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null)
110 Input(coarseLevel,
"Coordinates");
113 if (pL.get<
bool>(
"transpose: use implicit") ==
false)
114 Input(coarseLevel,
"R");
117 Input(coarseLevel,
"Importer");
120 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
123 typedef Xpetra::MultiVector<double, LO, GO, NO> xdMV;
125 const ParameterList& pL = GetParameterList();
127 int implicit = !pL.get<
bool>(
"repartition: rebalance P and R");
128 int writeStart = pL.get<
int> (
"write start");
129 int writeEnd = pL.get<
int> (
"write end");
131 if (writeStart == 0 && fineLevel.
GetLevelID() == 0 && writeStart <= writeEnd && IsAvailable(fineLevel,
"Coordinates")) {
132 std::string fileName =
"coordinates_level_0.m";
133 RCP<xdMV> fineCoords = fineLevel.
Get< RCP<xdMV> >(
"Coordinates");
134 if (fineCoords != Teuchos::null)
135 Xpetra::IO<double,LO,GO,NO>::Write(fileName, *fineCoords);
138 RCP<const Import> importer = Get<RCP<const Import> >(coarseLevel,
"Importer");
144 RCP<ParameterList> params = rcp(
new ParameterList());
146 params->set(
"printLoadBalancingInfo",
true);
147 params->set(
"printCommInfo",
true);
150 std::string transferType = pL.get<std::string>(
"type");
151 if (transferType ==
"Interpolation") {
152 RCP<Matrix> originalP = Get< RCP<Matrix> >(coarseLevel,
"P");
158 if (implicit || importer.is_null()) {
159 GetOStream(
Runtime0) <<
"Using original prolongator" << std::endl;
160 Set(coarseLevel,
"P", originalP);
178 RCP<Matrix> rebalancedP = originalP;
179 RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(originalP);
180 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null,
Exceptions::BadCast,
"Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
182 RCP<CrsMatrix> rebalancedP2 = crsOp->getCrsMatrix();
183 TEUCHOS_TEST_FOR_EXCEPTION(rebalancedP2 == Teuchos::null, std::runtime_error,
"Xpetra::CrsMatrixWrap doesn't have a CrsMatrix");
186 SubFactoryMonitor subM(*
this,
"Rebalancing prolongator -- fast map replacement", coarseLevel);
188 RCP<const Import> newImporter;
191 newImporter = ImportFactory::Build(importer->getTargetMap(), rebalancedP->getColMap());
193 rebalancedP2->replaceDomainMapAndImporter(importer->getTargetMap(), newImporter);
203 Set(coarseLevel,
"P", rebalancedP);
210 if (importer.is_null()) {
211 if (IsAvailable(coarseLevel,
"Nullspace"))
212 Set(coarseLevel,
"Nullspace", Get<RCP<MultiVector> >(coarseLevel,
"Nullspace"));
214 if (pL.isParameter(
"Coordinates") && pL.get< RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null)
215 if (IsAvailable(coarseLevel,
"Coordinates"))
216 Set(coarseLevel,
"Coordinates", Get< RCP<xdMV> >(coarseLevel,
"Coordinates"));
221 if (pL.isParameter(
"Coordinates") &&
222 pL.get< RCP<const FactoryBase> >(
"Coordinates") != Teuchos::null &&
223 IsAvailable(coarseLevel,
"Coordinates")) {
224 RCP<xdMV> coords = Get<RCP<xdMV> >(coarseLevel,
"Coordinates");
229 LO nodeNumElts = coords->getMap()->getNodeNumElements();
232 LO myBlkSize = 0, blkSize = 0;
234 myBlkSize = importer->getSourceMap()->getNodeNumElements() / nodeNumElts;
235 MueLu_maxAll(coords->getMap()->getComm(), myBlkSize, blkSize);
237 RCP<const Import> coordImporter;
239 coordImporter = importer;
245 RCP<const Map> origMap = coords->getMap();
246 GO indexBase = origMap->getIndexBase();
248 ArrayView<const GO> OEntries = importer->getTargetMap()->getNodeElementList();
249 LO numEntries = OEntries.size()/blkSize;
250 ArrayRCP<GO> Entries(numEntries);
251 for (LO i = 0; i < numEntries; i++)
252 Entries[i] = (OEntries[i*blkSize]-indexBase)/blkSize + indexBase;
254 RCP<const Map> targetMap = MapFactory::Build(origMap->lib(), origMap->getGlobalNumElements(), Entries(), indexBase, origMap->getComm());
255 coordImporter = ImportFactory::Build(origMap, targetMap);
258 RCP<xdMV> permutedCoords = Xpetra::MultiVectorFactory<double,LO,GO,NO>::Build(coordImporter->getTargetMap(), coords->getNumVectors());
259 permutedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
261 if (pL.isParameter(
"repartition: use subcommunicators") ==
true && pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
262 permutedCoords->replaceMap(permutedCoords->getMap()->removeEmptyProcesses());
264 Set(coarseLevel,
"Coordinates", permutedCoords);
266 std::string fileName =
"rebalanced_coordinates_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
267 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd && permutedCoords->getMap() != Teuchos::null)
268 Xpetra::IO<double,LO,GO,NO>::Write(fileName, *permutedCoords);
271 if (IsAvailable(coarseLevel,
"Nullspace")) {
272 RCP<MultiVector> nullspace = Get< RCP<MultiVector> >(coarseLevel,
"Nullspace");
277 RCP<MultiVector> permutedNullspace = MultiVectorFactory::Build(importer->getTargetMap(), nullspace->getNumVectors());
278 permutedNullspace->doImport(*nullspace, *importer, Xpetra::INSERT);
280 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
281 permutedNullspace->replaceMap(permutedNullspace->getMap()->removeEmptyProcesses());
283 Set(coarseLevel,
"Nullspace", permutedNullspace);
287 if (pL.get<
bool>(
"transpose: use implicit") ==
false) {
288 RCP<Matrix> originalR = Get< RCP<Matrix> >(coarseLevel,
"R");
292 if (implicit || importer.is_null()) {
293 GetOStream(
Runtime0) <<
"Using original restrictor" << std::endl;
294 Set(coarseLevel,
"R", originalR);
297 RCP<Matrix> rebalancedR;
299 SubFactoryMonitor subM(*
this,
"Rebalancing restriction -- fusedImport", coarseLevel);
302 Teuchos::ParameterList listLabel;
303 listLabel.set(
"Timer Label",
"MueLu::RebalanceR-" +
Teuchos::toString(coarseLevel.GetLevelID()));
304 rebalancedR = MatrixFactory::Build(originalR, *importer, dummy, importer->getTargetMap(),Teuchos::rcp(&listLabel,
false));
306 Set(coarseLevel,
"R", rebalancedR);
324 #endif // MUELU_REBALANCETRANSFERFACTORY_DEF_HPP