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 (
const GlobalOrdinal gblRow,
1015 Teuchos::ArrayView<const GlobalOrdinal>& gblColInds)
const;
1019 bool supportsRowViews ()
const;
1032 getLocalRowView (
const LocalOrdinal lclRow,
1033 Teuchos::ArrayView<const LocalOrdinal>& lclColInds)
const;
1040 std::string description()
const;
1044 describe (Teuchos::FancyOStream& out,
1045 const Teuchos::EVerbosityLevel verbLevel =
1046 Teuchos::Describable::verbLevel_default)
const;
1058 const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
1059 const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs);
1063 const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
1064 Teuchos::Array<GlobalOrdinal> &exports,
1065 const Teuchos::ArrayView<size_t> & numPacketsPerLID,
1066 size_t& constantNumPackets,
1070 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
1071 Teuchos::Array<GlobalOrdinal>& exports,
1072 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
1073 size_t& constantNumPackets,
1077 unpackAndCombine (
const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
1078 const Teuchos::ArrayView<const GlobalOrdinal> &imports,
1079 const Teuchos::ArrayView<size_t> &numPacketsPerLID,
1080 size_t constantNumPackets,
1130 getLocalDiagOffsets (
const Kokkos::View<size_t*, device_type, Kokkos::MemoryUnmanaged>& offsets)
const;
1142 getLocalDiagOffsets (Teuchos::ArrayRCP<size_t>& offsets)
const;
1167 getNumEntriesPerLocalRowUpperBound (Teuchos::ArrayRCP<const size_t>& boundPerLocalRow,
1168 size_t& boundForAllLocalRows,
1169 bool& boundSameForAllLocalRows)
const;
1180 setAllIndices (
const typename local_graph_type::row_map_type& rowPointers,
1181 const typename local_graph_type::entries_type::non_const_type& columnIndices);
1192 setAllIndices (
const Teuchos::ArrayRCP<size_t> & rowPointers,
1193 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices);
1202 Teuchos::ArrayRCP<const size_t> getNodeRowPtrs ()
const;
1207 Teuchos::ArrayRCP<const LocalOrdinal> getNodePackedIndices()
const;
1219 void replaceColMap (
const Teuchos::RCP<const map_type>& newColMap);
1241 reindexColumns (
const Teuchos::RCP<const map_type>& newColMap,
1242 const Teuchos::RCP<const import_type>& newImport = Teuchos::null,
1243 const bool sortIndicesInEachRow =
true);
1259 replaceDomainMapAndImporter (
const Teuchos::RCP<const map_type>& newDomainMap,
1260 const Teuchos::RCP<const import_type>& newImporter);
1294 template<
class ViewType,
class OffsetViewType >
1295 struct pack_functor {
1296 typedef typename ViewType::execution_space execution_space;
1299 OffsetViewType src_offset;
1300 OffsetViewType dest_offset;
1301 typedef typename OffsetViewType::non_const_value_type ScalarIndx;
1303 pack_functor(ViewType dest_, ViewType src_, OffsetViewType dest_offset_, OffsetViewType src_offset_):
1304 src(src_),dest(dest_),src_offset(src_offset_),dest_offset(dest_offset_) {};
1306 KOKKOS_INLINE_FUNCTION
1307 void operator() (
size_t row)
const {
1308 ScalarIndx i = src_offset(row);
1309 ScalarIndx j = dest_offset(row);
1310 const ScalarIndx k = dest_offset(row+1);
1320 struct SLocalGlobalViews {
1321 Teuchos::ArrayView<const GlobalOrdinal> ginds;
1322 Teuchos::ArrayView<const LocalOrdinal> linds;
1324 struct SLocalGlobalNCViews {
1325 Teuchos::ArrayView<GlobalOrdinal> ginds;
1326 Teuchos::ArrayView<LocalOrdinal> linds;
1329 bool indicesAreAllocated ()
const;
1330 void allocateIndices (
const ELocalGlobal lg);
1333 Teuchos::ArrayRCP<Teuchos::Array<T> > allocateValues2D ()
const 1335 using Teuchos::arcp;
1336 using Teuchos::Array;
1337 using Teuchos::ArrayRCP;
1338 using Teuchos::null;
1339 const char tfecfFuncName[] =
"allocateValues2D: ";
1341 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1342 (! indicesAreAllocated (), std::runtime_error,
1343 "Graph indices must be allocated before values.");
1344 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1346 "Graph indices must be allocated in a dynamic profile.");
1348 ArrayRCP<Array<T> > values2D;
1349 values2D = arcp<Array<T> > (getNodeNumRows ());
1350 if (lclInds2D_ != null) {
1351 const size_t numRows = lclInds2D_.size ();
1352 for (
size_t r = 0; r < numRows; ++r) {
1353 values2D[r].resize (lclInds2D_[r].size ());
1356 else if (gblInds2D_ != null) {
1357 const size_t numRows = gblInds2D_.size ();
1358 for (
size_t r = 0; r < numRows; ++r) {
1359 values2D[r].resize (gblInds2D_[r].size ());
1367 const size_t newAllocSize,
1368 Teuchos::Array<T>& rowVals)
1370 #ifdef HAVE_TPETRA_DEBUG 1371 TEUCHOS_TEST_FOR_EXCEPT( ! isLocallyIndexed () );
1372 TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated() );
1373 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1374 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1375 TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1376 #endif // HAVE_TPETRA_DEBUG 1379 lclInds2D_[rowInfo.localRow].resize (newAllocSize);
1380 rowVals.resize (newAllocSize);
1383 rowInfoOut.allocSize = newAllocSize;
1389 updateGlobalAllocAndValues (
const RowInfo rowInfo,
1390 const size_t newAllocSize,
1391 Teuchos::Array<T>& rowVals)
1393 #ifdef HAVE_TPETRA_DEBUG 1394 TEUCHOS_TEST_FOR_EXCEPT( ! isGloballyIndexed () );
1395 TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated () );
1396 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1397 TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1398 TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1399 #endif // HAVE_TPETRA_DEBUG 1402 gblInds2D_[rowInfo.localRow].resize (newAllocSize);
1403 rowVals.resize (newAllocSize);
1406 rowInfoOut.allocSize = newAllocSize;
1420 void makeIndicesLocal ();
1421 void makeImportExport ();
1427 template<ELocalGlobal lg>
1428 size_t filterIndices (
const SLocalGlobalNCViews& inds)
const 1430 using Teuchos::ArrayView;
1431 static_assert (lg == GlobalIndices || lg == LocalIndices,
1432 "Tpetra::CrsGraph::filterIndices: The template parameter " 1433 "lg must be either GlobalIndices or LocalIndicies.");
1435 const map_type& cmap = *colMap_;
1436 size_t numFiltered = 0;
1437 #ifdef HAVE_TPETRA_DEBUG 1438 size_t numFiltered_debug = 0;
1440 if (lg == GlobalIndices) {
1441 ArrayView<GlobalOrdinal> ginds = inds.ginds;
1442 typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1443 typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1444 while (cptr != ginds.end()) {
1447 #ifdef HAVE_TPETRA_DEBUG 1448 ++numFiltered_debug;
1453 numFiltered = fend - ginds.begin();
1455 else if (lg == LocalIndices) {
1456 ArrayView<LocalOrdinal> linds = inds.linds;
1457 typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1458 typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1459 while (cptr != linds.end()) {
1462 #ifdef HAVE_TPETRA_DEBUG 1463 ++numFiltered_debug;
1468 numFiltered = fend - linds.begin();
1470 #ifdef HAVE_TPETRA_DEBUG 1471 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1479 filterGlobalIndicesAndValues (
const Teuchos::ArrayView<GlobalOrdinal>& ginds,
1480 const Teuchos::ArrayView<T>& vals)
const 1482 using Teuchos::ArrayView;
1483 const map_type& cmap = *colMap_;
1484 size_t numFiltered = 0;
1485 typename ArrayView<T>::iterator fvalsend = vals.begin();
1486 typename ArrayView<T>::iterator valscptr = vals.begin();
1487 #ifdef HAVE_TPETRA_DEBUG 1488 size_t numFiltered_debug = 0;
1490 typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1491 typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1492 while (cptr != ginds.end()) {
1495 *fvalsend++ = *valscptr;
1496 #ifdef HAVE_TPETRA_DEBUG 1497 ++numFiltered_debug;
1503 numFiltered = fend - ginds.begin();
1504 #ifdef HAVE_TPETRA_DEBUG 1505 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1506 TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1507 const size_t numFilteredActual =
1508 static_cast<size_t> (fvalsend - vals.begin ());
1509 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1510 #endif // HAVE_TPETRA_DEBUG 1516 filterLocalIndicesAndValues (
const Teuchos::ArrayView<LocalOrdinal>& linds,
1517 const Teuchos::ArrayView<T>& vals)
const 1519 using Teuchos::ArrayView;
1520 const map_type& cmap = *colMap_;
1521 size_t numFiltered = 0;
1522 typename ArrayView<T>::iterator fvalsend = vals.begin();
1523 typename ArrayView<T>::iterator valscptr = vals.begin();
1524 #ifdef HAVE_TPETRA_DEBUG 1525 size_t numFiltered_debug = 0;
1527 typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1528 typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1529 while (cptr != linds.end()) {
1532 *fvalsend++ = *valscptr;
1533 #ifdef HAVE_TPETRA_DEBUG 1534 ++numFiltered_debug;
1540 numFiltered = fend - linds.begin();
1541 #ifdef HAVE_TPETRA_DEBUG 1542 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1543 TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1544 const size_t numFilteredActual =
1545 Teuchos::as<size_t> (fvalsend - vals.begin ());
1546 TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1581 insertIndices (
const RowInfo& rowInfo,
1582 const SLocalGlobalViews& newInds,
1583 const ELocalGlobal lg,
1584 const ELocalGlobal I);
1625 template<
class Scalar>
1628 const SLocalGlobalViews& newInds,
1629 const Teuchos::ArrayView<Scalar>& oldRowVals,
1630 const Teuchos::ArrayView<const Scalar>& newRowVals,
1631 const ELocalGlobal lg,
1632 const ELocalGlobal I)
1634 #ifdef HAVE_TPETRA_DEBUG 1635 const char tfecfFuncName[] =
"insertIndicesAndValues: ";
1636 #endif // HAVE_TPETRA_DEBUG 1638 #ifdef HAVE_TPETRA_DEBUG 1639 size_t numNewInds = 0;
1641 numNewInds = insertIndices (rowInfo, newInds, lg, I);
1642 }
catch (std::exception& e) {
1643 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1644 (
true, std::runtime_error,
"insertIndices threw an exception: " 1647 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1648 (numNewInds > static_cast<size_t> (oldRowVals.size ()),
1649 std::runtime_error,
"numNewInds (" << numNewInds <<
") > " 1650 "oldRowVals.size() (" << oldRowVals.size () <<
".");
1652 const size_t numNewInds = insertIndices (rowInfo, newInds, lg, I);
1653 #endif // HAVE_TPETRA_DEBUG 1655 typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1657 #ifdef HAVE_TPETRA_DEBUG 1658 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1659 (rowInfo.numEntries + numNewInds > static_cast<size_t> (oldRowVals.size ()),
1660 std::runtime_error,
"rowInfo.numEntries (" << rowInfo.numEntries <<
")" 1661 " + numNewInds (" << numNewInds <<
") > oldRowVals.size() (" 1662 << oldRowVals.size () <<
").");
1663 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1664 (static_cast<size_type> (numNewInds) > newRowVals.size (),
1665 std::runtime_error,
"numNewInds (" << numNewInds <<
") > " 1666 "newRowVals.size() (" << newRowVals.size () <<
").");
1667 #endif // HAVE_TPETRA_DEBUG 1669 size_type oldInd =
static_cast<size_type
> (rowInfo.numEntries);
1671 #ifdef HAVE_TPETRA_DEBUG 1673 #endif // HAVE_TPETRA_DEBUG 1676 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 1677 #define GCC_VERSION __GNUC__*100+__GNUC_MINOR__*10+__GNUC_PATCHLEVEL__ 1678 #if GCC_VERSION >= 490 1679 #define GCC_WORKAROUND 1682 #ifdef GCC_WORKAROUND 1683 size_type nNI =
static_cast<size_type
>(numNewInds);
1685 memcpy(&oldRowVals[oldInd], &newRowVals[0], nNI*
sizeof(Scalar));
1726 #else // GCC Workaround above 1727 for (size_type newInd = 0; newInd < static_cast<size_type> (numNewInds);
1728 ++newInd, ++oldInd) {
1729 oldRowVals[oldInd] = newRowVals[newInd];
1731 #endif // GCC Workaround 1732 #ifdef HAVE_TPETRA_DEBUG 1734 catch (std::exception& e) {
1735 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1736 (
true, std::runtime_error,
"for loop for copying values threw an " 1737 "exception: " << e.what ());
1739 #endif // HAVE_TPETRA_DEBUG 1743 insertGlobalIndicesImpl (
const LocalOrdinal myRow,
1744 const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1746 insertLocalIndicesImpl (
const LocalOrdinal myRow,
1747 const Teuchos::ArrayView<const LocalOrdinal> &indices);
1750 insertLocalIndicesFiltered (
const LocalOrdinal localRow,
1751 const Teuchos::ArrayView<const LocalOrdinal> &indices);
1755 insertGlobalIndicesFiltered (
const GlobalOrdinal localRow,
1756 const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1762 static const bool useAtomicUpdatesByDefault =
1763 #ifdef KOKKOS_HAVE_SERIAL 1764 ! std::is_same<execution_space, Kokkos::Serial>::value;
1767 #endif // KOKKOS_HAVE_SERIAL 1807 template<
class OutputScalarViewType,
1808 class LocalIndicesViewType,
1809 class InputScalarViewType,
1810 class BinaryFunction>
1813 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
1814 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
1815 const typename UnmanagedView<InputScalarViewType>::type& newVals,
1817 const bool atomic = useAtomicUpdatesByDefault)
const 1825 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
1826 "Template parameter OutputScalarViewType must be " 1828 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
1829 "Template parameter LocalIndicesViewType must be " 1831 static_assert (Kokkos::is_view<InputScalarViewType>::value,
1832 "Template parameter InputScalarViewType must be a " 1834 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
1835 "Template parameter OutputScalarViewType must " 1837 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
1838 "Template parameter LocalIndicesViewType must " 1840 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
1841 "Template parameter InputScalarViewType must have " 1843 static_assert (std::is_same<
1844 typename OutputScalarViewType::non_const_value_type,
1845 typename InputScalarViewType::non_const_value_type>::value,
1846 "Template parameters OutputScalarViewType and " 1847 "InputScalarViewType must contain values of the same " 1849 static_assert (std::is_same<
1850 typename LocalIndicesViewType::non_const_value_type,
1851 local_ordinal_type>::value,
1852 "Template parameter LocalIndicesViewType must " 1853 "contain values of type local_ordinal_type.");
1855 typedef typename OutputScalarViewType::non_const_value_type ST;
1856 typedef LocalOrdinal LO;
1857 typedef GlobalOrdinal GO;
1859 if (newVals.dimension_0 () != inds.dimension_0 ()) {
1861 return Teuchos::OrdinalTraits<LO>::invalid ();
1863 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
1864 const bool sorted = this->isSorted ();
1869 if (isLocallyIndexed ()) {
1872 auto colInds = this->getLocalKokkosRowView (rowInfo);
1874 for (LO j = 0; j < numElts; ++j) {
1875 const LO lclColInd = inds(j);
1876 const size_t offset =
1877 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
1878 lclColInd, hint, sorted);
1879 if (offset != rowInfo.numEntries) {
1888 volatile ST*
const dest = &rowVals(offset);
1889 (void) atomic_binary_function_update (dest, newVals(j), f);
1893 rowVals(offset) = f (rowVals(offset), newVals(j));
1900 else if (isGloballyIndexed ()) {
1904 if (colMap_.is_null ()) {
1911 const map_type& colMap = *colMap_;
1914 auto colInds = this->getGlobalKokkosRowView (rowInfo);
1916 const GO GINV = Teuchos::OrdinalTraits<GO>::invalid ();
1917 for (LO j = 0; j < numElts; ++j) {
1919 if (gblColInd != GINV) {
1920 const size_t offset =
1921 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
1922 gblColInd, hint, sorted);
1923 if (offset != rowInfo.numEntries) {
1932 volatile ST*
const dest = &rowVals(offset);
1933 (void) atomic_binary_function_update (dest, newVals(j), f);
1937 rowVals(offset) = f (rowVals(offset), newVals(j));
1973 template<
class OutputScalarViewType,
1974 class LocalIndicesViewType,
1975 class InputScalarViewType>
1978 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
1979 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
1980 const typename UnmanagedView<InputScalarViewType>::type& newVals,
1981 const bool atomic = useAtomicUpdatesByDefault)
const 1989 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
1990 "Template parameter OutputScalarViewType must be " 1992 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
1993 "Template parameter LocalIndicesViewType must be " 1995 static_assert (Kokkos::is_view<InputScalarViewType>::value,
1996 "Template parameter InputScalarViewType must be a " 1998 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
1999 "Template parameter OutputScalarViewType must " 2001 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
2002 "Template parameter LocalIndicesViewType must " 2004 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
2005 "Template parameter InputScalarViewType must have " 2007 static_assert (std::is_same<
2008 typename OutputScalarViewType::non_const_value_type,
2009 typename InputScalarViewType::non_const_value_type>::value,
2010 "Template parameters OutputScalarViewType and " 2011 "InputScalarViewType must contain values of the same " 2013 static_assert (std::is_same<
2014 typename LocalIndicesViewType::non_const_value_type,
2015 local_ordinal_type>::value,
2016 "Template parameter LocalIndicesViewType must " 2017 "contain values of type local_ordinal_type.");
2019 typedef LocalOrdinal LO;
2020 typedef GlobalOrdinal GO;
2026 if (colMap_.is_null ()) {
2028 return Teuchos::OrdinalTraits<LO>::invalid ();
2030 else if (newVals.dimension_0 () != inds.dimension_0 ()) {
2032 return Teuchos::OrdinalTraits<LO>::invalid ();
2035 const bool sorted = this->isSorted ();
2044 if (isLocallyIndexed ()) {
2047 auto colInds = this->getLocalKokkosRowView (rowInfo);
2049 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2050 for (LO j = 0; j < numElts; ++j) {
2051 const LO lclColInd = inds(j);
2052 const size_t offset =
2053 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2054 lclColInd, hint, sorted);
2055 if (offset != rowInfo.numEntries) {
2057 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2060 rowVals(offset) += newVals(j);
2067 else if (isGloballyIndexed ()) {
2070 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2072 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2073 for (LO j = 0; j < numElts; ++j) {
2074 const GO gblColInd = this->colMap_->getGlobalElement (inds(j));
2075 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2076 const size_t offset =
2077 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2078 gblColInd, hint, sorted);
2079 if (offset != rowInfo.numEntries) {
2081 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2084 rowVals(offset) += newVals(j);
2128 template<
class OutputScalarViewType,
2129 class LocalIndicesViewType,
2130 class InputScalarViewType>
2133 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
2134 const typename UnmanagedView<LocalIndicesViewType>::type& inds,
2135 const typename UnmanagedView<InputScalarViewType>::type& newVals)
const 2143 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
2144 "Template parameter OutputScalarViewType must be " 2146 static_assert (Kokkos::is_view<LocalIndicesViewType>::value,
2147 "Template parameter LocalIndicesViewType must be " 2149 static_assert (Kokkos::is_view<InputScalarViewType>::value,
2150 "Template parameter InputScalarViewType must be a " 2152 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
2153 "Template parameter OutputScalarViewType must " 2155 static_assert (static_cast<int> (LocalIndicesViewType::rank) == 1,
2156 "Template parameter LocalIndicesViewType must " 2158 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
2159 "Template parameter InputScalarViewType must have " 2161 static_assert (std::is_same<
2162 typename OutputScalarViewType::non_const_value_type,
2163 typename InputScalarViewType::non_const_value_type>::value,
2164 "Template parameters OutputScalarViewType and " 2165 "InputScalarViewType must contain values of the same " 2167 static_assert (std::is_same<
2168 typename LocalIndicesViewType::non_const_value_type,
2169 local_ordinal_type>::value,
2170 "Template parameter LocalIndicesViewType must " 2171 "contain values of type local_ordinal_type.");
2173 typedef LocalOrdinal LO;
2174 typedef GlobalOrdinal GO;
2180 if (colMap_.is_null ()) {
2182 return Teuchos::OrdinalTraits<LO>::invalid ();
2184 else if (newVals.dimension_0 () != inds.dimension_0 ()) {
2186 return Teuchos::OrdinalTraits<LO>::invalid ();
2189 const bool sorted = this->isSorted ();
2198 if (isLocallyIndexed ()) {
2201 auto colInds = this->getLocalKokkosRowView (rowInfo);
2203 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2204 for (LO j = 0; j < numElts; ++j) {
2205 const LO lclColInd = inds(j);
2206 const size_t offset =
2207 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2208 lclColInd, hint, sorted);
2209 if (offset != rowInfo.numEntries) {
2210 rowVals(offset) = newVals(j);
2216 else if (isGloballyIndexed ()) {
2219 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2221 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2222 for (LO j = 0; j < numElts; ++j) {
2223 const GO gblColInd = this->colMap_->getGlobalElement (inds(j));
2224 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2225 const size_t offset =
2226 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2227 gblColInd, hint, sorted);
2228 if (offset != rowInfo.numEntries) {
2229 rowVals(offset) = newVals(j);
2271 template<
class Scalar,
class InputMemorySpace,
class ValsMemorySpace>
2274 const Kokkos::View<Scalar*, ValsMemorySpace,
2275 Kokkos::MemoryUnmanaged>& rowVals,
2276 const Kokkos::View<
const GlobalOrdinal*, InputMemorySpace,
2277 Kokkos::MemoryUnmanaged>& inds,
2278 const Kokkos::View<
const Scalar*, InputMemorySpace,
2279 Kokkos::MemoryUnmanaged>& newVals,
2280 const bool atomic = useAtomicUpdatesByDefault)
const 2282 typedef LocalOrdinal LO;
2283 typedef GlobalOrdinal GO;
2285 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2287 return Teuchos::OrdinalTraits<LO>::invalid ();
2290 const bool sorted = this->isSorted ();
2299 if (isLocallyIndexed ()) {
2303 if (colMap_.is_null ()) {
2311 auto colInds = this->getLocalKokkosRowView (rowInfo);
2312 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2314 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2315 for (LO j = 0; j < numElts; ++j) {
2316 const LO lclColInd = this->colMap_->getLocalElement (inds(j));
2317 if (lclColInd != LINV) {
2318 const size_t offset =
2319 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2320 lclColInd, hint, sorted);
2321 if (offset != rowInfo.numEntries) {
2323 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2326 rowVals(offset) += newVals(j);
2334 else if (isGloballyIndexed ()) {
2337 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2339 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2340 for (LO j = 0; j < numElts; ++j) {
2341 const GO gblColInd = inds(j);
2342 const size_t offset =
2343 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2344 gblColInd, hint, sorted);
2345 if (offset != rowInfo.numEntries) {
2347 Kokkos::atomic_add (&rowVals(offset), newVals(j));
2350 rowVals(offset) += newVals(j);
2388 template<
class OutputScalarViewType,
2389 class GlobalIndicesViewType,
2390 class InputScalarViewType>
2393 const typename UnmanagedView<OutputScalarViewType>::type& rowVals,
2394 const typename UnmanagedView<GlobalIndicesViewType>::type& inds,
2395 const typename UnmanagedView<InputScalarViewType>::type& newVals)
const 2403 static_assert (Kokkos::is_view<OutputScalarViewType>::value,
2404 "Template parameter OutputScalarViewType must be " 2406 static_assert (Kokkos::is_view<GlobalIndicesViewType>::value,
2407 "Template parameter GlobalIndicesViewType must be " 2409 static_assert (Kokkos::is_view<InputScalarViewType>::value,
2410 "Template parameter InputScalarViewType must be a " 2412 static_assert (static_cast<int> (OutputScalarViewType::rank) == 1,
2413 "Template parameter OutputScalarViewType must " 2415 static_assert (static_cast<int> (GlobalIndicesViewType::rank) == 1,
2416 "Template parameter GlobalIndicesViewType must " 2418 static_assert (static_cast<int> (InputScalarViewType::rank) == 1,
2419 "Template parameter InputScalarViewType must have " 2421 static_assert (std::is_same<
2422 typename OutputScalarViewType::non_const_value_type,
2423 typename InputScalarViewType::non_const_value_type>::value,
2424 "Template parameters OutputScalarViewType and " 2425 "InputScalarViewType must contain values of the same " 2427 static_assert (std::is_same<
2428 typename GlobalIndicesViewType::non_const_value_type,
2429 global_ordinal_type>::value,
2430 "Template parameter GlobalIndicesViewType must " 2431 "contain values of type global_ordinal_type.");
2433 typedef LocalOrdinal LO;
2434 typedef GlobalOrdinal GO;
2436 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2438 return Teuchos::OrdinalTraits<LO>::invalid ();
2441 const bool sorted = this->isSorted ();
2450 if (isLocallyIndexed ()) {
2454 if (colMap_.is_null ()) {
2462 auto colInds = this->getLocalKokkosRowView (rowInfo);
2463 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2465 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2466 for (LO j = 0; j < numElts; ++j) {
2467 const LO lclColInd = this->colMap_->getLocalElement (inds(j));
2468 if (lclColInd != LINV) {
2469 const size_t offset =
2470 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2471 lclColInd, hint, sorted);
2472 if (offset != rowInfo.numEntries) {
2473 rowVals(offset) = newVals(j);
2480 else if (isGloballyIndexed ()) {
2483 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2485 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2486 for (LO j = 0; j < numElts; ++j) {
2487 const GO gblColInd = inds(j);
2488 const size_t offset =
2489 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2490 gblColInd, hint, sorted);
2491 if (offset != rowInfo.numEntries) {
2492 rowVals(offset) = newVals(j);
2531 template<
class Scalar,
2532 class BinaryFunction,
2533 class InputMemorySpace,
2534 class ValsMemorySpace>
2537 const Kokkos::View<Scalar*, ValsMemorySpace,
2538 Kokkos::MemoryUnmanaged>& rowVals,
2539 const Kokkos::View<
const GlobalOrdinal*,
2541 Kokkos::MemoryUnmanaged>& inds,
2542 const Kokkos::View<
const Scalar*,
2544 Kokkos::MemoryUnmanaged>& newVals,
2546 const bool atomic = useAtomicUpdatesByDefault)
const 2548 typedef LocalOrdinal LO;
2549 typedef GlobalOrdinal GO;
2551 if (newVals.dimension_0 () != inds.dimension_0 ()) {
2553 return Teuchos::OrdinalTraits<LO>::invalid ();
2556 const LO numElts =
static_cast<LO
> (inds.dimension_0 ());
2557 const bool sorted = this->isSorted ();
2562 if (isLocallyIndexed ()) {
2566 if (colMap_.is_null ()) {
2572 const map_type& colMap = *colMap_;
2575 auto colInds = this->getLocalKokkosRowView (rowInfo);
2577 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2578 for (LO j = 0; j < numElts; ++j) {
2580 if (lclColInd != LINV) {
2581 const size_t offset =
2582 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2583 lclColInd, hint, sorted);
2584 if (offset != rowInfo.numEntries) {
2593 volatile Scalar*
const dest = &rowVals(offset);
2594 (void) atomic_binary_function_update (dest, newVals(j), f);
2598 rowVals(offset) = f (rowVals(offset), newVals(j));
2606 else if (isGloballyIndexed ()) {
2609 auto colInds = this->getGlobalKokkosRowView (rowInfo);
2611 for (LO j = 0; j < numElts; ++j) {
2612 const GO gblColInd = inds(j);
2613 const size_t offset =
2614 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2615 gblColInd, hint, sorted);
2616 if (offset != rowInfo.numEntries) {
2625 volatile Scalar*
const dest = &rowVals(offset);
2626 (void) atomic_binary_function_update (dest, newVals(j), f);
2630 rowVals(offset) = f (rowVals(offset), newVals(j));
2649 bool isMerged ()
const;
2656 void setLocallyModified ();
2664 sortAndMergeAllIndices (
const bool sorted,
const bool merged);
2671 void sortRowIndices (
const RowInfo& rowinfo);
2681 size_t mergeRowIndices (
const RowInfo& rowInfo);
2695 setDomainRangeMaps (
const Teuchos::RCP<const map_type>& domainMap,
2696 const Teuchos::RCP<const map_type>& rangeMap);
2698 void staticAssertions()
const;
2699 void clearGlobalConstants();
2709 void computeGlobalConstants();
2716 void computeLocalConstants();
2720 RowInfo getRowInfo (
const LocalOrdinal myRow)
const;
2734 RowInfo getRowInfoFromGlobalRowIndex (
const GlobalOrdinal gblRow)
const;
2739 Teuchos::ArrayView<const LocalOrdinal>
2740 getLocalView (
const RowInfo rowinfo)
const;
2745 Teuchos::ArrayView<LocalOrdinal>
2746 getLocalViewNonConst (
const RowInfo rowinfo);
2759 getLocalViewRawConst (
const LocalOrdinal*& lclInds,
2760 LocalOrdinal& numEnt,
2761 const RowInfo& rowinfo)
const;
2771 Kokkos::View<const LocalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2772 getLocalKokkosRowView (
const RowInfo& rowInfo)
const;
2780 Kokkos::View<LocalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2781 getLocalKokkosRowViewNonConst (
const RowInfo& rowInfo);
2789 Kokkos::View<const GlobalOrdinal*, execution_space, Kokkos::MemoryUnmanaged>
2790 getGlobalKokkosRowView (
const RowInfo& rowInfo)
const;
2797 Teuchos::ArrayView<const GlobalOrdinal>
2798 getGlobalView (
const RowInfo& rowinfo)
const;
2803 Teuchos::ArrayView<GlobalOrdinal>
2804 getGlobalViewNonConst (
const RowInfo& rowinfo);
2818 getGlobalViewRawConst (
const GlobalOrdinal*& gblInds,
2819 LocalOrdinal& numEnt,
2820 const RowInfo& rowinfo)
const;
2830 local_graph_type getLocalGraph ()
const;
2833 void fillLocalGraph (
const Teuchos::RCP<Teuchos::ParameterList>& params);
2836 bool hasRowInfo ()
const;
2839 void checkInternalState ()
const;
2924 typename Kokkos::View<const size_t*, execution_space>::HostMirror
3034 typename Kokkos::View<size_t*, Kokkos::LayoutLeft, device_type>::HostMirror
3049 bool indicesAreAllocated_;
3050 bool indicesAreLocal_;
3051 bool indicesAreGlobal_;
3095 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic = Node::
classic>
3096 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> >
3098 size_t maxNumEntriesPerRow = 0,
3099 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
3103 return rcp (
new graph_type (map, maxNumEntriesPerRow,
DynamicProfile, params));
3108 template<
class LocalOrdinal,
3109 class GlobalOrdinal,
3110 class OutputNodeType,
3111 class InputNodeType>
3112 class CrsGraphCopier<CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType>,
3113 CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> > {
3118 static Teuchos::RCP<output_crs_graph_type>
3119 clone (
const input_crs_graph_type& graphIn,
3120 const Teuchos::RCP<OutputNodeType> &nodeOut,
3121 const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
3123 using Teuchos::arcp;
3124 using Teuchos::Array;
3125 using Teuchos::ArrayRCP;
3126 using Teuchos::ArrayView;
3127 using Teuchos::null;
3128 using Teuchos::outArg;
3129 using Teuchos::ParameterList;
3130 using Teuchos::parameterList;
3133 using Teuchos::REDUCE_MIN;
3134 using Teuchos::reduceAll;
3135 using Teuchos::sublist;
3138 typedef LocalOrdinal LO;
3139 typedef GlobalOrdinal GO;
3140 typedef typename ArrayView<const GO>::size_type size_type;
3141 typedef ::Tpetra::Map<LO, GO, InputNodeType> input_map_type;
3142 typedef ::Tpetra::Map<LO, GO, OutputNodeType> output_map_type;
3143 const char prefix[] =
"Tpetra::Details::CrsGraphCopier::clone: ";
3147 bool fillCompleteClone =
true;
3148 bool useLocalIndices = graphIn.hasColMap ();
3151 if (! params.is_null ()) {
3152 fillCompleteClone = params->get (
"fillComplete clone", fillCompleteClone);
3153 useLocalIndices = params->get (
"Locally indexed clone", useLocalIndices);
3154 if (params->get (
"Static profile clone",
true) ==
false) {
3157 debug = params->get (
"Debug", debug);
3160 const Teuchos::Comm<int>& comm = * (graphIn.getRowMap ()->getComm ());
3161 const int myRank = comm.getRank ();
3163 TEUCHOS_TEST_FOR_EXCEPTION(
3164 ! graphIn.hasColMap () && useLocalIndices, std::runtime_error,
3165 prefix <<
"You asked clone() to use local indices (by setting the " 3166 "\"Locally indexed clone\" parameter to true), but the source graph " 3167 "does not yet have a column Map, so this is impossible.");
3170 std::ostringstream os;
3171 os <<
"Process " << myRank <<
": Cloning row Map" << endl;
3175 RCP<const output_map_type> clonedRowMap =
3176 graphIn.getRowMap ()->template clone<OutputNodeType> (nodeOut);
3180 RCP<output_crs_graph_type> clonedGraph;
3182 ArrayRCP<const size_t> numEntriesPerRow;
3183 size_t numEntriesForAll = 0;
3184 bool boundSameForAllLocalRows =
true;
3187 std::ostringstream os;
3188 os <<
"Process " << myRank <<
": Getting per-row bounds" << endl;
3191 graphIn.getNumEntriesPerLocalRowUpperBound (numEntriesPerRow,
3193 boundSameForAllLocalRows);
3195 std::ostringstream os;
3196 os <<
"Process " << myRank <<
": numEntriesForAll = " 3197 << numEntriesForAll << endl;
3202 std::ostringstream os;
3203 os <<
"Process " << myRank <<
": graphIn.getNodeMaxNumRowEntries() = " 3204 << graphIn.getNodeMaxNumRowEntries () << endl;
3208 RCP<ParameterList> graphparams;
3209 if (params.is_null ()) {
3210 graphparams = parameterList (
"CrsGraph");
3212 graphparams = sublist (params,
"CrsGraph");
3214 if (useLocalIndices) {
3215 RCP<const output_map_type> clonedColMap =
3216 graphIn.getColMap ()->template clone<OutputNodeType> (nodeOut);
3217 if (boundSameForAllLocalRows) {
3218 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap, clonedColMap,
3219 numEntriesForAll, pftype,
3222 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap, clonedColMap,
3223 numEntriesPerRow, pftype,
3227 if (boundSameForAllLocalRows) {
3228 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap,
3229 numEntriesForAll, pftype,
3232 clonedGraph = rcp (
new output_crs_graph_type (clonedRowMap,
3234 pftype, graphparams));
3239 std::ostringstream os;
3240 os <<
"Process " << myRank <<
": Invoked output graph's constructor" << endl;
3245 numEntriesPerRow = null;
3246 numEntriesForAll = 0;
3249 const input_map_type& inputRowMap = * (graphIn.getRowMap ());
3250 const size_type numRows =
3251 static_cast<size_type
> (inputRowMap.getNodeNumElements ());
3253 bool failed =
false;
3255 if (useLocalIndices) {
3256 const LO localMinLID = inputRowMap.getMinLocalIndex ();
3257 const LO localMaxLID = inputRowMap.getMaxLocalIndex ();
3259 if (graphIn.isLocallyIndexed ()) {
3262 ArrayView<const LO> linds;
3263 for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
3264 graphIn.getLocalRowView (lrow, linds);
3265 if (linds.size () != 0) {
3266 clonedGraph->insertLocalIndices (lrow, linds);
3270 catch (std::exception& e) {
3271 std::ostringstream os;
3272 os <<
"Process " << myRank <<
": copying (reading local by view, " 3273 "writing local) indices into the output graph threw an " 3274 "exception: " << e.what () << endl;
3281 TEUCHOS_TEST_FOR_EXCEPTION(
3282 ! graphIn.hasColMap () && useLocalIndices, std::invalid_argument,
3283 prefix <<
"You asked clone() to use local indices (by setting the " 3284 "\"Locally indexed clone\" parameter to true), but the source graph " 3285 "does not yet have a column Map, so this is impossible.");
3300 size_t myMaxNumRowEntries =
3301 graphIn.isFillActive () ?
static_cast<size_t> (0) :
3302 graphIn.getNodeMaxNumRowEntries ();
3304 Array<LO> linds (myMaxNumRowEntries);
3307 for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
3308 size_t theNumEntries = graphIn.getNumEntriesInLocalRow (lrow);
3309 if (theNumEntries > myMaxNumRowEntries) {
3310 myMaxNumRowEntries = theNumEntries;
3311 linds.resize (myMaxNumRowEntries);
3313 graphIn.getLocalRowCopy (lrow, linds (), theNumEntries);
3314 if (theNumEntries != 0) {
3315 clonedGraph->insertLocalIndices (lrow, linds (0, theNumEntries));
3319 catch (std::exception& e) {
3320 std::ostringstream os;
3321 os <<
"Process " << myRank <<
": copying (reading local by copy, " 3322 "writing local) indices into the output graph threw an exception: " 3323 << e.what () << endl;
3331 const GlobalOrdinal localMinGID = inputRowMap.getMinGlobalIndex ();
3332 const GlobalOrdinal localMaxGID = inputRowMap.getMaxGlobalIndex ();
3333 const bool inputRowMapIsContiguous = inputRowMap.isContiguous ();
3335 if (graphIn.isGloballyIndexed ()) {
3336 ArrayView<const GlobalOrdinal> ginds;
3338 if (inputRowMapIsContiguous) {
3340 for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
3341 graphIn.getGlobalRowView (grow, ginds);
3342 if (ginds.size () != 0) {
3343 clonedGraph->insertGlobalIndices (grow, ginds);
3347 catch (std::exception& e) {
3348 std::ostringstream os;
3349 os <<
"Process " << myRank <<
": copying (reading global by view, " 3350 "writing global) indices into the output graph threw an " 3351 "exception: " << e.what () << endl;
3358 ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
3359 for (size_type k = 0; k < numRows; ++k) {
3360 const GO grow = inputRowMapGIDs[k];
3361 graphIn.getGlobalRowView (grow, ginds);
3362 if (ginds.size () != 0) {
3363 clonedGraph->insertGlobalIndices (grow, ginds);
3367 catch (std::exception& e) {
3368 std::ostringstream os;
3369 os <<
"Process " << myRank <<
": copying (reading global by view, " 3370 "writing global) indices into the output graph threw an " 3371 "exception: " << e.what () << endl;
3384 size_t myMaxNumRowEntries =
3385 graphIn.isFillActive () ?
static_cast<size_t> (0) :
3386 graphIn.getNodeMaxNumRowEntries ();
3388 Array<GO> ginds (myMaxNumRowEntries);
3390 if (inputRowMapIsContiguous) {
3392 for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
3393 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
3394 if (theNumEntries > myMaxNumRowEntries) {
3395 myMaxNumRowEntries = theNumEntries;
3396 ginds.resize (myMaxNumRowEntries);
3398 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
3399 if (theNumEntries != 0) {
3400 clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
3404 catch (std::exception& e) {
3405 std::ostringstream os;
3406 os <<
"Process " << myRank <<
": copying (reading global by copy, " 3407 "writing global) indices into the output graph threw an " 3408 "exception: " << e.what () << endl;
3415 ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
3416 for (size_type k = 0; k < numRows; ++k) {
3417 const GO grow = inputRowMapGIDs[k];
3419 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
3420 if (theNumEntries > myMaxNumRowEntries) {
3421 myMaxNumRowEntries = theNumEntries;
3422 ginds.resize (myMaxNumRowEntries);
3424 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
3425 if (theNumEntries != 0) {
3426 clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
3430 catch (std::exception& e) {
3431 std::ostringstream os;
3432 os <<
"Process " << myRank <<
": copying (reading global by copy, " 3433 "writing global) indices into the output graph threw an " 3434 "exception: " << e.what () << endl;
3444 std::ostringstream os;
3445 os <<
"Process " << myRank <<
": copied entries" << endl;
3449 if (fillCompleteClone) {
3450 RCP<ParameterList> fillparams = params.is_null () ?
3451 parameterList (
"fillComplete") :
3452 sublist (params,
"fillComplete");
3454 RCP<const output_map_type> clonedRangeMap;
3455 RCP<const output_map_type> clonedDomainMap;
3456 if (! graphIn.getRangeMap ().is_null () &&
3457 graphIn.getRangeMap () != graphIn.getRowMap ()) {
3459 graphIn.getRangeMap ()->template clone<OutputNodeType> (nodeOut);
3462 clonedRangeMap = clonedRowMap;
3464 if (! graphIn.getDomainMap ().is_null ()
3465 && graphIn.getDomainMap () != graphIn.getRowMap ()) {
3467 graphIn.getDomainMap ()->template clone<OutputNodeType> (nodeOut);
3470 clonedDomainMap = clonedRowMap;
3474 std::ostringstream os;
3475 os <<
"Process " << myRank <<
": About to call fillComplete on " 3476 "cloned graph" << endl;
3479 clonedGraph->fillComplete (clonedDomainMap, clonedRangeMap, fillparams);
3481 catch (std::exception &e) {
3483 std::ostringstream os;
3484 os << prefix <<
"Process " << myRank <<
": Caught the following " 3485 "exception while calling fillComplete() on clone of type" 3486 << endl << Teuchos::typeName (*clonedGraph) << endl;
3491 int lclSuccess = failed ? 0 : 1;
3493 reduceAll<int, int> (comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
3494 TEUCHOS_TEST_FOR_EXCEPTION(
3495 gblSuccess != 1, std::logic_error, prefix <<
3496 "Clone failed on at least one process.");
3499 std::ostringstream os;
3500 os <<
"Process " << myRank <<
": Done with CrsGraph::clone" << endl;
3510 #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.
size_t nodeMaxNumRowEntries_
Local maximum of the number of entries in each row.
bool haveGlobalConstants_
Whether all processes have computed global constants.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
global_size_t globalMaxNumRowEntries_
Global maximum of the number of entries in each row.
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.
size_t nodeNumDiags_
Local number of (populated) diagonal entries.
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.
int makeColMap(Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &colMap, const Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &domMap, const RowGraph< LO, GO, NT > &graph, const bool sortEachProcsGids=true, std::ostream *errStrm=NULL)
Make the graph's column Map.
local_graph_type::entries_type::non_const_type k_lclInds1D_
Local column indices for all rows.
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.
size_t nodeNumEntries_
Local number of (populated) entries; must always be consistent.
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.
global_size_t globalNumDiags_
Global number of (populated) diagonal entries.
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 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.
bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The Map specialization used by this class.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
global_size_t globalNumEntries_
Global number of entries in the graph.
A parallel distribution of indices 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.