42 #ifndef TPETRA_CRSGRAPH_DEF_HPP 43 #define TPETRA_CRSGRAPH_DEF_HPP 55 #include "Tpetra_Details_getGraphDiagOffsets.hpp" 56 #include "Tpetra_Distributor.hpp" 57 #include "Teuchos_SerialDenseMatrix.hpp" 67 template<
class LO,
class GO,
class DT,
class OffsetType,
class NumEntType>
68 class ConvertColumnIndicesFromGlobalToLocal {
70 ConvertColumnIndicesFromGlobalToLocal (const ::Kokkos::View<LO*, DT>& lclColInds,
71 const ::Kokkos::View<const GO*, DT>& gblColInds,
72 const ::Kokkos::View<const OffsetType*, DT>& ptr,
73 const ::Tpetra::Details::LocalMap<LO, GO, DT>& lclColMap,
74 const ::Kokkos::View<const NumEntType*, DT>& numRowEnt) :
75 lclColInds_ (lclColInds),
76 gblColInds_ (gblColInds),
78 lclColMap_ (lclColMap),
79 numRowEnt_ (numRowEnt)
83 operator () (
const LO& lclRow, OffsetType& curNumBad)
const 85 const OffsetType offset = ptr_(lclRow);
89 const LO numEnt =
static_cast<LO
> (numRowEnt_(lclRow));
90 for (LO j = 0; j < numEnt; ++j) {
91 const GO gid = gblColInds_(offset + j);
92 const LO lid = lclColMap_.getLocalElement (gid);
93 lclColInds_(offset + j) = lid;
101 run (const ::Kokkos::View<LO*, DT>& lclColInds,
102 const ::Kokkos::View<const GO*, DT>& gblColInds,
103 const ::Kokkos::View<const OffsetType*, DT>& ptr,
104 const ::Tpetra::Details::LocalMap<LO, GO, DT>& lclColMap,
105 const ::Kokkos::View<const NumEntType*, DT>& numRowEnt)
107 typedef ::Kokkos::RangePolicy<typename DT::execution_space, LO> range_type;
108 typedef ConvertColumnIndicesFromGlobalToLocal<LO, GO, DT, OffsetType, NumEntType> functor_type;
110 const LO lclNumRows = ptr.dimension_0 () == 0 ?
111 static_cast<LO
> (0) : static_cast<LO> (ptr.dimension_0 () - 1);
112 OffsetType numBad = 0;
114 ::Kokkos::parallel_reduce (range_type (0, lclNumRows),
115 functor_type (lclColInds, gblColInds, ptr,
116 lclColMap, numRowEnt),
122 ::Kokkos::View<LO*, DT> lclColInds_;
123 ::Kokkos::View<const GO*, DT> gblColInds_;
124 ::Kokkos::View<const OffsetType*, DT> ptr_;
126 ::Kokkos::View<const NumEntType*, DT> numRowEnt_;
145 template<
class LO,
class GO,
class DT,
class OffsetType,
class NumEntType>
148 const Kokkos::View<const GO*, DT>& gblColInds,
149 const Kokkos::View<const OffsetType*, DT>& ptr,
151 const Kokkos::View<const NumEntType*, DT>& numRowEnt)
153 using Impl::ConvertColumnIndicesFromGlobalToLocal;
154 typedef ConvertColumnIndicesFromGlobalToLocal<LO, GO, DT, OffsetType, NumEntType> impl_type;
155 return impl_type::run (lclColInds, gblColInds, ptr, lclColMap, numRowEnt);
160 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
161 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
162 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
163 size_t maxNumEntriesPerRow,
165 const Teuchos::RCP<Teuchos::ParameterList>& params) :
168 , nodeNumEntries_ (0)
169 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
171 , numAllocForAllRows_ (maxNumEntriesPerRow)
175 , indicesAreAllocated_ (false)
176 , indicesAreLocal_ (false)
177 , indicesAreGlobal_ (false)
178 , fillComplete_ (false)
179 , indicesAreSorted_ (true)
180 , noRedundancies_ (true)
181 , haveLocalConstants_ (false)
182 , haveGlobalConstants_ (false)
183 , sortGhostsAssociatedWithEachProcessor_ (true)
185 const char tfecfFuncName[] =
"CrsGraph(rowMap,maxNumEntriesPerRow," 188 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
189 maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
190 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 191 "a valid size_t value, which in this case means it must not be " 192 "Teuchos::OrdinalTraits<size_t>::invalid().");
194 checkInternalState ();
197 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
199 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
200 const Teuchos::RCP<const map_type>& colMap,
201 const size_t maxNumEntriesPerRow,
203 const Teuchos::RCP<Teuchos::ParameterList>& params) :
207 , nodeNumEntries_ (0)
208 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
210 , numAllocForAllRows_ (maxNumEntriesPerRow)
214 , indicesAreAllocated_ (false)
215 , indicesAreLocal_ (false)
216 , indicesAreGlobal_ (false)
217 , fillComplete_ (false)
218 , indicesAreSorted_ (true)
219 , noRedundancies_ (true)
220 , haveLocalConstants_ (false)
221 , haveGlobalConstants_ (false)
222 , sortGhostsAssociatedWithEachProcessor_ (true)
224 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,maxNumEntriesPerRow," 227 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
228 maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
229 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 230 "a valid size_t value, which in this case means it must not be " 231 "Teuchos::OrdinalTraits<size_t>::invalid().");
233 checkInternalState ();
236 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
238 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
239 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
241 const Teuchos::RCP<Teuchos::ParameterList>& params) :
244 , nodeNumEntries_ (0)
245 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
247 , numAllocForAllRows_ (0)
251 , indicesAreAllocated_ (false)
252 , indicesAreLocal_ (false)
253 , indicesAreGlobal_ (false)
254 , fillComplete_ (false)
255 , indicesAreSorted_ (true)
256 , noRedundancies_ (true)
257 , haveLocalConstants_ (false)
258 , haveGlobalConstants_ (false)
259 , sortGhostsAssociatedWithEachProcessor_ (true)
261 const char tfecfFuncName[] =
"CrsGraph(rowMap,numEntPerRow,pftype,params): ";
264 const size_t lclNumRows = rowMap.is_null () ?
265 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
266 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
267 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
268 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
269 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 270 "the input row Map.");
272 #ifdef HAVE_TPETRA_DEBUG 273 for (
size_t r = 0; r < lclNumRows; ++r) {
274 const size_t curRowCount = numEntPerRow[r];
275 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
276 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
277 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 278 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
280 #endif // HAVE_TPETRA_DEBUG 285 typedef decltype (k_numAllocPerRow_) out_view_type;
286 typedef typename out_view_type::non_const_type nc_view_type;
287 typedef Kokkos::View<
const size_t*,
288 typename nc_view_type::array_layout,
290 Kokkos::MemoryUnmanaged> in_view_type;
291 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
292 nc_view_type numAllocPerRowOut (
"Tpetra::CrsGraph::numAllocPerRow",
295 k_numAllocPerRow_ = numAllocPerRowOut;
298 checkInternalState ();
301 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
303 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
304 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
306 const Teuchos::RCP<Teuchos::ParameterList>& params) :
309 , nodeNumEntries_ (0)
310 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
312 , k_numAllocPerRow_ (numEntPerRow.h_view)
313 , numAllocForAllRows_ (0)
317 , indicesAreAllocated_ (false)
318 , indicesAreLocal_ (false)
319 , indicesAreGlobal_ (false)
320 , fillComplete_ (false)
321 , indicesAreSorted_ (true)
322 , noRedundancies_ (true)
323 , haveLocalConstants_ (false)
324 , haveGlobalConstants_ (false)
325 , sortGhostsAssociatedWithEachProcessor_ (true)
327 const char tfecfFuncName[] =
"CrsGraph(rowMap,numEntPerRow,pftype,params): ";
330 const size_t lclNumRows = rowMap.is_null () ?
331 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
332 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
333 static_cast<size_t> (numEntPerRow.dimension_0 ()) != lclNumRows,
334 std::invalid_argument,
"numEntPerRow has length " <<
335 numEntPerRow.dimension_0 () <<
" != the local number of rows " <<
336 lclNumRows <<
" as specified by " "the input row Map.");
338 #ifdef HAVE_TPETRA_DEBUG 339 for (
size_t r = 0; r < lclNumRows; ++r) {
340 const size_t curRowCount = numEntPerRow.h_view(r);
341 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
342 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
343 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 344 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
346 #endif // HAVE_TPETRA_DEBUG 349 checkInternalState ();
353 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
355 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
356 const Teuchos::RCP<const map_type>& colMap,
357 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
359 const Teuchos::RCP<Teuchos::ParameterList>& params) :
363 , nodeNumEntries_ (0)
364 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
366 , k_numAllocPerRow_ (numEntPerRow.h_view)
367 , numAllocForAllRows_ (0)
371 , indicesAreAllocated_ (false)
372 , indicesAreLocal_ (false)
373 , indicesAreGlobal_ (false)
374 , fillComplete_ (false)
375 , indicesAreSorted_ (true)
376 , noRedundancies_ (true)
377 , haveLocalConstants_ (false)
378 , haveGlobalConstants_ (false)
379 , sortGhostsAssociatedWithEachProcessor_ (true)
381 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype,params): ";
384 const size_t lclNumRows = rowMap.is_null () ?
385 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
386 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
387 static_cast<size_t> (numEntPerRow.dimension_0 ()) != lclNumRows,
388 std::invalid_argument,
"numEntPerRow has length " <<
389 numEntPerRow.dimension_0 () <<
" != the local number of rows " <<
390 lclNumRows <<
" as specified by " "the input row Map.");
392 #ifdef HAVE_TPETRA_DEBUG 393 for (
size_t r = 0; r < lclNumRows; ++r) {
394 const size_t curRowCount = numEntPerRow.h_view(r);
395 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
396 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
397 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 398 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
400 #endif // HAVE_TPETRA_DEBUG 403 checkInternalState ();
407 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
409 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
410 const Teuchos::RCP<const map_type>& colMap,
411 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
413 const Teuchos::RCP<Teuchos::ParameterList>& params) :
417 , nodeNumEntries_ (0)
418 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
420 , numAllocForAllRows_ (0)
424 , indicesAreAllocated_ (false)
425 , indicesAreLocal_ (false)
426 , indicesAreGlobal_ (false)
427 , fillComplete_ (false)
428 , indicesAreSorted_ (true)
429 , noRedundancies_ (true)
430 , haveLocalConstants_ (false)
431 , haveGlobalConstants_ (false)
432 , sortGhostsAssociatedWithEachProcessor_ (true)
434 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype," 438 const size_t lclNumRows = rowMap.is_null () ?
439 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
440 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
441 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
442 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
443 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 444 "the input row Map.");
446 #ifdef HAVE_TPETRA_DEBUG 447 for (
size_t r = 0; r < lclNumRows; ++r) {
448 const size_t curRowCount = numEntPerRow[r];
449 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
450 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
451 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 452 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
454 #endif // HAVE_TPETRA_DEBUG 459 typedef decltype (k_numAllocPerRow_) out_view_type;
460 typedef typename out_view_type::non_const_type nc_view_type;
461 typedef Kokkos::View<
const size_t*,
462 typename nc_view_type::array_layout,
464 Kokkos::MemoryUnmanaged> in_view_type;
465 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
466 nc_view_type numAllocPerRowOut (
"Tpetra::CrsGraph::numAllocPerRow",
469 k_numAllocPerRow_ = numAllocPerRowOut;
472 checkInternalState ();
476 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
478 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
479 const Teuchos::RCP<const map_type>& colMap,
480 const typename local_graph_type::row_map_type& rowPointers,
481 const typename local_graph_type::entries_type::non_const_type& columnIndices,
482 const Teuchos::RCP<Teuchos::ParameterList>& params) :
490 , nodeNumAllocated_(
Teuchos::OrdinalTraits<size_t>::invalid())
492 , numAllocForAllRows_(0)
493 , storageStatus_ (
Details::STORAGE_1D_PACKED)
494 , indicesAreAllocated_(true)
495 , indicesAreLocal_(true)
496 , indicesAreGlobal_(false)
497 , fillComplete_(false)
498 , indicesAreSorted_(true)
499 , noRedundancies_(true)
500 , haveLocalConstants_ (false)
501 , haveGlobalConstants_ (false)
502 , sortGhostsAssociatedWithEachProcessor_(true)
505 setAllIndices (rowPointers, columnIndices);
506 checkInternalState ();
510 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
512 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
513 const Teuchos::RCP<const map_type>& colMap,
514 const Teuchos::ArrayRCP<size_t>& rowPointers,
515 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
516 const Teuchos::RCP<Teuchos::ParameterList>& params) :
523 , nodeNumEntries_ (0)
524 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
526 , numAllocForAllRows_ (0)
527 , storageStatus_ (
Details::STORAGE_1D_PACKED)
528 , indicesAreAllocated_ (true)
529 , indicesAreLocal_ (true)
530 , indicesAreGlobal_ (false)
531 , fillComplete_ (false)
532 , indicesAreSorted_ (true)
533 , noRedundancies_ (true)
534 , haveLocalConstants_ (false)
535 , haveGlobalConstants_ (false)
536 , sortGhostsAssociatedWithEachProcessor_ (true)
539 setAllIndices (rowPointers, columnIndices);
540 checkInternalState ();
544 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
546 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
547 const Teuchos::RCP<const map_type>& colMap,
549 const Teuchos::RCP<Teuchos::ParameterList>& params)
553 , lclGraph_ (k_local_graph_)
557 , nodeNumEntries_ (0)
558 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
560 , numAllocForAllRows_ (0)
561 , storageStatus_ (
Details::STORAGE_1D_PACKED)
562 , indicesAreAllocated_ (true)
563 , indicesAreLocal_ (true)
564 , indicesAreGlobal_ (false)
565 , fillComplete_ (false)
566 , indicesAreSorted_ (true)
567 , noRedundancies_ (true)
568 , haveLocalConstants_ (false)
569 , haveGlobalConstants_ (false)
570 , sortGhostsAssociatedWithEachProcessor_(true)
573 using Teuchos::ArrayRCP;
574 using Teuchos::ParameterList;
575 using Teuchos::parameterList;
577 typedef GlobalOrdinal GO;
578 typedef LocalOrdinal LO;
581 const char tfecfFuncName[] =
"CrsGraph(Map,Map,Kokkos::LocalStaticCrsGraph)";
583 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
584 colMap.is_null (), std::runtime_error,
585 ": The input column Map must be nonnull.");
586 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
587 k_local_graph_.numRows () != rowMap->getNodeNumElements (),
589 ": The input row Map and the input local graph need to have the same " 590 "number of rows. The row Map claims " << rowMap->getNodeNumElements ()
591 <<
" row(s), but the local graph claims " << k_local_graph_.numRows ()
600 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
601 k_lclInds1D_.dimension_0 () != 0 || k_gblInds1D_.dimension_0 () != 0, std::logic_error,
602 ": cannot have 1D data structures allocated.");
603 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
604 ! lclInds2D_.is_null () || ! gblInds2D_.is_null (), std::logic_error,
605 ": cannot have 2D data structures allocated.");
607 nodeNumAllocated_ = k_local_graph_.row_map (getNodeNumRows ());
608 nodeNumEntries_ = k_local_graph_.row_map (getNodeNumRows ());
614 setDomainRangeMaps (rowMap_, rowMap_);
617 k_lclInds1D_ = lclGraph_.entries;
618 k_rowPtrs_ = lclGraph_.row_map;
620 typename local_graph_type::row_map_type d_ptrs = lclGraph_.row_map;
621 typename local_graph_type::entries_type d_inds = lclGraph_.entries;
624 upperTriangular_ =
true;
625 lowerTriangular_ =
true;
626 nodeMaxNumRowEntries_ = 0;
630 const size_t numLocalRows = getNodeNumRows ();
631 for (
size_t localRow = 0; localRow < numLocalRows; ++localRow) {
632 const GO globalRow = rowMap_->getGlobalElement (localRow);
633 const LO rlcid = colMap_->getLocalElement (globalRow);
640 if (rlcid != Teuchos::OrdinalTraits<LO>::invalid ()) {
641 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
642 rlcid + 1 >= static_cast<LO> (d_ptrs.dimension_0 ()),
643 std::runtime_error,
": The given row Map and/or column Map is/are " 644 "not compatible with the provided local graph.");
645 if (d_ptrs(rlcid) != d_ptrs(rlcid + 1)) {
646 const size_t smallestCol =
647 static_cast<size_t> (d_inds(d_ptrs(rlcid)));
648 const size_t largestCol =
649 static_cast<size_t> (d_inds(d_ptrs(rlcid + 1)-1));
650 if (smallestCol < localRow) {
651 upperTriangular_ =
false;
653 if (localRow < largestCol) {
654 lowerTriangular_ =
false;
656 for (
size_t i = d_ptrs(rlcid); i < d_ptrs(rlcid + 1); ++i) {
657 if (d_inds(i) == rlcid) {
662 nodeMaxNumRowEntries_ =
663 std::max (static_cast<size_t> (d_ptrs(rlcid + 1) - d_ptrs(rlcid)),
664 nodeMaxNumRowEntries_);
668 haveLocalConstants_ =
true;
669 computeGlobalConstants ();
671 fillComplete_ =
true;
672 checkInternalState ();
676 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
682 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
683 Teuchos::RCP<const Teuchos::ParameterList>
688 using Teuchos::ParameterList;
689 using Teuchos::parameterList;
691 RCP<ParameterList> params = parameterList (
"Tpetra::CrsGraph");
694 RCP<ParameterList> importSublist = parameterList (
"Import");
706 Distributor distributor (rowMap_->getComm (), importSublist);
707 params->set (
"Import", *importSublist,
"How the Import performs communication.");
713 params->set (
"Export", *importSublist,
"How the Export performs communication.");
719 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
724 Teuchos::RCP<const Teuchos::ParameterList> validParams =
725 getValidParameters ();
726 params->validateParametersAndSetDefaults (*validParams);
727 this->setMyParamList (params);
731 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
736 return rowMap_->getGlobalNumElements ();
740 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
745 const char tfecfFuncName[] =
"getGlobalNumCols: ";
746 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
747 ! isFillComplete () || getDomainMap ().is_null (), std::runtime_error,
748 "The graph does not have a domain Map. You may not call this method in " 750 return getDomainMap ()->getGlobalNumElements ();
754 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
759 return rowMap_.is_null () ?
static_cast<size_t> (0) :
760 rowMap_->getNodeNumElements ();
764 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
769 const char tfecfFuncName[] =
"getNodeNumCols: ";
770 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
771 ! hasColMap (), std::runtime_error,
772 "The graph does not have a column Map. You may not call this method " 773 "unless the graph has a column Map. This requires either that a custom " 774 "column Map was given to the constructor, or that fillComplete() has " 776 return colMap_.is_null () ?
static_cast<size_t> (0) :
777 colMap_->getNodeNumElements ();
781 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
786 return nodeNumDiags_;
790 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
795 return globalNumDiags_;
799 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
804 return rowMap_.is_null () ? Teuchos::null : rowMap_->
getNode ();
808 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
809 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
817 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
818 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
826 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
827 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
835 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
836 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
843 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
844 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
852 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
853 Teuchos::RCP<const Export<LocalOrdinal, GlobalOrdinal, Node> >
861 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
866 return ! colMap_.is_null ();
870 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
878 const bool isOpt = indicesAreAllocated_ &&
879 k_numRowEntries_.dimension_0 () == 0 &&
880 getNodeNumRows () > 0;
882 #ifdef HAVE_TPETRA_DEBUG 883 const char tfecfFuncName[] =
"isStorageOptimized";
884 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
886 ": The matrix claims to have optimized storage, but getProfileType() " 887 "returns DynamicProfile. This should never happen. Please report this " 888 "bug to the Tpetra developers.");
889 #endif // HAVE_TPETRA_DEBUG 895 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
904 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
909 return globalNumEntries_;
913 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
918 return nodeNumEntries_;
922 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
927 return globalMaxNumRowEntries_;
931 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
936 return nodeMaxNumRowEntries_;
940 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
945 return fillComplete_;
949 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
954 return ! fillComplete_;
958 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
963 return upperTriangular_;
967 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
972 return lowerTriangular_;
976 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
981 return indicesAreLocal_;
985 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
990 return indicesAreGlobal_;
994 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
999 return nodeNumAllocated_;
1003 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1004 Teuchos::RCP<const Teuchos::Comm<int> >
1008 return rowMap_.is_null () ? Teuchos::null : rowMap_->
getComm ();
1012 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1021 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1026 return indicesAreAllocated_;
1030 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1032 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1035 return indicesAreSorted_;
1039 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1044 return noRedundancies_;
1048 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1058 indicesAreSorted_ =
false;
1059 noRedundancies_ =
false;
1063 haveLocalConstants_ =
false;
1067 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1072 using Teuchos::arcp;
1073 using Teuchos::Array;
1074 using Teuchos::ArrayRCP;
1075 typedef Teuchos::ArrayRCP<size_t>::size_type size_type;
1076 typedef typename local_graph_type::row_map_type::non_const_type
1077 non_const_row_map_type;
1078 typedef typename local_graph_type::entries_type::non_const_type
1080 typedef Kokkos::View<GlobalOrdinal*,
1081 typename lcl_col_inds_type::array_layout,
1082 device_type> gbl_col_inds_type;
1083 const char tfecfFuncName[] =
"allocateIndices: ";
1088 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1089 isLocallyIndexed () && lg == GlobalIndices, std::logic_error,
1090 "The graph is locally indexed, but Tpetra code is calling this method " 1091 "with lg=GlobalIndices. Please report this bug to the Tpetra developers.");
1092 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1093 isGloballyIndexed () && lg == LocalIndices, std::logic_error,
1094 "The graph is globally indexed, but Tpetra code is calling this method " 1095 "with lg=LocalIndices. Please report this bug to the Tpetra developers.");
1096 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1097 indicesAreAllocated (), std::logic_error,
"The graph's indices are " 1098 "already allocated, but Tpetra code is calling allocateIndices) again. " 1099 "Please report this bug to the Tpetra developers.");
1101 const size_t numRows = getNodeNumRows ();
1103 if (getProfileType () == StaticProfile) {
1107 non_const_row_map_type k_rowPtrs (
"Tpetra::CrsGraph::ptr", numRows + 1);
1109 if (k_numAllocPerRow_.dimension_0 () != 0) {
1114 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1115 k_numAllocPerRow_.dimension_0 () != numRows, std::invalid_argument,
1116 "k_numAllocPerRow_ is allocated (has length != 0), but its length = " 1117 << k_numAllocPerRow_.dimension_0 () <<
" != numRows = " << numRows
1136 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1137 (numAllocForAllRows_ == Teuchos::OrdinalTraits<size_t>::invalid (),
1138 std::invalid_argument,
"numAllocForAllRows_ has an invalid value, " 1139 "namely Teuchos::OrdinalTraits<size_t>::invalid() = " <<
1140 Teuchos::OrdinalTraits<size_t>::invalid () <<
".");
1147 k_rowPtrs_ = k_rowPtrs;
1151 const size_type numInds =
static_cast<size_type
> (k_rowPtrs_(numRows));
1152 if (lg == LocalIndices) {
1153 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1156 k_gblInds1D_ = gbl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1158 nodeNumAllocated_ = numInds;
1159 storageStatus_ = Details::STORAGE_1D_UNPACKED;
1166 const bool useNumAllocPerRow = (k_numAllocPerRow_.dimension_0 () != 0);
1168 if (lg == LocalIndices) {
1169 lclInds2D_ = arcp<Array<LocalOrdinal> > (numRows);
1170 nodeNumAllocated_ = 0;
1171 for (
size_t i = 0; i < numRows; ++i) {
1172 const size_t howMany = useNumAllocPerRow ?
1173 k_numAllocPerRow_(i) : numAllocForAllRows_;
1174 nodeNumAllocated_ += howMany;
1176 lclInds2D_[i].resize (howMany);
1181 gblInds2D_ = arcp<Array<GlobalOrdinal> > (numRows);
1182 nodeNumAllocated_ = 0;
1183 for (
size_t i = 0; i < numRows; ++i) {
1184 const size_t howMany = useNumAllocPerRow ?
1185 k_numAllocPerRow_(i) : numAllocForAllRows_;
1186 nodeNumAllocated_ += howMany;
1188 gblInds2D_[i].resize (howMany);
1192 storageStatus_ = Details::STORAGE_2D;
1195 indicesAreLocal_ = (lg == LocalIndices);
1196 indicesAreGlobal_ = (lg == GlobalIndices);
1199 using Kokkos::ViewAllocateWithoutInitializing;
1200 typedef decltype (k_numRowEntries_) row_ent_type;
1201 const char label[] =
"Tpetra::CrsGraph::numRowEntries";
1203 row_ent_type numRowEnt (ViewAllocateWithoutInitializing (label), numRows);
1205 k_numRowEntries_ = numRowEnt;
1209 numAllocForAllRows_ = 0;
1210 k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
1211 indicesAreAllocated_ =
true;
1212 checkInternalState ();
1216 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1217 Teuchos::ArrayView<const LocalOrdinal>
1218 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1221 using Kokkos::subview;
1222 typedef LocalOrdinal LO;
1224 Kokkos::MemoryUnmanaged> row_view_type;
1226 if (rowinfo.allocSize == 0) {
1227 return Teuchos::ArrayView<const LO> ();
1230 if (k_lclInds1D_.dimension_0 () != 0) {
1231 const size_t start = rowinfo.offset1D;
1232 const size_t len = rowinfo.allocSize;
1233 const std::pair<size_t, size_t> rng (start, start + len);
1239 row_view_type rowView = subview (row_view_type (k_lclInds1D_), rng);
1240 const LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1241 return Teuchos::ArrayView<const LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1243 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1244 return lclInds2D_[rowinfo.localRow] ();
1247 return Teuchos::ArrayView<const LO> ();
1252 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1256 LocalOrdinal& numEnt,
1262 if (rowinfo.allocSize != 0) {
1263 if (k_lclInds1D_.dimension_0 () != 0) {
1264 #ifdef HAVE_TPETRA_DEBUG 1265 if (rowinfo.offset1D + rowinfo.allocSize >
1266 static_cast<size_t> (k_lclInds1D_.dimension_0 ())) {
1267 return static_cast<LocalOrdinal
> (-1);
1269 #endif // HAVE_TPETRA_DEBUG 1270 lclInds = &k_lclInds1D_[rowinfo.offset1D];
1271 numEnt = rowinfo.allocSize;
1274 #ifdef HAVE_TPETRA_DEBUG 1275 if (rowinfo.localRow >= static_cast<size_t> (lclInds2D_.size ())) {
1276 return static_cast<LocalOrdinal
> (-1);
1278 #endif // HAVE_TPETRA_DEBUG 1281 const auto& curRow = lclInds2D_[rowinfo.localRow];
1282 if (! curRow.empty ()) {
1283 lclInds = curRow.getRawPtr ();
1284 numEnt = curRow.size ();
1288 return static_cast<LocalOrdinal
> (0);
1291 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1292 Teuchos::ArrayView<LocalOrdinal>
1296 using Kokkos::subview;
1297 typedef LocalOrdinal LO;
1299 Kokkos::MemoryUnmanaged> row_view_type;
1301 if (rowinfo.allocSize == 0) {
1302 return Teuchos::ArrayView<LO> ();
1305 if (k_lclInds1D_.dimension_0 () != 0) {
1306 const size_t start = rowinfo.offset1D;
1307 const size_t len = rowinfo.allocSize;
1308 const std::pair<size_t, size_t> rng (start, start + len);
1314 row_view_type rowView = subview (row_view_type (k_lclInds1D_), rng);
1315 LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1316 return Teuchos::ArrayView<LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1318 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1319 return lclInds2D_[rowinfo.localRow] ();
1322 return Teuchos::ArrayView<LO> ();
1328 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1329 Kokkos::View<
const LocalOrdinal*,
1331 Kokkos::MemoryUnmanaged>
1335 typedef LocalOrdinal LO;
1336 typedef Kokkos::View<
const LO*, execution_space,
1337 Kokkos::MemoryUnmanaged> row_view_type;
1339 if (rowinfo.allocSize == 0) {
1340 return row_view_type ();
1343 if (k_lclInds1D_.dimension_0 () != 0) {
1344 const size_t start = rowinfo.offset1D;
1345 const size_t len = rowinfo.allocSize;
1346 const std::pair<size_t, size_t> rng (start, start + len);
1352 return Kokkos::subview (row_view_type (k_lclInds1D_), rng);
1354 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1359 Teuchos::Array<LocalOrdinal>& lclInds = lclInds2D_[rowinfo.localRow];
1360 const LO* rowPtr = lclInds.getRawPtr ();
1361 const auto rowSize = lclInds.size ();
1362 return row_view_type (rowPtr, rowSize);
1365 return row_view_type ();
1371 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1372 Kokkos::View<LocalOrdinal*,
1373 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1374 Kokkos::MemoryUnmanaged>
1375 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1376 getLocalKokkosRowViewNonConst (
const RowInfo& rowinfo)
1378 typedef LocalOrdinal LO;
1379 typedef Kokkos::View<LO*, execution_space,
1380 Kokkos::MemoryUnmanaged> row_view_type;
1382 if (rowinfo.allocSize == 0) {
1383 return row_view_type ();
1386 if (k_lclInds1D_.dimension_0 () != 0) {
1387 const size_t start = rowinfo.offset1D;
1388 const size_t len = rowinfo.allocSize;
1389 const std::pair<size_t, size_t> rng (start, start + len);
1395 return Kokkos::subview (row_view_type (k_lclInds1D_), rng);
1397 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1398 Teuchos::ArrayView<LO> rowAv = lclInds2D_[rowinfo.localRow] ();
1399 return row_view_type (rowAv.getRawPtr (), rowAv.size ());
1402 return row_view_type ();
1408 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1409 Kokkos::View<
const GlobalOrdinal*,
1410 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1411 Kokkos::MemoryUnmanaged>
1412 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1413 getGlobalKokkosRowView (
const RowInfo& rowinfo)
const 1415 typedef GlobalOrdinal GO;
1416 typedef Kokkos::View<
const GO*, execution_space,
1417 Kokkos::MemoryUnmanaged> row_view_type;
1419 if (rowinfo.allocSize == 0) {
1420 return row_view_type ();
1423 if (this->k_gblInds1D_.dimension_0 () != 0) {
1424 const size_t start = rowinfo.offset1D;
1425 const size_t len = rowinfo.allocSize;
1426 const std::pair<size_t, size_t> rng (start, start + len);
1432 return Kokkos::subview (row_view_type (this->k_gblInds1D_), rng);
1434 else if (! this->gblInds2D_[rowinfo.localRow].empty ()) {
1435 Teuchos::ArrayView<const GO> rowAv = this->gblInds2D_[rowinfo.localRow] ();
1439 return row_view_type (rowAv.getRawPtr (), rowAv.size ());
1442 return row_view_type ();
1448 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1449 Teuchos::ArrayView<const GlobalOrdinal>
1450 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1453 Teuchos::ArrayView<const GlobalOrdinal> view;
1454 if (rowinfo.allocSize > 0) {
1455 if (k_gblInds1D_.dimension_0 () != 0) {
1456 auto rng = std::make_pair (rowinfo.offset1D,
1457 rowinfo.offset1D + rowinfo.allocSize);
1464 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged = k_gblInds1D_;
1465 view = Kokkos::Compat::getConstArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1467 else if (! gblInds2D_[rowinfo.localRow].empty()) {
1468 view = gblInds2D_[rowinfo.localRow] ();
1475 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1479 LocalOrdinal& numEnt,
1485 if (rowinfo.allocSize != 0) {
1486 if (k_gblInds1D_.dimension_0 () != 0) {
1487 #ifdef HAVE_TPETRA_DEBUG 1488 if (rowinfo.offset1D + rowinfo.allocSize >
1489 static_cast<size_t> (k_gblInds1D_.dimension_0 ())) {
1490 return static_cast<LocalOrdinal
> (-1);
1492 #endif // HAVE_TPETRA_DEBUG 1493 gblInds = &k_gblInds1D_[rowinfo.offset1D];
1494 numEnt = rowinfo.allocSize;
1497 #ifdef HAVE_TPETRA_DEBUG 1498 if (rowinfo.localRow >= static_cast<size_t> (gblInds2D_.size ())) {
1499 return static_cast<LocalOrdinal
> (-1);
1501 #endif // HAVE_TPETRA_DEBUG 1502 const auto& curRow = gblInds2D_[rowinfo.localRow];
1503 if (! curRow.empty ()) {
1504 gblInds = curRow.getRawPtr ();
1505 numEnt = curRow.size ();
1509 return static_cast<LocalOrdinal
> (0);
1513 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1514 Teuchos::ArrayView<GlobalOrdinal>
1518 Teuchos::ArrayView<GlobalOrdinal> view;
1519 if (rowinfo.allocSize > 0) {
1520 if (k_gblInds1D_.dimension_0 () != 0) {
1521 auto rng = std::make_pair (rowinfo.offset1D,
1522 rowinfo.offset1D + rowinfo.allocSize);
1529 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged = k_gblInds1D_;
1530 view = Kokkos::Compat::getArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1532 else if (! gblInds2D_[rowinfo.localRow].empty()) {
1533 view = gblInds2D_[rowinfo.localRow] ();
1540 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1545 #ifdef HAVE_TPETRA_DEBUG 1546 const char tfecfFuncName[] =
"getRowInfo: ";
1547 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1548 ! hasRowInfo (), std::logic_error,
1549 "Late catch! Graph does not have row info anymore. " 1550 "Error should have been caught earlier. " 1551 "Please report this bug to the Tpetra developers.");
1552 #endif // HAVE_TPETRA_DEBUG 1554 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1556 if (! hasRowInfo () || rowMap_.is_null () ||
1557 ! rowMap_->isNodeLocalElement (myRow)) {
1558 ret.localRow = STINV;
1561 ret.offset1D = STINV;
1565 ret.localRow =
static_cast<size_t> (myRow);
1566 if (nodeNumAllocated_ != 0 && nodeNumAllocated_ != STINV) {
1571 ret.offset1D = k_rowPtrs_(myRow);
1572 ret.allocSize = k_rowPtrs_(myRow+1) - k_rowPtrs_(myRow);
1573 if (k_numRowEntries_.dimension_0 () == 0) {
1574 ret.numEntries = ret.allocSize;
1576 ret.numEntries = k_numRowEntries_(myRow);
1580 ret.offset1D = STINV;
1581 if (isLocallyIndexed ()) {
1582 ret.allocSize = lclInds2D_[myRow].size ();
1585 ret.allocSize = gblInds2D_[myRow].size ();
1587 ret.numEntries = k_numRowEntries_(myRow);
1590 else if (nodeNumAllocated_ == 0) {
1594 ret.offset1D = STINV;
1596 else if (! indicesAreAllocated ()) {
1602 const bool useNumAllocPerRow = (k_numAllocPerRow_.dimension_0 () != 0);
1603 if (useNumAllocPerRow) {
1604 ret.allocSize = k_numAllocPerRow_(myRow);
1606 ret.allocSize = numAllocForAllRows_;
1609 ret.offset1D = STINV;
1613 TEUCHOS_TEST_FOR_EXCEPT(
true);
1619 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1624 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1626 if (! this->hasRowInfo () || this->rowMap_.is_null ()) {
1627 ret.localRow = STINV;
1630 ret.offset1D = STINV;
1633 const LocalOrdinal myRow = this->rowMap_->getLocalElement (gblRow);
1634 if (myRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
1635 ret.localRow = STINV;
1638 ret.offset1D = STINV;
1642 ret.localRow =
static_cast<size_t> (myRow);
1643 if (nodeNumAllocated_ != 0 && nodeNumAllocated_ != STINV) {
1648 ret.offset1D = k_rowPtrs_(myRow);
1649 ret.allocSize = k_rowPtrs_(myRow+1) - k_rowPtrs_(myRow);
1650 if (k_numRowEntries_.dimension_0 () == 0) {
1651 ret.numEntries = ret.allocSize;
1653 ret.numEntries = k_numRowEntries_(myRow);
1657 ret.offset1D = STINV;
1658 if (isLocallyIndexed ()) {
1659 ret.allocSize = lclInds2D_[myRow].size ();
1662 ret.allocSize = gblInds2D_[myRow].size ();
1664 ret.numEntries = k_numRowEntries_(myRow);
1667 else if (nodeNumAllocated_ == 0) {
1671 ret.offset1D = STINV;
1673 else if (! indicesAreAllocated ()) {
1679 const bool useNumAllocPerRow = (k_numAllocPerRow_.dimension_0 () != 0);
1680 if (useNumAllocPerRow) {
1681 ret.allocSize = k_numAllocPerRow_(myRow);
1683 ret.allocSize = numAllocForAllRows_;
1686 ret.offset1D = STINV;
1690 TEUCHOS_TEST_FOR_EXCEPT(
true);
1696 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1701 using Teuchos::OrdinalTraits;
1702 typedef LocalOrdinal LO;
1703 typedef GlobalOrdinal GO;
1709 static_assert (
sizeof (GlobalOrdinal) >=
sizeof (LocalOrdinal),
1710 "Tpetra::CrsGraph: sizeof(GlobalOrdinal) must be >= sizeof(LocalOrdinal).");
1713 static_assert (
sizeof (
size_t) >=
sizeof (LocalOrdinal),
1714 "Tpetra::CrsGraph: sizeof(size_t) must be >= sizeof(LocalOrdinal).");
1715 static_assert (
sizeof(GST) >=
sizeof(
size_t),
1716 "Tpetra::CrsGraph: sizeof(Tpetra::global_size_t) must be >= sizeof(size_t).");
1724 const char msg[] =
"Tpetra::CrsGraph: Object cannot be created with the " 1725 "given template arguments: size assumptions are not valid.";
1726 TEUCHOS_TEST_FOR_EXCEPTION(
1727 static_cast<size_t> (Teuchos::OrdinalTraits<LO>::max ()) > Teuchos::OrdinalTraits<size_t>::max (),
1728 std::runtime_error, msg);
1729 TEUCHOS_TEST_FOR_EXCEPTION(
1730 static_cast<GST> (Teuchos::OrdinalTraits<LO>::max ()) > static_cast<GST> (Teuchos::OrdinalTraits<GO>::max ()),
1731 std::runtime_error, msg);
1732 TEUCHOS_TEST_FOR_EXCEPTION(
1733 static_cast<size_t> (Teuchos::OrdinalTraits<GO>::max ()) > Teuchos::OrdinalTraits<GST>::max(),
1734 std::runtime_error, msg);
1735 TEUCHOS_TEST_FOR_EXCEPTION(
1736 Teuchos::OrdinalTraits<size_t>::max () > Teuchos::OrdinalTraits<GST>::max (),
1737 std::runtime_error, msg);
1741 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1743 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
1745 const SLocalGlobalViews &newInds,
1746 const ELocalGlobal lg,
1747 const ELocalGlobal I)
1749 using Teuchos::ArrayView;
1750 #ifdef HAVE_TPETRA_DEBUG 1751 TEUCHOS_TEST_FOR_EXCEPTION(
1752 lg != GlobalIndices && lg != LocalIndices, std::invalid_argument,
1753 "Tpetra::CrsGraph::insertIndices: lg must be either GlobalIndices or " 1755 #endif // HAVE_TPETRA_DEBUG 1756 size_t numNewInds = 0;
1757 if (lg == GlobalIndices) {
1758 ArrayView<const GlobalOrdinal> new_ginds = newInds.ginds;
1759 numNewInds = new_ginds.size();
1760 if (I == GlobalIndices) {
1761 ArrayView<GlobalOrdinal> gind_view = getGlobalViewNonConst(rowinfo);
1762 std::copy(new_ginds.begin(), new_ginds.end(), gind_view.begin()+rowinfo.numEntries);
1764 else if (I == LocalIndices) {
1765 ArrayView<LocalOrdinal> lind_view = getLocalViewNonConst(rowinfo);
1766 typename ArrayView<const GlobalOrdinal>::iterator in = new_ginds.begin();
1767 const typename ArrayView<const GlobalOrdinal>::iterator stop = new_ginds.end();
1768 typename ArrayView<LocalOrdinal>::iterator out = lind_view.begin()+rowinfo.numEntries;
1769 while (in != stop) {
1770 *out++ = colMap_->getLocalElement (*in++);
1774 else if (lg == LocalIndices) {
1775 ArrayView<const LocalOrdinal> new_linds = newInds.linds;
1776 numNewInds = new_linds.size();
1777 if (I == LocalIndices) {
1778 ArrayView<LocalOrdinal> lind_view = getLocalViewNonConst(rowinfo);
1779 std::copy(new_linds.begin(), new_linds.end(), lind_view.begin()+rowinfo.numEntries);
1781 else if (I == GlobalIndices) {
1782 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Tpetra::CrsGraph::" 1783 "insertIndices: the case where the input indices are local and the " 1784 "indices to write are global (lg=LocalIndices, I=GlobalIndices) is " 1785 "not implemented, because it does not make sense." << std::endl <<
1786 "If you have correct local column indices, that means the graph has " 1787 "a column Map. In that case, you should be storing local indices.");
1791 k_numRowEntries_(rowinfo.localRow) += numNewInds;
1792 nodeNumEntries_ += numNewInds;
1793 setLocallyModified ();
1798 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1802 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
1804 using Kokkos::subview;
1805 typedef Kokkos::pair<size_t, size_t> range_type;
1806 const char tfecfFuncName[] =
"insertGlobalIndicesImpl: ";
1808 RowInfo rowInfo = getRowInfo(myRow);
1809 size_t numNewInds = indices.size();
1810 size_t newNumEntries = rowInfo.numEntries + numNewInds;
1812 if (newNumEntries > rowInfo.allocSize) {
1813 if (getProfileType () == StaticProfile) {
1823 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1824 (rowInfo.numEntries > rowInfo.allocSize, std::logic_error,
1825 "For local row " << myRow <<
", rowInfo.numEntries = " 1826 << rowInfo.numEntries <<
" > rowInfo.allocSize = " 1827 << rowInfo.allocSize
1828 <<
". Please report this bug to the Tpetra developers.");
1830 size_t dupCount = 0;
1831 if (k_gblInds1D_.dimension_0 () != 0) {
1832 const size_t curOffset = rowInfo.offset1D;
1833 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1834 (static_cast<size_t> (k_gblInds1D_.dimension_0 ()) < curOffset,
1835 std::logic_error,
"k_gblInds1D_.dimension_0() = " <<
1836 k_gblInds1D_.dimension_0 () <<
" < offset1D = " << curOffset
1837 <<
". Please report this bug to the Tpetra developers.");
1838 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1839 (static_cast<size_t> (k_gblInds1D_.dimension_0 ()) <
1840 curOffset + rowInfo.numEntries,
1841 std::logic_error,
"k_gblInds1D_.dimension_0() = " <<
1842 k_gblInds1D_.dimension_0 () <<
" < offset1D (= " << curOffset <<
1843 ") + rowInfo.numEntries (= " << rowInfo.numEntries <<
"). Please " 1844 "report this bug to the Tpetra developers.");
1845 const Kokkos::pair<size_t, size_t>
1846 range (curOffset, curOffset + rowInfo.numEntries);
1848 auto gblIndsCur = subview (k_gblInds1D_, range);
1849 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1850 (static_cast<size_t> (gblIndsCur.dimension_0 ()) != rowInfo.numEntries,
1851 std::logic_error,
"gblIndsCur.dimension_0() = " <<
1852 gblIndsCur.dimension_0 () <<
" != rowInfo.numEntries = " <<
1853 rowInfo.numEntries <<
". Please report this bug to the Tpetra " 1856 const size_t numInput =
static_cast<size_t> (indices.size ());
1857 for (
size_t k_new = 0; k_new < numInput; ++k_new) {
1858 const GlobalOrdinal gblIndToInsert = indices[k_new];
1859 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1860 if (gblIndsCur[k_old] == gblIndToInsert) {
1872 Teuchos::ArrayView<GlobalOrdinal> gblInds = (gblInds2D_[myRow]) ();
1873 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1874 (rowInfo.allocSize != static_cast<size_t> (gblInds.size ()),
1875 std::logic_error,
"rowInfo.allocSize = " << rowInfo.allocSize
1876 <<
" != gblInds.size() = " << gblInds.size ()
1877 <<
". Please report this bug to the Tpetra developers.");
1878 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1879 (rowInfo.numEntries > static_cast<size_t> (gblInds.size ()),
1880 std::logic_error,
"rowInfo.numEntries = " << rowInfo.numEntries
1881 <<
" > gblInds.size() = " << gblInds.size ()
1882 <<
". Please report this bug to the Tpetra developers.");
1883 auto gblIndsCur = gblInds (0, rowInfo.numEntries);
1885 const size_t numInput =
static_cast<size_t> (indices.size ());
1886 for (
size_t k_new = 0; k_new < numInput; ++k_new) {
1887 const GlobalOrdinal gblIndToInsert = indices[k_new];
1888 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1889 if (gblIndsCur[k_old] == gblIndToInsert) {
1901 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1902 (static_cast<size_t> (indices.size ()) < dupCount, std::logic_error,
1903 "indices.size() = " << indices.size () <<
" < dupCount = " <<
1904 dupCount <<
". Please report this bug to the Tpetra developers.");
1905 const size_t numNewToInsert =
1906 static_cast<size_t> (indices.size ()) - dupCount;
1908 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1909 (rowInfo.numEntries + numNewToInsert > rowInfo.allocSize,
1910 std::runtime_error,
"For local row " << myRow <<
" on Process " <<
1911 this->getComm ()->getRank () <<
", even after excluding " << dupCount
1912 <<
" duplicate(s) in input, the new number of entries " <<
1913 (rowInfo.numEntries + numNewToInsert) <<
" still exceeds this row's " 1914 "static allocation size " << rowInfo.allocSize <<
". You must " 1915 "either fix the upper bound on the number of entries in this row, " 1916 "or switch from StaticProfile to DynamicProfile.");
1918 if (k_gblInds1D_.dimension_0 () != 0) {
1919 const size_t curOffset = rowInfo.offset1D;
1921 subview (k_gblInds1D_, range_type (curOffset,
1922 curOffset + rowInfo.numEntries));
1924 subview (k_gblInds1D_, range_type (curOffset + rowInfo.numEntries,
1925 curOffset + rowInfo.allocSize));
1928 for (
size_t k_new = 0; k_new < numNewInds; ++k_new) {
1929 const GlobalOrdinal gblIndToInsert = indices[k_new];
1931 bool isAlreadyInOld =
false;
1932 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1933 if (gblIndsCur[k_old] == gblIndToInsert) {
1934 isAlreadyInOld =
true;
1938 if (! isAlreadyInOld) {
1939 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1940 (curPos >= numNewToInsert, std::logic_error,
"curPos = " <<
1941 curPos <<
" >= numNewToInsert = " << numNewToInsert <<
". " 1942 "Please report this bug to the Tpetra developers.");
1943 gblIndsNew[curPos] = gblIndToInsert;
1949 Teuchos::ArrayView<GlobalOrdinal> gblInds = (gblInds2D_[myRow]) ();
1951 auto gblIndsCur = gblInds (0, rowInfo.numEntries);
1952 auto gblIndsNew = gblInds (rowInfo.numEntries,
1953 rowInfo.allocSize - rowInfo.numEntries);
1956 for (
size_t k_new = 0; k_new < numNewInds; ++k_new) {
1957 const GlobalOrdinal gblIndToInsert = indices[k_new];
1959 bool isAlreadyInOld =
false;
1960 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1961 if (gblIndsCur[k_old] == gblIndToInsert) {
1962 isAlreadyInOld =
true;
1966 if (! isAlreadyInOld) {
1967 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1968 (curPos >= numNewToInsert, std::logic_error,
"curPos = " <<
1969 curPos <<
" >= numNewToInsert = " << numNewToInsert <<
". " 1970 "Please report this bug to the Tpetra developers.");
1971 gblIndsNew[curPos] = gblIndToInsert;
1977 k_numRowEntries_(myRow) = rowInfo.numEntries + numNewToInsert;
1978 nodeNumEntries_ += numNewToInsert;
1979 setLocallyModified ();
1981 #ifdef HAVE_TPETRA_DEBUG 1982 newNumEntries = rowInfo.numEntries + numNewToInsert;
1983 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
1984 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1985 (chkNewNumEntries != newNumEntries, std::logic_error,
1986 "After inserting new entries, getNumEntriesInLocalRow(" << myRow <<
1987 ") = " << chkNewNumEntries <<
" != newNumEntries = " << newNumEntries
1988 <<
". Please report this bug to the Tpetra developers.");
1989 #endif // HAVE_TPETRA_DEBUG 1995 size_t newAllocSize = 2*rowInfo.allocSize;
1996 if (newAllocSize < newNumEntries) {
1997 newAllocSize = newNumEntries;
1999 gblInds2D_[myRow].resize(newAllocSize);
2000 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
2005 if (k_gblInds1D_.dimension_0 () != 0) {
2006 const size_t numIndsToCopy =
static_cast<size_t> (indices.size ());
2007 const size_t offset = rowInfo.offset1D + rowInfo.numEntries;
2008 for (
size_t k = 0; k < numIndsToCopy; ++k) {
2009 k_gblInds1D_[offset + k] = indices[k];
2013 std::copy(indices.begin(), indices.end(),
2014 gblInds2D_[myRow].begin()+rowInfo.numEntries);
2017 k_numRowEntries_(myRow) += numNewInds;
2018 nodeNumEntries_ += numNewInds;
2019 setLocallyModified ();
2021 #ifdef HAVE_TPETRA_DEBUG 2023 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
2024 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2025 chkNewNumEntries != newNumEntries, std::logic_error,
2026 ": Internal logic error. Please contact Tpetra team.");
2032 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2034 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
2035 insertLocalIndicesImpl (
const LocalOrdinal myRow,
2036 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2038 using Kokkos::MemoryUnmanaged;
2039 using Kokkos::subview;
2041 typedef LocalOrdinal LO;
2042 const char* tfecfFuncName (
"insertLocallIndicesImpl");
2044 const RowInfo rowInfo = this->getRowInfo(myRow);
2045 const size_t numNewInds = indices.size();
2046 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
2047 if (newNumEntries > rowInfo.allocSize) {
2048 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2049 getProfileType() == StaticProfile, std::runtime_error,
2050 ": new indices exceed statically allocated graph structure.");
2053 size_t newAllocSize = 2*rowInfo.allocSize;
2054 if (newAllocSize < newNumEntries)
2055 newAllocSize = newNumEntries;
2056 lclInds2D_[myRow].resize(newAllocSize);
2057 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
2061 if (k_lclInds1D_.dimension_0 () != 0) {
2062 typedef View<const LO*, execution_space, MemoryUnmanaged> input_view_type;
2063 typedef View<LO*, execution_space, MemoryUnmanaged> row_view_type;
2065 input_view_type inputInds (indices.getRawPtr (), indices.size ());
2066 const size_t start = rowInfo.offset1D + rowInfo.numEntries;
2067 const std::pair<size_t, size_t> rng (start, start + newNumEntries);
2072 row_view_type myInds = subview (row_view_type (k_lclInds1D_), rng);
2076 std::copy (indices.begin (), indices.end (),
2077 lclInds2D_[myRow].begin () + rowInfo.numEntries);
2080 k_numRowEntries_(myRow) += numNewInds;
2081 nodeNumEntries_ += numNewInds;
2082 setLocallyModified ();
2083 #ifdef HAVE_TPETRA_DEBUG 2085 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
2086 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2087 chkNewNumEntries != newNumEntries, std::logic_error,
2088 ": Internal logic error. Please contact Tpetra team.");
2094 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2096 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
2099 if (rowinfo.numEntries > 0) {
2100 Teuchos::ArrayView<LocalOrdinal> inds_view =
2101 this->getLocalViewNonConst (rowinfo);
2102 std::sort (inds_view.begin (), inds_view.begin () + rowinfo.numEntries);
2107 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2112 using Teuchos::ArrayView;
2113 const char tfecfFuncName[] =
"mergeRowIndices: ";
2114 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2115 isStorageOptimized (), std::logic_error,
"The graph is already storage " 2116 "optimized, so we shouldn't be merging any indices. " 2117 "Please report this bug to the Tpetra developers.");
2119 ArrayView<LocalOrdinal> inds_view = this->getLocalViewNonConst (rowinfo);
2120 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
2121 beg = inds_view.begin();
2122 end = inds_view.begin() + rowinfo.numEntries;
2123 newend = std::unique(beg,end);
2124 const size_t mergedEntries = newend - beg;
2125 #ifdef HAVE_TPETRA_DEBUG 2128 TEUCHOS_TEST_FOR_EXCEPT( isStorageOptimized () && mergedEntries != rowinfo.numEntries );
2129 #endif // HAVE_TPETRA_DEBUG 2131 k_numRowEntries_(rowinfo.localRow) = mergedEntries;
2132 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
2136 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2140 const Teuchos::RCP<const map_type>& rangeMap)
2143 if (domainMap_ != domainMap) {
2144 domainMap_ = domainMap;
2145 importer_ = Teuchos::null;
2147 if (rangeMap_ != rangeMap) {
2148 rangeMap_ = rangeMap;
2149 exporter_ = Teuchos::null;
2154 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2159 globalNumEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2160 globalNumDiags_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2161 globalMaxNumRowEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2162 haveGlobalConstants_ =
false;
2166 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2168 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
2169 checkInternalState ()
const 2171 #ifdef HAVE_TPETRA_DEBUG 2172 const global_size_t GSTI = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2173 const size_t STI = Teuchos::OrdinalTraits<size_t>::invalid ();
2174 const char err[] =
"Tpetra::CrsGraph::checkInternalState: Likely internal " 2175 "logic error. Please contact Tpetra team.";
2180 TEUCHOS_TEST_FOR_EXCEPTION( rowMap_ == Teuchos::null, std::logic_error, err );
2182 TEUCHOS_TEST_FOR_EXCEPTION( isFillActive() == isFillComplete(), std::logic_error, err );
2184 TEUCHOS_TEST_FOR_EXCEPTION( isFillComplete() ==
true && (colMap_ == Teuchos::null || rangeMap_ == Teuchos::null || domainMap_ == Teuchos::null), std::logic_error, err );
2186 TEUCHOS_TEST_FOR_EXCEPTION( isStorageOptimized() ==
true && indicesAreAllocated() ==
false, std::logic_error, err );
2188 TEUCHOS_TEST_FOR_EXCEPTION( isStorageOptimized() ==
true && getNodeAllocationSize() != getNodeNumEntries(), std::logic_error, err );
2190 TEUCHOS_TEST_FOR_EXCEPTION( haveGlobalConstants_ ==
false && ( globalNumEntries_ != GSTI || globalNumDiags_ != GSTI || globalMaxNumRowEntries_ != GSTI ), std::logic_error, err );
2192 TEUCHOS_TEST_FOR_EXCEPTION( haveGlobalConstants_ ==
true && ( globalNumEntries_ == GSTI || globalNumDiags_ == GSTI || globalMaxNumRowEntries_ == GSTI ), std::logic_error, err );
2193 TEUCHOS_TEST_FOR_EXCEPTION( haveGlobalConstants_ ==
true && ( globalNumEntries_ < nodeNumEntries_ || globalNumDiags_ < nodeNumDiags_ || globalMaxNumRowEntries_ < nodeMaxNumRowEntries_ ),
2194 std::logic_error, err );
2196 TEUCHOS_TEST_FOR_EXCEPTION(
2197 indicesAreAllocated () && (numAllocForAllRows_ != 0 ||
2198 k_numAllocPerRow_.dimension_0 () != 0),
2199 std::logic_error, err );
2201 TEUCHOS_TEST_FOR_EXCEPTION(
2202 ! indicesAreAllocated () && (nodeNumAllocated_ != STI ||
2203 nodeNumEntries_ != 0),
2204 std::logic_error, err );
2206 TEUCHOS_TEST_FOR_EXCEPTION( isStorageOptimized() && pftype_ !=
StaticProfile, std::logic_error, err );
2213 TEUCHOS_TEST_FOR_EXCEPTION(
2214 isGloballyIndexed () && k_rowPtrs_.dimension_0 () != 0 &&
2215 (
static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != getNodeNumRows () + 1 ||
2216 k_rowPtrs_(getNodeNumRows ()) !=
static_cast<size_t> (k_gblInds1D_.dimension_0 ())),
2217 std::logic_error, err );
2219 TEUCHOS_TEST_FOR_EXCEPTION(
2220 isLocallyIndexed () && k_rowPtrs_.dimension_0 () != 0 &&
2221 (
static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != getNodeNumRows () + 1 ||
2222 k_rowPtrs_(getNodeNumRows ()) !=
static_cast<size_t> (k_lclInds1D_.dimension_0 ())),
2223 std::logic_error, err );
2228 TEUCHOS_TEST_FOR_EXCEPTION(
2230 indicesAreAllocated () &&
2231 getNodeNumRows () > 0 &&
2232 lclInds2D_.is_null () && gblInds2D_.is_null (),
2233 std::logic_error, err );
2238 TEUCHOS_TEST_FOR_EXCEPTION(
2240 indicesAreAllocated () &&
2241 getNodeNumRows () > 0 &&
2242 (k_numRowEntries_.dimension_0 () == 0 ||
2243 (lclInds2D_.is_null () && gblInds2D_.is_null ())),
2244 std::logic_error, err );
2247 TEUCHOS_TEST_FOR_EXCEPTION(
2249 (k_lclInds1D_.dimension_0 () != 0 || k_gblInds1D_.dimension_0 () != 0),
2250 std::logic_error, err );
2252 TEUCHOS_TEST_FOR_EXCEPTION(
2254 std::logic_error, err );
2257 TEUCHOS_TEST_FOR_EXCEPTION(
2259 getNodeAllocationSize () > 0 && k_lclInds1D_.dimension_0 () == 0 &&
2260 k_gblInds1D_.dimension_0 () == 0,
2261 std::logic_error, err);
2263 TEUCHOS_TEST_FOR_EXCEPTION(
2264 pftype_ ==
StaticProfile && (lclInds2D_ != Teuchos::null || gblInds2D_ != Teuchos::null),
2265 std::logic_error, err );
2268 TEUCHOS_TEST_FOR_EXCEPTION(
2269 ! indicesAreAllocated () &&
2270 ((k_rowPtrs_.dimension_0 () != 0 || k_numRowEntries_.dimension_0 () != 0) ||
2271 k_lclInds1D_.dimension_0 () != 0 || lclInds2D_ != Teuchos::null ||
2272 k_gblInds1D_.dimension_0 () != 0 || gblInds2D_ != Teuchos::null),
2273 std::logic_error, err );
2278 TEUCHOS_TEST_FOR_EXCEPTION( (indicesAreLocal_ || indicesAreGlobal_) && ! indicesAreAllocated_, std::logic_error, err );
2280 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreLocal_ ==
true && indicesAreGlobal_ ==
true, std::logic_error, err );
2282 TEUCHOS_TEST_FOR_EXCEPTION(
2283 indicesAreLocal_ && (k_gblInds1D_.dimension_0 () != 0 || gblInds2D_ != Teuchos::null),
2284 std::logic_error, err );
2286 TEUCHOS_TEST_FOR_EXCEPTION(
2287 indicesAreGlobal_ && (k_lclInds1D_.dimension_0 () != 0 || lclInds2D_ != Teuchos::null),
2288 std::logic_error, err );
2290 TEUCHOS_TEST_FOR_EXCEPTION(
2291 indicesAreLocal_ && getNodeAllocationSize () > 0 &&
2292 k_lclInds1D_.dimension_0 () == 0 && getNodeNumRows () > 0 &&
2293 lclInds2D_.is_null (),
2294 std::logic_error, err);
2296 TEUCHOS_TEST_FOR_EXCEPTION(
2297 indicesAreGlobal_ && getNodeAllocationSize () > 0 &&
2298 k_gblInds1D_.dimension_0 () == 0 && getNodeNumRows () > 0 &&
2299 gblInds2D_.is_null (),
2300 std::logic_error, err);
2302 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
true && nodeNumAllocated_ == STI, std::logic_error, err );
2304 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
false && nodeNumAllocated_ != STI, std::logic_error, err );
2306 if (indicesAreAllocated()) {
2307 size_t actualNumAllocated = 0;
2309 if (isGloballyIndexed() && gblInds2D_ != Teuchos::null) {
2310 for (
size_t r = 0; r < getNodeNumRows(); ++r) {
2311 actualNumAllocated += gblInds2D_[r].size();
2314 else if (isLocallyIndexed() && lclInds2D_ != Teuchos::null) {
2315 for (
size_t r = 0; r < getNodeNumRows(); ++r) {
2316 actualNumAllocated += lclInds2D_[r].size();
2319 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2321 else if (k_rowPtrs_.dimension_0 () != 0) {
2322 TEUCHOS_TEST_FOR_EXCEPTION(
2323 static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != getNodeNumRows () + 1,
2324 std::logic_error, err);
2326 actualNumAllocated = k_rowPtrs_(getNodeNumRows ());
2327 TEUCHOS_TEST_FOR_EXCEPTION(
2328 isLocallyIndexed () &&
2329 static_cast<size_t> (k_lclInds1D_.dimension_0 ()) != actualNumAllocated,
2330 std::logic_error, err );
2331 TEUCHOS_TEST_FOR_EXCEPTION(
2332 isGloballyIndexed () &&
2333 static_cast<size_t> (k_gblInds1D_.dimension_0 ()) != actualNumAllocated,
2334 std::logic_error, err );
2335 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2338 #endif // HAVE_TPETRA_DEBUG 2342 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2347 using Teuchos::OrdinalTraits;
2348 const LocalOrdinal lrow = rowMap_->getLocalElement (globalRow);
2349 if (hasRowInfo () && lrow != OrdinalTraits<LocalOrdinal>::invalid ()) {
2350 const RowInfo rowinfo = this->getRowInfo (lrow);
2351 return rowinfo.numEntries;
2353 return OrdinalTraits<size_t>::invalid ();
2358 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2363 if (hasRowInfo () && rowMap_->isNodeLocalElement (localRow)) {
2364 const RowInfo rowinfo = this->getRowInfo (localRow);
2365 return rowinfo.numEntries;
2367 return Teuchos::OrdinalTraits<size_t>::invalid ();
2372 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2377 const LocalOrdinal lrow = rowMap_->getLocalElement (globalRow);
2378 if (hasRowInfo () && lrow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2379 const RowInfo rowinfo = this->getRowInfo (lrow);
2380 return rowinfo.allocSize;
2382 return Teuchos::OrdinalTraits<size_t>::invalid ();
2387 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2392 if (hasRowInfo () && rowMap_->isNodeLocalElement (localRow)) {
2393 const RowInfo rowinfo = this->getRowInfo (localRow);
2394 return rowinfo.allocSize;
2396 return Teuchos::OrdinalTraits<size_t>::invalid();
2401 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2402 Teuchos::ArrayRCP<const size_t>
2406 using Kokkos::ViewAllocateWithoutInitializing;
2407 using Kokkos::create_mirror_view;
2408 using Teuchos::ArrayRCP;
2409 typedef typename local_graph_type::row_map_type row_map_type;
2410 typedef typename row_map_type::non_const_value_type row_offset_type;
2411 #ifdef HAVE_TPETRA_DEBUG 2412 const char prefix[] =
"Tpetra::CrsGraph::getNodeRowPtrs: ";
2413 const char suffix[] =
" Please report this bug to the Tpetra developers.";
2414 #endif // HAVE_TPETRA_DEBUG 2415 const size_t size = k_rowPtrs_.dimension_0 ();
2416 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
2419 return ArrayRCP<const size_t> ();
2422 ArrayRCP<const row_offset_type> ptr_rot;
2423 ArrayRCP<const size_t> ptr_st;
2428 typename row_map_type::HostMirror ptr_h = create_mirror_view (k_rowPtrs_);
2430 #ifdef HAVE_TPETRA_DEBUG 2431 TEUCHOS_TEST_FOR_EXCEPTION(
2432 ptr_h.dimension_0 () != k_rowPtrs_.dimension_0 (), std::logic_error,
2433 prefix <<
"size_t == row_offset_type, but ptr_h.dimension_0() = " 2434 << ptr_h.dimension_0 () <<
" != k_rowPtrs_.dimension_0() = " 2435 << k_rowPtrs_.dimension_0 () <<
".");
2436 TEUCHOS_TEST_FOR_EXCEPTION(
2437 same && size != 0 && k_rowPtrs_.ptr_on_device () == NULL, std::logic_error,
2438 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2439 << size <<
" != 0, but k_rowPtrs_.ptr_on_device() == NULL." << suffix);
2440 TEUCHOS_TEST_FOR_EXCEPTION(
2441 same && size != 0 && ptr_h.ptr_on_device () == NULL, std::logic_error,
2442 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2443 << size <<
" != 0, but create_mirror_view(k_rowPtrs_).ptr_on_device() " 2444 "== NULL." << suffix);
2445 #endif // HAVE_TPETRA_DEBUG 2446 ptr_rot = Kokkos::Compat::persistingView (ptr_h);
2449 typedef Kokkos::View<size_t*, device_type> ret_view_type;
2450 ret_view_type ptr_d (ViewAllocateWithoutInitializing (
"ptr"), size);
2452 typename ret_view_type::HostMirror ptr_h = create_mirror_view (ptr_d);
2454 ptr_st = Kokkos::Compat::persistingView (ptr_h);
2456 #ifdef HAVE_TPETRA_DEBUG 2457 TEUCHOS_TEST_FOR_EXCEPTION(
2458 same && size != 0 && ptr_rot.is_null (), std::logic_error,
2459 prefix <<
"size_t == row_offset_type and size = " << size
2460 <<
" != 0, but ptr_rot is null." << suffix);
2461 TEUCHOS_TEST_FOR_EXCEPTION(
2462 ! same && size != 0 && ptr_st.is_null (), std::logic_error,
2463 prefix <<
"size_t != row_offset_type and size = " << size
2464 <<
" != 0, but ptr_st is null." << suffix);
2465 #endif // HAVE_TPETRA_DEBUG 2469 #ifdef HAVE_TPETRA_DEBUG 2470 ArrayRCP<const size_t> retval =
2471 Kokkos::Impl::if_c<same,
2472 ArrayRCP<const row_offset_type>,
2473 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2474 TEUCHOS_TEST_FOR_EXCEPTION(
2475 size != 0 && retval.is_null (), std::logic_error,
2476 prefix <<
"size = " << size <<
" != 0, but retval is null." << suffix);
2479 return Kokkos::Impl::if_c<same,
2480 ArrayRCP<const row_offset_type>,
2481 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2482 #endif // HAVE_TPETRA_DEBUG 2486 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2487 Teuchos::ArrayRCP<const LocalOrdinal>
2491 return Kokkos::Compat::persistingView (k_lclInds1D_);
2495 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2499 const Teuchos::ArrayView<LocalOrdinal>&indices,
2500 size_t& numEntries)
const 2502 using Teuchos::ArrayView;
2503 typedef LocalOrdinal LO;
2504 typedef GlobalOrdinal GO;
2505 const char tfecfFuncName[] =
"getLocalRowCopy: ";
2507 TEUCHOS_TEST_FOR_EXCEPTION(
2508 isGloballyIndexed () && ! hasColMap (), std::runtime_error,
2509 "Tpetra::CrsGraph::getLocalRowCopy: The graph is globally indexed and " 2510 "does not have a column Map yet. That means we don't have local indices " 2511 "for columns yet, so it doesn't make sense to call this method. If the " 2512 "graph doesn't have a column Map yet, you should call fillComplete on " 2514 #ifdef HAVE_TPETRA_DEBUG 2515 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2516 ! hasRowInfo(), std::runtime_error,
2517 "Graph row information was deleted at fillComplete.");
2518 #endif // HAVE_TPETRA_DEBUG 2522 const RowInfo rowinfo = getRowInfo (localRow);
2524 const size_t theNumEntries = rowinfo.numEntries;
2525 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2526 static_cast<size_t> (indices.size ()) < theNumEntries, std::runtime_error,
2527 "Specified storage (size==" << indices.size () <<
") does not suffice " 2528 "to hold all " << theNumEntries <<
" entry/ies for this row.");
2529 numEntries = theNumEntries;
2531 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2532 if (isLocallyIndexed ()) {
2533 ArrayView<const LO> lview = getLocalView (rowinfo);
2534 for (
size_t j = 0; j < theNumEntries; ++j) {
2535 indices[j] = lview[j];
2538 else if (isGloballyIndexed ()) {
2539 ArrayView<const GO> gview = getGlobalView (rowinfo);
2540 for (
size_t j = 0; j < theNumEntries; ++j) {
2541 indices[j] = colMap_->getLocalElement (gview[j]);
2548 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2552 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2553 size_t& numEntries)
const 2555 using Teuchos::ArrayView;
2556 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2557 #ifdef HAVE_TPETRA_DEBUG 2558 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2559 ! hasRowInfo (), std::runtime_error,
2560 "Graph row information was deleted at fillComplete.");
2561 #endif // HAVE_TPETRA_DEBUG 2565 const RowInfo rowinfo = getRowInfoFromGlobalRowIndex (globalRow);
2566 const size_t theNumEntries = rowinfo.numEntries;
2567 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2568 static_cast<size_t> (indices.size ()) < theNumEntries, std::runtime_error,
2569 "Specified storage (size==" << indices.size () <<
") does not suffice " 2570 "to hold all " << theNumEntries <<
" entry/ies for this row.");
2571 numEntries = theNumEntries;
2573 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2574 if (isLocallyIndexed ()) {
2575 ArrayView<const LocalOrdinal> lview = getLocalView (rowinfo);
2576 for (
size_t j = 0; j < theNumEntries; ++j) {
2577 indices[j] = colMap_->getGlobalElement (lview[j]);
2580 else if (isGloballyIndexed ()) {
2581 ArrayView<const GlobalOrdinal> gview = getGlobalView (rowinfo);
2582 for (
size_t j = 0; j < theNumEntries; ++j) {
2583 indices[j] = gview[j];
2590 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2594 Teuchos::ArrayView<const LocalOrdinal>& indices)
const 2596 const char tfecfFuncName[] =
"getLocalRowView: ";
2597 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2598 isGloballyIndexed (), std::runtime_error,
"The graph's indices are " 2599 "currently stored as global indices, so we cannot return a view with " 2600 "local column indices, whether or not the graph has a column Map. If " 2601 "the graph _does_ have a column Map, use getLocalRowCopy() instead.");
2602 #ifdef HAVE_TPETRA_DEBUG 2603 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2604 ! hasRowInfo (), std::runtime_error,
"Graph row information was " 2605 "deleted at fillComplete().");
2606 #endif // HAVE_TPETRA_DEBUG 2610 const RowInfo rowInfo = getRowInfo (localRow);
2611 indices = Teuchos::null;
2612 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
2613 rowInfo.numEntries > 0) {
2614 indices = this->getLocalView (rowInfo);
2619 indices = indices (0, rowInfo.numEntries);
2622 #ifdef HAVE_TPETRA_DEBUG 2623 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2624 (static_cast<size_t> (indices.size ()) !=
2625 getNumEntriesInLocalRow (localRow), std::logic_error,
"indices.size() " 2626 "= " << indices.size () <<
" != getNumEntriesInLocalRow(localRow=" <<
2627 localRow <<
") = " << getNumEntriesInLocalRow (localRow) <<
2628 ". Please report this bug to the Tpetra developers.");
2629 #endif // HAVE_TPETRA_DEBUG 2633 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2637 Teuchos::ArrayView<const GlobalOrdinal>& indices)
const 2639 const char tfecfFuncName[] =
"getGlobalRowView: ";
2640 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2641 isLocallyIndexed (), std::runtime_error,
"The graph's indices are " 2642 "currently stored as local indices, so we cannot return a view with " 2643 "global column indices. Use getGlobalRowCopy() instead.");
2644 #ifdef HAVE_TPETRA_DEBUG 2645 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2646 ! hasRowInfo (), std::runtime_error,
2647 "Graph row information was deleted at fillComplete().");
2648 #endif // HAVE_TPETRA_DEBUG 2652 const RowInfo rowInfo = getRowInfoFromGlobalRowIndex (globalRow);
2653 indices = Teuchos::null;
2654 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
2655 rowInfo.numEntries > 0) {
2656 indices = (this->getGlobalView (rowInfo)) (0, rowInfo.numEntries);
2659 #ifdef HAVE_TPETRA_DEBUG 2660 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2661 (static_cast<size_t> (indices.size ()) != getNumEntriesInGlobalRow (globalRow),
2662 std::logic_error,
"indices.size() = " << indices.size ()
2663 <<
" != getNumEntriesInGlobalRow(globalRow=" << globalRow <<
") = " 2664 << getNumEntriesInGlobalRow (globalRow)
2665 <<
". Please report this bug to the Tpetra developers.");
2666 #endif // HAVE_TPETRA_DEBUG 2670 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2674 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2676 const char tfecfFuncName[] =
"insertLocalIndices";
2678 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2679 ! isFillActive (), std::runtime_error,
2680 ": requires that fill is active.");
2681 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2682 isGloballyIndexed (), std::runtime_error,
2683 ": graph indices are global; use insertGlobalIndices().");
2684 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2685 ! hasColMap (), std::runtime_error,
2686 ": cannot insert local indices without a column map.");
2687 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2688 ! rowMap_->isNodeLocalElement (localRow), std::runtime_error,
2689 ": row does not belong to this node.");
2690 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2691 ! hasRowInfo (), std::runtime_error,
2692 ": graph row information was deleted at fillComplete().");
2693 if (! indicesAreAllocated ()) {
2694 allocateIndices (LocalIndices);
2697 #ifdef HAVE_TPETRA_DEBUG 2703 using Teuchos::Array;
2704 using Teuchos::toString;
2706 typedef typename Teuchos::ArrayView<const LocalOrdinal>::size_type size_type;
2708 const map_type& colMap = * (getColMap ());
2709 Array<LocalOrdinal> badColInds;
2710 bool allInColMap =
true;
2711 for (size_type k = 0; k < indices.size (); ++k) {
2713 allInColMap =
false;
2714 badColInds.push_back (indices[k]);
2717 if (! allInColMap) {
2718 std::ostringstream os;
2719 os <<
"Tpetra::CrsMatrix::insertLocalIndices: You attempted to insert " 2720 "entries in owned row " << localRow <<
", at the following column " 2721 "indices: " << toString (indices) <<
"." << endl;
2722 os <<
"Of those, the following indices are not in the column Map on " 2723 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2724 "the graph has a column Map already, it is invalid to insert entries " 2725 "at those locations.";
2726 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2729 #endif // HAVE_TPETRA_DEBUG 2731 insertLocalIndicesImpl (localRow, indices);
2733 #ifdef HAVE_TPETRA_DEBUG 2734 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2735 indicesAreAllocated() ==
false || isLocallyIndexed() ==
false,
2737 ": Violated stated post-conditions. Please contact Tpetra team.");
2741 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2745 const LocalOrdinal numEnt,
2746 const LocalOrdinal inds[])
2748 Teuchos::ArrayView<const LocalOrdinal> indsT (inds, numEnt);
2749 this->insertLocalIndices (localRow, indsT);
2752 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2756 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2758 typedef LocalOrdinal LO;
2759 const char tfecfFuncName[] =
"insertLocalIndicesFiltered";
2761 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2762 isFillActive() ==
false, std::runtime_error,
2763 ": requires that fill is active.");
2764 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2765 isGloballyIndexed() ==
true, std::runtime_error,
2766 ": graph indices are global; use insertGlobalIndices().");
2767 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2768 hasColMap() ==
false, std::runtime_error,
2769 ": cannot insert local indices without a column map.");
2770 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2771 rowMap_->isNodeLocalElement(localRow) ==
false, std::runtime_error,
2772 ": row does not belong to this node.");
2773 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2774 ! hasRowInfo (), std::runtime_error,
2775 ": graph row information was deleted at fillComplete().");
2776 if (! indicesAreAllocated ()) {
2777 allocateIndices (LocalIndices);
2782 Teuchos::Array<LO> filtered_indices (indices);
2783 SLocalGlobalViews inds_view;
2784 SLocalGlobalNCViews inds_ncview;
2785 inds_ncview.linds = filtered_indices();
2786 const size_t numFilteredEntries =
2787 filterIndices<LocalIndices>(inds_ncview);
2788 inds_view.linds = filtered_indices (0, numFilteredEntries);
2789 insertLocalIndicesImpl(localRow, inds_view.linds);
2792 insertLocalIndicesImpl(localRow, indices);
2794 #ifdef HAVE_TPETRA_DEBUG 2795 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2796 indicesAreAllocated() ==
false || isLocallyIndexed() ==
false,
2798 ": Violated stated post-conditions. Please contact Tpetra team.");
2803 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2807 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2809 using Teuchos::Array;
2810 using Teuchos::ArrayView;
2811 typedef LocalOrdinal LO;
2812 typedef GlobalOrdinal GO;
2813 typedef typename ArrayView<const GO>::size_type size_type;
2814 const char tfecfFuncName[] =
"insertGlobalIndices";
2816 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2817 isLocallyIndexed() ==
true, std::runtime_error,
2818 ": graph indices are local; use insertLocalIndices().");
2819 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2820 ! hasRowInfo (), std::runtime_error,
2821 ": graph row information was deleted at fillComplete().");
2826 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2827 isFillActive() ==
false, std::runtime_error,
2828 ": You are not allowed to call this method if fill is not active. " 2829 "If fillComplete has been called, you must first call resumeFill " 2830 "before you may insert indices.");
2831 if (! indicesAreAllocated ()) {
2832 allocateIndices (GlobalIndices);
2834 const LO myRow = rowMap_->getLocalElement (grow);
2835 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2836 #ifdef HAVE_TPETRA_DEBUG 2839 const map_type& colMap = * (getColMap ());
2844 Array<GO> badColInds;
2845 bool allInColMap =
true;
2846 for (size_type k = 0; k < indices.size (); ++k) {
2848 allInColMap =
false;
2849 badColInds.push_back (indices[k]);
2852 if (! allInColMap) {
2853 std::ostringstream os;
2854 os <<
"Tpetra::CrsGraph::insertGlobalIndices: You attempted to insert " 2855 "entries in owned row " << grow <<
", at the following column " 2856 "indices: " << toString (indices) <<
"." << endl;
2857 os <<
"Of those, the following indices are not in the column Map on " 2858 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2859 "the matrix has a column Map already, it is invalid to insert " 2860 "entries at those locations.";
2861 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2864 #endif // HAVE_TPETRA_DEBUG 2865 insertGlobalIndicesImpl (myRow, indices);
2868 const size_type numIndices = indices.size ();
2872 std::vector<GO>& nonlocalRow = nonlocals_[grow];
2873 for (size_type k = 0; k < numIndices; ++k) {
2874 nonlocalRow.push_back (indices[k]);
2877 #ifdef HAVE_TPETRA_DEBUG 2878 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2879 indicesAreAllocated() ==
false || isGloballyIndexed() ==
false,
2881 ": Violated stated post-conditions. Please contact Tpetra team.");
2886 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2890 const LocalOrdinal numEnt,
2891 const GlobalOrdinal inds[])
2893 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
2894 this->insertGlobalIndices (globalRow, indsT);
2898 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2902 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2904 using Teuchos::Array;
2905 using Teuchos::ArrayView;
2906 typedef LocalOrdinal LO;
2907 typedef GlobalOrdinal GO;
2908 const char tfecfFuncName[] =
"insertGlobalIndicesFiltered";
2910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2911 isLocallyIndexed() ==
true, std::runtime_error,
2912 ": graph indices are local; use insertLocalIndices().");
2913 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2914 ! hasRowInfo (), std::runtime_error,
2915 ": graph row information was deleted at fillComplete().");
2920 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2921 isFillActive() ==
false, std::runtime_error,
2922 ": You are not allowed to call this method if fill is not active. " 2923 "If fillComplete has been called, you must first call resumeFill " 2924 "before you may insert indices.");
2925 if (! indicesAreAllocated ()) {
2926 allocateIndices (GlobalIndices);
2928 const LO myRow = rowMap_->getLocalElement (grow);
2929 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2932 Array<GO> filtered_indices(indices);
2933 SLocalGlobalViews inds_view;
2934 SLocalGlobalNCViews inds_ncview;
2935 inds_ncview.ginds = filtered_indices();
2936 const size_t numFilteredEntries =
2937 filterIndices<GlobalIndices> (inds_ncview);
2938 inds_view.ginds = filtered_indices (0, numFilteredEntries);
2939 insertGlobalIndicesImpl(myRow, inds_view.ginds);
2942 insertGlobalIndicesImpl(myRow, indices);
2946 typedef typename ArrayView<const GO>::size_type size_type;
2947 const size_type numIndices = indices.size ();
2948 for (size_type k = 0; k < numIndices; ++k) {
2949 nonlocals_[grow].push_back (indices[k]);
2952 #ifdef HAVE_TPETRA_DEBUG 2953 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2954 indicesAreAllocated() ==
false || isGloballyIndexed() ==
false,
2956 ": Violated stated post-conditions. Please contact Tpetra team.");
2961 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2966 const char tfecfFuncName[] =
"removeLocalIndices: ";
2967 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2968 ! isFillActive (), std::runtime_error,
"requires that fill is active.");
2969 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2970 isStorageOptimized (), std::runtime_error,
2971 "cannot remove indices after optimizeStorage() has been called.");
2972 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2973 isGloballyIndexed (), std::runtime_error,
"graph indices are global.");
2974 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2975 ! rowMap_->isNodeLocalElement (lrow), std::runtime_error,
2976 "Local row " << lrow <<
" is not in the row Map on the calling process.");
2977 if (! indicesAreAllocated ()) {
2978 allocateIndices (LocalIndices);
2983 clearGlobalConstants ();
2985 if (k_numRowEntries_.dimension_0 () != 0) {
2986 const size_t oldNumEntries = k_numRowEntries_(lrow);
2987 nodeNumEntries_ -= oldNumEntries;
2988 k_numRowEntries_(lrow) = 0;
2990 #ifdef HAVE_TPETRA_DEBUG 2991 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2992 getNumEntriesInLocalRow (lrow) != 0 ||
2993 ! indicesAreAllocated () ||
2994 ! isLocallyIndexed (), std::logic_error,
2995 ": Violated stated post-conditions. Please contact Tpetra team.");
2996 #endif // HAVE_TPETRA_DEBUG 3000 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3004 const typename local_graph_type::entries_type::non_const_type& columnIndices)
3006 const char tfecfFuncName[] =
"setAllIndices: ";
3007 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3008 ! hasColMap () || getColMap ().is_null (), std::runtime_error,
3009 "The graph must have a column Map before you may call this method.");
3010 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3011 static_cast<size_t> (rowPointers.size ()) != this->getNodeNumRows () + 1,
3012 std::runtime_error,
"rowPointers.size() = " << rowPointers.size () <<
3013 " != this->getNodeNumRows()+1 = " << (this->getNodeNumRows () + 1) <<
3019 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3020 k_lclInds1D_.dimension_0 () != 0 || k_gblInds1D_.dimension_0 () != 0,
3021 std::runtime_error,
"You may not call this method if 1-D data structures " 3022 "are already allocated.");
3024 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3025 lclInds2D_ != Teuchos::null || gblInds2D_ != Teuchos::null,
3026 std::runtime_error,
"You may not call this method if 2-D data structures " 3027 "are already allocated.");
3029 const size_t localNumEntries = rowPointers(getNodeNumRows ());
3031 indicesAreAllocated_ =
true;
3032 indicesAreLocal_ =
true;
3034 k_lclInds1D_ = columnIndices;
3035 k_rowPtrs_ = rowPointers;
3036 nodeNumAllocated_ = localNumEntries;
3037 nodeNumEntries_ = localNumEntries;
3045 numAllocForAllRows_ = 0;
3046 k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
3048 checkInternalState ();
3052 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3056 const Teuchos::ArrayRCP<LocalOrdinal>& columnIndices)
3059 typedef typename local_graph_type::row_map_type row_map_type;
3060 typedef typename row_map_type::array_layout layout_type;
3061 typedef typename row_map_type::non_const_value_type row_offset_type;
3062 typedef View<
size_t*, layout_type , Kokkos::HostSpace,
3063 Kokkos::MemoryUnmanaged> input_view_type;
3064 typedef typename row_map_type::non_const_type nc_row_map_type;
3066 const size_t size =
static_cast<size_t> (rowPointers.size ());
3067 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
3068 input_view_type ptr_in (rowPointers.getRawPtr (), size);
3070 nc_row_map_type ptr_rot (
"Tpetra::CrsGraph::ptr", size);
3076 input_view_type ptr_decoy (rowPointers.getRawPtr (), size);
3079 input_view_type>::select (ptr_rot, ptr_decoy),
3084 const bool inHostMemory =
3085 Kokkos::Impl::is_same<
typename row_map_type::memory_space,
3086 Kokkos::HostSpace>::value;
3097 View<size_t*, layout_type ,execution_space > ptr_st (
"Tpetra::CrsGraph::ptr", size);
3107 Kokkos::View<LocalOrdinal*, layout_type , execution_space > k_ind =
3108 Kokkos::Compat::getKokkosViewDeepCopy<device_type> (columnIndices ());
3109 setAllIndices (ptr_rot, k_ind);
3113 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3117 size_t& boundForAllLocalRows,
3118 bool& boundSameForAllLocalRows)
const 3123 Teuchos::ArrayRCP<const size_t> numEntriesPerRow;
3124 size_t numEntriesForAll = 0;
3125 bool allRowsSame =
true;
3127 const ptrdiff_t numRows =
static_cast<ptrdiff_t
> (this->getNodeNumRows ());
3129 if (! this->indicesAreAllocated ()) {
3130 if (k_numAllocPerRow_.dimension_0 () != 0) {
3135 numEntriesPerRow = Kokkos::Compat::persistingView (k_numAllocPerRow_);
3136 allRowsSame =
false;
3139 numEntriesForAll = numAllocForAllRows_;
3143 else if (k_numRowEntries_.dimension_0 () != 0) {
3148 numEntriesPerRow = Kokkos::Compat::persistingView (k_numRowEntries_);
3149 allRowsSame =
false;
3151 else if (this->nodeNumAllocated_ == 0) {
3152 numEntriesForAll = 0;
3158 TEUCHOS_TEST_FOR_EXCEPTION(
3160 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 3161 "The graph is not StaticProfile, but storage appears to be optimized. " 3162 "Please report this bug to the Tpetra developers.");
3163 TEUCHOS_TEST_FOR_EXCEPTION(
3164 numRows != 0 && k_rowPtrs_.dimension_0 () == 0, std::logic_error,
3165 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 3166 "The graph has " << numRows <<
" (> 0) row" << (numRows != 1 ?
"s" :
"")
3167 <<
" on the calling process, but the k_rowPtrs_ array has zero entries. " 3168 "Please report this bug to the Tpetra developers.");
3170 Teuchos::ArrayRCP<size_t> numEnt;
3172 numEnt = Teuchos::arcp<size_t> (numRows);
3177 bool allRowsReallySame =
false;
3178 for (ptrdiff_t i = 0; i < numRows; ++i) {
3179 numEnt[i] = k_rowPtrs_(i+1) - k_rowPtrs_(i);
3180 if (i != 0 && numEnt[i] != numEnt[i-1]) {
3181 allRowsReallySame =
false;
3184 if (allRowsReallySame) {
3186 numEntriesForAll = 0;
3188 numEntriesForAll = numEnt[1] - numEnt[0];
3193 numEntriesPerRow = numEnt;
3194 allRowsSame =
false;
3198 TEUCHOS_TEST_FOR_EXCEPTION(
3199 numEntriesForAll != 0 && numEntriesPerRow.size () != 0, std::logic_error,
3200 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3201 "numEntriesForAll and numEntriesPerRow are not consistent. The former " 3202 "is nonzero (" << numEntriesForAll <<
"), but the latter has nonzero " 3203 "size " << numEntriesPerRow.size () <<
". " 3204 "Please report this bug to the Tpetra developers.");
3205 TEUCHOS_TEST_FOR_EXCEPTION(
3206 numEntriesForAll != 0 && ! allRowsSame, std::logic_error,
3207 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3208 "numEntriesForAll and allRowsSame are not consistent. The former " 3209 "is nonzero (" << numEntriesForAll <<
"), but the latter is false. " 3210 "Please report this bug to the Tpetra developers.");
3211 TEUCHOS_TEST_FOR_EXCEPTION(
3212 numEntriesPerRow.size () != 0 && allRowsSame, std::logic_error,
3213 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3214 "numEntriesPerRow and allRowsSame are not consistent. The former has " 3215 "nonzero length " << numEntriesForAll <<
", but the latter is true. " 3216 "Please report this bug to the Tpetra developers.");
3218 boundPerLocalRow = numEntriesPerRow;
3219 boundForAllLocalRows = numEntriesForAll;
3220 boundSameForAllLocalRows = allRowsSame;
3224 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3229 using Teuchos::Comm;
3230 using Teuchos::outArg;
3233 using Teuchos::REDUCE_MAX;
3234 using Teuchos::REDUCE_MIN;
3235 using Teuchos::reduceAll;
3237 typedef LocalOrdinal LO;
3238 typedef GlobalOrdinal GO;
3239 typedef typename Teuchos::Array<GO>::size_type size_type;
3240 const char tfecfFuncName[] =
"globalAssemble: ";
3242 RCP<const Comm<int> > comm = getComm ();
3244 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3245 (! isFillActive (), std::runtime_error,
"Fill must be active before " 3246 "you may call this method.");
3248 const size_t myNumNonlocalRows = nonlocals_.size ();
3255 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
3256 int someoneHasNonlocalRows = 0;
3257 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
3258 outArg (someoneHasNonlocalRows));
3259 if (someoneHasNonlocalRows == 0) {
3273 RCP<const map_type> nonlocalRowMap;
3275 Teuchos::ArrayRCP<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
3277 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
3278 size_type curPos = 0;
3279 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
3280 ++mapIter, ++curPos) {
3281 myNonlocalGblRows[curPos] = mapIter->first;
3282 std::vector<GO>& gblCols = mapIter->second;
3283 std::sort (gblCols.begin (), gblCols.end ());
3284 auto vecLast = std::unique (gblCols.begin (), gblCols.end ());
3285 gblCols.erase (vecLast, gblCols.end ());
3286 numEntPerNonlocalRow[curPos] = gblCols.size ();
3297 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
3299 auto iter = std::min_element (myNonlocalGblRows.begin (),
3300 myNonlocalGblRows.end ());
3301 if (iter != myNonlocalGblRows.end ()) {
3302 myMinNonlocalGblRow = *iter;
3305 GO gblMinNonlocalGblRow = 0;
3306 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
3307 outArg (gblMinNonlocalGblRow));
3308 const GO indexBase = gblMinNonlocalGblRow;
3309 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
3310 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
3318 RCP<crs_graph_type> nonlocalGraph =
3319 rcp (
new crs_graph_type (nonlocalRowMap, numEntPerNonlocalRow,
3322 size_type curPos = 0;
3323 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
3324 ++mapIter, ++curPos) {
3325 const GO gblRow = mapIter->first;
3326 std::vector<GO>& gblCols = mapIter->second;
3327 const LO numEnt =
static_cast<LO
> (numEntPerNonlocalRow[curPos]);
3328 nonlocalGraph->insertGlobalIndices (gblRow, numEnt, gblCols.data ());
3340 auto origRowMap = this->getRowMap ();
3341 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
3343 if (origRowMapIsOneToOne) {
3344 export_type exportToOrig (nonlocalRowMap, origRowMap);
3354 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
3360 crs_graph_type oneToOneGraph (oneToOneRowMap, 0);
3362 oneToOneGraph.doExport (*nonlocalGraph, exportToOneToOne,
Tpetra::INSERT);
3366 nonlocalGraph = Teuchos::null;
3369 import_type importToOrig (oneToOneRowMap, origRowMap);
3377 decltype (nonlocals_) newNonlocals;
3378 std::swap (nonlocals_, newNonlocals);
3380 checkInternalState ();
3384 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3389 const char tfecfFuncName[] =
"resumeFill";
3390 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(! hasRowInfo(), std::runtime_error,
3391 ": Sorry, you cannot resume fill of the CrsGraph, since the graph's row " 3392 "information was deleted in fillComplete().");
3394 #ifdef HAVE_TPETRA_DEBUG 3395 Teuchos::barrier( *rowMap_->getComm() );
3396 #endif // HAVE_TPETRA_DEBUG 3397 clearGlobalConstants();
3398 if (params != Teuchos::null) this->setParameterList (params);
3399 lowerTriangular_ =
false;
3400 upperTriangular_ =
false;
3402 indicesAreSorted_ =
true;
3403 noRedundancies_ =
true;
3404 fillComplete_ =
false;
3405 #ifdef HAVE_TPETRA_DEBUG 3406 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3407 ! isFillActive() || isFillComplete(), std::logic_error,
3408 "::resumeFill(): At end of method, either fill is not active or fill is " 3409 "complete. This violates stated post-conditions. Please report this bug " 3410 "to the Tpetra developers.");
3411 #endif // HAVE_TPETRA_DEBUG 3415 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3430 Teuchos::RCP<const map_type> domMap = this->getDomainMap ();
3431 if (domMap.is_null ()) {
3432 domMap = this->getRowMap ();
3434 Teuchos::RCP<const map_type> ranMap = this->getRangeMap ();
3435 if (ranMap.is_null ()) {
3436 ranMap = this->getRowMap ();
3438 this->fillComplete (domMap, ranMap, params);
3442 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3446 const Teuchos::RCP<const map_type>& rangeMap,
3447 const Teuchos::RCP<Teuchos::ParameterList>& params)
3449 const char tfecfFuncName[] =
"fillComplete";
3451 #ifdef HAVE_TPETRA_DEBUG 3452 rowMap_->
getComm ()->barrier ();
3453 #endif // HAVE_TPETRA_DEBUG 3455 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! isFillActive() || isFillComplete(),
3456 std::runtime_error,
": Graph fill state must be active (isFillActive() " 3457 "must be true) before calling fillComplete().");
3459 const int numProcs = getComm ()->getSize ();
3467 if (! params.is_null ()) {
3468 if (params->isParameter (
"sort column map ghost gids")) {
3469 sortGhostsAssociatedWithEachProcessor_ =
3470 params->get<
bool> (
"sort column map ghost gids",
3471 sortGhostsAssociatedWithEachProcessor_);
3473 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3474 sortGhostsAssociatedWithEachProcessor_ =
3475 params->get<
bool> (
"Sort column Map ghost GIDs",
3476 sortGhostsAssociatedWithEachProcessor_);
3482 bool assertNoNonlocalInserts =
false;
3483 if (! params.is_null ()) {
3484 assertNoNonlocalInserts =
3485 params->get<
bool> (
"No Nonlocal Changes", assertNoNonlocalInserts);
3491 if (! indicesAreAllocated ()) {
3494 allocateIndices (LocalIndices);
3497 allocateIndices (GlobalIndices);
3505 const bool mayNeedGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3506 if (mayNeedGlobalAssemble) {
3512 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3513 numProcs > 1 && nonlocals_.size() > 0, std::runtime_error,
3514 ":" << std::endl <<
"The graph's communicator contains only one " 3515 "process, but there are nonlocal entries. " << std::endl <<
3516 "This probably means that invalid entries were added to the graph.");
3521 setDomainRangeMaps (domainMap, rangeMap);
3527 if (! hasColMap ()) {
3533 makeIndicesLocal ();
3535 if (! isSorted ()) {
3545 makeImportExport ();
3546 computeGlobalConstants ();
3547 fillLocalGraph (params);
3548 fillComplete_ =
true;
3550 #ifdef HAVE_TPETRA_DEBUG 3551 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3552 isFillActive() ==
true || isFillComplete() ==
false, std::logic_error,
3553 ": Violated stated post-conditions. Please contact Tpetra team.");
3556 checkInternalState ();
3560 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3564 const Teuchos::RCP<const map_type>& rangeMap,
3565 const Teuchos::RCP<const import_type>& importer,
3566 const Teuchos::RCP<const export_type>& exporter,
3567 const Teuchos::RCP<Teuchos::ParameterList>& params)
3569 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
3570 #ifdef HAVE_TPETRA_MMM_TIMINGS 3572 if(!params.is_null())
3573 label = params->get(
"Timer Label",label);
3574 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
3575 using Teuchos::TimeMonitor;
3576 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Setup"))));
3580 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3581 domainMap.is_null () || rangeMap.is_null (),
3582 std::runtime_error,
"The input domain Map and range Map must be nonnull.");
3583 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3584 pftype_ !=
StaticProfile, std::runtime_error,
"You may not call this " 3585 "method unless the graph is StaticProfile.");
3586 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3587 isFillComplete () || ! hasColMap (), std::runtime_error,
"You may not " 3588 "call this method unless the graph has a column Map.");
3589 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3590 getNodeNumRows () > 0 && k_rowPtrs_.dimension_0 () == 0,
3591 std::runtime_error,
"The calling process has getNodeNumRows() = " 3592 << getNodeNumRows () <<
" > 0 rows, but the row offsets array has not " 3594 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3595 static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != getNodeNumRows () + 1,
3596 std::runtime_error,
"The row offsets array has length " <<
3597 k_rowPtrs_.dimension_0 () <<
" != getNodeNumRows()+1 = " <<
3598 (getNodeNumRows () + 1) <<
".");
3608 nodeNumAllocated_ = k_rowPtrs_(getNodeNumRows ());
3609 nodeNumEntries_ = nodeNumAllocated_;
3621 numAllocForAllRows_ = 0;
3622 k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
3623 indicesAreAllocated_ =
true;
3628 indicesAreLocal_ =
true;
3629 indicesAreGlobal_ =
false;
3632 #ifdef HAVE_TPETRA_MMM_TIMINGS 3633 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Maps"))));
3635 setDomainRangeMaps (domainMap, rangeMap);
3638 indicesAreSorted_ =
true;
3639 noRedundancies_ =
true;
3642 #ifdef HAVE_TPETRA_MMM_TIMINGS 3643 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckI"))));
3646 importer_ = Teuchos::null;
3647 exporter_ = Teuchos::null;
3648 if (importer != Teuchos::null) {
3649 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3650 ! importer->getSourceMap ()->isSameAs (*getDomainMap ()) ||
3651 ! importer->getTargetMap ()->isSameAs (*getColMap ()),
3652 std::invalid_argument,
": importer does not match matrix maps.");
3653 importer_ = importer;
3657 #ifdef HAVE_TPETRA_MMM_TIMINGS 3658 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckE"))));
3661 if (exporter != Teuchos::null) {
3662 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3663 ! exporter->getSourceMap ()->isSameAs (*getRowMap ()) ||
3664 ! exporter->getTargetMap ()->isSameAs (*getRangeMap ()),
3665 std::invalid_argument,
": exporter does not match matrix maps.");
3666 exporter_ = exporter;
3669 #ifdef HAVE_TPETRA_MMM_TIMINGS 3670 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXmake"))));
3673 makeImportExport ();
3676 #ifdef HAVE_TPETRA_MMM_TIMINGS 3677 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cGC"))));
3679 computeGlobalConstants ();
3682 #ifdef HAVE_TPETRA_MMM_TIMINGS 3683 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-fLG"))));
3685 fillLocalGraph (params);
3686 fillComplete_ =
true;
3688 #ifdef HAVE_TPETRA_MMM_TIMINGS 3689 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cIS"))));
3691 checkInternalState ();
3695 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3698 fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params)
3701 using Kokkos::create_mirror_view;
3702 typedef decltype (k_numRowEntries_) row_entries_type;
3703 typedef typename local_graph_type::row_map_type row_map_type;
3704 typedef typename row_map_type::non_const_type non_const_row_map_type;
3705 typedef typename local_graph_type::entries_type::non_const_type lclinds_1d_type;
3706 #ifdef HAVE_TPETRA_DEBUG 3707 const char tfecfFuncName[] =
"fillLocalGraph (called from fillComplete or " 3708 "expertStaticFillComplete): ";
3709 #endif // HAVE_TPETRA_DEBUG 3710 const size_t lclNumRows = this->getNodeNumRows ();
3717 non_const_row_map_type ptr_d;
3718 row_map_type ptr_d_const;
3719 lclinds_1d_type ind_d;
3721 bool requestOptimizedStorage =
true;
3722 if (! params.is_null () && ! params->get (
"Optimize Storage",
true)) {
3723 requestOptimizedStorage =
false;
3725 if (getProfileType () == DynamicProfile) {
3733 #ifdef HAVE_TPETRA_DEBUG 3734 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3735 (static_cast<size_t> (k_numRowEntries_.dimension_0 ()) != lclNumRows,
3736 std::logic_error,
"(DynamicProfile branch) " 3737 "k_numRowEntries_.dimension_0() = " 3738 << k_numRowEntries_.dimension_0 ()
3739 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3740 #endif // HAVE_TPETRA_DEBUG 3749 size_t lclTotalNumEntries = 0;
3752 ptr_d = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows+1);
3753 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
3756 ptr_d_const = ptr_d;
3759 #ifdef HAVE_TPETRA_DEBUG 3760 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3761 (static_cast<size_t> (ptr_d.dimension_0 ()) != lclNumRows + 1,
3762 std::logic_error,
"(DynamicProfile branch) After packing ptr_d, " 3763 "ptr_d.dimension_0() = " << ptr_d.dimension_0 () <<
" != " 3764 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
3769 auto ptr_d_ent_d = Kokkos::subview (ptr_d, lclNumRows);
3770 auto ptr_d_ent_h = create_mirror_view (ptr_d_ent_d);
3772 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3773 (ptr_d_ent_h () != lclTotalNumEntries, std::logic_error,
3774 "(DynamicProfile branch) After packing ptr_d, ptr_d(lclNumRows = " 3775 << lclNumRows <<
") = " << ptr_d_ent_h () <<
" != total number of " 3776 "entries on the calling process = " << lclTotalNumEntries <<
".");
3778 #endif // HAVE_TPETRA_DEBUG 3781 ind_d = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3787 auto ptr_h = create_mirror_view (ptr_d);
3789 auto ind_h = create_mirror_view (ind_d);
3792 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
3793 for (
size_t row = 0; row < lclNumRows; ++row) {
3794 const size_t numEnt = numRowEnt_h(row);
3795 std::copy (lclInds2D_[row].begin (),
3796 lclInds2D_[row].begin () + numEnt,
3797 ind_h.ptr_on_device () + ptr_h(row));
3802 #ifdef HAVE_TPETRA_DEBUG 3804 if (ptr_d.dimension_0 () != 0) {
3805 const size_t numOffsets =
static_cast<size_t> (ptr_d.dimension_0 ());
3810 auto ptr_d_ent_d = Kokkos::subview (ptr_d, numOffsets - 1);
3811 auto ptr_d_ent_h = create_mirror_view (ptr_d_ent_d);
3813 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3814 (static_cast<size_t> (ptr_d_ent_h ()) != ind_d.dimension_0 (),
3815 std::logic_error,
"(DynamicProfile branch) After packing column " 3816 "indices, ptr_d(" << (numOffsets-1) <<
") = " << ptr_d_ent_h ()
3817 <<
" != ind_d.dimension_0() = " << ind_d.dimension_0 () <<
".");
3819 #endif // HAVE_TPETRA_DEBUG 3826 #ifdef HAVE_TPETRA_DEBUG 3829 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3830 (k_rowPtrs_.dimension_0 () == 0, std::logic_error,
3831 "(StaticProfile branch) k_rowPtrs_ has size zero, but shouldn't");
3832 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3833 (k_rowPtrs_.dimension_0 () != lclNumRows + 1, std::logic_error,
3834 "(StaticProfile branch) k_rowPtrs_.dimension_0() = " 3835 << k_rowPtrs_.dimension_0 () <<
" != (lclNumRows + 1) = " 3836 << (lclNumRows + 1) <<
".");
3838 const size_t numOffsets = k_rowPtrs_.dimension_0 ();
3843 auto k_rowPtrs_ent_d = Kokkos::subview (k_rowPtrs_, numOffsets - 1);
3844 auto k_rowPtrs_ent_h = create_mirror_view (k_rowPtrs_ent_d);
3847 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3849 k_lclInds1D_.dimension_0 () != k_rowPtrs_ent_h (),
3850 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
3851 numOffsets <<
" != 0 and k_lclInds1D_.dimension_0() = " <<
3852 k_lclInds1D_.dimension_0 () <<
" != k_rowPtrs_(" << numOffsets <<
3853 ") = " << k_rowPtrs_ent_h () <<
".");
3855 #endif // HAVE_TPETRA_DEBUG 3857 if (nodeNumEntries_ != nodeNumAllocated_) {
3865 #ifdef HAVE_TPETRA_DEBUG 3866 if (k_rowPtrs_.dimension_0 () != 0) {
3867 const size_t numOffsets =
3868 static_cast<size_t> (k_rowPtrs_.dimension_0 ());
3872 auto k_rowPtrs_ent_d = Kokkos::subview (k_rowPtrs_, numOffsets - 1);
3873 auto k_rowPtrs_ent_h = create_mirror_view (k_rowPtrs_ent_d);
3875 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3876 (k_rowPtrs_ent_h () != static_cast<size_t> (k_lclInds1D_.dimension_0 ()),
3877 std::logic_error,
"(StaticProfile unpacked branch) Before " 3878 "allocating or packing, k_rowPtrs_(" << (numOffsets-1) <<
") = " 3879 << k_rowPtrs_ent_h () <<
" != k_lclInds1D_.dimension_0() = " 3880 << k_lclInds1D_.dimension_0 () <<
".");
3882 #endif // HAVE_TPETRA_DEBUG 3890 size_t lclTotalNumEntries = 0;
3893 ptr_d = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
3894 ptr_d_const = ptr_d;
3898 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
3899 #ifdef HAVE_TPETRA_DEBUG 3900 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3901 (static_cast<size_t> (numRowEnt_h.dimension_0 ()) != lclNumRows,
3902 std::logic_error,
"(StaticProfile unpacked branch) " 3903 "numRowEnt_h.dimension_0() = " << numRowEnt_h.dimension_0 ()
3904 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3905 #endif // HAVE_TPETRA_DEBUG 3909 #ifdef HAVE_TPETRA_DEBUG 3910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3911 (static_cast<size_t> (ptr_d.dimension_0 ()) != lclNumRows + 1,
3912 std::logic_error,
"(StaticProfile unpacked branch) After " 3913 "allocating ptr_d, ptr_d.dimension_0() = " << ptr_d.dimension_0 ()
3914 <<
" != lclNumRows+1 = " << (lclNumRows+1) <<
".");
3919 auto ptr_d_ent_d = Kokkos::subview (ptr_d, lclNumRows);
3920 auto ptr_d_ent_h = create_mirror_view (ptr_d_ent_d);
3922 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3923 (ptr_d_ent_h () != lclTotalNumEntries, std::logic_error,
3924 "Tpetra::CrsGraph::fillLocalGraph: In StaticProfile unpacked " 3925 "branch, after filling ptr_d, ptr_d(lclNumRows=" << lclNumRows
3926 <<
") = " << ptr_d_ent_h () <<
" != total number of entries on " 3927 "the calling process = " << lclTotalNumEntries <<
".");
3929 #endif // HAVE_TPETRA_DEBUG 3933 ind_d = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3945 typedef pack_functor<
3946 typename local_graph_type::entries_type::non_const_type,
3947 row_map_type> inds_packer_type;
3948 inds_packer_type f (ind_d, k_lclInds1D_, ptr_d, k_rowPtrs_);
3949 Kokkos::parallel_for (lclNumRows, f);
3951 #ifdef HAVE_TPETRA_DEBUG 3952 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3953 (ptr_d.dimension_0 () == 0, std::logic_error,
"(StaticProfile " 3954 "\"Optimize Storage\"=true branch) After packing, " 3955 "ptr_d.dimension_0() = 0. This probably means k_rowPtrs_ was " 3956 "never allocated.");
3957 if (ptr_d.dimension_0 () != 0) {
3958 const size_t numOffsets =
static_cast<size_t> (ptr_d.dimension_0 ());
3962 auto ptr_d_ent_d = Kokkos::subview (ptr_d, numOffsets - 1);
3963 auto ptr_d_ent_h = create_mirror_view (ptr_d_ent_d);
3965 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3966 (static_cast<size_t> (ptr_d_ent_h ()) != ind_d.dimension_0 (),
3967 std::logic_error,
"(StaticProfile \"Optimize Storage\"=true " 3968 "branch) After packing, ptr_d(" << (numOffsets-1) <<
") = " <<
3969 ptr_d_ent_h () <<
" != ind_d.dimension_0() = " <<
3970 ind_d.dimension_0 () <<
".");
3972 #endif // HAVE_TPETRA_DEBUG 3975 ptr_d_const = k_rowPtrs_;
3976 ind_d = k_lclInds1D_;
3978 #ifdef HAVE_TPETRA_DEBUG 3979 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3980 (ptr_d_const.dimension_0 () == 0, std::logic_error,
"(StaticProfile " 3981 "\"Optimize Storage\"=false branch) ptr_d_const.dimension_0() = 0. " 3982 "This probably means that k_rowPtrs_ was never allocated.");
3983 if (ptr_d_const.dimension_0 () != 0) {
3984 const size_t numOffsets =
3985 static_cast<size_t> (ptr_d_const.dimension_0 ());
3989 auto ptr_d_const_ent_d = Kokkos::subview (ptr_d_const, numOffsets - 1);
3990 auto ptr_d_const_ent_h = create_mirror_view (ptr_d_const_ent_d);
3992 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3993 (static_cast<size_t> (ptr_d_const_ent_h ()) != ind_d.dimension_0 (),
3994 std::logic_error,
"(StaticProfile \"Optimize Storage\"=false " 3995 "branch) ptr_d_const(" << (numOffsets-1) <<
") = " <<
3996 ptr_d_const_ent_h () <<
" != ind_d.dimension_0() = " <<
3997 ind_d.dimension_0 () <<
".");
3999 #endif // HAVE_TPETRA_DEBUG 4003 #ifdef HAVE_TPETRA_DEBUG 4005 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4006 (static_cast<size_t> (ptr_d_const.dimension_0 ()) != lclNumRows + 1,
4007 std::logic_error,
"After packing, ptr_d_const.dimension_0() = " <<
4008 ptr_d_const.dimension_0 () <<
" != lclNumRows+1 = " << (lclNumRows+1)
4010 if (ptr_d_const.dimension_0 () != 0) {
4011 const size_t numOffsets =
static_cast<size_t> (ptr_d_const.dimension_0 ());
4015 auto ptr_d_const_ent_d = Kokkos::subview (ptr_d_const, numOffsets - 1);
4016 auto ptr_d_const_ent_h = create_mirror_view (ptr_d_const_ent_d);
4018 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4019 (static_cast<size_t> (ptr_d_const_ent_h ()) != ind_d.dimension_0 (),
4020 std::logic_error,
"After packing, ptr_d_const(" << (numOffsets-1) <<
4021 ") = " << ptr_d_const_ent_h () <<
" != ind_d.dimension_0() = " <<
4022 ind_d.dimension_0 () <<
".");
4024 #endif // HAVE_TPETRA_DEBUG 4026 if (requestOptimizedStorage) {
4032 lclInds2D_ = Teuchos::null;
4033 k_numRowEntries_ = row_entries_type ();
4036 k_rowPtrs_ = ptr_d_const;
4037 k_lclInds1D_ = ind_d;
4041 nodeNumAllocated_ = nodeNumEntries_;
4050 lclGraph_ = local_graph_type (ind_d, ptr_d_const);
4060 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4062 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
4063 replaceColMap (
const Teuchos::RCP<const map_type>& newColMap)
4072 const char tfecfFuncName[] =
"replaceColMap: ";
4073 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4074 isLocallyIndexed () || isGloballyIndexed (), std::runtime_error,
4075 "Requires matching maps and non-static graph.");
4076 colMap_ = newColMap;
4079 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4083 const Teuchos::RCP<const import_type>& newImport,
4084 const bool sortIndicesInEachRow)
4086 using Teuchos::REDUCE_MIN;
4087 using Teuchos::reduceAll;
4089 typedef GlobalOrdinal GO;
4090 typedef LocalOrdinal LO;
4091 typedef typename local_graph_type::entries_type::non_const_type col_inds_type;
4092 const char tfecfFuncName[] =
"reindexColumns: ";
4094 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4095 isFillComplete (), std::runtime_error,
"The graph is fill complete " 4096 "(isFillComplete() returns true). You must call resumeFill() before " 4097 "you may call this method.");
4115 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4130 bool allCurColIndsValid =
true;
4135 bool localSuffices =
true;
4143 typename local_graph_type::entries_type::non_const_type newLclInds1D;
4144 Teuchos::ArrayRCP<Teuchos::Array<LO> > newLclInds2D;
4149 if (indicesAreAllocated ()) {
4150 if (isLocallyIndexed ()) {
4152 const map_type& oldColMap = * (getColMap ());
4155 RCP<node_type> node = getRowMap ()->
getNode ();
4157 col_inds_type (
"Tpetra::CrsGraph::ind", nodeNumAllocated_);
4159 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4160 const RowInfo rowInfo = this->getRowInfo (lclRow);
4161 const size_t beg = rowInfo.offset1D;
4162 const size_t end = beg + rowInfo.numEntries;
4163 for (
size_t k = beg; k < end; ++k) {
4166 const LO oldLclCol = k_lclInds1D_(k);
4167 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4168 allCurColIndsValid =
false;
4176 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4177 allCurColIndsValid =
false;
4181 const LO newLclCol = newColMap->getLocalElement (gblCol);
4182 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4183 localSuffices =
false;
4188 newLclInds1D(k) = newLclCol;
4197 newLclInds2D = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4200 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4201 const RowInfo rowInfo = this->getRowInfo (lclRow);
4202 newLclInds2D.resize (rowInfo.allocSize);
4204 Teuchos::ArrayView<const LO> oldLclRowView = getLocalView (rowInfo);
4205 Teuchos::ArrayView<LO> newLclRowView = (newLclInds2D[lclRow]) ();
4207 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4208 const LO oldLclCol = oldLclRowView[k];
4209 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4210 allCurColIndsValid =
false;
4217 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4218 allCurColIndsValid =
false;
4222 const LO newLclCol = newColMap->getLocalElement (gblCol);
4223 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4224 localSuffices =
false;
4227 newLclRowView[k] = newLclCol;
4239 allCurColIndsValid =
false;
4256 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4257 const RowInfo rowInfo = this->getRowInfo (lclRow);
4258 Teuchos::ArrayView<const GO> oldGblRowView = getGlobalView (rowInfo);
4259 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4260 const GO gblCol = oldGblRowView[k];
4261 if (! newColMap->isNodeGlobalElement (gblCol)) {
4262 localSuffices =
false;
4272 lclSuccess[0] = allCurColIndsValid ? 1 : 0;
4273 lclSuccess[1] = localSuffices ? 1 : 0;
4277 RCP<const Teuchos::Comm<int> > comm =
4278 getRowMap ().is_null () ? Teuchos::null : getRowMap ()->getComm ();
4279 if (! comm.is_null ()) {
4280 reduceAll<int, int> (*comm, REDUCE_MIN, 2, lclSuccess, gblSuccess);
4283 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4284 gblSuccess[0] == 0, std::runtime_error,
"It is not possible to continue." 4285 " The most likely reason is that the graph is locally indexed, but the " 4286 "column Map is missing (null) on some processes, due to a previous call " 4287 "to replaceColMap().");
4289 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4290 gblSuccess[1] == 0, std::runtime_error,
"On some process, the graph " 4291 "contains column indices that are in the old column Map, but not in the " 4292 "new column Map (on that process). This method does NOT redistribute " 4293 "data; it does not claim to do the work of an Import or Export operation." 4294 " This means that for all processess, the calling process MUST own all " 4295 "column indices, in both the old column Map and the new column Map. In " 4296 "this case, you will need to do an Import or Export operation to " 4297 "redistribute data.");
4300 if (isLocallyIndexed ()) {
4302 k_lclInds1D_ = newLclInds1D;
4304 lclInds2D_ = newLclInds2D;
4312 indicesAreSorted_ =
false;
4313 if (sortIndicesInEachRow) {
4323 colMap_ = newColMap;
4325 if (newImport.is_null ()) {
4333 if (! domainMap_.is_null ()) {
4334 if (! domainMap_->isSameAs (* newColMap)) {
4335 importer_ = Teuchos::rcp (
new import_type (domainMap_, newColMap));
4337 importer_ = Teuchos::null;
4342 importer_ = newImport;
4347 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4351 const Teuchos::RCP<const import_type>& newImporter)
4353 const char prefix[] =
"Tpetra::CrsGraph::replaceDomainMapAndImporter: ";
4354 TEUCHOS_TEST_FOR_EXCEPTION(
4355 colMap_.is_null (), std::invalid_argument, prefix <<
"You may not call " 4356 "this method unless the graph already has a column Map.");
4357 TEUCHOS_TEST_FOR_EXCEPTION(
4358 newDomainMap.is_null (), std::invalid_argument,
4359 prefix <<
"The new domain Map must be nonnull.");
4361 #ifdef HAVE_TPETRA_DEBUG 4362 if (newImporter.is_null ()) {
4367 const bool colSameAsDom = colMap_->isSameAs (*newDomainMap);
4368 TEUCHOS_TEST_FOR_EXCEPTION(
4369 colSameAsDom, std::invalid_argument,
"If the new Import is null, " 4370 "then the new domain Map must be the same as the current column Map.");
4373 const bool colSameAsTgt =
4374 colMap_->isSameAs (* (newImporter->getTargetMap ()));
4375 const bool newDomSameAsSrc =
4376 newDomainMap->isSameAs (* (newImporter->getSourceMap ()));
4377 TEUCHOS_TEST_FOR_EXCEPTION(
4378 ! colSameAsTgt || ! newDomSameAsSrc, std::invalid_argument,
"If the " 4379 "new Import is nonnull, then the current column Map must be the same " 4380 "as the new Import's target Map, and the new domain Map must be the " 4381 "same as the new Import's source Map.");
4383 #endif // HAVE_TPETRA_DEBUG 4385 domainMap_ = newDomainMap;
4386 importer_ = Teuchos::rcp_const_cast<
import_type> (newImporter);
4389 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4397 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4402 using Teuchos::ArrayView;
4403 using Teuchos::outArg;
4404 using Teuchos::reduceAll;
4405 typedef LocalOrdinal LO;
4406 typedef GlobalOrdinal GO;
4409 #ifdef HAVE_TPETRA_DEBUG 4410 TEUCHOS_TEST_FOR_EXCEPTION(! hasColMap(), std::logic_error,
"Tpetra::" 4411 "CrsGraph::computeGlobalConstants: At this point, the graph should have " 4412 "a column Map, but it does not. Please report this bug to the Tpetra " 4414 #endif // HAVE_TPETRA_DEBUG 4418 if (! haveLocalConstants_) {
4430 upperTriangular_ =
true;
4431 lowerTriangular_ =
true;
4432 nodeMaxNumRowEntries_ = 0;
4436 const map_type& rowMap = *rowMap_;
4437 const map_type& colMap = *colMap_;
4449 if (indicesAreAllocated () && nodeNumAllocated_ > 0) {
4450 const LO numLocalRows =
static_cast<LO
> (this->getNodeNumRows ());
4451 for (LO localRow = 0; localRow < numLocalRows; ++localRow) {
4452 const GO globalRow = rowMap.getGlobalElement (localRow);
4459 const LO rlcid = colMap.getLocalElement (globalRow);
4461 const RowInfo rowInfo = this->getRowInfo (localRow);
4462 ArrayView<const LO> rview = getLocalView (rowInfo);
4463 typename ArrayView<const LO>::iterator beg, end, cur;
4464 beg = rview.begin();
4465 end = beg + rowInfo.numEntries;
4467 for (cur = beg; cur != end; ++cur) {
4469 if (rlcid == *cur) ++nodeNumDiags_;
4476 const size_t smallestCol =
static_cast<size_t> (*beg);
4477 const size_t largestCol =
static_cast<size_t> (*(end - 1));
4479 if (smallestCol < static_cast<size_t> (localRow)) {
4480 upperTriangular_ =
false;
4482 if (static_cast<size_t> (localRow) < largestCol) {
4483 lowerTriangular_ =
false;
4487 nodeMaxNumRowEntries_ = std::max (nodeMaxNumRowEntries_, rowInfo.numEntries);
4490 haveLocalConstants_ =
true;
4496 if (haveGlobalConstants_ ==
false) {
4510 lcl[0] =
static_cast<GST
> (nodeNumEntries_);
4511 lcl[1] =
static_cast<GST
> (nodeNumDiags_);
4512 reduceAll<int,GST> (*getComm (), Teuchos::REDUCE_SUM,
4514 globalNumEntries_ = gbl[0];
4515 globalNumDiags_ = gbl[1];
4516 reduceAll<int,GST> (*getComm (), Teuchos::REDUCE_MAX,
4517 static_cast<GST
> (nodeMaxNumRowEntries_),
4518 outArg (globalMaxNumRowEntries_));
4519 haveGlobalConstants_ =
true;
4524 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4526 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
4529 using Teuchos::arcp;
4530 using Teuchos::Array;
4531 typedef LocalOrdinal LO;
4532 typedef GlobalOrdinal GO;
4533 typedef device_type DT;
4534 typedef typename local_graph_type::row_map_type::non_const_value_type offset_type;
4535 typedef decltype (k_numRowEntries_) row_entries_type;
4536 typedef typename row_entries_type::non_const_value_type num_ent_type;
4537 typedef typename local_graph_type::entries_type::non_const_type
4539 typedef Kokkos::View<GO*,
typename lcl_col_inds_type::array_layout,
4540 device_type> gbl_col_inds_type;
4542 const char tfecfFuncName[] =
"makeIndicesLocal: ";
4544 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4545 (! this->hasColMap (), std::logic_error,
"The graph does not have a " 4546 "column Map yet. This method should never be called in that case. " 4547 "Please report this bug to the Tpetra developers.");
4548 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4549 (this->getColMap ().is_null (), std::logic_error,
"The graph claims " 4550 "that it has a column Map, because hasColMap() returns true. However, " 4551 "the result of getColMap() is null. This should never happen. Please " 4552 "report this bug to the Tpetra developers.");
4554 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4555 const map_type& colMap = * (this->getColMap ());
4557 if (isGloballyIndexed () && lclNumRows != 0) {
4559 typename row_entries_type::const_type h_numRowEnt = k_numRowEntries_;
4566 constexpr
bool LO_GO_same = std::is_same<LO, GO>::value;
4567 if (nodeNumAllocated_ && LO_GO_same) {
4570 k_lclInds1D_ = Kokkos::Impl::if_c<LO_GO_same,
4572 lcl_col_inds_type>::select (k_gblInds1D_, k_lclInds1D_);
4575 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4576 (k_rowPtrs_.dimension_0 () == 0, std::logic_error,
4577 "k_rowPtrs_.dimension_0() == 0. This should never happen at this " 4578 "point. Please report this bug to the Tpetra developers.");
4583 auto lastEnt_d = Kokkos::subview (k_rowPtrs_, lclNumRows);
4584 auto lastEnt_h = Kokkos::create_mirror_view (lastEnt_d);
4586 const auto numEnt = lastEnt_h ();
4588 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::lclind", numEnt);
4591 auto lclColMap = colMap.getLocalMap ();
4599 auto k_numRowEnt = Kokkos::create_mirror_view (device_type (), h_numRowEnt);
4602 const size_t numBad =
4603 convertColumnIndicesFromGlobalToLocal<LO, GO, DT, offset_type, num_ent_type> (k_lclInds1D_,
4608 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4609 (numBad != 0, std::runtime_error,
"When converting column indices " 4610 "from global to local, we encountered " << numBad
4611 <<
"ind" << (numBad != static_cast<size_t> (1) ?
"ices" :
"ex")
4612 <<
" that do" << (numBad != static_cast<size_t> (1) ?
"es" :
"")
4613 <<
" not live in the column Map on this process.");
4618 k_gblInds1D_ = gbl_col_inds_type ();
4621 lclInds2D_ = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4622 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4623 if (! gblInds2D_[lclRow].empty ()) {
4624 const GO*
const ginds = gblInds2D_[lclRow].getRawPtr ();
4628 const LO rna =
static_cast<LO
> (gblInds2D_[lclRow].size ());
4629 const LO numEnt =
static_cast<LO
> (h_numRowEnt(lclRow));
4630 lclInds2D_[lclRow].resize (rna);
4631 LO*
const linds = lclInds2D_[lclRow].getRawPtr ();
4632 for (LO j = 0; j < numEnt; ++j) {
4633 const GO gid = ginds[j];
4634 const LO lid = colMap.getLocalElement (gid);
4636 #ifdef HAVE_TPETRA_DEBUG 4637 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4638 (linds[j] == Teuchos::OrdinalTraits<LO>::invalid(),
4640 "Global column ginds[j=" << j <<
"]=" << ginds[j]
4641 <<
" of local row " << lclRow <<
" is not in the column Map. " 4642 "This should never happen. Please report this bug to the " 4643 "Tpetra developers.");
4644 #endif // HAVE_TPETRA_DEBUG 4648 gblInds2D_ = Teuchos::null;
4652 lclGraph_ = local_graph_type (k_lclInds1D_, k_rowPtrs_);
4653 indicesAreLocal_ =
true;
4654 indicesAreGlobal_ =
false;
4655 checkInternalState ();
4659 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4661 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
4664 typedef LocalOrdinal LO;
4667 TEUCHOS_TEST_FOR_EXCEPT( isGloballyIndexed () );
4668 if (isSorted () ==
false) {
4671 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4672 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4673 const RowInfo rowInfo = this->getRowInfo (lclRow);
4674 this->sortRowIndices (rowInfo);
4677 indicesAreSorted_ =
true;
4681 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4686 using Teuchos::Array;
4687 using Teuchos::ArrayView;
4688 using Teuchos::outArg;
4690 using Teuchos::REDUCE_MAX;
4691 using Teuchos::reduceAll;
4693 typedef LocalOrdinal LO;
4694 typedef GlobalOrdinal GO;
4695 const char tfecfFuncName[] =
"makeColMap";
4703 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4704 isLocallyIndexed (), std::runtime_error,
4705 ": The graph is locally indexed. Calling makeColMap() to make the " 4706 "column Map requires that the graph be globally indexed.");
4711 Array<GO> myColumns;
4717 if (isGloballyIndexed ()) {
4741 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
4742 size_t numLocalColGIDs = 0, numRemoteColGIDs = 0;
4746 Array<char> GIDisLocal (domainMap_->getNodeNumElements (), 0);
4747 std::set<GO> RemoteGIDSet;
4749 std::vector<GO> RemoteGIDUnorderedVector;
4750 const LO myNumRows = this->getNodeNumRows ();
4751 for (LO r = 0; r < myNumRows; ++r) {
4752 const RowInfo rowinfo = this->getRowInfo (r);
4753 if (rowinfo.numEntries > 0) {
4759 ArrayView<const GO> rowGids = getGlobalView (rowinfo);
4760 rowGids = rowGids (0, rowinfo.numEntries);
4762 for (
size_t k = 0; k < rowinfo.numEntries; ++k) {
4763 const GO gid = rowGids[k];
4764 const LO lid = domainMap_->getLocalElement (gid);
4766 const char alreadyFound = GIDisLocal[lid];
4767 if (alreadyFound == 0) {
4768 GIDisLocal[lid] =
static_cast<char> (1);
4773 const bool notAlreadyFound = RemoteGIDSet.insert (gid).second;
4774 if (notAlreadyFound) {
4775 if (! sortGhostsAssociatedWithEachProcessor_) {
4782 RemoteGIDUnorderedVector.push_back (gid);
4820 if (domainMap_->getComm ()->getSize () == 1) {
4821 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4822 numRemoteColGIDs != 0, std::runtime_error,
4823 ": " << numRemoteColGIDs <<
" column " 4824 << (numRemoteColGIDs != 1 ?
"indices are" :
"index is")
4825 <<
" not in the domain Map." << endl
4826 <<
"Either these indices are invalid or the domain Map is invalid." 4827 << endl <<
"Remember that nonsquare matrices, or matrices where the " 4828 "row and range Maps are different, require calling the version of " 4829 "fillComplete that takes the domain and range Maps as input.");
4830 if (numLocalColGIDs == domainMap_->getNodeNumElements()) {
4831 colMap_ = domainMap_;
4832 checkInternalState ();
4841 myColumns.resize (numLocalColGIDs + numRemoteColGIDs);
4843 ArrayView<GO> LocalColGIDs = myColumns (0, numLocalColGIDs);
4844 ArrayView<GO> RemoteColGIDs = myColumns (numLocalColGIDs, numRemoteColGIDs);
4847 if (sortGhostsAssociatedWithEachProcessor_) {
4849 std::copy (RemoteGIDSet.begin(), RemoteGIDSet.end(),
4850 RemoteColGIDs.begin());
4853 std::copy (RemoteGIDUnorderedVector.begin(),
4854 RemoteGIDUnorderedVector.end(), RemoteColGIDs.begin());
4858 Array<int> RemoteImageIDs (numRemoteColGIDs);
4862 domainMap_->getRemoteIndexList (RemoteColGIDs, RemoteImageIDs ());
4863 #ifdef HAVE_TPETRA_DEBUG 4871 const int missingID_lcl = (stat ==
IDNotPresent ? 1 : 0);
4872 int missingID_gbl = 0;
4873 reduceAll<int, int> (*getComm (), REDUCE_MAX, missingID_lcl,
4874 outArg (missingID_gbl));
4875 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4876 missingID_gbl == 1, std::runtime_error,
4877 ": Some column indices are not in the domain Map." << endl
4878 <<
"Either these column indices are invalid or the domain Map is " 4879 "invalid." << endl <<
"Likely cause: For a nonsquare matrix, you " 4880 "must give the domain and range Maps as input to fillComplete.");
4883 #endif // HAVE_TPETRA_DEBUG 4893 sort2 (RemoteImageIDs.begin(), RemoteImageIDs.end(), RemoteColGIDs.begin());
4905 const size_t numDomainElts = domainMap_->getNodeNumElements ();
4906 if (numLocalColGIDs == numDomainElts) {
4910 if (domainMap_->isContiguous ()) {
4916 GO curColMapGid = domainMap_->getMinGlobalIndex ();
4917 for (
size_t k = 0; k < numLocalColGIDs; ++k, ++curColMapGid) {
4918 LocalColGIDs[k] = curColMapGid;
4922 ArrayView<const GO> domainElts = domainMap_->getNodeElementList ();
4923 std::copy (domainElts.begin(), domainElts.end(), LocalColGIDs.begin());
4929 size_t numLocalCount = 0;
4930 if (domainMap_->isContiguous ()) {
4936 GO curColMapGid = domainMap_->getMinGlobalIndex ();
4937 for (
size_t i = 0; i < numDomainElts; ++i, ++curColMapGid) {
4938 if (GIDisLocal[i]) {
4939 LocalColGIDs[numLocalCount++] = curColMapGid;
4944 ArrayView<const GO> domainElts = domainMap_->getNodeElementList ();
4945 for (
size_t i = 0; i < numDomainElts; ++i) {
4946 if (GIDisLocal[i]) {
4947 LocalColGIDs[numLocalCount++] = domainElts[i];
4951 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4952 numLocalCount != numLocalColGIDs, std::logic_error,
4953 ": numLocalCount = " << numLocalCount <<
" != numLocalColGIDs = " 4954 << numLocalColGIDs <<
". This should never happen. Please report " 4955 "this bug to the Tpetra developers.");
5000 Teuchos::OrdinalTraits<global_size_t>::invalid ();
5005 const GO indexBase = domainMap_->getIndexBase ();
5006 colMap_ = rcp (
new map_type (gstInv, myColumns, indexBase,
5007 domainMap_->getComm (),
5008 domainMap_->getNode ()));
5010 checkInternalState ();
5014 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5019 TEUCHOS_TEST_FOR_EXCEPT( isGloballyIndexed() );
5020 TEUCHOS_TEST_FOR_EXCEPT( ! isSorted() );
5021 if (! isMerged ()) {
5022 const LocalOrdinal lclNumRows =
5023 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
5024 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
5025 const RowInfo rowInfo = this->getRowInfo (row);
5026 mergeRowIndices(rowInfo);
5029 noRedundancies_ =
true;
5034 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5039 using Teuchos::ParameterList;
5043 TEUCHOS_TEST_FOR_EXCEPTION(! hasColMap (), std::logic_error,
"Tpetra::" 5044 "CrsGraph::makeImportExport: This method may not be called unless the " 5045 "graph has a column Map.");
5046 RCP<ParameterList> params = this->getNonconstParameterList ();
5055 if (importer_.is_null ()) {
5057 if (domainMap_ != colMap_ && (! domainMap_->isSameAs (*colMap_))) {
5058 if (params.is_null () || ! params->isSublist (
"Import")) {
5059 importer_ = rcp (
new import_type (domainMap_, colMap_));
5061 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5062 importer_ = rcp (
new import_type (domainMap_, colMap_, importSublist));
5069 if (exporter_.is_null ()) {
5071 if (rangeMap_ != rowMap_ && ! rangeMap_->isSameAs (*rowMap_)) {
5072 if (params.is_null () || ! params->isSublist (
"Export")) {
5073 exporter_ = rcp (
new export_type (rowMap_, rangeMap_));
5076 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5077 exporter_ = rcp (
new export_type (rowMap_, rangeMap_, exportSublist));
5084 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5086 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
5087 description ()
const 5089 std::ostringstream oss;
5090 oss << dist_object_type::description ();
5091 if (isFillComplete ()) {
5092 oss <<
"{status = fill complete" 5093 <<
", global rows = " << getGlobalNumRows()
5094 <<
", global cols = " << getGlobalNumCols()
5095 <<
", global num entries = " << getGlobalNumEntries()
5099 oss <<
"{status = fill not complete" 5100 <<
", global rows = " << getGlobalNumRows()
5107 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5111 const Teuchos::EVerbosityLevel verbLevel)
const 5113 const char tfecfFuncName[] =
"describe()";
5114 using Teuchos::ArrayView;
5115 using Teuchos::Comm;
5117 using Teuchos::VERB_DEFAULT;
5118 using Teuchos::VERB_NONE;
5119 using Teuchos::VERB_LOW;
5120 using Teuchos::VERB_MEDIUM;
5121 using Teuchos::VERB_HIGH;
5122 using Teuchos::VERB_EXTREME;
5126 Teuchos::EVerbosityLevel vl = verbLevel;
5127 if (vl == VERB_DEFAULT) vl = VERB_LOW;
5128 RCP<const Comm<int> > comm = this->getComm();
5129 const int myImageID = comm->getRank(),
5130 numImages = comm->getSize();
5132 for (
size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
5135 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5136 Teuchos::OSTab tab (out);
5144 if (vl != VERB_NONE) {
5145 if (myImageID == 0) out << this->description() << std::endl;
5147 if (isFillComplete() && myImageID == 0) {
5148 out <<
"Global number of diagonals = " << globalNumDiags_ << std::endl;
5149 out <<
"Global max number of row entries = " << globalMaxNumRowEntries_ << std::endl;
5152 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5153 if (myImageID == 0) out <<
"\nRow map: " << std::endl;
5154 rowMap_->describe(out,vl);
5155 if (colMap_ != Teuchos::null) {
5156 if (myImageID == 0) out <<
"\nColumn map: " << std::endl;
5157 colMap_->describe(out,vl);
5159 if (domainMap_ != Teuchos::null) {
5160 if (myImageID == 0) out <<
"\nDomain map: " << std::endl;
5161 domainMap_->describe(out,vl);
5163 if (rangeMap_ != Teuchos::null) {
5164 if (myImageID == 0) out <<
"\nRange map: " << std::endl;
5165 rangeMap_->describe(out,vl);
5169 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5170 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5171 if (myImageID == imageCtr) {
5172 out <<
"Node ID = " << imageCtr << std::endl
5173 <<
"Node number of entries = " << nodeNumEntries_ << std::endl
5174 <<
"Node number of diagonals = " << nodeNumDiags_ << std::endl
5175 <<
"Node max number of entries = " << nodeMaxNumRowEntries_ << std::endl;
5176 if (indicesAreAllocated()) {
5177 out <<
"Node number of allocated entries = " << nodeNumAllocated_ << std::endl;
5180 out <<
"Indices are not allocated." << std::endl;
5189 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
5190 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5191 ! hasRowInfo (), std::runtime_error,
": reduce verbosity level; " 5192 "graph row information was deleted at fillComplete().");
5193 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5194 if (myImageID == imageCtr) {
5195 out << std::setw(width) <<
"Node ID" 5196 << std::setw(width) <<
"Global Row" 5197 << std::setw(width) <<
"Num Entries";
5198 if (vl == VERB_EXTREME) {
5202 const LocalOrdinal lclNumRows =
5203 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
5204 for (LocalOrdinal r=0; r < lclNumRows; ++r) {
5205 const RowInfo rowinfo = this->getRowInfo (r);
5206 GlobalOrdinal gid = rowMap_->getGlobalElement(r);
5207 out << std::setw(width) << myImageID
5208 << std::setw(width) << gid
5209 << std::setw(width) << rowinfo.numEntries;
5210 if (vl == VERB_EXTREME) {
5212 if (isGloballyIndexed()) {
5213 ArrayView<const GlobalOrdinal> rowview = getGlobalView(rowinfo);
5214 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << rowview[j] <<
" ";
5216 else if (isLocallyIndexed()) {
5217 ArrayView<const LocalOrdinal> rowview = getLocalView(rowinfo);
5218 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << colMap_->getGlobalElement(rowview[j]) <<
" ";
5233 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5247 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5252 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
5253 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs)
5255 using Teuchos::Array;
5256 using Teuchos::ArrayView;
5257 typedef LocalOrdinal LO;
5258 typedef GlobalOrdinal GO;
5259 const char tfecfFuncName[] =
"copyAndPermute";
5263 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5264 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
5265 ": permuteToLIDs and permuteFromLIDs must have the same size.");
5279 const row_graph_type* srcRowGraph =
dynamic_cast<const row_graph_type*
> (&source);
5280 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5281 srcRowGraph == NULL, std::invalid_argument,
5282 ": The source object must be a RowGraph with matching first three " 5283 "template parameters.");
5290 const map_type& srcRowMap = * (srcRowGraph->getRowMap ());
5291 const map_type& tgtRowMap = * (this->getRowMap ());
5292 const bool src_filled = srcRowGraph->isFillComplete ();
5299 if (src_filled || srcCrsGraph == NULL) {
5305 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5307 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (gid);
5308 row_copy.resize (row_length);
5309 size_t check_row_length = 0;
5310 srcRowGraph->getGlobalRowCopy (gid, row_copy (), check_row_length);
5311 this->insertGlobalIndices (gid, row_copy ());
5314 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5316 ArrayView<const GO> row;
5317 srcCrsGraph->getGlobalRowView (gid, row);
5318 this->insertGlobalIndices (gid, row);
5325 if (src_filled || srcCrsGraph == NULL) {
5326 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5329 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (srcgid);
5330 row_copy.resize (row_length);
5331 size_t check_row_length = 0;
5332 srcRowGraph->getGlobalRowCopy (srcgid, row_copy (), check_row_length);
5333 this->insertGlobalIndices (mygid, row_copy ());
5336 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5339 ArrayView<const GO> row;
5340 srcCrsGraph->getGlobalRowView (srcgid, row);
5341 this->insertGlobalIndices (mygid, row);
5347 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5351 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
5352 Teuchos::Array<GlobalOrdinal> &exports,
5353 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
5354 size_t& constantNumPackets,
5357 using Teuchos::Array;
5358 const char tfecfFuncName[] =
"packAndPrepare";
5359 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5360 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5361 ": exportLIDs and numPacketsPerLID must have the same size.");
5363 const row_graph_type& srcGraph =
dynamic_cast<const row_graph_type&
> (source);
5368 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5369 this->isFillComplete (), std::runtime_error,
5370 ": The target graph of an Import or Export must not be fill complete.");
5372 srcGraph.pack (exportLIDs, exports, numPacketsPerLID, constantNumPackets, distor);
5376 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5378 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
5379 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5380 Teuchos::Array<GlobalOrdinal>& exports,
5381 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5382 size_t& constantNumPackets,
5385 using Teuchos::Array;
5386 typedef LocalOrdinal LO;
5387 typedef GlobalOrdinal GO;
5388 const char tfecfFuncName[] =
"pack";
5391 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5392 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5393 ": exportLIDs and numPacketsPerLID must have the same size.");
5395 const map_type& srcMap = * (this->getMap ());
5396 constantNumPackets = 0;
5403 size_t totalNumPackets = 0;
5405 for (LO i = 0; i < exportLIDs.size (); ++i) {
5407 size_t row_length = this->getNumEntriesInGlobalRow (GID);
5408 numPacketsPerLID[i] = row_length;
5409 totalNumPackets += row_length;
5412 exports.resize (totalNumPackets);
5416 size_t exportsOffset = 0;
5417 for (LO i = 0; i < exportLIDs.size (); ++i) {
5418 const GO GID = srcMap.getGlobalElement (exportLIDs[i]);
5419 size_t row_length = this->getNumEntriesInGlobalRow (GID);
5420 row.resize (row_length);
5421 size_t check_row_length = 0;
5422 this->getGlobalRowCopy (GID, row (), check_row_length);
5423 typename Array<GO>::const_iterator row_iter = row.begin();
5424 typename Array<GO>::const_iterator row_end = row.end();
5426 for (; row_iter != row_end; ++row_iter, ++j) {
5427 exports[exportsOffset+j] = *row_iter;
5429 exportsOffset += row.size();
5434 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5437 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
5438 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
5439 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
5440 size_t constantNumPackets,
5444 using Teuchos::ArrayView;
5445 typedef LocalOrdinal LO;
5446 typedef GlobalOrdinal GO;
5465 const char tfecfFuncName[] =
"unpackAndCombine: ";
5466 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5467 importLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5468 "importLIDs and numPacketsPerLID must have the same size.");
5469 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5470 isFillComplete (), std::runtime_error,
5471 "Import or Export operations are not allowed on the destination " 5472 "CrsGraph if it is fill complete.");
5473 size_t importsOffset = 0;
5475 typedef typename ArrayView<const LO>::const_iterator iter_type;
5476 iter_type impLIDiter = importLIDs.begin();
5477 iter_type impLIDend = importLIDs.end();
5479 for (
size_t i = 0; impLIDiter != impLIDend; ++impLIDiter, ++i) {
5480 LO row_length = numPacketsPerLID[i];
5482 const GO*
const row_raw = (row_length == 0) ? NULL : &imports[importsOffset];
5483 ArrayView<const GlobalOrdinal> row (row_raw, row_length);
5484 insertGlobalIndicesFiltered (this->getMap ()->getGlobalElement (*impLIDiter), row);
5485 importsOffset += row_length;
5490 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5495 using Teuchos::Comm;
5496 using Teuchos::null;
5497 using Teuchos::ParameterList;
5503 RCP<const map_type> rowMap, domainMap, rangeMap, colMap;
5504 RCP<import_type> importer;
5505 RCP<export_type> exporter;
5508 RCP<const Comm<int> > newComm =
5509 (newMap.is_null ()) ? null : newMap->getComm ();
5511 if (! domainMap_.is_null ()) {
5512 if (domainMap_.getRawPtr () == rowMap_.getRawPtr ()) {
5519 domainMap = domainMap_->replaceCommWithSubset (newComm);
5522 if (! rangeMap_.is_null ()) {
5523 if (rangeMap_.getRawPtr () == rowMap_.getRawPtr ()) {
5530 rangeMap = rangeMap_->replaceCommWithSubset (newComm);
5533 if (! colMap.is_null ()) {
5534 colMap = colMap_->replaceCommWithSubset (newComm);
5538 if (! newComm.is_null ()) {
5539 RCP<ParameterList> params = this->getNonconstParameterList ();
5547 if (! rangeMap_.is_null () &&
5548 rangeMap != rowMap &&
5549 ! rangeMap->isSameAs (*rowMap)) {
5550 if (params.is_null () || ! params->isSublist (
"Export")) {
5551 exporter = rcp (
new export_type (rowMap, rangeMap));
5554 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5555 exporter = rcp (
new export_type (rowMap, rangeMap, exportSublist));
5559 if (! domainMap_.is_null () &&
5560 domainMap != colMap &&
5561 ! domainMap->isSameAs (*colMap)) {
5562 if (params.is_null () || ! params->isSublist (
"Import")) {
5563 importer = rcp (
new import_type (domainMap, colMap));
5565 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5566 importer = rcp (
new import_type (domainMap, colMap, importSublist));
5574 exporter_ = exporter;
5575 importer_ = importer;
5582 this->map_ = rowMap;
5583 domainMap_ = domainMap;
5584 rangeMap_ = rangeMap;
5588 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5593 if (indicesAreAllocated () &&
5595 k_rowPtrs_.dimension_0 () == 0) {
5602 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5607 typedef LocalOrdinal LO;
5608 typedef GlobalOrdinal GO;
5609 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
5611 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5612 (! hasColMap (), std::runtime_error,
"The graph must have a column Map.");
5613 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5614 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5615 (static_cast<LO> (offsets.dimension_0 ()) < lclNumRows,
5616 std::invalid_argument,
"offsets.dimension_0() = " <<
5617 offsets.dimension_0 () <<
" < getNodeNumRows() = " << lclNumRows <<
".");
5619 const map_type& rowMap = * (this->getRowMap ());
5620 const map_type& colMap = * (this->getColMap ());
5622 #ifdef HAVE_TPETRA_DEBUG 5623 bool allRowMapDiagEntriesInColMap =
true;
5624 bool allDiagEntriesFound =
true;
5625 bool allOffsetsCorrect =
true;
5626 bool noOtherWeirdness =
true;
5627 std::vector<std::pair<LO, size_t> > wrongOffsets;
5628 #endif // HAVE_TPETRA_DEBUG 5639 const bool sorted = this->isSorted ();
5640 if (isFillComplete ()) {
5641 auto lclGraph = this->getLocalGraph ();
5642 Details::getGraphDiagOffsets (offsets, lclRowMap, lclColMap,
5643 lclGraph.row_map, lclGraph.entries,
5647 for (LO lclRowInd = 0; lclRowInd < lclNumRows; ++lclRowInd) {
5648 const GO gblRowInd = lclRowMap.getGlobalElement (lclRowInd);
5649 const GO gblColInd = gblRowInd;
5650 const LO lclColInd = lclColMap.getLocalElement (gblColInd);
5653 #ifdef HAVE_TPETRA_DEBUG 5654 allRowMapDiagEntriesInColMap =
false;
5655 #endif // HAVE_TPETRA_DEBUG 5659 const RowInfo rowInfo = this->getRowInfo (lclRowInd);
5660 if (static_cast<LO> (rowInfo.localRow) == lclRowInd &&
5661 rowInfo.numEntries > 0) {
5663 auto colInds = this->getLocalKokkosRowView (rowInfo);
5664 const size_t hint = 0;
5665 const size_t offset =
5666 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
5667 lclColInd, hint, sorted);
5668 offsets(lclRowInd) = offset;
5670 #ifdef HAVE_TPETRA_DEBUG 5675 Teuchos::ArrayView<const LO> lclColInds;
5677 this->getLocalRowView (lclRowInd, lclColInds);
5680 noOtherWeirdness =
false;
5683 if (noOtherWeirdness) {
5684 const size_t numEnt = lclColInds.size ();
5685 if (offset >= numEnt) {
5688 allOffsetsCorrect =
false;
5689 wrongOffsets.push_back (std::make_pair (lclRowInd, offset));
5691 const LO actualLclColInd = lclColInds[offset];
5692 const GO actualGblColInd = lclColMap.getGlobalElement (actualLclColInd);
5693 if (actualGblColInd != gblColInd) {
5694 allOffsetsCorrect =
false;
5695 wrongOffsets.push_back (std::make_pair (lclRowInd, offset));
5699 #endif // HAVE_TPETRA_DEBUG 5703 #ifdef HAVE_TPETRA_DEBUG 5704 allDiagEntriesFound =
false;
5705 #endif // HAVE_TPETRA_DEBUG 5711 #ifdef HAVE_TPETRA_DEBUG 5712 if (wrongOffsets.size () != 0) {
5713 std::ostringstream os;
5714 os <<
"Proc " << this->getComm ()->getRank () <<
": Wrong offsets: [";
5715 for (
size_t k = 0; k < wrongOffsets.size (); ++k) {
5716 os <<
"(" << wrongOffsets[k].first <<
"," 5717 << wrongOffsets[k].second <<
")";
5718 if (k + 1 < wrongOffsets.size ()) {
5722 os <<
"]" << std::endl;
5723 std::cerr << os.str ();
5725 #endif // HAVE_TPETRA_DEBUG 5727 #ifdef HAVE_TPETRA_DEBUG 5728 using Teuchos::reduceAll;
5730 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getComm ();
5731 const bool localSuccess =
5732 allRowMapDiagEntriesInColMap && allDiagEntriesFound && allOffsetsCorrect;
5733 const int numResults = 5;
5735 lclResults[0] = allRowMapDiagEntriesInColMap ? 1 : 0;
5736 lclResults[1] = allDiagEntriesFound ? 1 : 0;
5737 lclResults[2] = allOffsetsCorrect ? 1 : 0;
5738 lclResults[3] = noOtherWeirdness ? 1 : 0;
5741 lclResults[4] = ! localSuccess ? comm->getRank () : comm->getSize ();
5749 reduceAll<int, int> (*comm, Teuchos::REDUCE_MIN,
5750 numResults, lclResults, gblResults);
5752 if (gblResults[0] != 1 || gblResults[1] != 1 || gblResults[2] != 1
5753 || gblResults[3] != 1) {
5754 std::ostringstream os;
5755 os <<
"Issue(s) that we noticed (on Process " << gblResults[4] <<
", " 5756 "possibly among others): " << endl;
5757 if (gblResults[0] == 0) {
5758 os <<
" - The column Map does not contain at least one diagonal entry " 5759 "of the graph." << endl;
5761 if (gblResults[1] == 0) {
5762 os <<
" - On one or more processes, some row does not contain a " 5763 "diagonal entry." << endl;
5765 if (gblResults[2] == 0) {
5766 os <<
" - On one or more processes, some offsets are incorrect." 5769 if (gblResults[3] == 0) {
5770 os <<
" - One or more processes had some other error." 5773 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::runtime_error, os.str());
5775 #endif // HAVE_TPETRA_DEBUG 5796 template<
class DeviceType,
5797 const bool memSpaceIsHostSpace =
5798 std::is_same<
typename DeviceType::memory_space,
5799 Kokkos::HostSpace>::value>
5800 struct HelpGetLocalDiagOffsets {};
5802 template<
class DeviceType>
5803 struct HelpGetLocalDiagOffsets<DeviceType, true> {
5804 typedef DeviceType device_type;
5805 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5806 Kokkos::MemoryUnmanaged> device_offsets_type;
5807 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5808 Kokkos::MemoryUnmanaged> host_offsets_type;
5810 static device_offsets_type
5811 getDeviceOffsets (
const host_offsets_type& hostOffsets)
5819 copyBackIfNeeded (
const host_offsets_type& ,
5820 const device_offsets_type& )
5824 template<
class DeviceType>
5825 struct HelpGetLocalDiagOffsets<DeviceType, false> {
5826 typedef DeviceType device_type;
5830 typedef Kokkos::View<size_t*, device_type> device_offsets_type;
5831 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5832 Kokkos::MemoryUnmanaged> host_offsets_type;
5834 static device_offsets_type
5835 getDeviceOffsets (
const host_offsets_type& hostOffsets)
5839 return device_offsets_type (
"offsets", hostOffsets.dimension_0 ());
5843 copyBackIfNeeded (
const host_offsets_type& hostOffsets,
5844 const device_offsets_type& deviceOffsets)
5852 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5854 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
5855 getLocalDiagOffsets (Teuchos::ArrayRCP<size_t>& offsets)
const 5857 typedef LocalOrdinal LO;
5858 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
5859 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5860 (! this->hasColMap (), std::runtime_error,
5861 "The graph does not yet have a column Map.");
5862 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5863 if (static_cast<LO> (offsets.size ()) != myNumRows) {
5867 offsets.resize (myNumRows);
5879 typedef HelpGetLocalDiagOffsets<device_type> helper_type;
5880 typedef typename helper_type::host_offsets_type host_offsets_type;
5882 host_offsets_type hostOffsets (offsets.getRawPtr (), myNumRows);
5884 auto deviceOffsets = helper_type::getDeviceOffsets (hostOffsets);
5886 this->getLocalDiagOffsets (deviceOffsets);
5887 helper_type::copyBackIfNeeded (hostOffsets, deviceOffsets);
5897 #define TPETRA_CRSGRAPH_GRAPH_INSTANT(LO,GO,NODE) template class CrsGraph< LO , GO , NODE >; 5901 #define TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) 5902 #define TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) 5903 #define TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) 5904 #define TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) 5906 #define TPETRA_CRSGRAPH_INSTANT(S,LO,GO,NODE) \ 5907 TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5908 TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5909 TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) \ 5910 TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) 5912 #endif // TPETRA_CRSGRAPH_DEF_HPP Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void copyOffsets(const OutputViewType &dst, const InputViewType &src)
Copy row offsets (in a sparse graph or matrix) from src to dst. The offsets may have different types...
GlobalOrdinal getIndexBase() const
Returns the index base for global indices for this graph.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
Declare and define Tpetra::Details::copyOffsets, an implementation detail of Tpetra (in particular...
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
void removeEmptyProcessesInPlace(Teuchos::RCP< DistObjectType > &input, const Teuchos::RCP< const Map< typename DistObjectType::local_ordinal_type, typename DistObjectType::global_ordinal_type, typename DistObjectType::node_type > > &newMap)
Remove processes which contain no elements in this object's Map.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the communicator.
local_map_type getLocalMap() const
Get the local Map for Kokkos kernels.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
Teuchos::RCP< node_type > getNode() const
Returns the underlying node.
Implementation details of Tpetra.
size_t global_size_t
Global size_t object.
Kokkos::StaticCrsGraph< LO, Kokkos::LayoutLeft, execution_space > local_graph_type
The type of the part of the sparse graph on each MPI process.
Traits class for "invalid" (flag) values of integer types that Tpetra uses as local ordinals or globa...
Insert new values that don't currently exist.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createOneToOne(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &M)
Creates a one-to-one version of the given Map where each GID is owned by only one process...
OffsetType convertColumnIndicesFromGlobalToLocal(const Kokkos::View< LO *, DT > &lclColInds, const Kokkos::View< const GO *, DT > &gblColInds, const Kokkos::View< const OffsetType *, DT > &ptr, const LocalMap< LO, GO, DT > &lclColMap, const Kokkos::View< const NumEntType *, DT > &numRowEnt)
Convert a (StaticProfile) CrsGraph's global column indices into local column indices.
Declare and define the function Tpetra::Details::computeOffsetsFromCounts, an implementation detail o...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
Abstract base class for objects that can be the source of an Import or Export operation.
OffsetsViewType::non_const_value_type computeOffsetsFromConstantCount(const OffsetsViewType &ptr, const CountType &count)
Compute offsets from a constant count.
node_type node_type
This class' Kokkos Node type.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Teuchos::RCP< Node > getNode() const
Get this Map's Node object.
device_type::execution_space execution_space
This class' Kokkos execution space.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.