162 NumLocalParts_ = List.get(
"partitioner: local parts", NumLocalParts_);
163 OverlappingLevel_ = List.get(
"partitioner: overlap", OverlappingLevel_);
164 verbose_ = List.get(
"partitioner: print level", verbose_);
165 maintainSparsity_ = List.get(
"partitioner: maintain sparsity",
false);
166 typedef Teuchos::RCP< Tpetra::Map<typename GraphType::local_ordinal_type, typename GraphType::global_ordinal_type, typename GraphType::node_type>
const > map_type;
167 typedef Teuchos::RCP<Tpetra::Import<typename GraphType::local_ordinal_type, typename GraphType::global_ordinal_type, typename GraphType::node_type>
const > import_type;
172 import_type theImport = Graph_->getImporter();
173 if (theImport != Teuchos::null) List.set< import_type >(
"theImport",theImport);
174 List.set< map_type >(
"OverlapRowMap",Graph_->getRowMap());
176 if (NumLocalParts_ < 0) {
177 NumLocalParts_ = Graph_->getLocalNumRows() / (-NumLocalParts_);
179 if (NumLocalParts_ == 0) {
184 TEUCHOS_TEST_FOR_EXCEPTION(
185 NumLocalParts_ < 0 ||
186 Teuchos::as<size_t> (NumLocalParts_) > Graph_->getLocalNumRows(),
188 "Ifpack2::OverlappingPartitioner::setParameters: "
189 "Invalid NumLocalParts_ = " << NumLocalParts_ <<
".");
190 TEUCHOS_TEST_FOR_EXCEPTION(
191 OverlappingLevel_ < 0, std::runtime_error,
192 "Ifpack2::OverlappingPartitioner::setParameters: "
193 "Invalid OverlappingLevel_ = " << OverlappingLevel_ <<
".");
195 setPartitionParameters(List);
205 TEUCHOS_TEST_FOR_EXCEPTION(
206 NumLocalParts_ < 1 || OverlappingLevel_ < 0,
208 "Ifpack2::OverlappingPartitioner::compute: "
209 "Invalid NumLocalParts_ or OverlappingLevel_.");
213 const char printMsg[] =
"OverlappingPartitioner: ";
215 if (verbose_ && (Graph_->getComm()->getRank() == 0)) {
216 cout << printMsg <<
"Number of local parts = "
217 << NumLocalParts_ << endl;
218 cout << printMsg <<
"Approx. Number of global parts = "
219 << NumLocalParts_ * Graph_->getComm ()->getSize () << endl;
220 cout << printMsg <<
"Amount of overlap = "
221 << OverlappingLevel_ << endl;
225 Partition_.resize (Graph_->getLocalNumRows ());
229 TEUCHOS_TEST_FOR_EXCEPTION(
230 ! Graph_->isFillComplete (), std::runtime_error,
231 "Ifpack2::OverlappingPartitioner::compute: "
232 "The input graph must be fill complete.");
234 TEUCHOS_TEST_FOR_EXCEPTION(
235 Graph_->getGlobalNumRows () != Graph_->getGlobalNumCols (),
237 "Ifpack2::OverlappingPartitioner::compute: "
238 "The input graph must be (globally) square.");
241 computePartitions ();
244 computeOverlappingPartitions ();
256 if (Partition_.size() == 0)
259 const local_ordinal_type invalid =
260 Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
266 std::vector<size_t> sizes;
267 sizes.resize (NumLocalParts_);
270 for (
int i = 0; i < NumLocalParts_; ++i) {
274 for (
size_t i = 0; i < Graph_->getLocalNumRows (); ++i) {
275 TEUCHOS_TEST_FOR_EXCEPTION(
276 Partition_[i] >= NumLocalParts_, std::runtime_error,
277 "Ifpack2::OverlappingPartitioner::computeOverlappingPartitions: "
278 "Partition_[i] > NumLocalParts_.");
281 if (Partition_[i] != invalid) {
282 sizes[Partition_[i]]++;
287 Parts_.resize (NumLocalParts_);
288 for (
int i = 0; i < NumLocalParts_; ++i) {
289 Parts_[i].resize (sizes[i]);
293 for (
int i = 0; i < NumLocalParts_; ++i) {
297 for (
size_t i = 0; i < Graph_->getLocalNumRows (); ++i) {
298 const local_ordinal_type part = Partition_[i];
299 if (part != invalid) {
300 const size_t count = sizes[part];
301 Parts_[part][count] = i;
307 if (OverlappingLevel_ == 0) {
312 for (
int level = 1; level <= OverlappingLevel_; ++level) {
313 std::vector<std::vector<size_t> > tmp;
314 tmp.resize (NumLocalParts_);
320 int MaxNumEntries_tmp = Graph_->getLocalMaxNumRowEntries();
321 nonconst_local_inds_host_view_type Indices(
"Indices",MaxNumEntries_tmp);
322 nonconst_local_inds_host_view_type newIndices(
"newIndices",MaxNumEntries_tmp);
324 if (!maintainSparsity_) {
326 local_ordinal_type numLocalRows = Graph_->getLocalNumRows();
327 for (
int part = 0; part < NumLocalParts_ ; ++part) {
328 for (
size_t i = 0; i < Teuchos::as<size_t> (Parts_[part].size ()); ++i) {
329 const local_ordinal_type LRID = Parts_[part][i];
332 Graph_->getLocalRowCopy (LRID, Indices, numIndices);
334 for (
size_t j = 0; j < numIndices; ++j) {
336 const local_ordinal_type col = Indices[j];
337 if (col >= numLocalRows) {
342 std::vector<size_t>::iterator where =
343 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (col));
346 if (where == tmp[part].end()) {
347 tmp[part].push_back (col);
357 std::vector<size_t>::iterator where =
358 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (LRID));
362 if (where == tmp[part].end ()) {
363 tmp[part].push_back (LRID);
371 for (
int part = 0; part < NumLocalParts_ ; ++part) {
372 for (
size_t i = 0; i < Teuchos::as<size_t> (Parts_[part].size ()); ++i) {
373 const local_ordinal_type LRID = Parts_[part][i];
376 Graph_->getLocalRowCopy (LRID, Indices, numIndices);
381 Tpetra::sort(Indices,numIndices);
383 for (
size_t j = 0; j < numIndices; ++j) {
385 const local_ordinal_type col = Indices[j];
386 if (Teuchos::as<size_t> (col) >= Graph_->getLocalNumRows ()) {
391 std::vector<size_t>::iterator where =
392 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (col));
395 if (where == tmp[part].end()) {
398 size_t numNewIndices;
399 Graph_->getLocalRowCopy(col, newIndices, numNewIndices);
400 Tpetra::sort(newIndices,numNewIndices);
401 auto Indices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(Indices, 0, numIndices);
402 auto newIndices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(newIndices, 0, numNewIndices);
403 bool isSubset = std::includes(Indices_rcp.begin(),Indices_rcp.begin()+numIndices,
404 newIndices_rcp.begin(),newIndices_rcp.begin()+numNewIndices);
406 tmp[part].push_back (col);
412 std::vector<size_t>::iterator where =
413 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (LRID));
417 if (where == tmp[part].end ()) {
418 tmp[part].push_back (LRID);
430 for (
int i = 0; i < NumLocalParts_; ++i) {
431 Parts_[i].resize (tmp[i].size ());
432 for (
size_t j = 0; j < tmp[i].size (); ++j) {
433 Parts_[i][j] = tmp[i][j];