42 #ifndef TPETRA_IMPORT_UTIL2_HPP 43 #define TPETRA_IMPORT_UTIL2_HPP 50 #include "Tpetra_ConfigDefs.hpp" 52 #include "Tpetra_Import.hpp" 53 #include "Tpetra_HashTable.hpp" 54 #include "Tpetra_Map.hpp" 56 #include "Tpetra_Distributor.hpp" 57 #include "Kokkos_DualView.hpp" 58 #include <Teuchos_Array.hpp> 69 template<
class T,
class D>
70 Kokkos::View<T*, D, Kokkos::MemoryUnmanaged>
71 getNonconstView (
const Teuchos::ArrayView<T>& x)
73 typedef Kokkos::View<T*, D, Kokkos::MemoryUnmanaged> view_type;
74 typedef typename view_type::size_type size_type;
75 const size_type numEnt =
static_cast<size_type
> (x.size ());
76 return view_type (x.getRawPtr (), numEnt);
79 template<
class T,
class D>
80 Kokkos::View<const T*, D, Kokkos::MemoryUnmanaged>
81 getConstView (
const Teuchos::ArrayView<const T>& x)
83 typedef Kokkos::View<const T*, D, Kokkos::MemoryUnmanaged> view_type;
84 typedef typename view_type::size_type size_type;
85 const size_type numEnt =
static_cast<size_type
> (x.size ());
86 return view_type (x.getRawPtr (), numEnt);
92 struct GetHostExecSpace {
93 typedef typename Space::execution_space execution_space;
94 typedef typename Kokkos::View<int*, execution_space>::HostMirror::execution_space host_execution_space;
100 namespace Import_Util {
116 template<
typename Scalar,
117 typename LocalOrdinal,
118 typename GlobalOrdinal,
122 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
123 Kokkos::DualView<char*, typename Node::device_type>& exports,
124 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
125 size_t& constantNumPackets,
127 const Teuchos::ArrayView<const int>& SourcePids);
144 template<
typename Scalar,
145 typename LocalOrdinal,
146 typename GlobalOrdinal,
150 const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
151 const Teuchos::ArrayView<const char> &imports,
152 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
153 size_t constantNumPackets,
157 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
158 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs);
174 template<
typename Scalar,
175 typename LocalOrdinal,
176 typename GlobalOrdinal,
180 const Teuchos::ArrayView<const LocalOrdinal>& importLIDs,
181 const Teuchos::ArrayView<const char>& imports,
182 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
183 size_t constantNumPackets,
187 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
188 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs,
189 size_t TargetNumRows,
190 size_t TargetNumNonzeros,
192 const Teuchos::ArrayView<size_t>& rowPointers,
193 const Teuchos::ArrayView<GlobalOrdinal>& columnIndices,
194 const Teuchos::ArrayView<Scalar>& values,
195 const Teuchos::ArrayView<const int>& SourcePids,
196 Teuchos::Array<int>& TargetPids);
200 template<
typename Scalar,
typename Ordinal>
203 const Teuchos::ArrayView<Ordinal>& CRS_colind,
204 const Teuchos::ArrayView<Scalar>&CRS_vals);
207 template<
typename rowptr_array_type,
typename colind_array_type,
typename vals_array_type>
210 const colind_array_type& CRS_colind,
211 const vals_array_type& CRS_vals);
217 template<
typename Scalar,
typename Ordinal>
220 const Teuchos::ArrayView<Ordinal>& CRS_colind,
221 const Teuchos::ArrayView<Scalar>& CRS_vals);
238 template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
241 const Teuchos::ArrayView<LocalOrdinal> &columnIndices_LID,
242 const Teuchos::ArrayView<GlobalOrdinal> &columnIndices_GID,
244 const Teuchos::ArrayView<const int> &owningPids,
245 Teuchos::Array<int> &remotePids,
275 template<
class LO,
class GO,
class D>
277 packRowCount (
const size_t numEnt,
278 const size_t numBytesPerValue)
291 const size_t numEntLen = PackTraits<LO, D>::packValueCount (numEntLO);
292 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
293 const size_t pidsLen = numEnt * PackTraits<int, D>::packValueCount (lid);
294 const size_t valsLen = numEnt * numBytesPerValue;
295 return numEntLen + gidsLen + pidsLen + valsLen;
299 template<
class LO,
class D>
303 const size_t numBytes,
304 const size_t numBytesPerValue)
306 using Kokkos::subview;
308 typedef typename PackTraits<LO, D>::input_buffer_type input_buffer_type;
309 typedef typename input_buffer_type::size_type size_type;
313 return static_cast<size_t> (0);
317 const size_t theNumBytes = PackTraits<LO, D>::packValueCount (numEntLO);
318 #ifdef HAVE_TPETRA_DEBUG 319 TEUCHOS_TEST_FOR_EXCEPTION(
320 theNumBytes > numBytes, std::logic_error,
"unpackRowCount: " 321 "theNumBytes = " << theNumBytes <<
" < numBytes = " << numBytes
323 #endif // HAVE_TPETRA_DEBUG 324 const std::pair<size_type, size_type> rng (offset, offset + theNumBytes);
325 input_buffer_type inBuf = subview (imports, rng);
326 const size_t actualNumBytes = PackTraits<LO, D>::unpackValue (numEntLO, inBuf);
327 (void)actualNumBytes;
328 #ifdef HAVE_TPETRA_DEBUG 329 TEUCHOS_TEST_FOR_EXCEPTION(
330 theNumBytes > numBytes, std::logic_error,
"unpackRowCount: " 331 "actualNumBytes = " << actualNumBytes <<
" < numBytes = " << numBytes
333 #endif // HAVE_TPETRA_DEBUG 334 return static_cast<size_t> (numEntLO);
339 template<
class ST,
class LO,
class GO,
class D>
347 const size_t numBytesPerValue)
349 using Kokkos::subview;
356 typedef typename PackTraits<LO, D>::output_buffer_type output_buffer_type;
357 typedef typename output_buffer_type::size_type size_type;
358 typedef typename std::pair<size_type, size_type> pair_type;
366 const LO numEntLO =
static_cast<size_t> (numEnt);
369 const size_t numEntBeg = offset;
370 const size_t numEntLen = PackTraits<LO, D>::packValueCount (numEntLO);
371 const size_t gidsBeg = numEntBeg + numEntLen;
372 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
373 const size_t pidsBeg = gidsBeg + gidsLen;
374 const size_t pidsLen = numEnt * PackTraits<int, D>::packValueCount (pid);
375 const size_t valsBeg = pidsBeg + pidsLen;
376 const size_t valsLen = numEnt * numBytesPerValue;
378 output_buffer_type numEntOut =
379 subview (exports, pair_type (numEntBeg, numEntBeg + numEntLen));
380 output_buffer_type gidsOut =
381 subview (exports, pair_type (gidsBeg, gidsBeg + gidsLen));
382 output_buffer_type pidsOut =
383 subview (exports, pair_type (pidsBeg, pidsBeg + pidsLen));
384 output_buffer_type valsOut =
385 subview (exports, pair_type (valsBeg, valsBeg + valsLen));
387 size_t numBytesOut = 0;
388 numBytesOut += PackTraits<LO, D>::packValue (numEntOut, numEntLO);
389 numBytesOut += PackTraits<GO, D>::packArray (gidsOut, gidsIn, numEnt);
390 numBytesOut += PackTraits<int, D>::packArray (pidsOut, pidsIn, numEnt);
391 numBytesOut += PackTraits<ST, D>::packArray (valsOut, valsIn, numEnt);
393 const size_t expectedNumBytes = numEntLen + gidsLen + pidsLen + valsLen;
394 TEUCHOS_TEST_FOR_EXCEPTION(
395 numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: " 396 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = " 397 << expectedNumBytes <<
".");
403 template<
class ST,
class LO,
class GO,
class D>
410 const size_t numBytes,
412 const size_t numBytesPerValue)
414 using Kokkos::subview;
421 typedef typename PackTraits<LO, D>::input_buffer_type input_buffer_type;
422 typedef typename input_buffer_type::size_type size_type;
423 typedef typename std::pair<size_type, size_type> pair_type;
429 TEUCHOS_TEST_FOR_EXCEPTION(
430 static_cast<size_t> (imports.dimension_0 ()) <= offset, std::logic_error,
431 "unpackRow: imports.dimension_0() = " << imports.dimension_0 () <<
432 " <= offset = " << offset <<
".");
433 TEUCHOS_TEST_FOR_EXCEPTION(
434 static_cast<size_t> (imports.dimension_0 ()) < offset + numBytes,
435 std::logic_error,
"unpackRow: imports.dimension_0() = " 436 << imports.dimension_0 () <<
" < offset + numBytes = " 437 << (offset + numBytes) <<
".");
443 const size_t numEntBeg = offset;
444 const size_t numEntLen = PackTraits<LO, D>::packValueCount (lid);
445 const size_t gidsBeg = numEntBeg + numEntLen;
446 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
447 const size_t pidsBeg = gidsBeg + gidsLen;
448 const size_t pidsLen = numEnt * PackTraits<int, D>::packValueCount (pid);
449 const size_t valsBeg = pidsBeg + pidsLen;
450 const size_t valsLen = numEnt * numBytesPerValue;
452 input_buffer_type numEntIn = subview (imports, pair_type (numEntBeg, numEntBeg + numEntLen));
453 input_buffer_type gidsIn = subview (imports, pair_type (gidsBeg, gidsBeg + gidsLen));
454 input_buffer_type pidsIn = subview (imports, pair_type (pidsBeg, pidsBeg + pidsLen));
455 input_buffer_type valsIn = subview (imports, pair_type (valsBeg, valsBeg + valsLen));
457 size_t numBytesOut = 0;
459 numBytesOut += PackTraits<LO, D>::unpackValue (numEntOut, numEntIn);
460 TEUCHOS_TEST_FOR_EXCEPTION(
461 static_cast<size_t> (numEntOut) != numEnt, std::logic_error,
462 "unpackRow: Expected number of entries " << numEnt
463 <<
" != actual number of entries " << numEntOut <<
".");
465 numBytesOut += PackTraits<GO, D>::unpackArray (gidsOut, gidsIn, numEnt);
466 numBytesOut += PackTraits<int, D>::unpackArray (pidsOut, pidsIn, numEnt);
467 numBytesOut += PackTraits<ST, D>::unpackArray (valsOut, valsIn, numEnt);
469 TEUCHOS_TEST_FOR_EXCEPTION(
470 numBytesOut != numBytes, std::logic_error,
"unpackRow: numBytesOut = " 471 << numBytesOut <<
" != numBytes = " << numBytes <<
".");
472 const size_t expectedNumBytes = numEntLen + gidsLen + pidsLen + valsLen;
473 TEUCHOS_TEST_FOR_EXCEPTION(
474 numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: " 475 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = " 476 << expectedNumBytes <<
".");
488 template<
class ST,
class DT,
489 const bool outputIsHostMemory =
490 std::is_same<typename DT::memory_space, Kokkos::HostSpace>::value>
491 struct Get1DConstViewOfUnmanagedHostArray {};
493 template<
class ST,
class DT>
494 struct Get1DConstViewOfUnmanagedHostArray<ST, DT, true> {
495 typedef Kokkos::View<const ST*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged> output_view_type;
497 static output_view_type
498 getView (
const char [],
const ST* x_raw,
const size_t x_len)
502 return output_view_type (x_raw, x_len);
506 template<
class ST,
class DT>
507 struct Get1DConstViewOfUnmanagedHostArray<ST, DT, false> {
508 typedef Kokkos::View<const ST*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged> input_view_type;
509 typedef Kokkos::View<const ST*, DT> output_view_type;
511 static output_view_type
512 getView (
const char label[],
const ST* x_raw,
const size_t x_len)
514 input_view_type x_in (x_raw, x_len);
521 Kokkos::View<ST*, DT> x_out (std::string (label), x_len);
527 template<
class ST,
class DT>
528 typename Get1DConstViewOfUnmanagedHostArray<ST, DT>::output_view_type
529 get1DConstViewOfUnmanagedHostArray (
const char label[],
const ST* x_raw,
const size_t x_len)
531 return Get1DConstViewOfUnmanagedHostArray<ST, DT>::getView (label, x_raw, x_len);
538 namespace Import_Util {
540 template<
typename Scalar,
541 typename LocalOrdinal,
542 typename GlobalOrdinal,
546 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
547 Kokkos::DualView<char*, typename Node::device_type>& exports,
548 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
549 size_t& constantNumPackets,
551 const Teuchos::ArrayView<const int>& SourcePids)
554 using Kokkos::MemoryUnmanaged;
555 using Kokkos::subview;
557 using Teuchos::Array;
558 using Teuchos::ArrayView;
561 typedef LocalOrdinal LO;
562 typedef GlobalOrdinal GO;
564 typedef typename matrix_type::impl_scalar_type ST;
565 typedef typename Node::device_type device_type;
566 typedef typename device_type::execution_space execution_space;
572 typedef typename Kokkos::DualView<char*, device_type>::t_host::device_type HDS;
574 typedef typename ArrayView<const LO>::size_type size_type;
575 typedef std::pair<typename View<int*, HDS>::size_type,
576 typename View<int*, HDS>::size_type> pair_type;
577 const char prefix[] =
"Tpetra::Import_Util::packAndPrepareWithOwningPIDs: ";
584 TEUCHOS_TEST_FOR_EXCEPTION(
586 prefix <<
"SourceMatrix must be locally indexed.");
587 TEUCHOS_TEST_FOR_EXCEPTION(
588 SourceMatrix.
getColMap ().is_null (), std::logic_error,
589 prefix <<
"The source matrix claims to be locally indexed, but its column " 590 "Map is null. This should never happen. Please report this bug to the " 591 "Tpetra developers.");
592 const size_type numExportLIDs = exportLIDs.size ();
593 TEUCHOS_TEST_FOR_EXCEPTION(
594 numExportLIDs != numPacketsPerLID.size (), std::invalid_argument, prefix
595 <<
"exportLIDs.size() = " << numExportLIDs <<
"!= numPacketsPerLID.size() " 596 <<
" = " << numPacketsPerLID.size () <<
".");
597 TEUCHOS_TEST_FOR_EXCEPTION(
598 static_cast<size_t> (SourcePids.size ()) != SourceMatrix.
getColMap ()->getNodeNumElements (),
599 std::invalid_argument, prefix <<
"SourcePids.size() = " 600 << SourcePids.size ()
601 <<
"!= SourceMatrix.getColMap()->getNodeNumElements() = " 602 << SourceMatrix.
getColMap ()->getNodeNumElements () <<
".");
607 constantNumPackets = 0;
612 size_t totalNumBytes = 0;
613 size_t totalNumEntries = 0;
614 size_t maxRowLength = 0;
615 for (size_type i = 0; i < numExportLIDs; ++i) {
616 const LO lclRow = exportLIDs[i];
621 size_t numBytesPerValue = 0;
627 ArrayView<const Scalar> valsView;
628 ArrayView<const LO> lidsView;
630 const ST* valsViewRaw =
reinterpret_cast<const ST*
> (valsView.getRawPtr ());
631 View<const ST*, Kokkos::HostSpace, MemoryUnmanaged> valsViewK (valsViewRaw, valsView.size ());
632 TEUCHOS_TEST_FOR_EXCEPTION(
633 static_cast<size_t> (valsViewK.dimension_0 ()) != numEnt,
634 std::logic_error, prefix <<
"Local row " << i <<
" claims to have " 635 << numEnt <<
"entry/ies, but the View returned by getLocalRowView() " 636 "has " << valsViewK.dimension_0 () <<
" entry/ies. This should never " 637 "happen. Please report this bug to the Tpetra developers.");
646 numBytesPerValue = PackTraits<ST, Kokkos::HostSpace>::packValueCount (valsViewK(0));
652 const size_t numBytes =
653 packRowCount<LO, GO, Kokkos::HostSpace> (numEnt, numBytesPerValue);
654 numPacketsPerLID[i] = numBytes;
655 totalNumBytes += numBytes;
656 totalNumEntries += numEnt;
657 maxRowLength = std::max (maxRowLength, numEnt);
663 if (totalNumEntries > 0) {
664 if (static_cast<size_t> (exports.dimension_0 ()) !=
665 static_cast<size_t> (totalNumBytes)) {
669 execution_space::fence ();
670 exports = Kokkos::DualView<char*, device_type> (
"exports", totalNumBytes);
671 execution_space::fence ();
676 exports.template modify<Kokkos::HostSpace> ();
690 auto exports_h = exports.template view<Kokkos::HostSpace> ();
699 const map_type& colMap = * (SourceMatrix.
getColMap ());
702 typename View<GO*, device_type>::HostMirror gids;
703 typename View<int*, device_type>::HostMirror pids;
707 gids = PackTraits<GO, HDS>::allocateArray (gid, maxRowLength,
"gids");
708 pids = PackTraits<int, HDS>::allocateArray (pid, maxRowLength,
"pids");
711 for (size_type i = 0; i < numExportLIDs; i++) {
712 const LO lclRow = exportLIDs[i];
715 ArrayView<const Scalar> valsView;
716 ArrayView<const LO> lidsView;
718 const ST* valsViewRaw =
reinterpret_cast<const ST*
> (valsView.getRawPtr ());
725 auto valsViewK = get1DConstViewOfUnmanagedHostArray<ST, HDS> (
"valsViewK", valsViewRaw,
static_cast<size_t> (valsView.size ()));
726 const size_t numEnt =
static_cast<size_t> (valsViewK.dimension_0 ());
735 const size_t numBytesPerValue = numEnt == 0 ?
736 static_cast<size_t> (0) :
737 PackTraits<ST, Kokkos::HostSpace>::packValueCount (valsViewK(0));
740 auto gidsView = subview (gids, pair_type (0, numEnt));
741 auto pidsView = subview (pids, pair_type (0, numEnt));
742 for (
size_t k = 0; k < numEnt; ++k) {
743 gidsView(k) = colMap.getGlobalElement (lidsView[k]);
744 pidsView(k) = SourcePids[lidsView[k]];
748 const size_t numBytes =
749 packRow<ST, LO, GO, HDS> (exports_h, offset, numEnt,
750 gidsView, pidsView, valsViewK,
756 #ifdef HAVE_TPETRA_DEBUG 757 TEUCHOS_TEST_FOR_EXCEPTION(
758 offset != totalNumBytes, std::logic_error, prefix <<
"At end of method, " 759 "the final offset (in bytes) " << offset <<
" does not equal the total " 760 "number of bytes packed " << totalNumBytes <<
". Please report this bug " 761 "to the Tpetra developers.");
762 #endif // HAVE_TPETRA_DEBUG 766 template<
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
769 const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
770 const Teuchos::ArrayView<const char> &imports,
771 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
772 size_t constantNumPackets,
776 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
777 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs)
779 using Kokkos::MemoryUnmanaged;
781 typedef LocalOrdinal LO;
782 typedef GlobalOrdinal GO;
784 typedef typename matrix_type::impl_scalar_type ST;
785 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
786 typedef typename Node::execution_space execution_space;
787 typedef typename GetHostExecSpace<execution_space>::host_execution_space HES;
788 const char prefix[] =
"unpackAndCombineWithOwningPIDsCount: ";
790 TEUCHOS_TEST_FOR_EXCEPTION(
791 permuteToLIDs.size () != permuteFromLIDs.size (), std::invalid_argument,
792 prefix <<
"permuteToLIDs.size() = " << permuteToLIDs.size () <<
" != " 793 "permuteFromLIDs.size() = " << permuteFromLIDs.size() <<
".");
797 TEUCHOS_TEST_FOR_EXCEPTION(
798 ! locallyIndexed, std::invalid_argument, prefix <<
"The input CrsMatrix " 799 "'SourceMatrix' must be locally indexed.");
800 TEUCHOS_TEST_FOR_EXCEPTION(
801 importLIDs.size () != numPacketsPerLID.size (), std::invalid_argument,
802 prefix <<
"importLIDs.size() = " << importLIDs.size () <<
" != " 803 "numPacketsPerLID.size() = " << numPacketsPerLID.size () <<
".");
805 View<const char*, HES, MemoryUnmanaged> importsK (imports.getRawPtr (),
812 for (
size_t sourceLID = 0; sourceLID < numSameIDs; ++sourceLID) {
813 const LO srcLID =
static_cast<LO
> (sourceLID);
818 const size_type numPermuteToLIDs = permuteToLIDs.size ();
819 for (size_type p = 0; p < numPermuteToLIDs; ++p) {
825 const size_type numImportLIDs = importLIDs.size ();
826 for (size_type i = 0; i < numImportLIDs; ++i) {
827 const size_t numBytes = numPacketsPerLID[i];
831 const size_t numEnt = unpackRowCount<LO, HES> (importsK, offset,
832 numBytes,
sizeof (ST));
839 template<
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
842 const Teuchos::ArrayView<const LocalOrdinal>& importLIDs,
843 const Teuchos::ArrayView<const char>& imports,
844 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
845 const size_t constantNumPackets,
848 const size_t numSameIDs,
849 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
850 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs,
851 size_t TargetNumRows,
852 size_t TargetNumNonzeros,
853 const int MyTargetPID,
854 const Teuchos::ArrayView<size_t>& CSR_rowptr,
855 const Teuchos::ArrayView<GlobalOrdinal>& CSR_colind,
856 const Teuchos::ArrayView<Scalar>& CSR_vals,
857 const Teuchos::ArrayView<const int>& SourcePids,
858 Teuchos::Array<int>& TargetPids)
861 using Kokkos::MemoryUnmanaged;
862 using Kokkos::subview;
864 using Teuchos::ArrayRCP;
865 using Teuchos::ArrayView;
867 using Teuchos::av_reinterpret_cast;
868 using Teuchos::outArg;
869 using Teuchos::REDUCE_MAX;
870 using Teuchos::reduceAll;
871 typedef LocalOrdinal LO;
872 typedef GlobalOrdinal GO;
873 typedef typename Node::execution_space execution_space;
874 typedef typename GetHostExecSpace<execution_space>::host_execution_space HES;
876 typedef typename matrix_type::impl_scalar_type ST;
878 typedef typename ArrayView<const LO>::size_type size_type;
881 const char prefix[] =
"Tpetra::Import_Util::unpackAndCombineIntoCrsArrays: ";
883 const size_t N = TargetNumRows;
884 const size_t mynnz = TargetNumNonzeros;
887 const int MyPID = MyTargetPID;
889 TEUCHOS_TEST_FOR_EXCEPTION(
890 TargetNumRows + 1 != static_cast<size_t> (CSR_rowptr.size ()),
891 std::invalid_argument, prefix <<
"CSR_rowptr.size() = " <<
892 CSR_rowptr.size () <<
"!= TargetNumRows+1 = " << TargetNumRows+1 <<
".");
893 TEUCHOS_TEST_FOR_EXCEPTION(
894 permuteToLIDs.size () != permuteFromLIDs.size (), std::invalid_argument,
895 prefix <<
"permuteToLIDs.size() = " << permuteToLIDs.size ()
896 <<
"!= permuteFromLIDs.size() = " << permuteFromLIDs.size () <<
".");
897 const size_type numImportLIDs = importLIDs.size ();
898 TEUCHOS_TEST_FOR_EXCEPTION(
899 numImportLIDs != numPacketsPerLID.size (), std::invalid_argument,
900 prefix <<
"importLIDs.size() = " << numImportLIDs <<
" != " 901 "numPacketsPerLID.size() = " << numPacketsPerLID.size() <<
".");
904 View<const char*, HES, MemoryUnmanaged> importsK (imports.getRawPtr (),
907 for (
size_t i = 0; i< N+1; ++i) {
912 for (
size_t i = 0; i < numSameIDs; ++i) {
917 size_t numPermuteIDs = permuteToLIDs.size ();
918 for (
size_t i = 0; i < numPermuteIDs; ++i) {
919 CSR_rowptr[permuteToLIDs[i]] =
926 for (size_type k = 0; k < numImportLIDs; ++k) {
927 const size_t numBytes = numPacketsPerLID[k];
931 const size_t numEnt = unpackRowCount<LO, HES> (importsK, offset,
932 numBytes,
sizeof (ST));
933 CSR_rowptr[importLIDs[k]] += numEnt;
940 Teuchos::Array<size_t> NewStartRow (N + 1);
943 size_t last_len = CSR_rowptr[0];
945 for (
size_t i = 1; i < N+1; ++i) {
946 size_t new_len = CSR_rowptr[i];
947 CSR_rowptr[i] = last_len + CSR_rowptr[i-1];
948 NewStartRow[i] = CSR_rowptr[i];
952 TEUCHOS_TEST_FOR_EXCEPTION(
953 CSR_rowptr[N] != mynnz, std::invalid_argument, prefix <<
"CSR_rowptr[last]" 954 " = " << CSR_rowptr[N] <<
"!= mynnz = " << mynnz <<
".");
957 if (static_cast<size_t> (TargetPids.size ()) != mynnz) {
958 TargetPids.resize (mynnz);
960 TargetPids.assign (mynnz, -1);
963 ArrayRCP<const size_t> Source_rowptr_RCP;
964 ArrayRCP<const LO> Source_colind_RCP;
965 ArrayRCP<const Scalar> Source_vals_RCP;
966 SourceMatrix.getAllValues (Source_rowptr_RCP, Source_colind_RCP, Source_vals_RCP);
967 ArrayView<const size_t> Source_rowptr = Source_rowptr_RCP ();
968 ArrayView<const LO> Source_colind = Source_colind_RCP ();
969 ArrayView<const Scalar> Source_vals = Source_vals_RCP ();
971 const map_type& sourceColMap = * (SourceMatrix.
getColMap());
972 ArrayView<const GO> globalColElts = sourceColMap.getNodeElementList();
975 for (
size_t i = 0; i < numSameIDs; ++i) {
976 size_t FromRow = Source_rowptr[i];
977 size_t ToRow = CSR_rowptr[i];
978 NewStartRow[i] += Source_rowptr[i+1] - Source_rowptr[i];
980 for (
size_t j = Source_rowptr[i]; j < Source_rowptr[i+1]; ++j) {
981 CSR_vals[ToRow + j - FromRow] = Source_vals[j];
982 CSR_colind[ToRow + j - FromRow] = globalColElts[Source_colind[j]];
983 TargetPids[ToRow + j - FromRow] =
984 (SourcePids[Source_colind[j]] != MyPID) ?
985 SourcePids[Source_colind[j]] : -1;
989 size_t numBytesPerValue = 0;
990 if (PackTraits<ST, HES>::compileTimeSize) {
992 numBytesPerValue = PackTraits<ST, HES>::packValueCount (val);
1007 if (Source_rowptr.size () == 0 || Source_rowptr[Source_rowptr.size () - 1] == 0) {
1008 numBytesPerValue = PackTraits<ST, HES>::packValueCount (CSR_vals[0]);
1011 numBytesPerValue = PackTraits<ST, HES>::packValueCount (Source_vals[0]);
1013 size_t lclNumBytesPerValue = numBytesPerValue;
1014 Teuchos::RCP<const Teuchos::Comm<int> > comm = SourceMatrix.
getComm ();
1015 reduceAll<int, size_t> (*comm, REDUCE_MAX, lclNumBytesPerValue,
1016 outArg (numBytesPerValue));
1020 for (
size_t i = 0; i < numPermuteIDs; ++i) {
1021 LO FromLID = permuteFromLIDs[i];
1022 size_t FromRow = Source_rowptr[FromLID];
1023 size_t ToRow = CSR_rowptr[permuteToLIDs[i]];
1025 NewStartRow[permuteToLIDs[i]] += Source_rowptr[FromLID+1]-Source_rowptr[FromLID];
1027 for (
size_t j = Source_rowptr[FromLID]; j < Source_rowptr[FromLID+1]; ++j) {
1028 CSR_vals[ToRow + j - FromRow] = Source_vals[j];
1029 CSR_colind[ToRow + j - FromRow] = globalColElts[Source_colind[j]];
1030 TargetPids[ToRow + j - FromRow] =
1031 (SourcePids[Source_colind[j]] != MyPID) ?
1032 SourcePids[Source_colind[j]] : -1;
1037 if (imports.size () > 0) {
1039 #ifdef HAVE_TPETRA_DEBUG 1043 for (
size_t i = 0; i < static_cast<size_t> (numImportLIDs); ++i) {
1044 const size_t numBytes = numPacketsPerLID[i];
1045 if (numBytes == 0) {
1052 const size_t numEnt = unpackRowCount<LO, HES> (importsK, offset, numBytes,
1054 const LO lclRow = importLIDs[i];
1055 const size_t StartRow = NewStartRow[lclRow];
1056 NewStartRow[lclRow] += numEnt;
1058 View<GO*, HES, MemoryUnmanaged> gidsOut =
1059 getNonconstView<GO, HES> (CSR_colind (StartRow, numEnt));
1060 View<int*, HES, MemoryUnmanaged> pidsOut =
1061 getNonconstView<int, HES> (TargetPids (StartRow, numEnt));
1062 ArrayView<Scalar> valsOutS = CSR_vals (StartRow, numEnt);
1063 View<ST*, HES, MemoryUnmanaged> valsOut =
1064 getNonconstView<ST, HES> (av_reinterpret_cast<ST> (valsOutS));
1066 const size_t numBytesOut =
1067 unpackRow<ST, LO, GO, HES> (gidsOut, pidsOut, valsOut, importsK,
1068 offset, numBytes, numEnt, numBytesPerValue);
1069 if (numBytesOut != numBytes) {
1070 #ifdef HAVE_TPETRA_DEBUG 1077 for (
size_t j = 0; j < numEnt; ++j) {
1078 const int pid = pidsOut[j];
1079 pidsOut[j] = (pid != MyPID) ? pid : -1;
1083 #ifdef HAVE_TPETRA_DEBUG 1084 TEUCHOS_TEST_FOR_EXCEPTION(
1085 offset != static_cast<size_t> (imports.size ()), std::logic_error, prefix
1086 <<
"After unpacking and counting all the import packets, the final offset" 1087 " in bytes " << offset <<
" != imports.size() = " << imports.size () <<
1088 ". Please report this bug to the Tpetra developers.");
1089 TEUCHOS_TEST_FOR_EXCEPTION(
1090 lclErr != 0, std::logic_error, prefix <<
"numBytes != numBytesOut " 1091 "somewhere in unpack loop. This should never happen. " 1092 "Please report this bug to the Tpetra developers.");
1093 #endif // HAVE_TPETRA_DEBUG 1098 template<
typename Scalar,
typename Ordinal>
1101 const Teuchos::ArrayView<Ordinal> & CRS_colind,
1102 const Teuchos::ArrayView<Scalar> &CRS_vals)
1107 size_t NumRows = CRS_rowptr.size()-1;
1108 size_t nnz = CRS_colind.size();
1110 for(
size_t i = 0; i < NumRows; i++){
1111 size_t start=CRS_rowptr[i];
1112 if(start >= nnz)
continue;
1114 Scalar* locValues = &CRS_vals[start];
1115 size_t NumEntries = CRS_rowptr[i+1] - start;
1116 Ordinal* locIndices = &CRS_colind[start];
1118 Ordinal n = NumEntries;
1120 while (m<n) m = m*3+1;
1124 Ordinal max = n - m;
1125 for(Ordinal j = 0; j < max; j++) {
1126 for(Ordinal k = j; k >= 0; k-=m) {
1127 if(locIndices[k+m] >= locIndices[k])
1129 Scalar dtemp = locValues[k+m];
1130 locValues[k+m] = locValues[k];
1131 locValues[k] = dtemp;
1132 Ordinal itemp = locIndices[k+m];
1133 locIndices[k+m] = locIndices[k];
1134 locIndices[k] = itemp;
1143 template<
typename rowptr_array_type,
typename colind_array_type,
typename vals_array_type>
1146 const colind_array_type& CRS_colind,
1147 const vals_array_type& CRS_vals) {
1153 size_t NumRows = CRS_rowptr.dimension_0()-1;
1154 size_t nnz = CRS_colind.dimension_0();
1155 typedef typename colind_array_type::traits::non_const_value_type Ordinal;
1156 typedef typename vals_array_type::traits::non_const_value_type Scalar;
1158 typedef size_t index_type;
1159 typedef typename vals_array_type::execution_space execution_space;
1162 typedef Kokkos::RangePolicy<execution_space, index_type> range_type;
1164 Kokkos::parallel_for (range_type (0, NumRows), KOKKOS_LAMBDA (
const size_t i) {
1165 size_t start=CRS_rowptr(i);
1167 size_t NumEntries = CRS_rowptr(i+1) - start;
1169 Ordinal n = (Ordinal) NumEntries;
1171 while (m<n) m = m*3+1;
1175 Ordinal max = n - m;
1176 for(Ordinal j = 0; j < max; j++) {
1177 for(Ordinal k = j; k >= 0; k-=m) {
1178 size_t sk = start+k;
1179 if(CRS_colind(sk+m) >= CRS_colind(sk))
1181 Scalar dtemp = CRS_vals(sk+m);
1182 CRS_vals(sk+m) = CRS_vals(sk);
1183 CRS_vals(sk) = dtemp;
1184 Ordinal itemp = CRS_colind(sk+m);
1185 CRS_colind(sk+m) = CRS_colind(sk);
1186 CRS_colind(sk) = itemp;
1200 template<
typename Scalar,
typename Ordinal>
1203 const Teuchos::ArrayView<Ordinal> & CRS_colind,
1204 const Teuchos::ArrayView<Scalar> &CRS_vals)
1211 size_t NumRows = CRS_rowptr.size()-1;
1212 size_t nnz = CRS_colind.size();
1213 size_t new_curr=CRS_rowptr[0], old_curr=CRS_rowptr[0];
1215 for(
size_t i = 0; i < NumRows; i++){
1216 size_t old_rowptr_i=CRS_rowptr[i];
1217 CRS_rowptr[i] = old_curr;
1218 if(old_rowptr_i >= nnz)
continue;
1220 Scalar* locValues = &CRS_vals[old_rowptr_i];
1221 size_t NumEntries = CRS_rowptr[i+1] - old_rowptr_i;
1222 Ordinal* locIndices = &CRS_colind[old_rowptr_i];
1225 Ordinal n = NumEntries;
1229 Ordinal max = n - m;
1230 for(Ordinal j = 0; j < max; j++) {
1231 for(Ordinal k = j; k >= 0; k-=m) {
1232 if(locIndices[k+m] >= locIndices[k])
1234 Scalar dtemp = locValues[k+m];
1235 locValues[k+m] = locValues[k];
1236 locValues[k] = dtemp;
1237 Ordinal itemp = locIndices[k+m];
1238 locIndices[k+m] = locIndices[k];
1239 locIndices[k] = itemp;
1246 for(
size_t j=old_rowptr_i; j < CRS_rowptr[i+1]; j++) {
1247 if(j > old_rowptr_i && CRS_colind[j]==CRS_colind[new_curr-1]) {
1248 CRS_vals[new_curr-1] += CRS_vals[j];
1250 else if(new_curr==j) {
1254 CRS_colind[new_curr] = CRS_colind[j];
1255 CRS_vals[new_curr] = CRS_vals[j];
1262 CRS_rowptr[NumRows] = new_curr;
1265 template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
1268 const Teuchos::ArrayView<LocalOrdinal> &colind_LID,
1269 const Teuchos::ArrayView<GlobalOrdinal> &colind_GID,
1271 const Teuchos::ArrayView<const int> &owningPIDs,
1272 Teuchos::Array<int> &remotePIDs,
1276 typedef LocalOrdinal LO;
1277 typedef GlobalOrdinal GO;
1280 const char prefix[] =
"lowCommunicationMakeColMapAndReindex: ";
1284 const map_type& domainMap = *domainMapRCP;
1290 Teuchos::Array<bool> LocalGIDs;
1291 if (numDomainElements > 0) {
1292 LocalGIDs.resize (numDomainElements,
false);
1303 const size_t numMyRows = rowptr.size () - 1;
1304 const int hashsize = std::max (static_cast<int> (numMyRows), 100);
1307 Teuchos::Array<GO> RemoteGIDList;
1308 RemoteGIDList.reserve (hashsize);
1309 Teuchos::Array<int> PIDList;
1310 PIDList.reserve (hashsize);
1321 size_t NumLocalColGIDs = 0;
1322 LO NumRemoteColGIDs = 0;
1323 for (
size_t i = 0; i < numMyRows; ++i) {
1324 for(
size_t j = rowptr[i]; j < rowptr[i+1]; ++j) {
1325 const GO GID = colind_GID[j];
1327 const LO LID = domainMap.getLocalElement (GID);
1329 const bool alreadyFound = LocalGIDs[LID];
1330 if (! alreadyFound) {
1331 LocalGIDs[LID] =
true;
1334 colind_LID[j] = LID;
1337 const LO hash_value = RemoteGIDs.
get (GID);
1338 if (hash_value == -1) {
1339 const int PID = owningPIDs[j];
1340 TEUCHOS_TEST_FOR_EXCEPTION(
1341 PID == -1, std::invalid_argument, prefix <<
"Cannot figure out if " 1343 colind_LID[j] =
static_cast<LO
> (numDomainElements + NumRemoteColGIDs);
1344 RemoteGIDs.
add (GID, NumRemoteColGIDs);
1345 RemoteGIDList.push_back (GID);
1346 PIDList.push_back (PID);
1350 colind_LID[j] =
static_cast<LO
> (numDomainElements + hash_value);
1358 if (domainMap.getComm ()->getSize () == 1) {
1361 TEUCHOS_TEST_FOR_EXCEPTION(
1362 NumRemoteColGIDs != 0, std::runtime_error, prefix <<
"There is only one " 1363 "process in the domain Map's communicator, which means that there are no " 1364 "\"remote\" indices. Nevertheless, some column indices are not in the " 1366 if (static_cast<size_t> (NumLocalColGIDs) == numDomainElements) {
1370 colMap = domainMapRCP;
1377 const LO numMyCols = NumLocalColGIDs + NumRemoteColGIDs;
1378 Teuchos::Array<GO> ColIndices;
1379 GO* RemoteColIndices = NULL;
1380 if (numMyCols > 0) {
1381 ColIndices.resize (numMyCols);
1382 if (NumLocalColGIDs != static_cast<size_t> (numMyCols)) {
1383 RemoteColIndices = &ColIndices[NumLocalColGIDs];
1387 for (LO i = 0; i < NumRemoteColGIDs; ++i) {
1388 RemoteColIndices[i] = RemoteGIDList[i];
1392 Teuchos::Array<LO> RemotePermuteIDs (NumRemoteColGIDs);
1393 for (LO i = 0; i < NumRemoteColGIDs; ++i) {
1394 RemotePermuteIDs[i]=i;
1401 ColIndices.begin () + NumLocalColGIDs,
1402 RemotePermuteIDs.begin ());
1408 remotePIDs = PIDList;
1417 LO StartCurrent = 0, StartNext = 1;
1418 while (StartNext < NumRemoteColGIDs) {
1419 if (PIDList[StartNext]==PIDList[StartNext-1]) {
1423 Tpetra::sort2 (ColIndices.begin () + NumLocalColGIDs + StartCurrent,
1424 ColIndices.begin () + NumLocalColGIDs + StartNext,
1425 RemotePermuteIDs.begin () + StartCurrent);
1426 StartCurrent = StartNext;
1430 Tpetra::sort2 (ColIndices.begin () + NumLocalColGIDs + StartCurrent,
1431 ColIndices.begin () + NumLocalColGIDs + StartNext,
1432 RemotePermuteIDs.begin () + StartCurrent);
1435 Teuchos::Array<LO> ReverseRemotePermuteIDs (NumRemoteColGIDs);
1436 for (LO i = 0; i < NumRemoteColGIDs; ++i) {
1437 ReverseRemotePermuteIDs[RemotePermuteIDs[i]] = i;
1441 bool use_local_permute =
false;
1442 Teuchos::Array<LO> LocalPermuteIDs (numDomainElements);
1454 Teuchos::ArrayView<const GO> domainGlobalElements = domainMap.getNodeElementList();
1455 if (static_cast<size_t> (NumLocalColGIDs) == numDomainElements) {
1456 if (NumLocalColGIDs > 0) {
1458 std::copy (domainGlobalElements.begin (), domainGlobalElements.end (),
1459 ColIndices.begin ());
1463 LO NumLocalAgain = 0;
1464 use_local_permute =
true;
1465 for (
size_t i = 0; i < numDomainElements; ++i) {
1467 LocalPermuteIDs[i] = NumLocalAgain;
1468 ColIndices[NumLocalAgain++] = domainGlobalElements[i];
1471 TEUCHOS_TEST_FOR_EXCEPTION(
1472 static_cast<size_t> (NumLocalAgain) != NumLocalColGIDs,
1473 std::runtime_error, prefix <<
"Local ID count test failed.");
1477 const GST minus_one = Teuchos::OrdinalTraits<GST>::invalid ();
1478 colMap = rcp (
new map_type (minus_one, ColIndices, domainMap.getIndexBase (),
1479 domainMap.getComm (), domainMap.getNode ()));
1482 for (
size_t i = 0; i < numMyRows; ++i) {
1483 for (
size_t j = rowptr[i]; j < rowptr[i+1]; ++j) {
1484 const LO ID = colind_LID[j];
1485 if (static_cast<size_t> (ID) < numDomainElements) {
1486 if (use_local_permute) {
1487 colind_LID[j] = LocalPermuteIDs[colind_LID[j]];
1494 colind_LID[j] = NumLocalColGIDs + ReverseRemotePermuteIDs[colind_LID[j]-numDomainElements];
1506 #include "Tpetra_CrsMatrix.hpp" 1508 #endif // TPETRA_IMPORT_UTIL_HPP void sortAndMergeCrsEntries(const Teuchos::ArrayView< size_t > &CRS_rowptr, const Teuchos::ArrayView< Ordinal > &CRS_colind, const Teuchos::ArrayView< Scalar > &CRS_vals)
Sort and merge the entries of the (raw CSR) matrix by column index within each row.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
void unpackAndCombineIntoCrsArrays(const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &SourceMatrix, const Teuchos::ArrayView< const LocalOrdinal > &importLIDs, const Teuchos::ArrayView< const char > &imports, const Teuchos::ArrayView< const size_t > &numPacketsPerLID, size_t constantNumPackets, Distributor &distor, CombineMode combineMode, size_t numSameIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteToLIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteFromLIDs, size_t TargetNumRows, size_t TargetNumNonzeros, int MyTargetPID, const Teuchos::ArrayView< size_t > &rowPointers, const Teuchos::ArrayView< GlobalOrdinal > &columnIndices, const Teuchos::ArrayView< Scalar > &values, const Teuchos::ArrayView< const int > &SourcePids, Teuchos::Array< int > &TargetPids)
unpackAndCombineIntoCrsArrays
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
Sort the first array, and apply the same permutation to the second and third arrays.
Traits class for packing / unpacking data of type T, using Kokkos data structures that live in the gi...
Declaration of the Tpetra::CrsMatrix class.
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
size_t unpackAndCombineWithOwningPIDsCount(const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &SourceMatrix, const Teuchos::ArrayView< const LocalOrdinal > &importLIDs, const Teuchos::ArrayView< const char > &imports, const Teuchos::ArrayView< const size_t > &numPacketsPerLID, size_t constantNumPackets, Distributor &distor, CombineMode combineMode, size_t numSameIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteToLIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteFromLIDs)
Special version of Tpetra::CrsMatrix::unpackAndCombine that also unpacks owning process ranks...
Kokkos::View< char *, D, Kokkos::MemoryUnmanaged > output_buffer_type
The type of an output buffer of bytes.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
void sortCrsEntries(const Teuchos::ArrayView< size_t > &CRS_rowptr, const Teuchos::ArrayView< Ordinal > &CRS_colind, const Teuchos::ArrayView< Scalar > &CRS_vals)
Sort the entries of the (raw CSR) matrix by column index within each row.
void lowCommunicationMakeColMapAndReindex(const Teuchos::ArrayView< const size_t > &rowPointers, const Teuchos::ArrayView< LocalOrdinal > &columnIndices_LID, const Teuchos::ArrayView< GlobalOrdinal > &columnIndices_GID, const Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &domainMap, const Teuchos::ArrayView< const int > &owningPids, Teuchos::Array< int > &remotePids, Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &colMap)
lowCommunicationMakeColMapAndReindex
size_t global_size_t
Global size_t object.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Kokkos::View< const value_type *, D, Kokkos::MemoryUnmanaged > input_array_type
The type of an input array of value_type.
void packAndPrepareWithOwningPIDs(const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &SourceMatrix, const Teuchos::ArrayView< const LocalOrdinal > &exportLIDs, Kokkos::DualView< char *, typename Node::device_type > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, Distributor &distor, const Teuchos::ArrayView< const int > &SourcePids)
Special version of Tpetra::CrsMatrix::packAndPrepare that also packs owning process ranks...
void getLocalRowView(LocalOrdinal LocalRow, Teuchos::ArrayView< const LocalOrdinal > &indices, Teuchos::ArrayView< const Scalar > &values) const
Get a constant, nonpersisting view of a row of this matrix, using local row and column indices...
Kokkos::View< const char *, D, Kokkos::MemoryUnmanaged > input_buffer_type
The type of an input buffer of bytes.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
ValueType get(const KeyType key)
Get the value corresponding to the given key.
A parallel distribution of indices over processes.
void add(const KeyType key, const ValueType value)
Add a key and its value to the hash table.
Kokkos::View< value_type *, D, Kokkos::MemoryUnmanaged > output_array_type
The type of an output array of value_type.
Stand-alone utility functions and macros.
Teuchos::RCP< const map_type > getColMap() const
The Map that describes the column distribution in this matrix.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
bool isLocallyIndexed() const
Whether the matrix is locally indexed on the calling process.