42 #ifndef TPETRA_CRSGRAPH_DECL_HPP 43 #define TPETRA_CRSGRAPH_DECL_HPP 53 #include "Tpetra_RowGraph.hpp" 54 #include "Tpetra_DistObject.hpp" 55 #include "Tpetra_Exceptions.hpp" 58 #include "Kokkos_Sparse_findRelOffset.hpp" 59 #include "Kokkos_DualView.hpp" 60 #include "Kokkos_StaticCrsGraph.hpp" 62 #include "Teuchos_Describable.hpp" 63 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp" 68 #ifndef DOXYGEN_SHOULD_SKIP_THIS 74 template <
class LO,
class GO,
class N, const
bool isClassic>
78 template <
class S,
class LO,
class GO,
class N, const
bool isClassic>
81 namespace Experimental {
83 template<
class S,
class LO,
class GO,
class N>
89 template<
class OutputCrsGraphType,
class InputCrsGraphType>
90 class CrsGraphCopier {
92 static Teuchos::RCP<OutputCrsGraphType>
93 clone (
const InputCrsGraphType& graphIn,
94 const Teuchos::RCP<typename OutputCrsGraphType::node_type> nodeOut,
95 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
101 template<
class ViewType>
102 struct UnmanagedView {
103 static_assert (Kokkos::is_view<ViewType>::value,
104 "ViewType must be a Kokkos::View specialization.");
108 typedef Kokkos::View<
typename ViewType::data_type,
109 typename ViewType::array_layout,
110 typename ViewType::device_type,
111 Kokkos::MemoryUnmanaged> type;
114 template<
class T,
class BinaryFunction>
115 T atomic_binary_function_update (
volatile T*
const dest,
const T& inputVal, BinaryFunction f)
127 T newVal = f (assume, inputVal);
128 oldVal = Kokkos::atomic_compare_exchange (dest, assume, newVal);
129 }
while (assume != oldVal);
135 #endif // DOXYGEN_SHOULD_SKIP_THIS 264 class GlobalOrdinal = ::Tpetra::Details::DefaultTypes::global_ordinal_type,
266 const bool classic = Node::classic>
268 public RowGraph<LocalOrdinal, GlobalOrdinal, Node>,
273 public Teuchos::ParameterListAcceptorDefaultBase
275 static_assert (! classic,
"The 'classic' version of Tpetra was deprecated long ago, and has been removed.");
277 template <
class S,
class LO,
class GO,
class N, const
bool isClassic>
279 template <
class LO2,
class GO2,
class N2, const
bool isClassic>
281 template <
class S,
class LO,
class GO,
class N>
282 friend class ::Tpetra::Experimental::BlockCrsMatrix;
301 typedef Kokkos::StaticCrsGraph<LocalOrdinal,
312 typedef typename local_graph_type::entries_type::non_const_type t_LocalOrdinal_1D
TPETRA_DEPRECATED;
342 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
343 size_t maxNumEntriesPerRow,
345 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
364 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
365 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
367 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
387 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
388 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
390 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
413 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
414 const Teuchos::RCP<const map_type>& colMap,
415 const size_t maxNumEntriesPerRow,
417 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
437 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
438 const Teuchos::RCP<const map_type>& colMap,
439 const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
441 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
462 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
463 const Teuchos::RCP<const map_type>& colMap,
464 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
466 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
487 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
488 const Teuchos::RCP<const map_type>& colMap,
489 const typename local_graph_type::row_map_type& rowPointers,
490 const typename local_graph_type::entries_type::non_const_type& columnIndices,
491 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
512 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
513 const Teuchos::RCP<const map_type>& colMap,
514 const Teuchos::ArrayRCP<size_t> & rowPointers,
515 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
516 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
536 CrsGraph (
const Teuchos::RCP<const map_type>& rowMap,
537 const Teuchos::RCP<const map_type>& colMap,
538 const local_graph_type& lclGraph,
539 const Teuchos::RCP<Teuchos::ParameterList>& params);
568 template<
class Node2>
569 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node2, Node2::classic> >
570 clone (
const Teuchos::RCP<Node2>& node2,
571 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
const 575 typedef Details::CrsGraphCopier<output_crs_graph_type, input_crs_graph_type> copier_type;
576 return copier_type::clone (*
this, node2, params);
587 void setParameterList (
const Teuchos::RCP<Teuchos::ParameterList>& params);
590 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters ()
const;
618 insertGlobalIndices (
const GlobalOrdinal globalRow,
619 const Teuchos::ArrayView<const GlobalOrdinal>& indices);
628 insertGlobalIndices (
const GlobalOrdinal globalRow,
629 const LocalOrdinal numEnt,
630 const GlobalOrdinal inds[]);
648 insertLocalIndices (
const LocalOrdinal localRow,
649 const Teuchos::ArrayView<const LocalOrdinal> &indices);
658 insertLocalIndices (
const LocalOrdinal localRow,
659 const LocalOrdinal numEnt,
660 const LocalOrdinal inds[]);
672 void removeLocalIndices (LocalOrdinal localRow);
688 void globalAssemble ();
698 void resumeFill (
const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
735 fillComplete (
const Teuchos::RCP<const map_type> &domainMap,
736 const Teuchos::RCP<const map_type> &rangeMap,
737 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
764 fillComplete (
const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
792 expertStaticFillComplete (
const Teuchos::RCP<const map_type> & domainMap,
793 const Teuchos::RCP<const map_type> & rangeMap,
794 const Teuchos::RCP<const import_type> &importer=Teuchos::null,
795 const Teuchos::RCP<const export_type> &exporter=Teuchos::null,
796 const Teuchos::RCP<Teuchos::ParameterList> ¶ms=Teuchos::null);
802 Teuchos::RCP<const Teuchos::Comm<int> > getComm()
const;
805 Teuchos::RCP<node_type> getNode()
const;
808 Teuchos::RCP<const map_type> getRowMap ()
const;
811 Teuchos::RCP<const map_type> getColMap ()
const;
814 Teuchos::RCP<const map_type> getDomainMap ()
const;
817 Teuchos::RCP<const map_type> getRangeMap ()
const;
820 Teuchos::RCP<const import_type> getImporter ()
const;
823 Teuchos::RCP<const export_type> getExporter ()
const;
837 size_t getNodeNumRows()
const;
842 size_t getNodeNumCols()
const;
845 GlobalOrdinal getIndexBase()
const;
853 size_t getNodeNumEntries()
const;
857 size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow)
const;
865 size_t getNumEntriesInLocalRow (LocalOrdinal localRow)
const;
875 size_t getNodeAllocationSize()
const;
879 size_t getNumAllocatedEntriesInGlobalRow(GlobalOrdinal globalRow)
const;
883 size_t getNumAllocatedEntriesInLocalRow(LocalOrdinal localRow)
const;
893 size_t getNodeNumDiags()
const;
907 size_t getGlobalMaxNumRowEntries()
const;
912 size_t getNodeMaxNumRowEntries()
const;
928 bool hasColMap()
const;
937 bool isLowerTriangular()
const;
946 bool isUpperTriangular()
const;
949 bool isLocallyIndexed()
const;
952 bool isGloballyIndexed()
const;
955 bool isFillComplete()
const;
958 bool isFillActive()
const;
967 bool isSorted()
const;
976 bool isStorageOptimized()
const;
987 getGlobalRowCopy (GlobalOrdinal GlobalRow,
988 const Teuchos::ArrayView<GlobalOrdinal>& Indices,
989 size_t& NumIndices)
const;
999 getLocalRowCopy (LocalOrdinal LocalRow,
1000 const Teuchos::ArrayView<LocalOrdinal>& indices,
1001 size_t& NumIndices)
const;
1014 getGlobalRowView (GlobalOrdinal GlobalRow,
1015 Teuchos::ArrayView<const GlobalOrdinal>& Indices)
const;
1028 getLocalRowView (LocalOrdinal LocalRow,
1029 Teuchos::ArrayView<const LocalOrdinal>& indices)
const;
1036 std::string description()
const;
1040 describe (Teuchos::FancyOStream& out,
1041 const Teuchos::EVerbosityLevel verbLevel =
1042 Teuchos::Describable::verbLevel_default)
const;
1054 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
1055 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs);
1059 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
1060 Teuchos::Array<GlobalOrdinal> &exports,
1061 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
1062 size_t& constantNumPackets,
1066 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
1067 Teuchos::Array<GlobalOrdinal>& exports,
1068 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
1069 size_t& constantNumPackets,
1073 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
1074 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
1075 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
1076 size_t constantNumPackets,
1126 getLocalDiagOffsets (
const Kokkos::View<size_t*, device_type, Kokkos::MemoryUnmanaged>& offsets)
const;
1138 getLocalDiagOffsets (Teuchos::ArrayRCP<size_t>& offsets)
const;
1163 getNumEntriesPerLocalRowUpperBound (Teuchos::ArrayRCP<const size_t>& boundPerLocalRow,
1164 size_t& boundForAllLocalRows,
1165 bool& boundSameForAllLocalRows)
const;
1176 setAllIndices (
const typename local_graph_type::row_map_type& rowPointers,
1177 const typename local_graph_type::entries_type::non_const_type& columnIndices);
1188 setAllIndices (
const Teuchos::ArrayRCP<size_t> & rowPointers,
1189 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices);
1198 Teuchos::ArrayRCP<const size_t> getNodeRowPtrs ()
const;
1203 Teuchos::ArrayRCP<const LocalOrdinal> getNodePackedIndices()
const;
1215 void replaceColMap (
const Teuchos::RCP<const map_type>& newColMap);
1237 reindexColumns (
const Teuchos::RCP<const map_type>& newColMap,
1238 const Teuchos::RCP<const import_type>& newImport = Teuchos::null,
1239 const bool sortIndicesInEachRow =
true);
1255 replaceDomainMapAndImporter (
const Teuchos::RCP<const map_type>& newDomainMap,
1256 const Teuchos::RCP<const import_type>& newImporter);
1290 template<
class ViewType,
class OffsetViewType >
1291 struct pack_functor {
1292 typedef typename ViewType::execution_space execution_space;
1295 OffsetViewType src_offset;
1296 OffsetViewType dest_offset;
1297 typedef typename OffsetViewType::non_const_value_type ScalarIndx;
1299 pack_functor(ViewType dest_, ViewType src_, OffsetViewType dest_offset_, OffsetViewType src_offset_):
1300 src(src_),dest(dest_),src_offset(src_offset_),dest_offset(dest_offset_) {};
1302 KOKKOS_INLINE_FUNCTION
1303 void operator() (
size_t row)
const {
1304 ScalarIndx i = src_offset(row);
1305 ScalarIndx j = dest_offset(row);
1306 const ScalarIndx k = dest_offset(row+1);
1316 struct SLocalGlobalViews {
1317 Teuchos::ArrayView<const GlobalOrdinal> ginds;
1318 Teuchos::ArrayView<const LocalOrdinal> linds;
1320 struct SLocalGlobalNCViews {
1321 Teuchos::ArrayView<GlobalOrdinal> ginds;
1322 Teuchos::ArrayView<LocalOrdinal> linds;
1325 bool indicesAreAllocated ()
const;
1326 void allocateIndices (
const ELocalGlobal lg);
1329 Teuchos::ArrayRCP<Teuchos::Array<T> > allocateValues2D ()
const 1331 using Teuchos::arcp;
1332 using Teuchos::Array;
1333 using Teuchos::ArrayRCP;
1334 using Teuchos::null;
1335 const char tfecfFuncName[] =
"allocateValues2D: ";
1337 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1338 (! indicesAreAllocated (), std::runtime_error,
1339 "Graph indices must be allocated before values.");
1340 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1342 "Graph indices must be allocated in a dynamic profile.");
1344 ArrayRCP<Array<T> > values2D;
1345 values2D = arcp<Array<T> > (getNodeNumRows ());
1346 if (lclInds2D_ != null) {
1347 const size_t numRows = lclInds2D_.size ();
1348 for (
size_t r = 0; r < numRows; ++r) {
1349 values2D[r].resize (lclInds2D_[r].size ());
1352 else if (gblInds2D_ != null) {
1353 const size_t numRows = gblInds2D_.size ();
1354 for (
size_t r = 0; r < numRows; ++r) {
1355 values2D[r].resize (gblInds2D_[r].size ());
1363 const size_t newAllocSize,
1364 Teuchos::Array<T>& rowVals)
1366 #ifdef HAVE_TPETRA_DEBUG 1367 TEUCHOS_TEST_FOR_EXCEPT( ! isLocallyIndexed () );
1368 TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated() );
1369 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1370 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1371 TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1372 #endif // HAVE_TPETRA_DEBUG 1375 lclInds2D_[rowInfo.localRow].resize (newAllocSize);
1376 rowVals.resize (newAllocSize);
1377 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1380 rowInfoOut.allocSize = newAllocSize;
1386 updateGlobalAllocAndValues (
const RowInfo rowInfo,
1387 const size_t newAllocSize,
1388 Teuchos::Array<T>& rowVals)
1390 #ifdef HAVE_TPETRA_DEBUG 1391 TEUCHOS_TEST_FOR_EXCEPT( ! isGloballyIndexed () );
1392 TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated () );
1393 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1394 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1395 TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1396 #endif // HAVE_TPETRA_DEBUG 1399 gblInds2D_[rowInfo.localRow].resize (newAllocSize);
1400 rowVals.resize (newAllocSize);
1401 nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1404 rowInfoOut.allocSize = newAllocSize;
1413 void makeIndicesLocal ();
1414 void makeImportExport ();
1420 template<ELocalGlobal lg>
1421 size_t filterIndices (
const SLocalGlobalNCViews& inds)
const 1423 using Teuchos::ArrayView;
1424 static_assert (lg == GlobalIndices || lg == LocalIndices,
1425 "Tpetra::CrsGraph::filterIndices: The template parameter " 1426 "lg must be either GlobalIndices or LocalIndicies.");
1428 const map_type& cmap = *colMap_;
1429 size_t numFiltered = 0;
1430 #ifdef HAVE_TPETRA_DEBUG 1431 size_t numFiltered_debug = 0;
1433 if (lg == GlobalIndices) {
1434 ArrayView<GlobalOrdinal> ginds = inds.ginds;
1435 typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1436 typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1437 while (cptr != ginds.end()) {
1440 #ifdef HAVE_TPETRA_DEBUG 1441 ++numFiltered_debug;
1446 numFiltered = fend - ginds.begin();
1448 else if (lg == LocalIndices) {
1449 ArrayView<LocalOrdinal> linds = inds.linds;
1450 typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1451 typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1452 while (cptr != linds.end()) {
1455 #ifdef HAVE_TPETRA_DEBUG 1456 ++numFiltered_debug;
1461 numFiltered = fend - linds.begin();
1463 #ifdef HAVE_TPETRA_DEBUG 1464 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1472 filterGlobalIndicesAndValues (
const Teuchos::ArrayView<GlobalOrdinal>& ginds,
1473 const Teuchos::ArrayView<T>& vals)
const 1475 using Teuchos::ArrayView;
1476 const map_type& cmap = *colMap_;
1477 size_t numFiltered = 0;
1478 typename ArrayView<T>::iterator fvalsend = vals.begin();
1479 typename ArrayView<T>::iterator valscptr = vals.begin();
1480 #ifdef HAVE_TPETRA_DEBUG 1481 size_t numFiltered_debug = 0;
1483 typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1484 typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1485 while (cptr != ginds.end()) {
1488 *fvalsend++ = *valscptr;
1489 #ifdef HAVE_TPETRA_DEBUG 1490 ++numFiltered_debug;
1496 numFiltered = fend - ginds.begin();
1497 #ifdef HAVE_TPETRA_DEBUG 1498 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1499 TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1500 const size_t numFilteredActual =
1501 static_cast<size_t> (fvalsend - vals.begin ());
1502 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1503 #endif // HAVE_TPETRA_DEBUG 1509 filterLocalIndicesAndValues (
const Teuchos::ArrayView<LocalOrdinal>& linds,
1510 const Teuchos::ArrayView<T>& vals)
const 1512 using Teuchos::ArrayView;
1513 const map_type& cmap = *colMap_;
1514 size_t numFiltered = 0;
1515 typename ArrayView<T>::iterator fvalsend = vals.begin();
1516 typename ArrayView<T>::iterator valscptr = vals.begin();
1517 #ifdef HAVE_TPETRA_DEBUG 1518 size_t numFiltered_debug = 0;
1520 typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1521 typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1522 while (cptr != linds.end()) {
1525 *fvalsend++ = *valscptr;
1526 #ifdef HAVE_TPETRA_DEBUG 1527 ++numFiltered_debug;
1533 numFiltered = fend - linds.begin();
1534 #ifdef HAVE_TPETRA_DEBUG 1535 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1536 TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1537 const size_t numFilteredActual =
1538 Teuchos::as<size_t> (fvalsend - vals.begin ());
1539 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1574 insertIndices (
const RowInfo& rowInfo,
1575 const SLocalGlobalViews& newInds,
1576 const ELocalGlobal lg,
1577 const ELocalGlobal I);
1618 template<
class Scalar>
1621 const SLocalGlobalViews& newInds,
1622 const Teuchos::ArrayView<Scalar>& oldRowVals,
1623 const Teuchos::ArrayView<const Scalar>& newRowVals,
1624 const ELocalGlobal lg,
1625 const ELocalGlobal I)
1627 #ifdef HAVE_TPETRA_DEBUG 1628 const char tfecfFuncName[] =
"insertIndicesAndValues: ";
1629 #endif // HAVE_TPETRA_DEBUG 1631 #ifdef HAVE_TPETRA_DEBUG 1632 size_t numNewInds = 0;
1634 numNewInds = insertIndices (rowInfo, newInds, lg, I);
1635 }
catch (std::exception& e) {
1636 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1637 (
true, std::runtime_error,
"insertIndices threw an exception: " 1640 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1641 (numNewInds > static_cast<size_t> (oldRowVals.size ()),
1642 std::runtime_error,
"numNewInds (" << numNewInds <<
") > " 1643 "oldRowVals.size() (" << oldRowVals.size () <<
".");
1645 const size_t numNewInds = insertIndices (rowInfo, newInds, lg, I);
1646 #endif // HAVE_TPETRA_DEBUG 1648 typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1650 #ifdef HAVE_TPETRA_DEBUG 1651 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1652 (rowInfo.numEntries + numNewInds > static_cast<size_t> (oldRowVals.size ()),
1653 std::runtime_error,
"rowInfo.numEntries (" << rowInfo.numEntries <<
")" 1654 " + numNewInds (" << numNewInds <<
") > oldRowVals.size() (" 1655 << oldRowVals.size () <<
").");
1656 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1657 (static_cast<size_type> (numNewInds) > newRowVals.size (),
1658 std::runtime_error,
"numNewInds (" << numNewInds <<
") > " 1659 "newRowVals.size() (" << newRowVals.size () <<
").");
1660 #endif // HAVE_TPETRA_DEBUG 1662 size_type oldInd =
static_cast<size_type
> (rowInfo.numEntries);
1664 #ifdef HAVE_TPETRA_DEBUG 1666 #endif // HAVE_TPETRA_DEBUG 1669 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 1670 #define GCC_VERSION __GNUC__*100+__GNUC_MINOR__*10+__GNUC_PATCHLEVEL__ 1671 #if GCC_VERSION >= 490 1672 #define GCC_WORKAROUND 1675 #ifdef GCC_WORKAROUND 1676 size_type nNI =
static_cast<size_type
>(numNewInds);
1678 memcpy(&oldRowVals[oldInd], &newRowVals[0], nNI*
sizeof(Scalar));
1719 #else // GCC Workaround above 1720 for (size_type newInd = 0; newInd < static_cast<size_type> (numNewInds);
1721 ++newInd, ++oldInd) {
1722 oldRowVals[oldInd] = newRowVals[newInd];
1724 #endif // GCC Workaround 1725 #ifdef HAVE_TPETRA_DEBUG 1727 catch (std::exception& e) {
1728 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1729 (
true, std::runtime_error,
"for loop for copying values threw an " 1730 "exception: " << e.what ());
1732 #endif // HAVE_TPETRA_DEBUG 1736 insertGlobalIndicesImpl (
const LocalOrdinal myRow,
1737 const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1739 insertLocalIndicesImpl (
const LocalOrdinal myRow,
1740 const Teuchos::ArrayView<const LocalOrdinal> &indices);
1743 insertLocalIndicesFiltered (
const LocalOrdinal localRow,
1744 const Teuchos::ArrayView<const LocalOrdinal> &indices);
1748 insertGlobalIndicesFiltered (
const GlobalOrdinal localRow,
1749 const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1755 static const bool useAtomicUpdatesByDefault =
1756 #ifdef KOKKOS_HAVE_SERIAL 1757 ! std::is_same<execution_space, Kokkos::Serial>::value;
1760 #endif // KOKKOS_HAVE_SERIAL 1800 template<
class OutputScalarViewType,
1801 class LocalIndicesViewType,
1802 class InputScalarViewType,
1803 class BinaryFunction>
1806 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
1807 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
1808 const typename UnmanagedView<InputScalarViewType>::type& newVals,
1810 const bool atomic = useAtomicUpdatesByDefault)
const 1818 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
1819 "Template parameter OutputScalarViewType must be " 1821 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
1822 "Template parameter LocalIndicesViewType must be " 1824 static_assert (Kokkos::is_view<InputScalarViewType>::value,
1825 "Template parameter InputScalarViewType must be a " 1827 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
1828 "Template parameter OutputScalarViewType must " 1830 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
1831 "Template parameter LocalIndicesViewType must " 1833 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
1834 "Template parameter InputScalarViewType must have " 1836 static_assert (std::is_same<
1837 typename OutputScalarViewType::non_const_value_type,
1838 typename InputScalarViewType::non_const_value_type>::value,
1839 "Template parameters OutputScalarViewType and " 1840 "InputScalarViewType must contain values of the same " 1842 static_assert (std::is_same<
1843 typename LocalIndicesViewType::non_const_value_type,
1844 local_ordinal_type>::value,
1845 "Template parameter LocalIndicesViewType must " 1846 "contain values of type local_ordinal_type.");
1848 typedef typename OutputScalarViewType::non_const_value_type ST;
1849 typedef LocalOrdinal LO;
1850 typedef GlobalOrdinal GO;
1852 if (newVals.dimension_0 () != inds.dimension_0 ()) {
1854 return Teuchos::OrdinalTraits<LO>::invalid ();
1856 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
1857 const bool sorted = this->isSorted ();
1862 if (isLocallyIndexed ()) {
1865 auto colInds = this->getLocalKokkosRowView (rowInfo);
1867 for (LO j = 0; j < numElts; ++j) {
1868 const LO lclColInd = inds(j);
1869 const size_t offset =
1870 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
1871 lclColInd, hint, sorted);
1872 if (offset != rowInfo.numEntries) {
1881 volatile ST*
const dest = &rowVals(offset);
1882 (void) atomic_binary_function_update (dest, newVals(j), f);
1886 rowVals(offset) = f (rowVals(offset), newVals(j));
1893 else if (isGloballyIndexed ()) {
1897 if (colMap_.is_null ()) {
1904 const map_type& colMap = *colMap_;
1907 auto colInds = this->getGlobalKokkosRowView (rowInfo);
1909 const GO GINV = Teuchos::OrdinalTraits<GO>::invalid ();
1910 for (LO j = 0; j < numElts; ++j) {
1912 if (gblColInd != GINV) {
1913 const size_t offset =
1914 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
1915 gblColInd, hint, sorted);
1916 if (offset != rowInfo.numEntries) {
1925 volatile ST*
const dest = &rowVals(offset);
1926 (void) atomic_binary_function_update (dest, newVals(j), f);
1930 rowVals(offset) = f (rowVals(offset), newVals(j));
1966 template<
class OutputScalarViewType,
1967 class LocalIndicesViewType,
1968 class InputScalarViewType>
1971 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
1972 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
1973 const typename UnmanagedView<InputScalarViewType>::type& newVals,
1974 const bool atomic = useAtomicUpdatesByDefault)
const 1982 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
1983 "Template parameter OutputScalarViewType must be " 1985 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
1986 "Template parameter LocalIndicesViewType must be " 1988 static_assert (Kokkos::is_view<InputScalarViewType>::value,
1989 "Template parameter InputScalarViewType must be a " 1991 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
1992 "Template parameter OutputScalarViewType must " 1994 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
1995 "Template parameter LocalIndicesViewType must " 1997 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
1998 "Template parameter InputScalarViewType must have " 2000 static_assert (std::is_same<
2001 typename OutputScalarViewType::non_const_value_type,
2002 typename InputScalarViewType::non_const_value_type>::value,
2003 "Template parameters OutputScalarViewType and " 2004 "InputScalarViewType must contain values of the same " 2006 static_assert (std::is_same<
2007 typename LocalIndicesViewType::non_const_value_type,
2008 local_ordinal_type>::value,
2009 "Template parameter LocalIndicesViewType must " 2010 "contain values of type local_ordinal_type.");
2012 typedef LocalOrdinal LO;
2013 typedef GlobalOrdinal GO;
2019 if (colMap_.is_null ()) {
2021 return Teuchos::OrdinalTraits<LO>::invalid ();
2023 else if (newVals.dimension_0 () != inds.dimension_0 ()) {
2025 return Teuchos::OrdinalTraits<LO>::invalid ();
2028 const bool sorted = this->isSorted ();
2037 if (isLocallyIndexed ()) {
2040 auto colInds = this->getLocalKokkosRowView (rowInfo);
2042 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2043 for (LO j = 0; j < numElts; ++j) {
2044 const LO lclColInd = inds(j);
2045 const size_t offset =
2046 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2047 lclColInd, hint, sorted);
2048 if (offset != rowInfo.numEntries) {
2050 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2053 rowVals(offset) += newVals(j);
2060 else if (isGloballyIndexed ()) {
2063 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2065 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2066 for (LO j = 0; j < numElts; ++j) {
2067 const GO gblColInd = this->colMap_->getGlobalElement (inds(j));
2068 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2069 const size_t offset =
2070 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2071 gblColInd, hint, sorted);
2072 if (offset != rowInfo.numEntries) {
2074 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2077 rowVals(offset) += newVals(j);
2121 template<
class OutputScalarViewType,
2122 class LocalIndicesViewType,
2123 class InputScalarViewType>
2126 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
2127 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
2128 const typename UnmanagedView<InputScalarViewType>::type& newVals)
const 2136 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
2137 "Template parameter OutputScalarViewType must be " 2139 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
2140 "Template parameter LocalIndicesViewType must be " 2142 static_assert (Kokkos::is_view<InputScalarViewType>::value,
2143 "Template parameter InputScalarViewType must be a " 2145 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
2146 "Template parameter OutputScalarViewType must " 2148 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
2149 "Template parameter LocalIndicesViewType must " 2151 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
2152 "Template parameter InputScalarViewType must have " 2154 static_assert (std::is_same<
2155 typename OutputScalarViewType::non_const_value_type,
2156 typename InputScalarViewType::non_const_value_type>::value,
2157 "Template parameters OutputScalarViewType and " 2158 "InputScalarViewType must contain values of the same " 2160 static_assert (std::is_same<
2161 typename LocalIndicesViewType::non_const_value_type,
2162 local_ordinal_type>::value,
2163 "Template parameter LocalIndicesViewType must " 2164 "contain values of type local_ordinal_type.");
2166 typedef LocalOrdinal LO;
2167 typedef GlobalOrdinal GO;
2173 if (colMap_.is_null ()) {
2175 return Teuchos::OrdinalTraits<LO>::invalid ();
2177 else if (newVals.dimension_0 () != inds.dimension_0 ()) {
2179 return Teuchos::OrdinalTraits<LO>::invalid ();
2182 const bool sorted = this->isSorted ();
2191 if (isLocallyIndexed ()) {
2194 auto colInds = this->getLocalKokkosRowView (rowInfo);
2196 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2197 for (LO j = 0; j < numElts; ++j) {
2198 const LO lclColInd = inds(j);
2199 const size_t offset =
2200 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2201 lclColInd, hint, sorted);
2202 if (offset != rowInfo.numEntries) {
2203 rowVals(offset) = newVals(j);
2209 else if (isGloballyIndexed ()) {
2212 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2214 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2215 for (LO j = 0; j < numElts; ++j) {
2216 const GO gblColInd = this->colMap_->getGlobalElement (inds(j));
2217 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2218 const size_t offset =
2219 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2220 gblColInd, hint, sorted);
2221 if (offset != rowInfo.numEntries) {
2222 rowVals(offset) = newVals(j);
2264 template<
class Scalar,
class InputMemorySpace,
class ValsMemorySpace>
2267 const Kokkos::View<Scalar*, ValsMemorySpace,
2268 Kokkos::MemoryUnmanaged>& rowVals,
2269 const Kokkos::View<
const GlobalOrdinal*, InputMemorySpace,
2270 Kokkos::MemoryUnmanaged>& inds,
2271 const Kokkos::View<
const Scalar*, InputMemorySpace,
2272 Kokkos::MemoryUnmanaged>& newVals,
2273 const bool atomic = useAtomicUpdatesByDefault)
const 2275 typedef LocalOrdinal LO;
2276 typedef GlobalOrdinal GO;
2278 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2280 return Teuchos::OrdinalTraits<LO>::invalid ();
2283 const bool sorted = this->isSorted ();
2292 if (isLocallyIndexed ()) {
2296 if (colMap_.is_null ()) {
2304 auto colInds = this->getLocalKokkosRowView (rowInfo);
2305 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2307 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2308 for (LO j = 0; j < numElts; ++j) {
2309 const LO lclColInd = this->colMap_->getLocalElement (inds(j));
2310 if (lclColInd != LINV) {
2311 const size_t offset =
2312 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2313 lclColInd, hint, sorted);
2314 if (offset != rowInfo.numEntries) {
2316 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2319 rowVals(offset) += newVals(j);
2327 else if (isGloballyIndexed ()) {
2330 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2332 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2333 for (LO j = 0; j < numElts; ++j) {
2334 const GO gblColInd = inds(j);
2335 const size_t offset =
2336 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2337 gblColInd, hint, sorted);
2338 if (offset != rowInfo.numEntries) {
2340 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2343 rowVals(offset) += newVals(j);
2381 template<
class OutputScalarViewType,
2382 class GlobalIndicesViewType,
2383 class InputScalarViewType>
2386 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
2387 const typename UnmanagedView<GlobalIndicesViewType>::type& inds,
2388 const typename UnmanagedView<InputScalarViewType>::type& newVals)
const 2396 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
2397 "Template parameter OutputScalarViewType must be " 2399 static_assert (Kokkos::is_view<GlobalIndicesViewType>::value,
2400 "Template parameter GlobalIndicesViewType must be " 2402 static_assert (Kokkos::is_view<InputScalarViewType>::value,
2403 "Template parameter InputScalarViewType must be a " 2405 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
2406 "Template parameter OutputScalarViewType must " 2408 static_assert (static_cast<int> (GlobalIndicesViewType::rank) == 1,
2409 "Template parameter GlobalIndicesViewType must " 2411 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
2412 "Template parameter InputScalarViewType must have " 2414 static_assert (std::is_same<
2415 typename OutputScalarViewType::non_const_value_type,
2416 typename InputScalarViewType::non_const_value_type>::value,
2417 "Template parameters OutputScalarViewType and " 2418 "InputScalarViewType must contain values of the same " 2420 static_assert (std::is_same<
2421 typename GlobalIndicesViewType::non_const_value_type,
2422 global_ordinal_type>::value,
2423 "Template parameter GlobalIndicesViewType must " 2424 "contain values of type global_ordinal_type.");
2426 typedef LocalOrdinal LO;
2427 typedef GlobalOrdinal GO;
2429 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2431 return Teuchos::OrdinalTraits<LO>::invalid ();
2434 const bool sorted = this->isSorted ();
2443 if (isLocallyIndexed ()) {
2447 if (colMap_.is_null ()) {
2455 auto colInds = this->getLocalKokkosRowView (rowInfo);
2456 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2458 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2459 for (LO j = 0; j < numElts; ++j) {
2460 const LO lclColInd = this->colMap_->getLocalElement (inds(j));
2461 if (lclColInd != LINV) {
2462 const size_t offset =
2463 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2464 lclColInd, hint, sorted);
2465 if (offset != rowInfo.numEntries) {
2466 rowVals(offset) = newVals(j);
2473 else if (isGloballyIndexed ()) {
2476 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2478 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2479 for (LO j = 0; j < numElts; ++j) {
2480 const GO gblColInd = inds(j);
2481 const size_t offset =
2482 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2483 gblColInd, hint, sorted);
2484 if (offset != rowInfo.numEntries) {
2485 rowVals(offset) = newVals(j);
2524 template<
class Scalar,
2525 class BinaryFunction,
2526 class InputMemorySpace,
2527 class ValsMemorySpace>
2530 const Kokkos::View<Scalar*, ValsMemorySpace,
2531 Kokkos::MemoryUnmanaged>& rowVals,
2532 const Kokkos::View<
const GlobalOrdinal*,
2534 Kokkos::MemoryUnmanaged>& inds,
2535 const Kokkos::View<
const Scalar*,
2537 Kokkos::MemoryUnmanaged>& newVals,
2539 const bool atomic = useAtomicUpdatesByDefault)
const 2541 typedef LocalOrdinal LO;
2542 typedef GlobalOrdinal GO;
2544 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2546 return Teuchos::OrdinalTraits<LO>::invalid ();
2549 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2550 const bool sorted = this->isSorted ();
2555 if (isLocallyIndexed ()) {
2559 if (colMap_.is_null ()) {
2565 const map_type& colMap = *colMap_;
2568 auto colInds = this->getLocalKokkosRowView (rowInfo);
2570 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2571 for (LO j = 0; j < numElts; ++j) {
2573 if (lclColInd != LINV) {
2574 const size_t offset =
2575 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2576 lclColInd, hint, sorted);
2577 if (offset != rowInfo.numEntries) {
2586 volatile Scalar*
const dest = &rowVals(offset);
2587 (void) atomic_binary_function_update (dest, newVals(j), f);
2591 rowVals(offset) = f (rowVals(offset), newVals(j));
2599 else if (isGloballyIndexed ()) {
2602 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2604 for (LO j = 0; j < numElts; ++j) {
2605 const GO gblColInd = inds(j);
2606 const size_t offset =
2607 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2608 gblColInd, hint, sorted);
2609 if (offset != rowInfo.numEntries) {
2618 volatile Scalar*
const dest = &rowVals(offset);
2619 (void) atomic_binary_function_update (dest, newVals(j), f);
2623 rowVals(offset) = f (rowVals(offset), newVals(j));
2642 bool isMerged ()
const;
2649 void setLocallyModified ();
2652 void sortAllIndices ();
2655 void sortRowIndices (
const RowInfo rowinfo);
2671 template <
class Scalar>
2674 const Teuchos::ArrayView<Scalar>& values)
2676 if (rowinfo.numEntries > 0) {
2677 Teuchos::ArrayView<LocalOrdinal> inds_view =
2678 this->getLocalViewNonConst (rowinfo);
2679 sort2 (inds_view.begin (), inds_view.begin () + rowinfo.numEntries,
2692 void mergeAllIndices ();
2698 void mergeRowIndices (
RowInfo rowinfo);
2710 template<
class Scalar>
2713 const Teuchos::ArrayView<Scalar>& rowValues)
2715 using Teuchos::ArrayView;
2716 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
2717 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2718 (isStorageOptimized(), std::logic_error,
"It is invalid to call this " 2719 "method if the graph's storage has already been optimized. Please " 2720 "report this bug to the Tpetra developers.");
2722 typedef typename ArrayView<Scalar>::iterator Iter;
2723 Iter rowValueIter = rowValues.begin ();
2724 ArrayView<LocalOrdinal> inds_view = getLocalViewNonConst (rowinfo);
2725 typename ArrayView<LocalOrdinal>::iterator beg, end, newend;
2728 beg = inds_view.begin();
2729 end = inds_view.begin() + rowinfo.numEntries;
2732 typename ArrayView<LocalOrdinal>::iterator cur = beg + 1;
2733 Iter vcur = rowValueIter + 1;
2734 Iter vend = rowValueIter;
2736 while (cur != end) {
2737 if (*cur != *newend) {
2754 const size_t mergedEntries = newend - beg;
2755 #ifdef HAVE_TPETRA_DEBUG 2758 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2759 (isStorageOptimized() && mergedEntries != rowinfo.numEntries,
2761 "Merge was incorrect; it eliminated entries from the graph. " 2762 <<
"Please report this bug to the Tpetra developers.");
2763 #endif // HAVE_TPETRA_DEBUG 2765 k_numRowEntries_(rowinfo.localRow) = mergedEntries;
2766 nodeNumEntries_ -= (rowinfo.numEntries - mergedEntries);
2781 setDomainRangeMaps (
const Teuchos::RCP<const map_type>& domainMap,
2782 const Teuchos::RCP<const map_type>& rangeMap);
2784 void staticAssertions()
const;
2785 void clearGlobalConstants();
2786 void computeGlobalConstants();
2790 RowInfo getRowInfo (
const LocalOrdinal myRow)
const;
2804 RowInfo getRowInfoFromGlobalRowIndex (
const GlobalOrdinal gblRow)
const;
2809 Teuchos::ArrayView<const LocalOrdinal>
2810 getLocalView (
const RowInfo rowinfo)
const;
2815 Teuchos::ArrayView<LocalOrdinal>
2816 getLocalViewNonConst (
const RowInfo rowinfo);
2829 getLocalViewRawConst (
const LocalOrdinal*& lclInds,
2830 LocalOrdinal& numEnt,
2831 const RowInfo& rowinfo)
const;
2841 Kokkos::View<const LocalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2842 getLocalKokkosRowView (
const RowInfo& rowinfo)
const;
2850 Kokkos::View<LocalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2851 getLocalKokkosRowViewNonConst (
const RowInfo& rowinfo);
2859 Kokkos::View<const GlobalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2860 getGlobalKokkosRowView (
const RowInfo& rowinfo)
const;
2867 Teuchos::ArrayView<const GlobalOrdinal>
2868 getGlobalView (
const RowInfo rowinfo)
const;
2873 Teuchos::ArrayView<GlobalOrdinal>
2874 getGlobalViewNonConst (
const RowInfo rowinfo);
2888 getGlobalViewRawConst (
const GlobalOrdinal*& gblInds,
2889 LocalOrdinal& numEnt,
2890 const RowInfo& rowinfo)
const;
2900 local_graph_type getLocalGraph ()
const;
2903 void fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params);
2906 bool hasRowInfo ()
const;
2909 void checkInternalState ()
const;
2941 global_size_t globalNumEntries_, globalNumDiags_, globalMaxNumRowEntries_;
2942 size_t nodeNumEntries_, nodeNumDiags_, nodeMaxNumRowEntries_, nodeNumAllocated_;
2972 typename Kokkos::View<const size_t*, execution_space>::HostMirror
3082 typename Kokkos::View<size_t*, Kokkos::LayoutLeft, device_type>::HostMirror
3097 bool indicesAreAllocated_;
3098 bool indicesAreLocal_;
3099 bool indicesAreGlobal_;
3143 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic = Node::
classic>
3144 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> >
3146 size_t maxNumEntriesPerRow = 0,
3147 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
3151 return rcp (
new graph_type (map, maxNumEntriesPerRow,
DynamicProfile, params));
3156 template<
class LocalOrdinal,
3157 class GlobalOrdinal,
3158 class OutputNodeType,
3159 class InputNodeType>
3160 class CrsGraphCopier<CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType>,
3161 CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> > {
3166 static Teuchos::RCP<output_crs_graph_type>
3167 clone (
const input_crs_graph_type& graphIn,
3168 const Teuchos::RCP<OutputNodeType> &nodeOut,
3169 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
3171 using Teuchos::arcp;
3172 using Teuchos::Array;
3173 using Teuchos::ArrayRCP;
3174 using Teuchos::ArrayView;
3175 using Teuchos::null;
3176 using Teuchos::outArg;
3177 using Teuchos::ParameterList;
3178 using Teuchos::parameterList;
3181 using Teuchos::REDUCE_MIN;
3182 using Teuchos::reduceAll;
3183 using Teuchos::sublist;
3186 typedef LocalOrdinal LO;
3187 typedef GlobalOrdinal GO;
3188 typedef typename ArrayView<const GO>::size_type size_type;
3189 typedef ::Tpetra::Map<LO, GO, InputNodeType> input_map_type;
3190 typedef ::Tpetra::Map<LO, GO, OutputNodeType> output_map_type;
3191 const char prefix[] =
"Tpetra::Details::CrsGraphCopier::clone: ";
3195 bool fillCompleteClone =
true;
3196 bool useLocalIndices = graphIn.hasColMap ();
3199 if (! params.is_null ()) {
3200 fillCompleteClone = params->get (
"fillComplete clone", fillCompleteClone);
3201 useLocalIndices = params->get (
"Locally indexed clone", useLocalIndices);
3202 if (params->get (
"Static profile clone",
true) ==
false) {
3205 debug = params->get (
"Debug", debug);
3208 const Teuchos::Comm<int>& comm = * (graphIn.getRowMap ()->getComm ());
3209 const int myRank = comm.getRank ();
3211 TEUCHOS_TEST_FOR_EXCEPTION(
3212 ! graphIn.hasColMap () && useLocalIndices, std::runtime_error,
3213 prefix <<
"You asked clone() to use local indices (by setting the " 3214 "\"Locally indexed clone\" parameter to true), but the source graph " 3215 "does not yet have a column Map, so this is impossible.");
3218 std::ostringstream os;
3219 os <<
"Process " << myRank <<
": Cloning row Map" << endl;
3223 RCP<const output_map_type> clonedRowMap =
3224 graphIn.getRowMap ()->template clone<OutputNodeType> (nodeOut);
3228 RCP<output_crs_graph_type> clonedGraph;
3230 ArrayRCP<const size_t> numEntriesPerRow;
3231 size_t numEntriesForAll = 0;
3232 bool boundSameForAllLocalRows =
true;
3235 std::ostringstream os;
3236 os <<
"Process " << myRank <<
": Getting per-row bounds" << endl;
3239 graphIn.getNumEntriesPerLocalRowUpperBound (numEntriesPerRow,
3241 boundSameForAllLocalRows);
3243 std::ostringstream os;
3244 os <<
"Process " << myRank <<
": numEntriesForAll = " 3245 << numEntriesForAll << endl;
3250 std::ostringstream os;
3251 os <<
"Process " << myRank <<
": graphIn.getNodeMaxNumRowEntries() = " 3252 << graphIn.getNodeMaxNumRowEntries () << endl;
3256 RCP<ParameterList> graphparams;
3257 if (params.is_null ()) {
3258 graphparams = parameterList (
"CrsGraph");
3260 graphparams = sublist (params,
"CrsGraph");
3262 if (useLocalIndices) {
3263 RCP<const output_map_type> clonedColMap =
3264 graphIn.getColMap ()->template clone<OutputNodeType> (nodeOut);
3265 if (boundSameForAllLocalRows) {
3266 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap, clonedColMap,
3267 numEntriesForAll, pftype,
3270 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap, clonedColMap,
3271 numEntriesPerRow, pftype,
3275 if (boundSameForAllLocalRows) {
3276 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap,
3277 numEntriesForAll, pftype,
3280 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap,
3282 pftype, graphparams));
3287 std::ostringstream os;
3288 os <<
"Process " << myRank <<
": Invoked output graph's constructor" << endl;
3293 numEntriesPerRow = null;
3294 numEntriesForAll = 0;
3297 const input_map_type& inputRowMap = * (graphIn.getRowMap ());
3298 const size_type numRows =
3299 static_cast<size_type
> (inputRowMap.getNodeNumElements ());
3301 bool failed =
false;
3303 if (useLocalIndices) {
3304 const LO localMinLID = inputRowMap.getMinLocalIndex ();
3305 const LO localMaxLID = inputRowMap.getMaxLocalIndex ();
3307 if (graphIn.isLocallyIndexed ()) {
3310 ArrayView<const LO> linds;
3311 for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
3312 graphIn.getLocalRowView (lrow, linds);
3313 if (linds.size () != 0) {
3314 clonedGraph->insertLocalIndices (lrow, linds);
3318 catch (std::exception& e) {
3319 std::ostringstream os;
3320 os <<
"Process " << myRank <<
": copying (reading local by view, " 3321 "writing local) indices into the output graph threw an " 3322 "exception: " << e.what () << endl;
3329 TEUCHOS_TEST_FOR_EXCEPTION(
3330 ! graphIn.hasColMap () && useLocalIndices, std::invalid_argument,
3331 prefix <<
"You asked clone() to use local indices (by setting the " 3332 "\"Locally indexed clone\" parameter to true), but the source graph " 3333 "does not yet have a column Map, so this is impossible.");
3348 size_t myMaxNumRowEntries =
3349 graphIn.isFillActive () ?
static_cast<size_t> (0) :
3350 graphIn.getNodeMaxNumRowEntries ();
3352 Array<LO> linds (myMaxNumRowEntries);
3355 for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
3356 size_t theNumEntries = graphIn.getNumEntriesInLocalRow (lrow);
3357 if (theNumEntries > myMaxNumRowEntries) {
3358 myMaxNumRowEntries = theNumEntries;
3359 linds.resize (myMaxNumRowEntries);
3361 graphIn.getLocalRowCopy (lrow, linds (), theNumEntries);
3362 if (theNumEntries != 0) {
3363 clonedGraph->insertLocalIndices (lrow, linds (0, theNumEntries));
3367 catch (std::exception& e) {
3368 std::ostringstream os;
3369 os <<
"Process " << myRank <<
": copying (reading local by copy, " 3370 "writing local) indices into the output graph threw an exception: " 3371 << e.what () << endl;
3379 const GlobalOrdinal localMinGID = inputRowMap.getMinGlobalIndex ();
3380 const GlobalOrdinal localMaxGID = inputRowMap.getMaxGlobalIndex ();
3381 const bool inputRowMapIsContiguous = inputRowMap.isContiguous ();
3383 if (graphIn.isGloballyIndexed ()) {
3384 ArrayView<const GlobalOrdinal> ginds;
3386 if (inputRowMapIsContiguous) {
3388 for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
3389 graphIn.getGlobalRowView (grow, ginds);
3390 if (ginds.size () != 0) {
3391 clonedGraph->insertGlobalIndices (grow, ginds);
3395 catch (std::exception& e) {
3396 std::ostringstream os;
3397 os <<
"Process " << myRank <<
": copying (reading global by view, " 3398 "writing global) indices into the output graph threw an " 3399 "exception: " << e.what () << endl;
3406 ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
3407 for (size_type k = 0; k < numRows; ++k) {
3408 const GO grow = inputRowMapGIDs[k];
3409 graphIn.getGlobalRowView (grow, ginds);
3410 if (ginds.size () != 0) {
3411 clonedGraph->insertGlobalIndices (grow, ginds);
3415 catch (std::exception& e) {
3416 std::ostringstream os;
3417 os <<
"Process " << myRank <<
": copying (reading global by view, " 3418 "writing global) indices into the output graph threw an " 3419 "exception: " << e.what () << endl;
3432 size_t myMaxNumRowEntries =
3433 graphIn.isFillActive () ?
static_cast<size_t> (0) :
3434 graphIn.getNodeMaxNumRowEntries ();
3436 Array<GO> ginds (myMaxNumRowEntries);
3438 if (inputRowMapIsContiguous) {
3440 for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
3441 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
3442 if (theNumEntries > myMaxNumRowEntries) {
3443 myMaxNumRowEntries = theNumEntries;
3444 ginds.resize (myMaxNumRowEntries);
3446 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
3447 if (theNumEntries != 0) {
3448 clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
3452 catch (std::exception& e) {
3453 std::ostringstream os;
3454 os <<
"Process " << myRank <<
": copying (reading global by copy, " 3455 "writing global) indices into the output graph threw an " 3456 "exception: " << e.what () << endl;
3463 ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
3464 for (size_type k = 0; k < numRows; ++k) {
3465 const GO grow = inputRowMapGIDs[k];
3467 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
3468 if (theNumEntries > myMaxNumRowEntries) {
3469 myMaxNumRowEntries = theNumEntries;
3470 ginds.resize (myMaxNumRowEntries);
3472 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
3473 if (theNumEntries != 0) {
3474 clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
3478 catch (std::exception& e) {
3479 std::ostringstream os;
3480 os <<
"Process " << myRank <<
": copying (reading global by copy, " 3481 "writing global) indices into the output graph threw an " 3482 "exception: " << e.what () << endl;
3492 std::ostringstream os;
3493 os <<
"Process " << myRank <<
": copied entries" << endl;
3497 if (fillCompleteClone) {
3498 RCP<ParameterList> fillparams = params.is_null () ?
3499 parameterList (
"fillComplete") :
3500 sublist (params,
"fillComplete");
3502 RCP<const output_map_type> clonedRangeMap;
3503 RCP<const output_map_type> clonedDomainMap;
3504 if (! graphIn.getRangeMap ().is_null () &&
3505 graphIn.getRangeMap () != graphIn.getRowMap ()) {
3507 graphIn.getRangeMap ()->template clone<OutputNodeType> (nodeOut);
3510 clonedRangeMap = clonedRowMap;
3512 if (! graphIn.getDomainMap ().is_null ()
3513 && graphIn.getDomainMap () != graphIn.getRowMap ()) {
3515 graphIn.getDomainMap ()->template clone<OutputNodeType> (nodeOut);
3518 clonedDomainMap = clonedRowMap;
3522 std::ostringstream os;
3523 os <<
"Process " << myRank <<
": About to call fillComplete on " 3524 "cloned graph" << endl;
3527 clonedGraph->fillComplete (clonedDomainMap, clonedRangeMap, fillparams);
3529 catch (std::exception &e) {
3531 std::ostringstream os;
3532 os << prefix <<
"Process " << myRank <<
": Caught the following " 3533 "exception while calling fillComplete() on clone of type" 3534 << endl << Teuchos::typeName (*clonedGraph) << endl;
3539 int lclSuccess = failed ? 0 : 1;
3541 reduceAll<int, int> (comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
3542 TEUCHOS_TEST_FOR_EXCEPTION(
3543 gblSuccess != 1, std::logic_error, prefix <<
3544 "Clone failed on at least one process.");
3547 std::ostringstream os;
3548 os <<
"Process " << myRank <<
": Done with CrsGraph::clone" << endl;
3558 #endif // TPETRA_CRSGRAPH_DECL_HPP Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
LocalOrdinal sumIntoGlobalValues(const RowInfo &rowInfo, const Kokkos::View< Scalar *, ValsMemorySpace, Kokkos::MemoryUnmanaged > &rowVals, const Kokkos::View< const GlobalOrdinal *, InputMemorySpace, Kokkos::MemoryUnmanaged > &inds, const Kokkos::View< const Scalar *, InputMemorySpace, Kokkos::MemoryUnmanaged > &newVals, const bool atomic=useAtomicUpdatesByDefault) const
Implementation detail of CrsMatrix::sumIntoGlobalValues.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
bool haveGlobalConstants_
Whether all processes have computed global constants.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
An abstract interface for graphs accessed by rows.
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
GlobalOrdinal global_ordinal_type
This class' second template parameter; the type of global indices.
bool noRedundancies_
Whether the graph's indices are non-redundant (merged) in each row, on this process.
KokkosClassic::DefaultNode::DefaultNodeType node_type
Default value of Node template parameter.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
local_graph_type LocalStaticCrsGraphType TPETRA_DEPRECATED
DEPRECATED; use local_graph_type (above) instead.
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.
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.
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.
LocalOrdinal local_ordinal_type
This class' first template parameter; the type of local indices.
Teuchos::RCP< CrsGraph< LocalOrdinal, GlobalOrdinal, Node, classic > > createCrsGraph(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, size_t maxNumEntriesPerRow=0, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Nonmember function to create an empty CrsGraph given a row Map and the max number of entries allowed ...
void removeEmptyProcessesInPlace(Teuchos::RCP< DistObjectType > &input, const Teuchos::RCP< const Map< typename DistObjectType::local_ordinal_type, typename DistObjectType::global_ordinal_type, typename DistObjectType::node_type > > &newMap)
Remove processes which contain no elements in this object's Map.
bool upperTriangular_
Whether the graph is locally upper triangular.
LocalOrdinal sumIntoLocalValues(const RowInfo &rowInfo, const typename UnmanagedView< OutputScalarViewType >::type &rowVals, const typename UnmanagedView< LocalIndicesViewType >::type &inds, const typename UnmanagedView< InputScalarViewType >::type &newVals, const bool atomic=useAtomicUpdatesByDefault) const
Implementation detail of CrsMatrix::sumIntoLocalValues.
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.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
int local_ordinal_type
Default value of LocalOrdinal template parameter.
LocalOrdinal replaceLocalValues(const RowInfo &rowInfo, const typename UnmanagedView< OutputScalarViewType >::type &rowVals, const typename UnmanagedView< LocalIndicesViewType >::type &inds, const typename UnmanagedView< InputScalarViewType >::type &newVals) const
Implementation detail of CrsMatrix::replaceLocalValues.
LocalOrdinal transformLocalValues(const RowInfo &rowInfo, const typename UnmanagedView< OutputScalarViewType >::type &rowVals, const typename UnmanagedView< LocalIndicesViewType >::type &inds, const typename UnmanagedView< InputScalarViewType >::type &newVals, BinaryFunction f, const bool atomic=useAtomicUpdatesByDefault) const
Transform the given values using local indices.
Teuchos::RCP< const map_type > colMap_
The Map describing the distribution of columns of the graph.
Implementation details of Tpetra.
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 haveLocalConstants_
Whether this process has computed local constants.
t_GlobalOrdinal_1D k_gblInds1D_
Global column indices for all rows.
local_graph_type lclGraph_
Local graph; only initialized after first fillComplete() call.
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.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Teuchos::RCP< CrsGraph< LocalOrdinal, GlobalOrdinal, Node2, Node2::classic > > clone(const Teuchos::RCP< Node2 > &node2, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null) const
Create a cloned CrsGraph for a different Node type.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
Abstract base class for objects that can be the source of an Import or Export operation.
Teuchos::RCP< const import_type > importer_
The Import from the domain Map to the column Map.
LocalOrdinal transformGlobalValues(const RowInfo &rowInfo, const Kokkos::View< Scalar *, ValsMemorySpace, Kokkos::MemoryUnmanaged > &rowVals, const Kokkos::View< const GlobalOrdinal *, InputMemorySpace, Kokkos::MemoryUnmanaged > &inds, const Kokkos::View< const Scalar *, InputMemorySpace, Kokkos::MemoryUnmanaged > &newVals, BinaryFunction f, const bool atomic=useAtomicUpdatesByDefault) const
Transform the given values using global indices.
Node node_type
This class' Kokkos Node type.
Teuchos::RCP< const map_type > rowMap_
The Map describing the distribution of rows of the graph.
Teuchos::ArrayRCP< Teuchos::Array< LocalOrdinal > > lclInds2D_
Local column indices for all rows.
Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The Map specialization used by this class.
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.
Describes a parallel distribution of objects over processes.
Details::EStorageStatus storageStatus_
Status of the graph's storage, when not in a fill-complete state.
Stand-alone utility functions and macros.
device_type::execution_space execution_space
This class' Kokkos execution space.
local_graph_type::entries_type::non_const_type t_LocalOrdinal_1D TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::entries_type::non_const_type instead.
local_graph_type::row_map_type::const_type k_rowPtrs_
Row offsets for "1-D" storage.
Kokkos::View< size_t *, Kokkos::LayoutLeft, device_type >::HostMirror k_numRowEntries_
The number of local entries in each locally owned row.
std::map< GlobalOrdinal, std::vector< GlobalOrdinal > > nonlocals_
Nonlocal data given to insertGlobalValues or sumIntoGlobalValues.
local_graph_type::row_map_type t_RowPtrs TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::row_map_type instead.
local_graph_type::row_map_type::non_const_type t_RowPtrsNC TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::row_map_type::non_const_type instead.
Kokkos::View< GlobalOrdinal *, execution_space > t_GlobalOrdinal_1D
Type of the k_gblInds1D_ array of global column indices.
Base class for distributed Tpetra objects that support data redistribution.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
Tpetra::Export< LocalOrdinal, GlobalOrdinal, Node > export_type
The Export specialization used by this class.
LocalOrdinal replaceGlobalValues(const RowInfo &rowInfo, const typename UnmanagedView< OutputScalarViewType >::type &rowVals, const typename UnmanagedView< GlobalIndicesViewType >::type &inds, const typename UnmanagedView< InputScalarViewType >::type &newVals) const
Implementation detail of CrsMatrix::replaceGlobalValues.
EStorageStatus
Status of the graph's or matrix's storage, when not in a fill-complete state.
Teuchos::RCP< const export_type > exporter_
The Export from the row Map to the range Map.
bool lowerTriangular_
Whether the graph is locally lower triangular.
Kokkos::View< const size_t *, execution_space >::HostMirror k_numAllocPerRow_
The maximum number of entries to allow in each locally owned row, per row.
Tpetra::Import< LocalOrdinal, GlobalOrdinal, Node > import_type
The Import specialization used by this class.