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;
1194 typedef LocalOrdinal LO;
1196 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);
1211 row_view_type rowView = subview (row_view_type (
k_lclInds1D_), rng);
1212 const LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1213 return Teuchos::ArrayView<const LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1215 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1219 return Teuchos::ArrayView<const LO> ();
1225 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1226 Teuchos::ArrayView<LocalOrdinal>
1230 using Kokkos::subview;
1231 typedef LocalOrdinal LO;
1233 Kokkos::MemoryUnmanaged> row_view_type;
1235 if (rowinfo.allocSize == 0) {
1236 return Teuchos::ArrayView<LO> ();
1240 const size_t start = rowinfo.offset1D;
1241 const size_t len = rowinfo.allocSize;
1242 const std::pair<size_t, size_t> rng (start, start + len);
1248 row_view_type rowView = subview (row_view_type (
k_lclInds1D_), rng);
1249 LO*
const rowViewRaw = (len == 0) ? NULL : rowView.ptr_on_device ();
1250 return Teuchos::ArrayView<LO> (rowViewRaw, len, Teuchos::RCP_DISABLE_NODE_LOOKUP);
1252 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1256 return Teuchos::ArrayView<LO> ();
1262 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1263 Kokkos::View<
const LocalOrdinal*,
1265 Kokkos::MemoryUnmanaged>
1269 typedef LocalOrdinal LO;
1271 Kokkos::MemoryUnmanaged> row_view_type;
1273 if (rowinfo.allocSize == 0) {
1274 return row_view_type ();
1278 const size_t start = rowinfo.offset1D;
1279 const size_t len = rowinfo.allocSize;
1280 const std::pair<size_t, size_t> rng (start, start + len);
1286 return Kokkos::subview (row_view_type (
k_lclInds1D_), rng);
1288 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1289 Teuchos::ArrayView<const LO> rowAv =
lclInds2D_[rowinfo.localRow] ();
1290 return row_view_type (rowAv.getRawPtr (), rowAv.size ());
1293 return row_view_type ();
1299 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1300 Kokkos::View<LocalOrdinal*,
1301 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1302 Kokkos::MemoryUnmanaged>
1306 typedef LocalOrdinal LO;
1308 Kokkos::MemoryUnmanaged> row_view_type;
1310 if (rowinfo.allocSize == 0) {
1311 return row_view_type ();
1315 const size_t start = rowinfo.offset1D;
1316 const size_t len = rowinfo.allocSize;
1317 const std::pair<size_t, size_t> rng (start, start + len);
1323 return Kokkos::subview (row_view_type (
k_lclInds1D_), rng);
1325 else if (!
lclInds2D_[rowinfo.localRow].empty ()) {
1326 Teuchos::ArrayView<LO> rowAv =
lclInds2D_[rowinfo.localRow] ();
1327 return row_view_type (rowAv.getRawPtr (), rowAv.size ());
1330 return row_view_type ();
1336 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1337 Kokkos::View<
const GlobalOrdinal*,
1338 typename CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
1339 Kokkos::MemoryUnmanaged>
1343 typedef GlobalOrdinal GO;
1345 Kokkos::MemoryUnmanaged> row_view_type;
1347 if (rowinfo.allocSize == 0) {
1348 return row_view_type ();
1352 const size_t start = rowinfo.offset1D;
1353 const size_t len = rowinfo.allocSize;
1354 const std::pair<size_t, size_t> rng (start, start + len);
1360 return Kokkos::subview (row_view_type (this->
k_gblInds1D_), rng);
1362 else if (! this->
gblInds2D_[rowinfo.localRow].empty ()) {
1363 Teuchos::ArrayView<const GO> rowAv = this->
gblInds2D_[rowinfo.localRow] ();
1367 return row_view_type (rowAv.getRawPtr (), rowAv.size ());
1370 return row_view_type ();
1376 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1377 Teuchos::ArrayView<const GlobalOrdinal>
1381 Teuchos::ArrayView<const GlobalOrdinal> view;
1382 if (rowinfo.allocSize > 0) {
1384 auto rng = std::make_pair (rowinfo.offset1D,
1385 rowinfo.offset1D + rowinfo.allocSize);
1392 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged =
k_gblInds1D_;
1393 view = Kokkos::Compat::getConstArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1395 else if (!
gblInds2D_[rowinfo.localRow].empty()) {
1403 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1404 Teuchos::ArrayView<GlobalOrdinal>
1408 Teuchos::ArrayView<GlobalOrdinal> view;
1409 if (rowinfo.allocSize > 0) {
1411 auto rng = std::make_pair (rowinfo.offset1D,
1412 rowinfo.offset1D + rowinfo.allocSize);
1419 Kokkos::MemoryUnmanaged> k_gblInds1D_unmanaged =
k_gblInds1D_;
1420 view = Kokkos::Compat::getArrayView (Kokkos::subview (k_gblInds1D_unmanaged, rng));
1422 else if (!
gblInds2D_[rowinfo.localRow].empty()) {
1430 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1435 #ifdef HAVE_TPETRA_DEBUG 1436 const char tfecfFuncName[] =
"getRowInfo";
1437 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1438 !
rowMap_->isNodeLocalElement (myRow), std::logic_error,
1439 ": The given (local) row index myRow = " << myRow
1440 <<
" does not belong to the graph's row Map. " 1441 "This probably indicates a bug in Tpetra::CrsGraph or Tpetra::CrsMatrix. " 1442 "Please report this bug to the Tpetra developers.");
1443 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1445 ": Late catch! Graph does not have row info anymore. " 1446 "Error should have been caught earlier. " 1447 "Please report this bug to the Tpetra developers.");
1448 #endif // HAVE_TPETRA_DEBUG 1450 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1453 ret.localRow = STINV;
1456 ret.offset1D = STINV;
1460 ret.localRow =
static_cast<size_t> (myRow);
1461 if (nodeNumAllocated_ != 0 && nodeNumAllocated_ != STINV) {
1469 ret.numEntries = ret.allocSize;
1475 ret.offset1D = STINV;
1485 else if (nodeNumAllocated_ == 0) {
1489 ret.offset1D = STINV;
1491 else if (! indicesAreAllocated ()) {
1498 if (useNumAllocPerRow) {
1504 ret.offset1D = STINV;
1508 TEUCHOS_TEST_FOR_EXCEPT(
true);
1514 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1519 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1522 ret.localRow = STINV;
1525 ret.offset1D = STINV;
1528 const LocalOrdinal myRow = this->
rowMap_->getLocalElement (gblRow);
1529 if (myRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
1530 ret.localRow = STINV;
1533 ret.offset1D = STINV;
1537 ret.localRow =
static_cast<size_t> (myRow);
1538 if (nodeNumAllocated_ != 0 && nodeNumAllocated_ != STINV) {
1546 ret.numEntries = ret.allocSize;
1552 ret.offset1D = STINV;
1562 else if (nodeNumAllocated_ == 0) {
1566 ret.offset1D = STINV;
1568 else if (! indicesAreAllocated ()) {
1575 if (useNumAllocPerRow) {
1581 ret.offset1D = STINV;
1585 TEUCHOS_TEST_FOR_EXCEPT(
true);
1591 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1596 using Teuchos::OrdinalTraits;
1597 typedef LocalOrdinal LO;
1598 typedef GlobalOrdinal GO;
1604 static_assert (
sizeof (GlobalOrdinal) >=
sizeof (LocalOrdinal),
1605 "Tpetra::CrsGraph: sizeof(GlobalOrdinal) must be >= sizeof(LocalOrdinal).");
1608 static_assert (
sizeof (
size_t) >=
sizeof (LocalOrdinal),
1609 "Tpetra::CrsGraph: sizeof(size_t) must be >= sizeof(LocalOrdinal).");
1610 static_assert (
sizeof(GST) >=
sizeof(
size_t),
1611 "Tpetra::CrsGraph: sizeof(Tpetra::global_size_t) must be >= sizeof(size_t).");
1619 const char msg[] =
"Tpetra::CrsGraph: Object cannot be created with the " 1620 "given template arguments: size assumptions are not valid.";
1621 TEUCHOS_TEST_FOR_EXCEPTION(
1622 static_cast<size_t> (OrdinalTraits<LO>::max ()) > OrdinalTraits<size_t>::max (),
1623 std::runtime_error, msg);
1624 TEUCHOS_TEST_FOR_EXCEPTION(
1625 static_cast<GST> (OrdinalTraits<LO>::max ()) > static_cast<GST> (OrdinalTraits<GO>::max ()),
1626 std::runtime_error, msg);
1627 TEUCHOS_TEST_FOR_EXCEPTION(
1628 static_cast<size_t> (OrdinalTraits<GO>::max ()) > OrdinalTraits<GST>::max(),
1629 std::runtime_error, msg);
1630 TEUCHOS_TEST_FOR_EXCEPTION(
1631 OrdinalTraits<size_t>::max () > OrdinalTraits<GST>::max (),
1632 std::runtime_error, msg);
1636 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1640 const SLocalGlobalViews &newInds,
1641 const ELocalGlobal lg,
1642 const ELocalGlobal I)
1644 using Teuchos::ArrayView;
1645 #ifdef HAVE_TPETRA_DEBUG 1646 TEUCHOS_TEST_FOR_EXCEPTION(
1647 lg != GlobalIndices && lg != LocalIndices, std::invalid_argument,
1648 "Tpetra::CrsGraph::insertIndices: lg must be either GlobalIndices or " 1650 #endif // HAVE_TPETRA_DEBUG 1651 size_t numNewInds = 0;
1652 if (lg == GlobalIndices) {
1653 ArrayView<const GlobalOrdinal> new_ginds = newInds.ginds;
1654 numNewInds = new_ginds.size();
1655 if (I == GlobalIndices) {
1657 std::copy(new_ginds.begin(), new_ginds.end(), gind_view.begin()+rowinfo.numEntries);
1659 else if (I == LocalIndices) {
1661 typename ArrayView<const GlobalOrdinal>::iterator in = new_ginds.begin();
1662 const typename ArrayView<const GlobalOrdinal>::iterator stop = new_ginds.end();
1663 typename ArrayView<LocalOrdinal>::iterator out = lind_view.begin()+rowinfo.numEntries;
1664 while (in != stop) {
1665 *out++ =
colMap_->getLocalElement (*in++);
1669 else if (lg == LocalIndices) {
1670 ArrayView<const LocalOrdinal> new_linds = newInds.linds;
1671 numNewInds = new_linds.size();
1672 if (I == LocalIndices) {
1674 std::copy(new_linds.begin(), new_linds.end(), lind_view.begin()+rowinfo.numEntries);
1676 else if (I == GlobalIndices) {
1677 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Tpetra::CrsGraph::" 1678 "insertIndices: the case where the input indices are local and the " 1679 "indices to write are global (lg=LocalIndices, I=GlobalIndices) is " 1680 "not implemented, because it does not make sense." << std::endl <<
1681 "If you have correct local column indices, that means the graph has " 1682 "a column Map. In that case, you should be storing local indices.");
1688 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1692 nodeNumEntries_ += numNewInds;
1698 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1702 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
1704 const char tfecfFuncName[] =
"insertGlobalIndicesImpl";
1707 const size_t numNewInds = indices.size();
1708 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
1709 if (newNumEntries > rowInfo.allocSize) {
1710 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1712 ": new indices exceed statically allocated graph structure.");
1715 size_t newAllocSize = 2*rowInfo.allocSize;
1716 if (newAllocSize < newNumEntries) {
1717 newAllocSize = newNumEntries;
1720 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1725 const size_t numIndsToCopy =
static_cast<size_t> (indices.size ());
1726 const size_t offset = rowInfo.offset1D + rowInfo.numEntries;
1727 for (
size_t k = 0; k < numIndsToCopy; ++k) {
1732 std::copy(indices.begin(), indices.end(),
1733 gblInds2D_[myRow].begin()+rowInfo.numEntries);
1738 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1742 nodeNumEntries_ += numNewInds;
1745 #ifdef HAVE_TPETRA_DEBUG 1748 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1749 chkNewNumEntries != newNumEntries, std::logic_error,
1750 ": Internal logic error. Please contact Tpetra team.");
1756 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1760 const Teuchos::ArrayView<const LocalOrdinal>& indices)
1762 using Kokkos::MemoryUnmanaged;
1763 using Kokkos::subview;
1765 typedef LocalOrdinal LO;
1766 const char* tfecfFuncName (
"insertLocallIndicesImpl");
1769 const size_t numNewInds = indices.size();
1770 const size_t newNumEntries = rowInfo.numEntries + numNewInds;
1771 if (newNumEntries > rowInfo.allocSize) {
1772 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1774 ": new indices exceed statically allocated graph structure.");
1777 size_t newAllocSize = 2*rowInfo.allocSize;
1778 if (newAllocSize < newNumEntries)
1779 newAllocSize = newNumEntries;
1781 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1786 typedef View<const LO*, execution_space, MemoryUnmanaged> input_view_type;
1787 typedef View<LO*, execution_space, MemoryUnmanaged> row_view_type;
1789 input_view_type inputInds (indices.getRawPtr (), indices.size ());
1790 const size_t start = rowInfo.offset1D + rowInfo.numEntries;
1791 const std::pair<size_t, size_t> rng (start, start + newNumEntries);
1796 row_view_type myInds = subview (row_view_type (
k_lclInds1D_), rng);
1800 std::copy (indices.begin (), indices.end (),
1801 lclInds2D_[myRow].begin () + rowInfo.numEntries);
1806 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
1810 nodeNumEntries_ += numNewInds;
1812 #ifdef HAVE_TPETRA_DEBUG 1815 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1816 chkNewNumEntries != newNumEntries, std::logic_error,
1817 ": Internal logic error. Please contact Tpetra team.");
1823 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1824 template <
class Scalar>
1828 const SLocalGlobalViews& newInds,
1829 const Teuchos::ArrayView<Scalar>& oldRowVals,
1830 const Teuchos::ArrayView<const Scalar>& newRowVals,
1831 const ELocalGlobal lg,
1832 const ELocalGlobal I)
1834 #ifdef HAVE_TPETRA_DEBUG 1835 size_t numNewInds = 0;
1838 }
catch (std::exception& e) {
1839 TEUCHOS_TEST_FOR_EXCEPTION(
1840 true, std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1841 "insertIndices threw an exception: " << e.what ());
1843 TEUCHOS_TEST_FOR_EXCEPTION(
1844 numNewInds > static_cast<size_t> (oldRowVals.size ()), std::runtime_error,
1845 "Tpetra::CrsGraph::insertIndicesAndValues: numNewInds (" << numNewInds
1846 <<
") > oldRowVals.size() (" << oldRowVals.size () <<
".");
1848 const size_t numNewInds =
insertIndices (rowInfo, newInds, lg, I);
1849 #endif // HAVE_TPETRA_DEBUG 1851 typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1853 #ifdef HAVE_TPETRA_DEBUG 1854 TEUCHOS_TEST_FOR_EXCEPTION(
1855 rowInfo.numEntries + numNewInds > static_cast<size_t> (oldRowVals.size ()),
1856 std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: rowInfo." 1857 "numEntries (" << rowInfo.numEntries <<
") + numNewInds (" << numNewInds
1858 <<
") > oldRowVals.size() (" << oldRowVals.size () <<
").");
1859 TEUCHOS_TEST_FOR_EXCEPTION(
1860 static_cast<size_type> (numNewInds) > newRowVals.size (),
1861 std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1862 "numNewInds (" << numNewInds <<
") > newRowVals.size() (" 1863 << newRowVals.size () <<
").");
1864 #endif // HAVE_TPETRA_DEBUG 1866 size_type oldInd =
static_cast<size_type
> (rowInfo.numEntries);
1868 #ifdef HAVE_TPETRA_DEBUG 1870 #endif // HAVE_TPETRA_DEBUG 1873 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 1874 #define GCC_VERSION __GNUC__*100+__GNUC_MINOR__*10+__GNUC_PATCHLEVEL__ 1875 #if GCC_VERSION >= 490 1876 #define GCC_WORKAROUND 1879 #ifdef GCC_WORKAROUND 1880 size_type nNI =
static_cast<size_type
>(numNewInds);
1882 memcpy(&oldRowVals[oldInd], &newRowVals[0], nNI*
sizeof(Scalar));
1924 #else // GCC Workaround above 1925 for (size_type newInd = 0; newInd < static_cast<size_type> (numNewInds);
1926 ++newInd, ++oldInd) {
1927 oldRowVals[oldInd] = newRowVals[newInd];
1929 #endif // GCC Workaround 1930 #ifdef HAVE_TPETRA_DEBUG 1932 catch (std::exception& e) {
1933 TEUCHOS_TEST_FOR_EXCEPTION(
1934 true, std::runtime_error,
"Tpetra::CrsGraph::insertIndicesAndValues: " 1935 "for loop for copying values threw an exception: " << e.what ());
1937 #endif // HAVE_TPETRA_DEBUG 1941 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1946 if (rowinfo.numEntries > 0) {
1947 Teuchos::ArrayView<LocalOrdinal> inds_view =
1949 std::sort (inds_view.begin (), inds_view.begin () + rowinfo.numEntries);
1954 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1955 template <
class Scalar>
1959 const Teuchos::ArrayView<Scalar>& values)
1961 if (rowinfo.numEntries > 0) {
1962 Teuchos::ArrayView<LocalOrdinal> inds_view =
1964 sort2 (inds_view.begin (), inds_view.begin () + rowinfo.numEntries,
1970 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1975 using Teuchos::ArrayView;
1976 const char tfecfFuncName[] =
"mergeRowIndices: ";
1977 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1979 "optimized, so we shouldn't be merging any indices. " 1980 "Please report this bug to the Tpetra developers.");
1983 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
1984 beg = inds_view.begin();
1985 end = inds_view.begin() + rowinfo.numEntries;
1986 newend = std::unique(beg,end);
1987 const size_t mergedEntries = newend - beg;
1988 #ifdef HAVE_TPETRA_DEBUG 1991 TEUCHOS_TEST_FOR_EXCEPT(
isStorageOptimized () && mergedEntries != rowinfo.numEntries );
1992 #endif // HAVE_TPETRA_DEBUG 1996 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
2000 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
2004 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2005 template<
class Scalar>
2009 const Teuchos::ArrayView<Scalar>& rowValues)
2011 using Teuchos::ArrayView;
2012 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
2013 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2015 "method if the graph's storage has already been optimized. Please " 2016 "report this bug to the Tpetra developers.");
2018 typedef typename ArrayView<Scalar>::iterator Iter;
2019 Iter rowValueIter = rowValues.begin ();
2021 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
2024 beg = inds_view.begin();
2025 end = inds_view.begin() + rowinfo.numEntries;
2028 typename ArrayView<LocalOrdinal>::iterator cur = beg + 1;
2029 Iter vcur = rowValueIter + 1;
2030 Iter vend = rowValueIter;
2032 while (cur != end) {
2033 if (*cur != *newend) {
2050 const size_t mergedEntries = newend - beg;
2051 #ifdef HAVE_TPETRA_DEBUG 2054 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2057 ": Merge was incorrect; it eliminated entries from the graph. " 2058 << std::endl <<
"Please report this bug to the Tpetra developers.");
2059 #endif // HAVE_TPETRA_DEBUG 2063 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
2067 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
2071 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2075 const Teuchos::RCP<const map_type>& rangeMap)
2089 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2093 const LocalOrdinal ind,
2094 const size_t hint)
const 2096 auto colInds = this->getLocalKokkosRowView (rowinfo);
2101 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2105 const LocalOrdinal ind,
2106 const Kokkos::View<
const LocalOrdinal*,
device_type,
2107 Kokkos::MemoryUnmanaged>& colInds,
2108 const size_t hint)
const 2110 typedef const LocalOrdinal* IT;
2117 if (hint < rowinfo.numEntries && colInds(hint) == ind) {
2125 IT beg = colInds.ptr_on_device ();
2126 IT end = beg + rowinfo.numEntries;
2127 IT ptr = beg + rowinfo.numEntries;
2131 std::pair<IT,IT> p = std::equal_range (beg, end, ind);
2132 if (p.first == p.second) {
2139 ptr = std::find (beg, end, ind);
2146 return static_cast<size_t> (ptr - beg);
2149 return Teuchos::OrdinalTraits<size_t>::invalid ();
2154 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2158 const GlobalOrdinal ind,
2159 const Kokkos::View<
const GlobalOrdinal*,
2161 const size_t hint)
const 2163 typedef const GlobalOrdinal* IT;
2170 if (hint < rowinfo.numEntries && colInds(hint) == ind) {
2178 IT beg = colInds.ptr_on_device ();
2179 IT end = beg + rowinfo.numEntries;
2180 IT ptr = beg + rowinfo.numEntries;
2184 std::pair<IT,IT> p = std::equal_range (beg, end, ind);
2185 if (p.first == p.second) {
2192 ptr = std::find (beg, end, ind);
2199 return static_cast<size_t> (ptr - beg);
2202 return Teuchos::OrdinalTraits<size_t>::invalid ();
2207 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2211 const GlobalOrdinal ind,
2212 const size_t hint)
const 2214 auto colInds = this->getGlobalKokkosRowView (rowinfo);
2219 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2224 globalNumEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2225 globalNumDiags_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2226 globalMaxNumRowEntries_ = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2231 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2236 #ifdef HAVE_TPETRA_DEBUG 2237 const global_size_t GSTI = Teuchos::OrdinalTraits<global_size_t>::invalid ();
2238 const size_t STI = Teuchos::OrdinalTraits<size_t>::invalid ();
2239 const char err[] =
"Tpetra::CrsGraph::checkInternalState: Likely internal " 2240 "logic error. Please contact Tpetra team.";
2245 TEUCHOS_TEST_FOR_EXCEPTION(
rowMap_ == null, std::logic_error, err );
2251 TEUCHOS_TEST_FOR_EXCEPTION(
isStorageOptimized() ==
true && indicesAreAllocated() ==
false, std::logic_error, err );
2255 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
false && ( globalNumEntries_ != GSTI || globalNumDiags_ != GSTI || globalMaxNumRowEntries_ != GSTI ), std::logic_error, err );
2257 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
true && ( globalNumEntries_ == GSTI || globalNumDiags_ == GSTI || globalMaxNumRowEntries_ == GSTI ), std::logic_error, err );
2258 TEUCHOS_TEST_FOR_EXCEPTION(
haveGlobalConstants_ ==
true && ( globalNumEntries_ < nodeNumEntries_ || globalNumDiags_ < nodeNumDiags_ || globalMaxNumRowEntries_ < nodeMaxNumRowEntries_ ),
2259 std::logic_error, err );
2261 TEUCHOS_TEST_FOR_EXCEPTION(
2264 std::logic_error, err );
2266 TEUCHOS_TEST_FOR_EXCEPTION(
2267 ! indicesAreAllocated () && (nodeNumAllocated_ != STI ||
2268 nodeNumEntries_ != 0),
2269 std::logic_error, err );
2278 TEUCHOS_TEST_FOR_EXCEPTION(
2282 std::logic_error, err );
2284 TEUCHOS_TEST_FOR_EXCEPTION(
2288 std::logic_error, err );
2293 TEUCHOS_TEST_FOR_EXCEPTION(
2295 indicesAreAllocated () &&
2298 std::logic_error, err );
2303 TEUCHOS_TEST_FOR_EXCEPTION(
2305 indicesAreAllocated () &&
2308 std::logic_error, err );
2311 TEUCHOS_TEST_FOR_EXCEPTION(
2314 std::logic_error, err );
2316 TEUCHOS_TEST_FOR_EXCEPTION(
2318 std::logic_error, err );
2321 TEUCHOS_TEST_FOR_EXCEPTION(
2325 std::logic_error, err);
2327 TEUCHOS_TEST_FOR_EXCEPTION(
2329 std::logic_error, err );
2332 TEUCHOS_TEST_FOR_EXCEPTION(
2333 ! indicesAreAllocated () &&
2337 std::logic_error, err );
2342 TEUCHOS_TEST_FOR_EXCEPTION( (indicesAreLocal_ || indicesAreGlobal_) && ! indicesAreAllocated_, std::logic_error, err );
2344 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreLocal_ ==
true && indicesAreGlobal_ ==
true, std::logic_error, err );
2346 TEUCHOS_TEST_FOR_EXCEPTION(
2348 std::logic_error, err );
2350 TEUCHOS_TEST_FOR_EXCEPTION(
2352 std::logic_error, err );
2354 TEUCHOS_TEST_FOR_EXCEPTION(
2358 std::logic_error, err);
2360 TEUCHOS_TEST_FOR_EXCEPTION(
2364 std::logic_error, err);
2366 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
true && nodeNumAllocated_ == STI, std::logic_error, err );
2368 TEUCHOS_TEST_FOR_EXCEPTION( indicesAreAllocated() ==
false && nodeNumAllocated_ != STI, std::logic_error, err );
2370 if (indicesAreAllocated()) {
2371 size_t actualNumAllocated = 0;
2383 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2386 TEUCHOS_TEST_FOR_EXCEPTION(
2388 std::logic_error, err);
2391 TEUCHOS_TEST_FOR_EXCEPTION(
2393 static_cast<size_t> (
k_lclInds1D_.dimension_0 ()) != actualNumAllocated,
2394 std::logic_error, err );
2395 TEUCHOS_TEST_FOR_EXCEPTION(
2397 static_cast<size_t> (
k_gblInds1D_.dimension_0 ()) != actualNumAllocated,
2398 std::logic_error, err );
2399 TEUCHOS_TEST_FOR_EXCEPTION(actualNumAllocated != nodeNumAllocated_, std::logic_error, err );
2402 #endif // HAVE_TPETRA_DEBUG 2406 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2411 using Teuchos::OrdinalTraits;
2412 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2413 if (
hasRowInfo () && lrow != OrdinalTraits<LocalOrdinal>::invalid ()) {
2415 return rowinfo.numEntries;
2417 return OrdinalTraits<size_t>::invalid ();
2422 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2429 return rowinfo.numEntries;
2431 return Teuchos::OrdinalTraits<size_t>::invalid ();
2436 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2441 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2442 if (
hasRowInfo () && lrow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2444 return rowinfo.allocSize;
2446 return Teuchos::OrdinalTraits<size_t>::invalid ();
2451 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2458 return rowinfo.allocSize;
2460 return Teuchos::OrdinalTraits<size_t>::invalid();
2466 template<
class OutputViewType,
class InputViewType>
2471 CopyOffsets (
const OutputViewType& ptr_out,
2472 const InputViewType& ptr_in) :
2477 KOKKOS_INLINE_FUNCTION
void operator () (
const ptrdiff_t& i)
const {
2478 typedef typename OutputViewType::non_const_value_type value_type;
2481 ptr_out_(i) =
static_cast<value_type
> (ptr_in_(i));
2485 OutputViewType ptr_out_;
2486 InputViewType ptr_in_;
2491 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2492 Teuchos::ArrayRCP<const size_t>
2496 using Kokkos::ViewAllocateWithoutInitializing;
2497 using Kokkos::create_mirror_view;
2498 using Teuchos::ArrayRCP;
2499 typedef typename local_graph_type::row_map_type row_map_type;
2500 typedef typename row_map_type::non_const_value_type row_offset_type;
2501 #ifdef HAVE_TPETRA_DEBUG 2502 const char prefix[] =
"Tpetra::CrsGraph::getNodeRowPtrs: ";
2503 const char suffix[] =
" Please report this bug to the Tpetra developers.";
2504 #endif // HAVE_TPETRA_DEBUG 2505 const size_t size =
k_rowPtrs_.dimension_0 ();
2506 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
2509 return ArrayRCP<const size_t> ();
2512 ArrayRCP<const row_offset_type> ptr_rot;
2513 ArrayRCP<const size_t> ptr_st;
2518 typename row_map_type::HostMirror ptr_h = create_mirror_view (
k_rowPtrs_);
2520 #ifdef HAVE_TPETRA_DEBUG 2521 TEUCHOS_TEST_FOR_EXCEPTION(
2522 ptr_h.dimension_0 () !=
k_rowPtrs_.dimension_0 (), std::logic_error,
2523 prefix <<
"size_t == row_offset_type, but ptr_h.dimension_0() = " 2524 << ptr_h.dimension_0 () <<
" != k_rowPtrs_.dimension_0() = " 2526 TEUCHOS_TEST_FOR_EXCEPTION(
2527 same && size != 0 &&
k_rowPtrs_.ptr_on_device () == NULL, std::logic_error,
2528 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2529 << size <<
" != 0, but k_rowPtrs_.ptr_on_device() == NULL." << suffix);
2530 TEUCHOS_TEST_FOR_EXCEPTION(
2531 same && size != 0 && ptr_h.ptr_on_device () == NULL, std::logic_error,
2532 prefix <<
"size_t == row_offset_type and k_rowPtrs_.dimension_0() = " 2533 << size <<
" != 0, but create_mirror_view(k_rowPtrs_).ptr_on_device() " 2534 "== NULL." << suffix);
2535 #endif // HAVE_TPETRA_DEBUG 2536 ptr_rot = Kokkos::Compat::persistingView (ptr_h);
2539 typedef Kokkos::View<size_t*, device_type> ret_view_type;
2540 ret_view_type ptr_d (ViewAllocateWithoutInitializing (
"ptr"), size);
2541 CopyOffsets<ret_view_type, row_map_type> functor (ptr_d,
k_rowPtrs_);
2542 Kokkos::parallel_for (size, functor);
2543 typename ret_view_type::HostMirror ptr_h = create_mirror_view (ptr_d);
2545 ptr_st = Kokkos::Compat::persistingView (ptr_h);
2547 #ifdef HAVE_TPETRA_DEBUG 2548 TEUCHOS_TEST_FOR_EXCEPTION(
2549 same && size != 0 && ptr_rot.is_null (), std::logic_error,
2550 prefix <<
"size_t == row_offset_type and size = " << size
2551 <<
" != 0, but ptr_rot is null." << suffix);
2552 TEUCHOS_TEST_FOR_EXCEPTION(
2553 ! same && size != 0 && ptr_st.is_null (), std::logic_error,
2554 prefix <<
"size_t != row_offset_type and size = " << size
2555 <<
" != 0, but ptr_st is null." << suffix);
2556 #endif // HAVE_TPETRA_DEBUG 2560 #ifdef HAVE_TPETRA_DEBUG 2561 ArrayRCP<const size_t> retval =
2562 Kokkos::Impl::if_c<same,
2563 ArrayRCP<const row_offset_type>,
2564 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2565 TEUCHOS_TEST_FOR_EXCEPTION(
2566 size != 0 && retval.is_null (), std::logic_error,
2567 prefix <<
"size = " << size <<
" != 0, but retval is null." << suffix);
2570 return Kokkos::Impl::if_c<same,
2571 ArrayRCP<const row_offset_type>,
2572 ArrayRCP<const size_t> >::select (ptr_rot, ptr_st);
2573 #endif // HAVE_TPETRA_DEBUG 2577 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2578 Teuchos::ArrayRCP<const LocalOrdinal>
2586 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2590 const Teuchos::ArrayView<LocalOrdinal>&indices,
2591 size_t& numEntries)
const 2593 using Teuchos::ArrayView;
2594 typedef LocalOrdinal LO;
2595 typedef GlobalOrdinal GO;
2597 TEUCHOS_TEST_FOR_EXCEPTION(
2599 "Tpetra::CrsGraph::getLocalRowCopy: The graph is globally indexed and " 2600 "does not have a column Map yet. That means we don't have local indices " 2601 "for columns yet, so it doesn't make sense to call this method. If the " 2602 "graph doesn't have a column Map yet, you should call fillComplete on " 2604 TEUCHOS_TEST_FOR_EXCEPTION(
2606 "Tpetra::CrsGraph::getLocalRowCopy: graph row information was deleted " 2607 "at fillComplete().");
2609 if (!
getRowMap ()->isNodeLocalElement (localRow)) {
2615 const size_t theNumEntries = rowinfo.numEntries;
2617 TEUCHOS_TEST_FOR_EXCEPTION(
2618 static_cast<size_t> (indices.size ()) < theNumEntries,
2620 "Tpetra::CrsGraph::getLocalRowCopy: The given row " << localRow <<
" has " 2621 << theNumEntries <<
" entries, but indices.size() = " << indices.size ()
2622 <<
", which does not suffice to store the row's indices.");
2624 numEntries = theNumEntries;
2628 std::copy (lview.begin (), lview.begin () + numEntries, indices.begin ());
2633 for (
size_t j = 0; j < numEntries; ++j) {
2650 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2654 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2655 size_t& NumIndices)
const 2657 using Teuchos::ArrayView;
2658 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2661 const LocalOrdinal lrow =
rowMap_->getLocalElement (globalRow);
2667 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2668 lrow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
2670 "GlobalRow (== " << globalRow <<
") does not belong to this process.");
2671 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2673 "Graph row information was deleted at fillComplete().");
2675 NumIndices = rowinfo.numEntries;
2676 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2677 static_cast<size_t> (indices.size ()) < NumIndices, std::runtime_error,
2678 "Specified storage (size==" << indices.size () <<
") does not suffice " 2679 "to hold all entries for this row (NumIndices == " << NumIndices <<
").");
2681 ArrayView<const LocalOrdinal> lview = this->
getLocalView (rowinfo);
2682 for (
size_t j = 0; j < NumIndices; ++j) {
2683 indices[j] =
colMap_->getGlobalElement (lview[j]);
2687 ArrayView<const GlobalOrdinal> gview = this->
getGlobalView (rowinfo);
2688 std::copy (gview.begin (), gview.begin () + NumIndices, indices.begin ());
2693 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2697 Teuchos::ArrayView<const LocalOrdinal>& indices)
const 2699 const char tfecfFuncName[] =
"getLocalRowView: ";
2700 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2702 "currently stored as global indices, so we cannot return a view with " 2703 "local column indices, whether or not the graph has a column Map. If " 2704 "the graph _does_ have a column Map, use getLocalRowCopy() instead.");
2705 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2706 !
hasRowInfo (), std::runtime_error,
"Graph row information was " 2707 "deleted at fillComplete().");
2708 indices = Teuchos::null;
2709 if (
rowMap_->isNodeLocalElement (localRow)) {
2711 if (rowinfo.numEntries > 0) {
2717 indices = indices (0, rowinfo.numEntries);
2720 #ifdef HAVE_TPETRA_DEBUG 2721 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2723 std::logic_error,
": Violated stated post-conditions. Please contact Tpetra team.");
2724 #endif // HAVE_TPETRA_DEBUG 2728 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2732 Teuchos::ArrayView<const GlobalOrdinal>& indices)
const 2734 const char tfecfFuncName[] =
"getGlobalRowView: ";
2735 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2737 "currently stored as local indices, so we cannot return a view with " 2738 "global column indices. Use getGlobalRowCopy() instead.");
2739 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2741 "Graph row information was deleted at fillComplete().");
2745 const LocalOrdinal localRow =
rowMap_->getLocalElement (globalRow);
2746 indices = Teuchos::null;
2747 if (localRow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2749 if (rowInfo.numEntries > 0) {
2750 indices = (this->
getGlobalView (rowInfo)) (0, rowInfo.numEntries);
2753 #ifdef HAVE_TPETRA_DEBUG 2754 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2757 "Violated stated postconditions: indices.size() = " << indices.size ()
2758 <<
" != getNumEntriesInGlobalRow(globalRow=" << globalRow
2760 <<
". Please report this bug to the Tpetra developers.");
2761 #endif // HAVE_TPETRA_DEBUG 2765 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2769 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2771 const char tfecfFuncName[] =
"insertLocalIndices";
2773 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2775 ": requires that fill is active.");
2776 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2778 ": graph indices are global; use insertGlobalIndices().");
2779 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2781 ": cannot insert local indices without a column map.");
2782 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2783 !
rowMap_->isNodeLocalElement (localRow), std::runtime_error,
2784 ": row does not belong to this node.");
2785 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2787 ": graph row information was deleted at fillComplete().");
2788 if (! indicesAreAllocated ()) {
2789 allocateIndices (LocalIndices);
2792 #ifdef HAVE_TPETRA_DEBUG 2798 using Teuchos::Array;
2799 using Teuchos::toString;
2801 typedef typename Teuchos::ArrayView<const LocalOrdinal>::size_type size_type;
2804 Array<LocalOrdinal> badColInds;
2805 bool allInColMap =
true;
2806 for (size_type k = 0; k < indices.size (); ++k) {
2808 allInColMap =
false;
2809 badColInds.push_back (indices[k]);
2812 if (! allInColMap) {
2813 std::ostringstream os;
2814 os <<
"Tpetra::CrsMatrix::insertLocalIndices: You attempted to insert " 2815 "entries in owned row " << localRow <<
", at the following column " 2816 "indices: " << toString (indices) <<
"." << endl;
2817 os <<
"Of those, the following indices are not in the column Map on " 2818 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2819 "the graph has a column Map already, it is invalid to insert entries " 2820 "at those locations.";
2821 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2824 #endif // HAVE_TPETRA_DEBUG 2826 insertLocalIndicesImpl (localRow, indices);
2828 #ifdef HAVE_TPETRA_DEBUG 2829 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2832 ": Violated stated post-conditions. Please contact Tpetra team.");
2837 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2841 const Teuchos::ArrayView<const LocalOrdinal>& indices)
2843 typedef LocalOrdinal LO;
2844 const char tfecfFuncName[] =
"insertLocalIndicesFiltered";
2846 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2848 ": requires that fill is active.");
2849 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2851 ": graph indices are global; use insertGlobalIndices().");
2852 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2853 hasColMap() ==
false, std::runtime_error,
2854 ": cannot insert local indices without a column map.");
2855 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2856 rowMap_->isNodeLocalElement(localRow) ==
false, std::runtime_error,
2857 ": row does not belong to this node.");
2858 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2860 ": graph row information was deleted at fillComplete().");
2861 if (! indicesAreAllocated ()) {
2862 allocateIndices (LocalIndices);
2867 Teuchos::Array<LO> filtered_indices (indices);
2868 SLocalGlobalViews inds_view;
2869 SLocalGlobalNCViews inds_ncview;
2870 inds_ncview.linds = filtered_indices();
2871 const size_t numFilteredEntries =
2872 filterIndices<LocalIndices>(inds_ncview);
2873 inds_view.linds = filtered_indices (0, numFilteredEntries);
2874 insertLocalIndicesImpl(localRow, inds_view.linds);
2877 insertLocalIndicesImpl(localRow, indices);
2879 #ifdef HAVE_TPETRA_DEBUG 2880 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2883 ": Violated stated post-conditions. Please contact Tpetra team.");
2888 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2892 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2894 using Teuchos::ArrayView;
2895 typedef LocalOrdinal LO;
2896 typedef GlobalOrdinal GO;
2897 typedef typename ArrayView<const GO>::size_type size_type;
2898 const char tfecfFuncName[] =
"insertGlobalIndices";
2900 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2902 ": graph indices are local; use insertLocalIndices().");
2903 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2905 ": graph row information was deleted at fillComplete().");
2910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2912 ": You are not allowed to call this method if fill is not active. " 2913 "If fillComplete has been called, you must first call resumeFill " 2914 "before you may insert indices.");
2915 if (! indicesAreAllocated ()) {
2916 allocateIndices (GlobalIndices);
2918 const LO myRow =
rowMap_->getLocalElement (grow);
2919 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2920 #ifdef HAVE_TPETRA_DEBUG 2928 Array<GO> badColInds;
2929 bool allInColMap =
true;
2930 for (size_type k = 0; k < indices.size (); ++k) {
2932 allInColMap =
false;
2933 badColInds.push_back (indices[k]);
2936 if (! allInColMap) {
2937 std::ostringstream os;
2938 os <<
"Tpetra::CrsGraph::insertGlobalIndices: You attempted to insert " 2939 "entries in owned row " << grow <<
", at the following column " 2940 "indices: " << toString (indices) <<
"." << endl;
2941 os <<
"Of those, the following indices are not in the column Map on " 2942 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 2943 "the matrix has a column Map already, it is invalid to insert " 2944 "entries at those locations.";
2945 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
2948 #endif // HAVE_TPETRA_DEBUG 2949 insertGlobalIndicesImpl (myRow, indices);
2952 const size_type numIndices = indices.size ();
2956 std::vector<GO>& nonlocalRow =
nonlocals_[grow];
2957 for (size_type k = 0; k < numIndices; ++k) {
2958 nonlocalRow.push_back (indices[k]);
2961 #ifdef HAVE_TPETRA_DEBUG 2962 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2965 ": Violated stated post-conditions. Please contact Tpetra team.");
2970 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2974 const Teuchos::ArrayView<const GlobalOrdinal>& indices)
2976 using Teuchos::Array;
2977 using Teuchos::ArrayView;
2978 typedef LocalOrdinal LO;
2979 typedef GlobalOrdinal GO;
2980 const char tfecfFuncName[] =
"insertGlobalIndicesFiltered";
2982 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2984 ": graph indices are local; use insertLocalIndices().");
2985 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2987 ": graph row information was deleted at fillComplete().");
2992 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2994 ": You are not allowed to call this method if fill is not active. " 2995 "If fillComplete has been called, you must first call resumeFill " 2996 "before you may insert indices.");
2997 if (! indicesAreAllocated ()) {
2998 allocateIndices (GlobalIndices);
3000 const LO myRow =
rowMap_->getLocalElement (grow);
3001 if (myRow != Teuchos::OrdinalTraits<LO>::invalid ()) {
3004 Array<GO> filtered_indices(indices);
3005 SLocalGlobalViews inds_view;
3006 SLocalGlobalNCViews inds_ncview;
3007 inds_ncview.ginds = filtered_indices();
3008 const size_t numFilteredEntries =
3009 filterIndices<GlobalIndices> (inds_ncview);
3010 inds_view.ginds = filtered_indices (0, numFilteredEntries);
3011 insertGlobalIndicesImpl(myRow, inds_view.ginds);
3014 insertGlobalIndicesImpl(myRow, indices);
3018 typedef typename ArrayView<const GO>::size_type size_type;
3019 const size_type numIndices = indices.size ();
3020 for (size_type k = 0; k < numIndices; ++k) {
3024 #ifdef HAVE_TPETRA_DEBUG 3025 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3028 ": Violated stated post-conditions. Please contact Tpetra team.");
3033 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3038 const char tfecfFuncName[] =
"removeLocalIndices: ";
3039 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3040 !
isFillActive (), std::runtime_error,
"requires that fill is active.");
3041 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3043 "cannot remove indices after optimizeStorage() has been called.");
3044 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3046 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3047 !
rowMap_->isNodeLocalElement (lrow), std::runtime_error,
3048 "Local row " << lrow <<
" is not in the row Map on the calling process.");
3049 if (! indicesAreAllocated ()) {
3050 allocateIndices (LocalIndices);
3055 clearGlobalConstants ();
3059 nodeNumEntries_ -= oldNumEntries;
3063 k_numRowEntries_.template modify<typename t_numRowEntries_::host_mirror_space> ();
3067 #ifdef HAVE_TPETRA_DEBUG 3068 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3070 ! indicesAreAllocated () ||
3072 ": Violated stated post-conditions. Please contact Tpetra team.");
3073 #endif // HAVE_TPETRA_DEBUG 3077 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3081 const typename local_graph_type::entries_type::non_const_type& columnIndices)
3083 const char tfecfFuncName[] =
"setAllIndices: ";
3084 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3086 "The graph must have a column Map before you may call this method.");
3087 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3088 static_cast<size_t> (rowPointers.size ()) != this->
getNodeNumRows () + 1,
3089 std::runtime_error,
"rowPointers.size() = " << rowPointers.size () <<
3090 " != this->getNodeNumRows()+1 = " << (this->
getNodeNumRows () + 1) <<
3096 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3098 std::runtime_error,
"You may not call this method if 1-D data structures " 3099 "are already allocated.");
3101 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3103 std::runtime_error,
"You may not call this method if 2-D data structures " 3104 "are already allocated.");
3108 indicesAreAllocated_ =
true;
3109 indicesAreLocal_ =
true;
3113 nodeNumAllocated_ = localNumEntries;
3114 nodeNumEntries_ = localNumEntries;
3126 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3130 const Teuchos::ArrayRCP<LocalOrdinal>& columnIndices)
3133 typedef typename local_graph_type::row_map_type row_map_type;
3134 typedef typename row_map_type::array_layout layout_type;
3135 typedef typename row_map_type::non_const_value_type row_offset_type;
3136 typedef View<
size_t*, layout_type , Kokkos::HostSpace,
3137 Kokkos::MemoryUnmanaged> input_view_type;
3138 typedef typename row_map_type::non_const_type nc_row_map_type;
3140 const size_t size =
static_cast<size_t> (rowPointers.size ());
3141 const bool same = Kokkos::Impl::is_same<size_t, row_offset_type>::value;
3142 input_view_type ptr_in (rowPointers.getRawPtr (), size);
3144 nc_row_map_type ptr_rot (
"Tpetra::CrsGraph::ptr", size);
3150 input_view_type ptr_decoy (rowPointers.getRawPtr (), size);
3153 input_view_type>::select (ptr_rot, ptr_decoy),
3158 const bool inHostMemory =
3159 Kokkos::Impl::is_same<
typename row_map_type::memory_space,
3160 Kokkos::HostSpace>::value;
3163 typedef CopyOffsets<nc_row_map_type, input_view_type> functor_type;
3164 functor_type functor (ptr_rot, ptr_in);
3165 Kokkos::parallel_for (size, functor);
3172 View<size_t*, layout_type ,execution_space > ptr_st (
"Tpetra::CrsGraph::ptr", size);
3177 typedef CopyOffsets<nc_row_map_type,
3178 View<size_t*, layout_type, execution_space> > functor_type;
3179 functor_type functor (ptr_rot, ptr_st);
3180 Kokkos::parallel_for (size, functor);
3184 Kokkos::View<LocalOrdinal*, layout_type , execution_space > k_ind =
3185 Kokkos::Compat::getKokkosViewDeepCopy<device_type> (columnIndices ());
3190 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3194 size_t& boundForAllLocalRows,
3195 bool& boundSameForAllLocalRows)
const 3200 Teuchos::ArrayRCP<const size_t> numEntriesPerRow;
3201 size_t numEntriesForAll = 0;
3202 bool allRowsSame =
true;
3204 const ptrdiff_t numRows =
static_cast<ptrdiff_t
> (this->
getNodeNumRows ());
3206 if (! this->indicesAreAllocated ()) {
3209 allRowsSame =
false;
3217 numEntriesPerRow = Kokkos::Compat::persistingView (
k_numRowEntries_.h_view);
3218 allRowsSame =
false;
3220 else if (this->nodeNumAllocated_ == 0) {
3221 numEntriesForAll = 0;
3227 TEUCHOS_TEST_FOR_EXCEPTION(
3229 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 3230 "The graph is not StaticProfile, but storage appears to be optimized. " 3231 "Please report this bug to the Tpetra developers.");
3232 TEUCHOS_TEST_FOR_EXCEPTION(
3233 numRows != 0 &&
k_rowPtrs_.dimension_0 () == 0, std::logic_error,
3234 "Tpetra::CrsGraph::getNumEntriesPerRowUpperBound: " 3235 "The graph has " << numRows <<
" (> 0) row" << (numRows != 1 ?
"s" :
"")
3236 <<
" on the calling process, but the k_rowPtrs_ array has zero entries. " 3237 "Please report this bug to the Tpetra developers.");
3239 Teuchos::ArrayRCP<size_t> numEnt;
3241 numEnt = Teuchos::arcp<size_t> (numRows);
3246 bool allRowsReallySame =
false;
3247 for (ptrdiff_t i = 0; i < numRows; ++i) {
3249 if (i != 0 && numEnt[i] != numEnt[i-1]) {
3250 allRowsReallySame =
false;
3253 if (allRowsReallySame) {
3255 numEntriesForAll = 0;
3257 numEntriesForAll = numEnt[1] - numEnt[0];
3262 numEntriesPerRow = numEnt;
3263 allRowsSame =
false;
3267 TEUCHOS_TEST_FOR_EXCEPTION(
3268 numEntriesForAll != 0 && numEntriesPerRow.size () != 0, std::logic_error,
3269 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3270 "numEntriesForAll and numEntriesPerRow are not consistent. The former " 3271 "is nonzero (" << numEntriesForAll <<
"), but the latter has nonzero " 3272 "size " << numEntriesPerRow.size () <<
". " 3273 "Please report this bug to the Tpetra developers.");
3274 TEUCHOS_TEST_FOR_EXCEPTION(
3275 numEntriesForAll != 0 && ! allRowsSame, std::logic_error,
3276 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3277 "numEntriesForAll and allRowsSame are not consistent. The former " 3278 "is nonzero (" << numEntriesForAll <<
"), but the latter is false. " 3279 "Please report this bug to the Tpetra developers.");
3280 TEUCHOS_TEST_FOR_EXCEPTION(
3281 numEntriesPerRow.size () != 0 && allRowsSame, std::logic_error,
3282 "Tpetra::CrsGraph::getNumEntriesPerLocalRowUpperBound: " 3283 "numEntriesPerRow and allRowsSame are not consistent. The former has " 3284 "nonzero length " << numEntriesForAll <<
", but the latter is true. " 3285 "Please report this bug to the Tpetra developers.");
3287 boundPerLocalRow = numEntriesPerRow;
3288 boundForAllLocalRows = numEntriesForAll;
3289 boundSameForAllLocalRows = allRowsSame;
3294 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3299 using Teuchos::Array;
3301 using Teuchos::Comm;
3302 using Teuchos::gatherAll;
3303 using Teuchos::ireceive;
3304 using Teuchos::isend;
3305 using Teuchos::outArg;
3306 using Teuchos::REDUCE_MAX;
3307 using Teuchos::reduceAll;
3308 using Teuchos::toString;
3309 using Teuchos::waitAll;
3311 using std::make_pair;
3313 typedef GlobalOrdinal GO;
3314 typedef typename std::map<GO, std::vector<GO> >::const_iterator NLITER;
3315 typedef typename Array<GO>::size_type size_type;
3317 const char tfecfFuncName[] =
"globalAssemble";
3318 RCP<const Comm<int> > comm =
getComm();
3320 const int numImages = comm->getSize();
3321 const int myImageID = comm->getRank();
3322 #ifdef HAVE_TPETRA_DEBUG 3323 Teuchos::barrier (*comm);
3324 #endif // HAVE_TPETRA_DEBUG 3326 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( !
isFillActive(), std::runtime_error,
3327 ": requires that fill is active.");
3330 size_t MyNonlocals =
nonlocals_.size(), MaxGlobalNonlocals;
3331 reduceAll (*comm, REDUCE_MAX, MyNonlocals, outArg (MaxGlobalNonlocals));
3332 if (MaxGlobalNonlocals == 0) {
3344 Array<pair<int, GO> > IdsAndRows;
3345 std::map<GO, int> NLR2Id;
3346 Teuchos::SerialDenseMatrix<int, char> globalNeighbors;
3347 Array<int> sendIDs, recvIDs;
3352 std::set<GO> setOfRows;
3354 setOfRows.insert (iter->first);
3357 NLRs.resize (setOfRows.size ());
3358 std::copy (setOfRows.begin (), setOfRows.end (), NLRs.begin ());
3361 Array<int> NLRIds(NLRs.size());
3364 rowMap_->getRemoteIndexList (NLRs (), NLRIds ());
3367 reduceAll<int, int> (*comm, REDUCE_MAX, lclerror, outArg (gblerror));
3368 if (gblerror != 0) {
3369 const int myRank = comm->getRank ();
3370 std::ostringstream os;
3371 os <<
"On one or more processes in the communicator, " 3372 <<
"there were insertions into rows of the graph that do not " 3373 <<
"exist in the row Map on any process in the communicator." 3374 << endl <<
"This process " << myRank <<
" is " 3375 << (lclerror == 0 ?
"not " :
"") <<
"one of those offending " 3376 <<
"processes." << endl;
3377 if (lclerror != 0) {
3381 Array<GO> invalidNonlocalRows;
3382 for (size_type k = 0; k < NLRs.size (); ++k) {
3383 if (NLRIds[k] == -1) {
3384 invalidNonlocalRows.push_back (NLRs[k]);
3387 const size_type numInvalid = invalidNonlocalRows.size ();
3388 os <<
"On this process, " << numInvalid <<
" nonlocal row" 3389 << (numInvalid != 1 ?
"s " :
" ") <<
" were inserted that are " 3390 <<
"not in the row Map on any process." << endl;
3392 if (numInvalid <= 100) {
3393 os <<
"Offending row indices: " 3394 << toString (invalidNonlocalRows ()) << endl;
3397 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3398 gblerror != 0, std::runtime_error,
3399 ": nonlocal entries correspond to invalid rows." 3400 << endl << os.str ());
3407 IdsAndRows.reserve(NLRs.size());
3408 Array<char> localNeighbors(numImages, 0);
3409 typename Array<GO>::const_iterator nlr;
3410 typename Array<int>::const_iterator id;
3411 for (nlr = NLRs.begin(),
id = NLRIds.begin();
3412 nlr != NLRs.end(); ++nlr, ++id) {
3414 localNeighbors[*id] = 1;
3416 IdsAndRows.push_back(make_pair(*
id,*nlr));
3418 for (
int j=0; j<numImages; ++j) {
3419 if (localNeighbors[j]) {
3420 sendIDs.push_back(j);
3424 std::sort(IdsAndRows.begin(),IdsAndRows.end());
3426 globalNeighbors.shapeUninitialized(numImages,numImages);
3427 gatherAll (*
getComm(), numImages, localNeighbors.getRawPtr(),
3428 numImages * numImages, globalNeighbors.values());
3440 for (
int j=0; j<numImages; ++j) {
3441 if (globalNeighbors(myImageID,j)) {
3442 recvIDs.push_back(j);
3445 const size_t numRecvs = recvIDs.size();
3450 Array<pair<GO, GO> > IJSendBuffer;
3451 Array<size_t> sendSizes(sendIDs.size(), 0);
3452 size_t numSends = 0;
3453 for (
typename Array<pair<int, GO> >::const_iterator IdAndRow = IdsAndRows.begin();
3454 IdAndRow != IdsAndRows.end(); ++IdAndRow) {
3455 int id = IdAndRow->first;
3456 GO row = IdAndRow->second;
3458 if (sendIDs[numSends] !=
id) {
3460 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(sendIDs[numSends] !=
id,
3461 std::logic_error,
": internal logic error. Contact Tpetra team.");
3464 for (
typename std::vector<GO>::const_iterator j =
nonlocals_[row].begin ();
3466 IJSendBuffer.push_back (pair<GlobalOrdinal, GlobalOrdinal> (row, *j));
3467 sendSizes[numSends]++;
3470 if (IdsAndRows.size() > 0) {
3473 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3474 as<
typename Array<int>::size_type> (numSends) != sendIDs.size (),
3475 std::logic_error,
": internal logic error. Contact Tpetra team.");
3487 Array<RCP<Teuchos::CommRequest<int> > > requests;
3490 for (
size_t s = 0; s < numSends ; ++s) {
3493 requests.push_back (isend<int, size_t> (*comm,
3494 rcp (&sendSizes[s],
false),
3498 Array<size_t> recvSizes (numRecvs);
3499 for (
size_t r = 0; r < numRecvs; ++r) {
3502 requests.push_back (ireceive (*comm, rcp (&recvSizes[r],
false), recvIDs[r]));
3505 if (! requests.empty()) {
3506 waitAll (*comm, requests());
3508 #ifdef HAVE_TPETRA_DEBUG 3509 Teuchos::barrier (*comm);
3510 #endif // HAVE_TPETRA_DEBUG 3513 requests.resize (0);
3519 Array<ArrayView<pair<GO,GO> > > sendBuffers(numSends,null);
3522 for (
size_t s=0; s<numSends; ++s) {
3523 sendBuffers[s] = IJSendBuffer(cur,sendSizes[s]);
3524 cur += sendSizes[s];
3528 for (
size_t s=0; s < numSends ; ++s)
3532 ArrayRCP<pair<GO,GO> > tmpSendBuf =
3533 arcp (sendBuffers[s].getRawPtr(), 0, sendBuffers[s].size(),
false);
3534 requests.push_back (isend<
int, pair<GO,GO> > (*comm, tmpSendBuf, sendIDs[s]));
3538 size_t totalRecvSize = std::accumulate (recvSizes.begin(), recvSizes.end(), 0);
3539 Array<pair<GO,GO> > IJRecvBuffer (totalRecvSize);
3541 Array<ArrayView<pair<GO,GO> > > recvBuffers (numRecvs, null);
3544 for (
size_t r=0; r<numRecvs; ++r) {
3545 recvBuffers[r] = IJRecvBuffer(cur,recvSizes[r]);
3546 cur += recvSizes[r];
3550 for (
size_t r = 0; r < numRecvs; ++r) {
3553 ArrayRCP<pair<GO,GO> > tmpRecvBuf =
3554 arcp (recvBuffers[r].getRawPtr(), 0, recvBuffers[r].size(),
false);
3555 requests.push_back (ireceive (*comm, tmpRecvBuf, recvIDs[r]));
3558 if (! requests.empty()) {
3559 waitAll (*comm, requests());
3561 #ifdef HAVE_TPETRA_DEBUG 3562 Teuchos::barrier (*comm);
3563 #endif // HAVE_TPETRA_DEBUG 3573 for (
typename Array<pair<GO,GO> >::const_iterator ij = IJRecvBuffer.begin();
3574 ij != IJRecvBuffer.end(); ++ij)
3582 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3587 const char tfecfFuncName[] =
"resumeFill";
3588 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
hasRowInfo(), std::runtime_error,
3589 ": Sorry, you cannot resume fill of the CrsGraph, since the graph's row " 3590 "information was deleted in fillComplete().");
3592 #ifdef HAVE_TPETRA_DEBUG 3593 Teuchos::barrier( *
rowMap_->getComm() );
3594 #endif // HAVE_TPETRA_DEBUG 3595 clearGlobalConstants();
3602 fillComplete_ =
false;
3603 #ifdef HAVE_TPETRA_DEBUG 3604 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3606 "::resumeFill(): At end of method, either fill is not active or fill is " 3607 "complete. This violates stated post-conditions. Please report this bug " 3608 "to the Tpetra developers.");
3609 #endif // HAVE_TPETRA_DEBUG 3613 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3628 Teuchos::RCP<const map_type> domMap = this->
getDomainMap ();
3629 if (domMap.is_null ()) {
3632 Teuchos::RCP<const map_type> ranMap = this->
getRangeMap ();
3633 if (ranMap.is_null ()) {
3640 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3644 const Teuchos::RCP<const map_type>& rangeMap,
3645 const Teuchos::RCP<Teuchos::ParameterList>& params)
3647 const char tfecfFuncName[] =
"fillComplete";
3649 #ifdef HAVE_TPETRA_DEBUG 3650 rowMap_->getComm ()->barrier ();
3651 #endif // HAVE_TPETRA_DEBUG 3654 std::runtime_error,
": Graph fill state must be active (isFillActive() " 3655 "must be true) before calling fillComplete().");
3657 const int numProcs =
getComm ()->getSize ();
3665 if (! params.is_null ()) {
3666 if (params->isParameter (
"sort column map ghost gids")) {
3668 params->get<
bool> (
"sort column map ghost gids",
3671 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3673 params->get<
bool> (
"Sort column Map ghost GIDs",
3680 bool assertNoNonlocalInserts =
false;
3681 if (! params.is_null ()) {
3682 assertNoNonlocalInserts =
3683 params->get<
bool> (
"No Nonlocal Changes", assertNoNonlocalInserts);
3689 if (! indicesAreAllocated ()) {
3692 allocateIndices (LocalIndices);
3695 allocateIndices (GlobalIndices);
3703 const bool mayNeedGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3704 if (mayNeedGlobalAssemble) {
3710 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3711 numProcs > 1 &&
nonlocals_.size() > 0, std::runtime_error,
3712 ":" << std::endl <<
"The graph's communicator contains only one " 3713 "process, but there are nonlocal entries. " << std::endl <<
3714 "This probably means that invalid entries were added to the graph.");
3731 makeIndicesLocal ();
3743 makeImportExport ();
3744 computeGlobalConstants ();
3745 fillLocalGraph (params);
3746 fillComplete_ =
true;
3748 #ifdef HAVE_TPETRA_DEBUG 3749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3751 ": Violated stated post-conditions. Please contact Tpetra team.");
3758 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3762 const Teuchos::RCP<const map_type>& rangeMap,
3763 const Teuchos::RCP<const import_type>& importer,
3764 const Teuchos::RCP<const export_type>& exporter,
3765 const Teuchos::RCP<Teuchos::ParameterList>& params)
3767 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
3768 #ifdef HAVE_TPETRA_MMM_TIMINGS 3770 if(!params.is_null())
3771 label = params->get(
"Timer Label",label);
3772 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
3773 using Teuchos::TimeMonitor;
3774 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Setup"))));
3778 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3779 domainMap.is_null () || rangeMap.is_null (),
3780 std::runtime_error,
"The input domain Map and range Map must be nonnull.");
3781 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3783 "method unless the graph is StaticProfile.");
3784 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3786 "call this method unless the graph has a column Map.");
3787 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3789 std::runtime_error,
"The calling process has getNodeNumRows() = " 3790 <<
getNodeNumRows () <<
" > 0 rows, but the row offsets array has not " 3792 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3794 std::runtime_error,
"The row offsets array has length " <<
3795 k_rowPtrs_.dimension_0 () <<
" != getNodeNumRows()+1 = " <<
3807 nodeNumEntries_ = nodeNumAllocated_;
3821 indicesAreAllocated_ =
true;
3826 indicesAreLocal_ =
true;
3827 indicesAreGlobal_ =
false;
3830 #ifdef HAVE_TPETRA_MMM_TIMINGS 3831 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-Maps"))));
3840 #ifdef HAVE_TPETRA_MMM_TIMINGS 3841 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckI"))));
3846 if (importer != Teuchos::null) {
3847 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3848 ! importer->getSourceMap ()->isSameAs (*
getDomainMap ()) ||
3849 ! importer->getTargetMap ()->isSameAs (*
getColMap ()),
3850 std::invalid_argument,
": importer does not match matrix maps.");
3855 #ifdef HAVE_TPETRA_MMM_TIMINGS 3856 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXcheckE"))));
3859 if (exporter != Teuchos::null) {
3860 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3861 ! exporter->getSourceMap ()->isSameAs (*
getRowMap ()) ||
3862 ! exporter->getTargetMap ()->isSameAs (*
getRangeMap ()),
3863 std::invalid_argument,
": exporter does not match matrix maps.");
3867 #ifdef HAVE_TPETRA_MMM_TIMINGS 3868 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-mIXmake"))));
3871 makeImportExport ();
3874 #ifdef HAVE_TPETRA_MMM_TIMINGS 3875 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cGC"))));
3877 computeGlobalConstants ();
3880 #ifdef HAVE_TPETRA_MMM_TIMINGS 3881 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-fLG"))));
3883 fillLocalGraph (params);
3884 fillComplete_ =
true;
3886 #ifdef HAVE_TPETRA_MMM_TIMINGS 3887 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-G-cIS"))));
3893 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3896 fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params)
3898 using Kokkos::create_mirror_view;
3899 using Teuchos::ArrayRCP;
3900 using Teuchos::null;
3903 typedef ArrayRCP<size_t>::size_type size_type;
3904 typedef t_numRowEntries_ row_entries_type;
3905 typedef typename local_graph_type::row_map_type row_map_type;
3906 typedef typename row_map_type::non_const_type non_const_row_map_type;
3907 typedef typename local_graph_type::entries_type::non_const_type lclinds_1d_type;
3916 non_const_row_map_type k_ptrs;
3917 row_map_type k_ptrs_const;
3918 lclinds_1d_type k_inds;
3925 typename row_entries_type::t_host h_numRowEnt = k_numRowEnt.h_view;
3927 bool requestOptimizedStorage =
true;
3928 if (! params.is_null () && ! params->get (
"Optimize Storage",
true)) {
3929 requestOptimizedStorage =
false;
3939 TEUCHOS_TEST_FOR_EXCEPTION(
3940 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
3941 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph (called from " 3942 "fillComplete or expertStaticFillComplete): For the DynamicProfile " 3943 "branch, k_numRowEnt has the wrong length. " 3944 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
3945 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
3953 size_t lclTotalNumEntries = 0;
3955 typename non_const_row_map_type::HostMirror h_ptrs;
3958 k_ptrs = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows+1);
3959 k_ptrs_const = k_ptrs;
3963 h_ptrs = create_mirror_view (k_ptrs);
3965 for (size_type i = 0; i < static_cast<size_type> (lclNumRows); ++i) {
3966 const size_t numEnt = h_numRowEnt(i);
3967 lclTotalNumEntries += numEnt;
3968 h_ptrs(i+1) = h_ptrs(i) + numEnt;
3973 TEUCHOS_TEST_FOR_EXCEPTION(
3974 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
3975 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile " 3976 "branch, after packing k_ptrs, k_ptrs.dimension_0() = " 3977 << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 3978 << (lclNumRows+1) <<
".");
3979 TEUCHOS_TEST_FOR_EXCEPTION(
3980 static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
3981 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile " 3982 "branch, after packing h_ptrs, h_ptrs.dimension_0() = " 3983 << h_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 3984 << (lclNumRows+1) <<
".");
3986 TEUCHOS_TEST_FOR_EXCEPTION(
3987 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
3988 "Tpetra::CrsGraph::fillLocalGraph: In DynamicProfile branch, after " 3989 "packing k_ptrs, k_ptrs(lclNumRows = " << lclNumRows <<
") = " <<
3990 k_ptrs(lclNumRows) <<
" != total number of entries on the calling " 3991 "process = " << lclTotalNumEntries <<
".");
3994 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
3996 typename lclinds_1d_type::HostMirror h_inds = create_mirror_view (k_inds);
3998 for (
size_t row = 0; row < lclNumRows; ++row) {
3999 const size_t numEnt = h_numRowEnt(row);
4002 h_inds.ptr_on_device () + h_ptrs(row));
4007 if (k_ptrs.dimension_0 () != 0) {
4008 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
4009 TEUCHOS_TEST_FOR_EXCEPTION(
4010 static_cast<size_t> (k_ptrs(numOffsets-1)) != k_inds.dimension_0 (),
4011 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 4012 "In DynamicProfile branch, after packing, k_ptrs(" << (numOffsets-1)
4013 <<
") = " << k_ptrs(numOffsets-1) <<
" != k_inds.dimension_0() = " 4014 << k_inds.dimension_0 () <<
".");
4024 TEUCHOS_TEST_FOR_EXCEPTION(
4025 k_rowPtrs_.dimension_0 () == 0, std::logic_error,
4026 "k_rowPtrs_ has size zero, but shouldn't");
4027 TEUCHOS_TEST_FOR_EXCEPTION(
4028 k_rowPtrs_.dimension_0 () != lclNumRows + 1, std::logic_error,
4029 "Tpetra::CrsGraph::fillLocalGraph: k_rowPtrs_ has size " 4030 <<
k_rowPtrs_.dimension_0 () <<
" != (lclNumRows + 1) = " 4031 << (lclNumRows + 1) <<
".")
4033 const size_t numOffsets =
k_rowPtrs_.dimension_0 ();
4035 TEUCHOS_TEST_FOR_EXCEPTION(
4038 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 4039 "numOffsets = " << numOffsets <<
" != 0 and " 4040 "k_lclInds1D_.dimension_0() = " <<
k_lclInds1D_.dimension_0 ()
4041 <<
" != k_rowPtrs_(" << numOffsets <<
") = " 4045 if (nodeNumEntries_ != nodeNumAllocated_) {
4052 TEUCHOS_TEST_FOR_EXCEPTION(
4053 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
4054 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph (called from " 4055 "fillComplete or expertStaticFillComplete): In StaticProfile " 4056 "unpacked branch, k_numRowEnt has the wrong length. " 4057 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
4058 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
4061 const size_t numOffsets =
4062 static_cast<size_t> (
k_rowPtrs_.dimension_0 ());
4063 TEUCHOS_TEST_FOR_EXCEPTION(
4065 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 4066 "In StaticProfile branch, before allocating or packing, " 4067 "k_rowPtrs_(" << (numOffsets-1) <<
") = " 4068 <<
k_rowPtrs_(numOffsets-1) <<
" != k_lclInds1D_.dimension_0() = " 4078 size_t lclTotalNumEntries = 0;
4081 k_ptrs = non_const_row_map_type (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
4082 k_ptrs_const = k_ptrs;
4089 typename non_const_row_map_type::HostMirror h_k_ptrs =
4090 create_mirror_view (k_ptrs);
4092 for (
size_t i = 0; i < lclNumRows; ++i) {
4093 const size_t numEnt = h_numRowEnt(i);
4094 lclTotalNumEntries += numEnt;
4095 h_k_ptrs(i+1) = h_k_ptrs(i) + numEnt;
4100 TEUCHOS_TEST_FOR_EXCEPTION(
4101 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
4102 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: In " 4103 "StaticProfile unpacked branch, after allocating k_ptrs, " 4104 "k_ptrs.dimension_0() = " << k_ptrs.dimension_0 () <<
" != " 4105 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
4107 TEUCHOS_TEST_FOR_EXCEPTION(
4108 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
4109 "Tpetra::CrsGraph::fillLocalGraph: In StaticProfile unpacked " 4110 "branch, after filling k_ptrs, k_ptrs(lclNumRows=" << lclNumRows
4111 <<
") = " << k_ptrs(lclNumRows) <<
" != total number of entries on " 4112 "the calling process = " << lclTotalNumEntries <<
".");
4115 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
4127 typedef pack_functor<typename local_graph_type::entries_type::non_const_type, row_map_type> inds_packer_type;
4129 Kokkos::parallel_for (lclNumRows, f);
4131 TEUCHOS_TEST_FOR_EXCEPTION(
4132 k_ptrs.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsGraph::" 4133 "fillLocalGraph: In StaticProfile \"Optimize Storage\" = true branch," 4134 " after packing, k_ptrs.dimension_0() = 0. This probably means that " 4135 "k_rowPtrs_ was never allocated.");
4136 if (k_ptrs.dimension_0 () != 0) {
4137 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
4138 TEUCHOS_TEST_FOR_EXCEPTION(
4139 static_cast<size_t> (k_ptrs(numOffsets - 1)) != k_inds.dimension_0 (),
4140 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 4141 "In StaticProfile \"Optimize Storage\"=true branch, after packing, " 4142 "k_ptrs(" << (numOffsets-1) <<
") = " << k_ptrs(numOffsets-1) <<
4143 " != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
4150 TEUCHOS_TEST_FOR_EXCEPTION(
4151 k_ptrs_const.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsGraph::" 4152 "fillLocalGraph: In StaticProfile \"Optimize Storage\" = " 4153 "false branch, k_ptrs_const.dimension_0() = 0. This probably means that " 4154 "k_rowPtrs_ was never allocated.");
4155 if (k_ptrs_const.dimension_0 () != 0) {
4156 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
4157 TEUCHOS_TEST_FOR_EXCEPTION(
4158 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
4159 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: " 4160 "In StaticProfile \"Optimize Storage\" = false branch, " 4161 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets - 1)
4162 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
4168 TEUCHOS_TEST_FOR_EXCEPTION(
4169 static_cast<size_t> (k_ptrs_const.dimension_0 ()) != lclNumRows + 1,
4170 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: After packing, " 4171 "k_ptrs_const.dimension_0() = " << k_ptrs_const.dimension_0 ()
4172 <<
" != lclNumRows+1 = " << (lclNumRows+1) <<
".");
4173 if (k_ptrs_const.dimension_0 () != 0) {
4174 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
4175 TEUCHOS_TEST_FOR_EXCEPTION(
4176 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
4177 std::logic_error,
"Tpetra::CrsGraph::fillLocalGraph: After packing, " 4178 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets-1)
4179 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
4182 if (requestOptimizedStorage) {
4197 nodeNumAllocated_ = nodeNumEntries_;
4216 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4228 const char tfecfFuncName[] =
"replaceColMap: ";
4229 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4231 "Requires matching maps and non-static graph.");
4235 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4239 const Teuchos::RCP<const import_type>& newImport,
4240 const bool sortIndicesInEachRow)
4242 using Teuchos::REDUCE_MIN;
4243 using Teuchos::reduceAll;
4245 typedef GlobalOrdinal GO;
4246 typedef LocalOrdinal LO;
4247 typedef typename local_graph_type::entries_type::non_const_type col_inds_type;
4248 const char tfecfFuncName[] =
"reindexColumns: ";
4250 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4251 isFillComplete (), std::runtime_error,
"The graph is fill complete " 4252 "(isFillComplete() returns true). You must call resumeFill() before " 4253 "you may call this method.");
4286 bool allCurColIndsValid =
true;
4291 bool localSuffices =
true;
4299 typename local_graph_type::entries_type::non_const_type newLclInds1D;
4300 Teuchos::ArrayRCP<Teuchos::Array<LO> > newLclInds2D;
4305 if (indicesAreAllocated ()) {
4311 RCP<node_type> node =
getRowMap ()->getNode ();
4313 col_inds_type (
"Tpetra::CrsGraph::ind", nodeNumAllocated_);
4315 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4317 const size_t beg = rowInfo.offset1D;
4318 const size_t end = beg + rowInfo.numEntries;
4319 for (
size_t k = beg; k < end; ++k) {
4323 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4324 allCurColIndsValid =
false;
4332 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4333 allCurColIndsValid =
false;
4337 const LO newLclCol = newColMap->getLocalElement (gblCol);
4338 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4339 localSuffices =
false;
4344 newLclInds1D(k) = newLclCol;
4353 newLclInds2D = Teuchos::arcp<Teuchos::Array<LO> > (lclNumRows);
4356 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4358 newLclInds2D.resize (rowInfo.allocSize);
4360 Teuchos::ArrayView<const LO> oldLclRowView =
getLocalView (rowInfo);
4361 Teuchos::ArrayView<LO> newLclRowView = (newLclInds2D[lclRow]) ();
4363 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4364 const LO oldLclCol = oldLclRowView[k];
4365 if (oldLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4366 allCurColIndsValid =
false;
4373 if (gblCol == Teuchos::OrdinalTraits<GO>::invalid ()) {
4374 allCurColIndsValid =
false;
4378 const LO newLclCol = newColMap->getLocalElement (gblCol);
4379 if (newLclCol == Teuchos::OrdinalTraits<LO>::invalid ()) {
4380 localSuffices =
false;
4383 newLclRowView[k] = newLclCol;
4395 allCurColIndsValid =
false;
4412 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4414 Teuchos::ArrayView<const GO> oldGblRowView =
getGlobalView (rowInfo);
4415 for (
size_t k = 0; k < rowInfo.numEntries; ++k) {
4416 const GO gblCol = oldGblRowView[k];
4417 if (! newColMap->isNodeGlobalElement (gblCol)) {
4418 localSuffices =
false;
4428 lclSuccess[0] = allCurColIndsValid ? 1 : 0;
4429 lclSuccess[1] = localSuffices ? 1 : 0;
4433 RCP<const Teuchos::Comm<int> > comm =
4435 if (! comm.is_null ()) {
4436 reduceAll<int, int> (*comm, REDUCE_MIN, 2, lclSuccess, gblSuccess);
4439 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4440 gblSuccess[0] == 0, std::runtime_error,
"It is not possible to continue." 4441 " The most likely reason is that the graph is locally indexed, but the " 4442 "column Map is missing (null) on some processes, due to a previous call " 4443 "to replaceColMap().");
4445 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4446 gblSuccess[1] == 0, std::runtime_error,
"On some process, the graph " 4447 "contains column indices that are in the old column Map, but not in the " 4448 "new column Map (on that process). This method does NOT redistribute " 4449 "data; it does not claim to do the work of an Import or Export operation." 4450 " This means that for all processess, the calling process MUST own all " 4451 "column indices, in both the old column Map and the new column Map. In " 4452 "this case, you will need to do an Import or Export operation to " 4453 "redistribute data.");
4469 if (sortIndicesInEachRow) {
4481 if (newImport.is_null ()) {
4503 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4507 const Teuchos::RCP<const import_type>& newImporter)
4509 const char prefix[] =
"Tpetra::CrsGraph::replaceDomainMapAndImporter: ";
4510 TEUCHOS_TEST_FOR_EXCEPTION(
4511 colMap_.is_null (), std::invalid_argument, prefix <<
"You may not call " 4512 "this method unless the graph already has a column Map.");
4513 TEUCHOS_TEST_FOR_EXCEPTION(
4514 newDomainMap.is_null (), std::invalid_argument,
4515 prefix <<
"The new domain Map must be nonnull.");
4517 #ifdef HAVE_TPETRA_DEBUG 4518 if (newImporter.is_null ()) {
4523 const bool colSameAsDom =
colMap_->isSameAs (*newDomainMap);
4524 TEUCHOS_TEST_FOR_EXCEPTION(
4525 colSameAsDom, std::invalid_argument,
"If the new Import is null, " 4526 "then the new domain Map must be the same as the current column Map.");
4529 const bool colSameAsTgt =
4530 colMap_->isSameAs (* (newImporter->getTargetMap ()));
4531 const bool newDomSameAsSrc =
4532 newDomainMap->isSameAs (* (newImporter->getSourceMap ()));
4533 TEUCHOS_TEST_FOR_EXCEPTION(
4534 ! colSameAsTgt || ! newDomSameAsSrc, std::invalid_argument,
"If the " 4535 "new Import is nonnull, then the current column Map must be the same " 4536 "as the new Import's target Map, and the new domain Map must be the " 4537 "same as the new Import's source Map.");
4539 #endif // HAVE_TPETRA_DEBUG 4545 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4553 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4561 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4567 using Teuchos::outArg;
4568 using Teuchos::reduceAll;
4569 typedef LocalOrdinal LO;
4570 typedef GlobalOrdinal GO;
4573 #ifdef HAVE_TPETRA_DEBUG 4574 TEUCHOS_TEST_FOR_EXCEPTION(!
hasColMap(), std::logic_error,
"Tpetra::" 4575 "CrsGraph::computeGlobalConstants: At this point, the graph should have " 4576 "a column Map, but it does not. Please report this bug to the Tpetra " 4578 #endif // HAVE_TPETRA_DEBUG 4596 nodeMaxNumRowEntries_ = 0;
4613 if (indicesAreAllocated () && nodeNumAllocated_ > 0) {
4614 const LO numLocalRows =
static_cast<LO
> (this->
getNodeNumRows ());
4615 for (LO localRow = 0; localRow < numLocalRows; ++localRow) {
4627 typename ArrayView<const LO>::iterator beg, end, cur;
4628 beg = rview.begin();
4629 end = beg + rowInfo.numEntries;
4631 for (cur = beg; cur != end; ++cur) {
4633 if (rlcid == *cur) ++nodeNumDiags_;
4640 const size_t smallestCol =
static_cast<size_t> (*beg);
4641 const size_t largestCol =
static_cast<size_t> (*(end - 1));
4643 if (smallestCol < static_cast<size_t> (localRow)) {
4646 if (static_cast<size_t> (localRow) < largestCol) {
4651 nodeMaxNumRowEntries_ = std::max (nodeMaxNumRowEntries_, rowInfo.numEntries);
4674 lcl[0] =
static_cast<GST
> (nodeNumEntries_);
4675 lcl[1] =
static_cast<GST
> (nodeNumDiags_);
4676 reduceAll<int,GST> (*
getComm (), Teuchos::REDUCE_SUM,
4678 globalNumEntries_ = gbl[0];
4679 globalNumDiags_ = gbl[1];
4680 reduceAll<int,GST> (*
getComm (), Teuchos::REDUCE_MAX,
4681 static_cast<GST
> (nodeMaxNumRowEntries_),
4682 outArg (globalMaxNumRowEntries_));
4688 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4693 using Teuchos::arcp;
4694 using Teuchos::Array;
4695 typedef LocalOrdinal LO;
4696 typedef GlobalOrdinal GO;
4697 typedef typename local_graph_type::entries_type::non_const_type
4699 typedef Kokkos::View<GlobalOrdinal*,
4700 typename lcl_col_inds_type::array_layout,
4702 const char tfecfFuncName[] =
"makeIndicesLocal";
4704 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4705 ! this->
hasColMap (), std::logic_error,
": The graph does not have a " 4706 "column Map yet. This method should never be called in that case. " 4707 "Please report this bug to the Tpetra developers.");
4708 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4709 this->
getColMap ().is_null (), std::logic_error,
": The graph claims " 4710 "that it has a column Map, because hasColMap() returns true. However, " 4711 "the result of getColMap() is null. This should never happen. Please " 4712 "report this bug to the Tpetra developers.");
4725 if (nodeNumAllocated_ && Kokkos::Impl::is_same<LO,GO>::value) {
4726 k_lclInds1D_ = Kokkos::Impl::if_c<Kokkos::Impl::is_same<LO,GO>::value,
4731 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4732 k_rowPtrs_.dimension_0 () == 0, std::logic_error,
": This should " 4733 "never happen at this point. Please report this bug to the Tpetra " 4735 const size_t numEnt =
k_rowPtrs_[lclNumRows];
4737 k_lclInds1D_ = lcl_col_inds_type (
"Tpetra::CrsGraph::lclind", numEnt);
4740 for (
size_t r = 0; r < lclNumRows; ++r) {
4742 const size_t numentry = h_numRowEnt(r);
4743 for (
size_t j = 0; j < numentry; ++j) {
4747 #ifdef HAVE_TPETRA_DEBUG 4748 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4749 k_lclInds1D_(offset + j) == Teuchos::OrdinalTraits<LO>::invalid(),
4751 ": In local row r=" << r <<
", global column " << gid <<
" is " 4752 "not in the column Map. This should never happen. Please " 4753 "report this bug to the Tpetra developers.");
4754 #endif // HAVE_TPETRA_DEBUG 4764 for (
size_t r = 0; r < lclNumRows; ++r) {
4766 const GO*
const ginds =
gblInds2D_[r].getRawPtr ();
4768 const size_t numentry = h_numRowEnt(r);
4770 LO*
const linds =
lclInds2D_[r].getRawPtr ();
4771 for (
size_t j = 0; j < numentry; ++j) {
4772 const GO gid = ginds[j];
4775 #ifdef HAVE_TPETRA_DEBUG 4776 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4777 linds[j] == Teuchos::OrdinalTraits<LO>::invalid(),
4779 ": Global column ginds[j=" << j <<
"]=" << ginds[j]
4780 <<
" of local row r=" << r <<
" is not in the column Map. " 4781 "This should never happen. Please report this bug to the " 4782 "Tpetra developers.");
4783 #endif // HAVE_TPETRA_DEBUG 4792 indicesAreLocal_ =
true;
4793 indicesAreGlobal_ =
false;
4798 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4803 typedef LocalOrdinal LO;
4811 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
4820 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4825 using Teuchos::Array;
4826 using Teuchos::ArrayView;
4828 using Teuchos::REDUCE_MAX;
4829 using Teuchos::reduceAll;
4831 typedef LocalOrdinal LO;
4832 typedef GlobalOrdinal GO;
4833 const char tfecfFuncName[] =
"makeColMap";
4841 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4843 ": The graph is locally indexed. Calling makeColMap() to make the " 4844 "column Map requires that the graph be globally indexed.");
4849 Array<GO> myColumns;
4879 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
4880 size_t numLocalColGIDs = 0, numRemoteColGIDs = 0;
4884 Array<char> GIDisLocal (
domainMap_->getNodeNumElements (), 0);
4885 std::set<GO> RemoteGIDSet;
4887 std::vector<GO> RemoteGIDUnorderedVector;
4889 for (LO r = 0; r < myNumRows; ++r) {
4891 if (rowinfo.numEntries > 0) {
4898 rowGids = rowGids (0, rowinfo.numEntries);
4900 for (
size_t k = 0; k < rowinfo.numEntries; ++k) {
4901 const GO gid = rowGids[k];
4902 const LO lid =
domainMap_->getLocalElement (gid);
4904 const char alreadyFound = GIDisLocal[lid];
4905 if (alreadyFound == 0) {
4906 GIDisLocal[lid] =
static_cast<char> (1);
4911 const bool notAlreadyFound = RemoteGIDSet.insert (gid).second;
4912 if (notAlreadyFound) {
4920 RemoteGIDUnorderedVector.push_back (gid);
4958 if (
domainMap_->getComm ()->getSize () == 1) {
4959 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4960 numRemoteColGIDs != 0, std::runtime_error,
4961 ": " << numRemoteColGIDs <<
" column " 4962 << (numRemoteColGIDs != 1 ?
"indices are" :
"index is")
4963 <<
" not in the domain Map." << endl
4964 <<
"Either these indices are invalid or the domain Map is invalid." 4965 << endl <<
"Remember that nonsquare matrices, or matrices where the " 4966 "row and range Maps are different, require calling the version of " 4967 "fillComplete that takes the domain and range Maps as input.");
4968 if (numLocalColGIDs ==
domainMap_->getNodeNumElements()) {
4979 myColumns.resize (numLocalColGIDs + numRemoteColGIDs);
4981 ArrayView<GO> LocalColGIDs = myColumns (0, numLocalColGIDs);
4982 ArrayView<GO> RemoteColGIDs = myColumns (numLocalColGIDs, numRemoteColGIDs);
4987 std::copy (RemoteGIDSet.begin(), RemoteGIDSet.end(),
4988 RemoteColGIDs.begin());
4991 std::copy (RemoteGIDUnorderedVector.begin(),
4992 RemoteGIDUnorderedVector.end(), RemoteColGIDs.begin());
4996 Array<int> RemoteImageIDs (numRemoteColGIDs);
5000 domainMap_->getRemoteIndexList (RemoteColGIDs, RemoteImageIDs ());
5001 #ifdef HAVE_TPETRA_DEBUG 5009 const int missingID_lcl = (stat ==
IDNotPresent ? 1 : 0);
5010 int missingID_gbl = 0;
5011 reduceAll<int, int> (*
getComm (), REDUCE_MAX, missingID_lcl,
5012 outArg (missingID_gbl));
5013 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5014 missingID_gbl == 1, std::runtime_error,
5015 ": Some column indices are not in the domain Map." << endl
5016 <<
"Either these column indices are invalid or the domain Map is " 5017 "invalid." << endl <<
"Likely cause: For a nonsquare matrix, you " 5018 "must give the domain and range Maps as input to fillComplete.");
5021 #endif // HAVE_TPETRA_DEBUG 5031 sort2 (RemoteImageIDs.begin(), RemoteImageIDs.end(), RemoteColGIDs.begin());
5043 const size_t numDomainElts =
domainMap_->getNodeNumElements ();
5044 if (numLocalColGIDs == numDomainElts) {
5054 GO curColMapGid =
domainMap_->getMinGlobalIndex ();
5055 for (
size_t k = 0; k < numLocalColGIDs; ++k, ++curColMapGid) {
5056 LocalColGIDs[k] = curColMapGid;
5060 ArrayView<const GO> domainElts =
domainMap_->getNodeElementList ();
5061 std::copy (domainElts.begin(), domainElts.end(), LocalColGIDs.begin());
5067 size_t numLocalCount = 0;
5074 GO curColMapGid =
domainMap_->getMinGlobalIndex ();
5075 for (
size_t i = 0; i < numDomainElts; ++i, ++curColMapGid) {
5076 if (GIDisLocal[i]) {
5077 LocalColGIDs[numLocalCount++] = curColMapGid;
5082 ArrayView<const GO> domainElts =
domainMap_->getNodeElementList ();
5083 for (
size_t i = 0; i < numDomainElts; ++i) {
5084 if (GIDisLocal[i]) {
5085 LocalColGIDs[numLocalCount++] = domainElts[i];
5089 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5090 numLocalCount != numLocalColGIDs, std::logic_error,
5091 ": numLocalCount = " << numLocalCount <<
" != numLocalColGIDs = " 5092 << numLocalColGIDs <<
". This should never happen. Please report " 5093 "this bug to the Tpetra developers.");
5138 Teuchos::OrdinalTraits<global_size_t>::invalid ();
5143 const GO indexBase =
domainMap_->getIndexBase ();
5152 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5158 TEUCHOS_TEST_FOR_EXCEPT( !
isSorted() );
5160 const LocalOrdinal lclNumRows =
5162 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
5172 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5177 using Teuchos::ParameterList;
5181 TEUCHOS_TEST_FOR_EXCEPTION(!
hasColMap (), std::logic_error,
"Tpetra::" 5182 "CrsGraph::makeImportExport: This method may not be called unless the " 5183 "graph has a column Map.");
5184 RCP<ParameterList> params = this->getNonconstParameterList ();
5196 if (params.is_null () || ! params->isSublist (
"Import")) {
5199 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5210 if (params.is_null () || ! params->isSublist (
"Export")) {
5214 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5222 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5227 std::ostringstream oss;
5230 oss <<
"{status = fill complete" 5237 oss <<
"{status = fill not complete" 5245 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5249 const Teuchos::EVerbosityLevel verbLevel)
const 5251 const char tfecfFuncName[] =
"describe()";
5254 using Teuchos::VERB_DEFAULT;
5255 using Teuchos::VERB_NONE;
5256 using Teuchos::VERB_LOW;
5257 using Teuchos::VERB_MEDIUM;
5258 using Teuchos::VERB_HIGH;
5259 using Teuchos::VERB_EXTREME;
5260 Teuchos::EVerbosityLevel vl = verbLevel;
5261 if (vl == VERB_DEFAULT) vl = VERB_LOW;
5262 RCP<const Comm<int> > comm = this->
getComm();
5263 const int myImageID = comm->getRank(),
5264 numImages = comm->getSize();
5269 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5270 Teuchos::OSTab tab (out);
5278 if (vl != VERB_NONE) {
5279 if (myImageID == 0) out << this->
description() << std::endl;
5282 out <<
"Global number of diagonals = " << globalNumDiags_ << std::endl;
5283 out <<
"Global max number of row entries = " << globalMaxNumRowEntries_ << std::endl;
5286 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5287 if (myImageID == 0) out <<
"\nRow map: " << std::endl;
5290 if (myImageID == 0) out <<
"\nColumn map: " << std::endl;
5294 if (myImageID == 0) out <<
"\nDomain map: " << std::endl;
5298 if (myImageID == 0) out <<
"\nRange map: " << std::endl;
5303 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
5304 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5305 if (myImageID == imageCtr) {
5306 out <<
"Node ID = " << imageCtr << std::endl
5307 <<
"Node number of entries = " << nodeNumEntries_ << std::endl
5308 <<
"Node number of diagonals = " << nodeNumDiags_ << std::endl
5309 <<
"Node max number of entries = " << nodeMaxNumRowEntries_ << std::endl;
5310 if (indicesAreAllocated()) {
5311 out <<
"Node number of allocated entries = " << nodeNumAllocated_ << std::endl;
5314 out <<
"Indices are not allocated." << std::endl;
5323 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
5324 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5325 !
hasRowInfo (), std::runtime_error,
": reduce verbosity level; " 5326 "graph row information was deleted at fillComplete().");
5327 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
5328 if (myImageID == imageCtr) {
5329 out << std::setw(width) <<
"Node ID" 5330 << std::setw(width) <<
"Global Row" 5331 << std::setw(width) <<
"Num Entries";
5332 if (vl == VERB_EXTREME) {
5336 const LocalOrdinal lclNumRows =
5338 for (LocalOrdinal r=0; r < lclNumRows; ++r) {
5340 GlobalOrdinal gid =
rowMap_->getGlobalElement(r);
5341 out << std::setw(width) << myImageID
5342 << std::setw(width) << gid
5343 << std::setw(width) << rowinfo.numEntries;
5344 if (vl == VERB_EXTREME) {
5347 ArrayView<const GlobalOrdinal> rowview =
getGlobalView(rowinfo);
5348 for (
size_t j=0; j < rowinfo.numEntries; ++j) out << rowview[j] <<
" ";
5351 ArrayView<const LocalOrdinal> rowview =
getLocalView(rowinfo);
5352 for (
size_t j=0; j < rowinfo.numEntries; ++j) out <<
colMap_->getGlobalElement(rowview[j]) <<
" ";
5367 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5381 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5386 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
5387 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs)
5389 using Teuchos::Array;
5390 using Teuchos::ArrayView;
5391 typedef LocalOrdinal LO;
5392 typedef GlobalOrdinal GO;
5393 const char tfecfFuncName[] =
"copyAndPermute";
5397 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5398 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
5399 ": permuteToLIDs and permuteFromLIDs must have the same size.");
5413 const row_graph_type* srcRowGraph =
dynamic_cast<const row_graph_type*
> (&source);
5414 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5415 srcRowGraph == NULL, std::invalid_argument,
5416 ": The source object must be a RowGraph with matching first three " 5417 "template parameters.");
5422 const this_type* srcCrsGraph =
dynamic_cast<const this_type*
> (&source);
5424 const map_type& srcRowMap = * (srcRowGraph->getRowMap ());
5426 const bool src_filled = srcRowGraph->isFillComplete ();
5433 if (src_filled || srcCrsGraph == NULL) {
5439 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5441 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (gid);
5442 row_copy.resize (row_length);
5443 size_t check_row_length = 0;
5444 srcRowGraph->getGlobalRowCopy (gid, row_copy (), check_row_length);
5448 for (
size_t i = 0; i < numSameIDs; ++i, ++myid) {
5450 ArrayView<const GO> row;
5451 srcCrsGraph->getGlobalRowView (gid, row);
5459 if (src_filled || srcCrsGraph == NULL) {
5460 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5463 size_t row_length = srcRowGraph->getNumEntriesInGlobalRow (srcgid);
5464 row_copy.resize (row_length);
5465 size_t check_row_length = 0;
5466 srcRowGraph->getGlobalRowCopy (srcgid, row_copy (), check_row_length);
5470 for (LO i = 0; i < permuteToLIDs.size (); ++i) {
5473 ArrayView<const GO> row;
5474 srcCrsGraph->getGlobalRowView (srcgid, row);
5481 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5485 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
5486 Teuchos::Array<GlobalOrdinal> &exports,
5487 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
5488 size_t& constantNumPackets,
5491 using Teuchos::Array;
5492 const char tfecfFuncName[] =
"packAndPrepare";
5493 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5494 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5495 ": exportLIDs and numPacketsPerLID must have the same size.");
5497 const row_graph_type& srcGraph =
dynamic_cast<const row_graph_type&
> (source);
5502 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5504 ": The target graph of an Import or Export must not be fill complete.");
5506 srcGraph.pack (exportLIDs, exports, numPacketsPerLID, constantNumPackets, distor);
5510 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5513 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5514 Teuchos::Array<GlobalOrdinal>& exports,
5515 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5516 size_t& constantNumPackets,
5519 using Teuchos::Array;
5520 typedef LocalOrdinal LO;
5521 typedef GlobalOrdinal GO;
5522 const char tfecfFuncName[] =
"pack";
5525 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5526 exportLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5527 ": exportLIDs and numPacketsPerLID must have the same size.");
5530 constantNumPackets = 0;
5537 size_t totalNumPackets = 0;
5539 for (LO i = 0; i < exportLIDs.size (); ++i) {
5542 numPacketsPerLID[i] = row_length;
5543 totalNumPackets += row_length;
5546 exports.resize (totalNumPackets);
5550 size_t exportsOffset = 0;
5551 for (LO i = 0; i < exportLIDs.size (); ++i) {
5552 const GO GID = srcMap.getGlobalElement (exportLIDs[i]);
5554 row.resize (row_length);
5555 size_t check_row_length = 0;
5557 typename Array<GO>::const_iterator row_iter = row.begin();
5558 typename Array<GO>::const_iterator row_end = row.end();
5560 for (; row_iter != row_end; ++row_iter, ++j) {
5561 exports[exportsOffset+j] = *row_iter;
5563 exportsOffset += row.size();
5568 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5571 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
5572 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
5573 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
5574 size_t constantNumPackets,
5578 using Teuchos::ArrayView;
5579 typedef LocalOrdinal LO;
5580 typedef GlobalOrdinal GO;
5599 const char tfecfFuncName[] =
"unpackAndCombine: ";
5600 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5601 importLIDs.size() != numPacketsPerLID.size(), std::runtime_error,
5602 "importLIDs and numPacketsPerLID must have the same size.");
5603 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5605 "Import or Export operations are not allowed on the destination " 5606 "CrsGraph if it is fill complete.");
5607 size_t importsOffset = 0;
5609 typedef typename ArrayView<const LO>::const_iterator iter_type;
5610 iter_type impLIDiter = importLIDs.begin();
5611 iter_type impLIDend = importLIDs.end();
5613 for (
size_t i = 0; impLIDiter != impLIDend; ++impLIDiter, ++i) {
5614 LO row_length = numPacketsPerLID[i];
5616 const GO*
const row_raw = (row_length == 0) ? NULL : &imports[importsOffset];
5617 ArrayView<const GlobalOrdinal> row (row_raw, row_length);
5619 importsOffset += row_length;
5624 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5629 using Teuchos::Comm;
5630 using Teuchos::null;
5631 using Teuchos::ParameterList;
5637 RCP<const map_type> rowMap, domainMap, rangeMap, colMap;
5638 RCP<import_type> importer;
5639 RCP<export_type> exporter;
5642 RCP<const Comm<int> > newComm =
5643 (newMap.is_null ()) ? null : newMap->getComm ();
5653 domainMap =
domainMap_->replaceCommWithSubset (newComm);
5664 rangeMap =
rangeMap_->replaceCommWithSubset (newComm);
5667 if (! colMap.is_null ()) {
5668 colMap =
colMap_->replaceCommWithSubset (newComm);
5672 if (! newComm.is_null ()) {
5673 RCP<ParameterList> params = this->getNonconstParameterList ();
5682 rangeMap != rowMap &&
5683 ! rangeMap->isSameAs (*rowMap)) {
5684 if (params.is_null () || ! params->isSublist (
"Export")) {
5685 exporter = rcp (
new export_type (rowMap, rangeMap));
5688 RCP<ParameterList> exportSublist = sublist (params,
"Export",
true);
5689 exporter = rcp (
new export_type (rowMap, rangeMap, exportSublist));
5694 domainMap != colMap &&
5695 ! domainMap->isSameAs (*colMap)) {
5696 if (params.is_null () || ! params->isSublist (
"Import")) {
5697 importer = rcp (
new import_type (domainMap, colMap));
5699 RCP<ParameterList> importSublist = sublist (params,
"Import",
true);
5700 importer = rcp (
new import_type (domainMap, colMap, importSublist));
5716 this->
map_ = rowMap;
5722 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5727 if (indicesAreAllocated () &&
5743 #define TPETRA_CRSGRAPH_GRAPH_INSTANT(LO,GO,NODE) template class CrsGraph< LO , GO , NODE >; 5744 #define TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) template void CrsGraph< LO , GO , NODE >::sortRowIndicesAndValues< S >(const RowInfo, const Teuchos::ArrayView< S >& ); 5745 #define TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) template void CrsGraph< LO , GO , NODE >::mergeRowIndicesAndValues< S >(RowInfo, const ArrayView< S >& ); 5746 #define TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) 5747 #define TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) template ArrayRCP< Array< S > > CrsGraph< LO , GO , NODE >::allocateValues2D< S >() const; 5749 #define TPETRA_CRSGRAPH_INSTANT(S,LO,GO,NODE) \ 5750 TPETRA_CRSGRAPH_SORTROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5751 TPETRA_CRSGRAPH_MERGEROWINDICESANDVALUES_INSTANT(S,LO,GO,NODE) \ 5752 TPETRA_CRSGRAPH_ALLOCATEVALUES1D_INSTANT(S,LO,GO,NODE) \ 5753 TPETRA_CRSGRAPH_ALLOCATEVALUES2D_INSTANT(S,LO,GO,NODE) \ 5754 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); 5756 #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.
size_t findLocalIndex(const RowInfo &rowinfo, const LocalOrdinal ind, const size_t hint=0) const
Find the column offset corresponding to the given (local) column index.
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 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 deep_copy(const LittleBlock< ST2, LO > &dst, const LittleBlock< ST1, LO > &src, typename std::enable_if< std::is_convertible< ST1, ST2 >::value &&!std::is_const< ST2 >::value, int >::type *=NULL)
Copy the LittleBlock src into the LittleBlock dst.
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 findGlobalIndex(const RowInfo &rowinfo, const GlobalOrdinal ind, const size_t hint=0) const
Find the column offset corresponding to the given (global) column index.
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.
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.
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.
RowInfo getRowInfoFromGlobalRowIndex(const GlobalOrdinal gblRow) const
Get information about the locally owned row with global index gblRow.
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.
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.
RowInfo getRowInfo(const LocalOrdinal myRow) const
Get information about the locally owned row with local index myRow.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.