MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_IsorropiaInterface_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/*
11 * MueLu_IsorropiaInterface_def.hpp
12 *
13 * Created on: Jun 10, 2013
14 * Author: tobias
15 */
16
17#ifndef MUELU_ISORROPIAINTERFACE_DEF_HPP_
18#define MUELU_ISORROPIAINTERFACE_DEF_HPP_
19
21
22#include <Teuchos_Utils.hpp>
23//#include <Teuchos_DefaultMpiComm.hpp> //TODO: fwd decl.
24//#include <Teuchos_OpaqueWrapper.hpp> //TODO: fwd decl.
25
26#include <Xpetra_MapFactory.hpp>
27#include <Xpetra_CrsGraphFactory.hpp>
28#include <Xpetra_BlockedMap.hpp>
29#include <Xpetra_BlockedCrsMatrix.hpp>
30
31#include "MueLu_Level.hpp"
32#include "MueLu_Exceptions.hpp"
33#include "MueLu_Monitor.hpp"
34
35#include "MueLu_AmalgamationInfo.hpp"
36
37namespace MueLu {
38
39template <class LocalOrdinal, class GlobalOrdinal, class Node>
41 RCP<ParameterList> validParamList = rcp(new ParameterList());
42
43 validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Factory of the matrix A");
44 validParamList->set<RCP<const FactoryBase> >("number of partitions", Teuchos::null, "Instance of RepartitionHeuristicFactory.");
45 validParamList->set<RCP<const FactoryBase> >("UnAmalgamationInfo", Teuchos::null, "Generating factory of UnAmalgamationInfo");
46
47 return validParamList;
48}
49
50template <class LocalOrdinal, class GlobalOrdinal, class Node>
52 Input(currentLevel, "A");
53 Input(currentLevel, "number of partitions");
54 Input(currentLevel, "UnAmalgamationInfo");
55}
56
57template <class LocalOrdinal, class GlobalOrdinal, class Node>
59 FactoryMonitor m(*this, "Build", level);
60 typedef Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node> BlockMap;
61
62 RCP<Matrix> A = Get<RCP<Matrix> >(level, "A");
63 RCP<AmalgamationInfo> amalInfo = Get<RCP<AmalgamationInfo> >(level, "UnAmalgamationInfo");
64 GO numParts = Get<int>(level, "number of partitions");
65
66 RCP<const Map> rowMap = A->getRowMap();
67 RCP<const Map> colMap = A->getColMap();
68
69 if (numParts == 1 || numParts == -1) {
70 // Running on one processor, so decomposition is the trivial one, all zeros.
71 RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(rowMap, true);
72 Set(level, "AmalgamatedPartition", decomposition);
73 return;
74 }
75
76 // ok, reconstruct graph information of matrix A
77 // Note, this is the non-rebalanced matrix A and we need the graph
78 // of the non-rebalanced matrix A. We cannot make use of the "Graph"
79 // that is/will be built for the aggregates later for several reasons
80 // 1) the "Graph" for the aggregates is meant to be based on the rebalanced matrix A
81 // 2) we cannot call a CoalesceDropFactory::Build here since this is very complicated and
82 // completely messes up the whole factory chain
83 // 3) CoalesceDropFactory is meant to provide some minimal Graph information for the aggregation
84 // (LWGraph), but here we need the full CrsGraph for Isorropia as input
85
86 // That is, why this code is somewhat redundant to CoalesceDropFactory
87
88 LO blockdim = 1; // block dim for fixed size blocks
89 GO indexBase = rowMap->getIndexBase(); // index base of maps
90 GO offset = 0;
91 LO blockid = -1; // block id in strided map
92 LO nStridedOffset = 0; // DOF offset for strided block id "blockid" (default = 0)
93 // LO stridedblocksize = blockdim; // size of strided block id "blockid" (default = fullblocksize, only if blockid!=-1 stridedblocksize <= fullblocksize)
94
95 // 1) check for blocking/striding information
96 // fill above variables
97 if (A->IsView("stridedMaps") &&
98 Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap("stridedMaps")) != Teuchos::null) {
99 Xpetra::viewLabel_t oldView = A->SwitchToView("stridedMaps"); // note: "stridedMaps are always non-overlapping (correspond to range and domain maps!)
100 RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap());
101 TEUCHOS_TEST_FOR_EXCEPTION(strMap == Teuchos::null, Exceptions::BadCast, "MueLu::IsorropiaInterface::Build: cast to strided row map failed.");
102 blockdim = strMap->getFixedBlockSize();
103 offset = strMap->getOffset();
104 blockid = strMap->getStridedBlockId();
105 if (blockid > -1) {
106 std::vector<size_t> stridingInfo = strMap->getStridingData();
107 for (size_t j = 0; j < Teuchos::as<size_t>(blockid); j++)
108 nStridedOffset += stridingInfo[j];
109 // stridedblocksize = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
110
111 } // else {
112 // stridedblocksize = blockdim;
113 //}
114 oldView = A->SwitchToView(oldView);
115 // GetOStream(Statistics0) << "IsorropiaInterface::Build():" << " found blockdim=" << blockdim << " from strided maps (blockid=" << blockid << ", strided block size=" << stridedblocksize << "). offset=" << offset << std::endl;
116 } else
117 GetOStream(Statistics0) << "IsorropiaInterface::Build(): no striding information available. Use blockdim=1 with offset=0" << std::endl;
118
119 // 2) get row map for amalgamated matrix (graph of A)
120 // with same distribution over all procs as row map of A
121 RCP<const Map> nodeMap = amalInfo->getNodeRowMap();
122 RCP<const BlockedMap> bnodeMap = Teuchos::rcp_dynamic_cast<const BlockedMap>(nodeMap);
123 if (!bnodeMap.is_null()) nodeMap = bnodeMap->getMap();
124
125 GetOStream(Statistics0) << "IsorropiaInterface:Build(): nodeMap " << nodeMap->getLocalNumElements() << "/" << nodeMap->getGlobalNumElements() << " elements" << std::endl;
126
127 // 3) create graph of amalgamated matrix
128 RCP<CrsGraph> crsGraph = CrsGraphFactory::Build(nodeMap, A->getLocalMaxNumRowEntries() * blockdim);
129
130 // 4) do amalgamation. generate graph of amalgamated matrix
131 for (LO row = 0; row < Teuchos::as<LO>(A->getRowMap()->getLocalNumElements()); row++) {
132 // get global DOF id
133 GO grid = rowMap->getGlobalElement(row);
134
135 // translate grid to nodeid
136 // JHU 2019-20-May this is identical to AmalgamationFactory::DOFGid2NodeId(), and is done
137 // to break a circular dependence when libraries are built statically
138 GO nodeId = (grid - offset - indexBase) / blockdim + indexBase;
139
140 size_t nnz = A->getNumEntriesInLocalRow(row);
141 Teuchos::ArrayView<const LO> indices;
142 Teuchos::ArrayView<const SC> vals;
143 A->getLocalRowView(row, indices, vals);
144
145 RCP<std::vector<GO> > cnodeIds = Teuchos::rcp(new std::vector<GO>); // global column block ids
146 LO realnnz = 0;
147 for (LO col = 0; col < Teuchos::as<LO>(nnz); col++) {
148 GO gcid = colMap->getGlobalElement(indices[col]); // global column id
149
150 if (vals[col] != 0.0) {
151 // JHU 2019-20-May this is identical to AmalgamationFactory::DOFGid2NodeId(), and is done
152 // to break a circular dependence when libraries are built statically
153 GO cnodeId = (gcid - offset - indexBase) / blockdim + indexBase;
154 cnodeIds->push_back(cnodeId);
155 realnnz++; // increment number of nnz in matrix row
156 }
157 }
158
159 Teuchos::ArrayRCP<GO> arr_cnodeIds = Teuchos::arcp(cnodeIds);
160
161 if (arr_cnodeIds.size() > 0)
162 crsGraph->insertGlobalIndices(nodeId, arr_cnodeIds());
163 }
164 // fill matrix graph
165 crsGraph->fillComplete(nodeMap, nodeMap);
166
167#ifdef HAVE_MPI
168#else // if we don't have MPI
169
170 // Running on one processor, so decomposition is the trivial one, all zeros.
171 RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(rowMap, true);
172 Set(level, "AmalgamatedPartition", decomposition);
173
174#endif // HAVE_MPI
175 // throw a more helpful error message if something failed
176 // TEUCHOS_TEST_FOR_EXCEPTION(!level.IsAvailable("AmalgamatedPartition"), Exceptions::RuntimeError, "IsorropiaInterface::Build : no \'Partition\' vector available on level. Isorropia failed to build a partition of the non-repartitioned graph of A. Please make sure, that Isorropia is correctly compiled (Epetra/Tpetra).");
177
178} // Build()
179
180} // namespace MueLu
181
182//#endif //if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
183
184#endif /* MUELU_ISORROPIAINTERFACE_DEF_HPP_ */
Exception indicating invalid cast attempted.
Timer to be used in factories. Similar to Monitor but with additional timers.
void DeclareInput(Level &level) const
Specifies the data that this class needs, and the factories that generate that data.
void Build(Level &level) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Class that holds all level-specific information.
Namespace for MueLu classes and methods.
@ Statistics0
Print statistics that do not involve significant additional computation.