117 NumLocalParts_ = List.get(
"partitioner: local parts", NumLocalParts_);
118 OverlappingLevel_ = List.get(
"partitioner: overlap", OverlappingLevel_);
119 verbose_ = List.get(
"partitioner: print level", verbose_);
120 maintainSparsity_ = List.get(
"partitioner: maintain sparsity",
false);
121 typedef Teuchos::RCP<Tpetra::Map<typename GraphType::local_ordinal_type, typename GraphType::global_ordinal_type, typename GraphType::node_type>
const> map_type;
122 typedef Teuchos::RCP<Tpetra::Import<typename GraphType::local_ordinal_type, typename GraphType::global_ordinal_type, typename GraphType::node_type>
const> import_type;
127 import_type theImport = Graph_->getImporter();
128 if (theImport != Teuchos::null) List.set<import_type>(
"theImport", theImport);
129 List.set<map_type>(
"OverlapRowMap", Graph_->getRowMap());
131 if (NumLocalParts_ < 0) {
132 NumLocalParts_ = Graph_->getLocalNumRows() / (-NumLocalParts_);
134 if (NumLocalParts_ == 0) {
139 TEUCHOS_TEST_FOR_EXCEPTION(
140 NumLocalParts_ < 0 ||
141 Teuchos::as<size_t>(NumLocalParts_) > Graph_->getLocalNumRows(),
143 "Ifpack2::OverlappingPartitioner::setParameters: "
144 "Invalid NumLocalParts_ = "
145 << NumLocalParts_ <<
".");
146 TEUCHOS_TEST_FOR_EXCEPTION(
147 OverlappingLevel_ < 0, std::runtime_error,
148 "Ifpack2::OverlappingPartitioner::setParameters: "
149 "Invalid OverlappingLevel_ = "
150 << OverlappingLevel_ <<
".");
152 setPartitionParameters(List);
161 TEUCHOS_TEST_FOR_EXCEPTION(
162 NumLocalParts_ < 1 || OverlappingLevel_ < 0,
164 "Ifpack2::OverlappingPartitioner::compute: "
165 "Invalid NumLocalParts_ or OverlappingLevel_.");
169 const char printMsg[] =
"OverlappingPartitioner: ";
171 if (verbose_ && (Graph_->getComm()->getRank() == 0)) {
172 cout << printMsg <<
"Number of local parts = "
173 << NumLocalParts_ << endl;
174 cout << printMsg <<
"Approx. Number of global parts = "
175 << NumLocalParts_ * Graph_->getComm()->getSize() << endl;
176 cout << printMsg <<
"Amount of overlap = "
177 << OverlappingLevel_ << endl;
181 Partition_.resize(Graph_->getLocalNumRows());
185 TEUCHOS_TEST_FOR_EXCEPTION(
186 !Graph_->isFillComplete(), std::runtime_error,
187 "Ifpack2::OverlappingPartitioner::compute: "
188 "The input graph must be fill complete.");
190 TEUCHOS_TEST_FOR_EXCEPTION(
191 Graph_->getGlobalNumRows() != Graph_->getGlobalNumCols(),
193 "Ifpack2::OverlappingPartitioner::compute: "
194 "The input graph must be (globally) square.");
200 computeOverlappingPartitions();
211 if (Partition_.size() == 0)
214 const local_ordinal_type invalid =
215 Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
221 std::vector<size_t> sizes;
222 sizes.resize(NumLocalParts_);
225 for (
int i = 0; i < NumLocalParts_; ++i) {
229 for (
size_t i = 0; i < Graph_->getLocalNumRows(); ++i) {
230 TEUCHOS_TEST_FOR_EXCEPTION(
231 Partition_[i] >= NumLocalParts_, std::runtime_error,
232 "Ifpack2::OverlappingPartitioner::computeOverlappingPartitions: "
233 "Partition_[i] > NumLocalParts_.");
236 if (Partition_[i] != invalid) {
237 sizes[Partition_[i]]++;
242 Parts_.resize(NumLocalParts_);
243 for (
int i = 0; i < NumLocalParts_; ++i) {
244 Parts_[i].resize(sizes[i]);
248 for (
int i = 0; i < NumLocalParts_; ++i) {
252 for (
size_t i = 0; i < Graph_->getLocalNumRows(); ++i) {
253 const local_ordinal_type part = Partition_[i];
254 if (part != invalid) {
255 const size_t count = sizes[part];
256 Parts_[part][count] = i;
262 if (OverlappingLevel_ == 0) {
267 for (
int level = 1; level <= OverlappingLevel_; ++level) {
268 std::vector<std::vector<size_t> > tmp;
269 tmp.resize(NumLocalParts_);
275 int MaxNumEntries_tmp = Graph_->getLocalMaxNumRowEntries();
276 nonconst_local_inds_host_view_type Indices(
"Indices", MaxNumEntries_tmp);
277 nonconst_local_inds_host_view_type newIndices(
"newIndices", MaxNumEntries_tmp);
279 if (!maintainSparsity_) {
280 local_ordinal_type numLocalRows = Graph_->getLocalNumRows();
281 for (
int part = 0; part < NumLocalParts_; ++part) {
282 for (
size_t i = 0; i < Teuchos::as<size_t>(Parts_[part].size()); ++i) {
283 const local_ordinal_type LRID = Parts_[part][i];
286 Graph_->getLocalRowCopy(LRID, Indices, numIndices);
288 for (
size_t j = 0; j < numIndices; ++j) {
290 const local_ordinal_type col = Indices[j];
291 if (col >= numLocalRows) {
296 std::vector<size_t>::iterator where =
297 std::find(tmp[part].begin(), tmp[part].end(), Teuchos::as<size_t>(col));
299 if (where == tmp[part].end()) {
300 tmp[part].push_back(col);
310 std::vector<size_t>::iterator where =
311 std::find(tmp[part].begin(), tmp[part].end(), Teuchos::as<size_t>(LRID));
315 if (where == tmp[part].end()) {
316 tmp[part].push_back(LRID);
324 for (
int part = 0; part < NumLocalParts_; ++part) {
325 for (
size_t i = 0; i < Teuchos::as<size_t>(Parts_[part].size()); ++i) {
326 const local_ordinal_type LRID = Parts_[part][i];
329 Graph_->getLocalRowCopy(LRID, Indices, numIndices);
334 Tpetra::sort(Indices, numIndices);
336 for (
size_t j = 0; j < numIndices; ++j) {
338 const local_ordinal_type col = Indices[j];
339 if (Teuchos::as<size_t>(col) >= Graph_->getLocalNumRows()) {
344 std::vector<size_t>::iterator where =
345 std::find(tmp[part].begin(), tmp[part].end(), Teuchos::as<size_t>(col));
347 if (where == tmp[part].end()) {
350 size_t numNewIndices;
351 Graph_->getLocalRowCopy(col, newIndices, numNewIndices);
352 Tpetra::sort(newIndices, numNewIndices);
353 auto Indices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(Indices, 0, numIndices);
354 auto newIndices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(newIndices, 0, numNewIndices);
355 bool isSubset = std::includes(Indices_rcp.begin(), Indices_rcp.begin() + numIndices,
356 newIndices_rcp.begin(), newIndices_rcp.begin() + numNewIndices);
358 tmp[part].push_back(col);
364 std::vector<size_t>::iterator where =
365 std::find(tmp[part].begin(), tmp[part].end(), Teuchos::as<size_t>(LRID));
369 if (where == tmp[part].end()) {
370 tmp[part].push_back(LRID);
382 for (
int i = 0; i < NumLocalParts_; ++i) {
383 Parts_[i].resize(tmp[i].size());
384 for (
size_t j = 0; j < tmp[i].size(); ++j) {
385 Parts_[i][j] = tmp[i][j];