43 #ifndef IFPACK2_OVERLAPPINGPARTITIONER_DEF_HPP 44 #define IFPACK2_OVERLAPPINGPARTITIONER_DEF_HPP 48 #include "Ifpack2_ConfigDefs.hpp" 49 #include "Ifpack2_OverlappingPartitioner_decl.hpp" 50 #include "Teuchos_Array.hpp" 51 #include "Teuchos_ArrayRCP.hpp" 55 template<
class GraphType>
60 OverlappingLevel_ (0),
63 maintainSparsity_(false)
67 template<
class GraphType>
71 template<
class GraphType>
75 return NumLocalParts_;
79 template<
class GraphType>
82 return OverlappingLevel_;
86 template<
class GraphType>
87 typename GraphType::local_ordinal_type
91 TEUCHOS_TEST_FOR_EXCEPTION(
92 MyRow < 0 || Teuchos::as<size_t> (MyRow) > Graph_->getNodeNumRows (),
94 "Ifpack2::OverlappingPartitioner::operator(): " 95 "Invalid local row index " << MyRow <<
".");
97 return Partition_[MyRow];
102 template<
class GraphType>
103 typename GraphType::local_ordinal_type
105 operator() (
const local_ordinal_type i,
const local_ordinal_type j)
const 107 TEUCHOS_TEST_FOR_EXCEPTION(
108 i < 0 || i > Teuchos::as<local_ordinal_type> (NumLocalParts_),
110 "Ifpack2::OverlappingPartitioner::operator(): " 111 "Invalid local row index i=" << i <<
".");
112 TEUCHOS_TEST_FOR_EXCEPTION(
113 j < 0 || j > Teuchos::as<local_ordinal_type> (Parts_[i].size ()),
115 "Ifpack2::OverlappingPartitioner::operator(): " 116 "Invalid node index j=" << j <<
".");
121 template<
class GraphType>
126 TEUCHOS_TEST_FOR_EXCEPTION(
127 Part < 0 || Part > Teuchos::as<local_ordinal_type> (NumLocalParts_),
129 "Ifpack2::OverlappingPartitioner::numRowsInPart: " 130 "Invalid partition index Part=" << Part <<
".");
131 return Parts_[Part].size ();
135 template<
class GraphType>
139 Teuchos::ArrayRCP<local_ordinal_type>& List)
const 142 const size_t numRows = numRowsInPart (Part);
143 for (
size_t i = 0; i < numRows; ++i) {
144 List[i] = Parts_[Part][i];
149 template<
class GraphType>
150 Teuchos::ArrayView<const typename GraphType::local_ordinal_type>
153 return Partition_.view (0, Graph_->getNodeNumRows ());
157 template<
class GraphType>
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);
167 if (NumLocalParts_ < 0) {
168 NumLocalParts_ = Graph_->getNodeNumRows() / (-NumLocalParts_);
170 if (NumLocalParts_ == 0) {
175 TEUCHOS_TEST_FOR_EXCEPTION(
176 NumLocalParts_ < 0 ||
177 Teuchos::as<size_t> (NumLocalParts_) > Graph_->getNodeNumRows(),
179 "Ifpack2::OverlappingPartitioner::setParameters: " 180 "Invalid NumLocalParts_ = " << NumLocalParts_ <<
".");
181 TEUCHOS_TEST_FOR_EXCEPTION(
182 OverlappingLevel_ < 0, std::runtime_error,
183 "Ifpack2::OverlappingPartitioner::setParameters: " 184 "Invalid OverlappingLevel_ = " << OverlappingLevel_ <<
".");
186 setPartitionParameters(List);
190 template<
class GraphType>
196 TEUCHOS_TEST_FOR_EXCEPTION(
197 NumLocalParts_ < 1 || OverlappingLevel_ < 0,
199 "Ifpack2::OverlappingPartitioner::compute: " 200 "Invalid NumLocalParts_ or OverlappingLevel_.");
204 const char printMsg[] =
"OverlappingPartitioner: ";
206 if (verbose_ && (Graph_->getComm()->getRank() == 0)) {
207 cout << printMsg <<
"Number of local parts = " 208 << NumLocalParts_ << endl;
209 cout << printMsg <<
"Approx. Number of global parts = " 210 << NumLocalParts_ * Graph_->getComm ()->getSize () << endl;
211 cout << printMsg <<
"Amount of overlap = " 212 << OverlappingLevel_ << endl;
216 Partition_.resize (Graph_->getNodeNumRows ());
220 TEUCHOS_TEST_FOR_EXCEPTION(
221 ! Graph_->isFillComplete (), std::runtime_error,
222 "Ifpack2::OverlappingPartitioner::compute: " 223 "The input graph must be fill complete.");
225 TEUCHOS_TEST_FOR_EXCEPTION(
226 Graph_->getGlobalNumRows () != Graph_->getGlobalNumCols (),
228 "Ifpack2::OverlappingPartitioner::compute: " 229 "The input graph must be (globally) square.");
232 computePartitions ();
235 computeOverlappingPartitions ();
242 template<
class GraphType>
247 if (Partition_.size() == 0)
250 const local_ordinal_type invalid =
251 Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
257 std::vector<size_t> sizes;
258 sizes.resize (NumLocalParts_);
261 for (
int i = 0; i < NumLocalParts_; ++i) {
265 for (
size_t i = 0; i < Graph_->getNodeNumRows (); ++i) {
266 TEUCHOS_TEST_FOR_EXCEPTION(
267 Partition_[i] >= NumLocalParts_, std::runtime_error,
268 "Ifpack2::OverlappingPartitioner::computeOverlappingPartitions: " 269 "Partition_[i] > NumLocalParts_.");
272 if (Partition_[i] != invalid) {
273 sizes[Partition_[i]]++;
278 Parts_.resize (NumLocalParts_);
279 for (
int i = 0; i < NumLocalParts_; ++i) {
280 Parts_[i].resize (sizes[i]);
284 for (
int i = 0; i < NumLocalParts_; ++i) {
288 for (
size_t i = 0; i < Graph_->getNodeNumRows (); ++i) {
289 const local_ordinal_type part = Partition_[i];
290 if (part != invalid) {
291 const size_t count = sizes[part];
292 Parts_[part][count] = i;
298 if (OverlappingLevel_ == 0) {
303 for (
int level = 1; level <= OverlappingLevel_; ++level) {
304 std::vector<std::vector<size_t> > tmp;
305 tmp.resize (NumLocalParts_);
311 int MaxNumEntries_tmp = Graph_->getNodeMaxNumRowEntries();
312 nonconst_local_inds_host_view_type Indices(
"Indices",MaxNumEntries_tmp);
313 nonconst_local_inds_host_view_type newIndices(
"newIndices",MaxNumEntries_tmp);
315 if (!maintainSparsity_) {
317 local_ordinal_type numLocalRows = Graph_->getNodeNumRows();
318 for (
int part = 0; part < NumLocalParts_ ; ++part) {
319 for (
size_t i = 0; i < Teuchos::as<size_t> (Parts_[part].size ()); ++i) {
320 const local_ordinal_type LRID = Parts_[part][i];
323 Graph_->getLocalRowCopy (LRID, Indices, numIndices);
325 for (
size_t j = 0; j < numIndices; ++j) {
327 const local_ordinal_type col = Indices[j];
328 if (col >= numLocalRows) {
333 std::vector<size_t>::iterator where =
334 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (col));
337 if (where == tmp[part].end()) {
338 tmp[part].push_back (col);
348 std::vector<size_t>::iterator where =
349 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (LRID));
353 if (where == tmp[part].end ()) {
354 tmp[part].push_back (LRID);
362 for (
int part = 0; part < NumLocalParts_ ; ++part) {
363 for (
size_t i = 0; i < Teuchos::as<size_t> (Parts_[part].size ()); ++i) {
364 const local_ordinal_type LRID = Parts_[part][i];
367 Graph_->getLocalRowCopy (LRID, Indices, numIndices);
372 Tpetra::sort(Indices,numIndices);
374 for (
size_t j = 0; j < numIndices; ++j) {
376 const local_ordinal_type col = Indices[j];
377 if (Teuchos::as<size_t> (col) >= Graph_->getNodeNumRows ()) {
382 std::vector<size_t>::iterator where =
383 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (col));
386 if (where == tmp[part].end()) {
389 size_t numNewIndices;
390 Graph_->getLocalRowCopy(col, newIndices, numNewIndices);
391 Tpetra::sort(newIndices,numNewIndices);
392 auto Indices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(Indices, 0, numIndices);
393 auto newIndices_rcp = Kokkos::Compat::persistingView<nonconst_local_inds_host_view_type>(newIndices, 0, numNewIndices);
394 bool isSubset = std::includes(Indices_rcp.begin(),Indices_rcp.begin()+numIndices,
395 newIndices_rcp.begin(),newIndices_rcp.begin()+numNewIndices);
397 tmp[part].push_back (col);
403 std::vector<size_t>::iterator where =
404 std::find (tmp[part].begin (), tmp[part].end (), Teuchos::as<size_t> (LRID));
408 if (where == tmp[part].end ()) {
409 tmp[part].push_back (LRID);
421 for (
int i = 0; i < NumLocalParts_; ++i) {
422 Parts_[i].resize (tmp[i].size ());
423 for (
size_t j = 0; j < tmp[i].size (); ++j) {
424 Parts_[i][j] = tmp[i][j];
431 template<
class GraphType>
438 template<
class GraphType>
442 Teuchos::FancyOStream fos (Teuchos::rcpFromRef (os));
443 fos.setOutputToRootOnly (0);
449 template<
class GraphType>
452 std::ostringstream oss;
453 oss << Teuchos::Describable::description();
455 oss <<
"{status = computed";
458 oss <<
"{status = is not computed";
465 template<
class GraphType>
469 if (verbLevel == Teuchos::VERB_NONE) {
473 os <<
"================================================================================" << endl;
474 os <<
"Ifpack2::OverlappingPartitioner" << endl;
475 os <<
"Number of local rows = " << Graph_->getNodeNumRows() << endl;
476 os <<
"Number of global rows = " << Graph_->getGlobalNumRows() << endl;
477 os <<
"Number of local parts = " << NumLocalParts_ << endl;
478 os <<
"Overlapping level = " << OverlappingLevel_ << endl;
479 os <<
"Is computed = " << IsComputed_ << endl;
480 os <<
"================================================================================" << endl;
485 #define IFPACK2_OVERLAPPINGPARTITIONER_INSTANT(LO,GO,N) \ 486 template class Ifpack2::OverlappingPartitioner<Tpetra::CrsGraph< LO, GO, N > >; \ 487 template class Ifpack2::OverlappingPartitioner<Tpetra::RowGraph< LO, GO, N > >; 489 #endif // IFPACK2_OVERLAPPINGPARTITIONER_DEF_HPP virtual std::ostream & print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator<<.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:440
size_t numRowsInPart(const local_ordinal_type Part) const
the number of rows contained in the given partition.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:124
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:450
OverlappingPartitioner(const Teuchos::RCP< const row_graph_type > &graph)
Constructor.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:57
virtual void computeOverlappingPartitions()
Computes the partitions. Returns 0 if successful.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:243
int overlappingLevel() const
The number of levels of overlap.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:80
virtual ~OverlappingPartitioner()
Destructor.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:68
virtual Teuchos::ArrayView< const local_ordinal_type > nonOverlappingPartition() const
A view of the local indices of the nonoverlapping partitions of each local row.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:151
virtual void compute()
Computes the partitions. Returns 0 if successful.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:191
void rowsInPart(const local_ordinal_type Part, Teuchos::ArrayRCP< local_ordinal_type > &List) const
Fill List with the local indices of the rows in the (overlapping) partition Part. ...
Definition: Ifpack2_OverlappingPartitioner_def.hpp:138
virtual bool isComputed() const
Returns true if partitions have been computed successfully.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:432
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:466
int numLocalParts() const
Number of computed local partitions.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:73
virtual void setParameters(Teuchos::ParameterList &List)
Set all the parameters for the partitioner.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:160
local_ordinal_type operator()(const local_ordinal_type MyRow) const
Local index of the nonoverlapping partition of the given row.
Definition: Ifpack2_OverlappingPartitioner_def.hpp:89
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:73