42 #ifndef TPETRA_CRSGRAPH_DEF_HPP 43 #define TPETRA_CRSGRAPH_DEF_HPP 53 #include "Tpetra_Distributor.hpp" 54 #include "Teuchos_Assert.hpp" 55 #include "Teuchos_NullIteratorTraits.hpp" 56 #include "Teuchos_as.hpp" 57 #include "Teuchos_SerialDenseMatrix.hpp" 58 #include "KokkosCompat_ClassicNodeAPI_Wrapper.hpp" 67 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
68 CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::
69 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
70 size_t maxNumEntriesPerRow,
72 const Teuchos::RCP<Teuchos::ParameterList>& params) :
76 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
78 , numAllocForAllRows_ (maxNumEntriesPerRow)
82 , indicesAreAllocated_ (false)
83 , indicesAreLocal_ (false)
84 , indicesAreGlobal_ (false)
85 , fillComplete_ (false)
86 , indicesAreSorted_ (true)
87 , noRedundancies_ (true)
88 , haveLocalConstants_ (false)
89 , haveGlobalConstants_ (false)
90 , sortGhostsAssociatedWithEachProcessor_ (true)
92 const char tfecfFuncName[] =
"CrsGraph(rowMap,maxNumEntriesPerRow," 95 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
96 maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
97 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 98 "a valid size_t value, which in this case means it must not be " 99 "Teuchos::OrdinalTraits<size_t>::invalid().");
104 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
106 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
107 const Teuchos::RCP<const map_type>& colMap,
108 const size_t maxNumEntriesPerRow,
110 const Teuchos::RCP<Teuchos::ParameterList>& params) :
114 , nodeNumEntries_ (0)
115 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
121 , indicesAreAllocated_ (false)
122 , indicesAreLocal_ (false)
123 , indicesAreGlobal_ (false)
124 , fillComplete_ (false)
131 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,maxNumEntriesPerRow," 134 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
135 maxNumEntriesPerRow == Teuchos::OrdinalTraits<size_t>::invalid (),
136 std::invalid_argument,
"The allocation hint maxNumEntriesPerRow must be " 137 "a valid size_t value, which in this case means it must not be " 138 "Teuchos::OrdinalTraits<size_t>::invalid().");
143 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
145 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
146 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
148 const Teuchos::RCP<Teuchos::ParameterList>& params) :
151 , nodeNumEntries_ (0)
152 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
158 , indicesAreAllocated_ (false)
159 , indicesAreLocal_ (false)
160 , indicesAreGlobal_ (false)
161 , fillComplete_ (false)
168 const char tfecfFuncName[] =
"CrsGraph(rowMap,numEntPerRow,pftype,params): ";
171 const size_t lclNumRows = rowMap.is_null () ?
172 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
173 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
174 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
175 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
176 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 177 "the input row Map.");
179 #ifdef HAVE_TPETRA_DEBUG 180 for (
size_t r = 0; r < lclNumRows; ++r) {
181 const size_t curRowCount = numEntPerRow[r];
182 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
183 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
184 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 185 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
187 #endif // HAVE_TPETRA_DEBUG 194 typedef Kokkos::DualView<size_t*, Kokkos::LayoutLeft, execution_space>
196 typedef typename dual_view_type::host_mirror_space host_type;
197 typedef Kokkos::View<
const size_t*, Kokkos::LayoutLeft, host_type,
198 Kokkos::MemoryUnmanaged> in_view_type;
199 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
200 dual_view_type k_numAllocPerRow (
"Tpetra::CrsGraph::numAllocPerRow",
202 k_numAllocPerRow.template modify<host_type> ();
204 k_numAllocPerRow.template sync<execution_space> ();
211 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
213 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
214 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
216 const Teuchos::RCP<Teuchos::ParameterList>& params) :
219 , nodeNumEntries_ (0)
220 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
227 , indicesAreAllocated_ (false)
228 , indicesAreLocal_ (false)
229 , indicesAreGlobal_ (false)
230 , fillComplete_ (false)
237 const char tfecfFuncName[] =
"CrsGraph(rowMap,numEntPerRow,pftype,params): ";
240 const size_t lclNumRows = rowMap.is_null () ?
241 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
242 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
243 static_cast<size_t> (numEntPerRow.dimension_0 ()) != lclNumRows,
244 std::invalid_argument,
"numEntPerRow has length " <<
245 numEntPerRow.dimension_0 () <<
" != the local number of rows " <<
246 lclNumRows <<
" as specified by " "the input row Map.");
248 #ifdef HAVE_TPETRA_DEBUG 249 for (
size_t r = 0; r < lclNumRows; ++r) {
250 const size_t curRowCount = numEntPerRow.h_view(r);
251 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
252 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
253 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 254 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
256 #endif // HAVE_TPETRA_DEBUG 263 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
265 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
266 const Teuchos::RCP<const map_type>& colMap,
267 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
269 const Teuchos::RCP<Teuchos::ParameterList>& params) :
273 , nodeNumEntries_ (0)
274 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
281 , indicesAreAllocated_ (false)
282 , indicesAreLocal_ (false)
283 , indicesAreGlobal_ (false)
284 , fillComplete_ (false)
291 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype,params): ";
294 const size_t lclNumRows = rowMap.is_null () ?
295 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
296 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
297 static_cast<size_t> (numEntPerRow.dimension_0 ()) != lclNumRows,
298 std::invalid_argument,
"numEntPerRow has length " <<
299 numEntPerRow.dimension_0 () <<
" != the local number of rows " <<
300 lclNumRows <<
" as specified by " "the input row Map.");
302 #ifdef HAVE_TPETRA_DEBUG 303 for (
size_t r = 0; r < lclNumRows; ++r) {
304 const size_t curRowCount = numEntPerRow.h_view(r);
305 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
306 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
307 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 308 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
310 #endif // HAVE_TPETRA_DEBUG 317 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
319 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
320 const Teuchos::RCP<const map_type>& colMap,
321 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
323 const Teuchos::RCP<Teuchos::ParameterList>& params) :
327 , nodeNumEntries_ (0)
328 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
334 , indicesAreAllocated_ (false)
335 , indicesAreLocal_ (false)
336 , indicesAreGlobal_ (false)
337 , fillComplete_ (false)
344 const char tfecfFuncName[] =
"CrsGraph(rowMap,colMap,numEntPerRow,pftype," 348 const size_t lclNumRows = rowMap.is_null () ?
349 static_cast<size_t> (0) : rowMap->getNodeNumElements ();
350 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
351 static_cast<size_t> (numEntPerRow.size ()) != lclNumRows,
352 std::invalid_argument,
"numEntPerRow has length " << numEntPerRow.size ()
353 <<
" != the local number of rows " << lclNumRows <<
" as specified by " 354 "the input row Map.");
356 #ifdef HAVE_TPETRA_DEBUG 357 for (
size_t r = 0; r < lclNumRows; ++r) {
358 const size_t curRowCount = numEntPerRow[r];
359 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
360 curRowCount == Teuchos::OrdinalTraits<size_t>::invalid (),
361 std::invalid_argument,
"numEntPerRow(" << r <<
") specifies an invalid " 362 "number of entries (Teuchos::OrdinalTraits<size_t>::invalid()).");
364 #endif // HAVE_TPETRA_DEBUG 371 typedef Kokkos::DualView<size_t*, Kokkos::LayoutLeft, execution_space>
373 typedef typename dual_view_type::host_mirror_space host_type;
374 typedef Kokkos::View<
const size_t*, Kokkos::LayoutLeft, host_type,
375 Kokkos::MemoryUnmanaged> in_view_type;
376 in_view_type numAllocPerRowIn (numEntPerRow.getRawPtr (), lclNumRows);
377 dual_view_type k_numAllocPerRow (
"Tpetra::CrsGraph::numAllocPerRow",
379 k_numAllocPerRow.template modify<host_type> ();
381 k_numAllocPerRow.template sync<execution_space> ();
389 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
391 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
392 const Teuchos::RCP<const map_type>& colMap,
393 const typename local_graph_type::row_map_type& rowPointers,
394 const typename local_graph_type::entries_type::non_const_type& columnIndices,
395 const Teuchos::RCP<Teuchos::ParameterList>& params) :
403 , nodeNumAllocated_(OrdinalTraits<size_t>::invalid())
407 , indicesAreAllocated_(true)
408 , indicesAreLocal_(true)
409 , indicesAreGlobal_(false)
410 , fillComplete_(false)
423 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
425 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
426 const Teuchos::RCP<const map_type>& colMap,
427 const Teuchos::ArrayRCP<size_t>& rowPointers,
428 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
429 const Teuchos::RCP<Teuchos::ParameterList>& params) :
436 , nodeNumEntries_ (0)
437 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
441 , indicesAreAllocated_ (true)
442 , indicesAreLocal_ (true)
443 , indicesAreGlobal_ (false)
444 , fillComplete_ (false)
457 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
459 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
460 const Teuchos::RCP<const map_type>& colMap,
462 const Teuchos::RCP<Teuchos::ParameterList>& params)
470 , nodeNumEntries_ (0)
471 , nodeNumAllocated_ (
Teuchos::OrdinalTraits<size_t>::invalid ())
475 , indicesAreAllocated_ (true)
476 , indicesAreLocal_ (true)
477 , indicesAreGlobal_ (false)
478 , fillComplete_ (false)
486 using Teuchos::ArrayRCP;
488 using Teuchos::ParameterList;
489 using Teuchos::parameterList;
491 typedef GlobalOrdinal GO;
492 typedef LocalOrdinal LO;
495 const char tfecfFuncName[] =
"CrsGraph(Map,Map,Kokkos::LocalStaticCrsGraph)";
497 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
498 colMap.is_null (), std::runtime_error,
499 ": The input column Map must be nonnull.");
500 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
501 k_local_graph_.numRows () != rowMap->getNodeNumElements (),
503 ": The input row Map and the input local graph need to have the same " 504 "number of rows. The row Map claims " << rowMap->getNodeNumElements ()
505 <<
" row(s), but the local graph claims " << k_local_graph_.numRows ()
514 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
516 ": cannot have 1D data structures allocated.");
517 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
519 ": cannot have 2D data structures allocated.");
534 typename local_graph_type::row_map_type d_ptrs =
lclGraph_.row_map;
535 typename local_graph_type::entries_type d_inds =
lclGraph_.entries;
540 nodeMaxNumRowEntries_ = 0;
545 for (
size_t localRow = 0; localRow < numLocalRows; ++localRow) {
546 const GO globalRow =
rowMap_->getGlobalElement (localRow);
547 const LO rlcid =
colMap_->getLocalElement (globalRow);
554 if (rlcid != Teuchos::OrdinalTraits<LO>::invalid ()) {
555 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
556 rlcid + 1 >= static_cast<LO> (d_ptrs.dimension_0 ()),
557 std::runtime_error,
": The given row Map and/or column Map is/are " 558 "not compatible with the provided local graph.");
559 if (d_ptrs(rlcid) != d_ptrs(rlcid + 1)) {
560 const size_t smallestCol =
561 static_cast<size_t> (d_inds(d_ptrs(rlcid)));
562 const size_t largestCol =
563 static_cast<size_t> (d_inds(d_ptrs(rlcid + 1)-1));
564 if (smallestCol < localRow) {
567 if (localRow < largestCol) {
570 for (
size_t i = d_ptrs(rlcid); i < d_ptrs(rlcid + 1); ++i) {
571 if (d_inds(i) == rlcid) {
576 nodeMaxNumRowEntries_ =
577 std::max (static_cast<size_t> (d_ptrs(rlcid + 1) - d_ptrs(rlcid)),
578 nodeMaxNumRowEntries_);
583 computeGlobalConstants ();
585 fillComplete_ =
true;
590 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
596 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
597 Teuchos::RCP<const Teuchos::ParameterList>
602 using Teuchos::ParameterList;
603 using Teuchos::parameterList;
605 RCP<ParameterList> params = parameterList (
"Tpetra::CrsGraph");
608 RCP<ParameterList> importSublist = parameterList (
"Import");
621 params->set (
"Import", *importSublist,
"How the Import performs communication.");
627 params->set (
"Export", *importSublist,
"How the Export performs communication.");
633 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
638 Teuchos::RCP<const Teuchos::ParameterList> validParams =
640 params->validateParametersAndSetDefaults (*validParams);
641 this->setMyParamList (params);
645 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
650 return rowMap_->getGlobalNumElements ();
654 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
659 const char tfecfFuncName[] =
"getGlobalNumCols: ";
660 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
662 "The graph does not have a domain Map. You may not call this method in " 668 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
673 return rowMap_.is_null () ?
static_cast<size_t> (0) :
674 rowMap_->getNodeNumElements ();
678 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
683 const char tfecfFuncName[] =
"getNodeNumCols: ";
684 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
686 "The graph does not have a column Map. You may not call this method " 687 "unless the graph has a column Map. This requires either that a custom " 688 "column Map was given to the constructor, or that fillComplete() has " 690 return colMap_.is_null () ?
static_cast<size_t> (0) :
691 colMap_->getNodeNumElements ();
695 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
700 return nodeNumDiags_;
704 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
709 return globalNumDiags_;
713 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
722 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
723 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
731 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
732 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
740 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
741 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
749 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
750 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
757 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
758 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
766 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
767 Teuchos::RCP<const Export<LocalOrdinal, GlobalOrdinal, Node> >
775 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
784 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
792 const bool isOpt = indicesAreAllocated_ &&
796 #ifdef HAVE_TPETRA_DEBUG 797 const char tfecfFuncName[] =
"isStorageOptimized";
798 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
800 ": The matrix claims to have optimized storage, but getProfileType() " 801 "returns DynamicProfile. This should never happen. Please report this " 802 "bug to the Tpetra developers.");
803 #endif // HAVE_TPETRA_DEBUG 809 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
818 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
823 return globalNumEntries_;
827 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
832 return nodeNumEntries_;
836 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
841 return globalMaxNumRowEntries_;
845 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
850 return nodeMaxNumRowEntries_;
854 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
859 return fillComplete_;
863 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
868 return ! fillComplete_;
872 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
881 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
890 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
895 return indicesAreLocal_;
899 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
904 return indicesAreGlobal_;
908 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
913 return nodeNumAllocated_;
917 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
918 Teuchos::RCP<const Teuchos::Comm<int> >
926 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
931 return rowMap_->getIndexBase ();
935 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
940 return indicesAreAllocated_;
944 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
953 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
962 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
981 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
987 using Teuchos::Array;
988 using Teuchos::ArrayRCP;
989 typedef Teuchos::ArrayRCP<size_t>::size_type size_type;
990 typedef typename local_graph_type::row_map_type::non_const_type
991 non_const_row_map_type;
992 typedef typename local_graph_type::entries_type::non_const_type
994 typedef Kokkos::View<GlobalOrdinal*,
995 typename lcl_col_inds_type::array_layout,
997 const char tfecfFuncName[] =
"allocateIndices: ";
1002 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1004 "The graph is locally indexed, but Tpetra code is calling this method " 1005 "with lg=GlobalIndices. Please report this bug to the Tpetra developers.");
1006 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1008 "The graph is globally indexed, but Tpetra code is calling this method " 1009 "with lg=LocalIndices. Please report this bug to the Tpetra developers.");
1010 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1011 indicesAreAllocated (), std::logic_error,
"The graph's indices are " 1012 "already allocated, but Tpetra code is calling allocateIndices) again. " 1013 "Please report this bug to the Tpetra developers.");
1021 non_const_row_map_type k_rowPtrs (
"Tpetra::CrsGraph::ptr", numRows + 1);
1028 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1030 "k_numAllocPerRow_ is allocated (has length != 0), but its length = " 1037 typename Kokkos::DualView<const size_t*, execution_space>::t_host h_numAllocPerRow =
1039 bool anyInvalidAllocSizes =
false;
1040 for (
size_t i = 0; i < numRows; ++i) {
1041 size_t allocSize = h_numAllocPerRow(i);
1042 if (allocSize == Teuchos::OrdinalTraits<size_t>::invalid ()) {
1043 anyInvalidAllocSizes =
true;
1046 k_rowPtrs(i+1) = k_rowPtrs(i) + allocSize;
1052 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1053 anyInvalidAllocSizes, std::invalid_argument,
"The input array of " 1054 "allocation sizes per row had at least one invalid (== " 1055 "Teuchos::OrdinalTraits<size_t>::invalid()) entry.");
1062 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1064 std::invalid_argument,
"numAllocForAllRows_ has an invalid value, " 1065 "namely Teuchos::OrdinalTraits<size_t>::invalid() = " <<
1066 Teuchos::OrdinalTraits<size_t>::invalid () <<
".");
1071 for (
size_t i = 0; i < numRows; ++i) {
1081 const size_type numInds =
static_cast<size_type
> (
k_rowPtrs_(numRows));
1082 if (lg == LocalIndices) {
1083 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1086 k_gblInds1D_ = gbl_col_inds_type (
"Tpetra::CrsGraph::ind", numInds);
1088 nodeNumAllocated_ = numInds;
1098 typename Kokkos::DualView<const size_t*, execution_space>::t_host h_numAllocPerRow =
1102 if (lg == LocalIndices) {
1103 lclInds2D_ = arcp<Array<LocalOrdinal> > (numRows);
1104 nodeNumAllocated_ = 0;
1105 for (
size_t i = 0; i < numRows; ++i) {
1106 const size_t howMany = useNumAllocPerRow ?
1108 nodeNumAllocated_ += howMany;
1115 gblInds2D_ = arcp<Array<GlobalOrdinal> > (numRows);
1116 nodeNumAllocated_ = 0;
1117 for (
size_t i = 0; i < numRows; ++i) {
1118 const size_t howMany = useNumAllocPerRow ?
1120 nodeNumAllocated_ += howMany;
1129 indicesAreLocal_ = (lg == LocalIndices);
1130 indicesAreGlobal_ = (lg == GlobalIndices);
1134 t_numRowEntries_ (
"Tpetra::CrsGraph::numRowEntries", numRows);
1139 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1141 std::fill (hostPtr, hostPtr + numRows, static_cast<size_t> (0));
1148 indicesAreAllocated_ =
true;
1153 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1155 Teuchos::ArrayRCP<Teuchos::Array<T> >
1159 using Teuchos::arcp;
1160 using Teuchos::Array;
1161 using Teuchos::ArrayRCP;
1162 const char tfecfFuncName[] =
"allocateValues2D: ";
1163 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1164 ! indicesAreAllocated (), std::runtime_error,
1165 "Graph indices must be allocated before values.");
1166 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1168 "Graph indices must be allocated in a dynamic profile.");
1170 ArrayRCP<Array<T> > values2D;
1174 for (
size_t r = 0; r < numRows; ++r) {
1180 for (
size_t r = 0; r < numRows; ++r) {
1188 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1189 Teuchos::ArrayView<const LocalOrdinal>
1193 using Kokkos::subview;
1195 typedef LocalOrdinal LO;
1196 typedef View<const LO*, execution_space, Kokkos::MemoryUnmanaged> row_view_type;
1198 if (rowinfo.allocSize == 0) {
1199 return Teuchos::ArrayView<const LO> ();
1203 const size_t start = rowinfo.offset1D;
1204 const size_t len = rowinfo.allocSize;
1205 const std::pair<size_t, size_t> rng (start, start + len);
1208 const LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1209 return Teuchos::ArrayView<const LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1211 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1215 return Teuchos::ArrayView<const LO> ();
1221 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1222 Teuchos::ArrayView<LocalOrdinal>
1226 using Kokkos::subview;
1228 typedef LocalOrdinal LO;
1229 typedef View<LO*, execution_space, Kokkos::MemoryUnmanaged> row_view_type;
1231 if (rowinfo.allocSize == 0) {
1232 return Teuchos::ArrayView<LO> ();
1236 const size_t start = rowinfo.offset1D;
1237 const size_t len = rowinfo.allocSize;
1238 const std::pair<size_t, size_t> rng (start, start + len);
1241 LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1242 return Teuchos::ArrayView<LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1244 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1248 return Teuchos::ArrayView<LO> ();
1254 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1255 Teuchos::ArrayView<const GlobalOrdinal>
1259 Teuchos::ArrayView<const GlobalOrdinal> view;
1260 if (rowinfo.allocSize > 0) {
1262 auto rng = std::make_pair (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
1263 view = Kokkos::Compat::getConstArrayView (Kokkos::subview (
k_gblInds1D_, rng));
1265 else if (!
gblInds2D_[rowinfo.localRow].empty()) {
1273 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1274 Teuchos::ArrayView<GlobalOrdinal>
1278 Teuchos::ArrayView<GlobalOrdinal> view;
1279 if (rowinfo.allocSize > 0) {
1281 auto rng = std::make_pair (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
1282 view = Kokkos::Compat::getArrayView (Kokkos::subview (
k_gblInds1D_, rng));
1284 else if (!
gblInds2D_[rowinfo.localRow].empty()) {
1292 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1297 #ifdef HAVE_TPETRA_DEBUG 1298 const char tfecfFuncName[] =
"getRowInfo";
1299 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1300 !
rowMap_->isNodeLocalElement (myRow), std::logic_error,
1301 ": The given (local) row index myRow = " << myRow
1302 <<
" does not belong to the graph's row Map. " 1303 "This probably indicates a bug in Tpetra::CrsGraph or Tpetra::CrsMatrix. " 1304 "Please report this bug to the Tpetra developers.");
1305 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1307 ": Late catch! Graph does not have row info anymore. " 1308 "Error should have been caught earlier. " 1309 "Please report this bug to the Tpetra developers.");
1310 #endif // HAVE_TPETRA_DEBUG 1312 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1314 ret.localRow = myRow;
1315 if (nodeNumAllocated_ != 0 && nodeNumAllocated_ != STINV) {
1323 ret.numEntries = ret.allocSize;
1329 ret.offset1D = STINV;
1339 else if (nodeNumAllocated_ == 0) {
1343 ret.offset1D = STINV;
1345 else if (! indicesAreAllocated ()) {
1352 if (useNumAllocPerRow) {
1358 ret.offset1D = STINV;
1362 TEUCHOS_TEST_FOR_EXCEPT(
true);
1368 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1373 using Teuchos::OrdinalTraits;
1374 typedef LocalOrdinal LO;
1375 typedef GlobalOrdinal GO;
1381 static_assert (
sizeof (GlobalOrdinal) >=
sizeof (LocalOrdinal),
1382 "Tpetra::CrsGraph: sizeof(GlobalOrdinal) must be >= sizeof(LocalOrdinal).");
1385 static_assert (
sizeof (
size_t) >=
sizeof (LocalOrdinal),
1386 "Tpetra::CrsGraph: sizeof(size_t) must be >= sizeof(LocalOrdinal).");
1387 static_assert (
sizeof(GST) >=
sizeof(
size_t),
1388 "Tpetra::CrsGraph: sizeof(Tpetra::global_size_t) must be >= sizeof(size_t).");
1396 const char msg[] =
"Tpetra::CrsGraph: Object cannot be created with the " 1397 "given template arguments: size assumptions are not valid.";
1398 TEUCHOS_TEST_FOR_EXCEPTION(
1399 static_cast<size_t> (OrdinalTraits<LO>::max ()) > OrdinalTraits<size_t>::max (),
1400 std::runtime_error, msg);
1401 TEUCHOS_TEST_FOR_EXCEPTION(
1402 static_cast<GST> (OrdinalTraits<LO>::max ()) > static_cast<GST> (OrdinalTraits<GO>::max ()),
1403 std::runtime_error, msg);
1404 TEUCHOS_TEST_FOR_EXCEPTION(
1405 static_cast<size_t> (OrdinalTraits<GO>::max ()) > OrdinalTraits<GST>::max(),
1406 std::runtime_error, msg);
1407 TEUCHOS_TEST_FOR_EXCEPTION(
1408 OrdinalTraits<size_t>::max () > OrdinalTraits<GST>::max (),
1409 std::runtime_error, msg);
1413 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1417 const SLocalGlobalViews &newInds,
1418 const ELocalGlobal lg,
1419 const ELocalGlobal I)
1421 using Teuchos::ArrayView;
1422 #ifdef HAVE_TPETRA_DEBUG 1423 TEUCHOS_TEST_FOR_EXCEPTION(
1424 lg != GlobalIndices && lg != LocalIndices, std::invalid_argument,
1425 "Tpetra::CrsGraph::insertIndices: lg must be either GlobalIndices or " 1427 #endif // HAVE_TPETRA_DEBUG 1428 size_t numNewInds = 0;
1429 if (lg == GlobalIndices) {
1430 ArrayView<const GlobalOrdinal> new_ginds = newInds.ginds;
1431 numNewInds = new_ginds.size();
1432 if (I == GlobalIndices) {
1434 std::copy(new_ginds.begin(), new_ginds.end(), gind_view.begin()+rowinfo.numEntries);
1436 else if (I == LocalIndices) {
1438 typename ArrayView<const GlobalOrdinal>::iterator in = new_ginds.begin();
1439 const typename ArrayView<const GlobalOrdinal>::iterator stop = new_ginds.end();
1440 typename ArrayView<LocalOrdinal>::iterator out = lind_view.begin()+rowinfo.numEntries;
1441 while (in != stop) {
1442 *out++ =
colMap_->getLocalElement (*in++);
1446 else if (lg == LocalIndices) {
1447 ArrayView<const LocalOrdinal> new_linds = newInds.linds;
1448 numNewInds = new_linds.size();
1449 if (I == LocalIndices) {
1451 std::copy(new_linds.begin(), new_linds.end(), lind_view.begin()+rowinfo.numEntries);
1453 else if (I == GlobalIndices) {
1454 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Tpetra::CrsGraph::" 1455 "insertIndices: the case where the input indices are local and the " 1456 "indices to write are global (lg=LocalIndices, I=GlobalIndices) is " 1457 "not implemented, because it does not make sense." << std::endl <<
1458 "If you have correct local column indices, that means the graph has " 1459 "a column Map. In that case, you should be storing local indices.");
1465 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1469 nodeNumEntries_ += numNewInds;
1475 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1479 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
1481 const char tfecfFuncName[] =
"insertGlobalIndicesImpl";
1484 const size_t numNewInds = indices.size();
1485 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
1486 if (newNumEntries > rowInfo.allocSize) {
1487 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1489 ": new indices exceed statically allocated graph structure.");
1492 size_t newAllocSize = 2*rowInfo.allocSize;
1493 if (newAllocSize < newNumEntries) {
1494 newAllocSize = newNumEntries;
1497 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1502 const size_t numIndsToCopy =
static_cast<size_t> (indices.size ());
1503 const size_t offset = rowInfo.offset1D + rowInfo.numEntries;
1504 for (
size_t k = 0; k < numIndsToCopy; ++k) {
1509 std::copy(indices.begin(), indices.end(),
1510 gblInds2D_[myRow].begin()+rowInfo.numEntries);
1515 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1519 nodeNumEntries_ += numNewInds;
1522 #ifdef HAVE_TPETRA_DEBUG 1525 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1526 chkNewNumEntries != newNumEntries, std::logic_error,
1527 ": Internal logic error. Please contact Tpetra team.");
1533 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1537 const Teuchos::ArrayView<const LocalOrdinal>& indices)
1539 using Kokkos::MemoryUnmanaged;
1540 using Kokkos::subview;
1542 typedef LocalOrdinal LO;
1543 const char* tfecfFuncName (
"insertLocallIndicesImpl");
1546 const size_t numNewInds = indices.size();
1547 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
1548 if (newNumEntries > rowInfo.allocSize) {
1549 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1551 ": new indices exceed statically allocated graph structure.");
1554 size_t newAllocSize = 2*rowInfo.allocSize;
1555 if (newAllocSize < newNumEntries)
1556 newAllocSize = newNumEntries;
1558 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1563 typedef View<const LO*, execution_space, MemoryUnmanaged> input_view_type;
1564 typedef View<LO*, execution_space> row_view_type;
1566 input_view_type inputInds (indices.getRawPtr (), indices.size ());
1567 const size_t start = rowInfo.offset1D + rowInfo.numEntries;
1568 const std::pair<size_t, size_t> rng (start, start + newNumEntries);
1573 std::copy (indices.begin (), indices.end (),
1574 lclInds2D_[myRow].begin () + rowInfo.numEntries);
1579 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1583 nodeNumEntries_ += numNewInds;
1585 #ifdef HAVE_TPETRA_DEBUG 1588 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1589 chkNewNumEntries != newNumEntries, std::logic_error,
1590 ": Internal logic error. Please contact Tpetra team.");
1596 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1597 template <
class Scalar>
1601 const SLocalGlobalViews& newInds,
1602 const Teuchos::ArrayView<Scalar>& oldRowVals,
1603 const Teuchos::ArrayView<const Scalar>& newRowVals,
1604 const ELocalGlobal lg,
1605 const ELocalGlobal I)
1607 #ifdef HAVE_TPETRA_DEBUG 1608 size_t numNewInds = 0;
1611 }
catch (std::exception& e) {
1612 TEUCHOS_TEST_FOR_EXCEPTION(
1613 true, std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1614 "insertIndices threw an exception: " << e.what ());
1616 TEUCHOS_TEST_FOR_EXCEPTION(
1617 numNewInds > static_cast<size_t> (oldRowVals.size ()), std::runtime_error,
1618 "Tpetra::CrsGraph::insertIndicesAndValues: numNewInds (" << numNewInds
1619 <<
") > oldRowVals.size() (" << oldRowVals.size () <<
".");
1621 const size_t numNewInds =
insertIndices (rowInfo, newInds, lg, I);
1622 #endif // HAVE_TPETRA_DEBUG 1624 typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1626 #ifdef HAVE_TPETRA_DEBUG 1627 TEUCHOS_TEST_FOR_EXCEPTION(
1628 rowInfo.numEntries + numNewInds > static_cast<size_t> (oldRowVals.size ()),
1629 std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: rowInfo." 1630 "numEntries (" << rowInfo.numEntries <<
") + numNewInds (" << numNewInds
1631 <<
") > oldRowVals.size() (" << oldRowVals.size () <<
").");
1632 TEUCHOS_TEST_FOR_EXCEPTION(
1633 static_cast<size_type> (numNewInds) > newRowVals.size (),
1634 std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1635 "numNewInds (" << numNewInds <<
") > newRowVals.size() (" 1636 << newRowVals.size () <<
").");
1637 #endif // HAVE_TPETRA_DEBUG 1639 size_type oldInd =
static_cast<size_type
> (rowInfo.numEntries);
1641 #ifdef HAVE_TPETRA_DEBUG 1643 #endif // HAVE_TPETRA_DEBUG 1646 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 1647 #define GCC_VERSION __GNUC__*100+__GNUC_MINOR__*10+__GNUC_PATCHLEVEL__ 1648 #if GCC_VERSION >= 490 1649 #define GCC_WORKAROUND 1652 #ifdef GCC_WORKAROUND 1653 size_type nNI =
static_cast<size_type
>(numNewInds);
1655 memcpy(&oldRowVals[oldInd], &newRowVals[0], nNI*
sizeof(Scalar));
1697 #else // GCC Workaround above 1698 for (size_type newInd = 0; newInd < static_cast<size_type> (numNewInds);
1699 ++newInd, ++oldInd) {
1700 oldRowVals[oldInd] = newRowVals[newInd];
1702 #endif // GCC Workaround 1703 #ifdef HAVE_TPETRA_DEBUG 1705 catch (std::exception& e) {
1706 TEUCHOS_TEST_FOR_EXCEPTION(
1707 true, std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1708 "for loop for copying values threw an exception: " << e.what ());
1710 #endif // HAVE_TPETRA_DEBUG 1714 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1719 if (rowinfo.numEntries > 0) {
1720 Teuchos::ArrayView<LocalOrdinal> inds_view =
1722 std::sort (inds_view.begin (), inds_view.begin () + rowinfo.numEntries);
1727 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1728 template <
class Scalar>
1732 const Teuchos::ArrayView<Scalar>& values)
1734 if (rowinfo.numEntries > 0) {
1735 Teuchos::ArrayView<LocalOrdinal> inds_view =
1737 sort2 (inds_view.begin (), inds_view.begin () + rowinfo.numEntries,
1743 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1748 using Teuchos::ArrayView;
1749 const char tfecfFuncName[] =
"mergeRowIndices: ";
1750 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1752 "optimized, so we shouldn't be merging any indices. " 1753 "Please report this bug to the Tpetra developers.");
1756 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
1757 beg = inds_view.begin();
1758 end = inds_view.begin() + rowinfo.numEntries;
1759 newend = std::unique(beg,end);
1760 const size_t mergedEntries = newend - beg;
1761 #ifdef HAVE_TPETRA_DEBUG 1764 TEUCHOS_TEST_FOR_EXCEPT(
isStorageOptimized () && mergedEntries != rowinfo.numEntries );
1765 #endif // HAVE_TPETRA_DEBUG 1769 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1773 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
1777 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1778 template<
class Scalar>
1782 const Teuchos::ArrayView<Scalar>& rowValues)
1784 using Teuchos::ArrayView;
1785 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
1786 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1788 "method if the graph's storage has already been optimized. Please " 1789 "report this bug to the Tpetra developers.");
1791 typedef typename ArrayView<Scalar>::iterator Iter;
1792 Iter rowValueIter = rowValues.begin ();
1794 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
1797 beg = inds_view.begin();
1798 end = inds_view.begin() + rowinfo.numEntries;
1801 typename ArrayView<LocalOrdinal>::iterator cur = beg + 1;
1802 Iter vcur = rowValueIter + 1;
1803 Iter vend = rowValueIter;
1805 while (cur != end) {
1806 if (*cur != *newend) {
1823 const size_t mergedEntries = newend - beg;
1824 #ifdef HAVE_TPETRA_DEBUG 1827 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1830 ": Merge was incorrect; it eliminated entries from the graph. " 1831 << std::endl <<
"Please report this bug to the Tpetra developers.");
1832 #endif // HAVE_TPETRA_DEBUG 1836 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1840 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
1844 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1848 const Teuchos::RCP<const map_type>& rangeMap)
1862 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1867 using Teuchos::ArrayView;
1868 ArrayView<const LocalOrdinal> colInds = this->
getLocalView (rowinfo);
1873 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1878 Teuchos::ArrayView<const LocalOrdinal> colInds,
1881 typedef typename Teuchos::ArrayView<const LocalOrdinal>::iterator IT;
1884 if (hint < rowinfo.numEntries && colInds[hint] == ind) {
1892 IT beg = colInds.begin ();
1893 IT end = beg + rowinfo.numEntries;
1894 IT ptr = beg + rowinfo.numEntries;
1898 std::pair<IT,IT> p = std::equal_range (beg, end, ind);
1899 if (p.first == p.second) {
1906 ptr = std::find (beg, end, ind);
1913 return static_cast<size_t> (ptr - beg);
1916 return Teuchos::OrdinalTraits<size_t>::invalid ();
1921 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1926 using Teuchos::ArrayView;
1927 typedef typename ArrayView<const GlobalOrdinal>::iterator IT;
1930 if (ind == Teuchos::OrdinalTraits<GlobalOrdinal>::invalid ()) {
1931 return Teuchos::OrdinalTraits<size_t>::invalid ();
1934 ArrayView<const GlobalOrdinal> indices =
getGlobalView (rowinfo);
1938 if (hint < rowinfo.numEntries && indices[hint] == ind) {
1942 IT beg = indices.begin ();
1943 IT end = indices.begin () + rowinfo.numEntries;
1945 const std::pair<IT,IT> p = std::equal_range (beg, end, ind);
1946 if (p.first == p.second) {
1947 return Teuchos::OrdinalTraits<size_t>::invalid ();
1949 return p.first - beg;
1953 const IT loc = std::find (beg, end, ind);
1955 return Teuchos::OrdinalTraits<size_t>::invalid ();
1963 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1968 globalNumEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
1969 globalNumDiags_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
1970 globalMaxNumRowEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
1975 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1980 #ifdef HAVE_TPETRA_DEBUG 1981 const global_size_t GSTI = Teuchos::OrdinalTraits<global_size_t>::invalid ();
1982 const size_t STI = Teuchos::OrdinalTraits<size_t>::invalid ();
1983 const char err[] =
"Tpetra::CrsGraph::checkInternalState: Likely internal " 1984 "logic error. Please contact Tpetra team.";
1989 TEUCHOS_TEST_FOR_EXCEPTION(
rowMap_ == null, std::logic_error, err );
1995 TEUCHOS_TEST_FOR_EXCEPTION(
isStorageOptimized() ==
true && indicesAreAllocated() ==
false, std::logic_error, err );
1999 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
false && ( globalNumEntries_ != GSTI || globalNumDiags_ != GSTI || globalMaxNumRowEntries_ != GSTI ), std::logic_error, err );
2001 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
true && ( globalNumEntries_ == GSTI || globalNumDiags_ == GSTI || globalMaxNumRowEntries_ == GSTI ), std::logic_error, err );
2002 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
true && ( globalNumEntries_ < nodeNumEntries_ || globalNumDiags_ < nodeNumDiags_ || globalMaxNumRowEntries_ < nodeMaxNumRowEntries_ ),
2003 std::logic_error, err );
2005 TEUCHOS_TEST_FOR_EXCEPTION(
2008 std::logic_error, err );
2010 TEUCHOS_TEST_FOR_EXCEPTION(
2011 ! indicesAreAllocated () && (nodeNumAllocated_ != STI ||
2012 nodeNumEntries_ != 0),
2013 std::logic_error, err );
2022 TEUCHOS_TEST_FOR_EXCEPTION(
2026 std::logic_error, err );
2028 TEUCHOS_TEST_FOR_EXCEPTION(
2032 std::logic_error, err );
2037 TEUCHOS_TEST_FOR_EXCEPTION(
2039 indicesAreAllocated () &&
2042 std::logic_error, err );
2047 TEUCHOS_TEST_FOR_EXCEPTION(
2049 indicesAreAllocated () &&
2052 std::logic_error, err );
2055 TEUCHOS_TEST_FOR_EXCEPTION(
2058 std::logic_error, err );
2060 TEUCHOS_TEST_FOR_EXCEPTION(
2062 std::logic_error, err );
2065 TEUCHOS_TEST_FOR_EXCEPTION(
2069 std::logic_error, err);
2071 TEUCHOS_TEST_FOR_EXCEPTION(
2073 std::logic_error, err );
2076 TEUCHOS_TEST_FOR_EXCEPTION(
2077 ! indicesAreAllocated () &&
2081 std::logic_error, err );
2086 TEUCHOS_TEST_FOR_EXCEPTION( (indicesAreLocal_ || indicesAreGlobal_) && ! indicesAreAllocated_, std::logic_error, err );
2088 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreLocal_ ==
true && indicesAreGlobal_ ==
true, std::logic_error, err );
2090 TEUCHOS_TEST_FOR_EXCEPTION(
2092 std::logic_error, err );
2094 TEUCHOS_TEST_FOR_EXCEPTION(
2096 std::logic_error, err );
2098 TEUCHOS_TEST_FOR_EXCEPTION(
2102 std::logic_error, err);
2104 TEUCHOS_TEST_FOR_EXCEPTION(
2108 std::logic_error, err);
2110 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
true && nodeNumAllocated_ == STI, std::logic_error, err );
2112 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
false && nodeNumAllocated_ != STI, std::logic_error, err );
2114 if (indicesAreAllocated()) {
2115 size_t actualNumAllocated = 0;
2127 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2130 TEUCHOS_TEST_FOR_EXCEPTION(
2132 std::logic_error, err);
2135 TEUCHOS_TEST_FOR_EXCEPTION(
2137 static_cast<size_t> (
k_lclInds1D_.dimension_0 ()) != actualNumAllocated,
2138 std::logic_error, err );
2139 TEUCHOS_TEST_FOR_EXCEPTION(
2141 static_cast<size_t> (
k_gblInds1D_.dimension_0 ()) != actualNumAllocated,
2142 std::logic_error, err );
2143 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2146 #endif // HAVE_TPETRA_DEBUG 2150 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2155 using Teuchos::OrdinalTraits;
2156 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2157 if (
hasRowInfo () && lrow != OrdinalTraits<LocalOrdinal>::invalid ()) {
2159 return rowinfo.numEntries;
2161 return OrdinalTraits<size_t>::invalid ();
2166 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2173 return rowinfo.numEntries;
2175 return Teuchos::OrdinalTraits<size_t>::invalid ();
2180 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2185 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2186 if (
hasRowInfo () && lrow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2188 return rowinfo.allocSize;
2190 return Teuchos::OrdinalTraits<size_t>::invalid ();
2195 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2202 return rowinfo.allocSize;
2204 return Teuchos::OrdinalTraits<size_t>::invalid();
2210 template<
class OutputViewType,
class InputViewType>
2215 CopyOffsets (
const OutputViewType& ptr_out,
2216 const InputViewType& ptr_in) :
2221 KOKKOS_INLINE_FUNCTION
void operator () (
const ptrdiff_t& i)
const {
2222 typedef typename OutputViewType::non_const_value_type value_type;
2225 ptr_out_(i) =
static_cast<value_type
> (ptr_in_(i));
2229 OutputViewType ptr_out_;
2230 InputViewType ptr_in_;
2235 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2236 Teuchos::ArrayRCP<const size_t>
2240 using Kokkos::ViewAllocateWithoutInitializing;
2241 using Kokkos::create_mirror_view;
2242 using Teuchos::ArrayRCP;
2243 typedef typename local_graph_type::row_map_type row_map_type;
2244 typedef typename row_map_type::non_const_value_type row_offset_type;
2245 #ifdef HAVE_TPETRA_DEBUG 2246 const char prefix[] =
"Tpetra::CrsGraph::getNodeRowPtrs: ";
2247 const char suffix[] =
" Please report this bug to the Tpetra developers.";
2248 #endif // HAVE_TPETRA_DEBUG 2249 const size_t size =
k_rowPtrs_.dimension_0 ();
2250 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
2253 return ArrayRCP<const size_t> ();
2256 ArrayRCP<const row_offset_type> ptr_rot;
2257 ArrayRCP<const size_t> ptr_st;
2262 typename row_map_type::HostMirror ptr_h = create_mirror_view (
k_rowPtrs_);
2264 #ifdef HAVE_TPETRA_DEBUG 2265 TEUCHOS_TEST_FOR_EXCEPTION(
2266 ptr_h.dimension_0 () !=
k_rowPtrs_.dimension_0 (), std::logic_error,
2267 prefix <<
"size_t == row_offset_type, but ptr_h.dimension_0() = " 2268 << ptr_h.dimension_0 () <<
" != k_rowPtrs_.dimension_0() = " 2270 TEUCHOS_TEST_FOR_EXCEPTION(
2271 same && size != 0 &&
k_rowPtrs_.ptr_on_device () == NULL, std::logic_error,
2272 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2273 << size <<
" != 0, but k_rowPtrs_.ptr_on_device() == NULL." << suffix);
2274 TEUCHOS_TEST_FOR_EXCEPTION(
2275 same && size != 0 && ptr_h.ptr_on_device () == NULL, std::logic_error,
2276 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2277 << size <<
" != 0, but create_mirror_view(k_rowPtrs_).ptr_on_device() " 2278 "== NULL." << suffix);
2279 #endif // HAVE_TPETRA_DEBUG 2280 ptr_rot = Kokkos::Compat::persistingView (ptr_h);
2283 typedef Kokkos::View<size_t*, device_type> ret_view_type;
2284 ret_view_type ptr_d (ViewAllocateWithoutInitializing (
"ptr"), size);
2285 CopyOffsets<ret_view_type, row_map_type> functor (ptr_d,
k_rowPtrs_);
2286 Kokkos::parallel_for (size, functor);
2287 typename ret_view_type::HostMirror ptr_h = create_mirror_view (ptr_d);
2289 ptr_st = Kokkos::Compat::persistingView (ptr_h);
2291 #ifdef HAVE_TPETRA_DEBUG 2292 TEUCHOS_TEST_FOR_EXCEPTION(
2293 same && size != 0 && ptr_rot.is_null (), std::logic_error,
2294 prefix <<
"size_t == row_offset_type and size = " << size
2295 <<
" != 0, but ptr_rot is null." << suffix);
2296 TEUCHOS_TEST_FOR_EXCEPTION(
2297 ! same && size != 0 && ptr_st.is_null (), std::logic_error,
2298 prefix <<
"size_t != row_offset_type and size = " << size
2299 <<
" != 0, but ptr_st is null." << suffix);
2300 #endif // HAVE_TPETRA_DEBUG 2304 #ifdef HAVE_TPETRA_DEBUG 2305 ArrayRCP<const size_t> retval =
2306 Kokkos::Impl::if_c<same,
2307 ArrayRCP<const row_offset_type>,
2308 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2309 TEUCHOS_TEST_FOR_EXCEPTION(
2310 size != 0 && retval.is_null (), std::logic_error,
2311 prefix <<
"size = " << size <<
" != 0, but retval is null." << suffix);
2314 return Kokkos::Impl::if_c<same,
2315 ArrayRCP<const row_offset_type>,
2316 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2317 #endif // HAVE_TPETRA_DEBUG 2321 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2322 Teuchos::ArrayRCP<const LocalOrdinal>
2330 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2334 const Teuchos::ArrayView<LocalOrdinal>&indices,
2335 size_t& numEntries)
const 2337 using Teuchos::ArrayView;
2338 typedef LocalOrdinal LO;
2339 typedef GlobalOrdinal GO;
2341 TEUCHOS_TEST_FOR_EXCEPTION(
2343 "Tpetra::CrsGraph::getLocalRowCopy: The graph is globally indexed and " 2344 "does not have a column Map yet. That means we don't have local indices " 2345 "for columns yet, so it doesn't make sense to call this method. If the " 2346 "graph doesn't have a column Map yet, you should call fillComplete on " 2348 TEUCHOS_TEST_FOR_EXCEPTION(
2350 "Tpetra::CrsGraph::getLocalRowCopy: graph row information was deleted " 2351 "at fillComplete().");
2353 if (!
getRowMap ()->isNodeLocalElement (localRow)) {
2359 const size_t theNumEntries = rowinfo.numEntries;
2361 TEUCHOS_TEST_FOR_EXCEPTION(
2362 static_cast<size_t> (indices.size ()) < theNumEntries,
2364 "Tpetra::CrsGraph::getLocalRowCopy: The given row " << localRow <<
" has " 2365 << theNumEntries <<
" entries, but indices.size() = " << indices.size ()
2366 <<
", which does not suffice to store the row's indices.");
2368 numEntries = theNumEntries;
2372 std::copy (lview.begin (), lview.begin () + numEntries, indices.begin ());
2377 for (
size_t j = 0; j < numEntries; ++j) {
2394 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2398 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2399 size_t& NumIndices)
const 2401 using Teuchos::ArrayView;
2402 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2405 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2411 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2412 lrow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
2414 "GlobalRow (== " << globalRow <<
") does not belong to this process.");
2415 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2417 "Graph row information was deleted at fillComplete().");
2419 NumIndices = rowinfo.numEntries;
2420 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2421 static_cast<size_t> (indices.size ()) < NumIndices, std::runtime_error,
2422 "Specified storage (size==" << indices.size () <<
") does not suffice " 2423 "to hold all entries for this row (NumIndices == " << NumIndices <<
").");
2425 ArrayView<const LocalOrdinal> lview = this->
getLocalView (rowinfo);
2426 for (
size_t j = 0; j < NumIndices; ++j) {
2427 indices[j] =
colMap_->getGlobalElement (lview[j]);
2431 ArrayView<const GlobalOrdinal> gview = this->
getGlobalView (rowinfo);
2432 std::copy (gview.begin (), gview.begin () + NumIndices, indices.begin ());
2437 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2441 Teuchos::ArrayView<const LocalOrdinal>& indices)
const 2443 const char tfecfFuncName[] =
"getLocalRowView: ";
2444 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2446 "currently stored as global indices, so we cannot return a view with " 2447 "local column indices, whether or not the graph has a column Map. If " 2448 "the graph _does_ have a column Map, use getLocalRowCopy() instead.");
2449 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2450 !
hasRowInfo (), std::runtime_error,
"Graph row information was " 2451 "deleted at fillComplete().");
2452 indices = Teuchos::null;
2453 if (
rowMap_->isNodeLocalElement (localRow)) {
2455 if (rowinfo.numEntries > 0) {
2461 indices = indices (0, rowinfo.numEntries);
2464 #ifdef HAVE_TPETRA_DEBUG 2465 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2467 std::logic_error,
": Violated stated post-conditions. Please contact Tpetra team.");
2468 #endif // HAVE_TPETRA_DEBUG 2472 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2476 Teuchos::ArrayView<const GlobalOrdinal>& indices)
const 2478 const char tfecfFuncName[] =
"getGlobalRowView: ";
2479 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2481 "currently stored as local indices, so we cannot return a view with " 2482 "global column indices. Use getGlobalRowCopy() instead.");
2483 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2485 "Graph row information was deleted at fillComplete().");
2489 const LocalOrdinal localRow =
rowMap_->getLocalElement (globalRow);
2490 indices = Teuchos::null;
2491 if (localRow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2493 if (rowInfo.numEntries > 0) {
2494 indices = (this->
getGlobalView (rowInfo)) (0, rowInfo.numEntries);
2497 #ifdef HAVE_TPETRA_DEBUG 2498 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2501 "Violated stated postconditions: indices.size() = " << indices.size ()
2502 <<
" != getNumEntriesInGlobalRow(globalRow=" << globalRow
2504 <<
". Please report this bug to the Tpetra developers.");
2505 #endif // HAVE_TPETRA_DEBUG 2509 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2513 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2515 const char tfecfFuncName[] =
"insertLocalIndices";
2517 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2519 ": requires that fill is active.");
2520 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2522 ": graph indices are global; use insertGlobalIndices().");
2523 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2525 ": cannot insert local indices without a column map.");
2526 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2527 !
rowMap_->isNodeLocalElement (localRow), std::runtime_error,
2528 ": row does not belong to this node.");
2529 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2531 ": graph row information was deleted at fillComplete().");
2532 if (! indicesAreAllocated ()) {
2533 allocateIndices (LocalIndices);
2536 #ifdef HAVE_TPETRA_DEBUG 2542 using Teuchos::Array;
2543 using Teuchos::toString;
2545 typedef typename Teuchos::ArrayView<const LocalOrdinal>::size_type size_type;
2548 Array<LocalOrdinal> badColInds;
2549 bool allInColMap =
true;
2550 for (size_type k = 0; k < indices.size (); ++k) {
2552 allInColMap =
false;
2553 badColInds.push_back (indices[k]);
2556 if (! allInColMap) {
2557 std::ostringstream os;
2558 os <<
"Tpetra::CrsMatrix::insertLocalIndices: You attempted to insert " 2559 "entries in owned row " << localRow <<
", at the following column " 2560 "indices: " << toString (indices) <<
"." << endl;
2561 os <<
"Of those, the following indices are not in the column Map on " 2562 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2563 "the graph has a column Map already, it is invalid to insert entries " 2564 "at those locations.";
2565 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2568 #endif // HAVE_TPETRA_DEBUG 2570 insertLocalIndicesImpl (localRow, indices);
2572 #ifdef HAVE_TPETRA_DEBUG 2573 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2576 ": Violated stated post-conditions. Please contact Tpetra team.");
2581 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2585 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2587 typedef LocalOrdinal LO;
2588 const char tfecfFuncName[] =
"insertLocalIndicesFiltered";
2590 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2592 ": requires that fill is active.");
2593 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2595 ": graph indices are global; use insertGlobalIndices().");
2596 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2597 hasColMap() ==
false, std::runtime_error,
2598 ": cannot insert local indices without a column map.");
2599 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2600 rowMap_->isNodeLocalElement(localRow) ==
false, std::runtime_error,
2601 ": row does not belong to this node.");
2602 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2604 ": graph row information was deleted at fillComplete().");
2605 if (! indicesAreAllocated ()) {
2606 allocateIndices (LocalIndices);
2611 Teuchos::Array<LO> filtered_indices (indices);
2612 SLocalGlobalViews inds_view;
2613 SLocalGlobalNCViews inds_ncview;
2614 inds_ncview.linds = filtered_indices();
2615 const size_t numFilteredEntries =
2616 filterIndices<LocalIndices>(inds_ncview);
2617 inds_view.linds = filtered_indices (0, numFilteredEntries);
2618 insertLocalIndicesImpl(localRow, inds_view.linds);
2621 insertLocalIndicesImpl(localRow, indices);
2623 #ifdef HAVE_TPETRA_DEBUG 2624 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2627 ": Violated stated post-conditions. Please contact Tpetra team.");
2632 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2636 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2638 using Teuchos::ArrayView;
2639 typedef LocalOrdinal LO;
2640 typedef GlobalOrdinal GO;
2641 typedef typename ArrayView<const GO>::size_type size_type;
2642 const char tfecfFuncName[] =
"insertGlobalIndices";
2644 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2646 ": graph indices are local; use insertLocalIndices().");
2647 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2649 ": graph row information was deleted at fillComplete().");
2654 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2656 ": You are not allowed to call this method if fill is not active. " 2657 "If fillComplete has been called, you must first call resumeFill " 2658 "before you may insert indices.");
2659 if (! indicesAreAllocated ()) {
2660 allocateIndices (GlobalIndices);
2662 const LO myRow =
rowMap_->getLocalElement (grow);
2663 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2664 #ifdef HAVE_TPETRA_DEBUG 2672 Array<GO> badColInds;
2673 bool allInColMap =
true;
2674 for (size_type k = 0; k < indices.size (); ++k) {
2676 allInColMap =
false;
2677 badColInds.push_back (indices[k]);
2680 if (! allInColMap) {
2681 std::ostringstream os;
2682 os <<
"Tpetra::CrsGraph::insertGlobalIndices: You attempted to insert " 2683 "entries in owned row " << grow <<
", at the following column " 2684 "indices: " << toString (indices) <<
"." << endl;
2685 os <<
"Of those, the following indices are not in the column Map on " 2686 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2687 "the matrix has a column Map already, it is invalid to insert " 2688 "entries at those locations.";
2689 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2692 #endif // HAVE_TPETRA_DEBUG 2693 insertGlobalIndicesImpl (myRow, indices);
2696 const size_type numIndices = indices.size ();
2700 std::vector<GO>& nonlocalRow =
nonlocals_[grow];
2701 for (size_type k = 0; k < numIndices; ++k) {
2702 nonlocalRow.push_back (indices[k]);
2705 #ifdef HAVE_TPETRA_DEBUG 2706 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2709 ": Violated stated post-conditions. Please contact Tpetra team.");
2714 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2718 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2720 using Teuchos::Array;
2721 using Teuchos::ArrayView;
2722 typedef LocalOrdinal LO;
2723 typedef GlobalOrdinal GO;
2724 const char tfecfFuncName[] =
"insertGlobalIndicesFiltered";
2726 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2728 ": graph indices are local; use insertLocalIndices().");
2729 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2731 ": graph row information was deleted at fillComplete().");
2736 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2738 ": You are not allowed to call this method if fill is not active. " 2739 "If fillComplete has been called, you must first call resumeFill " 2740 "before you may insert indices.");
2741 if (! indicesAreAllocated ()) {
2742 allocateIndices (GlobalIndices);
2744 const LO myRow =
rowMap_->getLocalElement (grow);
2745 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2748 Array<GO> filtered_indices(indices);
2749 SLocalGlobalViews inds_view;
2750 SLocalGlobalNCViews inds_ncview;
2751 inds_ncview.ginds = filtered_indices();
2752 const size_t numFilteredEntries =
2753 filterIndices<GlobalIndices> (inds_ncview);
2754 inds_view.ginds = filtered_indices (0, numFilteredEntries);
2755 insertGlobalIndicesImpl(myRow, inds_view.ginds);
2758 insertGlobalIndicesImpl(myRow, indices);
2762 typedef typename ArrayView<const GO>::size_type size_type;
2763 const size_type numIndices = indices.size ();
2764 for (size_type k = 0; k < numIndices; ++k) {
2768 #ifdef HAVE_TPETRA_DEBUG 2769 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2772 ": Violated stated post-conditions. Please contact Tpetra team.");
2777 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2782 const char tfecfFuncName[] =
"removeLocalIndices: ";
2783 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2784 !
isFillActive (), std::runtime_error,
"requires that fill is active.");
2785 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2787 "cannot remove indices after optimizeStorage() has been called.");
2788 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2790 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2791 !
rowMap_->isNodeLocalElement (lrow), std::runtime_error,
2792 "Local row " << lrow <<
" is not in the row Map on the calling process.");
2793 if (! indicesAreAllocated ()) {
2794 allocateIndices (LocalIndices);
2799 clearGlobalConstants ();
2803 nodeNumEntries_ -= oldNumEntries;
2807 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
2811 #ifdef HAVE_TPETRA_DEBUG 2812 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2814 ! indicesAreAllocated () ||
2816 ": Violated stated post-conditions. Please contact Tpetra team.");
2817 #endif // HAVE_TPETRA_DEBUG 2821 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2825 const typename local_graph_type::entries_type::non_const_type& columnIndices)
2827 const char tfecfFuncName[] =
"setAllIndices: ";
2828 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2830 "The graph must have a column Map before you may call this method.");
2831 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2832 static_cast<size_t> (rowPointers.size ()) != this->
getNodeNumRows () + 1,
2833 std::runtime_error,
"rowPointers.size() = " << rowPointers.size () <<
2834 " != this->getNodeNumRows()+1 = " << (this->
getNodeNumRows () + 1) <<
2840 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2842 std::runtime_error,
"You may not call this method if 1-D data structures " 2843 "are already allocated.");
2845 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2847 std::runtime_error,
"You may not call this method if 2-D data structures " 2848 "are already allocated.");
2852 indicesAreAllocated_ =
true;
2853 indicesAreLocal_ =
true;
2857 nodeNumAllocated_ = localNumEntries;
2858 nodeNumEntries_ = localNumEntries;
2870 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2874 const Teuchos::ArrayRCP<LocalOrdinal>& columnIndices)
2877 typedef typename local_graph_type::row_map_type row_map_type;
2878 typedef typename row_map_type::array_layout layout_type;
2879 typedef typename row_map_type::non_const_value_type row_offset_type;
2880 typedef View<
size_t*, layout_type , Kokkos::HostSpace,
2881 Kokkos::MemoryUnmanaged> input_view_type;
2882 typedef typename row_map_type::non_const_type nc_row_map_type;
2884 const size_t size =
static_cast<size_t> (rowPointers.size ());
2885 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
2886 input_view_type ptr_in (rowPointers.getRawPtr (), size);
2888 nc_row_map_type ptr_rot (
"Tpetra::CrsGraph::ptr", size);
2894 input_view_type ptr_decoy (rowPointers.getRawPtr (), size);
2897 input_view_type>::select (ptr_rot, ptr_decoy),
2902 const bool inHostMemory =
2903 Kokkos::Impl::is_same<
typename row_map_type::memory_space,
2904 Kokkos::HostSpace>::value;
2907 typedef CopyOffsets<nc_row_map_type, input_view_type> functor_type;
2908 functor_type functor (ptr_rot, ptr_in);
2909 Kokkos::parallel_for (size, functor);
2916 View<size_t*, layout_type ,execution_space > ptr_st (
"Tpetra::CrsGraph::ptr", size);
2921 typedef CopyOffsets<nc_row_map_type,
2922 View<size_t*, layout_type, execution_space> > functor_type;
2923 functor_type functor (ptr_rot, ptr_st);
2924 Kokkos::parallel_for (size, functor);
2928 Kokkos::View<LocalOrdinal*, layout_type , execution_space > k_ind =
2929 Kokkos::Compat::getKokkosViewDeepCopy<device_type> (columnIndices ());
2934 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2938 size_t& boundForAllLocalRows,
2939 bool& boundSameForAllLocalRows)
const 2944 Teuchos::ArrayRCP<const size_t> numEntriesPerRow;
2945 size_t numEntriesForAll = 0;
2946 bool allRowsSame =
true;
2948 const ptrdiff_t numRows =
static_cast<ptrdiff_t
> (this->
getNodeNumRows ());
2950 if (! this->indicesAreAllocated ()) {
2953 allRowsSame =
false;
2961 numEntriesPerRow = Kokkos::Compat::persistingView (
k_numRowEntries_.h_view);
2962 allRowsSame =
false;
2964 else if (this->nodeNumAllocated_ == 0) {
2965 numEntriesForAll = 0;
2971 TEUCHOS_TEST_FOR_EXCEPTION(
2973 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 2974 "The graph is not StaticProfile, but storage appears to be optimized. " 2975 "Please report this bug to the Tpetra developers.");
2976 TEUCHOS_TEST_FOR_EXCEPTION(
2977 numRows != 0 &&
k_rowPtrs_.dimension_0 () == 0, std::logic_error,
2978 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 2979 "The graph has " << numRows <<
" (> 0) row" << (numRows != 1 ?
"s" :
"")
2980 <<
" on the calling process, but the k_rowPtrs_ array has zero entries. " 2981 "Please report this bug to the Tpetra developers.");
2983 Teuchos::ArrayRCP<size_t> numEnt;
2985 numEnt = Teuchos::arcp<size_t> (numRows);
2990 bool allRowsReallySame =
false;
2991 for (ptrdiff_t i = 0; i < numRows; ++i) {
2993 if (i != 0 && numEnt[i] != numEnt[i-1]) {
2994 allRowsReallySame =
false;
2997 if (allRowsReallySame) {
2999 numEntriesForAll = 0;
3001 numEntriesForAll = numEnt[1] - numEnt[0];
3006 numEntriesPerRow = numEnt;
3007 allRowsSame =
false;
3011 TEUCHOS_TEST_FOR_EXCEPTION(
3012 numEntriesForAll != 0 && numEntriesPerRow.size () != 0, std::logic_error,
3013 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3014 "numEntriesForAll and numEntriesPerRow are not consistent. The former " 3015 "is nonzero (" << numEntriesForAll <<
"), but the latter has nonzero " 3016 "size " << numEntriesPerRow.size () <<
". " 3017 "Please report this bug to the Tpetra developers.");
3018 TEUCHOS_TEST_FOR_EXCEPTION(
3019 numEntriesForAll != 0 && ! allRowsSame, std::logic_error,
3020 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3021 "numEntriesForAll and allRowsSame are not consistent. The former " 3022 "is nonzero (" << numEntriesForAll <<
"), but the latter is false. " 3023 "Please report this bug to the Tpetra developers.");
3024 TEUCHOS_TEST_FOR_EXCEPTION(
3025 numEntriesPerRow.size () != 0 && allRowsSame, std::logic_error,
3026 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3027 "numEntriesPerRow and allRowsSame are not consistent. The former has " 3028 "nonzero length " << numEntriesForAll <<
", but the latter is true. " 3029 "Please report this bug to the Tpetra developers.");
3031 boundPerLocalRow = numEntriesPerRow;
3032 boundForAllLocalRows = numEntriesForAll;
3033 boundSameForAllLocalRows = allRowsSame;
3038 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3043 using Teuchos::Array;
3045 using Teuchos::Comm;
3046 using Teuchos::gatherAll;
3047 using Teuchos::ireceive;
3048 using Teuchos::isend;
3049 using Teuchos::outArg;
3050 using Teuchos::REDUCE_MAX;
3051 using Teuchos::reduceAll;
3052 using Teuchos::toString;
3053 using Teuchos::waitAll;
3055 using std::make_pair;
3057 typedef GlobalOrdinal GO;
3058 typedef typename std::map<GO, std::vector<GO> >::const_iterator NLITER;
3059 typedef typename Array<GO>::size_type size_type;
3061 const char tfecfFuncName[] =
"globalAssemble";
3062 RCP<const Comm<int> > comm =
getComm();
3064 const int numImages = comm->getSize();
3065 const int myImageID = comm->getRank();
3066 #ifdef HAVE_TPETRA_DEBUG 3067 Teuchos::barrier (*comm);
3068 #endif // HAVE_TPETRA_DEBUG 3070 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( !
isFillActive(), std::runtime_error,
3071 ": requires that fill is active.");
3074 size_t MyNonlocals =
nonlocals_.size(), MaxGlobalNonlocals;
3075 reduceAll (*comm, REDUCE_MAX, MyNonlocals, outArg (MaxGlobalNonlocals));
3076 if (MaxGlobalNonlocals == 0) {
3088 Array<pair<int, GO> > IdsAndRows;
3089 std::map<GO, int> NLR2Id;
3090 Teuchos::SerialDenseMatrix<int, char> globalNeighbors;
3091 Array<int> sendIDs, recvIDs;
3096 std::set<GO> setOfRows;
3098 setOfRows.insert (iter->first);
3101 NLRs.resize (setOfRows.size ());
3102 std::copy (setOfRows.begin (), setOfRows.end (), NLRs.begin ());
3105 Array<int> NLRIds(NLRs.size());
3108 rowMap_->getRemoteIndexList (NLRs (), NLRIds ());
3111 reduceAll<int, int> (*comm, REDUCE_MAX, lclerror, outArg (gblerror));
3112 if (gblerror != 0) {
3113 const int myRank = comm->getRank ();
3114 std::ostringstream os;
3115 os <<
"On one or more processes in the communicator, " 3116 <<
"there were insertions into rows of the graph that do not " 3117 <<
"exist in the row Map on any process in the communicator." 3118 << endl <<
"This process " << myRank <<
" is " 3119 << (lclerror == 0 ?
"not " :
"") <<
"one of those offending " 3120 <<
"processes." << endl;
3121 if (lclerror != 0) {
3125 Array<GO> invalidNonlocalRows;
3126 for (size_type k = 0; k < NLRs.size (); ++k) {
3127 if (NLRIds[k] == -1) {
3128 invalidNonlocalRows.push_back (NLRs[k]);
3131 const size_type numInvalid = invalidNonlocalRows.size ();
3132 os <<
"On this process, " << numInvalid <<
" nonlocal row" 3133 << (numInvalid != 1 ?
"s " :
" ") <<
" were inserted that are " 3134 <<
"not in the row Map on any process." << endl;
3136 if (numInvalid <= 100) {
3137 os <<
"Offending row indices: " 3138 << toString (invalidNonlocalRows ()) << endl;
3141 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3142 gblerror != 0, std::runtime_error,
3143 ": nonlocal entries correspond to invalid rows." 3144 << endl << os.str ());
3151 IdsAndRows.reserve(NLRs.size());
3152 Array<char> localNeighbors(numImages, 0);
3153 typename Array<GO>::const_iterator nlr;
3154 typename Array<int>::const_iterator id;
3155 for (nlr = NLRs.begin(),
id = NLRIds.begin();
3156 nlr != NLRs.end(); ++nlr, ++id) {
3158 localNeighbors[*id] = 1;
3160 IdsAndRows.push_back(make_pair(*
id,*nlr));
3162 for (
int j=0; j<numImages; ++j) {
3163 if (localNeighbors[j]) {
3164 sendIDs.push_back(j);
3168 std::sort(IdsAndRows.begin(),IdsAndRows.end());
3170 globalNeighbors.shapeUninitialized(numImages,numImages);
3171 gatherAll (*
getComm(), numImages, localNeighbors.getRawPtr(),
3172 numImages * numImages, globalNeighbors.values());
3184 for (
int j=0; j<numImages; ++j) {
3185 if (globalNeighbors(myImageID,j)) {
3186 recvIDs.push_back(j);
3189 const size_t numRecvs = recvIDs.size();
3194 Array<pair<GO, GO> > IJSendBuffer;
3195 Array<size_t> sendSizes(sendIDs.size(), 0);
3196 size_t numSends = 0;
3197 for (
typename Array<pair<int, GO> >::const_iterator IdAndRow = IdsAndRows.begin();
3198 IdAndRow != IdsAndRows.end(); ++IdAndRow) {
3199 int id = IdAndRow->first;
3200 GO row = IdAndRow->second;
3202 if (sendIDs[numSends] !=
id) {
3204 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(sendIDs[numSends] !=
id,
3205 std::logic_error,
": internal logic error. Contact Tpetra team.");
3208 for (
typename std::vector<GO>::const_iterator j =
nonlocals_[row].begin ();
3210 IJSendBuffer.push_back (pair<GlobalOrdinal, GlobalOrdinal> (row, *j));
3211 sendSizes[numSends]++;
3214 if (IdsAndRows.size() > 0) {
3217 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3218 as<
typename Array<int>::size_type> (numSends) != sendIDs.size (),
3219 std::logic_error,
": internal logic error. Contact Tpetra team.");
3231 Array<RCP<Teuchos::CommRequest<int> > > requests;
3234 for (
size_t s = 0; s < numSends ; ++s) {
3237 requests.push_back (isend<int, size_t> (*comm,
3238 rcp (&sendSizes[s],
false),
3242 Array<size_t> recvSizes (numRecvs);
3243 for (
size_t r = 0; r < numRecvs; ++r) {
3246 requests.push_back (ireceive (*comm, rcp (&recvSizes[r],
false), recvIDs[r]));
3249 if (! requests.empty()) {
3250 waitAll (*comm, requests());
3252 #ifdef HAVE_TPETRA_DEBUG 3253 Teuchos::barrier (*comm);
3254 #endif // HAVE_TPETRA_DEBUG 3257 requests.resize (0);
3263 Array<ArrayView<pair<GO,GO> > > sendBuffers(numSends,null);
3266 for (
size_t s=0; s<numSends; ++s) {
3267 sendBuffers[s] = IJSendBuffer(cur,sendSizes[s]);
3268 cur += sendSizes[s];
3272 for (
size_t s=0; s < numSends ; ++s)
3276 ArrayRCP<pair<GO,GO> > tmpSendBuf =
3277 arcp (sendBuffers[s].getRawPtr(), 0, sendBuffers[s].size(),
false);
3278 requests.push_back (isend<
int, pair<GO,GO> > (*comm, tmpSendBuf, sendIDs[s]));
3282 size_t totalRecvSize = std::accumulate (recvSizes.begin(), recvSizes.end(), 0);
3283 Array<pair<GO,GO> > IJRecvBuffer (totalRecvSize);
3285 Array<ArrayView<pair<GO,GO> > > recvBuffers (numRecvs, null);
3288 for (
size_t r=0; r<numRecvs; ++r) {
3289 recvBuffers[r] = IJRecvBuffer(cur,recvSizes[r]);
3290 cur += recvSizes[r];
3294 for (
size_t r = 0; r < numRecvs; ++r) {
3297 ArrayRCP<pair<GO,GO> > tmpRecvBuf =
3298 arcp (recvBuffers[r].getRawPtr(), 0, recvBuffers[r].size(),
false);
3299 requests.push_back (ireceive (*comm, tmpRecvBuf, recvIDs[r]));
3302 if (! requests.empty()) {
3303 waitAll (*comm, requests());
3305 #ifdef HAVE_TPETRA_DEBUG 3306 Teuchos::barrier (*comm);
3307 #endif // HAVE_TPETRA_DEBUG 3317 for (
typename Array<pair<GO,GO> >::const_iterator ij = IJRecvBuffer.begin();
3318 ij != IJRecvBuffer.end(); ++ij)
3326 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3331 const char tfecfFuncName[] =
"resumeFill";
3332 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
hasRowInfo(), std::runtime_error,
3333 ": Sorry, you cannot resume fill of the CrsGraph, since the graph's row " 3334 "information was deleted in fillComplete().");
3336 #ifdef HAVE_TPETRA_DEBUG 3337 Teuchos::barrier( *
rowMap_->getComm() );
3338 #endif // HAVE_TPETRA_DEBUG 3339 clearGlobalConstants();
3346 fillComplete_ =
false;
3347 #ifdef HAVE_TPETRA_DEBUG 3348 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3350 "::resumeFill(): At end of method, either fill is not active or fill is " 3351 "complete. This violates stated post-conditions. Please report this bug " 3352 "to the Tpetra developers.");
3353 #endif // HAVE_TPETRA_DEBUG 3357 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3372 Teuchos::RCP<const map_type> domMap = this->
getDomainMap ();
3373 if (domMap.is_null ()) {
3376 Teuchos::RCP<const map_type> ranMap = this->
getRangeMap ();
3377 if (ranMap.is_null ()) {
3384 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3388 const Teuchos::RCP<const map_type>& rangeMap,
3389 const Teuchos::RCP<Teuchos::ParameterList>& params)
3391 const char tfecfFuncName[] =
"fillComplete";
3393 #ifdef HAVE_TPETRA_DEBUG 3394 rowMap_->getComm ()->barrier ();
3395 #endif // HAVE_TPETRA_DEBUG 3398 std::runtime_error,
": Graph fill state must be active (isFillActive() " 3399 "must be true) before calling fillComplete().");
3401 const int numProcs =
getComm ()->getSize ();
3409 if (! params.is_null ()) {
3410 if (params->isParameter (
"sort column map ghost gids")) {
3412 params->get<
bool> (
"sort column map ghost gids",
3415 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3417 params->get<
bool> (
"Sort column Map ghost GIDs",
3424 bool assertNoNonlocalInserts =
false;
3425 if (! params.is_null ()) {
3426 assertNoNonlocalInserts =
3427 params->get<
bool> (
"No Nonlocal Changes", assertNoNonlocalInserts);
3433 if (! indicesAreAllocated ()) {
3436 allocateIndices (LocalIndices);
3439 allocateIndices (GlobalIndices);
3447 const bool mayNeedGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3448 if (mayNeedGlobalAssemble) {
3454 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3455 numProcs > 1 &&
nonlocals_.size() > 0, std::runtime_error,
3456 ":" << std::endl <<
"The graph's communicator contains only one " 3457 "process, but there are nonlocal entries. " << std::endl <<
3458 "This probably means that invalid entries were added to the graph.");
3475 makeIndicesLocal ();
3487 makeImportExport ();
3488 computeGlobalConstants ();
3489 fillLocalGraph (params);
3490 fillComplete_ =
true;
3492 #ifdef HAVE_TPETRA_DEBUG 3493 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3495 ": Violated stated post-conditions. Please contact Tpetra team.");
3502 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3506 const Teuchos::RCP<const map_type>& rangeMap,
3507 const Teuchos::RCP<const import_type>& importer,
3508 const Teuchos::RCP<const export_type>& exporter,
3509 const Teuchos::RCP<Teuchos::ParameterList>& params)
3511 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
3512 #ifdef HAVE_TPETRA_MMM_TIMINGS 3514 if(!params.is_null())
3515 label = params->get(
"Timer Label",label);
3516 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
3517 using Teuchos::TimeMonitor;
3518 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Setup"))));
3522 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3523 domainMap.is_null () || rangeMap.is_null (),
3524 std::runtime_error,
"The input domain Map and range Map must be nonnull.");
3525 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3527 "method unless the graph is StaticProfile.");
3528 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3530 "call this method unless the graph has a column Map.");
3531 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3533 std::runtime_error,
"The calling process has getNodeNumRows() = " 3534 <<
getNodeNumRows () <<
" > 0 rows, but the row offsets array has not " 3536 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3538 std::runtime_error,
"The row offsets array has length " <<
3539 k_rowPtrs_.dimension_0 () <<
" != getNodeNumRows()+1 = " <<
3551 nodeNumEntries_ = nodeNumAllocated_;
3565 indicesAreAllocated_ =
true;
3570 indicesAreLocal_ =
true;
3571 indicesAreGlobal_ =
false;
3574 #ifdef HAVE_TPETRA_MMM_TIMINGS 3575 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Maps"))));
3584 #ifdef HAVE_TPETRA_MMM_TIMINGS 3585 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckI"))));
3590 if (importer != Teuchos::null) {
3591 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3592 ! importer->getSourceMap ()->isSameAs (*
getDomainMap ()) ||
3593 ! importer->getTargetMap ()->isSameAs (*
getColMap ()),
3594 std::invalid_argument,
": importer does not match matrix maps.");
3599 #ifdef HAVE_TPETRA_MMM_TIMINGS 3600 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckE"))));
3603 if (exporter != Teuchos::null) {
3604 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3605 ! exporter->getSourceMap ()->isSameAs (*
getRowMap ()) ||
3606 ! exporter->getTargetMap ()->isSameAs (*
getRangeMap ()),
3607 std::invalid_argument,
": exporter does not match matrix maps.");
3611 #ifdef HAVE_TPETRA_MMM_TIMINGS 3612 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXmake"))));
3615 makeImportExport ();
3618 #ifdef HAVE_TPETRA_MMM_TIMINGS 3619 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cGC"))));
3621 computeGlobalConstants ();
3624 #ifdef HAVE_TPETRA_MMM_TIMINGS 3625 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-fLG"))));
3627 fillLocalGraph (params);
3628 fillComplete_ =
true;
3630 #ifdef HAVE_TPETRA_MMM_TIMINGS 3631 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cIS"))));
3637 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3640 fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params)
3642 using Kokkos::create_mirror_view;
3643 using Teuchos::ArrayRCP;
3644 using Teuchos::null;
3647 typedef ArrayRCP<size_t>::size_type size_type;
3648 typedef t_numRowEntries_ row_entries_type;
3649 typedef typename local_graph_type::row_map_type row_map_type;
3650 typedef typename row_map_type::non_const_type non_const_row_map_type;
3651 typedef typename local_graph_type::entries_type::non_const_type lclinds_1d_type;
3660 non_const_row_map_type k_ptrs;
3661 row_map_type k_ptrs_const;
3662 lclinds_1d_type k_inds;
3669 typename row_entries_type::t_host h_numRowEnt = k_numRowEnt.h_view;
3671 bool requestOptimizedStorage =
true;
3672 if (! params.is_null () && ! params->get (
"Optimize Storage",
true)) {
3673 requestOptimizedStorage =
false;
3683 TEUCHOS_TEST_FOR_EXCEPTION(
3684 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
3685 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph (called from " 3686 "fillComplete or expertStaticFillComplete): For the DynamicProfile " 3687 "branch, k_numRowEnt has the wrong length. " 3688 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
3689 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3697 size_t lclTotalNumEntries = 0;
3699 typename non_const_row_map_type::HostMirror h_ptrs;
3702 k_ptrs = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows+1);
3703 k_ptrs_const = k_ptrs;
3707 h_ptrs = create_mirror_view (k_ptrs);
3709 for (size_type i = 0; i < static_cast<size_type> (lclNumRows); ++i) {
3710 const size_t numEnt = h_numRowEnt(i);
3711 lclTotalNumEntries += numEnt;
3712 h_ptrs(i+1) = h_ptrs(i) + numEnt;
3717 TEUCHOS_TEST_FOR_EXCEPTION(
3718 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
3719 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile " 3720 "branch, after packing k_ptrs, k_ptrs.dimension_0() = " 3721 << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 3722 << (lclNumRows+1) <<
".");
3723 TEUCHOS_TEST_FOR_EXCEPTION(
3724 static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
3725 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile " 3726 "branch, after packing h_ptrs, h_ptrs.dimension_0() = " 3727 << h_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 3728 << (lclNumRows+1) <<
".");
3730 TEUCHOS_TEST_FOR_EXCEPTION(
3731 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
3732 "Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile branch, after " 3733 "packing k_ptrs, k_ptrs(lclNumRows = " << lclNumRows <<
") = " <<
3734 k_ptrs(lclNumRows) <<
" != total number of entries on the calling " 3735 "process = " << lclTotalNumEntries <<
".");
3738 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3740 typename lclinds_1d_type::HostMirror h_inds = create_mirror_view (k_inds);
3742 for (
size_t row = 0; row < lclNumRows; ++row) {
3743 const size_t numEnt = h_numRowEnt(row);
3746 h_inds.ptr_on_device () + h_ptrs(row));
3751 if (k_ptrs.dimension_0 () != 0) {
3752 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
3753 TEUCHOS_TEST_FOR_EXCEPTION(
3754 static_cast<size_t> (k_ptrs(numOffsets-1)) != k_inds.dimension_0 (),
3755 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 3756 "In DynamicProfile branch, after packing, k_ptrs(" << (numOffsets-1)
3757 <<
") = " << k_ptrs(numOffsets-1) <<
" != k_inds.dimension_0() = " 3758 << k_inds.dimension_0 () <<
".");
3768 TEUCHOS_TEST_FOR_EXCEPTION(
3769 k_rowPtrs_.dimension_0 () == 0, std::logic_error,
3770 "k_rowPtrs_ has size zero, but shouldn't");
3771 TEUCHOS_TEST_FOR_EXCEPTION(
3772 k_rowPtrs_.dimension_0 () != lclNumRows + 1, std::logic_error,
3773 "Tpetra::CrsGraph::fillLocalGraph: k_rowPtrs_ has size " 3774 <<
k_rowPtrs_.dimension_0 () <<
" != (lclNumRows + 1) = " 3775 << (lclNumRows + 1) <<
".")
3777 const size_t numOffsets =
k_rowPtrs_.dimension_0 ();
3779 TEUCHOS_TEST_FOR_EXCEPTION(
3782 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 3783 "numOffsets = " << numOffsets <<
" != 0 and " 3784 "k_lclInds1D_.dimension_0() = " <<
k_lclInds1D_.dimension_0 ()
3785 <<
" != k_rowPtrs_(" << numOffsets <<
") = " 3789 if (nodeNumEntries_ != nodeNumAllocated_) {
3796 TEUCHOS_TEST_FOR_EXCEPTION(
3797 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
3798 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph (called from " 3799 "fillComplete or expertStaticFillComplete): In StaticProfile " 3800 "unpacked branch, k_numRowEnt has the wrong length. " 3801 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
3802 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3805 const size_t numOffsets =
3806 static_cast<size_t> (
k_rowPtrs_.dimension_0 ());
3807 TEUCHOS_TEST_FOR_EXCEPTION(
3809 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 3810 "In StaticProfile branch, before allocating or packing, " 3811 "k_rowPtrs_(" << (numOffsets-1) <<
") = " 3812 <<
k_rowPtrs_(numOffsets-1) <<
" != k_lclInds1D_.dimension_0() = " 3822 size_t lclTotalNumEntries = 0;
3825 k_ptrs = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
3826 k_ptrs_const = k_ptrs;
3833 typename non_const_row_map_type::HostMirror h_k_ptrs =
3834 create_mirror_view (k_ptrs);
3836 for (
size_t i = 0; i < lclNumRows; ++i) {
3837 const size_t numEnt = h_numRowEnt(i);
3838 lclTotalNumEntries += numEnt;
3839 h_k_ptrs(i+1) = h_k_ptrs(i) + numEnt;
3844 TEUCHOS_TEST_FOR_EXCEPTION(
3845 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
3846 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In " 3847 "StaticProfile unpacked branch, after allocating k_ptrs, " 3848 "k_ptrs.dimension_0() = " << k_ptrs.dimension_0 () <<
" != " 3849 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
3851 TEUCHOS_TEST_FOR_EXCEPTION(
3852 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
3853 "Tpetra::CrsGraph::fillLocalGraph: In StaticProfile unpacked " 3854 "branch, after filling k_ptrs, k_ptrs(lclNumRows=" << lclNumRows
3855 <<
") = " << k_ptrs(lclNumRows) <<
" != total number of entries on " 3856 "the calling process = " << lclTotalNumEntries <<
".");
3859 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3871 typedef pack_functor<typename local_graph_type::entries_type::non_const_type, row_map_type> inds_packer_type;
3873 Kokkos::parallel_for (lclNumRows, f);
3875 TEUCHOS_TEST_FOR_EXCEPTION(
3876 k_ptrs.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsGraph::" 3877 "fillLocalGraph: In StaticProfile \"Optimize Storage\" = true branch," 3878 " after packing, k_ptrs.dimension_0() = 0. This probably means that " 3879 "k_rowPtrs_ was never allocated.");
3880 if (k_ptrs.dimension_0 () != 0) {
3881 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
3882 TEUCHOS_TEST_FOR_EXCEPTION(
3883 static_cast<size_t> (k_ptrs(numOffsets - 1)) != k_inds.dimension_0 (),
3884 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 3885 "In StaticProfile \"Optimize Storage\"=true branch, after packing, " 3886 "k_ptrs(" << (numOffsets-1) <<
") = " << k_ptrs(numOffsets-1) <<
3887 " != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
3894 TEUCHOS_TEST_FOR_EXCEPTION(
3895 k_ptrs_const.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsGraph::" 3896 "fillLocalGraph: In StaticProfile \"Optimize Storage\" = " 3897 "false branch, k_ptrs_const.dimension_0() = 0. This probably means that " 3898 "k_rowPtrs_ was never allocated.");
3899 if (k_ptrs_const.dimension_0 () != 0) {
3900 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
3901 TEUCHOS_TEST_FOR_EXCEPTION(
3902 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
3903 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 3904 "In StaticProfile \"Optimize Storage\" = false branch, " 3905 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets - 1)
3906 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
3912 TEUCHOS_TEST_FOR_EXCEPTION(
3913 static_cast<size_t> (k_ptrs_const.dimension_0 ()) != lclNumRows + 1,
3914 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: After packing, " 3915 "k_ptrs_const.dimension_0() = " << k_ptrs_const.dimension_0 ()
3916 <<
" != lclNumRows+1 = " << (lclNumRows+1) <<
".");
3917 if (k_ptrs_const.dimension_0 () != 0) {
3918 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
3919 TEUCHOS_TEST_FOR_EXCEPTION(
3920 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
3921 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: After packing, " 3922 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets-1)
3923 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
3926 if (requestOptimizedStorage) {
3941 nodeNumAllocated_ = nodeNumEntries_;
3960 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3972 const char tfecfFuncName[] =
"replaceColMap: ";
3973 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3975 "Requires matching maps and non-static graph.");
3979 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3983 const Teuchos::RCP<const import_type>& newImport,
3984 const bool sortIndicesInEachRow)
3986 using Teuchos::REDUCE_MIN;
3987 using Teuchos::reduceAll;
3989 typedef GlobalOrdinal GO;
3990 typedef LocalOrdinal LO;
3991 typedef typename local_graph_type::entries_type::non_const_type col_inds_type;
3992 const char tfecfFuncName[] =
"reindexColumns: ";
3994 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3995 isFillComplete (), std::runtime_error,
"The graph is fill complete " 3996 "(isFillComplete() returns true). You must call resumeFill() before " 3997 "you may call this method.");
4030 bool allCurColIndsValid =
true;
4035 bool localSuffices =
true;
4043 typename local_graph_type::entries_type::non_const_type newLclInds1D;
4044 Teuchos::ArrayRCP<Teuchos::Array<LO> > newLclInds2D;
4049 if (indicesAreAllocated ()) {
4055 RCP<node_type> node =
getRowMap ()->getNode ();
4057 col_inds_type (
"Tpetra::CrsGraph::ind", nodeNumAllocated_);
4059 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4061 const size_t beg = rowInfo.offset1D;
4062 const size_t end = beg + rowInfo.numEntries;
4063 for (
size_t k = beg; k < end; ++k) {
4067 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4068 allCurColIndsValid =
false;
4076 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4077 allCurColIndsValid =
false;
4081 const LO newLclCol = newColMap->getLocalElement (gblCol);
4082 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4083 localSuffices =
false;
4088 newLclInds1D(k) = newLclCol;
4097 newLclInds2D = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4100 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4102 newLclInds2D.resize (rowInfo.allocSize);
4104 Teuchos::ArrayView<const LO> oldLclRowView =
getLocalView (rowInfo);
4105 Teuchos::ArrayView<LO> newLclRowView = (newLclInds2D[lclRow]) ();
4107 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4108 const LO oldLclCol = oldLclRowView[k];
4109 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4110 allCurColIndsValid =
false;
4117 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4118 allCurColIndsValid =
false;
4122 const LO newLclCol = newColMap->getLocalElement (gblCol);
4123 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4124 localSuffices =
false;
4127 newLclRowView[k] = newLclCol;
4139 allCurColIndsValid =
false;
4156 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4158 Teuchos::ArrayView<const GO> oldGblRowView =
getGlobalView (rowInfo);
4159 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4160 const GO gblCol = oldGblRowView[k];
4161 if (! newColMap->isNodeGlobalElement (gblCol)) {
4162 localSuffices =
false;
4172 lclSuccess[0] = allCurColIndsValid ? 1 : 0;
4173 lclSuccess[1] = localSuffices ? 1 : 0;
4177 RCP<const Teuchos::Comm<int> > comm =
4179 if (! comm.is_null ()) {
4180 reduceAll<int, int> (*comm, REDUCE_MIN, 2, lclSuccess, gblSuccess);
4183 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4184 gblSuccess[0] == 0, std::runtime_error,
"It is not possible to continue." 4185 " The most likely reason is that the graph is locally indexed, but the " 4186 "column Map is missing (null) on some processes, due to a previous call " 4187 "to replaceColMap().");
4189 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4190 gblSuccess[1] == 0, std::runtime_error,
"On some process, the graph " 4191 "contains column indices that are in the old column Map, but not in the " 4192 "new column Map (on that process). This method does NOT redistribute " 4193 "data; it does not claim to do the work of an Import or Export operation." 4194 " This means that for all processess, the calling process MUST own all " 4195 "column indices, in both the old column Map and the new column Map. In " 4196 "this case, you will need to do an Import or Export operation to " 4197 "redistribute data.");
4213 if (sortIndicesInEachRow) {
4225 if (newImport.is_null ()) {
4247 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4251 const Teuchos::RCP<const import_type>& newImporter)
4253 const char prefix[] =
"Tpetra::CrsGraph::replaceDomainMapAndImporter: ";
4254 TEUCHOS_TEST_FOR_EXCEPTION(
4255 colMap_.is_null (), std::invalid_argument, prefix <<
"You may not call " 4256 "this method unless the graph already has a column Map.");
4257 TEUCHOS_TEST_FOR_EXCEPTION(
4258 newDomainMap.is_null (), std::invalid_argument,
4259 prefix <<
"The new domain Map must be nonnull.");
4261 #ifdef HAVE_TPETRA_DEBUG 4262 if (newImporter.is_null ()) {
4267 const bool colSameAsDom =
colMap_->isSameAs (*newDomainMap);
4268 TEUCHOS_TEST_FOR_EXCEPTION(
4269 colSameAsDom, std::invalid_argument,
"If the new Import is null, " 4270 "then the new domain Map must be the same as the current column Map.");
4273 const bool colSameAsTgt =
4274 colMap_->isSameAs (* (newImporter->getTargetMap ()));
4275 const bool newDomSameAsSrc =
4276 newDomainMap->isSameAs (* (newImporter->getSourceMap ()));
4277 TEUCHOS_TEST_FOR_EXCEPTION(
4278 ! colSameAsTgt || ! newDomSameAsSrc, std::invalid_argument,
"If the " 4279 "new Import is nonnull, then the current column Map must be the same " 4280 "as the new Import's target Map, and the new domain Map must be the " 4281 "same as the new Import's source Map.");
4283 #endif // HAVE_TPETRA_DEBUG 4289 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4297 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4305 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4311 using Teuchos::outArg;
4312 using Teuchos::reduceAll;
4313 typedef LocalOrdinal LO;
4314 typedef GlobalOrdinal GO;
4317 #ifdef HAVE_TPETRA_DEBUG 4318 TEUCHOS_TEST_FOR_EXCEPTION(!
hasColMap(), std::logic_error,
"Tpetra::" 4319 "CrsGraph::computeGlobalConstants: At this point, the graph should have " 4320 "a column Map, but it does not. Please report this bug to the Tpetra " 4322 #endif // HAVE_TPETRA_DEBUG 4340 nodeMaxNumRowEntries_ = 0;
4357 if (indicesAreAllocated () && nodeNumAllocated_ > 0) {
4359 for (
size_t localRow = 0; localRow < numLocalRows; ++localRow) {
4371 typename ArrayView<const LO>::iterator beg, end, cur;
4372 beg = rview.begin();
4373 end = beg + rowInfo.numEntries;
4375 for (cur = beg; cur != end; ++cur) {
4377 if (rlcid == *cur) ++nodeNumDiags_;
4384 const size_t smallestCol =
static_cast<size_t> (*beg);
4385 const size_t largestCol =
static_cast<size_t> (*(end - 1));
4387 if (smallestCol < localRow) {
4390 if (localRow < largestCol) {
4395 nodeMaxNumRowEntries_ = std::max (nodeMaxNumRowEntries_, rowInfo.numEntries);
4418 lcl[0] =
static_cast<GST
> (nodeNumEntries_);
4419 lcl[1] =
static_cast<GST
> (nodeNumDiags_);
4420 reduceAll<int,GST> (*
getComm (), Teuchos::REDUCE_SUM,
4422 globalNumEntries_ = gbl[0];
4423 globalNumDiags_ = gbl[1];
4424 reduceAll<int,GST> (*
getComm (), Teuchos::REDUCE_MAX,
4425 static_cast<GST
> (nodeMaxNumRowEntries_),
4426 outArg (globalMaxNumRowEntries_));
4432 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4437 using Teuchos::arcp;
4438 using Teuchos::Array;
4439 typedef LocalOrdinal LO;
4440 typedef GlobalOrdinal GO;
4441 typedef typename local_graph_type::entries_type::non_const_type
4443 typedef Kokkos::View<GlobalOrdinal*,
4444 typename lcl_col_inds_type::array_layout,
4446 const char tfecfFuncName[] =
"makeIndicesLocal";
4448 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4449 ! this->
hasColMap (), std::logic_error,
": The graph does not have a " 4450 "column Map yet. This method should never be called in that case. " 4451 "Please report this bug to the Tpetra developers.");
4452 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4453 this->
getColMap ().is_null (), std::logic_error,
": The graph claims " 4454 "that it has a column Map, because hasColMap() returns true. However, " 4455 "the result of getColMap() is null. This should never happen. Please " 4456 "report this bug to the Tpetra developers.");
4469 if (nodeNumAllocated_ && Kokkos::Impl::is_same<LO,GO>::value) {
4470 k_lclInds1D_ = Kokkos::Impl::if_c<Kokkos::Impl::is_same<LO,GO>::value,
4475 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4476 k_rowPtrs_.dimension_0 () == 0, std::logic_error,
": This should " 4477 "never happen at this point. Please report this bug to the Tpetra " 4479 const size_t numEnt =
k_rowPtrs_[lclNumRows];
4481 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::lclind", numEnt);
4484 for (
size_t r = 0; r < lclNumRows; ++r) {
4486 const size_t numentry = h_numRowEnt(r);
4487 for (
size_t j = 0; j < numentry; ++j) {
4491 #ifdef HAVE_TPETRA_DEBUG 4492 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4493 k_lclInds1D_(offset + j) == Teuchos::OrdinalTraits<LO>::invalid(),
4495 ": In local row r=" << r <<
", global column " << gid <<
" is " 4496 "not in the column Map. This should never happen. Please " 4497 "report this bug to the Tpetra developers.");
4498 #endif // HAVE_TPETRA_DEBUG 4508 for (
size_t r = 0; r < lclNumRows; ++r) {
4510 const GO*
const ginds =
gblInds2D_[r].getRawPtr ();
4512 const size_t numentry = h_numRowEnt(r);
4514 LO*
const linds =
lclInds2D_[r].getRawPtr ();
4515 for (
size_t j = 0; j < numentry; ++j) {
4516 const GO gid = ginds[j];
4519 #ifdef HAVE_TPETRA_DEBUG 4520 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4521 linds[j] == Teuchos::OrdinalTraits<LO>::invalid(),
4523 ": Global column ginds[j=" << j <<
"]=" << ginds[j]
4524 <<
" of local row r=" << r <<
" is not in the column Map. " 4525 "This should never happen. Please report this bug to the " 4526 "Tpetra developers.");
4527 #endif // HAVE_TPETRA_DEBUG 4536 indicesAreLocal_ =
true;
4537 indicesAreGlobal_ =
false;
4542 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4561 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4566 using Teuchos::Array;
4567 using Teuchos::ArrayView;
4569 using Teuchos::REDUCE_MAX;
4570 using Teuchos::reduceAll;
4572 typedef LocalOrdinal LO;
4573 typedef GlobalOrdinal GO;
4574 const char tfecfFuncName[] =
"makeColMap";
4582 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4584 ": The graph is locally indexed. Calling makeColMap() to make the " 4585 "column Map requires that the graph be globally indexed.");
4590 Array<GO> myColumns;
4620 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
4621 size_t numLocalColGIDs = 0, numRemoteColGIDs = 0;
4625 Array<char> GIDisLocal (
domainMap_->getNodeNumElements (), 0);
4626 std::set<GO> RemoteGIDSet;
4628 std::vector<GO> RemoteGIDUnorderedVector;
4630 for (
size_t r = 0; r < myNumRows; ++r) {
4632 if (rowinfo.numEntries > 0) {
4639 rowGids = rowGids (0, rowinfo.numEntries);
4641 for (
size_t k = 0; k < rowinfo.numEntries; ++k) {
4642 const GO gid = rowGids[k];
4643 const LO lid =
domainMap_->getLocalElement (gid);
4645 const char alreadyFound = GIDisLocal[lid];
4646 if (alreadyFound == 0) {
4647 GIDisLocal[lid] =
static_cast<char> (1);
4652 const bool notAlreadyFound = RemoteGIDSet.insert (gid).second;
4653 if (notAlreadyFound) {
4661 RemoteGIDUnorderedVector.push_back (gid);
4699 if (
domainMap_->getComm ()->getSize () == 1) {
4700 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4701 numRemoteColGIDs != 0, std::runtime_error,
4702 ": " << numRemoteColGIDs <<
" column " 4703 << (numRemoteColGIDs != 1 ?
"indices are" :
"index is")
4704 <<
" not in the domain Map." << endl
4705 <<
"Either these indices are invalid or the domain Map is invalid." 4706 << endl <<
"Remember that nonsquare matrices, or matrices where the " 4707 "row and range Maps are different, require calling the version of " 4708 "fillComplete that takes the domain and range Maps as input.");
4709 if (numLocalColGIDs ==
domainMap_->getNodeNumElements()) {
4720 myColumns.resize (numLocalColGIDs + numRemoteColGIDs);
4722 ArrayView<GO> LocalColGIDs = myColumns (0, numLocalColGIDs);
4723 ArrayView<GO> RemoteColGIDs = myColumns (numLocalColGIDs, numRemoteColGIDs);
4728 std::copy (RemoteGIDSet.begin(), RemoteGIDSet.end(),
4729 RemoteColGIDs.begin());
4732 std::copy (RemoteGIDUnorderedVector.begin(),
4733 RemoteGIDUnorderedVector.end(), RemoteColGIDs.begin());
4737 Array<int> RemoteImageIDs (numRemoteColGIDs);
4741 domainMap_->getRemoteIndexList (RemoteColGIDs, RemoteImageIDs ());
4742 #ifdef HAVE_TPETRA_DEBUG 4750 const int missingID_lcl = (stat ==
IDNotPresent ? 1 : 0);
4751 int missingID_gbl = 0;
4752 reduceAll<int, int> (*
getComm (), REDUCE_MAX, missingID_lcl,
4753 outArg (missingID_gbl));
4754 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4755 missingID_gbl == 1, std::runtime_error,
4756 ": Some column indices are not in the domain Map." << endl
4757 <<
"Either these column indices are invalid or the domain Map is " 4758 "invalid." << endl <<
"Likely cause: For a nonsquare matrix, you " 4759 "must give the domain and range Maps as input to fillComplete.");
4762 #endif // HAVE_TPETRA_DEBUG 4772 sort2 (RemoteImageIDs.begin(), RemoteImageIDs.end(), RemoteColGIDs.begin());
4784 const size_t numDomainElts =
domainMap_->getNodeNumElements ();
4785 if (numLocalColGIDs == numDomainElts) {
4795 GO curColMapGid =
domainMap_->getMinGlobalIndex ();
4796 for (
size_t k = 0; k < numLocalColGIDs; ++k, ++curColMapGid) {
4797 LocalColGIDs[k] = curColMapGid;
4801 ArrayView<const GO> domainElts =
domainMap_->getNodeElementList ();
4802 std::copy (domainElts.begin(), domainElts.end(), LocalColGIDs.begin());
4808 size_t numLocalCount = 0;
4815 GO curColMapGid =
domainMap_->getMinGlobalIndex ();
4816 for (
size_t i = 0; i < numDomainElts; ++i, ++curColMapGid) {
4817 if (GIDisLocal[i]) {
4818 LocalColGIDs[numLocalCount++] = curColMapGid;
4823 ArrayView<const GO> domainElts =
domainMap_->getNodeElementList ();
4824 for (
size_t i = 0; i < numDomainElts; ++i) {
4825 if (GIDisLocal[i]) {
4826 LocalColGIDs[numLocalCount++] = domainElts[i];
4830 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4831 numLocalCount != numLocalColGIDs, std::logic_error,
4832 ": numLocalCount = " << numLocalCount <<
" != numLocalColGIDs = " 4833 << numLocalColGIDs <<
". This should never happen. Please report " 4834 "this bug to the Tpetra developers.");
4879 Teuchos::OrdinalTraits<global_size_t>::invalid ();
4884 const GO indexBase =
domainMap_->getIndexBase ();
4893 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4899 TEUCHOS_TEST_FOR_EXCEPT( !
isSorted() );
4911 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4916 using Teuchos::ParameterList;
4920 TEUCHOS_TEST_FOR_EXCEPTION(!
hasColMap (), std::logic_error,
"Tpetra::" 4921 "CrsGraph::makeImportExport: This method may not be called unless the " 4922 "graph has a column Map.");
4923 RCP<ParameterList> params = this->getNonconstParameterList ();
4935 if (params.is_null () || ! params->isSublist (
"Import")) {
4938 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
4949 if (params.is_null () || ! params->isSublist (
"Export")) {
4953 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
4961 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4966 std::ostringstream oss;
4969 oss <<
"{status = fill complete" 4976 oss <<
"{status = fill not complete" 4984 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4988 const Teuchos::EVerbosityLevel verbLevel)
const 4990 const char tfecfFuncName[] =
"describe()";
4993 using Teuchos::VERB_DEFAULT;
4994 using Teuchos::VERB_NONE;
4995 using Teuchos::VERB_LOW;
4996 using Teuchos::VERB_MEDIUM;
4997 using Teuchos::VERB_HIGH;
4998 using Teuchos::VERB_EXTREME;
4999 Teuchos::EVerbosityLevel vl = verbLevel;
5000 if (vl == VERB_DEFAULT) vl = VERB_LOW;
5001 RCP<const Comm<int> > comm = this->
getComm();
5002 const int myImageID = comm->getRank(),
5003 numImages = comm->getSize();
5008 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5009 Teuchos::OSTab tab (out);
5017 if (vl != VERB_NONE) {
5018 if (myImageID == 0) out << this->
description() << std::endl;
5021 out <<
"Global number of diagonals = " << globalNumDiags_ << std::endl;
5022 out <<
"Global max number of row entries = " << globalMaxNumRowEntries_ << std::endl;
5025 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5026 if (myImageID == 0) out <<
"\nRow map: " << std::endl;
5029 if (myImageID == 0) out <<
"\nColumn map: " << std::endl;
5033 if (myImageID == 0) out <<
"\nDomain map: " << std::endl;
5037 if (myImageID == 0) out <<
"\nRange map: " << std::endl;
5042 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5043 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5044 if (myImageID == imageCtr) {
5045 out <<
"Node ID = " << imageCtr << std::endl
5046 <<
"Node number of entries = " << nodeNumEntries_ << std::endl
5047 <<
"Node number of diagonals = " << nodeNumDiags_ << std::endl
5048 <<
"Node max number of entries = " << nodeMaxNumRowEntries_ << std::endl;
5049 if (indicesAreAllocated()) {
5050 out <<
"Node number of allocated entries = " << nodeNumAllocated_ << std::endl;
5053 out <<
"Indices are not allocated." << std::endl;
5062 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
5063 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5064 !
hasRowInfo (), std::runtime_error,
": reduce verbosity level; " 5065 "graph row information was deleted at fillComplete().");
5066 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5067 if (myImageID == imageCtr) {
5068 out << std::setw(width) <<
"Node ID" 5069 << std::setw(width) <<
"Global Row" 5070 << std::setw(width) <<
"Num Entries";
5071 if (vl == VERB_EXTREME) {
5077 GlobalOrdinal gid =
rowMap_->getGlobalElement(r);
5078 out << std::setw(width) << myImageID
5079 << std::setw(width) << gid
5080 << std::setw(width) << rowinfo.numEntries;
5081 if (vl == VERB_EXTREME) {
5084 ArrayView<const GlobalOrdinal> rowview =
getGlobalView(rowinfo);
5085 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << rowview[j] <<
" ";
5088 ArrayView<const LocalOrdinal> rowview =
getLocalView(rowinfo);
5089 for (
size_t j=0; j < rowinfo.numEntries; ++j) out <<
colMap_->getGlobalElement(rowview[j]) <<
" ";
5104 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5123 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
5124 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs)
5126 using Teuchos::Array;
5127 using Teuchos::ArrayView;
5128 typedef LocalOrdinal LO;
5129 typedef GlobalOrdinal GO;
5130 const char tfecfFuncName[] =
"copyAndPermute";
5134 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5135 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
5136 ": permuteToLIDs and permuteFromLIDs must have the same size.");
5150 const row_graph_type* srcRowGraph =
dynamic_cast<const row_graph_type*
> (&source);
5151 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5152 srcRowGraph == NULL, std::invalid_argument,
5153 ": The source object must be a RowGraph with matching first three " 5154 "template parameters.");
5159 const this_type* srcCrsGraph =
dynamic_cast<const this_type*
> (&source);
5161 const map_type& srcRowMap = * (srcRowGraph->getRowMap ());
5163 const bool src_filled = srcRowGraph->isFillComplete ();
5170 if (src_filled || srcCrsGraph == NULL) {
5176 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5178 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (gid);
5179 row_copy.resize (row_length);
5180 size_t check_row_length = 0;
5181 srcRowGraph->getGlobalRowCopy (gid, row_copy (), check_row_length);
5185 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5187 ArrayView<const GO> row;
5188 srcCrsGraph->getGlobalRowView (gid, row);
5196 if (src_filled || srcCrsGraph == NULL) {
5197 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5200 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (srcgid);
5201 row_copy.resize (row_length);
5202 size_t check_row_length = 0;
5203 srcRowGraph->getGlobalRowCopy (srcgid, row_copy (), check_row_length);
5207 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5210 ArrayView<const GO> row;
5211 srcCrsGraph->getGlobalRowView (srcgid, row);
5218 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5222 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
5223 Teuchos::Array<GlobalOrdinal> &exports,
5224 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
5225 size_t& constantNumPackets,
5228 using Teuchos::Array;
5229 const char tfecfFuncName[] =
"packAndPrepare";
5230 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5231 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5232 ": exportLIDs and numPacketsPerLID must have the same size.");
5234 const row_graph_type& srcGraph =
dynamic_cast<const row_graph_type&
> (source);
5239 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5241 ": The target graph of an Import or Export must not be fill complete.");
5243 srcGraph.pack (exportLIDs, exports, numPacketsPerLID, constantNumPackets, distor);
5247 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5250 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5251 Teuchos::Array<GlobalOrdinal>& exports,
5252 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5253 size_t& constantNumPackets,
5256 using Teuchos::Array;
5257 typedef LocalOrdinal LO;
5258 typedef GlobalOrdinal GO;
5259 const char tfecfFuncName[] =
"pack";
5262 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5263 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5264 ": exportLIDs and numPacketsPerLID must have the same size.");
5267 constantNumPackets = 0;
5274 size_t totalNumPackets = 0;
5276 for (LO i = 0; i < exportLIDs.size (); ++i) {
5279 numPacketsPerLID[i] = row_length;
5280 totalNumPackets += row_length;
5283 exports.resize (totalNumPackets);
5287 size_t exportsOffset = 0;
5288 for (LO i = 0; i < exportLIDs.size (); ++i) {
5289 const GO GID = srcMap.getGlobalElement (exportLIDs[i]);
5291 row.resize (row_length);
5292 size_t check_row_length = 0;
5294 typename Array<GO>::const_iterator row_iter = row.begin();
5295 typename Array<GO>::const_iterator row_end = row.end();
5297 for (; row_iter != row_end; ++row_iter, ++j) {
5298 exports[exportsOffset+j] = *row_iter;
5300 exportsOffset += row.size();
5305 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5308 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
5309 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
5310 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
5311 size_t constantNumPackets,
5315 using Teuchos::ArrayView;
5316 typedef LocalOrdinal LO;
5317 typedef GlobalOrdinal GO;
5336 const char tfecfFuncName[] =
"unpackAndCombine: ";
5337 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5338 importLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5339 "importLIDs and numPacketsPerLID must have the same size.");
5340 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5342 "Import or Export operations are not allowed on the destination " 5343 "CrsGraph if it is fill complete.");
5344 size_t importsOffset = 0;
5346 typedef typename ArrayView<const LO>::const_iterator iter_type;
5347 iter_type impLIDiter = importLIDs.begin();
5348 iter_type impLIDend = importLIDs.end();
5350 for (
size_t i = 0; impLIDiter != impLIDend; ++impLIDiter, ++i) {
5351 LO row_length = numPacketsPerLID[i];
5353 const GO*
const row_raw = (row_length == 0) ? NULL : &imports[importsOffset];
5354 ArrayView<const GlobalOrdinal> row (row_raw, row_length);
5356 importsOffset += row_length;
5361 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5366 using Teuchos::Comm;
5367 using Teuchos::null;
5368 using Teuchos::ParameterList;
5374 RCP<const map_type> rowMap, domainMap, rangeMap, colMap;
5375 RCP<import_type> importer;
5376 RCP<export_type> exporter;
5379 RCP<const Comm<int> > newComm =
5380 (newMap.is_null ()) ? null : newMap->getComm ();
5390 domainMap =
domainMap_->replaceCommWithSubset (newComm);
5401 rangeMap =
rangeMap_->replaceCommWithSubset (newComm);
5404 if (! colMap.is_null ()) {
5405 colMap =
colMap_->replaceCommWithSubset (newComm);
5409 if (! newComm.is_null ()) {
5410 RCP<ParameterList> params = this->getNonconstParameterList ();
5419 rangeMap != rowMap &&
5420 ! rangeMap->isSameAs (*rowMap)) {
5421 if (params.is_null () || ! params->isSublist (
"Export")) {
5422 exporter = rcp (
new export_type (rowMap, rangeMap));
5425 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5426 exporter = rcp (
new export_type (rowMap, rangeMap, exportSublist));
5431 domainMap != colMap &&
5432 ! domainMap->isSameAs (*colMap)) {
5433 if (params.is_null () || ! params->isSublist (
"Import")) {
5434 importer = rcp (
new import_type (domainMap, colMap));
5436 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5437 importer = rcp (
new import_type (domainMap, colMap, importSublist));
5453 this->
map_ = rowMap;
5459 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5464 if (indicesAreAllocated () &&
5480 #define TPETRA_CRSGRAPH_GRAPH_INSTANT(LO,GO,NODE) template class CrsGraph< LO , GO , NODE >; 5481 #define TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) template void CrsGraph< LO , GO , NODE >::sortRowIndicesAndValues< S >(const RowInfo, const Teuchos::ArrayView< S >& ); 5482 #define TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) template void CrsGraph< LO , GO , NODE >::mergeRowIndicesAndValues< S >(RowInfo, const ArrayView< S >& ); 5483 #define TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) 5484 #define TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) template ArrayRCP< Array< S > > CrsGraph< LO , GO , NODE >::allocateValues2D< S >() const; 5486 #define TPETRA_CRSGRAPH_INSTANT(S,LO,GO,NODE) \ 5487 TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5488 TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5489 TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) \ 5490 TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) \ 5491 template void CrsGraph< LO , GO , NODE >::insertIndicesAndValues< S > (const RowInfo&, const SLocalGlobalViews&, const Teuchos::ArrayView< S >&, const Teuchos::ArrayView<const S >&, const ELocalGlobal, const ELocalGlobal); 5493 #endif // TPETRA_CRSGRAPH_DEF_HPP Teuchos::ArrayRCP< const LocalOrdinal > getNodePackedIndices() const
Get an Teuchos::ArrayRCP of the packed column-indices.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
bool isGloballyIndexed() const
If graph indices are in the global range, this function returns true. Otherwise, this function return...
Teuchos::RCP< const Comm< int > > getComm() const
Returns the communicator.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
bool haveGlobalConstants_
Whether all processes have computed global constants.
virtual void copyAndPermute(const SrcDistObject &source, size_t numSameIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteToLIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteFromLIDs)
Perform copies and permutations that are local to this process.
virtual std::string description() const
One-line descriptiion of this object.
std::string description() const
Return a simple one-line description of this object.
void expertStaticFillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< const import_type > &importer=Teuchos::null, const Teuchos::RCP< const export_type > &exporter=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Perform a fillComplete on a graph that already has data, via setAllIndices().
Teuchos::RCP< const map_type > getRowMap() const
Returns the Map that describes the row distribution in this graph.
void insertLocalIndicesFiltered(const LocalOrdinal localRow, const Teuchos::ArrayView< const LocalOrdinal > &indices)
Like insertLocalIndices(), but with column Map filtering.
bool isFillActive() const
Returns true if resumeFill() has been called and the graph is in edit mode.
Teuchos::ArrayView< LocalOrdinal > getLocalViewNonConst(const RowInfo rowinfo)
Get a nonconst, nonowned, locally indexed view of the locally owned row myRow, such that rowinfo = ge...
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes owning zero rows from the Maps and their communicator.
void insertGlobalIndices(GlobalOrdinal globalRow, const Teuchos::ArrayView< const GlobalOrdinal > &indices)
Insert global indices into the graph.
Teuchos::RCP< const map_type > getRangeMap() const
Returns the Map associated with the domain of this graph.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
size_t getNodeNumCols() const
Returns the number of columns connected to the locally owned rows of this graph.
bool hasRowInfo() const
Whether it is correct to call getRowInfo().
void removeLocalIndices(LocalOrdinal localRow)
Remove all graph indices from the specified local row.
bool noRedundancies_
Whether the graph's indices are non-redundant (merged) in each row, on this process.
local_graph_type getLocalGraph() const
Get the local graph.
bool sortGhostsAssociatedWithEachProcessor_
Whether to require makeColMap() (and therefore fillComplete()) to order column Map GIDs associated wi...
Node::device_type device_type
This class' Kokkos device type.
bool hasColMap() const
Whether the graph has a column Map.
Teuchos::RCP< const map_type > rangeMap_
The Map describing the range of the (matrix corresponding to the) graph.
ProfileType pftype_
Whether the graph was allocated with static or dynamic profile.
void getGlobalRowCopy(GlobalOrdinal GlobalRow, const Teuchos::ArrayView< GlobalOrdinal > &Indices, size_t &NumIndices) const
Get a copy of the given row, using global indices.
void mergeRowIndices(RowInfo rowinfo)
Merge duplicate row indices in the given row.
size_t getGlobalMaxNumRowEntries() const
Maximum number of entries in all rows over all processes.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
global_size_t getGlobalNumRows() const
Returns the number of global rows in the graph.
bool isSorted() const
Whether graph indices in all rows are known to be sorted.
t_numRowEntries_ k_numRowEntries_
The number of local entries in each locally owned row.
void setAllIndices(const typename local_graph_type::row_map_type &rowPointers, const typename local_graph_type::entries_type::non_const_type &columnIndices)
Set the graph's data directly, using 1-D storage.
ProfileType getProfileType() const
Returns true if the graph was allocated with static data structures.
local_graph_type::entries_type::non_const_type k_lclInds1D_
Local column indices for all rows.
void mergeRowIndicesAndValues(RowInfo rowinfo, const Teuchos::ArrayView< Scalar > &rowValues)
Merge duplicate row indices in the given row, along with their corresponding values.
Teuchos::ArrayRCP< Teuchos::Array< GlobalOrdinal > > gblInds2D_
Global column indices for all rows.
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 resumeFill(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Teuchos::RCP< const import_type > getImporter() const
Returns the importer associated with this graph.
void checkInternalState() const
Throw an exception if the internal state is not consistent.
bool isStorageOptimized() const
Returns true if storage has been optimized.
void fillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Signal that data entry is complete, specifying domain and range maps.
bool upperTriangular_
Whether the graph is locally upper triangular.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Set the given list of parameters (must be nonnull).
void insertGlobalIndicesFiltered(const GlobalOrdinal localRow, const Teuchos::ArrayView< const GlobalOrdinal > &indices)
Like insertGlobalIndices(), but with column Map filtering.
Teuchos::RCP< const map_type > domainMap_
The Map describing the domain of the (matrix corresponding to the) graph.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
size_t getNodeMaxNumRowEntries() const
Maximum number of entries in all rows owned by the calling process.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
bool isFillComplete() const
Returns true if fillComplete() has been called and the graph is in compute mode.
void replaceColMap(const Teuchos::RCP< const map_type > &newColMap)
Replace the graph's current column Map with the given Map.
Teuchos::RCP< const map_type > colMap_
The Map describing the distribution of columns of the graph.
size_t getNodeAllocationSize() const
Returns the total number of indices allocated for the graph, across all rows on this node...
Implementation details of Tpetra.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in the graph.
size_t numAllocForAllRows_
The maximum number of entries to allow in each locally owned row.
size_t global_size_t
Global size_t object.
Kokkos::StaticCrsGraph< LocalOrdinal, Kokkos::LayoutLeft, execution_space > local_graph_type
The type of the part of the sparse graph on each MPI process.
bool isLocallyIndexed() const
If graph indices are in the local range, this function returns true. Otherwise, this function returns...
Teuchos::RCP< const map_type > getDomainMap() const
Returns the Map associated with the domain of this graph.
bool haveLocalConstants_
Whether this process has computed local constants.
bool isMerged() const
Whether duplicate column indices in each row have been merged.
t_GlobalOrdinal_1D k_gblInds1D_
Global column indices for all rows.
Teuchos::RCP< node_type > getNode() const
Returns the underlying node.
GlobalOrdinal getIndexBase() const
Returns the index base for global indices for this graph.
size_t findGlobalIndex(RowInfo rowinfo, GlobalOrdinal ind, size_t hint=0) const
Find the column offset corresponding to the given (global) column index.
local_graph_type lclGraph_
Local graph; only initialized after first fillComplete() call.
void globalAssemble()
Communicate non-local contributions to other processes.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
void sortRowIndicesAndValues(const RowInfo rowinfo, const Teuchos::ArrayView< Scalar > &values)
Sort the column indices and their values in the given row.
void insertIndicesAndValues(const RowInfo &rowInfo, const SLocalGlobalViews &newInds, const Teuchos::ArrayView< Scalar > &oldRowVals, const Teuchos::ArrayView< const Scalar > &newRowVals, const ELocalGlobal lg, const ELocalGlobal I)
Insert indices and their values into the given row.
TPETRA_DEPRECATED local_graph_type getLocalGraph_Kokkos() const
Get the local graph (DEPRECATED: call getLocalGraph() instead).
bool isUpperTriangular() const
Whether the graph is locally upper triangular.
Sets up and executes a communication plan for a Tpetra DistObject.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
CombineMode
Rule for combining data in an Import or Export.
Teuchos::RCP< const map_type > map_
The Map over which this object is distributed.
void makeColMap()
Make the graph's column Map, if it does not already have one.
void getLocalRowCopy(LocalOrdinal LocalRow, const Teuchos::ArrayView< LocalOrdinal > &indices, size_t &NumIndices) const
Get a copy of the given row, using local indices.
Kokkos::DualView< const size_t *, Kokkos::LayoutLeft, execution_space > k_numAllocPerRow_
The maximum number of entries to allow in each locally owned row, per row.
global_size_t getGlobalNumCols() const
Returns the number of global columns in the graph.
Abstract base class for objects that can be the source of an Import or Export operation.
Teuchos::RCP< const import_type > importer_
The Import from the domain Map to the column Map.
Node node_type
This class' Kokkos Node type.
void reindexColumns(const Teuchos::RCP< const map_type > &newColMap, const Teuchos::RCP< const import_type > &newImport=Teuchos::null, const bool sortIndicesInEachRow=true)
Reindex the column indices in place, and replace the column Map. Optionally, replace the Import objec...
Teuchos::RCP< const map_type > getColMap() const
Returns the Map that describes the column distribution in this graph.
size_t insertIndices(const RowInfo &rowInfo, const SLocalGlobalViews &newInds, const ELocalGlobal lg, const ELocalGlobal I)
Insert indices into the given row.
Teuchos::ArrayView< GlobalOrdinal > getGlobalViewNonConst(const RowInfo rowinfo)
Get a nonconst, nonowned, globally indexed view of the locally owned row myRow, such that rowinfo = g...
Teuchos::RCP< const map_type > rowMap_
The Map describing the distribution of rows of the graph.
size_t getNodeNumEntries() const
Returns the local number of entries in the graph.
virtual void pack(const Teuchos::ArrayView< const LocalOrdinal > &exportLIDs, Teuchos::Array< GlobalOrdinal > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, Distributor &distor) const
Pack this object's data for Import or Export.
Teuchos::ArrayRCP< Teuchos::Array< LocalOrdinal > > lclInds2D_
Local column indices for all rows.
global_size_t getGlobalNumDiags() const
Returns the number of global diagonal entries, based on global row/column index comparisons.
size_t findLocalIndex(RowInfo rowinfo, LocalOrdinal ind, size_t hint=0) const
Find the column offset corresponding to the given (local) column index.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
size_t getNumAllocatedEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of allocated entries for this node in the specified global row ...
Describes a parallel distribution of objects over processes.
void setDomainRangeMaps(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap)
size_t getNumAllocatedEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of allocated entries on this node in the specified local row...
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
Details::EStorageStatus storageStatus_
Status of the graph's storage, when not in a fill-complete state.
size_t getNodeNumDiags() const
Returns the number of local diagonal entries, based on global row/column index comparisons.
device_type::execution_space execution_space
This class' Kokkos execution space.
local_graph_type::row_map_type::const_type k_rowPtrs_
Row offsets for "1-D" storage.
size_t getNodeNumRows() const
Returns the number of graph rows owned on the calling node.
void getGlobalRowView(GlobalOrdinal GlobalRow, Teuchos::ArrayView< const GlobalOrdinal > &Indices) const
Extract a const, non-persisting view of global indices in a specified row of the graph.
std::map< GlobalOrdinal, std::vector< GlobalOrdinal > > nonlocals_
Nonlocal data given to insertGlobalValues or sumIntoGlobalValues.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
void replaceDomainMapAndImporter(const Teuchos::RCP< const map_type > &newDomainMap, const Teuchos::RCP< const import_type > &newImporter)
Replace the current domain Map and Import with the given parameters.
void mergeAllIndices()
Merge duplicate row indices in all of the rows.
Teuchos::ArrayView< const LocalOrdinal > getLocalView(const RowInfo rowinfo) const
Get a const, nonowned, locally indexed view of the locally owned row myRow, such that rowinfo = getRo...
void setLocallyModified()
Report that we made a local modification to its structure.
virtual ~CrsGraph()
Destructor.
Kokkos::View< GlobalOrdinal *, execution_space > t_GlobalOrdinal_1D
Type of the k_gblInds1D_ array of global column indices.
Teuchos::RCP< const ParameterList > getValidParameters() const
Default parameter list suitable for validation.
void sortAllIndices()
Sort the column indices in all the rows.
bool isLowerTriangular() const
Whether the graph is locally lower triangular.
void sortRowIndices(const RowInfo rowinfo)
Sort the column indices in the given row.
void insertLocalIndices(const LocalOrdinal localRow, const Teuchos::ArrayView< const LocalOrdinal > &indices)
Insert local indices into the graph.
Teuchos::RCP< const export_type > exporter_
The Export from the row Map to the range Map.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object to the given output stream with given verbosity level.
Teuchos::ArrayView< const GlobalOrdinal > getGlobalView(const RowInfo rowinfo) const
Get a const, nonowned, globally indexed view of the locally owned row myRow, such that rowinfo = getR...
bool lowerTriangular_
Whether the graph is locally lower triangular.
Teuchos::RCP< const export_type > getExporter() const
Returns the exporter associated with this graph.
void getNumEntriesPerLocalRowUpperBound(Teuchos::ArrayRCP< const size_t > &boundPerLocalRow, size_t &boundForAllLocalRows, bool &boundSameForAllLocalRows) const
Get an upper bound on the number of entries that can be stored in each row.
virtual bool checkSizes(const SrcDistObject &source)
Compare the source and target (this) objects for compatibility.
Teuchos::ArrayRCP< const size_t > getNodeRowPtrs() const
Get a host view of the row offsets.
RowInfo getRowInfo(const size_t myRow) const
Get information about the locally owned row with local index myRow.
void getLocalRowView(LocalOrdinal LocalRow, Teuchos::ArrayView< const LocalOrdinal > &indices) const
Extract a const, non-persisting view of local indices in a specified row of the graph.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.