42 #ifndef TPETRA_CRSGRAPH_DEF_HPP 43 #define TPETRA_CRSGRAPH_DEF_HPP 55 #include "Tpetra_Details_gathervPrint.hpp" 56 #include "Tpetra_Details_getGraphDiagOffsets.hpp" 57 #include "Tpetra_Details_makeColMap.hpp" 60 #include "Tpetra_Distributor.hpp" 61 #include "Teuchos_SerialDenseMatrix.hpp" 71 template<
class LO,
class GO,
class DT,
class OffsetType,
class NumEntType>
72 class ConvertColumnIndicesFromGlobalToLocal {
74 ConvertColumnIndicesFromGlobalToLocal (const ::Kokkos::View<LO*, DT>& lclColInds,
75 const ::Kokkos::View<const GO*, DT>& gblColInds,
76 const ::Kokkos::View<const OffsetType*, DT>& ptr,
77 const ::Tpetra::Details::LocalMap<LO, GO, DT>& lclColMap,
78 const ::Kokkos::View<const NumEntType*, DT>& numRowEnt) :
79 lclColInds_ (lclColInds),
80 gblColInds_ (gblColInds),
82 lclColMap_ (lclColMap),
83 numRowEnt_ (numRowEnt)
87 operator () (
const LO& lclRow, OffsetType& curNumBad)
const 89 const OffsetType offset = ptr_(lclRow);
93 const LO numEnt =
static_cast<LO
> (numRowEnt_(lclRow));
94 for (LO j = 0; j < numEnt; ++j) {
95 const GO gid = gblColInds_(offset + j);
96 const LO lid = lclColMap_.getLocalElement (gid);
97 lclColInds_(offset + j) = lid;
98 if (lid == ::Tpetra::Details::OrdinalTraits<LO>::invalid ()) {
105 run (const ::Kokkos::View<LO*, DT>& lclColInds,
106 const ::Kokkos::View<const GO*, DT>& gblColInds,
107 const ::Kokkos::View<const OffsetType*, DT>& ptr,
108 const ::Tpetra::Details::LocalMap<LO, GO, DT>& lclColMap,
109 const ::Kokkos::View<const NumEntType*, DT>& numRowEnt)
111 typedef ::Kokkos::RangePolicy<typename DT::execution_space, LO> range_type;
112 typedef ConvertColumnIndicesFromGlobalToLocal<LO, GO, DT, OffsetType, NumEntType> functor_type;
114 const LO lclNumRows = ptr.dimension_0 () == 0 ?
115 static_cast<LO
> (0) : static_cast<LO> (ptr.dimension_0 () - 1);
116 OffsetType numBad = 0;
118 ::Kokkos::parallel_reduce (range_type (0, lclNumRows),
119 functor_type (lclColInds, gblColInds, ptr,
120 lclColMap, numRowEnt),
126 ::Kokkos::View<LO*, DT> lclColInds_;
127 ::Kokkos::View<const GO*, DT> gblColInds_;
128 ::Kokkos::View<const OffsetType*, DT> ptr_;
130 ::Kokkos::View<const NumEntType*, DT> numRowEnt_;
149 template<
class LO,
class GO,
class DT,
class OffsetType,
class NumEntType>
152 const Kokkos::View<const GO*, DT>& gblColInds,
153 const Kokkos::View<const OffsetType*, DT>& ptr,
155 const Kokkos::View<const NumEntType*, DT>& numRowEnt)
157 using Impl::ConvertColumnIndicesFromGlobalToLocal;
158 typedef ConvertColumnIndicesFromGlobalToLocal<LO, GO, DT, OffsetType, NumEntType> impl_type;
159 return impl_type::run (lclColInds, gblColInds, ptr, lclColMap, numRowEnt);
164 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
166 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
167 size_t maxNumEntriesPerRow,
169 const Teuchos::RCP<Teuchos::ParameterList>& params) :
172 , nodeNumEntries_ (0)
174 , numAllocForAllRows_ (maxNumEntriesPerRow)
178 , indicesAreAllocated_ (false)
179 , indicesAreLocal_ (false)
180 , indicesAreGlobal_ (false)
181 , fillComplete_ (false)
182 , indicesAreSorted_ (true)
183 , noRedundancies_ (true)
184 , haveLocalConstants_ (false)
185 , haveGlobalConstants_ (false)
186 , sortGhostsAssociatedWithEachProcessor_ (true)
188 const char tfecfFuncName[] =
"CrsGraph(rowMap,maxNumEntriesPerRow," 191 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
192 (maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
193 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 194 "a valid size_t value, which in this case means it must not be " 195 "Teuchos::OrdinalTraits<size_t>::invalid().");
197 checkInternalState ();
200 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
202 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
203 const Teuchos::RCP<const map_type>& colMap,
204 const size_t maxNumEntriesPerRow,
206 const Teuchos::RCP<Teuchos::ParameterList>& params) :
210 , nodeNumEntries_ (0)
212 , numAllocForAllRows_ (maxNumEntriesPerRow)
216 , indicesAreAllocated_ (false)
217 , indicesAreLocal_ (false)
218 , indicesAreGlobal_ (false)
219 , fillComplete_ (false)
220 , indicesAreSorted_ (true)
221 , noRedundancies_ (true)
222 , haveLocalConstants_ (false)
223 , haveGlobalConstants_ (false)
224 , sortGhostsAssociatedWithEachProcessor_ (true)
226 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,maxNumEntriesPerRow," 229 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
230 maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
231 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 232 "a valid size_t value, which in this case means it must not be " 233 "Teuchos::OrdinalTraits<size_t>::invalid().");
235 checkInternalState ();
238 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
240 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
241 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
243 const Teuchos::RCP<Teuchos::ParameterList>& params) :
246 , nodeNumEntries_ (0)
248 , numAllocForAllRows_ (0)
252 , indicesAreAllocated_ (false)
253 , indicesAreLocal_ (false)
254 , indicesAreGlobal_ (false)
255 , fillComplete_ (false)
256 , indicesAreSorted_ (true)
257 , noRedundancies_ (true)
258 , haveLocalConstants_ (false)
259 , haveGlobalConstants_ (false)
260 , sortGhostsAssociatedWithEachProcessor_ (true)
262 const char tfecfFuncName[] =
"CrsGraph(rowMap,numEntPerRow,pftype,params): ";
265 const size_t lclNumRows = rowMap.is_null () ?
266 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
267 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
268 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
269 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
270 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 271 "the input row Map.");
273 #ifdef HAVE_TPETRA_DEBUG 274 for (
size_t r = 0; r < lclNumRows; ++r) {
275 const size_t curRowCount = numEntPerRow[r];
276 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
277 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
278 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 279 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
281 #endif // HAVE_TPETRA_DEBUG 286 typedef decltype (k_numAllocPerRow_) out_view_type;
287 typedef typename out_view_type::non_const_type nc_view_type;
288 typedef Kokkos::View<
const size_t*,
289 typename nc_view_type::array_layout,
291 Kokkos::MemoryUnmanaged> in_view_type;
292 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
293 nc_view_type numAllocPerRowOut (
"Tpetra::CrsGraph::numAllocPerRow",
296 k_numAllocPerRow_ = numAllocPerRowOut;
299 checkInternalState ();
302 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
304 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
305 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
307 const Teuchos::RCP<Teuchos::ParameterList>& params) :
310 , nodeNumEntries_ (0)
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)
365 , k_numAllocPerRow_ (numEntPerRow.h_view)
366 , numAllocForAllRows_ (0)
370 , indicesAreAllocated_ (false)
371 , indicesAreLocal_ (false)
372 , indicesAreGlobal_ (false)
373 , fillComplete_ (false)
374 , indicesAreSorted_ (true)
375 , noRedundancies_ (true)
376 , haveLocalConstants_ (false)
377 , haveGlobalConstants_ (false)
378 , sortGhostsAssociatedWithEachProcessor_ (true)
380 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype,params): ";
383 const size_t lclNumRows = rowMap.is_null () ?
384 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
385 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
386 static_cast<size_t> (numEntPerRow.dimension_0 ()) != lclNumRows,
387 std::invalid_argument,
"numEntPerRow has length " <<
388 numEntPerRow.dimension_0 () <<
" != the local number of rows " <<
389 lclNumRows <<
" as specified by " "the input row Map.");
391 #ifdef HAVE_TPETRA_DEBUG 392 for (
size_t r = 0; r < lclNumRows; ++r) {
393 const size_t curRowCount = numEntPerRow.h_view(r);
394 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
395 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
396 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 397 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
399 #endif // HAVE_TPETRA_DEBUG 402 checkInternalState ();
406 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
408 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
409 const Teuchos::RCP<const map_type>& colMap,
410 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
412 const Teuchos::RCP<Teuchos::ParameterList>& params) :
416 , nodeNumEntries_ (0)
418 , numAllocForAllRows_ (0)
422 , indicesAreAllocated_ (false)
423 , indicesAreLocal_ (false)
424 , indicesAreGlobal_ (false)
425 , fillComplete_ (false)
426 , indicesAreSorted_ (true)
427 , noRedundancies_ (true)
428 , haveLocalConstants_ (false)
429 , haveGlobalConstants_ (false)
430 , sortGhostsAssociatedWithEachProcessor_ (true)
432 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype," 436 const size_t lclNumRows = rowMap.is_null () ?
437 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
438 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
439 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
440 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
441 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 442 "the input row Map.");
444 #ifdef HAVE_TPETRA_DEBUG 445 for (
size_t r = 0; r < lclNumRows; ++r) {
446 const size_t curRowCount = numEntPerRow[r];
447 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
448 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
449 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 450 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
452 #endif // HAVE_TPETRA_DEBUG 457 typedef decltype (k_numAllocPerRow_) out_view_type;
458 typedef typename out_view_type::non_const_type nc_view_type;
459 typedef Kokkos::View<
const size_t*,
460 typename nc_view_type::array_layout,
462 Kokkos::MemoryUnmanaged> in_view_type;
463 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
464 nc_view_type numAllocPerRowOut (
"Tpetra::CrsGraph::numAllocPerRow",
467 k_numAllocPerRow_ = numAllocPerRowOut;
470 checkInternalState ();
474 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
476 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
477 const Teuchos::RCP<const map_type>& colMap,
478 const typename local_graph_type::row_map_type& rowPointers,
479 const typename local_graph_type::entries_type::non_const_type& columnIndices,
480 const Teuchos::RCP<Teuchos::ParameterList>& params) :
484 , nodeNumEntries_ (0)
489 , numAllocForAllRows_(0)
490 , storageStatus_ (
Details::STORAGE_1D_PACKED)
491 , indicesAreAllocated_(true)
492 , indicesAreLocal_(true)
493 , indicesAreGlobal_(false)
494 , fillComplete_(false)
495 , indicesAreSorted_(true)
496 , noRedundancies_(true)
497 , haveLocalConstants_ (false)
498 , haveGlobalConstants_ (false)
499 , sortGhostsAssociatedWithEachProcessor_(true)
502 setAllIndices (rowPointers, columnIndices);
503 checkInternalState ();
507 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
509 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
510 const Teuchos::RCP<const map_type>& colMap,
511 const Teuchos::ArrayRCP<size_t>& rowPointers,
512 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
513 const Teuchos::RCP<Teuchos::ParameterList>& params) :
517 , nodeNumEntries_ (0)
522 , numAllocForAllRows_ (0)
523 , storageStatus_ (
Details::STORAGE_1D_PACKED)
524 , indicesAreAllocated_ (true)
525 , indicesAreLocal_ (true)
526 , indicesAreGlobal_ (false)
527 , fillComplete_ (false)
528 , indicesAreSorted_ (true)
529 , noRedundancies_ (true)
530 , haveLocalConstants_ (false)
531 , haveGlobalConstants_ (false)
532 , sortGhostsAssociatedWithEachProcessor_ (true)
535 setAllIndices (rowPointers, columnIndices);
536 checkInternalState ();
540 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
542 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
543 const Teuchos::RCP<const map_type>& colMap,
545 const Teuchos::RCP<Teuchos::ParameterList>& params)
549 , lclGraph_ (k_local_graph_)
550 , nodeNumEntries_ (0)
555 , numAllocForAllRows_ (0)
556 , storageStatus_ (
Details::STORAGE_1D_PACKED)
557 , indicesAreAllocated_ (true)
558 , indicesAreLocal_ (true)
559 , indicesAreGlobal_ (false)
560 , fillComplete_ (false)
561 , indicesAreSorted_ (true)
562 , noRedundancies_ (true)
563 , haveLocalConstants_ (false)
564 , haveGlobalConstants_ (false)
565 , sortGhostsAssociatedWithEachProcessor_(true)
568 using Teuchos::ArrayRCP;
569 using Teuchos::ParameterList;
570 using Teuchos::parameterList;
572 typedef GlobalOrdinal GO;
573 typedef LocalOrdinal LO;
576 const char tfecfFuncName[] =
"CrsGraph(Map,Map,Kokkos::LocalStaticCrsGraph)";
578 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
579 colMap.is_null (), std::runtime_error,
580 ": The input column Map must be nonnull.");
581 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
582 k_local_graph_.numRows () != rowMap->getNodeNumElements (),
584 ": The input row Map and the input local graph need to have the same " 585 "number of rows. The row Map claims " << rowMap->getNodeNumElements ()
586 <<
" row(s), but the local graph claims " << k_local_graph_.numRows ()
595 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
596 k_lclInds1D_.dimension_0 () != 0 || k_gblInds1D_.dimension_0 () != 0, std::logic_error,
597 ": cannot have 1D data structures allocated.");
598 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
599 ! lclInds2D_.is_null () || ! gblInds2D_.is_null (), std::logic_error,
600 ": cannot have 2D data structures allocated.");
602 if (this->getNodeNumRows () == 0) {
606 nodeNumEntries_ = Details::getEntryOnHost (this->lclGraph_.row_map,
607 this->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 this->rowMap_.is_null () ?
760 static_cast<size_t> (0) :
761 this->rowMap_->getNodeNumElements ();
765 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
770 const char tfecfFuncName[] =
"getNodeNumCols: ";
771 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
772 ! hasColMap (), std::runtime_error,
773 "The graph does not have a column Map. You may not call this method " 774 "unless the graph has a column Map. This requires either that a custom " 775 "column Map was given to the constructor, or that fillComplete() has " 777 return colMap_.is_null () ?
static_cast<size_t> (0) :
778 colMap_->getNodeNumElements ();
782 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
787 return nodeNumDiags_;
791 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
796 #ifdef HAVE_TPETRA_DEBUG 797 const char tfecfFuncName[] =
"getGlobalNumDiags()";
798 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!haveGlobalConstants_, std::logic_error,
799 ": The matrix does not have globalConstants computed, but the user has requested them.");
801 return globalNumDiags_;
805 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
810 return rowMap_.is_null () ? Teuchos::null : rowMap_->
getNode ();
814 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
815 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
823 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
824 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
832 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
833 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
841 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
842 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
849 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
850 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
858 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
859 Teuchos::RCP<const Export<LocalOrdinal, GlobalOrdinal, Node> >
867 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
872 return ! colMap_.is_null ();
876 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
884 const bool isOpt = indicesAreAllocated_ &&
885 k_numRowEntries_.dimension_0 () == 0 &&
886 getNodeNumRows () > 0;
888 #ifdef HAVE_TPETRA_DEBUG 889 const char tfecfFuncName[] =
"isStorageOptimized";
890 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
892 ": The matrix claims to have optimized storage, but getProfileType() " 893 "returns DynamicProfile. This should never happen. Please report this " 894 "bug to the Tpetra developers.");
895 #endif // HAVE_TPETRA_DEBUG 901 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
910 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
915 #ifdef HAVE_TPETRA_DEBUG 916 const char tfecfFuncName[] =
"getGlobalNumEntries()";
917 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!haveGlobalConstants_, std::logic_error,
918 ": The matrix does not have globalConstants computed, but the user has requested them.");
920 return globalNumEntries_;
924 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
929 return nodeNumEntries_;
933 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
938 #ifdef HAVE_TPETRA_DEBUG 939 const char tfecfFuncName[] =
"getGlobalMaxNumRowEntries()";
940 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!haveGlobalConstants_, std::logic_error,
941 ": The matrix does not have globalConstants computed, but the user has requested them.");
944 return globalMaxNumRowEntries_;
948 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
953 return nodeMaxNumRowEntries_;
957 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
962 return fillComplete_;
966 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
971 return ! fillComplete_;
975 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
980 return upperTriangular_;
984 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
989 return lowerTriangular_;
993 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
998 return indicesAreLocal_;
1002 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1007 return indicesAreGlobal_;
1011 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1016 typedef LocalOrdinal LO;
1018 if (this->indicesAreAllocated_) {
1019 const LO lclNumRows = this->getNodeNumRows ();
1020 if (lclNumRows == 0) {
1021 return static_cast<size_t> (0);
1023 else if (this->storageStatus_ == Details::STORAGE_1D_PACKED) {
1024 if (static_cast<LO> (this->lclGraph_.row_map.dimension_0 ()) <
1025 static_cast<LO> (lclNumRows + 1)) {
1026 return static_cast<size_t> (0);
1029 return Details::getEntryOnHost (this->lclGraph_.row_map, lclNumRows);
1032 else if (this->storageStatus_ == Details::STORAGE_1D_UNPACKED) {
1033 if (this->k_rowPtrs_.dimension_0 () == 0) {
1034 return static_cast<size_t> (0);
1037 return Details::getEntryOnHost (this->k_rowPtrs_, lclNumRows);
1040 else if (this->storageStatus_ == Details::STORAGE_2D) {
1041 size_t numAllocated = 0;
1042 if (this->isLocallyIndexed ()) {
1043 for (LocalOrdinal lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1044 numAllocated += this->lclInds2D_[lclRow].size ();
1047 else if (this->isGloballyIndexed ()) {
1048 for (LocalOrdinal lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1049 numAllocated += this->gblInds2D_[lclRow].size ();
1053 return numAllocated;
1056 return static_cast<size_t> (0);
1060 return Tpetra::Details::OrdinalTraits<size_t>::invalid ();
1065 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1066 Teuchos::RCP<const Teuchos::Comm<int> >
1070 return this->rowMap_.is_null () ? Teuchos::null : this->rowMap_->
getComm ();
1074 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1083 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1088 return indicesAreAllocated_;
1092 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1097 return indicesAreSorted_;
1101 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1106 return noRedundancies_;
1110 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1120 indicesAreSorted_ =
false;
1121 noRedundancies_ =
false;
1125 haveLocalConstants_ =
false;
1129 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1134 using Teuchos::arcp;
1135 using Teuchos::Array;
1136 using Teuchos::ArrayRCP;
1137 typedef Teuchos::ArrayRCP<size_t>::size_type size_type;
1138 typedef typename local_graph_type::row_map_type::non_const_type
1139 non_const_row_map_type;
1140 typedef typename local_graph_type::entries_type::non_const_type
1142 typedef Kokkos::View<GlobalOrdinal*,
1143 typename lcl_col_inds_type::array_layout,
1145 const char tfecfFuncName[] =
"allocateIndices: ";
1146 const char suffix[] =
" Please report this bug to the Tpetra developers.";
1151 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1152 (this->isLocallyIndexed () && lg == GlobalIndices, std::logic_error,
1153 "The graph is locally indexed, but Tpetra code is calling this method " 1154 "with lg=GlobalIndices." << suffix);
1155 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1156 (this->isGloballyIndexed () && lg == LocalIndices, std::logic_error,
1157 "The graph is globally indexed, but Tpetra code is calling this method " 1158 "with lg=LocalIndices. " << suffix);
1159 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1160 (this->indicesAreAllocated (), std::logic_error,
"The graph's indices " 1161 "are already allocated, but Tpetra is calling allocateIndices again." 1163 const size_t numRows = this->getNodeNumRows ();
1169 non_const_row_map_type k_rowPtrs (
"Tpetra::CrsGraph::ptr", numRows + 1);
1171 if (this->k_numAllocPerRow_.dimension_0 () != 0) {
1176 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1177 (this->k_numAllocPerRow_.dimension_0 () != numRows,
1178 std::invalid_argument,
"k_numAllocPerRow_ is allocated, that is, " 1179 "has nonzero length " << this->k_numAllocPerRow_.dimension_0 ()
1180 <<
", but its length != numRows = " << numRows <<
".");
1198 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1199 (this->numAllocForAllRows_ ==
1200 Tpetra::Details::OrdinalTraits<size_t>::invalid (),
1201 std::invalid_argument,
"numAllocForAllRows_ has an invalid value, " 1202 "namely Tpetra::Details::OrdinalTraits<size_t>::invalid() = " <<
1203 Tpetra::Details::OrdinalTraits<size_t>::invalid () <<
".");
1210 this->k_rowPtrs_ = k_rowPtrs;
1212 const size_type numInds = Details::getEntryOnHost (this->k_rowPtrs_, numRows);
1214 if (lg == LocalIndices) {
1215 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1218 k_gblInds1D_ = gbl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1220 storageStatus_ = Details::STORAGE_1D_UNPACKED;
1226 const bool useNumAllocPerRow =
1227 (this->k_numAllocPerRow_.dimension_0 () != 0);
1229 if (lg == LocalIndices) {
1230 this->lclInds2D_ = arcp<Array<LocalOrdinal> > (numRows);
1231 for (
size_t i = 0; i < numRows; ++i) {
1232 const size_t howMany = useNumAllocPerRow ?
1233 this->k_numAllocPerRow_(i) :
1234 this->numAllocForAllRows_;
1236 this->lclInds2D_[i].resize (howMany);
1241 this->gblInds2D_ = arcp<Array<GlobalOrdinal> > (numRows);
1242 for (
size_t i = 0; i < numRows; ++i) {
1243 const size_t howMany = useNumAllocPerRow ?
1244 this->k_numAllocPerRow_(i) :
1245 this->numAllocForAllRows_;
1247 this->gblInds2D_[i].resize (howMany);
1251 this->storageStatus_ = Details::STORAGE_2D;
1254 this->indicesAreLocal_ = (lg == LocalIndices);
1255 this->indicesAreGlobal_ = (lg == GlobalIndices);
1258 using Kokkos::ViewAllocateWithoutInitializing;
1259 typedef decltype (k_numRowEntries_) row_ent_type;
1260 const char label[] =
"Tpetra::CrsGraph::numRowEntries";
1262 row_ent_type numRowEnt (ViewAllocateWithoutInitializing (label), numRows);
1264 this->k_numRowEntries_ = numRowEnt;
1268 this->numAllocForAllRows_ = 0;
1269 this->k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
1270 this->indicesAreAllocated_ =
true;
1273 this->checkInternalState ();
1275 catch (std::logic_error& e) {
1276 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1277 (
true, std::logic_error,
"At end of allocateIndices, " 1278 "checkInternalState threw std::logic_error: " 1281 catch (std::exception& e) {
1282 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1283 (
true, std::runtime_error,
"At end of allocateIndices, " 1284 "checkInternalState threw std::exception: " 1288 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1289 (
true, std::runtime_error,
"At end of allocateIndices, " 1290 "checkInternalState threw an exception " 1291 "not a subclass of std::exception.");
1296 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1297 Teuchos::ArrayView<const LocalOrdinal>
1301 using Kokkos::subview;
1302 typedef LocalOrdinal LO;
1304 Kokkos::MemoryUnmanaged> row_view_type;
1306 if (rowinfo.allocSize == 0) {
1307 return Teuchos::ArrayView<const LO> ();
1310 if (k_lclInds1D_.dimension_0 () != 0) {
1311 const size_t start = rowinfo.offset1D;
1312 const size_t len = rowinfo.allocSize;
1313 const std::pair<size_t, size_t> rng (start, start + len);
1319 row_view_type rowView = subview (row_view_type (k_lclInds1D_), rng);
1320 const LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1321 return Teuchos::ArrayView<const LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1323 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1324 return lclInds2D_[rowinfo.localRow] ();
1327 return Teuchos::ArrayView<const LO> ();
1332 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1336 LocalOrdinal& numEnt,
1342 if (rowinfo.allocSize != 0) {
1343 if (k_lclInds1D_.dimension_0 () != 0) {
1344 #ifdef HAVE_TPETRA_DEBUG 1345 if (rowinfo.offset1D + rowinfo.allocSize >
1346 static_cast<size_t> (k_lclInds1D_.dimension_0 ())) {
1347 return static_cast<LocalOrdinal
> (-1);
1349 #endif // HAVE_TPETRA_DEBUG 1350 lclInds = &k_lclInds1D_[rowinfo.offset1D];
1351 numEnt = rowinfo.allocSize;
1354 #ifdef HAVE_TPETRA_DEBUG 1355 if (rowinfo.localRow >= static_cast<size_t> (lclInds2D_.size ())) {
1356 return static_cast<LocalOrdinal
> (-1);
1358 #endif // HAVE_TPETRA_DEBUG 1361 const auto& curRow = lclInds2D_[rowinfo.localRow];
1362 if (! curRow.empty ()) {
1363 lclInds = curRow.getRawPtr ();
1364 numEnt = curRow.size ();
1368 return static_cast<LocalOrdinal
> (0);
1371 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1372 Teuchos::ArrayView<LocalOrdinal>
1376 using Kokkos::subview;
1377 typedef LocalOrdinal LO;
1379 Kokkos::MemoryUnmanaged> row_view_type;
1381 if (rowinfo.allocSize == 0) {
1382 return Teuchos::ArrayView<LO> ();
1385 if (k_lclInds1D_.dimension_0 () != 0) {
1386 const size_t start = rowinfo.offset1D;
1387 const size_t len = rowinfo.allocSize;
1388 const std::pair<size_t, size_t> rng (start, start + len);
1394 row_view_type rowView = subview (row_view_type (k_lclInds1D_), rng);
1395 LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1396 return Teuchos::ArrayView<LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1398 else if (! lclInds2D_[rowinfo.localRow].empty ()) {
1399 return lclInds2D_[rowinfo.localRow] ();
1402 return Teuchos::ArrayView<LO> ();
1408 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1409 Kokkos::View<
const LocalOrdinal*,
1411 Kokkos::MemoryUnmanaged>
1415 typedef LocalOrdinal LO;
1417 Kokkos::MemoryUnmanaged> row_view_type;
1419 if (rowInfo.allocSize == 0) {
1420 return row_view_type ();
1423 if (k_lclInds1D_.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 (k_lclInds1D_), rng);
1434 else if (! this->lclInds2D_[rowInfo.localRow].empty ()) {
1441 Teuchos::Array<LO>& lclInds = this->lclInds2D_[rowInfo.localRow];
1442 return row_view_type (lclInds.getRawPtr (), lclInds.size ());
1445 return row_view_type ();
1451 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1452 Kokkos::View<LocalOrdinal*,
1453 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1454 Kokkos::MemoryUnmanaged>
1458 typedef LocalOrdinal LO;
1460 Kokkos::MemoryUnmanaged> row_view_type;
1462 if (rowInfo.allocSize == 0) {
1463 return row_view_type ();
1466 if (k_lclInds1D_.dimension_0 () != 0) {
1467 const size_t start = rowInfo.offset1D;
1468 const size_t len = rowInfo.allocSize;
1469 const std::pair<size_t, size_t> rng (start, start + len);
1475 return Kokkos::subview (row_view_type (this->k_lclInds1D_), rng);
1477 else if (! this->lclInds2D_[rowInfo.localRow].empty ()) {
1484 Teuchos::Array<LO>& cols = this->lclInds2D_[rowInfo.localRow];
1485 LO*
const colsRaw = cols.getRawPtr ();
1486 return row_view_type (colsRaw, cols.size ());
1489 return row_view_type ();
1495 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1496 Kokkos::View<
const GlobalOrdinal*,
1497 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1498 Kokkos::MemoryUnmanaged>
1502 typedef GlobalOrdinal GO;
1504 Kokkos::MemoryUnmanaged> row_view_type;
1506 if (rowinfo.allocSize == 0) {
1507 return row_view_type ();
1510 if (this->k_gblInds1D_.dimension_0 () != 0) {
1511 const size_t start = rowinfo.offset1D;
1512 const size_t len = rowinfo.allocSize;
1513 const std::pair<size_t, size_t> rng (start, start + len);
1519 return Kokkos::subview (row_view_type (this->k_gblInds1D_), rng);
1521 else if (! this->gblInds2D_[rowinfo.localRow].empty ()) {
1528 Teuchos::Array<GO>& cols = this->gblInds2D_[rowinfo.localRow];
1529 return row_view_type (cols.getRawPtr (), cols.size ());
1532 return row_view_type ();
1538 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1539 Teuchos::ArrayView<const GlobalOrdinal>
1543 Teuchos::ArrayView<const GlobalOrdinal> view;
1544 if (rowinfo.allocSize > 0) {
1545 if (k_gblInds1D_.dimension_0 () != 0) {
1546 auto rng = std::make_pair (rowinfo.offset1D,
1547 rowinfo.offset1D + rowinfo.allocSize);
1554 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged = k_gblInds1D_;
1555 view = Kokkos::Compat::getConstArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1557 else if (! gblInds2D_[rowinfo.localRow].empty()) {
1558 view = gblInds2D_[rowinfo.localRow] ();
1565 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1569 LocalOrdinal& numEnt,
1575 if (rowinfo.allocSize != 0) {
1576 if (k_gblInds1D_.dimension_0 () != 0) {
1577 #ifdef HAVE_TPETRA_DEBUG 1578 if (rowinfo.offset1D + rowinfo.allocSize >
1579 static_cast<size_t> (k_gblInds1D_.dimension_0 ())) {
1580 return static_cast<LocalOrdinal
> (-1);
1582 #endif // HAVE_TPETRA_DEBUG 1583 gblInds = &k_gblInds1D_[rowinfo.offset1D];
1584 numEnt = rowinfo.allocSize;
1587 #ifdef HAVE_TPETRA_DEBUG 1588 if (rowinfo.localRow >= static_cast<size_t> (gblInds2D_.size ())) {
1589 return static_cast<LocalOrdinal
> (-1);
1591 #endif // HAVE_TPETRA_DEBUG 1592 const auto& curRow = gblInds2D_[rowinfo.localRow];
1593 if (! curRow.empty ()) {
1594 gblInds = curRow.getRawPtr ();
1595 numEnt = curRow.size ();
1599 return static_cast<LocalOrdinal
> (0);
1603 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1604 Teuchos::ArrayView<GlobalOrdinal>
1608 Teuchos::ArrayView<GlobalOrdinal> view;
1609 if (rowinfo.allocSize > 0) {
1610 if (k_gblInds1D_.dimension_0 () != 0) {
1611 auto rng = std::make_pair (rowinfo.offset1D,
1612 rowinfo.offset1D + rowinfo.allocSize);
1619 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged = k_gblInds1D_;
1620 view = Kokkos::Compat::getArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1622 else if (! gblInds2D_[rowinfo.localRow].empty()) {
1623 view = gblInds2D_[rowinfo.localRow] ();
1630 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1635 #ifdef HAVE_TPETRA_DEBUG 1636 const char tfecfFuncName[] =
"getRowInfo: ";
1637 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1638 ! hasRowInfo (), std::logic_error,
1639 "Late catch! Graph does not have row info anymore. " 1640 "Error should have been caught earlier. " 1641 "Please report this bug to the Tpetra developers.");
1642 #endif // HAVE_TPETRA_DEBUG 1644 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1646 if (! this->hasRowInfo () || this->rowMap_.is_null () ||
1647 ! this->rowMap_->isNodeLocalElement (myRow)) {
1648 ret.localRow = STINV;
1651 ret.offset1D = STINV;
1655 ret.localRow =
static_cast<size_t> (myRow);
1656 if (this->indicesAreAllocated ()) {
1659 if (this->k_rowPtrs_.dimension_0 () == 0) {
1664 ret.offset1D = this->k_rowPtrs_(myRow);
1665 ret.allocSize = this->k_rowPtrs_(myRow+1) - this->k_rowPtrs_(myRow);
1668 ret.numEntries = (this->k_numRowEntries_.dimension_0 () == 0) ?
1670 this->k_numRowEntries_(myRow);
1673 ret.offset1D = STINV;
1674 if (this->isLocallyIndexed ()) {
1675 ret.allocSize = (this->lclInds2D_.size () == 0) ?
1677 this->lclInds2D_[myRow].size ();
1679 else if (this->isGloballyIndexed ()) {
1680 ret.allocSize = (this->gblInds2D_.size () == 0) ?
1682 this->gblInds2D_[myRow].size ();
1688 ret.numEntries = (this->k_numRowEntries_.dimension_0 () == 0) ?
1690 this->k_numRowEntries_(myRow);
1697 ret.allocSize = (this->k_numAllocPerRow_.dimension_0 () != 0) ?
1698 this->k_numAllocPerRow_(myRow) :
1699 this->numAllocForAllRows_;
1701 ret.offset1D = STINV;
1708 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1713 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1715 if (! this->hasRowInfo () || this->rowMap_.is_null ()) {
1716 ret.localRow = STINV;
1719 ret.offset1D = STINV;
1722 const LocalOrdinal myRow = this->rowMap_->getLocalElement (gblRow);
1723 if (myRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
1724 ret.localRow = STINV;
1727 ret.offset1D = STINV;
1731 ret.localRow =
static_cast<size_t> (myRow);
1732 if (this->indicesAreAllocated ()) {
1737 if (this->k_rowPtrs_.dimension_0 () == 0) {
1742 ret.offset1D = this->k_rowPtrs_(myRow);
1743 ret.allocSize = this->k_rowPtrs_(myRow+1) - this->k_rowPtrs_(myRow);
1746 ret.numEntries = (this->k_numRowEntries_.dimension_0 () == 0) ?
1748 this->k_numRowEntries_(myRow);
1751 ret.offset1D = STINV;
1752 if (this->isLocallyIndexed ()) {
1753 ret.allocSize = (this->lclInds2D_.size () == 0) ?
1755 this->lclInds2D_[myRow].size ();
1758 ret.allocSize = (this->gblInds2D_.size () == 0) ?
1760 this->gblInds2D_[myRow].size ();
1763 ret.numEntries = (this->k_numRowEntries_.dimension_0 () == 0) ?
1765 this->k_numRowEntries_(myRow);
1772 ret.allocSize = (this->k_numAllocPerRow_.dimension_0 () != 0) ?
1773 this->k_numAllocPerRow_(myRow) :
1774 this->numAllocForAllRows_;
1776 ret.offset1D = STINV;
1783 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1788 using Teuchos::OrdinalTraits;
1789 typedef LocalOrdinal LO;
1790 typedef GlobalOrdinal GO;
1796 static_assert (
sizeof (GlobalOrdinal) >=
sizeof (LocalOrdinal),
1797 "Tpetra::CrsGraph: sizeof(GlobalOrdinal) must be >= sizeof(LocalOrdinal).");
1800 static_assert (
sizeof (
size_t) >=
sizeof (LocalOrdinal),
1801 "Tpetra::CrsGraph: sizeof(size_t) must be >= sizeof(LocalOrdinal).");
1802 static_assert (
sizeof(GST) >=
sizeof(
size_t),
1803 "Tpetra::CrsGraph: sizeof(Tpetra::global_size_t) must be >= sizeof(size_t).");
1811 const char msg[] =
"Tpetra::CrsGraph: Object cannot be created with the " 1812 "given template arguments: size assumptions are not valid.";
1813 TEUCHOS_TEST_FOR_EXCEPTION(
1814 static_cast<size_t> (Teuchos::OrdinalTraits<LO>::max ()) > Teuchos::OrdinalTraits<size_t>::max (),
1815 std::runtime_error, msg);
1816 TEUCHOS_TEST_FOR_EXCEPTION(
1817 static_cast<GST> (Teuchos::OrdinalTraits<LO>::max ()) > static_cast<GST> (Teuchos::OrdinalTraits<GO>::max ()),
1818 std::runtime_error, msg);
1819 TEUCHOS_TEST_FOR_EXCEPTION(
1820 static_cast<size_t> (Teuchos::OrdinalTraits<GO>::max ()) > Teuchos::OrdinalTraits<GST>::max(),
1821 std::runtime_error, msg);
1822 TEUCHOS_TEST_FOR_EXCEPTION(
1823 Teuchos::OrdinalTraits<size_t>::max () > Teuchos::OrdinalTraits<GST>::max (),
1824 std::runtime_error, msg);
1828 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1832 const SLocalGlobalViews &newInds,
1833 const ELocalGlobal lg,
1834 const ELocalGlobal I)
1836 using Teuchos::ArrayView;
1837 #ifdef HAVE_TPETRA_DEBUG 1838 TEUCHOS_TEST_FOR_EXCEPTION(
1839 lg != GlobalIndices && lg != LocalIndices, std::invalid_argument,
1840 "Tpetra::CrsGraph::insertIndices: lg must be either GlobalIndices or " 1842 #endif // HAVE_TPETRA_DEBUG 1843 size_t numNewInds = 0;
1844 if (lg == GlobalIndices) {
1845 ArrayView<const GlobalOrdinal> new_ginds = newInds.ginds;
1846 numNewInds = new_ginds.size();
1847 if (I == GlobalIndices) {
1848 ArrayView<GlobalOrdinal> gind_view = getGlobalViewNonConst(rowinfo);
1849 std::copy(new_ginds.begin(), new_ginds.end(), gind_view.begin()+rowinfo.numEntries);
1851 else if (I == LocalIndices) {
1852 ArrayView<LocalOrdinal> lind_view = getLocalViewNonConst(rowinfo);
1853 typename ArrayView<const GlobalOrdinal>::iterator in = new_ginds.begin();
1854 const typename ArrayView<const GlobalOrdinal>::iterator stop = new_ginds.end();
1855 typename ArrayView<LocalOrdinal>::iterator out = lind_view.begin()+rowinfo.numEntries;
1856 while (in != stop) {
1857 *out++ = colMap_->getLocalElement (*in++);
1861 else if (lg == LocalIndices) {
1862 ArrayView<const LocalOrdinal> new_linds = newInds.linds;
1863 numNewInds = new_linds.size();
1864 if (I == LocalIndices) {
1865 ArrayView<LocalOrdinal> lind_view = getLocalViewNonConst(rowinfo);
1866 std::copy(new_linds.begin(), new_linds.end(), lind_view.begin()+rowinfo.numEntries);
1868 else if (I == GlobalIndices) {
1869 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Tpetra::CrsGraph::" 1870 "insertIndices: the case where the input indices are local and the " 1871 "indices to write are global (lg=LocalIndices, I=GlobalIndices) is " 1872 "not implemented, because it does not make sense." << std::endl <<
1873 "If you have correct local column indices, that means the graph has " 1874 "a column Map. In that case, you should be storing local indices.");
1878 k_numRowEntries_(rowinfo.localRow) += numNewInds;
1879 nodeNumEntries_ += numNewInds;
1880 setLocallyModified ();
1885 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1889 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
1891 using Kokkos::subview;
1892 typedef Kokkos::pair<size_t, size_t> range_type;
1893 const char tfecfFuncName[] =
"insertGlobalIndicesImpl: ";
1895 RowInfo rowInfo = getRowInfo(myRow);
1896 size_t numNewInds = indices.size();
1897 size_t newNumEntries = rowInfo.numEntries + numNewInds;
1899 if (newNumEntries > rowInfo.allocSize) {
1910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1911 (rowInfo.numEntries > rowInfo.allocSize, std::logic_error,
1912 "For local row " << myRow <<
", rowInfo.numEntries = " 1913 << rowInfo.numEntries <<
" > rowInfo.allocSize = " 1914 << rowInfo.allocSize
1915 <<
". Please report this bug to the Tpetra developers.");
1917 size_t dupCount = 0;
1918 if (k_gblInds1D_.dimension_0 () != 0) {
1919 const size_t curOffset = rowInfo.offset1D;
1920 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1921 (static_cast<size_t> (k_gblInds1D_.dimension_0 ()) < curOffset,
1922 std::logic_error,
"k_gblInds1D_.dimension_0() = " <<
1923 k_gblInds1D_.dimension_0 () <<
" < offset1D = " << curOffset
1924 <<
". Please report this bug to the Tpetra developers.");
1925 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1926 (static_cast<size_t> (k_gblInds1D_.dimension_0 ()) <
1927 curOffset + rowInfo.numEntries,
1928 std::logic_error,
"k_gblInds1D_.dimension_0() = " <<
1929 k_gblInds1D_.dimension_0 () <<
" < offset1D (= " << curOffset <<
1930 ") + rowInfo.numEntries (= " << rowInfo.numEntries <<
"). Please " 1931 "report this bug to the Tpetra developers.");
1932 const Kokkos::pair<size_t, size_t>
1933 range (curOffset, curOffset + rowInfo.numEntries);
1935 auto gblIndsCur = subview (k_gblInds1D_, range);
1936 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1937 (static_cast<size_t> (gblIndsCur.dimension_0 ()) != rowInfo.numEntries,
1938 std::logic_error,
"gblIndsCur.dimension_0() = " <<
1939 gblIndsCur.dimension_0 () <<
" != rowInfo.numEntries = " <<
1940 rowInfo.numEntries <<
". Please report this bug to the Tpetra " 1943 const size_t numInput =
static_cast<size_t> (indices.size ());
1944 for (
size_t k_new = 0; k_new < numInput; ++k_new) {
1945 const GlobalOrdinal gblIndToInsert = indices[k_new];
1946 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1947 if (gblIndsCur[k_old] == gblIndToInsert) {
1959 Teuchos::ArrayView<GlobalOrdinal> gblInds = (gblInds2D_[myRow]) ();
1960 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1961 (rowInfo.allocSize != static_cast<size_t> (gblInds.size ()),
1962 std::logic_error,
"rowInfo.allocSize = " << rowInfo.allocSize
1963 <<
" != gblInds.size() = " << gblInds.size ()
1964 <<
". Please report this bug to the Tpetra developers.");
1965 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1966 (rowInfo.numEntries > static_cast<size_t> (gblInds.size ()),
1967 std::logic_error,
"rowInfo.numEntries = " << rowInfo.numEntries
1968 <<
" > gblInds.size() = " << gblInds.size ()
1969 <<
". Please report this bug to the Tpetra developers.");
1970 auto gblIndsCur = gblInds (0, rowInfo.numEntries);
1972 const size_t numInput =
static_cast<size_t> (indices.size ());
1973 for (
size_t k_new = 0; k_new < numInput; ++k_new) {
1974 const GlobalOrdinal gblIndToInsert = indices[k_new];
1975 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
1976 if (gblIndsCur[k_old] == gblIndToInsert) {
1988 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1989 (static_cast<size_t> (indices.size ()) < dupCount, std::logic_error,
1990 "indices.size() = " << indices.size () <<
" < dupCount = " <<
1991 dupCount <<
". Please report this bug to the Tpetra developers.");
1992 const size_t numNewToInsert =
1993 static_cast<size_t> (indices.size ()) - dupCount;
1995 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1996 (rowInfo.numEntries + numNewToInsert > rowInfo.allocSize,
1997 std::runtime_error,
"For local row " << myRow <<
" on Process " <<
1998 this->getComm ()->getRank () <<
", even after excluding " << dupCount
1999 <<
" duplicate(s) in input, the new number of entries " <<
2000 (rowInfo.numEntries + numNewToInsert) <<
" still exceeds this row's " 2001 "static allocation size " << rowInfo.allocSize <<
". You must " 2002 "either fix the upper bound on the number of entries in this row, " 2003 "or switch from StaticProfile to DynamicProfile.");
2005 if (k_gblInds1D_.dimension_0 () != 0) {
2006 const size_t curOffset = rowInfo.offset1D;
2008 subview (k_gblInds1D_, range_type (curOffset,
2009 curOffset + rowInfo.numEntries));
2011 subview (k_gblInds1D_, range_type (curOffset + rowInfo.numEntries,
2012 curOffset + rowInfo.allocSize));
2015 for (
size_t k_new = 0; k_new < numNewInds; ++k_new) {
2016 const GlobalOrdinal gblIndToInsert = indices[k_new];
2018 bool isAlreadyInOld =
false;
2019 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
2020 if (gblIndsCur[k_old] == gblIndToInsert) {
2021 isAlreadyInOld =
true;
2025 if (! isAlreadyInOld) {
2026 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2027 (curPos >= numNewToInsert, std::logic_error,
"curPos = " <<
2028 curPos <<
" >= numNewToInsert = " << numNewToInsert <<
". " 2029 "Please report this bug to the Tpetra developers.");
2030 gblIndsNew[curPos] = gblIndToInsert;
2036 Teuchos::ArrayView<GlobalOrdinal> gblInds = (gblInds2D_[myRow]) ();
2038 auto gblIndsCur = gblInds (0, rowInfo.numEntries);
2039 auto gblIndsNew = gblInds (rowInfo.numEntries,
2040 rowInfo.allocSize - rowInfo.numEntries);
2043 for (
size_t k_new = 0; k_new < numNewInds; ++k_new) {
2044 const GlobalOrdinal gblIndToInsert = indices[k_new];
2046 bool isAlreadyInOld =
false;
2047 for (
size_t k_old = 0; k_old < rowInfo.numEntries; ++k_old) {
2048 if (gblIndsCur[k_old] == gblIndToInsert) {
2049 isAlreadyInOld =
true;
2053 if (! isAlreadyInOld) {
2054 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2055 (curPos >= numNewToInsert, std::logic_error,
"curPos = " <<
2056 curPos <<
" >= numNewToInsert = " << numNewToInsert <<
". " 2057 "Please report this bug to the Tpetra developers.");
2058 gblIndsNew[curPos] = gblIndToInsert;
2064 k_numRowEntries_(myRow) = rowInfo.numEntries + numNewToInsert;
2065 nodeNumEntries_ += numNewToInsert;
2066 setLocallyModified ();
2068 #ifdef HAVE_TPETRA_DEBUG 2069 newNumEntries = rowInfo.numEntries + numNewToInsert;
2070 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
2071 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2072 (chkNewNumEntries != newNumEntries, std::logic_error,
2073 "After inserting new entries, getNumEntriesInLocalRow(" << myRow <<
2074 ") = " << chkNewNumEntries <<
" != newNumEntries = " << newNumEntries
2075 <<
". Please report this bug to the Tpetra developers.");
2076 #endif // HAVE_TPETRA_DEBUG 2082 size_t newAllocSize = 2*rowInfo.allocSize;
2083 if (newAllocSize < newNumEntries) {
2084 newAllocSize = newNumEntries;
2086 gblInds2D_[myRow].resize(newAllocSize);
2091 if (k_gblInds1D_.dimension_0 () != 0) {
2092 const size_t numIndsToCopy =
static_cast<size_t> (indices.size ());
2093 const size_t offset = rowInfo.offset1D + rowInfo.numEntries;
2094 for (
size_t k = 0; k < numIndsToCopy; ++k) {
2095 k_gblInds1D_[offset + k] = indices[k];
2099 std::copy(indices.begin(), indices.end(),
2100 gblInds2D_[myRow].begin()+rowInfo.numEntries);
2103 k_numRowEntries_(myRow) += numNewInds;
2104 nodeNumEntries_ += numNewInds;
2105 setLocallyModified ();
2107 #ifdef HAVE_TPETRA_DEBUG 2109 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
2110 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2111 chkNewNumEntries != newNumEntries, std::logic_error,
2112 ": Internal logic error. Please contact Tpetra team.");
2118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2122 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2124 using Kokkos::MemoryUnmanaged;
2125 using Kokkos::subview;
2127 typedef LocalOrdinal LO;
2128 const char* tfecfFuncName (
"insertLocallIndicesImpl");
2130 const RowInfo rowInfo = this->getRowInfo(myRow);
2131 const size_t numNewInds = indices.size();
2132 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
2133 if (newNumEntries > rowInfo.allocSize) {
2134 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2136 ": new indices exceed statically allocated graph structure.");
2139 size_t newAllocSize = 2*rowInfo.allocSize;
2140 if (newAllocSize < newNumEntries)
2141 newAllocSize = newNumEntries;
2142 lclInds2D_[myRow].resize(newAllocSize);
2146 if (k_lclInds1D_.dimension_0 () != 0) {
2147 typedef View<const LO*, execution_space, MemoryUnmanaged> input_view_type;
2148 typedef View<LO*, execution_space, MemoryUnmanaged> row_view_type;
2150 input_view_type inputInds (indices.getRawPtr (), indices.size ());
2151 const size_t start = rowInfo.offset1D + rowInfo.numEntries;
2152 const std::pair<size_t, size_t> rng (start, start + newNumEntries);
2157 row_view_type myInds = subview (row_view_type (k_lclInds1D_), rng);
2161 std::copy (indices.begin (), indices.end (),
2162 lclInds2D_[myRow].begin () + rowInfo.numEntries);
2165 k_numRowEntries_(myRow) += numNewInds;
2166 nodeNumEntries_ += numNewInds;
2167 setLocallyModified ();
2168 #ifdef HAVE_TPETRA_DEBUG 2170 const size_t chkNewNumEntries = getNumEntriesInLocalRow (myRow);
2171 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2172 chkNewNumEntries != newNumEntries, std::logic_error,
2173 ": Internal logic error. Please contact Tpetra team.");
2179 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2184 if (rowInfo.numEntries > 0) {
2185 auto lclColInds = this->getLocalKokkosRowViewNonConst (rowInfo);
2187 LocalOrdinal*
const lclColIndsRaw = lclColInds.ptr_on_device ();
2188 std::sort (lclColIndsRaw, lclColIndsRaw + rowInfo.numEntries);
2193 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2198 auto lclColInds = this->getLocalKokkosRowViewNonConst (rowInfo);
2201 LocalOrdinal*
const beg = lclColInds.ptr_on_device ();
2202 LocalOrdinal*
const end = beg + rowInfo.numEntries;
2203 LocalOrdinal*
const newend = std::unique (beg, end);
2204 const size_t mergedEntries = newend - beg;
2207 this->k_numRowEntries_(rowInfo.localRow) = mergedEntries;
2208 return rowInfo.numEntries - mergedEntries;
2212 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2216 const Teuchos::RCP<const map_type>& rangeMap)
2219 if (domainMap_ != domainMap) {
2220 domainMap_ = domainMap;
2221 importer_ = Teuchos::null;
2223 if (rangeMap_ != rangeMap) {
2224 rangeMap_ = rangeMap;
2225 exporter_ = Teuchos::null;
2230 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2235 globalNumEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2236 globalNumDiags_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2237 globalMaxNumRowEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2238 haveGlobalConstants_ =
false;
2242 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2247 #ifdef HAVE_TPETRA_DEBUG 2248 const char tfecfFuncName[] =
"checkInternalState: ";
2249 const char suffix[] =
" Please report this bug to the Tpetra developers.";
2251 const global_size_t GSTI = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2257 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2258 (this->rowMap_.is_null (), std::logic_error,
2259 "Row Map is null." << suffix);
2262 const LocalOrdinal lclNumRows =
2263 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
2265 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2266 (this->isFillActive () == this->isFillComplete (), std::logic_error,
2267 "Graph cannot be both fill active and fill complete." << suffix);
2268 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2269 (this->isFillComplete () &&
2270 (this->colMap_.is_null () ||
2271 this->rangeMap_.is_null () ||
2272 this->domainMap_.is_null ()),
2274 "Graph is full complete, but at least one of {column, range, domain} " 2275 "Map is null." << suffix);
2276 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2277 (this->isStorageOptimized () && ! this->indicesAreAllocated (),
2278 std::logic_error,
"Storage is optimized, but indices are not " 2279 "allocated, not even trivially." << suffix);
2280 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2281 (this->indicesAreAllocated_ &&
2282 (this->storageStatus_ == Details::STORAGE_1D_PACKED ||
2283 this->storageStatus_ == Details::STORAGE_1D_UNPACKED) &&
2285 "Graph claims to have allocated indices and 1-D storage " 2286 "(either packed or unpacked), but also claims to be DynamicProfile.");
2287 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2288 (this->indicesAreAllocated_ &&
2289 this->storageStatus_ == Details::STORAGE_2D &&
2291 "Graph claims to have allocated indices and 2-D storage, " 2292 "but also claims to be StaticProfile.");
2293 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2294 (this->indicesAreAllocated_ &&
2295 this->storageStatus_ == Details::STORAGE_2D &&
2296 this->isLocallyIndexed () &&
2297 static_cast<LocalOrdinal> (this->lclInds2D_.size ()) != lclNumRows,
2299 "Graph claims to have allocated indices, be locally indexed, and have " 2300 "2-D storage, but lclInds2D_.size() = " << this->lclInds2D_.size ()
2301 <<
" != getNodeNumRows() = " << lclNumRows <<
".");
2302 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2303 (this->indicesAreAllocated_ &&
2304 this->storageStatus_ == Details::STORAGE_2D &&
2305 this->isGloballyIndexed () &&
2306 static_cast<LocalOrdinal> (this->gblInds2D_.size ()) != lclNumRows,
2308 "Graph claims to have allocated indices, be globally indexed, and have " 2309 "2-D storage, but gblInds2D_.size() = " << this->gblInds2D_.size ()
2310 <<
" != getNodeNumRows() = " << lclNumRows <<
".");
2312 size_t nodeAllocSize = 0;
2314 nodeAllocSize = this->getNodeAllocationSize ();
2316 catch (std::logic_error& e) {
2317 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2318 (
true, std::runtime_error,
"getNodeAllocationSize threw " 2319 "std::logic_error: " << e.what ());
2321 catch (std::exception& e) {
2322 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2323 (
true, std::runtime_error,
"getNodeAllocationSize threw an " 2324 "std::exception: " << e.what ());
2327 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2328 (
true, std::runtime_error,
"getNodeAllocationSize threw an exception " 2329 "not a subclass of std::exception.");
2332 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2333 (this->isStorageOptimized () &&
2334 nodeAllocSize != this->getNodeNumEntries (),
2335 std::logic_error,
"Storage is optimized, but " 2336 "this->getNodeAllocationSize() = " << nodeAllocSize
2337 <<
" != this->getNodeNumEntries() = " << this->getNodeNumEntries ()
2339 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2340 (! this->haveGlobalConstants_ &&
2341 (this->globalNumEntries_ != GSTI ||
2342 this->globalNumDiags_ != GSTI ||
2343 this->globalMaxNumRowEntries_ != GSTI),
2344 std::logic_error,
"Graph claims not to have global constants, but " 2345 "some of the global constants are not marked as invalid." << suffix);
2346 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2347 (this->haveGlobalConstants_ &&
2348 (this->globalNumEntries_ == GSTI ||
2349 this->globalNumDiags_ == GSTI ||
2350 this->globalMaxNumRowEntries_ == GSTI),
2351 std::logic_error,
"Graph claims to have global constants, but " 2352 "some of them are marked as invalid." << suffix);
2353 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2354 (this->haveGlobalConstants_ &&
2355 (this->globalNumEntries_ < this->nodeNumEntries_ ||
2356 this->globalNumDiags_ < this->nodeNumDiags_ ||
2357 this->globalMaxNumRowEntries_ < this->nodeMaxNumRowEntries_),
2358 std::logic_error,
"Graph claims to have global constants, and " 2359 "all of the values of the global constants are valid, but " 2360 "some of the local constants are greater than " 2361 "their corresponding global constants." << suffix);
2362 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2363 (this->indicesAreAllocated () &&
2364 (this->numAllocForAllRows_ != 0 ||
2365 this->k_numAllocPerRow_.dimension_0 () != 0),
2366 std::logic_error,
"The graph claims that its indices are allocated, but " 2367 "either numAllocForAllRows_ (= " << this->numAllocForAllRows_ <<
") is " 2368 "nonzero, or k_numAllocPerRow_ has nonzero dimension. In other words, " 2369 "the graph is supposed to release its \"allocation specifications\" " 2370 "when it allocates its indices." << suffix);
2371 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2372 (this->isStorageOptimized () && this->pftype_ !=
StaticProfile,
2374 "Storage is optimized, but graph is not StaticProfile." << suffix);
2375 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2376 (this->isGloballyIndexed () &&
2377 this->k_rowPtrs_.dimension_0 () != 0 &&
2378 (
static_cast<size_t> (this->k_rowPtrs_.dimension_0 ()) != static_cast<size_t> (lclNumRows + 1) ||
2379 this->k_rowPtrs_(lclNumRows) !=
static_cast<size_t> (this->k_gblInds1D_.dimension_0 ())),
2380 std::logic_error,
"If k_rowPtrs_ has nonzero size and " 2381 "the graph is globally indexed, then " 2382 "k_rowPtrs_ must have N+1 rows, and " 2383 "k_rowPtrs_(N) must equal k_gblInds1D_.dimension_0()." << suffix);
2384 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2385 (this->isLocallyIndexed () &&
2386 this->k_rowPtrs_.dimension_0 () != 0 &&
2387 (
static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != static_cast<size_t> (lclNumRows + 1) ||
2388 this->k_rowPtrs_(lclNumRows) !=
static_cast<size_t> (this->k_lclInds1D_.dimension_0 ())),
2389 std::logic_error,
"If k_rowPtrs_ has nonzero size and " 2390 "the graph is locally indexed, then " 2391 "k_rowPtrs_ must have N+1 rows, and " 2392 "k_rowPtrs_(N) must equal k_lclInds1D_.dimension_0()." << suffix);
2395 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2396 (this->indicesAreAllocated () &&
2397 this->getNodeNumRows () > 0 &&
2398 this->lclInds2D_.is_null () &&
2399 this->gblInds2D_.is_null (),
2400 std::logic_error,
"Graph has DynamicProfile, indices are allocated, and " 2401 "the calling process has nonzero rows, but 2-D column index storage " 2402 "(whether local or global) is not present." << suffix);
2403 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2404 (this->indicesAreAllocated () &&
2405 this->getNodeNumRows () > 0 &&
2406 this->k_numRowEntries_.dimension_0 () == 0,
2407 std::logic_error,
"Graph has DynamicProfile, indices are allocated, and " 2408 "the calling process has nonzero rows, but k_numRowEntries_ is not " 2409 "present." << suffix);
2410 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2411 (this->k_lclInds1D_.dimension_0 () != 0 ||
2412 this->k_gblInds1D_.dimension_0 () != 0,
2413 std::logic_error,
"Graph has DynamicProfile, but " 2414 "1-D allocations are present." << suffix);
2415 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2416 (this->k_rowPtrs_.dimension_0 () != 0,
2417 std::logic_error,
"Graph has DynamicProfile, but " 2418 "row offsets are present." << suffix);
2421 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2422 (this->indicesAreAllocated () &&
2423 nodeAllocSize > 0 &&
2424 this->k_lclInds1D_.dimension_0 () == 0 &&
2425 this->k_gblInds1D_.dimension_0 () == 0,
2426 std::logic_error,
"Graph has StaticProfile and is allocated " 2427 "nonnontrivally, but 1-D allocations are not present." << suffix);
2428 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2429 (this->lclInds2D_ != Teuchos::null || this->gblInds2D_ != Teuchos::null,
2430 std::logic_error,
"Graph has StaticProfile, but 2-D allocations are " 2431 "present." << suffix);
2434 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2435 (! this->indicesAreAllocated () &&
2436 ((this->k_rowPtrs_.dimension_0 () != 0 ||
2437 this->k_numRowEntries_.dimension_0 () != 0) ||
2438 this->k_lclInds1D_.dimension_0 () != 0 ||
2439 this->lclInds2D_ != Teuchos::null ||
2440 this->k_gblInds1D_.dimension_0 () != 0 ||
2441 this->gblInds2D_ != Teuchos::null),
2442 std::logic_error,
"If indices are not allocated, " 2443 "then none of the buffers should be." << suffix);
2447 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2448 ((this->indicesAreLocal_ || this->indicesAreGlobal_) &&
2449 ! this->indicesAreAllocated_,
2450 std::logic_error,
"Indices may be local or global only if they are " 2451 "allocated." << suffix);
2452 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2453 (this->indicesAreLocal_ && this->indicesAreGlobal_,
2454 std::logic_error,
"Indices may not be both local and global." << suffix);
2455 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2456 (this->indicesAreLocal_ &&
2457 (this->k_gblInds1D_.dimension_0 () != 0 || ! this->gblInds2D_.is_null ()),
2458 std::logic_error,
"Indices are local, but either " 2459 "k_gblInds1D_.dimension_0() (= " 2460 << this->k_gblInds1D_.dimension_0 () <<
") != 0, or " 2461 "gblInds2D_ is not null. In other words, if indices are local, " 2462 "then global allocations should not be present." << suffix);
2463 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2464 (this->indicesAreGlobal_ &&
2465 (this->k_lclInds1D_.dimension_0 () != 0 ||
2466 ! this->lclInds2D_.is_null ()),
2467 std::logic_error,
"Indices are global, but either " 2468 "k_lclInds1D_.dimension_0() (= " 2469 << this->k_lclInds1D_.dimension_0 () <<
") != 0, or " 2470 "lclInds2D_ is not null. In other words, if indices are global, " 2471 "then local allocations should not be present." << suffix);
2472 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2473 (this->indicesAreLocal_ &&
2474 nodeAllocSize > 0 &&
2475 this->k_lclInds1D_.dimension_0 () == 0 &&
2476 this->getNodeNumRows () > 0 &&
2477 this->lclInds2D_.is_null (),
2478 std::logic_error,
"Indices are local, getNodeAllocationSize() = " 2479 << nodeAllocSize <<
" > 0, k_lclInds1D_.dimension_0() = 0, " 2480 "getNodeNumRows() = " << this->getNodeNumRows () <<
" > 0, and " 2481 "lclInds2D_ is null." << suffix);
2482 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2483 (this->indicesAreGlobal_ &&
2484 nodeAllocSize > 0 &&
2485 this->k_gblInds1D_.dimension_0 () == 0 &&
2486 this->getNodeNumRows () > 0 &&
2487 this->gblInds2D_.is_null (),
2488 std::logic_error,
"Indices are global, getNodeAllocationSize() = " 2489 << nodeAllocSize <<
" > 0, k_gblInds1D_.dimension_0() = 0, " 2490 "getNodeNumRows() = " << this->getNodeNumRows () <<
" > 0, and " 2491 "gblInds2D_ is null." << suffix);
2493 if (this->indicesAreAllocated () &&
2495 this->k_rowPtrs_.dimension_0 () != 0) {
2496 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2497 (static_cast<size_t> (this->k_rowPtrs_.dimension_0 ()) !=
2498 this->getNodeNumRows () + 1,
2499 std::logic_error,
"Graph is StaticProfile, indices are allocated, and " 2500 "k_rowPtrs_ has nonzero length, but k_rowPtrs_.dimension_0() = " 2501 << this->k_rowPtrs_.dimension_0 () <<
" != getNodeNumRows()+1 = " 2502 << (this->getNodeNumRows () + 1) <<
"." << suffix);
2503 const size_t actualNumAllocated =
2504 Details::getEntryOnHost (this->k_rowPtrs_, this->getNodeNumRows ());
2505 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2506 (this->isLocallyIndexed () &&
2507 static_cast<size_t> (this->k_lclInds1D_.dimension_0 ()) != actualNumAllocated,
2508 std::logic_error,
"Graph is StaticProfile and locally indexed, " 2509 "indices are allocated, and k_rowPtrs_ has nonzero length, but " 2510 "k_lclInds1D_.dimension_0() = " << this->k_lclInds1D_.dimension_0 ()
2511 <<
" != actualNumAllocated = " << actualNumAllocated << suffix);
2512 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2513 (this->isGloballyIndexed () &&
2514 static_cast<size_t> (this->k_gblInds1D_.dimension_0 ()) != actualNumAllocated,
2515 std::logic_error,
"Graph is StaticProfile and globally indexed, " 2516 "indices are allocated, and k_rowPtrs_ has nonzero length, but " 2517 "k_gblInds1D_.dimension_0() = " << this->k_gblInds1D_.dimension_0 ()
2518 <<
" != actualNumAllocated = " << actualNumAllocated << suffix);
2520 #endif // HAVE_TPETRA_DEBUG 2524 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2529 using Teuchos::OrdinalTraits;
2530 const LocalOrdinal lrow = rowMap_->getLocalElement (globalRow);
2531 if (hasRowInfo () && lrow != OrdinalTraits<LocalOrdinal>::invalid ()) {
2532 const RowInfo rowinfo = this->getRowInfo (lrow);
2533 return rowinfo.numEntries;
2535 return OrdinalTraits<size_t>::invalid ();
2540 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2545 if (hasRowInfo () && rowMap_->isNodeLocalElement (localRow)) {
2546 const RowInfo rowinfo = this->getRowInfo (localRow);
2547 return rowinfo.numEntries;
2549 return Teuchos::OrdinalTraits<size_t>::invalid ();
2554 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2559 const LocalOrdinal lrow = rowMap_->getLocalElement (globalRow);
2560 if (hasRowInfo () && lrow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2561 const RowInfo rowinfo = this->getRowInfo (lrow);
2562 return rowinfo.allocSize;
2564 return Teuchos::OrdinalTraits<size_t>::invalid ();
2569 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2574 if (hasRowInfo () && rowMap_->isNodeLocalElement (localRow)) {
2575 const RowInfo rowinfo = this->getRowInfo (localRow);
2576 return rowinfo.allocSize;
2578 return Teuchos::OrdinalTraits<size_t>::invalid();
2583 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2584 Teuchos::ArrayRCP<const size_t>
2588 using Kokkos::ViewAllocateWithoutInitializing;
2589 using Kokkos::create_mirror_view;
2590 using Teuchos::ArrayRCP;
2591 typedef typename local_graph_type::row_map_type row_map_type;
2592 typedef typename row_map_type::non_const_value_type row_offset_type;
2593 #ifdef HAVE_TPETRA_DEBUG 2594 const char prefix[] =
"Tpetra::CrsGraph::getNodeRowPtrs: ";
2595 const char suffix[] =
" Please report this bug to the Tpetra developers.";
2596 #endif // HAVE_TPETRA_DEBUG 2597 const size_t size = k_rowPtrs_.dimension_0 ();
2598 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
2601 return ArrayRCP<const size_t> ();
2604 ArrayRCP<const row_offset_type> ptr_rot;
2605 ArrayRCP<const size_t> ptr_st;
2610 typename row_map_type::HostMirror ptr_h = create_mirror_view (k_rowPtrs_);
2612 #ifdef HAVE_TPETRA_DEBUG 2613 TEUCHOS_TEST_FOR_EXCEPTION(
2614 ptr_h.dimension_0 () != k_rowPtrs_.dimension_0 (), std::logic_error,
2615 prefix <<
"size_t == row_offset_type, but ptr_h.dimension_0() = " 2616 << ptr_h.dimension_0 () <<
" != k_rowPtrs_.dimension_0() = " 2617 << k_rowPtrs_.dimension_0 () <<
".");
2618 TEUCHOS_TEST_FOR_EXCEPTION(
2619 same && size != 0 && k_rowPtrs_.ptr_on_device () == NULL, std::logic_error,
2620 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2621 << size <<
" != 0, but k_rowPtrs_.ptr_on_device() == NULL." << suffix);
2622 TEUCHOS_TEST_FOR_EXCEPTION(
2623 same && size != 0 && ptr_h.ptr_on_device () == NULL, std::logic_error,
2624 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2625 << size <<
" != 0, but create_mirror_view(k_rowPtrs_).ptr_on_device() " 2626 "== NULL." << suffix);
2627 #endif // HAVE_TPETRA_DEBUG 2628 ptr_rot = Kokkos::Compat::persistingView (ptr_h);
2631 typedef Kokkos::View<size_t*, device_type> ret_view_type;
2632 ret_view_type ptr_d (ViewAllocateWithoutInitializing (
"ptr"), size);
2634 typename ret_view_type::HostMirror ptr_h = create_mirror_view (ptr_d);
2636 ptr_st = Kokkos::Compat::persistingView (ptr_h);
2638 #ifdef HAVE_TPETRA_DEBUG 2639 TEUCHOS_TEST_FOR_EXCEPTION(
2640 same && size != 0 && ptr_rot.is_null (), std::logic_error,
2641 prefix <<
"size_t == row_offset_type and size = " << size
2642 <<
" != 0, but ptr_rot is null." << suffix);
2643 TEUCHOS_TEST_FOR_EXCEPTION(
2644 ! same && size != 0 && ptr_st.is_null (), std::logic_error,
2645 prefix <<
"size_t != row_offset_type and size = " << size
2646 <<
" != 0, but ptr_st is null." << suffix);
2647 #endif // HAVE_TPETRA_DEBUG 2651 #ifdef HAVE_TPETRA_DEBUG 2652 ArrayRCP<const size_t> retval =
2653 Kokkos::Impl::if_c<same,
2654 ArrayRCP<const row_offset_type>,
2655 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2656 TEUCHOS_TEST_FOR_EXCEPTION(
2657 size != 0 && retval.is_null (), std::logic_error,
2658 prefix <<
"size = " << size <<
" != 0, but retval is null." << suffix);
2661 return Kokkos::Impl::if_c<same,
2662 ArrayRCP<const row_offset_type>,
2663 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2664 #endif // HAVE_TPETRA_DEBUG 2668 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2669 Teuchos::ArrayRCP<const LocalOrdinal>
2673 return Kokkos::Compat::persistingView (k_lclInds1D_);
2677 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2681 const Teuchos::ArrayView<LocalOrdinal>&indices,
2682 size_t& numEntries)
const 2684 using Teuchos::ArrayView;
2685 typedef LocalOrdinal LO;
2686 typedef GlobalOrdinal GO;
2687 const char tfecfFuncName[] =
"getLocalRowCopy: ";
2689 TEUCHOS_TEST_FOR_EXCEPTION(
2690 isGloballyIndexed () && ! hasColMap (), std::runtime_error,
2691 "Tpetra::CrsGraph::getLocalRowCopy: The graph is globally indexed and " 2692 "does not have a column Map yet. That means we don't have local indices " 2693 "for columns yet, so it doesn't make sense to call this method. If the " 2694 "graph doesn't have a column Map yet, you should call fillComplete on " 2696 #ifdef HAVE_TPETRA_DEBUG 2697 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2698 ! hasRowInfo(), std::runtime_error,
2699 "Graph row information was deleted at fillComplete.");
2700 #endif // HAVE_TPETRA_DEBUG 2704 const RowInfo rowinfo = getRowInfo (localRow);
2706 const size_t theNumEntries = rowinfo.numEntries;
2707 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2708 static_cast<size_t> (indices.size ()) < theNumEntries, std::runtime_error,
2709 "Specified storage (size==" << indices.size () <<
") does not suffice " 2710 "to hold all " << theNumEntries <<
" entry/ies for this row.");
2711 numEntries = theNumEntries;
2713 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2714 if (isLocallyIndexed ()) {
2715 ArrayView<const LO> lview = getLocalView (rowinfo);
2716 for (
size_t j = 0; j < theNumEntries; ++j) {
2717 indices[j] = lview[j];
2720 else if (isGloballyIndexed ()) {
2721 ArrayView<const GO> gview = getGlobalView (rowinfo);
2722 for (
size_t j = 0; j < theNumEntries; ++j) {
2723 indices[j] = colMap_->getLocalElement (gview[j]);
2730 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2734 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2735 size_t& numEntries)
const 2737 using Teuchos::ArrayView;
2738 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2739 #ifdef HAVE_TPETRA_DEBUG 2740 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2741 ! hasRowInfo (), std::runtime_error,
2742 "Graph row information was deleted at fillComplete.");
2743 #endif // HAVE_TPETRA_DEBUG 2747 const RowInfo rowinfo = getRowInfoFromGlobalRowIndex (globalRow);
2748 const size_t theNumEntries = rowinfo.numEntries;
2749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2750 static_cast<size_t> (indices.size ()) < theNumEntries, std::runtime_error,
2751 "Specified storage (size==" << indices.size () <<
") does not suffice " 2752 "to hold all " << theNumEntries <<
" entry/ies for this row.");
2753 numEntries = theNumEntries;
2755 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2756 if (isLocallyIndexed ()) {
2757 ArrayView<const LocalOrdinal> lview = getLocalView (rowinfo);
2758 for (
size_t j = 0; j < theNumEntries; ++j) {
2759 indices[j] = colMap_->getGlobalElement (lview[j]);
2762 else if (isGloballyIndexed ()) {
2763 ArrayView<const GlobalOrdinal> gview = getGlobalView (rowinfo);
2764 for (
size_t j = 0; j < theNumEntries; ++j) {
2765 indices[j] = gview[j];
2772 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2776 Teuchos::ArrayView<const LocalOrdinal>& indices)
const 2778 const char tfecfFuncName[] =
"getLocalRowView: ";
2779 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2780 isGloballyIndexed (), std::runtime_error,
"The graph's indices are " 2781 "currently stored as global indices, so we cannot return a view with " 2782 "local column indices, whether or not the graph has a column Map. If " 2783 "the graph _does_ have a column Map, use getLocalRowCopy() instead.");
2784 #ifdef HAVE_TPETRA_DEBUG 2785 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2786 ! hasRowInfo (), std::runtime_error,
"Graph row information was " 2787 "deleted at fillComplete().");
2788 #endif // HAVE_TPETRA_DEBUG 2792 const RowInfo rowInfo = getRowInfo (localRow);
2793 indices = Teuchos::null;
2794 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
2795 rowInfo.numEntries > 0) {
2796 indices = this->getLocalView (rowInfo);
2801 indices = indices (0, rowInfo.numEntries);
2804 #ifdef HAVE_TPETRA_DEBUG 2805 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2806 (static_cast<size_t> (indices.size ()) !=
2807 getNumEntriesInLocalRow (localRow), std::logic_error,
"indices.size() " 2808 "= " << indices.size () <<
" != getNumEntriesInLocalRow(localRow=" <<
2809 localRow <<
") = " << getNumEntriesInLocalRow (localRow) <<
2810 ". Please report this bug to the Tpetra developers.");
2811 #endif // HAVE_TPETRA_DEBUG 2815 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2819 Teuchos::ArrayView<const GlobalOrdinal>& indices)
const 2821 const char tfecfFuncName[] =
"getGlobalRowView: ";
2822 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2823 isLocallyIndexed (), std::runtime_error,
"The graph's indices are " 2824 "currently stored as local indices, so we cannot return a view with " 2825 "global column indices. Use getGlobalRowCopy() instead.");
2826 #ifdef HAVE_TPETRA_DEBUG 2827 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2828 ! hasRowInfo (), std::runtime_error,
2829 "Graph row information was deleted at fillComplete().");
2830 #endif // HAVE_TPETRA_DEBUG 2834 const RowInfo rowInfo = getRowInfoFromGlobalRowIndex (globalRow);
2835 indices = Teuchos::null;
2836 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
2837 rowInfo.numEntries > 0) {
2838 indices = (this->getGlobalView (rowInfo)) (0, rowInfo.numEntries);
2841 #ifdef HAVE_TPETRA_DEBUG 2842 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2843 (static_cast<size_t> (indices.size ()) != getNumEntriesInGlobalRow (globalRow),
2844 std::logic_error,
"indices.size() = " << indices.size ()
2845 <<
" != getNumEntriesInGlobalRow(globalRow=" << globalRow <<
") = " 2846 << getNumEntriesInGlobalRow (globalRow)
2847 <<
". Please report this bug to the Tpetra developers.");
2848 #endif // HAVE_TPETRA_DEBUG 2852 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2856 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2858 const char tfecfFuncName[] =
"insertLocalIndices";
2860 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2861 ! isFillActive (), std::runtime_error,
2862 ": requires that fill is active.");
2863 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2864 isGloballyIndexed (), std::runtime_error,
2865 ": graph indices are global; use insertGlobalIndices().");
2866 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2867 ! hasColMap (), std::runtime_error,
2868 ": cannot insert local indices without a column map.");
2869 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2870 ! rowMap_->isNodeLocalElement (localRow), std::runtime_error,
2871 ": row does not belong to this node.");
2872 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2873 ! hasRowInfo (), std::runtime_error,
2874 ": graph row information was deleted at fillComplete().");
2875 if (! indicesAreAllocated ()) {
2876 allocateIndices (LocalIndices);
2879 #ifdef HAVE_TPETRA_DEBUG 2885 using Teuchos::Array;
2886 using Teuchos::toString;
2888 typedef typename Teuchos::ArrayView<const LocalOrdinal>::size_type size_type;
2890 const map_type& colMap = * (getColMap ());
2891 Array<LocalOrdinal> badColInds;
2892 bool allInColMap =
true;
2893 for (size_type k = 0; k < indices.size (); ++k) {
2895 allInColMap =
false;
2896 badColInds.push_back (indices[k]);
2899 if (! allInColMap) {
2900 std::ostringstream os;
2901 os <<
"Tpetra::CrsMatrix::insertLocalIndices: You attempted to insert " 2902 "entries in owned row " << localRow <<
", at the following column " 2903 "indices: " << toString (indices) <<
"." << endl;
2904 os <<
"Of those, the following indices are not in the column Map on " 2905 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2906 "the graph has a column Map already, it is invalid to insert entries " 2907 "at those locations.";
2908 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2911 #endif // HAVE_TPETRA_DEBUG 2913 insertLocalIndicesImpl (localRow, indices);
2915 #ifdef HAVE_TPETRA_DEBUG 2916 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2917 indicesAreAllocated() ==
false || isLocallyIndexed() ==
false,
2919 ": Violated stated post-conditions. Please contact Tpetra team.");
2923 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2927 const LocalOrdinal numEnt,
2928 const LocalOrdinal inds[])
2930 Teuchos::ArrayView<const LocalOrdinal> indsT (inds, numEnt);
2931 this->insertLocalIndices (localRow, indsT);
2934 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2938 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2940 typedef LocalOrdinal LO;
2941 const char tfecfFuncName[] =
"insertLocalIndicesFiltered";
2943 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2944 isFillActive() ==
false, std::runtime_error,
2945 ": requires that fill is active.");
2946 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2947 isGloballyIndexed() ==
true, std::runtime_error,
2948 ": graph indices are global; use insertGlobalIndices().");
2949 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2950 hasColMap() ==
false, std::runtime_error,
2951 ": cannot insert local indices without a column map.");
2952 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2953 rowMap_->isNodeLocalElement(localRow) ==
false, std::runtime_error,
2954 ": row does not belong to this node.");
2955 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2956 ! hasRowInfo (), std::runtime_error,
2957 ": graph row information was deleted at fillComplete().");
2958 if (! indicesAreAllocated ()) {
2959 allocateIndices (LocalIndices);
2964 Teuchos::Array<LO> filtered_indices (indices);
2965 SLocalGlobalViews inds_view;
2966 SLocalGlobalNCViews inds_ncview;
2967 inds_ncview.linds = filtered_indices();
2968 const size_t numFilteredEntries =
2969 filterIndices<LocalIndices>(inds_ncview);
2970 inds_view.linds = filtered_indices (0, numFilteredEntries);
2971 insertLocalIndicesImpl(localRow, inds_view.linds);
2974 insertLocalIndicesImpl(localRow, indices);
2976 #ifdef HAVE_TPETRA_DEBUG 2977 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2978 indicesAreAllocated() ==
false || isLocallyIndexed() ==
false,
2980 ": Violated stated post-conditions. Please contact Tpetra team.");
2985 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2989 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2991 using Teuchos::Array;
2992 using Teuchos::ArrayView;
2993 typedef LocalOrdinal LO;
2994 typedef GlobalOrdinal GO;
2995 typedef typename ArrayView<const GO>::size_type size_type;
2996 const char tfecfFuncName[] =
"insertGlobalIndices";
2998 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2999 isLocallyIndexed() ==
true, std::runtime_error,
3000 ": graph indices are local; use insertLocalIndices().");
3001 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3002 ! hasRowInfo (), std::runtime_error,
3003 ": graph row information was deleted at fillComplete().");
3008 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3009 isFillActive() ==
false, std::runtime_error,
3010 ": You are not allowed to call this method if fill is not active. " 3011 "If fillComplete has been called, you must first call resumeFill " 3012 "before you may insert indices.");
3013 if (! indicesAreAllocated ()) {
3014 allocateIndices (GlobalIndices);
3016 const LO myRow = rowMap_->getLocalElement (grow);
3017 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
3018 #ifdef HAVE_TPETRA_DEBUG 3021 const map_type& colMap = * (getColMap ());
3026 Array<GO> badColInds;
3027 bool allInColMap =
true;
3028 for (size_type k = 0; k < indices.size (); ++k) {
3030 allInColMap =
false;
3031 badColInds.push_back (indices[k]);
3034 if (! allInColMap) {
3035 std::ostringstream os;
3036 os <<
"Tpetra::CrsGraph::insertGlobalIndices: You attempted to insert " 3037 "entries in owned row " << grow <<
", at the following column " 3038 "indices: " << toString (indices) <<
"." << endl;
3039 os <<
"Of those, the following indices are not in the column Map on " 3040 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 3041 "the matrix has a column Map already, it is invalid to insert " 3042 "entries at those locations.";
3043 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
3046 #endif // HAVE_TPETRA_DEBUG 3047 insertGlobalIndicesImpl (myRow, indices);
3050 const size_type numIndices = indices.size ();
3054 std::vector<GO>& nonlocalRow = nonlocals_[grow];
3055 for (size_type k = 0; k < numIndices; ++k) {
3056 nonlocalRow.push_back (indices[k]);
3059 #ifdef HAVE_TPETRA_DEBUG 3060 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3061 indicesAreAllocated() ==
false || isGloballyIndexed() ==
false,
3063 ": Violated stated post-conditions. Please contact Tpetra team.");
3068 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3072 const LocalOrdinal numEnt,
3073 const GlobalOrdinal inds[])
3075 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
3076 this->insertGlobalIndices (globalRow, indsT);
3080 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3084 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
3086 using Teuchos::Array;
3087 using Teuchos::ArrayView;
3088 typedef LocalOrdinal LO;
3089 typedef GlobalOrdinal GO;
3090 const char tfecfFuncName[] =
"insertGlobalIndicesFiltered";
3092 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3093 isLocallyIndexed() ==
true, std::runtime_error,
3094 ": graph indices are local; use insertLocalIndices().");
3095 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3096 ! hasRowInfo (), std::runtime_error,
3097 ": graph row information was deleted at fillComplete().");
3102 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3103 isFillActive() ==
false, std::runtime_error,
3104 ": You are not allowed to call this method if fill is not active. " 3105 "If fillComplete has been called, you must first call resumeFill " 3106 "before you may insert indices.");
3107 if (! indicesAreAllocated ()) {
3108 allocateIndices (GlobalIndices);
3110 const LO myRow = rowMap_->getLocalElement (grow);
3111 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
3114 Array<GO> filtered_indices(indices);
3115 SLocalGlobalViews inds_view;
3116 SLocalGlobalNCViews inds_ncview;
3117 inds_ncview.ginds = filtered_indices();
3118 const size_t numFilteredEntries =
3119 filterIndices<GlobalIndices> (inds_ncview);
3120 inds_view.ginds = filtered_indices (0, numFilteredEntries);
3121 insertGlobalIndicesImpl(myRow, inds_view.ginds);
3124 insertGlobalIndicesImpl(myRow, indices);
3128 typedef typename ArrayView<const GO>::size_type size_type;
3129 const size_type numIndices = indices.size ();
3130 for (size_type k = 0; k < numIndices; ++k) {
3131 nonlocals_[grow].push_back (indices[k]);
3134 #ifdef HAVE_TPETRA_DEBUG 3135 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3136 indicesAreAllocated() ==
false || isGloballyIndexed() ==
false,
3138 ": Violated stated post-conditions. Please contact Tpetra team.");
3143 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3148 const char tfecfFuncName[] =
"removeLocalIndices: ";
3149 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3150 ! isFillActive (), std::runtime_error,
"requires that fill is active.");
3151 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3152 isStorageOptimized (), std::runtime_error,
3153 "cannot remove indices after optimizeStorage() has been called.");
3154 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3155 isGloballyIndexed (), std::runtime_error,
"graph indices are global.");
3156 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3157 ! rowMap_->isNodeLocalElement (lrow), std::runtime_error,
3158 "Local row " << lrow <<
" is not in the row Map on the calling process.");
3159 if (! indicesAreAllocated ()) {
3160 allocateIndices (LocalIndices);
3165 clearGlobalConstants ();
3167 if (k_numRowEntries_.dimension_0 () != 0) {
3168 const size_t oldNumEntries = k_numRowEntries_(lrow);
3169 nodeNumEntries_ -= oldNumEntries;
3170 k_numRowEntries_(lrow) = 0;
3172 #ifdef HAVE_TPETRA_DEBUG 3173 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3174 getNumEntriesInLocalRow (lrow) != 0 ||
3175 ! indicesAreAllocated () ||
3176 ! isLocallyIndexed (), std::logic_error,
3177 ": Violated stated post-conditions. Please contact Tpetra team.");
3178 #endif // HAVE_TPETRA_DEBUG 3182 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3186 const typename local_graph_type::entries_type::non_const_type& columnIndices)
3188 const char tfecfFuncName[] =
"setAllIndices: ";
3189 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3190 ! hasColMap () || getColMap ().is_null (), std::runtime_error,
3191 "The graph must have a column Map before you may call this method.");
3192 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3193 static_cast<size_t> (rowPointers.size ()) != this->getNodeNumRows () + 1,
3194 std::runtime_error,
"rowPointers.size() = " << rowPointers.size () <<
3195 " != this->getNodeNumRows()+1 = " << (this->getNodeNumRows () + 1) <<
3201 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3202 (this->k_lclInds1D_.dimension_0 () != 0 ||
3203 this->k_gblInds1D_.dimension_0 () != 0,
3204 std::runtime_error,
"You may not call this method if 1-D data " 3205 "structures are already allocated.");
3207 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3208 (this->lclInds2D_ != Teuchos::null ||
3209 this->gblInds2D_ != Teuchos::null,
3210 std::runtime_error,
"You may not call this method if 2-D data " 3211 "structures are already allocated.");
3212 const size_t localNumEntries =
3213 Details::getEntryOnHost (rowPointers, this->getNodeNumRows ());
3215 indicesAreAllocated_ =
true;
3216 indicesAreLocal_ =
true;
3218 k_lclInds1D_ = columnIndices;
3219 k_rowPtrs_ = rowPointers;
3220 nodeNumEntries_ = localNumEntries;
3223 storageStatus_ = Details::STORAGE_1D_UNPACKED;
3232 numAllocForAllRows_ = 0;
3233 k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
3235 checkInternalState ();
3239 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3243 const Teuchos::ArrayRCP<LocalOrdinal>& columnIndices)
3246 typedef typename local_graph_type::row_map_type row_map_type;
3247 typedef typename row_map_type::array_layout layout_type;
3248 typedef typename row_map_type::non_const_value_type row_offset_type;
3249 typedef View<
size_t*, layout_type , Kokkos::HostSpace,
3250 Kokkos::MemoryUnmanaged> input_view_type;
3251 typedef typename row_map_type::non_const_type nc_row_map_type;
3253 const size_t size =
static_cast<size_t> (rowPointers.size ());
3254 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
3255 input_view_type ptr_in (rowPointers.getRawPtr (), size);
3257 nc_row_map_type ptr_rot (
"Tpetra::CrsGraph::ptr", size);
3263 input_view_type ptr_decoy (rowPointers.getRawPtr (), size);
3266 input_view_type>::select (ptr_rot, ptr_decoy),
3271 const bool inHostMemory =
3272 Kokkos::Impl::is_same<
typename row_map_type::memory_space,
3273 Kokkos::HostSpace>::value;
3284 View<size_t*, layout_type ,execution_space > ptr_st (
"Tpetra::CrsGraph::ptr", size);
3294 Kokkos::View<LocalOrdinal*, layout_type , execution_space > k_ind =
3295 Kokkos::Compat::getKokkosViewDeepCopy<device_type> (columnIndices ());
3296 setAllIndices (ptr_rot, k_ind);
3300 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3304 size_t& boundForAllLocalRows,
3305 bool& boundSameForAllLocalRows)
const 3307 const char tfecfFuncName[] =
"getNumEntriesPerLocalRowUpperBound: ";
3308 const char suffix[] =
" Please report this bug to the Tpetra developers.";
3313 Teuchos::ArrayRCP<const size_t> numEntriesPerRow;
3314 size_t numEntriesForAll = 0;
3315 bool allRowsSame =
true;
3317 const ptrdiff_t numRows =
static_cast<ptrdiff_t
> (this->getNodeNumRows ());
3319 if (this->indicesAreAllocated ()) {
3320 if (this->isStorageOptimized ()) {
3323 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3324 (this->getProfileType () !=
StaticProfile, std::logic_error,
3325 "The graph is not StaticProfile, but storage appears to be optimized." 3327 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3328 (numRows != 0 && k_rowPtrs_.dimension_0 () == 0, std::logic_error,
3329 "The graph has " << numRows <<
" (> 0) row" << (numRows != 1 ?
"s" :
"")
3330 <<
" on the calling process, but the k_rowPtrs_ array has zero entries." 3332 Teuchos::ArrayRCP<size_t> numEnt;
3334 numEnt = Teuchos::arcp<size_t> (numRows);
3339 bool allRowsReallySame =
false;
3340 for (ptrdiff_t i = 0; i < numRows; ++i) {
3341 numEnt[i] = this->k_rowPtrs_(i+1) - this->k_rowPtrs_(i);
3342 if (i != 0 && numEnt[i] != numEnt[i-1]) {
3343 allRowsReallySame =
false;
3346 if (allRowsReallySame) {
3348 numEntriesForAll = 0;
3350 numEntriesForAll = numEnt[1] - numEnt[0];
3355 numEntriesPerRow = numEnt;
3356 allRowsSame =
false;
3359 else if (k_numRowEntries_.dimension_0 () != 0) {
3364 numEntriesPerRow = Kokkos::Compat::persistingView (k_numRowEntries_);
3365 allRowsSame =
false;
3368 numEntriesForAll = 0;
3373 if (k_numAllocPerRow_.dimension_0 () != 0) {
3378 numEntriesPerRow = Kokkos::Compat::persistingView (k_numAllocPerRow_);
3379 allRowsSame =
false;
3382 numEntriesForAll = numAllocForAllRows_;
3387 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3388 (numEntriesForAll != 0 && numEntriesPerRow.size () != 0, std::logic_error,
3389 "numEntriesForAll and numEntriesPerRow are not consistent. The former " 3390 "is nonzero (" << numEntriesForAll <<
"), but the latter has nonzero " 3391 "size " << numEntriesPerRow.size () <<
"." << suffix);
3392 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3393 (numEntriesForAll != 0 && ! allRowsSame, std::logic_error,
3394 "numEntriesForAll and allRowsSame are not consistent. The former " 3395 "is nonzero (" << numEntriesForAll <<
"), but the latter is false." 3397 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3398 (numEntriesPerRow.size () != 0 && allRowsSame, std::logic_error,
3399 "numEntriesPerRow and allRowsSame are not consistent. The former has " 3400 "nonzero length " << numEntriesForAll <<
", but the latter is true." 3403 boundPerLocalRow = numEntriesPerRow;
3404 boundForAllLocalRows = numEntriesForAll;
3405 boundSameForAllLocalRows = allRowsSame;
3409 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3414 using Teuchos::Comm;
3415 using Teuchos::outArg;
3418 using Teuchos::REDUCE_MAX;
3419 using Teuchos::REDUCE_MIN;
3420 using Teuchos::reduceAll;
3422 typedef LocalOrdinal LO;
3423 typedef GlobalOrdinal GO;
3424 typedef typename Teuchos::Array<GO>::size_type size_type;
3425 const char tfecfFuncName[] =
"globalAssemble: ";
3427 RCP<const Comm<int> > comm = getComm ();
3429 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3430 (! isFillActive (), std::runtime_error,
"Fill must be active before " 3431 "you may call this method.");
3433 const size_t myNumNonlocalRows = nonlocals_.size ();
3440 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
3441 int someoneHasNonlocalRows = 0;
3442 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
3443 outArg (someoneHasNonlocalRows));
3444 if (someoneHasNonlocalRows == 0) {
3458 RCP<const map_type> nonlocalRowMap;
3460 Teuchos::ArrayRCP<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
3462 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
3463 size_type curPos = 0;
3464 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
3465 ++mapIter, ++curPos) {
3466 myNonlocalGblRows[curPos] = mapIter->first;
3467 std::vector<GO>& gblCols = mapIter->second;
3468 std::sort (gblCols.begin (), gblCols.end ());
3469 auto vecLast = std::unique (gblCols.begin (), gblCols.end ());
3470 gblCols.erase (vecLast, gblCols.end ());
3471 numEntPerNonlocalRow[curPos] = gblCols.size ();
3482 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
3484 auto iter = std::min_element (myNonlocalGblRows.begin (),
3485 myNonlocalGblRows.end ());
3486 if (iter != myNonlocalGblRows.end ()) {
3487 myMinNonlocalGblRow = *iter;
3490 GO gblMinNonlocalGblRow = 0;
3491 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
3492 outArg (gblMinNonlocalGblRow));
3493 const GO indexBase = gblMinNonlocalGblRow;
3494 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
3495 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
3503 RCP<crs_graph_type> nonlocalGraph =
3504 rcp (
new crs_graph_type (nonlocalRowMap, numEntPerNonlocalRow,
3507 size_type curPos = 0;
3508 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
3509 ++mapIter, ++curPos) {
3510 const GO gblRow = mapIter->first;
3511 std::vector<GO>& gblCols = mapIter->second;
3512 const LO numEnt =
static_cast<LO
> (numEntPerNonlocalRow[curPos]);
3513 nonlocalGraph->insertGlobalIndices (gblRow, numEnt, gblCols.data ());
3525 auto origRowMap = this->getRowMap ();
3526 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
3528 if (origRowMapIsOneToOne) {
3529 export_type exportToOrig (nonlocalRowMap, origRowMap);
3539 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
3545 crs_graph_type oneToOneGraph (oneToOneRowMap, 0);
3547 oneToOneGraph.doExport (*nonlocalGraph, exportToOneToOne,
Tpetra::INSERT);
3551 nonlocalGraph = Teuchos::null;
3554 import_type importToOrig (oneToOneRowMap, origRowMap);
3562 decltype (nonlocals_) newNonlocals;
3563 std::swap (nonlocals_, newNonlocals);
3565 checkInternalState ();
3569 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3574 const char tfecfFuncName[] =
"resumeFill";
3575 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(! hasRowInfo(), std::runtime_error,
3576 ": Sorry, you cannot resume fill of the CrsGraph, since the graph's row " 3577 "information was deleted in fillComplete().");
3579 #ifdef HAVE_TPETRA_DEBUG 3580 Teuchos::barrier( *rowMap_->getComm() );
3581 #endif // HAVE_TPETRA_DEBUG 3582 clearGlobalConstants();
3583 if (params != Teuchos::null) this->setParameterList (params);
3584 lowerTriangular_ =
false;
3585 upperTriangular_ =
false;
3587 indicesAreSorted_ =
true;
3588 noRedundancies_ =
true;
3589 fillComplete_ =
false;
3590 #ifdef HAVE_TPETRA_DEBUG 3591 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3592 ! isFillActive() || isFillComplete(), std::logic_error,
3593 "::resumeFill(): At end of method, either fill is not active or fill is " 3594 "complete. This violates stated post-conditions. Please report this bug " 3595 "to the Tpetra developers.");
3596 #endif // HAVE_TPETRA_DEBUG 3600 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3615 Teuchos::RCP<const map_type> domMap = this->getDomainMap ();
3616 if (domMap.is_null ()) {
3617 domMap = this->getRowMap ();
3619 Teuchos::RCP<const map_type> ranMap = this->getRangeMap ();
3620 if (ranMap.is_null ()) {
3621 ranMap = this->getRowMap ();
3623 this->fillComplete (domMap, ranMap, params);
3627 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3631 const Teuchos::RCP<const map_type>& rangeMap,
3632 const Teuchos::RCP<Teuchos::ParameterList>& params)
3634 const char tfecfFuncName[] =
"fillComplete: ";
3636 #ifdef HAVE_TPETRA_DEBUG 3637 rowMap_->
getComm ()->barrier ();
3638 #endif // HAVE_TPETRA_DEBUG 3640 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! isFillActive() || isFillComplete(),
3641 std::runtime_error,
"Graph fill state must be active (isFillActive() " 3642 "must be true) before calling fillComplete().");
3644 const int numProcs = getComm ()->getSize ();
3652 if (! params.is_null ()) {
3653 if (params->isParameter (
"sort column map ghost gids")) {
3654 sortGhostsAssociatedWithEachProcessor_ =
3655 params->get<
bool> (
"sort column map ghost gids",
3656 sortGhostsAssociatedWithEachProcessor_);
3658 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3659 sortGhostsAssociatedWithEachProcessor_ =
3660 params->get<
bool> (
"Sort column Map ghost GIDs",
3661 sortGhostsAssociatedWithEachProcessor_);
3667 bool assertNoNonlocalInserts =
false;
3668 if (! params.is_null ()) {
3669 assertNoNonlocalInserts =
3670 params->get<
bool> (
"No Nonlocal Changes", assertNoNonlocalInserts);
3676 if (! indicesAreAllocated ()) {
3679 allocateIndices (LocalIndices);
3682 allocateIndices (GlobalIndices);
3690 const bool mayNeedGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3691 if (mayNeedGlobalAssemble) {
3697 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3698 (numProcs > 1 && nonlocals_.size() > 0, std::runtime_error,
3699 "The graph's communicator contains only one process, " 3700 "but there are nonlocal entries. " 3701 "This probably means that invalid entries were added to the graph.");
3706 setDomainRangeMaps (domainMap, rangeMap);
3712 if (! hasColMap ()) {
3718 makeIndicesLocal ();
3723 this->sortAndMergeAllIndices (this->isSorted (), this->isMerged ());
3725 makeImportExport ();
3726 computeGlobalConstants ();
3727 fillLocalGraph (params);
3728 fillComplete_ =
true;
3730 #ifdef HAVE_TPETRA_DEBUG 3731 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3732 isFillActive() ==
true || isFillComplete() ==
false, std::logic_error,
3733 ": Violated stated post-conditions. Please contact Tpetra team.");
3736 checkInternalState ();
3740 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3744 const Teuchos::RCP<const map_type>& rangeMap,
3745 const Teuchos::RCP<const import_type>& importer,
3746 const Teuchos::RCP<const export_type>& exporter,
3747 const Teuchos::RCP<Teuchos::ParameterList>& params)
3749 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
3750 #ifdef HAVE_TPETRA_MMM_TIMINGS 3752 if(!params.is_null())
3753 label = params->get(
"Timer Label",label);
3754 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
3755 using Teuchos::TimeMonitor;
3756 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Setup"))));
3760 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3761 domainMap.is_null () || rangeMap.is_null (),
3762 std::runtime_error,
"The input domain Map and range Map must be nonnull.");
3763 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3764 pftype_ !=
StaticProfile, std::runtime_error,
"You may not call this " 3765 "method unless the graph is StaticProfile.");
3766 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3767 isFillComplete () || ! hasColMap (), std::runtime_error,
"You may not " 3768 "call this method unless the graph has a column Map.");
3769 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3770 getNodeNumRows () > 0 && k_rowPtrs_.dimension_0 () == 0,
3771 std::runtime_error,
"The calling process has getNodeNumRows() = " 3772 << getNodeNumRows () <<
" > 0 rows, but the row offsets array has not " 3774 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3775 static_cast<size_t> (k_rowPtrs_.dimension_0 ()) != getNodeNumRows () + 1,
3776 std::runtime_error,
"The row offsets array has length " <<
3777 k_rowPtrs_.dimension_0 () <<
" != getNodeNumRows()+1 = " <<
3778 (getNodeNumRows () + 1) <<
".");
3789 Details::getEntryOnHost (this->k_rowPtrs_, this->getNodeNumRows ());
3801 numAllocForAllRows_ = 0;
3802 k_numAllocPerRow_ = decltype (k_numAllocPerRow_) ();
3803 indicesAreAllocated_ =
true;
3808 indicesAreLocal_ =
true;
3809 indicesAreGlobal_ =
false;
3812 #ifdef HAVE_TPETRA_MMM_TIMINGS 3813 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Maps"))));
3815 setDomainRangeMaps (domainMap, rangeMap);
3818 indicesAreSorted_ =
true;
3819 noRedundancies_ =
true;
3822 #ifdef HAVE_TPETRA_MMM_TIMINGS 3823 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckI"))));
3826 importer_ = Teuchos::null;
3827 exporter_ = Teuchos::null;
3828 if (importer != Teuchos::null) {
3829 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3830 ! importer->getSourceMap ()->isSameAs (*getDomainMap ()) ||
3831 ! importer->getTargetMap ()->isSameAs (*getColMap ()),
3832 std::invalid_argument,
": importer does not match matrix maps.");
3833 importer_ = importer;
3837 #ifdef HAVE_TPETRA_MMM_TIMINGS 3838 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckE"))));
3841 if (exporter != Teuchos::null) {
3842 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3843 ! exporter->getSourceMap ()->isSameAs (*getRowMap ()) ||
3844 ! exporter->getTargetMap ()->isSameAs (*getRangeMap ()),
3845 std::invalid_argument,
": exporter does not match matrix maps.");
3846 exporter_ = exporter;
3849 #ifdef HAVE_TPETRA_MMM_TIMINGS 3850 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXmake"))));
3853 makeImportExport ();
3856 #ifdef HAVE_TPETRA_MMM_TIMINGS 3857 if(params.is_null() || params->get(
"compute global constants",
true))
3858 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cGC (const)"))));
3860 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cGC (noconst)"))));
3862 if(params.is_null() || params->get(
"compute global constants",
true))
3863 computeGlobalConstants ();
3865 computeLocalConstants ();
3868 #ifdef HAVE_TPETRA_MMM_TIMINGS 3869 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-fLG"))));
3871 fillLocalGraph (params);
3872 fillComplete_ =
true;
3874 #ifdef HAVE_TPETRA_MMM_TIMINGS 3875 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cIS"))));
3877 checkInternalState ();
3881 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3884 fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params)
3887 typedef decltype (k_numRowEntries_) row_entries_type;
3888 typedef typename local_graph_type::row_map_type row_map_type;
3889 typedef typename row_map_type::non_const_type non_const_row_map_type;
3890 typedef typename local_graph_type::entries_type::non_const_type lclinds_1d_type;
3891 const char tfecfFuncName[] =
"fillLocalGraph (called from fillComplete or " 3892 "expertStaticFillComplete): ";
3893 const size_t lclNumRows = this->getNodeNumRows ();
3900 non_const_row_map_type ptr_d;
3901 row_map_type ptr_d_const;
3902 lclinds_1d_type ind_d;
3904 bool requestOptimizedStorage =
true;
3905 if (! params.is_null () && ! params->get (
"Optimize Storage",
true)) {
3906 requestOptimizedStorage =
false;
3916 #ifdef HAVE_TPETRA_DEBUG 3917 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3918 (static_cast<size_t> (this->k_numRowEntries_.dimension_0 ()) !=
3919 lclNumRows, std::logic_error,
"(DynamicProfile branch) " 3920 "k_numRowEntries_.dimension_0() = " << k_numRowEntries_.dimension_0 ()
3921 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3922 #endif // HAVE_TPETRA_DEBUG 3931 size_t lclTotalNumEntries = 0;
3934 ptr_d = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows+1);
3935 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
3938 ptr_d_const = ptr_d;
3941 #ifdef HAVE_TPETRA_DEBUG 3942 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3943 (static_cast<size_t> (ptr_d.dimension_0 ()) != lclNumRows + 1,
3944 std::logic_error,
"(DynamicProfile branch) After packing ptr_d, " 3945 "ptr_d.dimension_0() = " << ptr_d.dimension_0 () <<
" != " 3946 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
3948 const auto valToCheck = Details::getEntryOnHost (ptr_d, lclNumRows);
3949 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3950 (valToCheck != lclTotalNumEntries, std::logic_error,
3951 "(DynamicProfile branch) After packing ptr_d, ptr_d(lclNumRows = " 3952 << lclNumRows <<
") = " << valToCheck <<
" != total number of " 3953 "entries on the calling process = " << lclTotalNumEntries <<
".");
3955 #endif // HAVE_TPETRA_DEBUG 3958 ind_d = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3964 auto ptr_h = Kokkos::create_mirror_view (ptr_d);
3966 auto ind_h = Kokkos::create_mirror_view (ind_d);
3969 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
3970 for (
size_t row = 0; row < lclNumRows; ++row) {
3971 const size_t numEnt = numRowEnt_h(row);
3972 std::copy (lclInds2D_[row].begin (),
3973 lclInds2D_[row].begin () + numEnt,
3974 ind_h.ptr_on_device () + ptr_h(row));
3979 #ifdef HAVE_TPETRA_DEBUG 3981 if (ptr_d.dimension_0 () != 0) {
3982 const size_t numOffsets =
static_cast<size_t> (ptr_d.dimension_0 ());
3983 const size_t valToCheck = Details::getEntryOnHost (ptr_d, numOffsets - 1);
3984 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3985 (valToCheck != static_cast<size_t> (ind_d.dimension_0 ()),
3986 std::logic_error,
"(DynamicProfile branch) After packing column " 3987 "indices, ptr_d(" << (numOffsets-1) <<
") = " << valToCheck
3988 <<
" != ind_d.dimension_0() = " << ind_d.dimension_0 () <<
".");
3990 #endif // HAVE_TPETRA_DEBUG 3997 #ifdef HAVE_TPETRA_DEBUG 4000 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4001 (k_rowPtrs_.dimension_0 () == 0, std::logic_error,
4002 "(StaticProfile branch) k_rowPtrs_ has size zero, but shouldn't");
4003 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4004 (k_rowPtrs_.dimension_0 () != lclNumRows + 1, std::logic_error,
4005 "(StaticProfile branch) k_rowPtrs_.dimension_0() = " 4006 << k_rowPtrs_.dimension_0 () <<
" != (lclNumRows + 1) = " 4007 << (lclNumRows + 1) <<
".");
4009 const size_t numOffsets = k_rowPtrs_.dimension_0 ();
4010 const auto valToCheck =
4011 Details::getEntryOnHost (k_rowPtrs_, numOffsets - 1);
4012 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4014 k_lclInds1D_.dimension_0 () != valToCheck,
4015 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
4016 numOffsets <<
" != 0 and k_lclInds1D_.dimension_0() = " <<
4017 k_lclInds1D_.dimension_0 () <<
" != k_rowPtrs_(" << numOffsets <<
4018 ") = " << valToCheck <<
".");
4020 #endif // HAVE_TPETRA_DEBUG 4022 size_t allocSize = 0;
4024 allocSize = this->getNodeAllocationSize ();
4026 catch (std::logic_error& e) {
4027 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4028 (
true, std::logic_error,
"In fillLocalGraph, getNodeAllocationSize " 4029 "threw std::logic_error: " << e.what ());
4031 catch (std::runtime_error& e) {
4032 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4033 (
true, std::runtime_error,
"In fillLocalGraph, getNodeAllocationSize " 4034 "threw std::runtime_error: " << e.what ());
4036 catch (std::exception& e) {
4037 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4038 (
true, std::runtime_error,
"In fillLocalGraph, getNodeAllocationSize " 4039 "threw std::exception: " << e.what ());
4042 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4043 (
true, std::runtime_error,
"In fillLocalGraph, getNodeAllocationSize " 4044 "threw an exception not a subclass of std::exception.");
4047 if (nodeNumEntries_ != allocSize) {
4055 #ifdef HAVE_TPETRA_DEBUG 4056 if (k_rowPtrs_.dimension_0 () != 0) {
4057 const size_t numOffsets =
4058 static_cast<size_t> (k_rowPtrs_.dimension_0 ());
4059 const auto valToCheck =
4060 Details::getEntryOnHost (k_rowPtrs_, numOffsets - 1);
4061 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4062 (valToCheck != static_cast<size_t> (k_lclInds1D_.dimension_0 ()),
4063 std::logic_error,
"(StaticProfile unpacked branch) Before " 4064 "allocating or packing, k_rowPtrs_(" << (numOffsets-1) <<
") = " 4065 << valToCheck <<
" != k_lclInds1D_.dimension_0() = " 4066 << k_lclInds1D_.dimension_0 () <<
".");
4068 #endif // HAVE_TPETRA_DEBUG 4076 size_t lclTotalNumEntries = 0;
4079 ptr_d = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
4080 ptr_d_const = ptr_d;
4084 typename row_entries_type::const_type numRowEnt_h = k_numRowEntries_;
4085 #ifdef HAVE_TPETRA_DEBUG 4086 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4087 (static_cast<size_t> (numRowEnt_h.dimension_0 ()) != lclNumRows,
4088 std::logic_error,
"(StaticProfile unpacked branch) " 4089 "numRowEnt_h.dimension_0() = " << numRowEnt_h.dimension_0 ()
4090 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
4091 #endif // HAVE_TPETRA_DEBUG 4095 #ifdef HAVE_TPETRA_DEBUG 4096 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4097 (static_cast<size_t> (ptr_d.dimension_0 ()) != lclNumRows + 1,
4098 std::logic_error,
"(StaticProfile unpacked branch) After " 4099 "allocating ptr_d, ptr_d.dimension_0() = " << ptr_d.dimension_0 ()
4100 <<
" != lclNumRows+1 = " << (lclNumRows+1) <<
".");
4102 const auto valToCheck = Details::getEntryOnHost (ptr_d, lclNumRows);
4103 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4104 (valToCheck != lclTotalNumEntries, std::logic_error,
4105 "Tpetra::CrsGraph::fillLocalGraph: In StaticProfile unpacked " 4106 "branch, after filling ptr_d, ptr_d(lclNumRows=" << lclNumRows
4107 <<
") = " << valToCheck <<
" != total number of entries on " 4108 "the calling process = " << lclTotalNumEntries <<
".");
4110 #endif // HAVE_TPETRA_DEBUG 4114 ind_d = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
4126 typedef pack_functor<
4127 typename local_graph_type::entries_type::non_const_type,
4128 row_map_type> inds_packer_type;
4129 inds_packer_type f (ind_d, k_lclInds1D_, ptr_d, k_rowPtrs_);
4132 typedef Kokkos::RangePolicy<exec_space, LocalOrdinal> range_type;
4133 Kokkos::parallel_for (range_type (0, lclNumRows), f);
4136 #ifdef HAVE_TPETRA_DEBUG 4137 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4138 (ptr_d.dimension_0 () == 0, std::logic_error,
"(StaticProfile " 4139 "\"Optimize Storage\"=true branch) After packing, " 4140 "ptr_d.dimension_0() = 0. This probably means k_rowPtrs_ was " 4141 "never allocated.");
4142 if (ptr_d.dimension_0 () != 0) {
4143 const size_t numOffsets =
static_cast<size_t> (ptr_d.dimension_0 ());
4144 const auto valToCheck = Details::getEntryOnHost (ptr_d, numOffsets - 1);
4145 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4146 (static_cast<size_t> (valToCheck) != ind_d.dimension_0 (),
4147 std::logic_error,
"(StaticProfile \"Optimize Storage\"=true " 4148 "branch) After packing, ptr_d(" << (numOffsets-1) <<
") = " 4149 << valToCheck <<
" != ind_d.dimension_0() = " 4150 << ind_d.dimension_0 () <<
".");
4152 #endif // HAVE_TPETRA_DEBUG 4155 ptr_d_const = k_rowPtrs_;
4156 ind_d = k_lclInds1D_;
4158 #ifdef HAVE_TPETRA_DEBUG 4159 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4160 (ptr_d_const.dimension_0 () == 0, std::logic_error,
"(StaticProfile " 4161 "\"Optimize Storage\"=false branch) ptr_d_const.dimension_0() = 0. " 4162 "This probably means that k_rowPtrs_ was never allocated.");
4163 if (ptr_d_const.dimension_0 () != 0) {
4164 const size_t numOffsets =
4165 static_cast<size_t> (ptr_d_const.dimension_0 ());
4166 const size_t valToCheck =
4167 Details::getEntryOnHost (ptr_d_const, numOffsets - 1);
4168 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4169 (valToCheck != static_cast<size_t> (ind_d.dimension_0 ()),
4170 std::logic_error,
"(StaticProfile \"Optimize Storage\"=false " 4171 "branch) ptr_d_const(" << (numOffsets-1) <<
") = " << valToCheck
4172 <<
" != ind_d.dimension_0() = " << ind_d.dimension_0 () <<
".");
4174 #endif // HAVE_TPETRA_DEBUG 4178 #ifdef HAVE_TPETRA_DEBUG 4180 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4181 (static_cast<size_t> (ptr_d_const.dimension_0 ()) != lclNumRows + 1,
4182 std::logic_error,
"After packing, ptr_d_const.dimension_0() = " <<
4183 ptr_d_const.dimension_0 () <<
" != lclNumRows+1 = " << (lclNumRows+1)
4185 if (ptr_d_const.dimension_0 () != 0) {
4186 const size_t numOffsets =
static_cast<size_t> (ptr_d_const.dimension_0 ());
4187 const auto valToCheck = Details::getEntryOnHost (ptr_d_const, numOffsets - 1);
4188 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4189 (static_cast<size_t> (valToCheck) != ind_d.dimension_0 (),
4190 std::logic_error,
"After packing, ptr_d_const(" << (numOffsets-1)
4191 <<
") = " << valToCheck <<
" != ind_d.dimension_0() = " 4192 << ind_d.dimension_0 () <<
".");
4194 #endif // HAVE_TPETRA_DEBUG 4196 if (requestOptimizedStorage) {
4202 lclInds2D_ = Teuchos::null;
4203 k_numRowEntries_ = row_entries_type ();
4206 k_rowPtrs_ = ptr_d_const;
4207 k_lclInds1D_ = ind_d;
4212 storageStatus_ = Details::STORAGE_1D_PACKED;
4228 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4240 const char tfecfFuncName[] =
"replaceColMap: ";
4241 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4242 isLocallyIndexed () || isGloballyIndexed (), std::runtime_error,
4243 "Requires matching maps and non-static graph.");
4244 colMap_ = newColMap;
4247 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4251 const Teuchos::RCP<const import_type>& newImport,
4252 const bool sortIndicesInEachRow)
4254 using Teuchos::REDUCE_MIN;
4255 using Teuchos::reduceAll;
4257 typedef GlobalOrdinal GO;
4258 typedef LocalOrdinal LO;
4259 typedef typename local_graph_type::entries_type::non_const_type col_inds_type;
4260 const char tfecfFuncName[] =
"reindexColumns: ";
4262 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4263 isFillComplete (), std::runtime_error,
"The graph is fill complete " 4264 "(isFillComplete() returns true). You must call resumeFill() before " 4265 "you may call this method.");
4283 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4298 bool allCurColIndsValid =
true;
4303 bool localSuffices =
true;
4311 typename local_graph_type::entries_type::non_const_type newLclInds1D;
4312 Teuchos::ArrayRCP<Teuchos::Array<LO> > newLclInds2D;
4317 if (indicesAreAllocated ()) {
4318 if (isLocallyIndexed ()) {
4320 const map_type& oldColMap = * (getColMap ());
4323 const size_t allocSize = this->getNodeAllocationSize ();
4324 newLclInds1D = col_inds_type (
"Tpetra::CrsGraph::ind", allocSize);
4326 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4327 const RowInfo rowInfo = this->getRowInfo (lclRow);
4328 const size_t beg = rowInfo.offset1D;
4329 const size_t end = beg + rowInfo.numEntries;
4330 for (
size_t k = beg; k < end; ++k) {
4333 const LO oldLclCol = k_lclInds1D_(k);
4334 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4335 allCurColIndsValid =
false;
4343 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4344 allCurColIndsValid =
false;
4348 const LO newLclCol = newColMap->getLocalElement (gblCol);
4349 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4350 localSuffices =
false;
4355 newLclInds1D(k) = newLclCol;
4364 newLclInds2D = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4367 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4368 const RowInfo rowInfo = this->getRowInfo (lclRow);
4369 newLclInds2D.resize (rowInfo.allocSize);
4371 Teuchos::ArrayView<const LO> oldLclRowView = getLocalView (rowInfo);
4372 Teuchos::ArrayView<LO> newLclRowView = (newLclInds2D[lclRow]) ();
4374 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4375 const LO oldLclCol = oldLclRowView[k];
4376 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4377 allCurColIndsValid =
false;
4384 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4385 allCurColIndsValid =
false;
4389 const LO newLclCol = newColMap->getLocalElement (gblCol);
4390 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4391 localSuffices =
false;
4394 newLclRowView[k] = newLclCol;
4406 allCurColIndsValid =
false;
4423 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4424 const RowInfo rowInfo = this->getRowInfo (lclRow);
4425 Teuchos::ArrayView<const GO> oldGblRowView = getGlobalView (rowInfo);
4426 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4427 const GO gblCol = oldGblRowView[k];
4428 if (! newColMap->isNodeGlobalElement (gblCol)) {
4429 localSuffices =
false;
4439 lclSuccess[0] = allCurColIndsValid ? 1 : 0;
4440 lclSuccess[1] = localSuffices ? 1 : 0;
4444 RCP<const Teuchos::Comm<int> > comm =
4445 getRowMap ().is_null () ? Teuchos::null : getRowMap ()->getComm ();
4446 if (! comm.is_null ()) {
4447 reduceAll<int, int> (*comm, REDUCE_MIN, 2, lclSuccess, gblSuccess);
4450 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4451 gblSuccess[0] == 0, std::runtime_error,
"It is not possible to continue." 4452 " The most likely reason is that the graph is locally indexed, but the " 4453 "column Map is missing (null) on some processes, due to a previous call " 4454 "to replaceColMap().");
4456 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4457 gblSuccess[1] == 0, std::runtime_error,
"On some process, the graph " 4458 "contains column indices that are in the old column Map, but not in the " 4459 "new column Map (on that process). This method does NOT redistribute " 4460 "data; it does not claim to do the work of an Import or Export operation." 4461 " This means that for all processess, the calling process MUST own all " 4462 "column indices, in both the old column Map and the new column Map. In " 4463 "this case, you will need to do an Import or Export operation to " 4464 "redistribute data.");
4467 if (isLocallyIndexed ()) {
4469 k_lclInds1D_ = newLclInds1D;
4471 lclInds2D_ = newLclInds2D;
4479 indicesAreSorted_ =
false;
4480 if (sortIndicesInEachRow) {
4487 const bool sorted =
false;
4488 const bool merged =
true;
4489 this->sortAndMergeAllIndices (sorted, merged);
4492 colMap_ = newColMap;
4494 if (newImport.is_null ()) {
4502 if (! domainMap_.is_null ()) {
4503 if (! domainMap_->isSameAs (* newColMap)) {
4504 importer_ = Teuchos::rcp (
new import_type (domainMap_, newColMap));
4506 importer_ = Teuchos::null;
4511 importer_ = newImport;
4516 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4520 const Teuchos::RCP<const import_type>& newImporter)
4522 const char prefix[] =
"Tpetra::CrsGraph::replaceDomainMapAndImporter: ";
4523 TEUCHOS_TEST_FOR_EXCEPTION(
4524 colMap_.is_null (), std::invalid_argument, prefix <<
"You may not call " 4525 "this method unless the graph already has a column Map.");
4526 TEUCHOS_TEST_FOR_EXCEPTION(
4527 newDomainMap.is_null (), std::invalid_argument,
4528 prefix <<
"The new domain Map must be nonnull.");
4530 #ifdef HAVE_TPETRA_DEBUG 4531 if (newImporter.is_null ()) {
4536 const bool colSameAsDom = colMap_->isSameAs (*newDomainMap);
4537 TEUCHOS_TEST_FOR_EXCEPTION(
4538 colSameAsDom, std::invalid_argument,
"If the new Import is null, " 4539 "then the new domain Map must be the same as the current column Map.");
4542 const bool colSameAsTgt =
4543 colMap_->isSameAs (* (newImporter->getTargetMap ()));
4544 const bool newDomSameAsSrc =
4545 newDomainMap->isSameAs (* (newImporter->getSourceMap ()));
4546 TEUCHOS_TEST_FOR_EXCEPTION(
4547 ! colSameAsTgt || ! newDomSameAsSrc, std::invalid_argument,
"If the " 4548 "new Import is nonnull, then the current column Map must be the same " 4549 "as the new Import's target Map, and the new domain Map must be the " 4550 "same as the new Import's source Map.");
4552 #endif // HAVE_TPETRA_DEBUG 4554 domainMap_ = newDomainMap;
4555 importer_ = Teuchos::rcp_const_cast<
import_type> (newImporter);
4558 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4566 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4571 using ::Tpetra::Details::ProfilingRegion;
4572 using Teuchos::ArrayView;
4573 using Teuchos::outArg;
4574 using Teuchos::reduceAll;
4576 ProfilingRegion regionCGC (
"Tpetra::CrsGraph::computeGlobalConstants");
4579 if(haveGlobalConstants_)
return;
4581 #ifdef HAVE_TPETRA_DEBUG 4582 TEUCHOS_TEST_FOR_EXCEPTION(! hasColMap(), std::logic_error,
"Tpetra::" 4583 "CrsGraph::computeGlobalConstants: At this point, the graph should have " 4584 "a column Map, but it does not. Please report this bug to the Tpetra " 4586 #endif // HAVE_TPETRA_DEBUG 4588 if (! haveLocalConstants_) {
4589 computeLocalConstants();
4590 haveLocalConstants_ =
true;
4596 if (haveGlobalConstants_ ==
false) {
4610 lcl[0] =
static_cast<GST
> (nodeNumEntries_);
4611 lcl[1] =
static_cast<GST
> (nodeNumDiags_);
4612 reduceAll<int,GST> (*getComm (), Teuchos::REDUCE_SUM,
4614 globalNumEntries_ = gbl[0];
4615 globalNumDiags_ = gbl[1];
4616 reduceAll<int,GST> (*getComm (), Teuchos::REDUCE_MAX,
4617 static_cast<GST
> (nodeMaxNumRowEntries_),
4618 outArg (globalMaxNumRowEntries_));
4619 haveGlobalConstants_ =
true;
4624 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4629 using ::Tpetra::Details::ProfilingRegion;
4630 using Teuchos::ArrayView;
4631 using Teuchos::outArg;
4632 using Teuchos::reduceAll;
4633 typedef LocalOrdinal LO;
4634 typedef GlobalOrdinal GO;
4635 ProfilingRegion regionCLC (
"Tpetra::CrsGraph::computeLocalConstants");
4638 if(haveGlobalConstants_)
return;
4640 #ifdef HAVE_TPETRA_DEBUG 4641 TEUCHOS_TEST_FOR_EXCEPTION(! hasColMap(), std::logic_error,
"Tpetra::" 4642 "CrsGraph::computeLocalConstants: At this point, the graph should have " 4643 "a column Map, but it does not. Please report this bug to the Tpetra " 4645 #endif // HAVE_TPETRA_DEBUG 4649 if (! haveLocalConstants_) {
4662 upperTriangular_ =
true;
4663 lowerTriangular_ =
true;
4664 nodeMaxNumRowEntries_ = 0;
4681 if (this->indicesAreAllocated () && this->hasRowInfo ()) {
4682 const LO numLocalRows =
static_cast<LO
> (this->getNodeNumRows ());
4683 for (LO localRow = 0; localRow < numLocalRows; ++localRow) {
4693 const RowInfo rowInfo = this->getRowInfo (localRow);
4694 ArrayView<const LO> rview = this->getLocalView (rowInfo);
4695 typename ArrayView<const LO>::iterator beg, end, cur;
4696 beg = rview.begin();
4697 end = beg + rowInfo.numEntries;
4699 for (cur = beg; cur != end; ++cur) {
4701 if (rlcid == *cur) ++nodeNumDiags_;
4708 const size_t smallestCol =
static_cast<size_t> (*beg);
4709 const size_t largestCol =
static_cast<size_t> (*(end - 1));
4711 if (smallestCol < static_cast<size_t> (localRow)) {
4712 upperTriangular_ =
false;
4714 if (static_cast<size_t> (localRow) < largestCol) {
4715 lowerTriangular_ =
false;
4719 nodeMaxNumRowEntries_ = std::max (nodeMaxNumRowEntries_, rowInfo.numEntries);
4722 haveLocalConstants_ =
true;
4727 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4732 using ::Tpetra::Details::ProfilingRegion;
4733 using Teuchos::arcp;
4734 using Teuchos::Array;
4735 typedef LocalOrdinal LO;
4736 typedef GlobalOrdinal GO;
4738 typedef typename local_graph_type::row_map_type::non_const_value_type offset_type;
4739 typedef decltype (k_numRowEntries_) row_entries_type;
4740 typedef typename row_entries_type::non_const_value_type num_ent_type;
4741 typedef typename local_graph_type::entries_type::non_const_type
4743 typedef Kokkos::View<GO*,
typename lcl_col_inds_type::array_layout,
4745 const char tfecfFuncName[] =
"makeIndicesLocal: ";
4746 ProfilingRegion regionMakeIndicesLocal (
"Tpetra::CrsGraph::makeIndicesLocal");
4748 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4749 (! this->hasColMap (), std::logic_error,
"The graph does not have a " 4750 "column Map yet. This method should never be called in that case. " 4751 "Please report this bug to the Tpetra developers.");
4752 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4753 (this->getColMap ().is_null (), std::logic_error,
"The graph claims " 4754 "that it has a column Map, because hasColMap() returns true. However, " 4755 "the result of getColMap() is null. This should never happen. Please " 4756 "report this bug to the Tpetra developers.");
4758 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4759 const map_type& colMap = * (this->getColMap ());
4761 if (isGloballyIndexed () && lclNumRows != 0) {
4763 typename row_entries_type::const_type h_numRowEnt = k_numRowEntries_;
4770 constexpr
bool LO_GO_same = std::is_same<LO, GO>::value;
4775 k_lclInds1D_ = Kokkos::Impl::if_c<LO_GO_same,
4777 lcl_col_inds_type>::select (k_gblInds1D_, k_lclInds1D_);
4780 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4781 (k_rowPtrs_.dimension_0 () == 0, std::logic_error,
4782 "k_rowPtrs_.dimension_0() == 0. This should never happen at this " 4783 "point. Please report this bug to the Tpetra developers.");
4785 const auto numEnt = Details::getEntryOnHost (k_rowPtrs_, lclNumRows);
4794 using Kokkos::view_alloc;
4795 using Kokkos::WithoutInitializing;
4805 const std::string label (
"Tpetra::CrsGraph::lclind");
4807 lcl_col_inds_type (view_alloc (label, WithoutInitializing), numEnt);
4818 auto k_numRowEnt = Kokkos::create_mirror_view (
device_type (), h_numRowEnt);
4821 const size_t numBad =
4822 convertColumnIndicesFromGlobalToLocal<LO, GO, DT, offset_type, num_ent_type> (k_lclInds1D_,
4827 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4828 (numBad != 0, std::runtime_error,
"When converting column indices " 4829 "from global to local, we encountered " << numBad
4830 <<
"ind" << (numBad != static_cast<size_t> (1) ?
"ices" :
"ex")
4831 <<
" that do" << (numBad != static_cast<size_t> (1) ?
"es" :
"")
4832 <<
" not live in the column Map on this process.");
4837 k_gblInds1D_ = gbl_col_inds_type ();
4840 lclInds2D_ = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4841 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4842 if (! gblInds2D_[lclRow].empty ()) {
4843 const GO*
const ginds = gblInds2D_[lclRow].getRawPtr ();
4847 const LO rna =
static_cast<LO
> (gblInds2D_[lclRow].size ());
4848 const LO numEnt =
static_cast<LO
> (h_numRowEnt(lclRow));
4849 lclInds2D_[lclRow].resize (rna);
4850 LO*
const linds = lclInds2D_[lclRow].getRawPtr ();
4851 for (LO j = 0; j < numEnt; ++j) {
4852 const GO gid = ginds[j];
4855 #ifdef HAVE_TPETRA_DEBUG 4856 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4857 (linds[j] == Teuchos::OrdinalTraits<LO>::invalid(),
4859 "Global column ginds[j=" << j <<
"]=" << ginds[j]
4860 <<
" of local row " << lclRow <<
" is not in the column Map. " 4861 "This should never happen. Please report this bug to the " 4862 "Tpetra developers.");
4863 #endif // HAVE_TPETRA_DEBUG 4867 gblInds2D_ = Teuchos::null;
4872 indicesAreLocal_ =
true;
4873 indicesAreGlobal_ =
false;
4874 checkInternalState ();
4878 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4883 using ::Tpetra::Details::ProfilingRegion;
4884 #ifdef HAVE_TPETRA_DEBUG 4885 const char tfecfFuncName[] =
"makeColMap: ";
4886 #endif // HAVE_TPETRA_DEBUG 4887 ProfilingRegion regionSortAndMerge (
"Tpetra::CrsGraph::makeColMap");
4894 Teuchos::RCP<const map_type> colMap = this->colMap_;
4895 const bool sortEachProcsGids =
4896 this->sortGhostsAssociatedWithEachProcessor_;
4906 #ifdef HAVE_TPETRA_DEBUG 4907 using Teuchos::outArg;
4908 using Teuchos::REDUCE_MIN;
4909 using Teuchos::reduceAll;
4911 std::ostringstream errStrm;
4912 const int lclErrCode =
4914 sortEachProcsGids, &errStrm);
4915 auto comm = this->getComm ();
4916 if (! comm.is_null ()) {
4917 const int lclSuccess = (lclErrCode == 0) ? 1 : 0;
4919 reduceAll<int, int> (*comm, REDUCE_MIN, lclSuccess,
4920 outArg (gblSuccess));
4921 if (gblSuccess != 1) {
4922 std::ostringstream os;
4924 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4925 (
true, std::runtime_error,
4926 "makeColMap reports an error on at least one process." 4927 << std::endl << os.str ());
4930 #else // NOT HAVE_TPETRA_DEBUG 4932 sortEachProcsGids, NULL);
4933 #endif // HAVE_TPETRA_DEBUG 4937 this->colMap_ = colMap;
4939 checkInternalState ();
4943 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4948 using ::Tpetra::Details::ProfilingRegion;
4949 typedef LocalOrdinal LO;
4950 typedef typename Kokkos::View<LO*, device_type>::HostMirror::execution_space
4951 host_execution_space;
4952 typedef Kokkos::RangePolicy<host_execution_space, LO> range_type;
4953 const char tfecfFuncName[] =
"sortAndMergeAllIndices: ";
4954 ProfilingRegion regionSortAndMerge (
"Tpetra::CrsGraph::sortAndMergeAllIndices");
4956 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4957 (this->isGloballyIndexed (), std::logic_error,
4958 "This method may only be called after makeIndicesLocal." );
4960 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4961 (! merged && this->isStorageOptimized (), std::logic_error,
4962 "The graph is already storage optimized, so we shouldn't be merging any " 4963 "indices. Please report this bug to the Tpetra developers.");
4965 if (! sorted || ! merged) {
4966 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4967 size_t totalNumDups = 0;
4969 Kokkos::parallel_reduce (range_type (0, lclNumRows),
4970 [
this, sorted, merged] (
const LO& lclRow,
size_t& numDups) {
4971 const RowInfo rowInfo = this->getRowInfo (lclRow);
4973 this->sortRowIndices (rowInfo);
4976 numDups += this->mergeRowIndices (rowInfo);
4979 this->nodeNumEntries_ -= totalNumDups;
4980 this->indicesAreSorted_ =
true;
4981 this->noRedundancies_ =
true;
4986 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4991 using ::Tpetra::Details::ProfilingRegion;
4992 using Teuchos::ParameterList;
4995 const char tfecfFuncName[] =
"makeImportExport: ";
4996 ProfilingRegion regionMIE (
"Tpetra::CrsGraph::makeImportExport");
4998 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4999 (! this->hasColMap (), std::logic_error,
5000 "This method may not be called unless the graph has a column Map.");
5001 RCP<ParameterList> params = this->getNonconstParameterList ();
5010 if (importer_.is_null ()) {
5012 if (domainMap_ != colMap_ && (! domainMap_->isSameAs (*colMap_))) {
5013 if (params.is_null () || ! params->isSublist (
"Import")) {
5014 importer_ = rcp (
new import_type (domainMap_, colMap_));
5016 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5017 importer_ = rcp (
new import_type (domainMap_, colMap_, importSublist));
5024 if (exporter_.is_null ()) {
5026 if (rangeMap_ != rowMap_ && ! rangeMap_->isSameAs (*rowMap_)) {
5027 if (params.is_null () || ! params->isSublist (
"Export")) {
5028 exporter_ = rcp (
new export_type (rowMap_, rangeMap_));
5031 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5032 exporter_ = rcp (
new export_type (rowMap_, rangeMap_, exportSublist));
5039 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5044 std::ostringstream oss;
5045 oss << dist_object_type::description ();
5046 if (isFillComplete ()) {
5047 oss <<
"{status = fill complete" 5048 <<
", global rows = " << getGlobalNumRows()
5049 <<
", global cols = " << getGlobalNumCols()
5050 <<
", global num entries = " << getGlobalNumEntries()
5054 oss <<
"{status = fill not complete" 5055 <<
", global rows = " << getGlobalNumRows()
5062 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5066 const Teuchos::EVerbosityLevel verbLevel)
const 5068 const char tfecfFuncName[] =
"describe()";
5069 using Teuchos::ArrayView;
5070 using Teuchos::Comm;
5072 using Teuchos::VERB_DEFAULT;
5073 using Teuchos::VERB_NONE;
5074 using Teuchos::VERB_LOW;
5075 using Teuchos::VERB_MEDIUM;
5076 using Teuchos::VERB_HIGH;
5077 using Teuchos::VERB_EXTREME;
5081 Teuchos::EVerbosityLevel vl = verbLevel;
5082 if (vl == VERB_DEFAULT) vl = VERB_LOW;
5083 RCP<const Comm<int> > comm = this->getComm();
5084 const int myImageID = comm->getRank(),
5085 numImages = comm->getSize();
5087 for (
size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
5090 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5091 Teuchos::OSTab tab (out);
5099 if (vl != VERB_NONE) {
5100 if (myImageID == 0) out << this->description() << std::endl;
5102 if (isFillComplete() && myImageID == 0) {
5103 out <<
"Global number of diagonals = " << globalNumDiags_ << std::endl;
5104 out <<
"Global max number of row entries = " << globalMaxNumRowEntries_ << std::endl;
5107 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5108 if (myImageID == 0) out <<
"\nRow map: " << std::endl;
5109 rowMap_->describe(out,vl);
5110 if (colMap_ != Teuchos::null) {
5111 if (myImageID == 0) out <<
"\nColumn map: " << std::endl;
5112 colMap_->describe(out,vl);
5114 if (domainMap_ != Teuchos::null) {
5115 if (myImageID == 0) out <<
"\nDomain map: " << std::endl;
5116 domainMap_->describe(out,vl);
5118 if (rangeMap_ != Teuchos::null) {
5119 if (myImageID == 0) out <<
"\nRange map: " << std::endl;
5120 rangeMap_->describe(out,vl);
5124 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5125 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5126 if (myImageID == imageCtr) {
5127 out <<
"Node ID = " << imageCtr << std::endl
5128 <<
"Node number of entries = " << nodeNumEntries_ << std::endl
5129 <<
"Node number of diagonals = " << nodeNumDiags_ << std::endl
5130 <<
"Node max number of entries = " << nodeMaxNumRowEntries_ << std::endl;
5131 if (! indicesAreAllocated ()) {
5132 out <<
"Indices are not allocated." << std::endl;
5141 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
5142 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5143 ! hasRowInfo (), std::runtime_error,
": reduce verbosity level; " 5144 "graph row information was deleted at fillComplete().");
5145 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5146 if (myImageID == imageCtr) {
5147 out << std::setw(width) <<
"Node ID" 5148 << std::setw(width) <<
"Global Row" 5149 << std::setw(width) <<
"Num Entries";
5150 if (vl == VERB_EXTREME) {
5154 const LocalOrdinal lclNumRows =
5155 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
5156 for (LocalOrdinal r=0; r < lclNumRows; ++r) {
5157 const RowInfo rowinfo = this->getRowInfo (r);
5158 GlobalOrdinal gid = rowMap_->getGlobalElement(r);
5159 out << std::setw(width) << myImageID
5160 << std::setw(width) << gid
5161 << std::setw(width) << rowinfo.numEntries;
5162 if (vl == VERB_EXTREME) {
5164 if (isGloballyIndexed()) {
5165 ArrayView<const GlobalOrdinal> rowview = getGlobalView(rowinfo);
5166 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << rowview[j] <<
" ";
5168 else if (isLocallyIndexed()) {
5169 ArrayView<const LocalOrdinal> rowview = getLocalView(rowinfo);
5170 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << colMap_->getGlobalElement(rowview[j]) <<
" ";
5185 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5199 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5204 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
5205 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs)
5207 using Teuchos::Array;
5208 using Teuchos::ArrayView;
5209 typedef LocalOrdinal LO;
5210 typedef GlobalOrdinal GO;
5211 const char tfecfFuncName[] =
"copyAndPermute";
5215 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5216 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
5217 ": permuteToLIDs and permuteFromLIDs must have the same size.");
5231 const row_graph_type* srcRowGraph =
dynamic_cast<const row_graph_type*
> (&source);
5232 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5233 srcRowGraph == NULL, std::invalid_argument,
5234 ": The source object must be a RowGraph with matching first three " 5235 "template parameters.");
5240 const this_type* srcCrsGraph =
dynamic_cast<const this_type*
> (&source);
5242 const map_type& srcRowMap = * (srcRowGraph->getRowMap ());
5243 const map_type& tgtRowMap = * (this->getRowMap ());
5244 const bool src_filled = srcRowGraph->isFillComplete ();
5251 if (src_filled || srcCrsGraph == NULL) {
5257 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5259 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (gid);
5260 row_copy.resize (row_length);
5261 size_t check_row_length = 0;
5262 srcRowGraph->getGlobalRowCopy (gid, row_copy (), check_row_length);
5263 this->insertGlobalIndices (gid, row_copy ());
5266 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5268 ArrayView<const GO> row;
5269 srcCrsGraph->getGlobalRowView (gid, row);
5270 this->insertGlobalIndices (gid, row);
5277 if (src_filled || srcCrsGraph == NULL) {
5278 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5281 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (srcgid);
5282 row_copy.resize (row_length);
5283 size_t check_row_length = 0;
5284 srcRowGraph->getGlobalRowCopy (srcgid, row_copy (), check_row_length);
5285 this->insertGlobalIndices (mygid, row_copy ());
5288 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5291 ArrayView<const GO> row;
5292 srcCrsGraph->getGlobalRowView (srcgid, row);
5293 this->insertGlobalIndices (mygid, row);
5299 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5303 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
5304 Teuchos::Array<GlobalOrdinal> &exports,
5305 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
5306 size_t& constantNumPackets,
5309 using Teuchos::Array;
5310 const char tfecfFuncName[] =
"packAndPrepare";
5311 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5312 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5313 ": exportLIDs and numPacketsPerLID must have the same size.");
5315 const row_graph_type& srcGraph =
dynamic_cast<const row_graph_type&
> (source);
5320 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5321 this->isFillComplete (), std::runtime_error,
5322 ": The target graph of an Import or Export must not be fill complete.");
5324 srcGraph.pack (exportLIDs, exports, numPacketsPerLID, constantNumPackets, distor);
5328 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5331 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5332 Teuchos::Array<GlobalOrdinal>& exports,
5333 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5334 size_t& constantNumPackets,
5337 using Teuchos::Array;
5338 typedef LocalOrdinal LO;
5339 typedef GlobalOrdinal GO;
5340 const char tfecfFuncName[] =
"pack";
5343 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5344 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5345 ": exportLIDs and numPacketsPerLID must have the same size.");
5347 const map_type& srcMap = * (this->getMap ());
5348 constantNumPackets = 0;
5355 size_t totalNumPackets = 0;
5357 for (LO i = 0; i < exportLIDs.size (); ++i) {
5359 size_t row_length = this->getNumEntriesInGlobalRow (GID);
5360 numPacketsPerLID[i] = row_length;
5361 totalNumPackets += row_length;
5364 exports.resize (totalNumPackets);
5368 size_t exportsOffset = 0;
5369 for (LO i = 0; i < exportLIDs.size (); ++i) {
5370 const GO GID = srcMap.getGlobalElement (exportLIDs[i]);
5371 size_t row_length = this->getNumEntriesInGlobalRow (GID);
5372 row.resize (row_length);
5373 size_t check_row_length = 0;
5374 this->getGlobalRowCopy (GID, row (), check_row_length);
5375 typename Array<GO>::const_iterator row_iter = row.begin();
5376 typename Array<GO>::const_iterator row_end = row.end();
5378 for (; row_iter != row_end; ++row_iter, ++j) {
5379 exports[exportsOffset+j] = *row_iter;
5381 exportsOffset += row.size();
5386 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5389 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
5390 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
5391 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
5392 size_t constantNumPackets,
5396 using Teuchos::ArrayView;
5397 typedef LocalOrdinal LO;
5398 typedef GlobalOrdinal GO;
5417 const char tfecfFuncName[] =
"unpackAndCombine: ";
5418 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5419 importLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5420 "importLIDs and numPacketsPerLID must have the same size.");
5421 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5422 isFillComplete (), std::runtime_error,
5423 "Import or Export operations are not allowed on the destination " 5424 "CrsGraph if it is fill complete.");
5425 size_t importsOffset = 0;
5427 typedef typename ArrayView<const LO>::const_iterator iter_type;
5428 iter_type impLIDiter = importLIDs.begin();
5429 iter_type impLIDend = importLIDs.end();
5431 for (
size_t i = 0; impLIDiter != impLIDend; ++impLIDiter, ++i) {
5432 LO row_length = numPacketsPerLID[i];
5434 const GO*
const row_raw = (row_length == 0) ? NULL : &imports[importsOffset];
5435 ArrayView<const GlobalOrdinal> row (row_raw, row_length);
5436 insertGlobalIndicesFiltered (this->getMap ()->getGlobalElement (*impLIDiter), row);
5437 importsOffset += row_length;
5442 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5447 using Teuchos::Comm;
5448 using Teuchos::null;
5449 using Teuchos::ParameterList;
5455 RCP<const map_type> rowMap, domainMap, rangeMap, colMap;
5456 RCP<import_type> importer;
5457 RCP<export_type> exporter;
5460 RCP<const Comm<int> > newComm =
5461 (newMap.is_null ()) ? null : newMap->getComm ();
5463 if (! domainMap_.is_null ()) {
5464 if (domainMap_.getRawPtr () == rowMap_.getRawPtr ()) {
5471 domainMap = domainMap_->replaceCommWithSubset (newComm);
5474 if (! rangeMap_.is_null ()) {
5475 if (rangeMap_.getRawPtr () == rowMap_.getRawPtr ()) {
5482 rangeMap = rangeMap_->replaceCommWithSubset (newComm);
5485 if (! colMap.is_null ()) {
5486 colMap = colMap_->replaceCommWithSubset (newComm);
5490 if (! newComm.is_null ()) {
5491 RCP<ParameterList> params = this->getNonconstParameterList ();
5499 if (! rangeMap_.is_null () &&
5500 rangeMap != rowMap &&
5501 ! rangeMap->isSameAs (*rowMap)) {
5502 if (params.is_null () || ! params->isSublist (
"Export")) {
5503 exporter = rcp (
new export_type (rowMap, rangeMap));
5506 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5507 exporter = rcp (
new export_type (rowMap, rangeMap, exportSublist));
5511 if (! domainMap_.is_null () &&
5512 domainMap != colMap &&
5513 ! domainMap->isSameAs (*colMap)) {
5514 if (params.is_null () || ! params->isSublist (
"Import")) {
5515 importer = rcp (
new import_type (domainMap, colMap));
5517 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5518 importer = rcp (
new import_type (domainMap, colMap, importSublist));
5526 exporter_ = exporter;
5527 importer_ = importer;
5534 this->map_ = rowMap;
5535 domainMap_ = domainMap;
5536 rangeMap_ = rangeMap;
5540 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5545 if (this->indicesAreAllocated () &&
5547 this->k_rowPtrs_.dimension_0 () == 0) {
5554 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5559 typedef LocalOrdinal LO;
5560 typedef GlobalOrdinal GO;
5561 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
5563 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5564 (! hasColMap (), std::runtime_error,
"The graph must have a column Map.");
5565 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5566 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5567 (static_cast<LO> (offsets.dimension_0 ()) < lclNumRows,
5568 std::invalid_argument,
"offsets.dimension_0() = " <<
5569 offsets.dimension_0 () <<
" < getNodeNumRows() = " << lclNumRows <<
".");
5571 const map_type& rowMap = * (this->getRowMap ());
5572 const map_type& colMap = * (this->getColMap ());
5574 #ifdef HAVE_TPETRA_DEBUG 5575 bool allRowMapDiagEntriesInColMap =
true;
5576 bool allDiagEntriesFound =
true;
5577 bool allOffsetsCorrect =
true;
5578 bool noOtherWeirdness =
true;
5579 std::vector<std::pair<LO, size_t> > wrongOffsets;
5580 #endif // HAVE_TPETRA_DEBUG 5591 const bool sorted = this->isSorted ();
5592 if (isFillComplete ()) {
5593 auto lclGraph = this->getLocalGraph ();
5594 Details::getGraphDiagOffsets (offsets, lclRowMap, lclColMap,
5595 lclGraph.row_map, lclGraph.entries,
5602 auto offsets_h = Kokkos::create_mirror_view (offsets);
5604 for (LO lclRowInd = 0; lclRowInd < lclNumRows; ++lclRowInd) {
5608 const GO gblRowInd = lclRowMap.getGlobalElement (lclRowInd);
5609 const GO gblColInd = gblRowInd;
5610 const LO lclColInd = lclColMap.getLocalElement (gblColInd);
5612 if (lclColInd == Tpetra::Details::OrdinalTraits<LO>::invalid ()) {
5613 #ifdef HAVE_TPETRA_DEBUG 5614 allRowMapDiagEntriesInColMap =
false;
5615 #endif // HAVE_TPETRA_DEBUG 5616 offsets_h(lclRowInd) = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
5619 const RowInfo rowInfo = this->getRowInfo (lclRowInd);
5620 if (static_cast<LO> (rowInfo.localRow) == lclRowInd &&
5621 rowInfo.numEntries > 0) {
5623 auto colInds = this->getLocalKokkosRowView (rowInfo);
5624 const size_t hint = 0;
5625 const size_t offset =
5626 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
5627 lclColInd, hint, sorted);
5628 offsets_h(lclRowInd) = offset;
5630 #ifdef HAVE_TPETRA_DEBUG 5635 Teuchos::ArrayView<const LO> lclColInds;
5637 this->getLocalRowView (lclRowInd, lclColInds);
5640 noOtherWeirdness =
false;
5643 if (noOtherWeirdness) {
5644 const size_t numEnt = lclColInds.size ();
5645 if (offset >= numEnt) {
5648 allOffsetsCorrect =
false;
5649 wrongOffsets.push_back (std::make_pair (lclRowInd, offset));
5651 const LO actualLclColInd = lclColInds[offset];
5652 const GO actualGblColInd = lclColMap.getGlobalElement (actualLclColInd);
5653 if (actualGblColInd != gblColInd) {
5654 allOffsetsCorrect =
false;
5655 wrongOffsets.push_back (std::make_pair (lclRowInd, offset));
5659 #endif // HAVE_TPETRA_DEBUG 5662 offsets_h(lclRowInd) = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
5663 #ifdef HAVE_TPETRA_DEBUG 5664 allDiagEntriesFound =
false;
5665 #endif // HAVE_TPETRA_DEBUG 5673 #ifdef HAVE_TPETRA_DEBUG 5674 if (wrongOffsets.size () != 0) {
5675 std::ostringstream os;
5676 os <<
"Proc " << this->getComm ()->getRank () <<
": Wrong offsets: [";
5677 for (
size_t k = 0; k < wrongOffsets.size (); ++k) {
5678 os <<
"(" << wrongOffsets[k].first <<
"," 5679 << wrongOffsets[k].second <<
")";
5680 if (k + 1 < wrongOffsets.size ()) {
5684 os <<
"]" << std::endl;
5685 std::cerr << os.str ();
5687 #endif // HAVE_TPETRA_DEBUG 5689 #ifdef HAVE_TPETRA_DEBUG 5690 using Teuchos::reduceAll;
5692 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getComm ();
5693 const bool localSuccess =
5694 allRowMapDiagEntriesInColMap && allDiagEntriesFound && allOffsetsCorrect;
5695 const int numResults = 5;
5697 lclResults[0] = allRowMapDiagEntriesInColMap ? 1 : 0;
5698 lclResults[1] = allDiagEntriesFound ? 1 : 0;
5699 lclResults[2] = allOffsetsCorrect ? 1 : 0;
5700 lclResults[3] = noOtherWeirdness ? 1 : 0;
5703 lclResults[4] = ! localSuccess ? comm->getRank () : comm->getSize ();
5711 reduceAll<int, int> (*comm, Teuchos::REDUCE_MIN,
5712 numResults, lclResults, gblResults);
5714 if (gblResults[0] != 1 || gblResults[1] != 1 || gblResults[2] != 1
5715 || gblResults[3] != 1) {
5716 std::ostringstream os;
5717 os <<
"Issue(s) that we noticed (on Process " << gblResults[4] <<
", " 5718 "possibly among others): " << endl;
5719 if (gblResults[0] == 0) {
5720 os <<
" - The column Map does not contain at least one diagonal entry " 5721 "of the graph." << endl;
5723 if (gblResults[1] == 0) {
5724 os <<
" - On one or more processes, some row does not contain a " 5725 "diagonal entry." << endl;
5727 if (gblResults[2] == 0) {
5728 os <<
" - On one or more processes, some offsets are incorrect." 5731 if (gblResults[3] == 0) {
5732 os <<
" - One or more processes had some other error." 5735 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::runtime_error, os.str());
5737 #endif // HAVE_TPETRA_DEBUG 5758 template<
class DeviceType,
5759 const bool memSpaceIsHostSpace =
5760 std::is_same<
typename DeviceType::memory_space,
5761 Kokkos::HostSpace>::value>
5762 struct HelpGetLocalDiagOffsets {};
5764 template<
class DeviceType>
5765 struct HelpGetLocalDiagOffsets<DeviceType, true> {
5767 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5768 Kokkos::MemoryUnmanaged> device_offsets_type;
5769 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5770 Kokkos::MemoryUnmanaged> host_offsets_type;
5772 static device_offsets_type
5773 getDeviceOffsets (
const host_offsets_type& hostOffsets)
5781 copyBackIfNeeded (
const host_offsets_type& ,
5782 const device_offsets_type& )
5786 template<
class DeviceType>
5787 struct HelpGetLocalDiagOffsets<DeviceType, false> {
5792 typedef Kokkos::View<size_t*, device_type> device_offsets_type;
5793 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
5794 Kokkos::MemoryUnmanaged> host_offsets_type;
5796 static device_offsets_type
5797 getDeviceOffsets (
const host_offsets_type& hostOffsets)
5801 return device_offsets_type (
"offsets", hostOffsets.dimension_0 ());
5805 copyBackIfNeeded (
const host_offsets_type& hostOffsets,
5806 const device_offsets_type& deviceOffsets)
5814 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5819 typedef LocalOrdinal LO;
5820 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
5821 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5822 (! this->hasColMap (), std::runtime_error,
5823 "The graph does not yet have a column Map.");
5824 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5825 if (static_cast<LO> (offsets.size ()) != myNumRows) {
5829 offsets.resize (myNumRows);
5841 typedef HelpGetLocalDiagOffsets<device_type> helper_type;
5842 typedef typename helper_type::host_offsets_type host_offsets_type;
5844 host_offsets_type hostOffsets (offsets.getRawPtr (), myNumRows);
5846 auto deviceOffsets = helper_type::getDeviceOffsets (hostOffsets);
5848 this->getLocalDiagOffsets (deviceOffsets);
5849 helper_type::copyBackIfNeeded (hostOffsets, deviceOffsets);
5852 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5866 #define TPETRA_CRSGRAPH_GRAPH_INSTANT(LO,GO,NODE) template class CrsGraph< LO , GO , NODE >; 5870 #define TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) 5871 #define TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) 5872 #define TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) 5873 #define TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) 5875 #define TPETRA_CRSGRAPH_INSTANT(S,LO,GO,NODE) \ 5876 TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5877 TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5878 TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) \ 5879 TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) 5881 #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.
node_type ::device_type device_type
This class' Kokkos device type.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
int makeColMap(Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &colMap, const Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &domMap, const RowGraph< LO, GO, NT > &graph, const bool sortEachProcsGids=true, std::ostream *errStrm=NULL)
Make the graph's column Map.
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.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::RCP< node_type > getNode() const
Returns the underlying node.
Implementation details of Tpetra.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator, in rank order.
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.
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.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
device_type::execution_space execution_space
This class' Kokkos execution space.
Declaration and definition of Tpetra::Details::getEntryOnHost.
Kokkos::View< GO *, execution_space > t_GlobalOrdinal_1D
Type of the k_gblInds1D_ array of global column indices.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.