42 #ifndef TPETRA_CRSMATRIX_DEF_HPP 43 #define TPETRA_CRSMATRIX_DEF_HPP 53 #include "Tpetra_RowMatrix.hpp" 57 #include "Teuchos_SerialDenseMatrix.hpp" 58 #include "Teuchos_as.hpp" 59 #include "Teuchos_ArrayRCP.hpp" 83 template<
class Scalar>
87 typedef Teuchos::ScalarTraits<Scalar> STS;
88 return std::max (STS::magnitude (x), STS::magnitude (y));
103 template <
class Ordinal,
class Scalar>
113 v (
Teuchos::ScalarTraits<Scalar>::zero ())
121 CrsIJV (Ordinal row, Ordinal col,
const Scalar &val) :
122 i (row), j (col), v (val)
130 bool operator< (const CrsIJV<Ordinal, Scalar>& rhs)
const {
138 return this->i < rhs.i;
161 template <
typename Ordinal,
typename Scalar>
162 class SerializationTraits<int, Tpetra::
Details::CrsIJV<Ordinal, Scalar> >
163 :
public DirectSerializationTraits<int, Tpetra::Details::CrsIJV<Ordinal, Scalar> >
169 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
171 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
172 size_t maxNumEntriesPerRow,
174 const RCP<Teuchos::ParameterList>& params) :
175 dist_object_type (rowMap),
177 Details::STORAGE_1D_UNPACKED :
178 Details::STORAGE_2D),
179 fillComplete_ (
false),
180 frobNorm_ (-STM::one ())
184 myGraph_ = rcp (
new crs_graph_type (rowMap, maxNumEntriesPerRow,
187 catch (std::exception& e) {
188 TEUCHOS_TEST_FOR_EXCEPTION(
189 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 190 "exception while allocating CrsGraph: " << e.what ());
192 staticGraph_ = myGraph_;
194 checkInternalState ();
197 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
200 const Teuchos::ArrayRCP<const size_t>& NumEntriesPerRowToAlloc,
202 const Teuchos::RCP<Teuchos::ParameterList>& params) :
207 fillComplete_ (false),
208 frobNorm_ (-STM::one ())
212 myGraph_ = rcp (
new Graph (rowMap, NumEntriesPerRowToAlloc, pftype, params));
214 catch (std::exception &e) {
215 TEUCHOS_TEST_FOR_EXCEPTION(
216 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 217 "exception while allocating CrsGraph: " << e.what ());
219 staticGraph_ = myGraph_;
224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
227 const Teuchos::RCP<const map_type>& colMap,
228 size_t maxNumEntriesPerRow,
230 const Teuchos::RCP<Teuchos::ParameterList>& params) :
239 TEUCHOS_TEST_FOR_EXCEPTION(! staticGraph_.is_null(), std::logic_error,
240 "Tpetra::CrsMatrix ctor (row Map, col Map, maxNumEntriesPerRow, ...): " 241 "staticGraph_ is not null at the beginning of the constructor. " 242 "Please report this bug to the Tpetra developers.");
243 TEUCHOS_TEST_FOR_EXCEPTION(! myGraph_.is_null(), std::logic_error,
244 "Tpetra::CrsMatrix ctor (row Map, col Map, maxNumEntriesPerRow, ...): " 245 "myGraph_ is not null at the beginning of the constructor. " 246 "Please report this bug to the Tpetra developers.");
248 myGraph_ = rcp (
new Graph (rowMap, colMap, maxNumEntriesPerRow,
251 catch (std::exception &e) {
252 TEUCHOS_TEST_FOR_EXCEPTION(
253 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 254 "exception while allocating CrsGraph: " << e.what ());
256 staticGraph_ = myGraph_;
261 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
264 const Teuchos::RCP<const map_type>& colMap,
265 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
267 const Teuchos::RCP<Teuchos::ParameterList>& params) :
277 myGraph_ = rcp (
new Graph (rowMap, colMap, numEntPerRow, pftype, params));
279 catch (std::exception &e) {
280 TEUCHOS_TEST_FOR_EXCEPTION(
281 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 282 "exception while allocating CrsGraph: " << e.what ());
284 staticGraph_ = myGraph_;
289 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
291 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
292 const Teuchos::RCP<Teuchos::ParameterList>& params) :
294 staticGraph_ (graph),
299 const char tfecfFuncName[] =
"CrsMatrix(graph[,params])";
300 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(staticGraph_.is_null (),
301 std::runtime_error,
": When calling the CrsMatrix constructor that " 302 "accepts a static graph, the pointer to the graph must not be null.");
304 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! staticGraph_->isFillComplete (),
305 std::runtime_error,
": The specified graph is not fill-complete. You " 306 "must invoke fillComplete() on the graph before using it to construct a " 307 "CrsMatrix. Note that calling resumeFill() makes the graph not fill-" 308 "complete, even if you had previously called fillComplete(). In that " 309 "case, you must call fillComplete() on the graph again.");
317 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
320 const Teuchos::RCP<const map_type>& colMap,
321 const typename local_matrix_type::row_map_type& rowPointers,
322 const typename local_graph_type::entries_type::non_const_type& columnIndices,
323 const typename local_matrix_type::values_type& values,
324 const Teuchos::RCP<Teuchos::ParameterList>& params) :
332 myGraph_ = rcp (
new Graph (rowMap, colMap, rowPointers,
333 columnIndices, params));
335 catch (std::exception &e) {
336 TEUCHOS_TEST_FOR_EXCEPTION(
337 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 338 "exception while allocating CrsGraph: " << e.what ());
340 staticGraph_ = myGraph_;
341 k_values1D_ = values;
346 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
348 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
349 const Teuchos::RCP<const map_type>& colMap,
350 const Teuchos::ArrayRCP<size_t> & rowPointers,
351 const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
352 const Teuchos::ArrayRCP<Scalar> & values,
353 const Teuchos::RCP<Teuchos::ParameterList>& params) :
361 myGraph_ = rcp (
new Graph (rowMap, colMap, rowPointers,
362 columnIndices, params));
364 catch (std::exception &e) {
365 TEUCHOS_TEST_FOR_EXCEPTION(
366 true, std::runtime_error,
"Tpetra::CrsMatrix constructor: Caught " 367 "exception while allocating CrsGraph: " << e.what ());
369 staticGraph_ = myGraph_;
373 Teuchos::ArrayRCP<impl_scalar_type> vals =
375 k_values1D_ = Kokkos::Compat::getKokkosViewDeepCopy<device_type> (vals ());
380 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
383 const Teuchos::RCP<const map_type>& colMap,
385 const Teuchos::RCP<Teuchos::ParameterList>& params) :
392 using Teuchos::ArrayRCP;
396 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(rowMap,colMap,lclMatrix,params): ";
399 myGraph_ = rcp (
new Graph (rowMap, colMap, lclMatrix.graph, params));
401 catch (std::exception &e) {
402 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
403 true, std::runtime_error,
"Caught exception while allocating " 404 "CrsGraph: " << e.what ());
406 staticGraph_ = myGraph_;
417 #ifdef HAVE_TPETRA_DEBUG 418 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive (), std::logic_error,
419 "We're at the end of fillComplete(), but isFillActive() is true. " 420 "Please report this bug to the Tpetra developers.");
421 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete (), std::logic_error,
422 "We're at the end of fillComplete(), but isFillComplete() is false. " 423 "Please report this bug to the Tpetra developers.");
424 #endif // HAVE_TPETRA_DEBUG 428 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
433 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
434 Teuchos::RCP<const Teuchos::Comm<int> >
440 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
447 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
454 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
461 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
468 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
475 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
482 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
489 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
496 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
503 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
510 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
517 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
524 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
531 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
538 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
545 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
552 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
556 return getCrsGraph ()->getNumEntriesInGlobalRow (globalRow);
559 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
563 return getCrsGraph ()->getNumEntriesInLocalRow (localRow);
566 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
570 return getCrsGraph ()->getGlobalMaxNumRowEntries ();
573 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
580 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
587 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
588 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
594 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
595 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
601 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
602 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
608 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
609 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
615 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
616 Teuchos::RCP<const RowGraph<LocalOrdinal, GlobalOrdinal, Node> >
619 if (staticGraph_ != Teuchos::null) {
625 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
626 Teuchos::RCP<const CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> >
629 if (staticGraph_ != Teuchos::null) {
635 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
642 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
649 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
653 return myGraph_.is_null ();
656 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
663 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
670 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
675 #ifdef HAVE_TPETRA_DEBUG 679 if ((gas == GraphAlreadyAllocated) != staticGraph_->indicesAreAllocated()) {
680 const std::string err1 (
"allocateValues: The caller has asserted that " 682 const std::string err2 (
"already allocated, but the static graph says " 683 "that its indices are ");
684 const std::string err3 (
"already allocated. Please report this bug to " 685 "the Tpetra developers.");
686 TEUCHOS_TEST_FOR_EXCEPTION(gas == GraphAlreadyAllocated && ! staticGraph_->indicesAreAllocated(),
687 std::logic_error, err1 << err2 <<
"not " << err3);
688 TEUCHOS_TEST_FOR_EXCEPTION(gas != GraphAlreadyAllocated && staticGraph_->indicesAreAllocated(),
689 std::logic_error, err1 <<
"not " << err2 << err3);
697 TEUCHOS_TEST_FOR_EXCEPTION(
698 ! staticGraph_->indicesAreAllocated() && myGraph_.is_null(),
700 "allocateValues: The static graph says that its indices are not " 701 "allocated, but the graph is not owned by the matrix. Please report " 702 "this bug to the Tpetra developers.");
703 #endif // HAVE_TPETRA_DEBUG 705 if (gas == GraphNotYetAllocated) {
706 myGraph_->allocateIndices (lg);
717 const size_t lclNumRows = staticGraph_->getNodeNumRows ();
718 typename Graph::local_graph_type::row_map_type k_ptrs =
719 staticGraph_->k_rowPtrs_;
720 TEUCHOS_TEST_FOR_EXCEPTION(
721 k_ptrs.dimension_0 () != lclNumRows+1, std::logic_error,
722 "Tpetra::CrsMatrix::allocateValues: With StaticProfile, row offsets " 723 "array has length " << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 724 << (lclNumRows+1) <<
".");
729 const size_t lclTotalNumEntries = k_ptrs(lclNumRows);
732 typedef typename local_matrix_type::values_type values_type;
733 k_values1D_ = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
741 values2D_ = staticGraph_->template allocateValues2D<impl_scalar_type> ();
745 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
748 getAllValues (Teuchos::ArrayRCP<const size_t>& rowPointers,
749 Teuchos::ArrayRCP<const LocalOrdinal>& columnIndices,
750 Teuchos::ArrayRCP<const Scalar>& values)
const 752 const char tfecfFuncName[] =
"getAllValues: ";
753 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
754 columnIndices.size () != values.size (), std::runtime_error,
755 "Requires that columnIndices and values are the same size.");
757 RCP<const crs_graph_type> relevantGraph =
getCrsGraph ();
758 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
759 relevantGraph.is_null (), std::runtime_error,
760 "Requires that getCrsGraph() is not null.");
762 rowPointers = relevantGraph->getNodeRowPtrs ();
764 catch (std::exception &e) {
765 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
766 true, std::runtime_error,
767 "Caught exception while calling graph->getNodeRowPtrs(): " 771 columnIndices = relevantGraph->getNodePackedIndices ();
773 catch (std::exception &e) {
774 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
775 true, std::runtime_error,
776 "Caught exception while calling graph->getNodePackedIndices(): " 779 Teuchos::ArrayRCP<const impl_scalar_type> vals =
780 Kokkos::Compat::persistingView (k_values1D_);
781 values = Teuchos::arcp_reinterpret_cast<
const Scalar> (vals);
784 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
789 using Kokkos::create_mirror_view;
790 using Teuchos::arcp_const_cast;
791 using Teuchos::ArrayRCP;
795 typedef ArrayRCP<size_t>::size_type size_type;
796 typedef typename local_matrix_type::row_map_type row_map_type;
797 typedef typename Graph::t_numRowEntries_ row_entries_type;
798 typedef typename Graph::local_graph_type::entries_type::non_const_type lclinds_1d_type;
799 typedef typename local_matrix_type::values_type values_type;
803 TEUCHOS_TEST_FOR_EXCEPTION(
804 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::" 805 "fillLocalGraphAndMatrix (called from fillComplete or " 806 "expertStaticFillComplete): The nonconst graph (myGraph_) is null. This " 807 "means that the matrix has a const (a.k.a. \"static\") graph. This may " 808 "mean that fillComplete or expertStaticFillComplete has a bug, since it " 809 "should never call fillLocalGraphAndMatrix in that case. " 810 "Please report this bug to the Tpetra developers.");
820 typename row_map_type::non_const_type k_ptrs;
821 row_map_type k_ptrs_const;
822 lclinds_1d_type k_inds;
828 lclinds_1d_type k_lclInds1D_ = myGraph_->k_lclInds1D_;
834 row_entries_type k_numRowEnt = myGraph_->k_numRowEntries_;
835 typename row_entries_type::t_host h_numRowEnt = k_numRowEnt.h_view;
847 TEUCHOS_TEST_FOR_EXCEPTION(
848 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
849 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix (called " 850 "from fillComplete or expertStaticFillComplete): For the " 851 "DynamicProfile branch, k_numRowEnt has the wrong length. " 852 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
853 <<
" != getNodeNumRows() = " << lclNumRows <<
"");
861 size_t lclTotalNumEntries = 0;
863 typename row_map_type::non_const_type::HostMirror h_ptrs;
868 typename row_map_type::non_const_type packedRowOffsets (
"Tpetra::CrsGraph::ptr",
873 h_ptrs = create_mirror_view (packedRowOffsets);
875 for (size_type i = 0; i < static_cast<size_type> (lclNumRows); ++i) {
876 const size_t numEnt = h_numRowEnt(i);
877 lclTotalNumEntries += numEnt;
878 h_ptrs(i+1) = h_ptrs(i) + numEnt;
883 k_ptrs = packedRowOffsets;
884 k_ptrs_const = k_ptrs;
887 TEUCHOS_TEST_FOR_EXCEPTION(
888 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
889 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: In " 890 "DynamicProfile branch, after packing k_ptrs, k_ptrs.dimension_0()" 891 " = " << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 892 << (lclNumRows+1) <<
".");
893 TEUCHOS_TEST_FOR_EXCEPTION(
894 static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
895 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: In " 896 "DynamicProfile branch, after packing h_ptrs, h_ptrs.dimension_0()" 897 " = " << h_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 898 << (lclNumRows+1) <<
".");
900 TEUCHOS_TEST_FOR_EXCEPTION(
901 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
902 "Tpetra::CrsMatrix::fillLocalGraphAndMatrix: In DynamicProfile branch, " 903 "after packing k_ptrs, k_ptrs(lclNumRows = " << lclNumRows <<
") = " <<
904 k_ptrs(lclNumRows) <<
" != total number of entries on the calling " 905 "process = " << lclTotalNumEntries <<
".");
908 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
909 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
912 typename lclinds_1d_type::HostMirror h_inds = create_mirror_view (k_inds);
913 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
916 ArrayRCP<Array<LocalOrdinal> > lclInds2D = myGraph_->lclInds2D_;
917 for (
size_t row = 0; row < lclNumRows; ++row) {
918 const size_t numEnt = h_numRowEnt(row);
919 std::copy (lclInds2D[row].begin(),
920 lclInds2D[row].begin() + numEnt,
921 h_inds.ptr_on_device() + h_ptrs(row));
922 std::copy (values2D_[row].begin(),
923 values2D_[row].begin() + numEnt,
924 h_vals.ptr_on_device() + h_ptrs(row));
931 if (k_ptrs.dimension_0 () != 0) {
932 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
933 TEUCHOS_TEST_FOR_EXCEPTION(
934 static_cast<size_t> (k_ptrs(numOffsets-1)) != k_vals.dimension_0 (),
935 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 936 "In DynamicProfile branch, after packing, k_ptrs(" << (numOffsets-1)
937 <<
") = " << k_ptrs(numOffsets-1) <<
" != k_vals.dimension_0() = " 938 << k_vals.dimension_0 () <<
".");
939 TEUCHOS_TEST_FOR_EXCEPTION(
940 static_cast<size_t> (k_ptrs(numOffsets-1)) != k_inds.dimension_0 (),
941 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 942 "In DynamicProfile branch, after packing, k_ptrs(" << (numOffsets-1)
943 <<
") = " << k_ptrs(numOffsets-1) <<
" != k_inds.dimension_0() = " 944 << k_inds.dimension_0 () <<
".");
954 typename Graph::local_graph_type::row_map_type curRowOffsets =
955 myGraph_->k_rowPtrs_;
956 TEUCHOS_TEST_FOR_EXCEPTION(
957 curRowOffsets.dimension_0 () == 0, std::logic_error,
958 "curRowOffsets has size zero, but shouldn't");
959 TEUCHOS_TEST_FOR_EXCEPTION(
960 curRowOffsets.dimension_0 () != lclNumRows + 1, std::logic_error,
961 "Tpetra::CrsMatrix::fillLocalGraphAndMatrix: curRowOffsets has size " 962 << curRowOffsets.dimension_0 () <<
" != lclNumRows + 1 = " 963 << (lclNumRows + 1) <<
".")
965 const size_t numOffsets = curRowOffsets.dimension_0 ();
967 TEUCHOS_TEST_FOR_EXCEPTION(
969 myGraph_->k_lclInds1D_.dimension_0 () != curRowOffsets(numOffsets - 1),
970 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 971 "numOffsets = " << numOffsets <<
" != 0 and " 972 "myGraph_->k_lclInds1D_.dimension_0() = " 973 << myGraph_->k_lclInds1D_.dimension_0 ()
974 <<
" != curRowOffsets(" << numOffsets <<
") = " 975 << curRowOffsets(numOffsets - 1) <<
".");
978 if (myGraph_->nodeNumEntries_ != myGraph_->nodeNumAllocated_) {
985 TEUCHOS_TEST_FOR_EXCEPTION(
986 static_cast<size_t> (k_numRowEnt.dimension_0 ()) != lclNumRows,
987 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix (called" 988 " from fillComplete or expertStaticFillComplete): In StaticProfile " 989 "unpacked branch, k_numRowEnt has the wrong length. " 990 "k_numRowEnt.dimension_0() = " << k_numRowEnt.dimension_0 ()
991 <<
" != getNodeNumRows() = " << lclNumRows <<
".");
993 if (curRowOffsets.dimension_0 () != 0) {
994 const size_t numOffsets =
995 static_cast<size_t> (curRowOffsets.dimension_0 ());
996 TEUCHOS_TEST_FOR_EXCEPTION(
997 curRowOffsets(numOffsets-1) != static_cast<size_t> (k_values1D_.dimension_0 ()),
998 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 999 "In StaticProfile branch, before allocating or packing, " 1000 "curRowOffsets(" << (numOffsets-1) <<
") = " 1001 << curRowOffsets(numOffsets - 1)
1002 <<
" != k_values1D_.dimension_0() = " 1003 << k_values1D_.dimension_0 () <<
".");
1004 TEUCHOS_TEST_FOR_EXCEPTION(
1005 static_cast<size_t> (curRowOffsets(numOffsets - 1)) !=
1006 myGraph_->k_lclInds1D_.dimension_0 (),
1007 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 1008 "In StaticProfile branch, before allocating or packing, " 1009 "curRowOffsets(" << (numOffsets-1) <<
") = " 1010 << curRowOffsets(numOffsets - 1)
1011 <<
" != myGraph_->k_lclInds1D_.dimension_0() = " 1012 << myGraph_->k_lclInds1D_.dimension_0 () <<
".");
1021 size_t lclTotalNumEntries = 0;
1023 typename row_map_type::non_const_type::HostMirror h_ptrs;
1028 typename row_map_type::non_const_type packedRowOffsets (
"Tpetra::CrsGraph::ptr",
1036 h_ptrs = create_mirror_view (packedRowOffsets);
1038 for (size_type i = 0; i < static_cast<size_type> (lclNumRows); ++i) {
1039 const size_t numEnt = h_numRowEnt(i);
1040 lclTotalNumEntries += numEnt;
1041 h_ptrs(i+1) = h_ptrs(i) + numEnt;
1046 k_ptrs = packedRowOffsets;
1047 k_ptrs_const = k_ptrs;
1050 TEUCHOS_TEST_FOR_EXCEPTION(
1051 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
1052 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: For " 1053 "the StaticProfile unpacked-but-pack branch, after packing k_ptrs, " 1054 "k_ptrs.dimension_0() = " << k_ptrs.dimension_0 () <<
" != " 1055 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
1057 TEUCHOS_TEST_FOR_EXCEPTION(
1058 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
1059 "Tpetra::CrsMatrix::fillLocalGraphAndMatrix: In StaticProfile " 1060 "unpacked-but-pack branch, after filling k_ptrs, k_ptrs(lclNumRows=" 1061 << lclNumRows <<
") = " << k_ptrs(lclNumRows) <<
" != total number " 1062 "of entries on the calling process = " << lclTotalNumEntries <<
".");
1065 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1066 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1078 typedef pack_functor<
typename Graph::local_graph_type::entries_type::non_const_type,
1079 typename Graph::local_graph_type::row_map_type>
1081 inds_packer_type indsPacker (k_inds, myGraph_->k_lclInds1D_,
1082 k_ptrs, curRowOffsets);
1083 Kokkos::parallel_for (lclNumRows, indsPacker);
1087 typedef pack_functor<values_type, row_map_type> vals_packer_type;
1088 vals_packer_type valsPacker (k_vals, this->k_values1D_,
1089 k_ptrs, curRowOffsets);
1090 Kokkos::parallel_for (lclNumRows, valsPacker);
1092 TEUCHOS_TEST_FOR_EXCEPTION(
1093 k_ptrs.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsMatrix::" 1094 "fillLocalGraphAndMatrix: In StaticProfile \"Optimize Storage\" = " 1095 "true branch, after packing, k_ptrs.dimension_0() = 0. This " 1096 "probably means that k_rowPtrs_ was never allocated.");
1097 if (k_ptrs.dimension_0 () != 0) {
1098 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
1099 TEUCHOS_TEST_FOR_EXCEPTION(
1100 static_cast<size_t> (k_ptrs(numOffsets - 1)) != k_vals.dimension_0 (),
1101 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 1102 "In StaticProfile \"Optimize Storage\"=true branch, after packing, " 1103 "k_ptrs(" << (numOffsets-1) <<
") = " << k_ptrs(numOffsets-1) <<
1104 " != k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1105 TEUCHOS_TEST_FOR_EXCEPTION(
1106 static_cast<size_t> (k_ptrs(numOffsets - 1)) != k_inds.dimension_0 (),
1107 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 1108 "In StaticProfile \"Optimize Storage\"=true branch, after packing, " 1109 "k_ptrs(" << (numOffsets-1) <<
") = " << k_ptrs(numOffsets-1) <<
1110 " != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1114 k_ptrs_const = myGraph_->k_rowPtrs_;
1115 k_inds = myGraph_->k_lclInds1D_;
1116 k_vals = this->k_values1D_;
1118 TEUCHOS_TEST_FOR_EXCEPTION(
1119 k_ptrs_const.dimension_0 () == 0, std::logic_error,
"Tpetra::CrsMatrix::" 1120 "fillLocalGraphAndMatrix: In StaticProfile \"Optimize Storage\" = " 1121 "false branch, k_ptrs_const.dimension_0() = 0. This probably means that " 1122 "k_rowPtrs_ was never allocated.");
1123 if (k_ptrs_const.dimension_0 () != 0) {
1124 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
1125 TEUCHOS_TEST_FOR_EXCEPTION(
1126 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_vals.dimension_0 (),
1127 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 1128 "In StaticProfile \"Optimize Storage\" = false branch, " 1129 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets - 1)
1130 <<
" != k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1131 TEUCHOS_TEST_FOR_EXCEPTION(
1132 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
1133 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: " 1134 "In StaticProfile \"Optimize Storage\" = false branch, " 1135 "k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets - 1)
1136 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1142 TEUCHOS_TEST_FOR_EXCEPTION(
1143 static_cast<size_t> (k_ptrs_const.dimension_0 ()) != lclNumRows + 1,
1144 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: After " 1145 "packing, k_ptrs_const.dimension_0() = " << k_ptrs_const.dimension_0 ()
1146 <<
" != lclNumRows+1 = " << (lclNumRows+1) <<
".");
1147 if (k_ptrs_const.dimension_0 () != 0) {
1148 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
1149 TEUCHOS_TEST_FOR_EXCEPTION(
1150 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_vals.dimension_0 (),
1151 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: After " 1152 "packing, k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets-1)
1153 <<
" != k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1154 TEUCHOS_TEST_FOR_EXCEPTION(
1155 static_cast<size_t> (k_ptrs_const(numOffsets - 1)) != k_inds.dimension_0 (),
1156 std::logic_error,
"Tpetra::CrsMatrix::fillLocalGraphAndMatrix: After " 1157 "packing, k_ptrs_const(" << (numOffsets-1) <<
") = " << k_ptrs_const(numOffsets-1)
1158 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1165 const bool defaultOptStorage =
1167 const bool requestOptimizedStorage =
1168 (! params.is_null () && params->get (
"Optimize Storage", defaultOptStorage)) ||
1169 (params.is_null () && defaultOptStorage);
1176 if (requestOptimizedStorage) {
1182 myGraph_->lclInds2D_ = null;
1183 myGraph_->k_numRowEntries_ = row_entries_type ();
1186 this->values2D_ = null;
1189 myGraph_->k_rowPtrs_ = k_ptrs_const;
1190 myGraph_->k_lclInds1D_ = k_inds;
1191 this->k_values1D_ = k_vals;
1195 myGraph_->nodeNumAllocated_ = myGraph_->nodeNumEntries_;
1199 myGraph_->storageStatus_ = Details::STORAGE_1D_PACKED;
1211 myGraph_->lclGraph_ =
1217 myGraph_->lclGraph_);
1220 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1225 using Kokkos::create_mirror_view;
1226 using Teuchos::ArrayRCP;
1227 using Teuchos::Array;
1228 using Teuchos::null;
1231 typedef LocalOrdinal LO;
1232 typedef typename Graph::t_numRowEntries_ row_entries_type;
1233 typedef typename Graph::local_graph_type::row_map_type row_map_type;
1234 typedef typename row_map_type::non_const_type non_const_row_map_type;
1235 typedef typename local_matrix_type::values_type values_type;
1239 RCP<node_type> node = rowMap.
getNode ();
1250 ArrayRCP<Array<LO> > lclInds2D = staticGraph_->lclInds2D_;
1251 size_t nodeNumEntries = staticGraph_->nodeNumEntries_;
1252 size_t nodeNumAllocated = staticGraph_->nodeNumAllocated_;
1253 row_map_type k_rowPtrs_ = staticGraph_->lclGraph_.row_map;
1255 row_map_type k_ptrs;
1261 bool requestOptimizedStorage =
true;
1262 const bool default_OptimizeStorage =
1264 if (! params.is_null () && ! params->get (
"Optimize Storage", default_OptimizeStorage)) {
1265 requestOptimizedStorage =
false;
1272 if (! staticGraph_->isStorageOptimized () && requestOptimizedStorage) {
1274 "::fillLocalMatrix(): You requested optimized storage by setting the" 1275 "\"Optimize Storage\" flag to \"true\" in the parameter list, or by virtue" 1276 "of default behavior. However, the associated CrsGraph was filled separately" 1277 "and requested not to optimize storage. Therefore, the CrsMatrix cannot" 1278 "optimize storage.");
1279 requestOptimizedStorage =
false;
1286 row_entries_type k_numRowEnt = staticGraph_->k_numRowEntries_;
1287 typename row_entries_type::t_host h_numRowEnt = k_numRowEnt.h_view;
1312 size_t lclTotalNumEntries = 0;
1314 typename non_const_row_map_type::HostMirror h_ptrs;
1316 non_const_row_map_type packedRowOffsets (
"Tpetra::CrsGraph::ptr",
1321 h_ptrs = create_mirror_view (packedRowOffsets);
1323 for (
size_t i = 0; i < lclNumRows; ++i) {
1324 const size_t numEnt = h_numRowEnt(i);
1325 lclTotalNumEntries += numEnt;
1326 h_ptrs(i+1) = h_ptrs(i) + numEnt;
1329 k_ptrs = packedRowOffsets;
1332 TEUCHOS_TEST_FOR_EXCEPTION(
1333 static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
1334 std::logic_error,
"Tpetra::CrsMatrix::fillLocalMatrix: In " 1335 "DynamicProfile branch, after packing k_ptrs, k_ptrs.dimension_0()" 1336 " = " << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 1337 << (lclNumRows+1) <<
".");
1338 TEUCHOS_TEST_FOR_EXCEPTION(
1339 static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
1340 std::logic_error,
"Tpetra::CrsMatrix::fillLocalMatrix: In " 1341 "DynamicProfile branch, after packing h_ptrs, h_ptrs.dimension_0()" 1342 " = " << h_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 1343 << (lclNumRows+1) <<
".");
1345 TEUCHOS_TEST_FOR_EXCEPTION(
1346 k_ptrs(lclNumRows) != lclTotalNumEntries, std::logic_error,
1347 "Tpetra::CrsMatrix::fillLocalMatrix: In DynamicProfile branch, " 1348 "after packing k_ptrs, k_ptrs(lclNumRows = " << lclNumRows <<
") = " <<
1349 k_ptrs(lclNumRows) <<
" != total number of entries on the calling " 1350 "process = " << lclTotalNumEntries <<
".");
1353 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1355 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
1357 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1358 const size_t numEnt = h_numRowEnt(lclRow);
1359 std::copy (values2D_[lclRow].begin(),
1360 values2D_[lclRow].begin() + numEnt,
1361 h_vals.ptr_on_device() + h_ptrs(lclRow));
1367 if (k_ptrs.dimension_0 () != 0) {
1368 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
1369 TEUCHOS_TEST_FOR_EXCEPTION(
1370 static_cast<size_t> (k_ptrs(numOffsets-1)) != k_vals.dimension_0 (),
1371 std::logic_error,
"Tpetra::CrsMatrix::fillLocalMatrix: " 1372 "In DynamicProfile branch, after packing, k_ptrs(" << (numOffsets-1)
1373 <<
") = " << k_ptrs(numOffsets-1) <<
" != k_vals.dimension_0() = " 1374 << k_vals.dimension_0 () <<
".");
1395 if (nodeNumEntries != nodeNumAllocated) {
1398 non_const_row_map_type tmpk_ptrs (
"Tpetra::CrsGraph::ptr",
1403 size_t lclTotalNumEntries = 0;
1409 typename non_const_row_map_type::HostMirror h_ptrs =
1410 create_mirror_view (tmpk_ptrs);
1412 for (
size_t i = 0; i < lclNumRows; ++i) {
1413 const size_t numEnt = h_numRowEnt(i);
1414 lclTotalNumEntries += numEnt;
1415 h_ptrs(i+1) = h_ptrs(i) + numEnt;
1422 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1425 typedef pack_functor<values_type, row_map_type> packer_type;
1426 packer_type valsPacker (k_vals, k_values1D_, tmpk_ptrs, k_rowPtrs_);
1427 Kokkos::parallel_for (lclNumRows, valsPacker);
1430 k_vals = k_values1D_;
1435 if (requestOptimizedStorage) {
1439 k_values1D_ = k_vals;
1450 staticGraph_->getLocalGraph ());
1453 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1457 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1458 const Teuchos::ArrayView<const Scalar>& values)
1460 using Teuchos::Array;
1461 using Teuchos::ArrayView;
1462 using Teuchos::av_reinterpret_cast;
1463 using Teuchos::toString;
1465 const char tfecfFuncName[] =
"insertLocalValues";
1467 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillActive (), std::runtime_error,
1468 ": Fill is not active. After calling fillComplete, you must call " 1469 "resumeFill before you may insert entries into the matrix again.");
1470 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isStaticGraph (), std::runtime_error,
1471 " cannot insert indices with static graph; use replaceLocalValues() instead.");
1472 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(myGraph_->isGloballyIndexed(),
1473 std::runtime_error,
": graph indices are global; use insertGlobalValues().");
1474 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
hasColMap (), std::runtime_error,
1475 " cannot insert local indices without a column map.");
1476 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(values.size() != indices.size(),
1477 std::runtime_error,
": values.size() must equal indices.size().");
1478 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1479 !
getRowMap()->isNodeLocalElement(localRow), std::runtime_error,
1480 ": Local row index " << localRow <<
" does not belong to this process.");
1482 if (! myGraph_->indicesAreAllocated ()) {
1486 catch (std::exception& e) {
1487 TEUCHOS_TEST_FOR_EXCEPTION(
1488 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1489 "allocateValues(LocalIndices,GraphNotYetAllocated) threw an " 1490 "exception: " << e.what ());
1494 const size_t numEntriesToAdd =
static_cast<size_t> (indices.size ());
1495 #ifdef HAVE_TPETRA_DEBUG 1502 Array<LocalOrdinal> badColInds;
1503 bool allInColMap =
true;
1504 for (
size_t k = 0; k < numEntriesToAdd; ++k) {
1506 allInColMap =
false;
1507 badColInds.push_back (indices[k]);
1510 if (! allInColMap) {
1511 std::ostringstream os;
1512 os <<
"Tpetra::CrsMatrix::insertLocalValues: You attempted to insert " 1513 "entries in owned row " << localRow <<
", at the following column " 1514 "indices: " << toString (indices) <<
"." << endl;
1515 os <<
"Of those, the following indices are not in the column Map on " 1516 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 1517 "the matrix has a column Map already, it is invalid to insert " 1518 "entries at those locations.";
1519 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
1522 #endif // HAVE_TPETRA_DEBUG 1524 #ifdef HAVE_TPETRA_DEBUG 1527 rowInfo = myGraph_->getRowInfo (localRow);
1528 }
catch (std::exception& e) {
1529 TEUCHOS_TEST_FOR_EXCEPTION(
1530 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1531 "myGraph_->getRowInfo threw an exception: " << e.what ());
1534 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1535 #endif // HAVE_TPETRA_DEBUG 1537 const size_t curNumEntries = rowInfo.numEntries;
1538 const size_t newNumEntries = curNumEntries + numEntriesToAdd;
1539 if (newNumEntries > rowInfo.allocSize) {
1540 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1542 ": new indices exceed statically allocated graph structure.");
1546 rowInfo = myGraph_->template updateLocalAllocAndValues<impl_scalar_type> (rowInfo,
1548 values2D_[localRow]);
1549 }
catch (std::exception& e) {
1550 TEUCHOS_TEST_FOR_EXCEPTION(
1551 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1552 "myGraph_->updateGlobalAllocAndValues threw an exception: " 1556 typename Graph::SLocalGlobalViews indsView;
1557 indsView.linds = indices;
1559 #ifdef HAVE_TPETRA_DEBUG 1560 ArrayView<impl_scalar_type> valsView;
1563 }
catch (std::exception& e) {
1564 TEUCHOS_TEST_FOR_EXCEPTION(
1565 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1566 "getViewNonConst threw an exception: " << e.what ());
1569 ArrayView<impl_scalar_type> valsView = this->
getViewNonConst (rowInfo);
1570 #endif // HAVE_TPETRA_DEBUG 1572 ArrayView<const impl_scalar_type> valsIn =
1575 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, indsView,
1579 }
catch (std::exception& e) {
1580 TEUCHOS_TEST_FOR_EXCEPTION(
1581 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1582 "myGraph_->insertIndicesAndValues threw an exception: " 1586 #ifdef HAVE_TPETRA_DEBUG 1587 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
1588 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1589 chkNewNumEntries != newNumEntries, std::logic_error,
1590 ": The row should have " << newNumEntries <<
" entries after insert, but " 1591 "instead has " << chkNewNumEntries <<
". Please report this bug to the " 1592 "Tpetra developers.");
1593 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isLocallyIndexed(), std::logic_error,
1594 ": At end of insertLocalValues(), this CrsMatrix is not locally indexed. " 1595 "Please report this bug to the Tpetra developers.");
1596 #endif // HAVE_TPETRA_DEBUG 1599 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1603 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1604 const Teuchos::ArrayView<const Scalar>& values)
1606 using Teuchos::Array;
1607 using Teuchos::ArrayView;
1608 using Teuchos::av_reinterpret_cast;
1609 const char tfecfFuncName[] =
"insertLocalValues: ";
1611 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillActive (), std::runtime_error,
1612 "Requires that fill is active.");
1613 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isStaticGraph (), std::runtime_error,
1614 "Cannot insert indices with static graph; use replaceLocalValues() instead.");
1615 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(myGraph_->isGloballyIndexed(),
1616 std::runtime_error,
"Graph indices are global; use insertGlobalValues().");
1617 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1618 !
hasColMap (), std::runtime_error,
"The matrix has no column Map yet, " 1619 "so you cannot insert local indices. If you created the matrix without " 1620 "a column Map (or without a fill-complete graph), you must call " 1621 "fillComplete to create the column Map, before you may work with local " 1623 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1624 values.size () != indices.size (), std::runtime_error,
"values.size() = " 1625 << values.size () <<
" != indices.size() = " << indices.size ()<<
".");
1626 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1627 !
getRowMap()->isNodeLocalElement (localRow), std::runtime_error,
1628 "Local row index " << localRow <<
" does not belong to this process.");
1629 if (! myGraph_->indicesAreAllocated ()) {
1634 Array<LocalOrdinal> f_inds (indices);
1635 ArrayView<const impl_scalar_type> valsIn =
1637 Array<impl_scalar_type> f_vals (valsIn);
1638 const size_t numFilteredEntries =
1639 myGraph_->template filterLocalIndicesAndValues<impl_scalar_type> (f_inds (),
1641 if (numFilteredEntries > 0) {
1642 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1643 const size_t curNumEntries = rowInfo.numEntries;
1644 const size_t newNumEntries = curNumEntries + numFilteredEntries;
1645 if (newNumEntries > rowInfo.allocSize) {
1646 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1648 ": new indices exceed statically allocated graph structure. " 1649 "newNumEntries (" << newNumEntries <<
" > rowInfo.allocSize (" 1650 << rowInfo.allocSize <<
").");
1653 myGraph_->template updateLocalAllocAndValues<impl_scalar_type> (rowInfo,
1655 values2D_[localRow]);
1657 typename Graph::SLocalGlobalViews inds_view;
1658 inds_view.linds = f_inds (0, numFilteredEntries);
1659 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
1661 f_vals, LocalIndices,
1663 #ifdef HAVE_TPETRA_DEBUG 1664 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
1665 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
1666 std::logic_error,
": Internal logic error. Please contact Tpetra team.");
1667 #endif // HAVE_TPETRA_DEBUG 1669 #ifdef HAVE_TPETRA_DEBUG 1670 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isLocallyIndexed(), std::logic_error,
1671 ": At end of insertLocalValues(), this CrsMatrix is not locally indexed. " 1672 "Please report this bug to the Tpetra developers.");
1673 #endif // HAVE_TPETRA_DEBUG 1677 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1681 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
1682 const Teuchos::ArrayView<const Scalar>& values)
1684 using Teuchos::Array;
1685 using Teuchos::ArrayView;
1686 using Teuchos::av_reinterpret_cast;
1687 using Teuchos::toString;
1689 typedef LocalOrdinal LO;
1690 typedef GlobalOrdinal GO;
1691 typedef typename ArrayView<const GO>::size_type size_type;
1692 const char tfecfFuncName[] =
"insertGlobalValues: ";
1694 #ifdef HAVE_TPETRA_DEBUG 1695 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1696 values.size () != indices.size (), std::runtime_error,
1697 "values.size() = " << values.size() <<
" != indices.size() = " 1698 << indices.size() <<
".");
1699 #endif // HAVE_TPETRA_DEBUG 1701 const LO localRow =
getRowMap ()->getLocalElement (globalRow);
1703 if (localRow == OTL::invalid ()) {
1704 insertNonownedGlobalValues (globalRow, indices, values);
1709 std::ostringstream err;
1710 const int myRank =
getRowMap ()->getComm ()->getRank ();
1711 const int numProcs =
getRowMap ()->getComm ()->getSize ();
1713 err <<
"The matrix was constructed with a constant (\"static\") graph, " 1714 "yet the given global row index " << globalRow <<
" is in the row " 1715 "Map on the calling process (with rank " << myRank <<
", of " <<
1716 numProcs <<
" process(es)). In this case, you may not insert new " 1717 "entries into rows owned by the calling process.";
1719 if (!
getRowMap ()->isNodeGlobalElement (globalRow)) {
1720 err <<
" Furthermore, GID->LID conversion with the row Map claims that " 1721 "the global row index is owned on the calling process, yet " 1722 "getRowMap()->isNodeGlobalElement(globalRow) returns false. That's" 1723 " weird! This might indicate a Map bug. Please report this to the" 1724 " Tpetra developers.";
1726 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1730 if (! myGraph_->indicesAreAllocated ()) {
1734 catch (std::exception& e) {
1735 TEUCHOS_TEST_FOR_EXCEPTION(
1736 true, std::runtime_error,
"Tpetra::CrsMatrix::insertGlobalValues: " 1737 "allocateValues(GlobalIndices,GraphNotYetAllocated) threw an " 1738 "exception: " << e.what ());
1742 const size_type numEntriesToInsert = indices.size ();
1755 #ifdef HAVE_TPETRA_DEBUG 1756 Array<GO> badColInds;
1757 #endif // HAVE_TPETRA_DEBUG 1758 bool allInColMap =
true;
1759 for (size_type k = 0; k < numEntriesToInsert; ++k) {
1761 allInColMap =
false;
1762 #ifdef HAVE_TPETRA_DEBUG 1763 badColInds.push_back (indices[k]);
1766 #endif // HAVE_TPETRA_DEBUG 1769 if (! allInColMap) {
1770 std::ostringstream os;
1771 os <<
"You attempted to insert entries in owned row " << globalRow
1772 <<
", at the following column indices: " << toString (indices)
1774 #ifdef HAVE_TPETRA_DEBUG 1775 os <<
"Of those, the following indices are not in the column Map on " 1776 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 1777 "the matrix has a column Map already, it is invalid to insert " 1778 "entries at those locations.";
1780 os <<
"At least one of those indices is not in the column Map on this " 1781 "process." << endl <<
"It is invalid to insert into columns not in " 1782 "the column Map on the process that owns the row.";
1783 #endif // HAVE_TPETRA_DEBUG 1784 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1785 ! allInColMap, std::invalid_argument, os.str ());
1789 typename Graph::SLocalGlobalViews inds_view;
1790 ArrayView<const impl_scalar_type> vals_view;
1792 inds_view.ginds = indices;
1795 #ifdef HAVE_TPETRA_DEBUG 1798 rowInfo = myGraph_->getRowInfo (localRow);
1799 }
catch (std::exception& e) {
1800 TEUCHOS_TEST_FOR_EXCEPTION(
1801 true, std::runtime_error,
"myGraph_->getRowInfo(localRow=" << localRow
1802 <<
") threw an exception: " << e.what ());
1805 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1806 #endif // HAVE_TPETRA_DEBUG 1808 const size_t curNumEntries = rowInfo.numEntries;
1809 const size_t newNumEntries =
1810 curNumEntries +
static_cast<size_t> (numEntriesToInsert);
1811 if (newNumEntries > rowInfo.allocSize) {
1812 TEUCHOS_TEST_FOR_EXCEPTION(
1814 std::runtime_error,
"Tpetra::CrsMatrix::insertGlobalValues: new " 1815 "indices exceed statically allocated graph structure. curNumEntries" 1816 " (" << curNumEntries <<
") + numEntriesToInsert (" <<
1817 numEntriesToInsert <<
") > allocSize (" << rowInfo.allocSize <<
").");
1822 myGraph_->template updateGlobalAllocAndValues<impl_scalar_type> (rowInfo,
1824 values2D_[localRow]);
1825 }
catch (std::exception& e) {
1826 TEUCHOS_TEST_FOR_EXCEPTION(
1827 true, std::runtime_error,
"myGraph_->updateGlobalAllocAndValues" 1828 "(...) threw an exception: " << e.what ());
1836 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
1839 GlobalIndices, GlobalIndices);
1845 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
1848 GlobalIndices, LocalIndices);
1851 catch (std::exception& e) {
1852 TEUCHOS_TEST_FOR_EXCEPTION(
1853 true, std::runtime_error,
"myGraph_->insertIndicesAndValues(...) " 1854 "threw an exception: " << e.what ());
1857 #ifdef HAVE_TPETRA_DEBUG 1858 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
1859 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
1860 std::logic_error,
": There should be a total of " << newNumEntries
1861 <<
" entries in the row, but the graph now reports " << chkNewNumEntries
1862 <<
" entries. Please report this bug to the Tpetra developers.");
1863 #endif // HAVE_TPETRA_DEBUG 1868 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1872 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
1873 const Teuchos::ArrayView<const Scalar>& values)
1875 using Teuchos::Array;
1876 using Teuchos::ArrayView;
1877 using Teuchos::av_reinterpret_cast;
1878 typedef LocalOrdinal LO;
1879 typedef GlobalOrdinal GO;
1881 const char tfecfFuncName[] =
"insertGlobalValuesFiltered: ";
1891 #ifdef HAVE_TPETRA_DEBUG 1892 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1893 values.size () != indices.size (), std::runtime_error,
1894 "values.size() = " << values.size() <<
" != indices.size() = " 1895 << indices.size() <<
".");
1896 #endif // HAVE_TPETRA_DEBUG 1898 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
1899 const LO lrow =
getRowMap ()->getLocalElement (globalRow);
1901 if (lrow != Teuchos::OrdinalTraits<LO>::invalid ()) {
1904 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1906 "The matrix was constructed with a static graph. In that case, " 1907 "it is forbidden to insert new entries into rows owned by the " 1908 "calling process.");
1909 if (! myGraph_->indicesAreAllocated ()) {
1912 typename Graph::SLocalGlobalViews inds_view;
1913 ArrayView<const ST> vals_view;
1918 Array<GO> filtered_indices;
1919 Array<ST> filtered_values;
1923 filtered_indices.assign (indices.begin (), indices.end ());
1924 filtered_values.assign (valsIn.begin (), valsIn.end ());
1925 const size_t numFilteredEntries =
1926 myGraph_->template filterGlobalIndicesAndValues<ST> (filtered_indices (),
1927 filtered_values ());
1928 inds_view.ginds = filtered_indices (0, numFilteredEntries);
1929 vals_view = filtered_values (0, numFilteredEntries);
1932 inds_view.ginds = indices;
1935 const size_t numFilteredEntries = vals_view.size ();
1937 if (numFilteredEntries > 0) {
1938 RowInfo rowInfo = myGraph_->getRowInfo (lrow);
1939 const size_t curNumEntries = rowInfo.numEntries;
1940 const size_t newNumEntries = curNumEntries + numFilteredEntries;
1941 if (newNumEntries > rowInfo.allocSize) {
1942 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1944 "New indices exceed statically allocated graph structure.");
1947 rowInfo = myGraph_->template updateGlobalAllocAndValues<ST> (rowInfo,
1955 myGraph_->template insertIndicesAndValues<ST> (rowInfo, inds_view,
1958 GlobalIndices, GlobalIndices);
1964 myGraph_->template insertIndicesAndValues<ST> (rowInfo, inds_view,
1967 GlobalIndices, LocalIndices);
1969 #ifdef HAVE_TPETRA_DEBUG 1971 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (lrow);
1972 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
1973 std::logic_error,
": There should be a total of " << newNumEntries
1974 <<
" entries in the row, but the graph now reports " << chkNewNumEntries
1975 <<
" entries. Please report this bug to the Tpetra developers.");
1977 #endif // HAVE_TPETRA_DEBUG 1981 insertNonownedGlobalValues (globalRow, indices, values);
1986 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1990 const Teuchos::ArrayView<const LocalOrdinal> &indices,
1991 const Teuchos::ArrayView<const Scalar>& values)
1993 using Teuchos::Array;
1994 using Teuchos::ArrayView;
1995 using Teuchos::av_reinterpret_cast;
1996 typedef LocalOrdinal LO;
1997 typedef GlobalOrdinal GO;
2003 typedef typename ArrayView<GO>::size_type size_type;
2005 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
2008 return Teuchos::OrdinalTraits<LO>::invalid ();
2012 return Teuchos::OrdinalTraits<LO>::invalid ();
2014 else if (values.size () != indices.size ()) {
2016 return Teuchos::OrdinalTraits<LO>::invalid ();
2018 const bool isLocalRow =
getRowMap ()->isNodeLocalElement (localRow);
2025 return static_cast<LO
> (0);
2028 if (indices.size () == 0) {
2029 return static_cast<LO
> (0);
2032 RowInfo rowInfo = staticGraph_->getRowInfo (localRow);
2035 return staticGraph_->template transformLocalValues<ST, f_type> (rowInfo,
2048 const size_type numInds = indices.size ();
2055 Array<GO> gblInds (numInds);
2056 size_type numValid = 0;
2057 for (size_type k = 0; k < numInds; ++k) {
2060 if (gid != Teuchos::OrdinalTraits<GO>::invalid ()) {
2064 const LO numXformed =
2065 staticGraph_->template transformGlobalValues<ST, f_type> (rowInfo,
2070 if (static_cast<size_type> (numXformed) != numValid) {
2071 return Teuchos::OrdinalTraits<LO>::invalid ();
2083 return static_cast<LO
> (0);
2088 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2092 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2093 const Teuchos::ArrayView<const Scalar>& values)
2095 using Teuchos::Array;
2096 using Teuchos::ArrayView;
2097 using Teuchos::av_reinterpret_cast;
2098 typedef LocalOrdinal LO;
2099 typedef GlobalOrdinal GO;
2105 typedef typename ArrayView<GO>::size_type size_type;
2107 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
2110 return Teuchos::OrdinalTraits<LO>::invalid ();
2112 else if (values.size () != indices.size ()) {
2114 return Teuchos::OrdinalTraits<LO>::invalid ();
2117 const LO lrow = this->
getRowMap ()->getLocalElement (globalRow);
2118 if (lrow == Teuchos::OrdinalTraits<LO>::invalid ()) {
2123 return Teuchos::OrdinalTraits<LO>::invalid ();
2126 if (staticGraph_.is_null ()) {
2127 return Teuchos::OrdinalTraits<LO>::invalid ();
2131 if (indices.size () == 0) {
2132 return static_cast<LO
> (0);
2143 const size_type numInds = indices.size ();
2144 Array<LO> lclInds (numInds);
2145 for (size_type k = 0; k < numInds; ++k) {
2152 return graph.template transformLocalValues<ST, f_type> (rowInfo,
2159 return graph.template transformGlobalValues<ST, f_type> (rowInfo,
2170 return static_cast<LO
> (0);
2176 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2180 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2181 const Teuchos::ArrayView<const Scalar>& values)
2184 using Teuchos::Array;
2185 using Teuchos::ArrayView;
2186 using Teuchos::av_reinterpret_cast;
2187 typedef LocalOrdinal LO;
2188 typedef GlobalOrdinal GO;
2190 typedef std::plus<Scalar> f_type;
2191 typedef typename ArrayView<GO>::size_type size_type;
2193 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
2196 return Teuchos::OrdinalTraits<LO>::invalid ();
2198 else if (values.size () != indices.size ()) {
2200 return Teuchos::OrdinalTraits<LO>::invalid ();
2203 const LO lrow = this->
getRowMap ()->getLocalElement (globalRow);
2204 if (lrow == Teuchos::OrdinalTraits<LO>::invalid ()) {
2209 this->insertNonownedGlobalValues (globalRow, indices, values);
2216 return static_cast<LO
> (indices.size ());
2219 if (staticGraph_.is_null ()) {
2220 return Teuchos::OrdinalTraits<LO>::invalid ();
2224 if (indices.size () == 0) {
2225 return static_cast<LO
> (0);
2236 const size_type numInds = indices.size ();
2237 Array<LO> lclInds (numInds);
2238 for (size_type k = 0; k < numInds; ++k) {
2245 return graph.template transformLocalValues<ST, f_type> (rowInfo,
2252 return graph.template transformGlobalValues<ST, f_type> (rowInfo,
2263 return static_cast<LO
> (0);
2269 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2273 const Teuchos::ArrayView<const LocalOrdinal>& indices,
2274 const Teuchos::ArrayView<const Scalar>& values)
2276 using Teuchos::Array;
2277 using Teuchos::ArrayView;
2278 using Teuchos::av_reinterpret_cast;
2279 typedef LocalOrdinal LO;
2280 typedef GlobalOrdinal GO;
2282 typedef std::plus<Scalar> f_type;
2283 typedef typename ArrayView<GO>::size_type size_type;
2285 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
2288 return Teuchos::OrdinalTraits<LO>::invalid ();
2292 return Teuchos::OrdinalTraits<LO>::invalid ();
2294 else if (values.size () != indices.size ()) {
2296 return Teuchos::OrdinalTraits<LO>::invalid ();
2298 const bool isLocalRow =
getRowMap ()->isNodeLocalElement (localRow);
2302 return static_cast<LO
> (0);
2305 if (indices.size () == 0) {
2306 return static_cast<LO
> (0);
2309 RowInfo rowInfo = staticGraph_->getRowInfo (localRow);
2312 return staticGraph_->template transformLocalValues<ST, f_type> (rowInfo,
2325 const size_type numInds = indices.size ();
2332 Array<GO> gblInds (numInds);
2333 size_type numValid = 0;
2334 for (size_type k = 0; k < numInds; ++k) {
2337 if (gid != Teuchos::OrdinalTraits<GO>::invalid ()) {
2341 const LO numXformed =
2342 staticGraph_->template transformGlobalValues<ST, f_type> (rowInfo,
2347 if (static_cast<size_type> (numXformed) != numValid) {
2348 return Teuchos::OrdinalTraits<LO>::invalid ();
2360 return static_cast<LO
> (0);
2364 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2365 Teuchos::ArrayView<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type>
2369 using Kokkos::MemoryUnmanaged;
2371 using Teuchos::ArrayView;
2373 typedef std::pair<size_t, size_t> range_type;
2375 if (k_values1D_.dimension_0 () != 0 && rowinfo.allocSize > 0) {
2376 #ifdef HAVE_TPETRA_DEBUG 2377 TEUCHOS_TEST_FOR_EXCEPTION(
2378 rowinfo.offset1D + rowinfo.allocSize > k_values1D_.dimension_0 (),
2379 std::range_error,
"Tpetra::CrsMatrix::getView: Invalid access " 2380 "to 1-D storage of values." << std::endl <<
"rowinfo.offset1D (" <<
2381 rowinfo.offset1D <<
") + rowinfo.allocSize (" << rowinfo.allocSize <<
2382 ") > k_values1D_.dimension_0() (" << k_values1D_.dimension_0 () <<
").");
2383 #endif // HAVE_TPETRA_DEBUG 2384 range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
2385 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
2386 subview_type sv = Kokkos::subview (k_values1D_, range);
2388 const ST*
const sv_raw = (rowinfo.allocSize == 0) ? NULL : sv.ptr_on_device ();
2389 return ArrayView<const ST> (sv_raw, rowinfo.allocSize);
2391 else if (values2D_ != null) {
2392 return values2D_[rowinfo.localRow] ();
2395 return ArrayView<impl_scalar_type> ();
2399 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2400 Teuchos::ArrayView<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type>
2407 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2411 const Teuchos::ArrayView<LocalOrdinal>& indices,
2412 const Teuchos::ArrayView<Scalar>& values,
2413 size_t& numEntries)
const 2415 using Teuchos::ArrayView;
2416 using Teuchos::av_reinterpret_cast;
2417 typedef LocalOrdinal LO;
2418 typedef GlobalOrdinal GO;
2420 TEUCHOS_TEST_FOR_EXCEPTION(
2422 "Tpetra::CrsMatrix::getLocalRowCopy: The matrix is globally indexed and " 2423 "does not have a column Map yet. That means we don't have local indices " 2424 "for columns yet, so it doesn't make sense to call this method. If the " 2425 "matrix doesn't have a column Map yet, you should call fillComplete on " 2427 TEUCHOS_TEST_FOR_EXCEPTION(
2428 ! staticGraph_->hasRowInfo (), std::runtime_error,
2429 "Tpetra::CrsMatrix::getLocalRowCopy: The graph's row information was " 2430 "deleted at fillComplete().");
2432 if (! this->
getRowMap ()->isNodeLocalElement (localRow)) {
2438 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
2439 const size_t theNumEntries = rowinfo.numEntries;
2441 TEUCHOS_TEST_FOR_EXCEPTION(
2442 static_cast<size_t> (indices.size ()) < theNumEntries ||
2443 static_cast<size_t> (values.size ()) < theNumEntries,
2445 "Tpetra::CrsMatrix::getLocalRowCopy: The given row " << localRow
2446 <<
" has " << theNumEntries <<
" entries. One or both of the given " 2447 "ArrayViews are not long enough to store that many entries. indices " 2448 "can store " << indices.size() <<
" entries and values can store " 2449 << values.size() <<
" entries.");
2451 numEntries = theNumEntries;
2453 if (staticGraph_->isLocallyIndexed ()) {
2454 ArrayView<const LO> indrowview = staticGraph_->getLocalView (rowinfo);
2455 ArrayView<const Scalar> valrowview =
2456 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2457 std::copy (indrowview.begin (), indrowview.begin () + numEntries, indices.begin ());
2458 std::copy (valrowview.begin (), valrowview.begin () + numEntries, values.begin ());
2460 else if (staticGraph_->isGloballyIndexed ()) {
2461 ArrayView<const GO> indrowview = staticGraph_->getGlobalView (rowinfo);
2462 ArrayView<const Scalar> valrowview =
2463 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2464 std::copy (valrowview.begin (), valrowview.begin () + numEntries, values.begin ());
2467 for (
size_t j=0; j < numEntries; ++j) {
2476 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2480 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2481 const Teuchos::ArrayView<Scalar>& values,
2482 size_t& numEntries)
const 2484 using Teuchos::ArrayView;
2485 using Teuchos::av_reinterpret_cast;
2486 typedef LocalOrdinal LO;
2487 typedef GlobalOrdinal GO;
2489 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2490 const LocalOrdinal lrow =
getRowMap ()->getLocalElement (globalRow);
2491 if (lrow == OTL::invalid ()) {
2497 const RowInfo rowinfo = staticGraph_->getRowInfo (lrow);
2498 const size_t theNumEntries = rowinfo.numEntries;
2500 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2501 static_cast<size_t> (indices.size ()) < theNumEntries ||
2502 static_cast<size_t> (values.size ()) < theNumEntries,
2504 "The given row " << globalRow <<
", corresponding to local row " << lrow
2505 <<
", has " << theNumEntries <<
" entries. One or both of the given " 2506 "ArrayView input arguments are not long enough to store that many " 2507 "entries. indices.size() = " << indices.size() <<
", values.size() = " 2508 << values.size () <<
", but the number of entries in the row is " 2509 << theNumEntries <<
".");
2512 numEntries = theNumEntries;
2514 if (staticGraph_->isGloballyIndexed ()) {
2515 ArrayView<const GO> indrowview = staticGraph_->getGlobalView (rowinfo);
2516 ArrayView<const Scalar> valrowview =
2517 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2518 std::copy (indrowview.begin (), indrowview.begin () + numEntries, indices.begin ());
2519 std::copy (valrowview.begin (), valrowview.begin () + numEntries, values.begin ());
2521 else if (staticGraph_->isLocallyIndexed ()) {
2522 ArrayView<const LO> indrowview = staticGraph_->getLocalView(rowinfo);
2523 ArrayView<const Scalar> valrowview =
2524 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2525 std::copy (valrowview.begin (), valrowview.begin () + numEntries, values.begin ());
2526 for (
size_t j = 0; j < numEntries; ++j) {
2527 indices[j] =
getColMap ()->getGlobalElement (indrowview[j]);
2531 #ifdef HAVE_TPETRA_DEBUG 2533 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2534 staticGraph_->indicesAreAllocated (), std::logic_error,
2535 "Internal logic error. Please contact Tpetra team.");
2536 #endif // HAVE_TPETRA_DEBUG 2541 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2545 Teuchos::ArrayView<const LocalOrdinal>& indices,
2546 Teuchos::ArrayView<const Scalar>& values)
const 2548 using Teuchos::ArrayView;
2549 using Teuchos::av_reinterpret_cast;
2550 typedef LocalOrdinal LO;
2552 const char tfecfFuncName[] =
"getLocalRowView: ";
2553 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2555 "its indices as global indices, so you cannot get a view with local " 2556 "column indices. If the matrix has a column Map, you may call " 2557 "getLocalRowCopy() to get local column indices; otherwise, you may get " 2558 "a view with global column indices by calling getGlobalRowCopy().");
2559 indices = Teuchos::null;
2560 values = Teuchos::null;
2561 #ifdef HAVE_TPETRA_DEBUG 2562 size_t numEntries = 0;
2563 #endif // HAVE_TPETRA_DEBUG 2564 if (
getRowMap ()->isNodeLocalElement (localRow)) {
2565 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
2566 #ifdef HAVE_TPETRA_DEBUG 2567 numEntries = rowinfo.numEntries;
2568 #endif // HAVE_TPETRA_DEBUG 2569 if (rowinfo.numEntries > 0) {
2570 ArrayView<const LO> indTmp = staticGraph_->getLocalView (rowinfo);
2571 ArrayView<const Scalar> valTmp =
2572 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2573 indices = indTmp (0, rowinfo.numEntries);
2574 values = valTmp (0, rowinfo.numEntries);
2578 #ifdef HAVE_TPETRA_DEBUG 2579 const char suffix[] =
". This should never happen. Please report this " 2580 "bug to the Tpetra developers.";
2581 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2582 static_cast<size_t>(indices.size ()) != static_cast<size_t>(values.size ()), std::logic_error,
2583 "At the end of this method, for local row " << localRow <<
", " 2584 "indices.size() = " << indices.size () <<
" != values.size () = " 2585 << values.size () << suffix);
2586 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2587 static_cast<size_t>(indices.size ()) != static_cast<size_t>(numEntries), std::logic_error,
2588 "At the end of this method, for local row " << localRow <<
", " 2589 "indices.size() = " << indices.size () <<
" != numEntries = " 2590 << numEntries << suffix);
2592 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2593 numEntries != expectedNumEntries, std::logic_error,
2594 "At the end of this method, for local row " << localRow <<
", numEntries" 2595 " = " << numEntries <<
" != getNumEntriesInLocalRow(localRow)" 2596 " = "<< expectedNumEntries << suffix);
2597 #endif // HAVE_TPETRA_DEBUG 2600 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2604 Teuchos::ArrayView<const GlobalOrdinal>& indices,
2605 Teuchos::ArrayView<const Scalar>& values)
const 2607 using Teuchos::ArrayView;
2608 using Teuchos::av_reinterpret_cast;
2609 typedef GlobalOrdinal GO;
2610 const char tfecfFuncName[] =
"getGlobalRowView: ";
2612 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2614 "The matrix is locally indexed, so we cannot return a view of the row " 2615 "with global column indices. Use getGlobalRowCopy() instead.");
2616 indices = Teuchos::null;
2617 values = Teuchos::null;
2618 const LocalOrdinal lrow =
getRowMap ()->getLocalElement (globalRow);
2619 if (lrow != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2622 const RowInfo rowinfo = staticGraph_->getRowInfo(lrow);
2623 if (rowinfo.numEntries > 0) {
2624 ArrayView<const GO> indTmp = staticGraph_->getGlobalView (rowinfo);
2625 ArrayView<const Scalar> valTmp =
2626 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2627 indices = indTmp (0, rowinfo.numEntries);
2628 values = valTmp (0, rowinfo.numEntries);
2631 #ifdef HAVE_TPETRA_DEBUG 2632 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2634 indices.size () != values.size (),
2636 "Violated stated post-conditions. Please contact Tpetra team.");
2637 #endif // HAVE_TPETRA_DEBUG 2640 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2645 typedef LocalOrdinal LO;
2646 typedef Kokkos::SparseRowView<local_matrix_type> row_view_type;
2647 typedef typename Teuchos::Array<Scalar>::size_type size_type;
2648 const char tfecfFuncName[] =
"scale: ";
2651 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2653 "Fill must be active before you may call this method. " 2654 "Please call resumeFill() to make fill active.");
2656 const size_t nlrs = staticGraph_->getNodeNumRows ();
2657 const size_t numAlloc = staticGraph_->getNodeAllocationSize ();
2658 const size_t numEntries = staticGraph_->getNodeNumEntries ();
2659 if (! staticGraph_->indicesAreAllocated () || nlrs == 0 ||
2660 numAlloc == 0 || numEntries == 0) {
2666 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
2667 row_view_type row_i =
lclMatrix_.template row<typename row_view_type::size_type> (lclRow);
2668 for (LO k = 0; k < row_i.length; ++k) {
2670 row_i.value (k) *= theAlpha;
2675 for (
size_t row = 0; row < nlrs; ++row) {
2677 Teuchos::ArrayView<impl_scalar_type> rowVals = values2D_[row] ();
2678 for (size_type k = 0; k < numEnt; ++k) {
2679 rowVals[k] *= theAlpha;
2686 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2691 const char tfecfFuncName[] =
"setAllToScalar: ";
2693 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2695 "Fill must be active before you may call this method. " 2696 "Please call resumeFill() to make fill active.");
2702 const size_t nlrs = staticGraph_->getNodeNumRows(),
2703 numAlloc = staticGraph_->getNodeAllocationSize(),
2704 numEntries = staticGraph_->getNodeNumEntries();
2705 if (! staticGraph_->indicesAreAllocated () || numAlloc == 0 || numEntries == 0) {
2709 const ProfileType profType = staticGraph_->getProfileType ();
2714 typedef typename local_matrix_type::values_type values_type;
2715 Kokkos::Impl::ViewFill<values_type> (k_values1D_, theAlpha);
2718 for (
size_t row = 0; row < nlrs; ++row) {
2719 std::fill (values2D_[row].begin (), values2D_[row].end (), theAlpha);
2725 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2729 const typename local_graph_type::entries_type::non_const_type& columnIndices,
2730 const typename local_matrix_type::values_type& values)
2732 const char tfecfFuncName[] =
"setAllValues";
2733 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2734 columnIndices.size () != values.size (), std::runtime_error,
2735 ": columnIndices and values must have the same size. columnIndices.size() = " 2736 << columnIndices.size () <<
" != values.size() = " << values.size () <<
".");
2737 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2738 myGraph_.is_null (), std::runtime_error,
": myGraph_ must not be null.");
2741 myGraph_->setAllIndices (rowPointers, columnIndices);
2743 catch (std::exception &e) {
2744 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2745 true, std::runtime_error,
": Caught exception while calling myGraph_->" 2746 "setAllIndices(): " << e.what ());
2748 k_values1D_ = values;
2752 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2756 const Teuchos::ArrayRCP<LocalOrdinal>& columnIndices,
2757 const Teuchos::ArrayRCP<Scalar>& values)
2759 const char tfecfFuncName[] =
"setAllValues: ";
2760 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2761 columnIndices.size () != values.size (), std::runtime_error,
2762 "columnIndices.size() = " << columnIndices.size () <<
" != " 2763 "values.size() = " << values.size () <<
".");
2764 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2765 myGraph_.is_null (), std::runtime_error,
"myGraph_ must not be null.");
2768 myGraph_->setAllIndices (rowPointers, columnIndices);
2770 catch (std::exception &e) {
2771 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2772 true, std::runtime_error,
"Caught exception while calling myGraph_->" 2773 "setAllIndices(): " << e.what ());
2775 Teuchos::ArrayRCP<impl_scalar_type> vals =
2777 k_values1D_ = Kokkos::Compat::getKokkosViewDeepCopy<device_type> (vals ());
2781 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2786 using Teuchos::ArrayRCP;
2787 using Teuchos::ArrayView;
2788 const char tfecfFuncName[] =
"getLocalDiagOffsets";
2790 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2792 ": This method requires that the matrix have a column Map.");
2793 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2794 staticGraph_.is_null (), std::runtime_error,
2795 ": This method requires that the matrix have a graph.");
2801 if (static_cast<size_t> (offsets.size ()) != myNumRows) {
2802 offsets.resize (static_cast<size_t> (myNumRows));
2805 #ifdef HAVE_TPETRA_DEBUG 2806 bool allRowMapDiagEntriesInColMap =
true;
2807 bool allDiagEntriesFound =
true;
2808 #endif // HAVE_TPETRA_DEBUG 2810 for (
size_t r = 0; r < myNumRows; ++r) {
2811 const GlobalOrdinal rgid = rowMap.getGlobalElement (r);
2814 #ifdef HAVE_TPETRA_DEBUG 2815 if (rlid == Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2816 allRowMapDiagEntriesInColMap =
false;
2818 #endif // HAVE_TPETRA_DEBUG 2820 if (rlid != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2821 RowInfo rowinfo = staticGraph_->getRowInfo (r);
2822 if (rowinfo.numEntries > 0) {
2823 offsets[r] = staticGraph_->findLocalIndex (rowinfo, rlid);
2826 offsets[r] = Teuchos::OrdinalTraits<size_t>::invalid ();
2827 #ifdef HAVE_TPETRA_DEBUG 2828 allDiagEntriesFound =
false;
2829 #endif // HAVE_TPETRA_DEBUG 2834 #ifdef HAVE_TPETRA_DEBUG 2835 using Teuchos::reduceAll;
2838 const bool localSuccess =
2839 allRowMapDiagEntriesInColMap && allDiagEntriesFound;
2840 int localResults[3];
2841 localResults[0] = allRowMapDiagEntriesInColMap ? 1 : 0;
2842 localResults[1] = allDiagEntriesFound ? 1 : 0;
2846 ! localSuccess ?
getComm ()->getRank () :
getComm ()->getSize ();
2847 int globalResults[3];
2848 globalResults[0] = 0;
2849 globalResults[1] = 0;
2850 globalResults[2] = 0;
2851 reduceAll<int, int> (* (
getComm ()), Teuchos::REDUCE_MIN,
2852 3, localResults, globalResults);
2853 if (globalResults[0] == 0 || globalResults[1] == 0) {
2854 std::ostringstream os;
2856 globalResults[0] == 0 && globalResults[1] == 0;
2857 os <<
": At least one process (including Process " << globalResults[2]
2858 <<
") had the following issue" << (both ?
"s" :
"") <<
":" << endl;
2859 if (globalResults[0] == 0) {
2860 os <<
" - The column Map does not contain at least one diagonal entry " 2861 "of the matrix." << endl;
2863 if (globalResults[1] == 0) {
2864 os <<
" - There is a row on that / those process(es) that does not " 2865 "contain a diagonal entry." << endl;
2867 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::runtime_error, os.str());
2869 #endif // HAVE_TPETRA_DEBUG 2872 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2877 using Teuchos::ArrayRCP;
2878 using Teuchos::ArrayView;
2879 using Teuchos::av_reinterpret_cast;
2880 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
2882 typedef typename vec_type::dual_view_type dual_view_type;
2883 typedef typename dual_view_type::host_mirror_space::execution_space host_execution_space;
2885 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2887 "This method requires that the matrix have a column Map.");
2888 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2889 staticGraph_.is_null (), std::runtime_error,
2890 "This method requires that the matrix have a graph.");
2894 #ifdef HAVE_TPETRA_DEBUG 2897 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2898 ! dvec.
getMap ()->isCompatible (rowMap), std::runtime_error,
2899 ": The input Vector's Map must be compatible with the CrsMatrix's row " 2900 "Map. You may check this by using Map's isCompatible method: " 2901 "dvec.getMap ()->isCompatible (A.getRowMap ());");
2902 #endif // HAVE_TPETRA_DEBUG 2908 lclVec.template modify<host_execution_space> ();
2909 typedef typename dual_view_type::t_host host_view_type;
2910 host_view_type lclVecHost = lclVec.h_view;
2916 typename host_view_type::array_layout,
2917 typename host_view_type::device_type,
2918 typename host_view_type::memory_traits>
2920 host_view_1d_type lclVecHost1d =
2921 Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
2925 for (
size_t r = 0; r < myNumRows; ++r) {
2926 lclVecHost1d(r) = STS::zero ();
2927 const GlobalOrdinal rgid = rowMap.getGlobalElement (r);
2930 if (rlid != Teuchos::OrdinalTraits<LocalOrdinal>::invalid ()) {
2931 RowInfo rowinfo = staticGraph_->getRowInfo (r);
2932 if (rowinfo.numEntries > 0) {
2933 const size_t j = staticGraph_->findLocalIndex (rowinfo, rlid);
2934 if (j != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2938 ArrayView<const impl_scalar_type> view = this->
getView (rowinfo);
2939 lclVecHost1d(r) = view[j];
2944 lclVec.template sync<execution_space> ();
2947 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2951 const Teuchos::ArrayView<const size_t>& offsets)
const 2953 using Teuchos::ArrayRCP;
2954 using Teuchos::ArrayView;
2956 typedef typename vec_type::dual_view_type dual_view_type;
2957 typedef typename dual_view_type::host_mirror_space::execution_space host_execution_space;
2959 #ifdef HAVE_TPETRA_DEBUG 2960 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
2964 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2965 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
2966 "The input Vector's Map must be compatible with (in the sense of Map::" 2967 "isCompatible) the CrsMatrix's row Map.");
2968 #endif // HAVE_TPETRA_DEBUG 2974 lclVec.template modify<host_execution_space> ();
2975 typedef typename dual_view_type::t_host host_view_type;
2976 host_view_type lclVecHost = lclVec.h_view;
2982 typename host_view_type::array_layout,
2983 typename host_view_type::device_type,
2984 typename host_view_type::memory_traits>
2986 host_view_1d_type lclVecHost1d =
2987 Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
2991 for (
size_t i = 0; i < myNumRows; ++i) {
2992 lclVecHost1d(i) = STS::zero ();
2993 if (offsets[i] != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2994 ArrayView<const LocalOrdinal> ind;
2995 ArrayView<const Scalar> val;
3000 lclVecHost1d(i) =
static_cast<impl_scalar_type
> (val[offsets[i]]);
3003 lclVec.template sync<execution_space> ();
3007 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3012 using Teuchos::ArrayRCP;
3013 using Teuchos::ArrayView;
3014 using Teuchos::null;
3017 using Teuchos::rcpFromRef;
3019 const char tfecfFuncName[] =
"leftScale";
3023 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3025 ": matrix must be fill complete.");
3026 RCP<const vec_type> xp;
3034 RCP<vec_type> tempVec = rcp (
new vec_type (
getRowMap ()));
3039 xp = rcpFromRef (x);
3043 xp = rcpFromRef (x);
3046 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::invalid_argument,
": The " 3047 "input scaling vector x's Map must be the same as either the row Map or " 3048 "the range Map of the CrsMatrix.");
3050 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
3051 ArrayView<impl_scalar_type> rowValues = null;
3054 for (
size_t i = 0; i < lclNumRows; ++i) {
3055 const RowInfo rowinfo = staticGraph_->getRowInfo (static_cast<LocalOrdinal> (i));
3058 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
3059 rowValues[j] *= scaleValue;
3064 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3069 using Teuchos::ArrayRCP;
3070 using Teuchos::ArrayView;
3071 using Teuchos::null;
3074 using Teuchos::rcpFromRef;
3076 const char tfecfFuncName[] =
"rightScale: ";
3080 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3081 !
isFillComplete (), std::runtime_error,
"Matrix must be fill complete.");
3082 RCP<const vec_type> xp;
3088 RCP<vec_type> tempVec = rcp (
new vec_type (
getColMap ()));
3093 xp = rcpFromRef (x);
3097 xp = rcpFromRef (x);
3099 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3100 true, std::runtime_error,
"The vector x must have the same Map as " 3101 "either the row Map or the range Map.");
3104 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
3105 ArrayView<impl_scalar_type> rowValues = null;
3108 for (
size_t i = 0; i < lclNumRows; ++i) {
3109 const RowInfo rowinfo = staticGraph_->getRowInfo (static_cast<LocalOrdinal> (i));
3111 ArrayView<const LocalOrdinal> colInds;
3112 getCrsGraph ()->getLocalRowView (static_cast<LocalOrdinal> (i), colInds);
3113 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
3119 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3124 using Teuchos::outArg;
3125 using Teuchos::REDUCE_SUM;
3126 using Teuchos::reduceAll;
3127 typedef typename Teuchos::ArrayRCP<const impl_scalar_type>::size_type size_type;
3135 if (frobNorm == -STM::one ()) {
3141 const size_type numEntries =
3143 for (size_type k = 0; k < numEntries; ++k) {
3149 const mag_type val_abs = STS::abs (val);
3150 mySum += val_abs * val_abs;
3155 for (
size_t r = 0; r < numRows; ++r) {
3156 RowInfo rowInfo = myGraph_->getRowInfo (r);
3157 const size_type numEntries =
3158 static_cast<size_type
> (rowInfo.numEntries);
3159 ArrayView<const impl_scalar_type> A_r =
3160 this->
getView (rowInfo).view (0, numEntries);
3161 for (size_type k = 0; k < numEntries; ++k) {
3163 const mag_type val_abs = STS::abs (val);
3164 mySum += val_abs * val_abs;
3170 reduceAll<int, mag_type> (* (
getComm ()), REDUCE_SUM,
3171 mySum, outArg (totalSum));
3172 frobNorm = STM::sqrt (totalSum);
3183 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3188 const char tfecfFuncName[] =
"replaceColMap: ";
3192 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3193 myGraph_.is_null (), std::runtime_error,
3194 "This method does not work if the matrix has a const graph. The whole " 3195 "idea of a const graph is that you are not allowed to change it, but " 3196 "this method necessarily must modify the graph, since the graph owns " 3197 "the matrix's column Map.");
3198 myGraph_->replaceColMap (newColMap);
3201 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3205 const Teuchos::RCP<const map_type>& newColMap,
3206 const Teuchos::RCP<const import_type>& newImport,
3207 const bool sortEachRow)
3209 const char tfecfFuncName[] =
"reindexColumns: ";
3210 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3211 graph == NULL && myGraph_.is_null (), std::invalid_argument,
3212 "The input graph is NULL, but the matrix does not own its graph.");
3215 const bool sortGraph =
false;
3217 if (sortEachRow && theGraph.isLocallyIndexed () && ! theGraph.isSorted ()) {
3221 const size_t lclNumRows = theGraph.getNodeNumRows ();
3222 for (
size_t row = 0; row < lclNumRows; ++row) {
3223 RowInfo rowInfo = theGraph.getRowInfo (row);
3224 Teuchos::ArrayView<impl_scalar_type> rv = this->
getViewNonConst (rowInfo);
3225 theGraph.template sortRowIndicesAndValues<impl_scalar_type> (rowInfo, rv);
3227 theGraph.indicesAreSorted_ =
true;
3231 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3235 Teuchos::RCP<const import_type>& newImporter)
3237 const char tfecfFuncName[] =
"replaceDomainMapAndImporter: ";
3238 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3239 myGraph_.is_null (), std::runtime_error,
3240 "This method does not work if the matrix has a const graph. The whole " 3241 "idea of a const graph is that you are not allowed to change it, but this" 3242 " method necessarily must modify the graph, since the graph owns the " 3243 "matrix's domain Map and Import objects.");
3244 myGraph_->replaceDomainMapAndImporter (newDomainMap, newImporter);
3247 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3251 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
3252 const Teuchos::ArrayView<const Scalar>& values)
3254 using Teuchos::Array;
3255 typedef GlobalOrdinal GO;
3256 typedef typename Array<GO>::size_type size_type;
3258 const size_type numToInsert = indices.size ();
3261 std::pair<Array<GO>, Array<Scalar> >& curRow =
nonlocals_[globalRow];
3262 Array<GO>& curRowInds = curRow.first;
3263 Array<Scalar>& curRowVals = curRow.second;
3264 const size_type newCapacity = curRowInds.size () + numToInsert;
3265 curRowInds.reserve (newCapacity);
3266 curRowVals.reserve (newCapacity);
3267 for (size_type k = 0; k < numToInsert; ++k) {
3268 curRowInds.push_back (indices[k]);
3269 curRowVals.push_back (values[k]);
3273 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3278 using Teuchos::arcp;
3279 using Teuchos::Array;
3280 using Teuchos::ArrayRCP;
3281 using Teuchos::ArrayView;
3282 using Teuchos::CommRequest;
3283 using Teuchos::gatherAll;
3284 using Teuchos::isend;
3285 using Teuchos::ireceive;
3286 using Teuchos::null;
3287 using Teuchos::outArg;
3289 using Teuchos::rcpFromRef;
3290 using Teuchos::REDUCE_MAX;
3291 using Teuchos::reduceAll;
3292 using Teuchos::SerialDenseMatrix;
3293 using Teuchos::tuple;
3294 using Teuchos::waitAll;
3295 using std::make_pair;
3297 typedef GlobalOrdinal GO;
3298 typedef typename Array<GO>::size_type size_type;
3301 typedef std::map<GO, pair<Array<GO>, Array<Scalar> > > nonlocals_map_type;
3302 typedef typename nonlocals_map_type::const_iterator nonlocals_iter_type;
3304 const char tfecfFuncName[] =
"globalAssemble";
3305 const Teuchos::Comm<int>& comm = * (
getComm ());
3306 const int numImages = comm.getSize ();
3307 const int myImageID = comm.getRank ();
3309 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3310 !
isFillActive (), std::runtime_error,
": requires that fill is active.");
3316 size_t MyNonlocals =
static_cast<size_t> (
nonlocals_.size ());
3317 size_t MaxGlobalNonlocals = 0;
3318 reduceAll<int, size_t> (comm, REDUCE_MAX, MyNonlocals,
3319 outArg (MaxGlobalNonlocals));
3320 if (MaxGlobalNonlocals == 0) {
3338 Array<pair<int,GlobalOrdinal> > IdsAndRows;
3339 std::map<GlobalOrdinal,int> NLR2Id;
3340 SerialDenseMatrix<int,char> globalNeighbors;
3341 Array<int> sendIDs, recvIDs;
3345 std::set<GlobalOrdinal> setOfRows;
3346 for (nonlocals_iter_type iter =
nonlocals_.begin ();
3348 setOfRows.insert (iter->first);
3351 Array<GlobalOrdinal> NLRs (setOfRows.size ());
3352 std::copy (setOfRows.begin (), setOfRows.end (), NLRs.begin ());
3355 Array<int> NLRIds (NLRs.size ());
3358 getRowMap ()->getRemoteIndexList (NLRs (), NLRIds ());
3361 reduceAll<int, int> (comm, REDUCE_MAX, lclerr, outArg (gblerr));
3362 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3363 gblerr, std::runtime_error,
": non-local entries correspond to " 3370 IdsAndRows.reserve (NLRs.size ());
3371 Array<char> localNeighbors (numImages, 0);
3372 typename Array<GO>::const_iterator nlr;
3373 typename Array<int>::const_iterator id;
3374 for (nlr = NLRs.begin (),
id = NLRIds.begin ();
3375 nlr != NLRs.end (); ++nlr, ++id) {
3377 localNeighbors[*id] = 1;
3378 IdsAndRows.push_back (make_pair (*
id, *nlr));
3380 for (
int j = 0; j < numImages; ++j) {
3381 if (localNeighbors[j]) {
3382 sendIDs.push_back (j);
3386 std::sort (IdsAndRows.begin (), IdsAndRows.end ());
3400 globalNeighbors.shapeUninitialized (numImages, numImages);
3401 gatherAll (comm, numImages, localNeighbors.getRawPtr (),
3402 numImages*numImages, globalNeighbors.values ());
3414 for (
int j=0; j<numImages; ++j) {
3415 if (globalNeighbors (myImageID, j)) {
3416 recvIDs.push_back (j);
3419 const size_t numRecvs = recvIDs.size ();
3424 Array<Details::CrsIJV<GlobalOrdinal, Scalar> > IJVSendBuffer;
3425 Array<size_t> sendSizes (sendIDs.size(), 0);
3426 size_t numSends = 0;
3427 for (
typename Array<pair<int, GlobalOrdinal> >::const_iterator IdAndRow = IdsAndRows.begin();
3428 IdAndRow != IdsAndRows.end(); ++IdAndRow)
3430 const int id = IdAndRow->first;
3431 const GO row = IdAndRow->second;
3434 if (sendIDs[numSends] !=
id) {
3436 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3437 sendIDs[numSends] !=
id, std::logic_error,
3438 ": internal logic error. Contact Tpetra team.");
3442 pair<Array<GO>, Array<Scalar> >& nonlocalsRow =
nonlocals_[row];
3443 ArrayView<const GO> nonlocalsRow_colInds = nonlocalsRow.first ();
3444 ArrayView<const Scalar> nonlocalsRow_values = nonlocalsRow.second ();
3445 const size_type numNonlocalsRow = nonlocalsRow_colInds.size ();
3447 for (size_type k = 0; k < numNonlocalsRow; ++k) {
3448 const Scalar val = nonlocalsRow_values[k];
3449 const GO col = nonlocalsRow_colInds[k];
3451 sendSizes[numSends]++;
3454 if (IdsAndRows.size () > 0) {
3457 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3458 static_cast<size_type> (numSends) != sendIDs.size(),
3459 std::logic_error,
": internal logic error. Contact Tpetra team.");
3469 Array<RCP<CommRequest<int> > > sendRequests;
3470 for (
size_t s = 0; s < numSends ; ++s) {
3472 sendRequests.push_back (isend<int, size_t> (comm, rcpFromRef (sendSizes[s]), sendIDs[s]));
3475 Array<RCP<CommRequest<int> > > recvRequests;
3476 Array<size_t> recvSizes (numRecvs);
3477 for (
size_t r = 0; r < numRecvs; ++r) {
3480 recvRequests.push_back (ireceive<int, size_t> (comm, rcpFromRef (recvSizes[r]), recvIDs[r]));
3483 if (! sendRequests.empty ()) {
3484 waitAll (comm, sendRequests ());
3486 if (! recvRequests.empty ()) {
3487 waitAll (comm, recvRequests ());
3490 sendRequests.clear ();
3491 recvRequests.clear ();
3497 Array<ArrayView<Details::CrsIJV<GO, Scalar> > > sendBuffers (numSends, null);
3500 for (
size_t s=0; s<numSends; ++s) {
3501 sendBuffers[s] = IJVSendBuffer (cur, sendSizes[s]);
3502 cur += sendSizes[s];
3506 for (
size_t s = 0; s < numSends; ++s) {
3509 ArrayRCP<Details::CrsIJV<GO, Scalar> > tmparcp =
3510 arcp (sendBuffers[s].getRawPtr (), 0, sendBuffers[s].size (),
false);
3515 size_t totalRecvSize = std::accumulate (recvSizes.begin (), recvSizes.end (), 0);
3516 Array<Details::CrsIJV<GO, Scalar> > IJVRecvBuffer (totalRecvSize);
3518 Array<ArrayView<Details::CrsIJV<GO, Scalar> > > recvBuffers (numRecvs, null);
3521 for (
size_t r = 0; r < numRecvs; ++r) {
3522 recvBuffers[r] = IJVRecvBuffer (cur, recvSizes[r]);
3523 cur += recvSizes[r];
3527 for (
size_t r = 0; r < numRecvs ; ++r) {
3530 ArrayRCP<Details::CrsIJV<GO, Scalar> > tmparcp =
3531 arcp (recvBuffers[r].getRawPtr (), 0, recvBuffers[r].size (),
false);
3532 recvRequests.push_back (ireceive (comm, tmparcp, recvIDs[r]));
3535 if (! sendRequests.empty ()) {
3536 waitAll (comm, sendRequests ());
3538 if (! recvRequests.empty ()) {
3539 waitAll (comm, recvRequests ());
3542 sendRequests.clear ();
3543 recvRequests.clear ();
3553 typedef typename Array<Details::CrsIJV<GO, Scalar> >::const_iterator ijv_iter_type;
3555 for (ijv_iter_type ijv = IJVRecvBuffer.begin ();
3556 ijv != IJVRecvBuffer.end (); ++ijv) {
3561 for (ijv_iter_type ijv = IJVRecvBuffer.begin ();
3562 ijv != IJVRecvBuffer.end (); ++ijv) {
3566 catch (std::runtime_error &e) {
3567 std::ostringstream outmsg;
3568 outmsg << e.what() << std::endl
3569 <<
"caught in globalAssemble() in " << __FILE__ <<
":" << __LINE__
3571 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, outmsg.str());
3579 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3585 myGraph_->resumeFill (params);
3591 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3605 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3620 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3625 TEUCHOS_TEST_FOR_EXCEPTION(
3626 getCrsGraph ().is_null (), std::logic_error,
"Tpetra::CrsMatrix::" 3627 "fillComplete(params): getCrsGraph() returns null. " 3628 "This should not happen at this point. " 3629 "Please report this bug to the Tpetra developers.");
3639 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3642 fillComplete (
const Teuchos::RCP<const map_type>& domainMap,
3643 const Teuchos::RCP<const map_type>& rangeMap,
3644 const Teuchos::RCP<Teuchos::ParameterList>& params)
3646 using Teuchos::ArrayRCP;
3649 const char tfecfFuncName[] =
"fillComplete";
3651 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3653 std::runtime_error,
": Matrix fill state must be active (isFillActive() " 3654 "must be true) before you may call fillComplete().");
3655 const int numProcs =
getComm ()->getSize ();
3663 bool assertNoNonlocalInserts =
false;
3666 bool sortGhosts =
true;
3668 if (! params.is_null ()) {
3669 assertNoNonlocalInserts = params->get (
"No Nonlocal Changes",
3670 assertNoNonlocalInserts);
3671 if (params->isParameter (
"sort column map ghost gids")) {
3672 sortGhosts = params->get (
"sort column map ghost gids", sortGhosts);
3674 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3675 sortGhosts = params->get (
"Sort column Map ghost GIDs", sortGhosts);
3680 const bool needGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3682 if (! myGraph_.is_null ()) {
3683 myGraph_->sortGhostsAssociatedWithEachProcessor_ = sortGhosts;
3697 if (needGlobalAssemble) {
3701 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3703 std::runtime_error,
": cannot have nonlocal entries on a serial run. " 3704 "An invalid entry (i.e., with row index not in the row Map) must have " 3705 "been submitted to the CrsMatrix.");
3726 const bool domainMapsMatch = staticGraph_->getDomainMap ()->isSameAs (*domainMap);
3727 const bool rangeMapsMatch = staticGraph_->getRangeMap ()->isSameAs (*rangeMap);
3729 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3730 ! domainMapsMatch, std::runtime_error,
3731 ": The CrsMatrix's domain Map does not match the graph's domain Map. " 3732 "The graph cannot be changed because it was given to the CrsMatrix " 3733 "constructor as const. You can fix this by passing in the graph's " 3734 "domain Map and range Map to the matrix's fillComplete call.");
3736 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3737 ! rangeMapsMatch, std::runtime_error,
3738 ": The CrsMatrix's range Map does not match the graph's range Map. " 3739 "The graph cannot be changed because it was given to the CrsMatrix " 3740 "constructor as const. You can fix this by passing in the graph's " 3741 "domain Map and range Map to the matrix's fillComplete call.");
3748 myGraph_->setDomainRangeMaps (domainMap, rangeMap);
3751 if (! myGraph_->hasColMap ()) {
3752 myGraph_->makeColMap ();
3757 myGraph_->makeIndicesLocal ();
3759 if (! myGraph_->isSorted ()) {
3762 if (! myGraph_->isMerged ()) {
3766 myGraph_->makeImportExport ();
3767 myGraph_->computeGlobalConstants ();
3768 myGraph_->fillComplete_ =
true;
3769 myGraph_->checkInternalState ();
3773 if (myGraph_.is_null ()) {
3794 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3798 const Teuchos::RCP<const map_type> & rangeMap,
3799 const Teuchos::RCP<const import_type>& importer,
3800 const Teuchos::RCP<const export_type>& exporter,
3801 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
3803 #ifdef HAVE_TPETRA_MMM_TIMINGS 3805 if(!params.is_null())
3806 label = params->get(
"Timer Label",label);
3807 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
3808 using Teuchos::TimeMonitor;
3809 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-Graph"))));
3812 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
3814 std::runtime_error,
"Matrix fill state must be active (isFillActive() " 3815 "must be true) before calling fillComplete().");
3816 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3817 myGraph_.is_null (), std::logic_error,
"myGraph_ is null. This is not allowed.");
3821 myGraph_->expertStaticFillComplete (domainMap, rangeMap, importer, exporter,params);
3823 #ifdef HAVE_TPETRA_MMM_TIMINGS 3824 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cGC"))));
3829 #ifdef HAVE_TPETRA_MMM_TIMINGS 3830 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-fLGAM"))));
3842 #ifdef HAVE_TPETRA_DEBUG 3843 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive(), std::logic_error,
3844 ": We're at the end of fillComplete(), but isFillActive() is true. " 3845 "Please report this bug to the Tpetra developers.");
3846 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete(), std::logic_error,
3847 ": We're at the end of fillComplete(), but isFillActive() is true. " 3848 "Please report this bug to the Tpetra developers.");
3849 #endif // HAVE_TPETRA_DEBUG 3851 #ifdef HAVE_TPETRA_MMM_TIMINGS 3852 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cIS"))));
3858 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3863 TEUCHOS_TEST_FOR_EXCEPTION(
3864 isStaticGraph (), std::runtime_error,
"Tpetra::CrsMatrix::sortEntries: " 3865 "Cannot sort with static graph.");
3866 if (! myGraph_->isSorted ()) {
3868 for (
size_t row = 0; row < lclNumRows; ++row) {
3869 RowInfo rowInfo = myGraph_->getRowInfo (row);
3870 Teuchos::ArrayView<impl_scalar_type> rv = this->
getViewNonConst (rowInfo);
3871 myGraph_->template sortRowIndicesAndValues<impl_scalar_type> (rowInfo, rv);
3874 myGraph_->indicesAreSorted_ =
true;
3878 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3883 TEUCHOS_TEST_FOR_EXCEPTION(
3885 "mergeRedundantEntries: Cannot merge with static graph.");
3886 if (! myGraph_->isMerged ()) {
3888 for (
size_t row = 0; row < lclNumRows; ++row) {
3889 RowInfo rowInfo = myGraph_->getRowInfo (row);
3890 Teuchos::ArrayView<impl_scalar_type> rv = this->
getViewNonConst (rowInfo);
3891 myGraph_->template mergeRowIndicesAndValues<impl_scalar_type> (rowInfo, rv);
3893 myGraph_->noRedundancies_ =
true;
3897 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3905 using Teuchos::null;
3908 using Teuchos::rcp_const_cast;
3909 using Teuchos::rcpFromRef;
3910 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
3911 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
3917 if (alpha == ZERO) {
3920 }
else if (beta != ONE) {
3934 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
3935 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
3941 const bool Y_is_overwritten = (beta ==
ZERO);
3952 if (Y_is_replicated && this->
getComm ()->getRank () > 0) {
3959 RCP<const MV> X_colMap;
3960 if (importer.is_null ()) {
3970 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
3975 X_colMap = rcpFromRef (X_in);
3986 X_colMapNonConst->doImport (X_in, *importer,
INSERT);
3987 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
3999 if (! exporter.is_null ()) {
4000 this->
template localMultiply<Scalar, Scalar> (*X_colMap, *Y_rowMap,
4007 if (Y_is_overwritten) {
4039 this->
template localMultiply<Scalar, Scalar> (*X_colMap,
4046 this->
template localMultiply<Scalar, Scalar> (*X_colMap, Y_in,
4056 if (Y_is_replicated) {
4061 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4066 const Teuchos::ETransp mode,
4070 using Teuchos::null;
4073 using Teuchos::rcp_const_cast;
4074 using Teuchos::rcpFromRef;
4075 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4078 if (alpha == ZERO) {
4101 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
4102 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
4108 const bool Y_is_overwritten = (beta ==
ZERO);
4109 if (Y_is_replicated && this->
getComm ()->getRank () > 0) {
4115 X = rcp (
new MV (X_in, Teuchos::Copy));
4117 X = rcpFromRef (X_in);
4121 if (importer != null) {
4129 if (exporter != null) {
4140 if (! exporter.is_null ()) {
4148 if (importer != null) {
4156 this->
template localMultiply<Scalar, Scalar> (*X, *
importMV_, mode,
4158 if (Y_is_overwritten) {
4175 MV Y (Y_in, Teuchos::Copy);
4176 this->
template localMultiply<Scalar, Scalar> (*X, Y, mode, alpha, beta);
4179 this->
template localMultiply<Scalar, Scalar> (*X, Y_in, mode, alpha, beta);
4186 if (Y_is_replicated) {
4191 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4196 Teuchos::ETransp mode,
4200 TEUCHOS_TEST_FOR_EXCEPTION(
4202 "Tpetra::CrsMatrix::apply(): Cannot call apply() until fillComplete() " 4203 "has been called.");
4205 if (mode == Teuchos::NO_TRANS) {
4213 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4220 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4226 const Scalar& dampingFactor,
4228 const int numSweeps)
const 4233 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4239 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
4240 const Scalar& dampingFactor,
4242 const int numSweeps)
const 4244 using Teuchos::null;
4247 using Teuchos::rcp_const_cast;
4248 using Teuchos::rcpFromRef;
4251 TEUCHOS_TEST_FOR_EXCEPTION(
4253 "Tpetra::CrsMatrix::gaussSeidel: cannot call this method until " 4254 "fillComplete() has been called.");
4255 TEUCHOS_TEST_FOR_EXCEPTION(
4257 std::invalid_argument,
4258 "Tpetra::CrsMatrix::gaussSeidel: The number of sweeps must be , " 4259 "nonnegative but you provided numSweeps = " << numSweeps <<
" < 0.");
4263 KokkosClassic::ESweepDirection localDirection;
4264 if (direction == Forward) {
4265 localDirection = KokkosClassic::Forward;
4267 else if (direction == Backward) {
4268 localDirection = KokkosClassic::Backward;
4270 else if (direction == Symmetric) {
4272 localDirection = KokkosClassic::Forward;
4275 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
4276 "Tpetra::CrsMatrix::gaussSeidel: The 'direction' enum does not have " 4277 "any of its valid values: Forward, Backward, or Symmetric.");
4280 if (numSweeps == 0) {
4287 RCP<const import_type> importer = this->
getGraph()->getImporter();
4288 RCP<const export_type> exporter = this->
getGraph()->getExporter();
4289 TEUCHOS_TEST_FOR_EXCEPTION(
4290 ! exporter.is_null (), std::runtime_error,
4291 "Tpetra's gaussSeidel implementation requires that the row, domain, " 4292 "and range Maps be the same. This cannot be the case, because the " 4293 "matrix has a nontrivial Export object.");
4296 RCP<const map_type> rangeMap = this->
getRangeMap ();
4297 RCP<const map_type> rowMap = this->
getGraph ()->getRowMap ();
4298 RCP<const map_type> colMap = this->
getGraph ()->getColMap ();
4300 #ifdef HAVE_TEUCHOS_DEBUG 4305 TEUCHOS_TEST_FOR_EXCEPTION(
4306 ! X.
getMap ()->isSameAs (*domainMap),
4308 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4309 "multivector X be in the domain Map of the matrix.");
4310 TEUCHOS_TEST_FOR_EXCEPTION(
4311 ! B.
getMap ()->isSameAs (*rangeMap),
4313 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4314 "B be in the range Map of the matrix.");
4315 TEUCHOS_TEST_FOR_EXCEPTION(
4316 ! D.
getMap ()->isSameAs (*rowMap),
4318 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4319 "D be in the row Map of the matrix.");
4320 TEUCHOS_TEST_FOR_EXCEPTION(
4321 ! rowMap->isSameAs (*rangeMap),
4323 "Tpetra::CrsMatrix::gaussSeidel requires that the row Map and the " 4324 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
4325 TEUCHOS_TEST_FOR_EXCEPTION(
4326 ! domainMap->isSameAs (*rangeMap),
4328 "Tpetra::CrsMatrix::gaussSeidel requires that the domain Map and " 4329 "the range Map of the matrix be the same.");
4335 #endif // HAVE_TEUCHOS_DEBUG 4345 B_in = rcpFromRef (B);
4354 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
4359 "gaussSeidel: The current implementation of the Gauss-Seidel kernel " 4360 "requires that X and B both have constant stride. Since B does not " 4361 "have constant stride, we had to make a copy. This is a limitation of " 4362 "the current implementation and not your fault, but we still report it " 4363 "as an efficiency warning for your information.");
4372 RCP<MV> X_domainMap;
4374 bool copiedInput =
false;
4376 if (importer.is_null ()) {
4378 X_domainMap = rcpFromRef (X);
4379 X_colMap = X_domainMap;
4380 copiedInput =
false;
4387 X_domainMap = X_colMap;
4392 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the " 4393 "Gauss-Seidel kernel requires that X and B both have constant " 4394 "stride. Since X does not have constant stride, we had to make a " 4395 "copy. This is a limitation of the current implementation and not " 4396 "your fault, but we still report it as an efficiency warning for " 4397 "your information.");
4402 X_domainMap = rcpFromRef (X);
4406 X_colMap = X_domainMap->offsetViewNonConst (colMap, 0);
4416 X_colMap->doImport (X, *importer,
INSERT);
4417 copiedInput =
false;
4425 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
4426 X_colMap->doImport (X, *importer,
INSERT);
4430 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the " 4431 "Gauss-Seidel kernel requires that X and B both have constant stride. " 4432 "Since X does not have constant stride, we had to make a copy. " 4433 "This is a limitation of the current implementation and not your fault, " 4434 "but we still report it as an efficiency warning for your information.");
4438 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
4439 if (! importer.is_null () && sweep > 0) {
4441 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4445 if (direction != Symmetric) {
4446 if (rowIndices.is_null ()) {
4447 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4452 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4459 const bool doImportBetweenDirections =
false;
4460 if (rowIndices.is_null ()) {
4461 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4463 KokkosClassic::Forward);
4468 if (doImportBetweenDirections) {
4470 if (! importer.is_null ()) {
4471 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4474 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4476 KokkosClassic::Backward);
4479 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4482 KokkosClassic::Forward);
4483 if (doImportBetweenDirections) {
4485 if (! importer.is_null ()) {
4486 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4489 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4492 KokkosClassic::Backward);
4502 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4508 const Scalar& dampingFactor,
4510 const int numSweeps,
4511 const bool zeroInitialGuess)
const 4514 numSweeps, zeroInitialGuess);
4517 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4523 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
4524 const Scalar& dampingFactor,
4526 const int numSweeps,
4527 const bool zeroInitialGuess)
const 4529 using Teuchos::null;
4532 using Teuchos::rcpFromRef;
4533 using Teuchos::rcp_const_cast;
4535 const char prefix[] =
"Tpetra::CrsMatrix::(reordered)gaussSeidelCopy: ";
4536 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4538 TEUCHOS_TEST_FOR_EXCEPTION(
4540 prefix <<
"The matrix is not fill complete.");
4541 TEUCHOS_TEST_FOR_EXCEPTION(
4542 numSweeps < 0, std::invalid_argument,
4543 prefix <<
"The number of sweeps must be nonnegative, " 4544 "but you provided numSweeps = " << numSweeps <<
" < 0.");
4548 KokkosClassic::ESweepDirection localDirection;
4549 if (direction == Forward) {
4550 localDirection = KokkosClassic::Forward;
4552 else if (direction == Backward) {
4553 localDirection = KokkosClassic::Backward;
4555 else if (direction == Symmetric) {
4557 localDirection = KokkosClassic::Forward;
4560 TEUCHOS_TEST_FOR_EXCEPTION(
4561 true, std::invalid_argument,
4562 prefix <<
"The 'direction' enum does not have any of its valid " 4563 "values: Forward, Backward, or Symmetric.");
4566 if (numSweeps == 0) {
4570 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
4571 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
4572 TEUCHOS_TEST_FOR_EXCEPTION(
4573 ! exporter.is_null (), std::runtime_error,
4574 "This method's implementation currently requires that the matrix's row, " 4575 "domain, and range Maps be the same. This cannot be the case, because " 4576 "the matrix has a nontrivial Export object.");
4579 RCP<const map_type> rangeMap = this->
getRangeMap ();
4580 RCP<const map_type> rowMap = this->
getGraph ()->getRowMap ();
4581 RCP<const map_type> colMap = this->
getGraph ()->getColMap ();
4583 #ifdef HAVE_TEUCHOS_DEBUG 4588 TEUCHOS_TEST_FOR_EXCEPTION(
4589 ! X.
getMap ()->isSameAs (*domainMap), std::runtime_error,
4590 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 4591 "multivector X be in the domain Map of the matrix.");
4592 TEUCHOS_TEST_FOR_EXCEPTION(
4593 ! B.
getMap ()->isSameAs (*rangeMap), std::runtime_error,
4594 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 4595 "B be in the range Map of the matrix.");
4596 TEUCHOS_TEST_FOR_EXCEPTION(
4597 ! D.
getMap ()->isSameAs (*rowMap), std::runtime_error,
4598 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 4599 "D be in the row Map of the matrix.");
4600 TEUCHOS_TEST_FOR_EXCEPTION(
4601 ! rowMap->isSameAs (*rangeMap), std::runtime_error,
4602 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the row Map and the " 4603 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
4604 TEUCHOS_TEST_FOR_EXCEPTION(
4605 ! domainMap->isSameAs (*rangeMap), std::runtime_error,
4606 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the domain Map and " 4607 "the range Map of the matrix be the same.");
4613 #endif // HAVE_TEUCHOS_DEBUG 4624 RCP<MV> X_domainMap;
4625 bool copyBackOutput =
false;
4626 if (importer.is_null ()) {
4628 X_colMap = rcpFromRef (X);
4629 X_domainMap = rcpFromRef (X);
4635 if (zeroInitialGuess) {
4636 X_colMap->putScalar (ZERO);
4648 X_domainMap = X_colMap;
4649 if (! zeroInitialGuess) {
4652 }
catch (std::exception& e) {
4653 std::ostringstream os;
4654 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: " 4655 "deep_copy(*X_domainMap, X) threw an exception: " 4656 << e.what () <<
".";
4657 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
4660 copyBackOutput =
true;
4664 "gaussSeidelCopy: The current implementation of the Gauss-Seidel " 4665 "kernel requires that X and B both have constant stride. Since X " 4666 "does not have constant stride, we had to make a copy. This is a " 4667 "limitation of the current implementation and not your fault, but we " 4668 "still report it as an efficiency warning for your information.");
4673 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
4675 #ifdef HAVE_TPETRA_DEBUG 4679 if (X_colMap->getLocalLength () != 0 && X_domainMap->getLocalLength ()) {
4680 TEUCHOS_TEST_FOR_EXCEPTION(
4681 X_colMap_view.h_view.ptr_on_device () != X_domainMap_view.h_view.ptr_on_device (),
4682 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: " 4683 "Pointer to start of column Map view of X is not equal to pointer to " 4684 "start of (domain Map view of) X. This may mean that " 4685 "Tpetra::MultiVector::offsetViewNonConst is broken. " 4686 "Please report this bug to the Tpetra developers.");
4689 TEUCHOS_TEST_FOR_EXCEPTION(
4690 X_colMap_view.dimension_0 () < X_domainMap_view.dimension_0 () ||
4691 X_colMap->getLocalLength () < X_domainMap->getLocalLength (),
4692 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: " 4693 "X_colMap has fewer local rows than X_domainMap. " 4694 "X_colMap_view.dimension_0() = " << X_colMap_view.dimension_0 ()
4695 <<
", X_domainMap_view.dimension_0() = " 4696 << X_domainMap_view.dimension_0 ()
4697 <<
", X_colMap->getLocalLength() = " << X_colMap->getLocalLength ()
4698 <<
", and X_domainMap->getLocalLength() = " 4699 << X_domainMap->getLocalLength ()
4700 <<
". This means that Tpetra::MultiVector::offsetViewNonConst " 4701 "is broken. Please report this bug to the Tpetra developers.");
4703 TEUCHOS_TEST_FOR_EXCEPTION(
4704 X_colMap->getNumVectors () != X_domainMap->getNumVectors (),
4705 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: " 4706 "X_colMap has a different number of columns than X_domainMap. " 4707 "X_colMap->getNumVectors() = " << X_colMap->getNumVectors ()
4708 <<
" != X_domainMap->getNumVectors() = " 4709 << X_domainMap->getNumVectors ()
4710 <<
". This means that Tpetra::MultiVector::offsetViewNonConst " 4711 "is broken. Please report this bug to the Tpetra developers.");
4712 #endif // HAVE_TPETRA_DEBUG 4714 if (zeroInitialGuess) {
4716 X_colMap->putScalar (ZERO);
4726 X_colMap->doImport (X, *importer,
INSERT);
4728 copyBackOutput =
true;
4736 B_in = rcpFromRef (B);
4745 }
catch (std::exception& e) {
4746 std::ostringstream os;
4747 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: " 4748 "deep_copy(*B_in_nonconst, B) threw an exception: " 4749 << e.what () <<
".";
4750 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
4752 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
4757 "gaussSeidelCopy: The current implementation requires that B have " 4758 "constant stride. Since B does not have constant stride, we had to " 4759 "copy it into a separate constant-stride multivector. This is a " 4760 "limitation of the current implementation and not your fault, but we " 4761 "still report it as an efficiency warning for your information.");
4764 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
4765 if (! importer.is_null () && sweep > 0) {
4768 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4772 if (direction != Symmetric) {
4773 if (rowIndices.is_null ()) {
4774 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4779 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4786 if (rowIndices.is_null ()) {
4787 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4789 KokkosClassic::Forward);
4795 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4797 KokkosClassic::Backward);
4800 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4803 KokkosClassic::Forward);
4804 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4807 KokkosClassic::Backward);
4813 if (copyBackOutput) {
4816 }
catch (std::exception& e) {
4817 TEUCHOS_TEST_FOR_EXCEPTION(
4818 true, std::runtime_error, prefix <<
"deep_copy(X, *X_domainMap) " 4819 "threw an exception: " << e.what ());
4824 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4826 Teuchos::RCP<CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node, classic> >
4830 using Teuchos::ArrayRCP;
4834 typedef typename out_mat_type::local_matrix_type out_lcl_mat_type;
4835 typedef typename out_lcl_mat_type::values_type out_vals_type;
4836 typedef ArrayRCP<size_t>::size_type size_type;
4837 const char tfecfFuncName[] =
"convert";
4839 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4840 !
isFillComplete (), std::runtime_error,
"This matrix (the source of " 4841 "the conversion) is not fill complete. You must first call " 4842 "fillComplete() (possibly with the domain and range Map) without an " 4843 "intervening call to resumeFill(), before you may call this method.");
4850 RCP<out_mat_type> newmat;
4854 newmat = rcp (
new out_mat_type (this->
getCrsGraph ()));
4858 const size_type numVals =
4859 static_cast<size_type
> (this->
lclMatrix_.values.dimension_0 ());
4865 out_vals_type newVals1D (
"Tpetra::CrsMatrix::val", numVals);
4866 for (size_type k = 0; k < numVals; ++k) {
4867 newVals1D(k) =
static_cast<T
> (this->k_values1D_(k));
4869 newmat->lclMatrix_ =
4870 out_lcl_mat_type (
"Tpetra::CrsMatrix::lclMatrix_",
4873 newmat->k_values1D_ = newVals1D;
4893 ArrayRCP<const size_t> ptr;
4894 ArrayRCP<const LocalOrdinal> ind;
4895 ArrayRCP<const Scalar> oldVal;
4896 this->getAllValues (ptr, ind, oldVal);
4898 RCP<const map_type> rowMap = this->
getRowMap ();
4899 RCP<const map_type> colMap = this->
getColMap ();
4903 const size_type numLocalRows =
4904 static_cast<size_type
> (rowMap->getNodeNumElements ());
4905 ArrayRCP<size_t> numEntriesPerRow (numLocalRows);
4906 for (size_type localRow = 0; localRow < numLocalRows; ++localRow) {
4907 numEntriesPerRow[localRow] =
4911 newmat = rcp (
new out_mat_type (rowMap, colMap, numEntriesPerRow,
4915 const size_type numVals = this->
lclMatrix_.values.dimension_0 ();
4916 ArrayRCP<T> newVals1D (numVals);
4918 for (size_type k = 0; k < numVals; ++k) {
4919 newVals1D[k] =
static_cast<T
> (this->k_values1D_(k));
4926 ArrayRCP<size_t> newPtr (ptr.size ());
4927 std::copy (ptr.begin (), ptr.end (), newPtr.begin ());
4928 ArrayRCP<LocalOrdinal> newInd (ind.size ());
4929 std::copy (ind.begin (), ind.end (), newInd.begin ());
4930 newmat->setAllValues (newPtr, newInd, newVals1D);
4936 RCP<const map_type> rangeMap = this->
getRangeMap ();
4937 RCP<const import_type> importer = this->
getCrsGraph ()->getImporter ();
4938 RCP<const export_type> exporter = this->
getCrsGraph ()->getExporter ();
4939 newmat->expertStaticFillComplete (domainMap, rangeMap, importer, exporter);
4946 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4951 #ifdef HAVE_TPETRA_DEBUG 4952 const char tfecfFuncName[] =
"checkInternalState: ";
4953 const char err[] =
"Internal state is not consistent. " 4954 "Please report this bug to the Tpetra developers.";
4958 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4959 staticGraph_.is_null (),
4960 std::logic_error, err);
4964 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4965 ! myGraph_.is_null () && myGraph_ != staticGraph_,
4966 std::logic_error, err);
4968 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4970 std::logic_error, err <<
" Specifically, the matrix is fill complete, " 4971 "but its graph is NOT fill complete.");
4973 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4975 std::logic_error, err);
4977 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4979 std::logic_error, err);
4981 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4983 std::logic_error, err);
4986 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4987 staticGraph_->indicesAreAllocated () &&
4988 staticGraph_->getNodeAllocationSize() > 0 &&
4989 staticGraph_->getNodeNumRows() > 0
4990 && values2D_.is_null () &&
4991 k_values1D_.dimension_0 () == 0,
4992 std::logic_error, err);
4994 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4995 k_values1D_.dimension_0 () > 0 && values2D_ != null,
4996 std::logic_error, err <<
" Specifically, k_values1D_ is allocated (has " 4997 "size " << k_values1D_.dimension_0 () <<
" > 0) and values2D_ is also " 4998 "allocated. CrsMatrix is not suppose to have both a 1-D and a 2-D " 4999 "allocation at the same time.");
5003 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5008 std::ostringstream os;
5010 os <<
"Tpetra::CrsMatrix (Kokkos refactor): {";
5011 if (this->getObjectLabel () !=
"") {
5012 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5015 os <<
"isFillComplete: true" 5022 os <<
"isFillComplete: false" 5029 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5033 const Teuchos::EVerbosityLevel verbLevel)
const 5037 using Teuchos::Comm;
5039 using Teuchos::TypeNameTraits;
5040 using Teuchos::VERB_DEFAULT;
5041 using Teuchos::VERB_NONE;
5042 using Teuchos::VERB_LOW;
5043 using Teuchos::VERB_MEDIUM;
5044 using Teuchos::VERB_HIGH;
5045 using Teuchos::VERB_EXTREME;
5047 const Teuchos::EVerbosityLevel vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
5049 if (vl == VERB_NONE) {
5053 Teuchos::OSTab tab0 (out);
5055 RCP<const Comm<int> > comm = this->
getComm();
5056 const int myRank = comm->getRank();
5057 const int numProcs = comm->getSize();
5062 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5072 out <<
"Tpetra::CrsMatrix (Kokkos refactor):" << endl;
5074 Teuchos::OSTab tab1 (out);
5077 if (this->getObjectLabel () !=
"") {
5078 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5081 out <<
"Template parameters:" << endl;
5082 Teuchos::OSTab tab2 (out);
5083 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
5084 <<
"LocalOrdinal: " << TypeNameTraits<LocalOrdinal>::name () << endl
5085 <<
"GlobalOrdinal: " << TypeNameTraits<GlobalOrdinal>::name () << endl
5086 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
5089 out <<
"isFillComplete: true" << endl
5094 << endl <<
"Global max number of entries in a row: " 5098 out <<
"isFillComplete: false" << endl
5104 if (vl < VERB_MEDIUM) {
5110 out << endl <<
"Row Map:" << endl;
5114 out <<
"null" << endl;
5126 out <<
"Column Map: ";
5130 out <<
"null" << endl;
5134 out <<
"same as row Map" << endl;
5145 out <<
"Domain Map: ";
5149 out <<
"null" << endl;
5153 out <<
"same as row Map" << endl;
5157 out <<
"same as column Map" << endl;
5168 out <<
"Range Map: ";
5172 out <<
"null" << endl;
5176 out <<
"same as domain Map" << endl;
5180 out <<
"same as row Map" << endl;
5190 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5191 if (myRank == curRank) {
5192 out <<
"Process rank: " << curRank << endl;
5193 Teuchos::OSTab tab2 (out);
5194 if (! staticGraph_->indicesAreAllocated ()) {
5195 out <<
"Graph indices not allocated" << endl;
5198 out <<
"Number of allocated entries: " 5199 << staticGraph_->getNodeAllocationSize () << endl;
5214 if (vl < VERB_HIGH) {
5219 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5220 if (myRank == curRank) {
5221 out << std::setw(width) <<
"Proc Rank" 5222 << std::setw(width) <<
"Global Row" 5223 << std::setw(width) <<
"Num Entries";
5224 if (vl == VERB_EXTREME) {
5225 out << std::setw(width) <<
"(Index,Value)";
5230 GlobalOrdinal gid =
getRowMap()->getGlobalElement(r);
5231 out << std::setw(width) << myRank
5232 << std::setw(width) << gid
5233 << std::setw(width) << nE;
5234 if (vl == VERB_EXTREME) {
5236 ArrayView<const GlobalOrdinal> rowinds;
5237 ArrayView<const Scalar> rowvals;
5239 for (
size_t j = 0; j < nE; ++j) {
5240 out <<
" (" << rowinds[j]
5241 <<
", " << rowvals[j]
5246 ArrayView<const LocalOrdinal> rowinds;
5247 ArrayView<const Scalar> rowvals;
5249 for (
size_t j=0; j < nE; ++j) {
5250 out <<
" (" <<
getColMap()->getGlobalElement(rowinds[j])
5251 <<
", " << rowvals[j]
5267 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5280 const row_matrix_type* srcRowMat =
5281 dynamic_cast<const row_matrix_type*
> (&source);
5282 return (srcRowMat != NULL);
5285 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5290 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
5291 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs)
5293 using Teuchos::Array;
5294 using Teuchos::ArrayView;
5295 typedef LocalOrdinal LO;
5296 typedef GlobalOrdinal GO;
5299 const char tfecfFuncName[] =
"copyAndPermute: ";
5301 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5302 permuteToLIDs.size() != permuteFromLIDs.size(),
5303 std::invalid_argument,
"permuteToLIDs.size() = " << permuteToLIDs.size()
5304 <<
"!= permuteFromLIDs.size() = " << permuteFromLIDs.size() <<
".");
5309 const row_matrix_type& srcMat =
dynamic_cast<const row_matrix_type&
> (source);
5316 const map_type& srcRowMap = * (srcMat.getRowMap ());
5318 Array<Scalar> rowVals;
5319 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
5320 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
5325 const GO targetGID = sourceGID;
5328 ArrayView<const GO> rowIndsConstView;
5329 ArrayView<const Scalar> rowValsConstView;
5331 if (sourceIsLocallyIndexed) {
5332 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
5333 if (rowLength > static_cast<size_t> (rowInds.size())) {
5334 rowInds.resize (rowLength);
5335 rowVals.resize (rowLength);
5339 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
5340 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
5345 size_t checkRowLength = 0;
5346 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
5348 #ifdef HAVE_TPETRA_DEBUG 5349 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
5350 std::logic_error,
"For global row index " << sourceGID <<
", the source" 5351 " matrix's getNumEntriesInGlobalRow() method returns a row length of " 5352 << rowLength <<
", but the getGlobalRowCopy() method reports that " 5353 "the row length is " << checkRowLength <<
". Please report this bug " 5354 "to the Tpetra developers.");
5355 #endif // HAVE_TPETRA_DEBUG 5357 rowIndsConstView = rowIndsView.view (0, rowLength);
5358 rowValsConstView = rowValsView.view (0, rowLength);
5361 srcMat.getGlobalRowView (sourceGID, rowIndsConstView, rowValsConstView);
5368 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
REPLACE);
5374 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
INSERT);
5382 const size_t numPermuteToLIDs =
static_cast<size_t> (permuteToLIDs.size ());
5383 for (
size_t p = 0; p < numPermuteToLIDs; ++p) {
5388 ArrayView<const GO> rowIndsConstView;
5389 ArrayView<const Scalar> rowValsConstView;
5391 if (sourceIsLocallyIndexed) {
5392 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
5393 if (rowLength > static_cast<size_t> (rowInds.size ())) {
5394 rowInds.resize (rowLength);
5395 rowVals.resize (rowLength);
5399 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
5400 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
5405 size_t checkRowLength = 0;
5406 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
5408 #ifdef HAVE_TPETRA_DEBUG 5409 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
5410 std::logic_error,
"For the source matrix's global row index " 5411 << sourceGID <<
", the source matrix's getNumEntriesInGlobalRow() " 5412 "method returns a row length of " << rowLength <<
", but the " 5413 "getGlobalRowCopy() method reports that the row length is " 5414 << checkRowLength <<
". Please report this bug to the Tpetra " 5416 #endif // HAVE_TPETRA_DEBUG 5418 rowIndsConstView = rowIndsView.view (0, rowLength);
5419 rowValsConstView = rowValsView.view (0, rowLength);
5422 srcMat.getGlobalRowView (sourceGID, rowIndsConstView, rowValsConstView);
5427 this->combineGlobalValues (targetGID, rowIndsConstView,
5431 this->combineGlobalValues (targetGID, rowIndsConstView,
5432 rowValsConstView,
INSERT);
5437 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5441 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5442 Teuchos::Array<char>& exports,
5443 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5444 size_t& constantNumPackets,
5447 using Teuchos::Array;
5448 using Teuchos::ArrayView;
5449 using Teuchos::av_reinterpret_cast;
5450 typedef LocalOrdinal LO;
5451 typedef GlobalOrdinal GO;
5452 const char tfecfFuncName[] =
"packAndPrepare: ";
5475 const row_matrix_type* srcRowMat =
5476 dynamic_cast<const row_matrix_type*
> (&source);
5477 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5478 srcRowMat == NULL, std::invalid_argument,
5479 "The source object of the Import or Export operation is neither a " 5480 "CrsMatrix (with the same template parameters as the target object), " 5481 "nor a RowMatrix (with the same first four template parameters as the " 5483 #ifdef HAVE_TPETRA_DEBUG 5485 using Teuchos::reduceAll;
5486 std::ostringstream msg;
5489 srcRowMat->pack (exportLIDs, exports, numPacketsPerLID,
5490 constantNumPackets, distor);
5491 }
catch (std::exception& e) {
5496 const Teuchos::Comm<int>& comm = * (this->
getComm ());
5497 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
5498 lclBad, Teuchos::outArg (gblBad));
5500 const int myRank = comm.getRank ();
5501 const int numProcs = comm.getSize ();
5502 for (
int r = 0; r < numProcs; ++r) {
5503 if (r == myRank && lclBad != 0) {
5504 std::ostringstream os;
5505 os <<
"Proc " << myRank <<
": " << msg.str () << std::endl;
5506 std::cerr << os.str ();
5512 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5513 true, std::logic_error,
"pack() threw an exception on one or " 5514 "more participating processes.");
5518 srcRowMat->pack (exportLIDs, exports, numPacketsPerLID,
5519 constantNumPackets, distor);
5520 #endif // HAVE_TPETRA_DEBUG 5523 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5526 packRow (
char*
const numEntOut,
5529 const size_t numEnt,
5530 const LocalOrdinal lclRow)
const 5532 using Teuchos::ArrayView;
5533 typedef LocalOrdinal LO;
5534 typedef GlobalOrdinal GO;
5536 const LO numEntLO =
static_cast<LO
> (numEnt);
5537 memcpy (numEntOut, &numEntLO,
sizeof (LO));
5542 ArrayView<const LO> indIn;
5543 ArrayView<const Scalar> valIn;
5548 for (
size_t k = 0; k < numEnt; ++k) {
5550 memcpy (indOut + k *
sizeof (GO), &gblIndIn,
sizeof (GO));
5552 memcpy (valOut, valIn.getRawPtr (), numEnt *
sizeof (Scalar));
5560 ArrayView<const GO> indIn;
5561 ArrayView<const Scalar> valIn;
5565 memcpy (indOut, indIn.getRawPtr (), numEnt *
sizeof (GO));
5566 memcpy (valOut, valIn.getRawPtr (), numEnt *
sizeof (Scalar));
5577 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5581 GlobalOrdinal*
const indInTmp,
5582 const size_t tmpSize,
5583 const char*
const valIn,
5584 const char*
const indIn,
5585 const size_t numEnt,
5586 const LocalOrdinal lclRow,
5589 if (tmpSize < numEnt || (numEnt != 0 && (valInTmp == NULL || indInTmp == NULL))) {
5592 memcpy (valInTmp, valIn, numEnt *
sizeof (Scalar));
5593 memcpy (indInTmp, indIn, numEnt *
sizeof (GlobalOrdinal));
5594 const GlobalOrdinal gblRow = this->
getRowMap ()->getGlobalElement (lclRow);
5595 Teuchos::ArrayView<Scalar> val ((numEnt == 0) ? NULL : valInTmp, numEnt);
5596 Teuchos::ArrayView<GlobalOrdinal> ind ((numEnt == 0) ? NULL : indInTmp, numEnt);
5597 this->combineGlobalValues (gblRow, ind, val, combineMode);
5602 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5606 size_t& totalNumEntries,
5607 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs)
const 5609 typedef LocalOrdinal LO;
5610 typedef GlobalOrdinal GO;
5611 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
5613 const size_type numExportLIDs = exportLIDs.size ();
5616 totalNumEntries = 0;
5617 for (size_type i = 0; i < numExportLIDs; ++i) {
5618 const LO lclRow = exportLIDs[i];
5622 if (curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid ()) {
5625 totalNumEntries += curNumEntries;
5636 const size_t allocSize =
5637 static_cast<size_t> (numExportLIDs) *
sizeof (LO) +
5638 totalNumEntries * (
sizeof (Scalar) +
sizeof (GO));
5639 if (static_cast<size_t> (exports.size ()) < allocSize) {
5640 exports.resize (allocSize);
5644 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5647 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5648 Teuchos::Array<char>& exports,
5649 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5650 size_t& constantNumPackets,
5653 using Teuchos::Array;
5654 using Teuchos::ArrayView;
5655 using Teuchos::av_reinterpret_cast;
5657 typedef LocalOrdinal LO;
5658 typedef GlobalOrdinal GO;
5659 typedef typename ArrayView<const LO>::size_type size_type;
5660 const char tfecfFuncName[] =
"pack: ";
5662 const size_type numExportLIDs = exportLIDs.size ();
5663 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5664 numExportLIDs != numPacketsPerLID.size (), std::invalid_argument,
5665 "exportLIDs.size() = " << numExportLIDs <<
" != numPacketsPerLID.size()" 5666 " = " << numPacketsPerLID.size () <<
".");
5671 constantNumPackets = 0;
5676 size_t totalNumEntries = 0;
5677 allocatePackSpace (exports, totalNumEntries, exportLIDs);
5678 const size_t bufSize =
static_cast<size_t> (exports.size ());
5690 size_type firstBadIndex = 0;
5691 size_t firstBadOffset = 0;
5692 size_t firstBadNumBytes = 0;
5693 bool outOfBounds =
false;
5694 bool packErr =
false;
5696 char*
const exportsRawPtr = exports.getRawPtr ();
5698 for (size_type i = 0; i < numExportLIDs; ++i) {
5699 const LO lclRow = exportLIDs[i];
5704 numPacketsPerLID[i] = 0;
5707 char*
const numEntBeg = exportsRawPtr + offset;
5708 char*
const numEntEnd = numEntBeg +
sizeof (LO);
5709 char*
const valBeg = numEntEnd;
5710 char*
const valEnd = valBeg + numEnt *
sizeof (Scalar);
5711 char*
const indBeg = valEnd;
5712 const size_t numBytes =
sizeof (LO) +
5713 numEnt * (
sizeof (Scalar) +
sizeof (GO));
5714 if (offset > bufSize || offset + numBytes > bufSize) {
5716 firstBadOffset = offset;
5717 firstBadNumBytes = numBytes;
5721 packErr = ! packRow (numEntBeg, valBeg, indBeg, numEnt, lclRow);
5724 firstBadOffset = offset;
5725 firstBadNumBytes = numBytes;
5731 numPacketsPerLID[i] = numBytes;
5736 TEUCHOS_TEST_FOR_EXCEPTION(
5737 outOfBounds, std::logic_error,
"First invalid offset into 'exports' " 5738 "pack buffer at index i = " << firstBadIndex <<
". exportLIDs[i]: " 5739 << exportLIDs[firstBadIndex] <<
", bufSize: " << bufSize <<
", offset: " 5740 << firstBadOffset <<
", numBytes: " << firstBadNumBytes <<
".");
5741 TEUCHOS_TEST_FOR_EXCEPTION(
5742 packErr, std::logic_error,
"First error in packRow() at index i = " 5743 << firstBadIndex <<
". exportLIDs[i]: " << exportLIDs[firstBadIndex]
5744 <<
", bufSize: " << bufSize <<
", offset: " << firstBadOffset
5745 <<
", numBytes: " << firstBadNumBytes <<
".");
5748 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5752 const Teuchos::ArrayView<const GlobalOrdinal>& columnIndices,
5753 const Teuchos::ArrayView<const Scalar>& values,
5756 const char tfecfFuncName[] =
"combineGlobalValues: ";
5762 if (combineMode ==
ADD) {
5765 else if (combineMode ==
REPLACE) {
5768 else if (combineMode ==
ABSMAX) {
5771 this->
template transformGlobalValues<AbsMax<Scalar> > (globalRowIndex,
5775 else if (combineMode ==
INSERT) {
5776 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5778 "INSERT combine mode is not allowed if the matrix has a static graph " 5779 "(i.e., was constructed with the CrsMatrix constructor that takes a " 5780 "const CrsGraph pointer).");
5783 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5784 true, std::logic_error,
"Invalid combine mode; should never get " 5785 "here! Please report this bug to the Tpetra developers.");
5789 if (combineMode ==
ADD || combineMode ==
INSERT) {
5796 insertGlobalValuesFiltered (globalRowIndex, columnIndices, values);
5807 else if (combineMode ==
ABSMAX) {
5808 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5810 "ABSMAX combine mode when the matrix has a dynamic graph is not yet " 5813 else if (combineMode ==
REPLACE) {
5814 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5816 "REPLACE combine mode when the matrix has a dynamic graph is not yet " 5820 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5821 true, std::logic_error,
"Should never get here! Please report this " 5822 "bug to the Tpetra developers.");
5828 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5832 const Teuchos::ArrayView<const char>& imports,
5833 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5834 size_t constantNumPackets,
5838 #ifdef HAVE_TPETRA_DEBUG 5839 const char tfecfFuncName[] =
"unpackAndCombine: ";
5841 const char* validModeNames[4] = {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT"};
5842 const int numValidModes = 4;
5844 if (std::find (validModes, validModes+numValidModes, combineMode) ==
5845 validModes+numValidModes) {
5846 std::ostringstream os;
5847 os <<
"Invalid combine mode. Valid modes are {";
5848 for (
int k = 0; k < numValidModes; ++k) {
5849 os << validModeNames[k];
5850 if (k < numValidModes - 1) {
5855 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5856 true, std::invalid_argument, os.str ());
5860 using Teuchos::reduceAll;
5861 std::ostringstream msg;
5864 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
5865 constantNumPackets, distor, combineMode);
5866 }
catch (std::exception& e) {
5871 const Teuchos::Comm<int>& comm = * (this->
getComm ());
5872 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
5873 lclBad, Teuchos::outArg (gblBad));
5875 const int myRank = comm.getRank ();
5876 const int numProcs = comm.getSize ();
5877 for (
int r = 0; r < numProcs; ++r) {
5878 if (r == myRank && lclBad != 0) {
5879 std::ostringstream os;
5880 os <<
"Proc " << myRank <<
": " << msg.str () << std::endl;
5881 std::cerr << os.str ();
5887 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5888 true, std::logic_error,
"unpackAndCombineImpl() threw an " 5889 "exception on one or more participating processes.");
5893 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
5894 constantNumPackets, distor, combineMode);
5895 #endif // HAVE_TPETRA_DEBUG 5898 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5902 const Teuchos::ArrayView<const char>& imports,
5903 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5904 size_t constantNumPackets,
5908 typedef LocalOrdinal LO;
5909 typedef GlobalOrdinal GO;
5910 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
5911 const char tfecfFuncName[] =
"unpackAndCombine: ";
5913 #ifdef HAVE_TPETRA_DEBUG 5915 const char* validModeNames[4] = {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT"};
5916 const int numValidModes = 4;
5918 if (std::find (validModes, validModes+numValidModes, combineMode) ==
5919 validModes+numValidModes) {
5920 std::ostringstream os;
5921 os <<
"Invalid combine mode. Valid modes are {";
5922 for (
int k = 0; k < numValidModes; ++k) {
5923 os << validModeNames[k];
5924 if (k < numValidModes - 1) {
5929 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5930 true, std::invalid_argument, os.str ());
5932 #endif // HAVE_TPETRA_DEBUG 5934 const size_type numImportLIDs = importLIDs.size ();
5935 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5936 numImportLIDs != numPacketsPerLID.size (), std::invalid_argument,
5937 "importLIDs.size() = " << numImportLIDs <<
" != numPacketsPerLID.size()" 5938 <<
" = " << numPacketsPerLID.size () <<
".");
5944 size_type firstBadIndex = 0;
5945 size_t firstBadOffset = 0;
5946 size_t firstBadExpectedNumBytes = 0;
5947 size_t firstBadNumBytes = 0;
5948 LO firstBadNumEnt = 0;
5957 bool outOfBounds =
false;
5958 bool wrongNumBytes =
false;
5959 bool unpackErr =
false;
5961 const size_t bufSize =
static_cast<size_t> (imports.size ());
5962 const char*
const importsRawPtr = imports.getRawPtr ();
5971 Array<Scalar> valInTmp;
5973 for (size_type i = 0; i < numImportLIDs; ++i) {
5974 const LO lclRow = importLIDs[i];
5975 const size_t numBytes = numPacketsPerLID[i];
5978 const char*
const numEntBeg = importsRawPtr + offset;
5979 const char*
const numEntEnd = numEntBeg +
sizeof (LO);
5984 memcpy (&numEnt, numEntBeg,
sizeof (LO));
5986 const char*
const valBeg = numEntEnd;
5987 const char*
const valEnd =
5988 valBeg +
static_cast<size_t> (numEnt) *
sizeof (Scalar);
5989 const char*
const indBeg = valEnd;
5990 const size_t expectedNumBytes =
sizeof (LO) +
5991 static_cast<size_t> (numEnt) * (
sizeof (Scalar) +
sizeof (GO));
5993 if (expectedNumBytes > numBytes) {
5995 firstBadOffset = offset;
5996 firstBadExpectedNumBytes = expectedNumBytes;
5997 firstBadNumBytes = numBytes;
5998 firstBadNumEnt = numEnt;
5999 wrongNumBytes =
true;
6002 if (offset > bufSize || offset + numBytes > bufSize) {
6004 firstBadOffset = offset;
6005 firstBadExpectedNumBytes = expectedNumBytes;
6006 firstBadNumBytes = numBytes;
6007 firstBadNumEnt = numEnt;
6011 size_t tmpNumEnt =
static_cast<size_t> (valInTmp.size ());
6012 if (tmpNumEnt < static_cast<size_t> (numEnt) ||
6013 static_cast<size_t> (indInTmp.size ()) < static_cast<size_t> (numEnt)) {
6015 tmpNumEnt = std::max (static_cast<size_t> (numEnt), tmpNumEnt * 2);
6016 valInTmp.resize (tmpNumEnt);
6017 indInTmp.resize (tmpNumEnt);
6020 ! unpackRow (valInTmp.getRawPtr (), indInTmp.getRawPtr (), tmpNumEnt,
6021 valBeg, indBeg, numEnt, lclRow, combineMode);
6024 firstBadOffset = offset;
6025 firstBadExpectedNumBytes = expectedNumBytes;
6026 firstBadNumBytes = numBytes;
6027 firstBadNumEnt = numEnt;
6034 if (wrongNumBytes || outOfBounds || unpackErr) {
6035 std::ostringstream os;
6036 os <<
" importLIDs[i]: " << importLIDs[firstBadIndex]
6037 <<
", bufSize: " << bufSize
6038 <<
", offset: " << firstBadOffset
6039 <<
", numBytes: " << firstBadNumBytes
6040 <<
", expectedNumBytes: " << firstBadExpectedNumBytes
6041 <<
", numEnt: " << firstBadNumEnt;
6042 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6043 wrongNumBytes, std::logic_error,
"At index i = " << firstBadIndex
6044 <<
", expectedNumBytes > numBytes." << os.str ());
6045 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6046 outOfBounds, std::logic_error,
"First invalid offset into 'imports' " 6047 "unpack buffer at index i = " << firstBadIndex <<
"." << os.str ());
6048 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6049 unpackErr, std::logic_error,
"First error in unpackRow() at index i = " 6050 << firstBadIndex <<
"." << os.str ());
6054 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6055 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
6058 const bool force)
const 6060 using Teuchos::null;
6064 TEUCHOS_TEST_FOR_EXCEPTION(
6065 ! this->
hasColMap (), std::runtime_error,
"Tpetra::CrsMatrix::getColumn" 6066 "MapMultiVector: You may only call this method if the matrix has a " 6067 "column Map. If the matrix does not yet have a column Map, you should " 6068 "first call fillComplete (with domain and range Map if necessary).");
6072 TEUCHOS_TEST_FOR_EXCEPTION(
6074 "CrsMatrix::getColumnMapMultiVector: You may only call this method if " 6075 "this matrix's graph is fill complete.");
6078 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
6079 RCP<const map_type> colMap = this->
getColMap ();
6092 if (! importer.is_null () || force) {
6094 X_colMap = rcp (
new MV (colMap, numVecs));
6111 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6112 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
6115 const bool force)
const 6117 using Teuchos::null;
6123 TEUCHOS_TEST_FOR_EXCEPTION(
6125 "CrsMatrix::getRowMapMultiVector: You may only call this method if this " 6126 "matrix's graph is fill complete.");
6129 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
6133 RCP<const map_type> rowMap = this->
getRowMap ();
6145 if (! exporter.is_null () || force) {
6147 Y_rowMap = rcp (
new MV (rowMap, numVecs));
6157 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6162 TEUCHOS_TEST_FOR_EXCEPTION(
6163 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::" 6164 "removeEmptyProcessesInPlace: This method does not work when the matrix " 6165 "was created with a constant graph (that is, when it was created using " 6166 "the version of its constructor that takes an RCP<const CrsGraph>). " 6167 "This is because the matrix is not allowed to modify the graph in that " 6168 "case, but removing empty processes requires modifying the graph.");
6169 myGraph_->removeEmptyProcessesInPlace (newMap);
6177 staticGraph_ = Teuchos::rcp_const_cast<
const Graph> (myGraph_);
6180 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6181 Teuchos::RCP<RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
6186 const Teuchos::RCP<const map_type>& domainMap,
6187 const Teuchos::RCP<const map_type>& rangeMap,
6188 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 6190 using Teuchos::Array;
6191 using Teuchos::ArrayRCP;
6192 using Teuchos::ParameterList;
6195 using Teuchos::rcp_implicit_cast;
6196 using Teuchos::sublist;
6197 typedef LocalOrdinal LO;
6198 typedef GlobalOrdinal GO;
6202 const crs_matrix_type& B = *
this;
6203 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
6204 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
6211 RCP<const map_type> A_rangeMap = A.
getRangeMap ();
6212 RCP<const map_type> B_domainMap = B.getDomainMap ();
6213 RCP<const map_type> B_rangeMap = B.getRangeMap ();
6215 RCP<const map_type> theDomainMap = domainMap;
6216 RCP<const map_type> theRangeMap = rangeMap;
6218 if (domainMap.is_null ()) {
6219 if (B_domainMap.is_null ()) {
6220 TEUCHOS_TEST_FOR_EXCEPTION(
6221 A_domainMap.is_null (), std::invalid_argument,
6222 "Tpetra::CrsMatrix::add: If neither A nor B have a domain Map, " 6223 "then you must supply a nonnull domain Map to this method.");
6224 theDomainMap = A_domainMap;
6226 theDomainMap = B_domainMap;
6229 if (rangeMap.is_null ()) {
6230 if (B_rangeMap.is_null ()) {
6231 TEUCHOS_TEST_FOR_EXCEPTION(
6232 A_rangeMap.is_null (), std::invalid_argument,
6233 "Tpetra::CrsMatrix::add: If neither A nor B have a range Map, " 6234 "then you must supply a nonnull range Map to this method.");
6235 theRangeMap = A_rangeMap;
6237 theRangeMap = B_rangeMap;
6241 #ifdef HAVE_TPETRA_DEBUG 6245 if (! A_domainMap.is_null () && ! A_rangeMap.is_null ()) {
6246 if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
6247 TEUCHOS_TEST_FOR_EXCEPTION(
6248 ! B_domainMap->isSameAs (*A_domainMap), std::invalid_argument,
6249 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a domain Map " 6250 "which is the same as (isSameAs) this RowMatrix's domain Map.");
6251 TEUCHOS_TEST_FOR_EXCEPTION(
6252 ! B_rangeMap->isSameAs (*A_rangeMap), std::invalid_argument,
6253 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a range Map " 6254 "which is the same as (isSameAs) this RowMatrix's range Map.");
6255 TEUCHOS_TEST_FOR_EXCEPTION(
6256 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
6257 std::invalid_argument,
6258 "Tpetra::CrsMatrix::add: The input domain Map must be the same as " 6259 "(isSameAs) this RowMatrix's domain Map.");
6260 TEUCHOS_TEST_FOR_EXCEPTION(
6261 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
6262 std::invalid_argument,
6263 "Tpetra::CrsMatrix::add: The input range Map must be the same as " 6264 "(isSameAs) this RowMatrix's range Map.");
6267 else if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
6268 TEUCHOS_TEST_FOR_EXCEPTION(
6269 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
6270 std::invalid_argument,
6271 "Tpetra::CrsMatrix::add: The input domain Map must be the same as " 6272 "(isSameAs) this RowMatrix's domain Map.");
6273 TEUCHOS_TEST_FOR_EXCEPTION(
6274 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
6275 std::invalid_argument,
6276 "Tpetra::CrsMatrix::add: The input range Map must be the same as " 6277 "(isSameAs) this RowMatrix's range Map.");
6280 TEUCHOS_TEST_FOR_EXCEPTION(
6281 domainMap.is_null () || rangeMap.is_null (), std::invalid_argument,
6282 "Tpetra::CrsMatrix::add: If neither A nor B have a domain and range " 6283 "Map, then you must supply a nonnull domain and range Map to this " 6286 #endif // HAVE_TPETRA_DEBUG 6291 bool callFillComplete =
true;
6292 RCP<ParameterList> constructorSublist;
6293 RCP<ParameterList> fillCompleteSublist;
6294 if (! params.is_null ()) {
6295 callFillComplete = params->get (
"Call fillComplete", callFillComplete);
6296 constructorSublist = sublist (params,
"Constructor parameters");
6297 fillCompleteSublist = sublist (params,
"fillComplete parameters");
6300 RCP<const map_type> A_rowMap = A.
getRowMap ();
6301 RCP<const map_type> B_rowMap = B.getRowMap ();
6302 RCP<const map_type> C_rowMap = B_rowMap;
6303 RCP<crs_matrix_type> C;
6310 if (A_rowMap->isSameAs (*B_rowMap)) {
6311 const LO localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
6312 ArrayRCP<size_t> C_maxNumEntriesPerRow (localNumRows, 0);
6315 if (alpha != ZERO) {
6316 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
6318 C_maxNumEntriesPerRow[localRow] += A_numEntries;
6323 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
6324 const size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
6325 C_maxNumEntriesPerRow[localRow] += B_numEntries;
6329 if (constructorSublist.is_null ()) {
6330 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow,
6333 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow,
6344 if (constructorSublist.is_null ()) {
6348 constructorSublist));
6352 #ifdef HAVE_TPETRA_DEBUG 6353 TEUCHOS_TEST_FOR_EXCEPTION(C.is_null (), std::logic_error,
6354 "Tpetra::RowMatrix::add: C should not be null at this point. " 6355 "Please report this bug to the Tpetra developers.");
6356 #endif // HAVE_TPETRA_DEBUG 6363 if (alpha != ZERO) {
6364 const LO A_localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
6365 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
6367 const GO globalRow = A_rowMap->getGlobalElement (localRow);
6368 if (A_numEntries > static_cast<size_t> (ind.size ())) {
6369 ind.resize (A_numEntries);
6370 val.resize (A_numEntries);
6372 ArrayView<GO> indView = ind (0, A_numEntries);
6373 ArrayView<Scalar> valView = val (0, A_numEntries);
6377 for (
size_t k = 0; k < A_numEntries; ++k) {
6378 valView[k] *= alpha;
6381 C->insertGlobalValues (globalRow, indView, valView);
6386 const LO B_localNumRows =
static_cast<LO
> (B_rowMap->getNodeNumElements ());
6387 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
6388 size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
6389 const GO globalRow = B_rowMap->getGlobalElement (localRow);
6390 if (B_numEntries > static_cast<size_t> (ind.size ())) {
6391 ind.resize (B_numEntries);
6392 val.resize (B_numEntries);
6394 ArrayView<GO> indView = ind (0, B_numEntries);
6395 ArrayView<Scalar> valView = val (0, B_numEntries);
6396 B.getGlobalRowCopy (globalRow, indView, valView, B_numEntries);
6399 for (
size_t k = 0; k < B_numEntries; ++k) {
6403 C->insertGlobalValues (globalRow, indView, valView);
6407 if (callFillComplete) {
6408 if (fillCompleteSublist.is_null ()) {
6409 C->fillComplete (theDomainMap, theRangeMap);
6411 C->fillComplete (theDomainMap, theRangeMap, fillCompleteSublist);
6414 return rcp_implicit_cast<row_matrix_type> (C);
6417 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6421 const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node>& rowTransfer,
6422 const Teuchos::RCP<const map_type>& domainMap,
6423 const Teuchos::RCP<const map_type>& rangeMap,
6424 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 6426 using Teuchos::ArrayView;
6427 using Teuchos::Comm;
6428 using Teuchos::ParameterList;
6430 typedef LocalOrdinal LO;
6431 typedef GlobalOrdinal GO;
6436 #ifdef HAVE_TPETRA_MMM_TIMINGS 6438 if(!params.is_null())
6439 label = params->get(
"Timer Label",label);
6440 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
6441 using Teuchos::TimeMonitor;
6442 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Pack-1"))));
6452 TEUCHOS_TEST_FOR_EXCEPTION(
6453 xferAsImport == NULL && xferAsExport == NULL, std::invalid_argument,
6454 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' input " 6455 "argument must be either an Import or an Export, and its template " 6456 "parameters must match the corresponding template parameters of the " 6461 const bool communication_needed = rowTransfer.getSourceMap ()->isDistributed ();
6467 bool reverseMode =
false;
6468 bool restrictComm =
false;
6469 RCP<ParameterList> matrixparams;
6470 if (! params.is_null ()) {
6471 reverseMode = params->get (
"Reverse Mode", reverseMode);
6472 restrictComm = params->get (
"Restrict Communicator", restrictComm);
6473 matrixparams = sublist (params,
"CrsMatrix");
6478 RCP<const map_type> MyRowMap = reverseMode ?
6479 rowTransfer.getSourceMap () : rowTransfer.getTargetMap ();
6480 RCP<const map_type> MyColMap;
6481 RCP<const map_type> MyDomainMap = ! domainMap.is_null () ?
6483 RCP<const map_type> MyRangeMap = ! rangeMap.is_null () ?
6485 RCP<const map_type> BaseRowMap = MyRowMap;
6486 RCP<const map_type> BaseDomainMap = MyDomainMap;
6494 if (! destMat.is_null ()) {
6505 const bool NewFlag = ! destMat->getGraph ()->isLocallyIndexed () &&
6506 ! destMat->getGraph ()->isGloballyIndexed ();
6507 TEUCHOS_TEST_FOR_EXCEPTION(
6508 ! NewFlag, std::invalid_argument,
"Tpetra::CrsMatrix::" 6509 "transferAndFillComplete: The input argument 'destMat' is only allowed " 6510 "to be nonnull, if its graph is empty (neither locally nor globally " 6519 TEUCHOS_TEST_FOR_EXCEPTION(
6520 ! destMat->getRowMap ()->isSameAs (*MyRowMap), std::invalid_argument,
6521 "Tpetra::CrsMatrix::transferAndFillComplete: The (row) Map of the " 6522 "input argument 'destMat' is not the same as the (row) Map specified " 6523 "by the input argument 'rowTransfer'.");
6524 TEUCHOS_TEST_FOR_EXCEPTION(
6525 ! destMat->checkSizes (*
this), std::invalid_argument,
6526 "Tpetra::CrsMatrix::transferAndFillComplete: You provided a nonnull " 6527 "destination matrix, but checkSizes() indicates that it is not a legal " 6528 "legal target for redistribution from the source matrix (*this). This " 6529 "may mean that they do not have the same dimensions.");
6543 TEUCHOS_TEST_FOR_EXCEPTION(
6544 ! (reverseMode ||
getRowMap ()->isSameAs (*rowTransfer.getSourceMap ())),
6545 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: " 6546 "rowTransfer->getSourceMap() must match this->getRowMap() in forward mode.");
6547 TEUCHOS_TEST_FOR_EXCEPTION(
6548 ! (! reverseMode ||
getRowMap ()->isSameAs (*rowTransfer.getTargetMap ())),
6549 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: " 6550 "rowTransfer->getTargetMap() must match this->getRowMap() in reverse mode.");
6563 const size_t NumSameIDs = rowTransfer.getNumSameIDs();
6564 ArrayView<const LO> ExportLIDs = reverseMode ?
6565 rowTransfer.getRemoteLIDs () : rowTransfer.getExportLIDs ();
6566 ArrayView<const LO> RemoteLIDs = reverseMode ?
6567 rowTransfer.getExportLIDs () : rowTransfer.getRemoteLIDs ();
6568 ArrayView<const LO> PermuteToLIDs = reverseMode ?
6569 rowTransfer.getPermuteFromLIDs () : rowTransfer.getPermuteToLIDs ();
6570 ArrayView<const LO> PermuteFromLIDs = reverseMode ?
6571 rowTransfer.getPermuteToLIDs () : rowTransfer.getPermuteFromLIDs ();
6572 Distributor& Distor = rowTransfer.getDistributor ();
6575 Teuchos::Array<int> SourcePids;
6576 Teuchos::Array<int> TargetPids;
6577 int MyPID =
getComm ()->getRank ();
6580 RCP<const map_type> ReducedRowMap, ReducedColMap,
6581 ReducedDomainMap, ReducedRangeMap;
6582 RCP<const Comm<int> > ReducedComm;
6586 if (destMat.is_null ()) {
6587 destMat = rcp (
new this_type (MyRowMap, 0,
StaticProfile, matrixparams));
6594 ReducedRowMap = MyRowMap->removeEmptyProcesses ();
6595 ReducedComm = ReducedRowMap.is_null () ?
6597 ReducedRowMap->getComm ();
6598 destMat->removeEmptyProcessesInPlace (ReducedRowMap);
6600 ReducedDomainMap = MyRowMap.getRawPtr () == MyDomainMap.getRawPtr () ?
6602 MyDomainMap->replaceCommWithSubset (ReducedComm);
6603 ReducedRangeMap = MyRowMap.getRawPtr () == MyRangeMap.getRawPtr () ?
6605 MyRangeMap->replaceCommWithSubset (ReducedComm);
6608 MyRowMap = ReducedRowMap;
6609 MyDomainMap = ReducedDomainMap;
6610 MyRangeMap = ReducedRangeMap;
6613 if (! ReducedComm.is_null ()) {
6614 MyPID = ReducedComm->getRank ();
6621 ReducedComm = MyRowMap->getComm ();
6627 #ifdef HAVE_TPETRA_MMM_TIMINGS 6628 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC ImportSetup"))));
6631 RCP<const import_type> MyImporter =
getGraph ()->getImporter ();
6633 if (! restrictComm && ! MyImporter.is_null () &&
6641 Import_Util::getPids (*MyImporter, SourcePids,
false);
6643 else if (MyImporter.is_null () && BaseDomainMap->isSameAs (*
getDomainMap ())) {
6645 SourcePids.resize (
getColMap ()->getNodeNumElements ());
6646 SourcePids.assign (
getColMap ()->getNodeNumElements (), MyPID);
6648 else if (BaseDomainMap->isSameAs (*BaseRowMap) &&
6651 IntVectorType TargetRow_pids (domainMap);
6652 IntVectorType SourceRow_pids (
getRowMap ());
6653 IntVectorType SourceCol_pids (
getColMap ());
6655 TargetRow_pids.putScalar (MyPID);
6656 if (! reverseMode && xferAsImport != NULL) {
6657 SourceRow_pids.doExport (TargetRow_pids, *xferAsImport,
INSERT);
6659 else if (reverseMode && xferAsExport != NULL) {
6660 SourceRow_pids.doExport (TargetRow_pids, *xferAsExport,
INSERT);
6662 else if (! reverseMode && xferAsExport != NULL) {
6663 SourceRow_pids.doImport (TargetRow_pids, *xferAsExport,
INSERT);
6665 else if (reverseMode && xferAsImport != NULL) {
6666 SourceRow_pids.doImport (TargetRow_pids, *xferAsImport,
INSERT);
6669 TEUCHOS_TEST_FOR_EXCEPTION(
6670 true, std::logic_error,
"Tpetra::CrsMatrix::" 6671 "transferAndFillComplete: Should never get here! " 6672 "Please report this bug to a Tpetra developer.");
6674 SourceCol_pids.doImport (SourceRow_pids, *MyImporter,
INSERT);
6675 SourcePids.resize (
getColMap ()->getNodeNumElements ());
6676 SourceCol_pids.get1dCopy (SourcePids ());
6679 TEUCHOS_TEST_FOR_EXCEPTION(
6680 true, std::invalid_argument,
"Tpetra::CrsMatrix::" 6681 "transferAndFillComplete: This method only allows either domainMap == " 6682 "getDomainMap (), or (domainMap == rowTransfer.getTargetMap () and " 6683 "getDomainMap () == getRowMap ()).");
6685 #ifdef HAVE_TPETRA_MMM_TIMINGS 6686 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Pack-2"))));
6709 size_t constantNumPackets = destMat->constantNumberOfPackets ();
6710 if (constantNumPackets == 0) {
6711 destMat->numExportPacketsPerLID_old_.resize (ExportLIDs.size ());
6712 destMat->numImportPacketsPerLID_old_.resize (RemoteLIDs.size ());
6719 const size_t rbufLen = RemoteLIDs.size() * constantNumPackets;
6720 if (static_cast<size_t> (destMat->imports_old_.size ()) != rbufLen) {
6721 destMat->imports_old_.resize (rbufLen);
6738 #ifdef HAVE_TPETRA_DEBUG 6740 using Teuchos::outArg;
6741 using Teuchos::REDUCE_MAX;
6742 using Teuchos::reduceAll;
6745 RCP<const Teuchos::Comm<int> > comm = this->
getComm ();
6746 const int myRank = comm->getRank ();
6747 const int numProcs = comm->getSize ();
6749 std::ostringstream os;
6752 Import_Util::packAndPrepareWithOwningPIDs (*
this, ExportLIDs,
6753 destMat->exports_old_,
6754 destMat->numExportPacketsPerLID_old_ (),
6755 constantNumPackets, Distor,
6758 catch (std::exception& e) {
6759 os <<
"Proc " << myRank <<
": " << e.what ();
6763 if (! comm.is_null ()) {
6764 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
6768 cerr <<
"packAndPrepareWithOwningPIDs threw an exception: " << endl;
6770 std::ostringstream err;
6771 for (
int r = 0; r < numProcs; ++r) {
6772 if (r == myRank && lclErr != 0) {
6773 cerr << os.str () << endl;
6780 TEUCHOS_TEST_FOR_EXCEPTION(
6781 true, std::logic_error,
"packAndPrepareWithOwningPIDs threw an " 6787 Import_Util::packAndPrepareWithOwningPIDs (*
this, ExportLIDs,
6788 destMat->exports_old_,
6789 destMat->numExportPacketsPerLID_old_ (),
6790 constantNumPackets, Distor,
6792 #endif // HAVE_TPETRA_DEBUG 6806 #ifdef HAVE_TPETRA_MMM_TIMINGS 6807 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Transfer"))));
6810 if (communication_needed) {
6812 if (constantNumPackets == 0) {
6813 Distor.doReversePostsAndWaits (destMat->numExportPacketsPerLID_old_ ().getConst (), 1,
6814 destMat->numImportPacketsPerLID_old_ ());
6815 size_t totalImportPackets = 0;
6816 for (
Array_size_type i = 0; i < destMat->numImportPacketsPerLID_old_.size (); ++i) {
6817 totalImportPackets += destMat->numImportPacketsPerLID_old_[i];
6819 destMat->imports_old_.resize (totalImportPackets);
6820 Distor.doReversePostsAndWaits (destMat->exports_old_ ().getConst (),
6821 destMat->numExportPacketsPerLID_old_ (),
6822 destMat->imports_old_ (),
6823 destMat->numImportPacketsPerLID_old_ ());
6826 Distor.doReversePostsAndWaits (destMat->exports_old_ ().getConst (),
6828 destMat->imports_old_ ());
6832 if (constantNumPackets == 0) {
6833 Distor.doPostsAndWaits (destMat->numExportPacketsPerLID_old_ ().getConst (), 1,
6834 destMat->numImportPacketsPerLID_old_ ());
6835 size_t totalImportPackets = 0;
6836 for (
Array_size_type i = 0; i < destMat->numImportPacketsPerLID_old_.size (); ++i) {
6837 totalImportPackets += destMat->numImportPacketsPerLID_old_[i];
6839 destMat->imports_old_.resize (totalImportPackets);
6840 Distor.doPostsAndWaits (destMat->exports_old_ ().getConst (),
6841 destMat->numExportPacketsPerLID_old_ (),
6842 destMat->imports_old_ (),
6843 destMat->numImportPacketsPerLID_old_ ());
6846 Distor.doPostsAndWaits (destMat->exports_old_ ().getConst (),
6848 destMat->imports_old_ ());
6866 #ifdef HAVE_TPETRA_MMM_TIMINGS 6867 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-1"))));
6870 Import_Util::unpackAndCombineWithOwningPIDsCount (*
this, RemoteLIDs,
6871 destMat->imports_old_ (),
6872 destMat->numImportPacketsPerLID_old_ (),
6873 constantNumPackets, Distor,
INSERT,
6874 NumSameIDs, PermuteToLIDs,
6876 size_t N = BaseRowMap->getNodeNumElements ();
6879 ArrayRCP<size_t> CSR_rowptr(N+1);
6880 ArrayRCP<GO> CSR_colind_GID;
6881 ArrayRCP<LO> CSR_colind_LID;
6882 ArrayRCP<Scalar> CSR_vals;
6883 CSR_colind_GID.resize (mynnz);
6884 CSR_vals.resize (mynnz);
6888 if (
typeid (LO) ==
typeid (GO)) {
6889 CSR_colind_LID = Teuchos::arcp_reinterpret_cast<LO> (CSR_colind_GID);
6892 CSR_colind_LID.resize (mynnz);
6910 Import_Util::unpackAndCombineIntoCrsArrays (*
this, RemoteLIDs, destMat->imports_old_ (),
6911 destMat->numImportPacketsPerLID_old_ (),
6912 constantNumPackets, Distor,
INSERT, NumSameIDs,
6913 PermuteToLIDs, PermuteFromLIDs, N, mynnz, MyPID,
6914 CSR_rowptr (), CSR_colind_GID (), CSR_vals (),
6915 SourcePids (), TargetPids);
6920 #ifdef HAVE_TPETRA_MMM_TIMINGS 6921 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-2"))));
6926 Teuchos::Array<int> RemotePids;
6927 Import_Util::lowCommunicationMakeColMapAndReindex (CSR_rowptr (),
6931 TargetPids, RemotePids,
6938 ReducedColMap = (MyRowMap.getRawPtr () == MyColMap.getRawPtr ()) ?
6940 MyColMap->replaceCommWithSubset (ReducedComm);
6941 MyColMap = ReducedColMap;
6945 destMat->replaceColMap (MyColMap);
6952 if (ReducedComm.is_null ()) {
6959 #ifdef HAVE_TPETRA_MMM_TIMINGS 6960 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-3"))));
6962 Import_Util::sortCrsEntries (CSR_rowptr (),
6965 if ((! reverseMode && xferAsImport != NULL) ||
6966 (reverseMode && xferAsExport != NULL)) {
6967 Import_Util::sortCrsEntries (CSR_rowptr (),
6971 else if ((! reverseMode && xferAsExport != NULL) ||
6972 (reverseMode && xferAsImport != NULL)) {
6973 Import_Util::sortAndMergeCrsEntries (CSR_rowptr (),
6976 if (CSR_rowptr[N] != mynnz) {
6977 CSR_colind_LID.resize (CSR_rowptr[N]);
6978 CSR_vals.resize (CSR_rowptr[N]);
6982 TEUCHOS_TEST_FOR_EXCEPTION(
6983 true, std::logic_error,
"Tpetra::CrsMatrix::" 6984 "transferAndFillComplete: Should never get here! " 6985 "Please report this bug to a Tpetra developer.");
6996 destMat->setAllValues (CSR_rowptr, CSR_colind_LID, CSR_vals);
7002 Teuchos::ParameterList esfc_params;
7003 #ifdef HAVE_TPETRA_MMM_TIMINGS 7004 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC CreateImporter"))));
7006 RCP<import_type> MyImport = rcp (
new import_type (MyDomainMap, MyColMap, RemotePids));
7007 #ifdef HAVE_TPETRA_MMM_TIMINGS 7008 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC ESFC"))));
7010 esfc_params.set(
"Timer Label",prefix + std::string(
"TAFC"));
7013 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap, MyImport,Teuchos::null,rcp(&esfc_params,
false));
7016 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7021 const Teuchos::RCP<const map_type>& domainMap,
7022 const Teuchos::RCP<const map_type>& rangeMap,
7023 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7025 transferAndFillComplete (destMatrix, importer, domainMap, rangeMap, params);
7029 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7034 const Teuchos::RCP<const map_type>& domainMap,
7035 const Teuchos::RCP<const map_type>& rangeMap,
7036 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7038 transferAndFillComplete (destMatrix, exporter, domainMap, rangeMap, params);
7049 #define TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR,LO,GO,NODE) \ 7051 template class CrsMatrix< SCALAR , LO , GO , NODE >; \ 7052 template RCP< CrsMatrix< SCALAR , LO , GO , NODE > > \ 7053 CrsMatrix< SCALAR , LO , GO , NODE >::convert< SCALAR > () const; 7055 #define TPETRA_CRSMATRIX_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \ 7057 template RCP< CrsMatrix< SO , LO , GO , NODE > > \ 7058 CrsMatrix< SI , LO , GO , NODE >::convert< SO > () const; 7060 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7062 RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7063 importAndFillCompleteCrsMatrix (const RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7064 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7065 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7066 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& importer, \ 7067 const RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7068 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7069 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7070 const RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7071 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7072 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7073 const RCP<Teuchos::ParameterList>& params); 7075 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7077 RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7078 exportAndFillCompleteCrsMatrix (const RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7079 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7080 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7081 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& exporter, \ 7082 const RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7083 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7084 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7085 const RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7086 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7087 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7088 const RCP<Teuchos::ParameterList>& params); 7090 #define TPETRA_CRSMATRIX_INSTANT(SCALAR, LO, GO ,NODE) \ 7091 TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR, LO, GO, NODE) \ 7092 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7093 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) 7095 #endif // TPETRA_CRSMATRIX_DEF_HPP void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
LocalOrdinal sumIntoLocalValues(const LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Sum into one or more sparse matrix entries, using local indices.
Kokkos::CrsMatrix< impl_scalar_type, LocalOrdinal, execution_space, void, typename local_graph_type::size_type > local_matrix_type
The specialization of Kokkos::CrsMatrix that represents the part of the sparse matrix on each MPI pro...
std::string description() const
A one-line description of this object.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
void reindexColumns(crs_graph_type *const graph, const Teuchos::RCP< const map_type > &newColMap, const Teuchos::RCP< const import_type > &newImport=Teuchos::null, const bool sortEachRow=true)
Reindex the column indices in place, and replace the column Map. Optionally, replace the Import objec...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::RCP< node_type > getNode() const
The Kokkos Node instance.
Functor for the the ABSMAX CombineMode of Import and Export operations.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
Teuchos::ArrayView< const impl_scalar_type > getView(RowInfo rowinfo) const
Constant view of all entries (including extra space) in the given row.
void getLocalRowCopy(LocalOrdinal localRow, const Teuchos::ArrayView< LocalOrdinal > &colInds, const Teuchos::ArrayView< Scalar > &vals, size_t &numEntries) const
Fill given arrays with a deep copy of the locally owned entries of the matrix in a given row...
virtual bool isLocallyIndexed() const =0
Whether matrix indices are locally indexed.
void checkInternalState() const
Check that this object's state is sane; throw if it's not.
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
Teuchos::RCP< const crs_graph_type > getCrsGraph() const
This matrix's graph, as a CrsGraph.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
Definition of the Tpetra::CrsGraph class.
void sortEntries()
Sort the entries of each row by their column indices.
Teuchos::RCP< const RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const
This matrix's graph, as a RowGraph.
virtual void copyAndPermute(const SrcDistObject &source, size_t numSameIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteToLIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteFromLIDs)
Perform copies and permutations that are local to this process.
void gaussSeidel(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &D, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps) const
"Hybrid" Jacobi + (Gauss-Seidel or SOR) on .
Teuchos::RCP< const map_type > getRowMap() const
The Map that describes the row distribution in this matrix.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
LocalOrdinal sumIntoGlobalValues(const GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Sum into one or more sparse matrix entries, using global indices.
void rightScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &x)
Details::EStorageStatus storageStatus_
Status of the matrix's storage, when not in a fill-complete state.
void getGlobalRowView(GlobalOrdinal GlobalRow, Teuchos::ArrayView< const GlobalOrdinal > &indices, Teuchos::ArrayView< const Scalar > &values) const
Get a constant, nonpersisting view of a row of this matrix, using global row and column indices...
Teuchos::RCP< const map_type > getColMap() const
The Map that describes the column distribution in this matrix.
One or more distributed dense vectors.
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0
The current number of entries on the calling process in the specified local row.
void mergeRedundantEntries()
Merge entries in each row with the same column indices.
bool isLocallyIndexed() const
Whether the matrix is locally indexed on the calling process.
virtual bool supportsRowViews() const
Return true if getLocalRowView() and getGlobalRowView() are valid for this object.
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.
bool isUpperTriangular() const
Indicates whether the matrix is upper triangular.
void replaceColMap(const Teuchos::RCP< const map_type > &newColMap)
Replace the matrix's column Map with the given Map.
virtual bool checkSizes(const SrcDistObject &source)
Compare the source and target (this) objects for compatibility.
void setAllValues(const typename local_matrix_type::row_map_type &rowPointers, const typename local_graph_type::entries_type::non_const_type &columnIndices, const typename local_matrix_type::values_type &values)
Sets the 1D pointer arrays of the graph.
size_t getNodeNumRows() const
The number of matrix rows owned by the calling process.
Node node_type
This class' fourth template parameter; the Kokkos device type.
bool fillComplete_
Whether the matrix is fill complete.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
GlobalOrdinal getIndexBase() const
The index base for global indices for this matrix.
void getGlobalRowCopy(GlobalOrdinal GlobalRow, const Teuchos::ArrayView< GlobalOrdinal > &Indices, const Teuchos::ArrayView< Scalar > &Values, size_t &NumEntries) const
Fill given arrays with a deep copy of the locally owned entries of the matrix in a given row...
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
Teuchos_Ordinal Array_size_type
Size type for Teuchos Array objects.
Teuchos::RCP< CrsMatrix< T, LocalOrdinal, GlobalOrdinal, Node, classic > > convert() const
Return another CrsMatrix with the same entries, but converted to a different Scalar type T...
CrsIJV()
Default constructor.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes owning zero rows from the Maps and their communicator.
void insertLocalValues(const LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert one or more entries into the matrix, using local indices.
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...
mag_type frobNorm_
Cached Frobenius norm of the (global) matrix.
Implementation details of Tpetra.
void insertGlobalValues(const GlobalOrdinal globalRow, const Teuchos::ArrayView< const GlobalOrdinal > &cols, const Teuchos::ArrayView< const Scalar > &vals)
Insert one or more entries into the matrix, using global indices.
void reduce()
Sum values of a locally replicated multivector across all processes.
void fillLocalMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local matrix.
size_t global_size_t
Global size_t object.
virtual void getGlobalRowCopy(GlobalOrdinal GlobalRow, const Teuchos::ArrayView< GlobalOrdinal > &Indices, const Teuchos::ArrayView< Scalar > &Values, size_t &NumEntries) const =0
Get a copy of the given global row's entries.
Kokkos::StaticCrsGraph< LocalOrdinal, Kokkos::LayoutLeft, execution_space > local_graph_type
The type of the part of the sparse graph on each MPI process.
Traits class for "invalid" (flag) values of integer types that Tpetra uses as local ordinals or globa...
Insert new values that don't currently exist.
void getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &diag) const
Get a copy of the diagonal entries of the matrix.
dual_view_type getDualView() const
Get the Kokkos::DualView which implements local storage.
Teuchos::RCP< MV > getRowMapMultiVector(const MV &Y_rangeMap, const bool force=false) const
Create a (or fetch a cached) row Map MultiVector.
bool isLowerTriangular() const
Indicates whether the matrix is lower triangular.
ESweepDirection
Sweep direction for Gauss-Seidel or Successive Over-Relaxation (SOR).
void allocateValues(ELocalGlobal lg, GraphAllocationStatus gas)
Allocate values (and optionally indices) using the Node.
LocalOrdinal replaceLocalValues(const LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace one or more entries' values, using local indices.
Teuchos::RCP< const map_type > getDomainMap() const
The domain Map of this matrix.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
bool isFillComplete() const
Whether the matrix is fill complete.
void scale(const Scalar &alpha)
Scale the matrix's values: this := alpha*this.
void resumeFill(const RCP< ParameterList > ¶ms=null)
Resume operations that may change the values or structure of the matrix.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
#define TPETRA_ABUSE_WARNING(throw_exception_test, Exception, msg)
Handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WA...
void unpackAndCombine(const Teuchos::ArrayView< const LocalOrdinal > &importLIDs, const Teuchos::ArrayView< const char > &imports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t constantNumPackets, Distributor &distor, CombineMode combineMode)
Unpack the imported column indices and values, and combine into matrix.
Sets up and executes a communication plan for a Tpetra DistObject.
void reorderedGaussSeidel(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &D, const Teuchos::ArrayView< LocalOrdinal > &rowIndices, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps) const
Reordered "Hybrid" Jacobi + (Gauss-Seidel or SOR) on .
Struct representing a sparse matrix entry as an i,j,v triplet.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
CombineMode
Rule for combining data in an Import or Export.
bool isStorageOptimized() const
Returns true if storage has been optimized.
Sum new values into existing values.
Teuchos::RCP< Node > getNode() const
Get this Map's Node object.
void exportAndFillComplete(Teuchos::RCP< CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > &destMatrix, const export_type &exporter, const Teuchos::RCP< const map_type > &domainMap=Teuchos::null, const Teuchos::RCP< const map_type > &rangeMap=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null) const
Export from this to the given destination matrix, and make the result fill complete.
Teuchos::RCP< const map_type > map_
The Map over which this object is distributed.
size_t getNodeNumDiags() const
Returns the number of local diagonal entries, based on global row/column index comparisons.
Utility functions for packing and unpacking sparse matrix entries.
bool isDistributed() const
Whether this is a globally distributed object.
ProfileType getProfileType() const
Returns true if the matrix was allocated with static data structures.
virtual ~CrsMatrix()
Destructor.
Replace old value with maximum of magnitudes of old and new values.
Abstract base class for objects that can be the source of an Import or Export operation.
global_size_t getGlobalNumRows() const
Number of global elements in the row map of this matrix.
global_size_t getGlobalNumDiags() const
Returns the number of global diagonal entries, based on global row/column index comparisons.
void replaceDomainMapAndImporter(const Teuchos::RCP< const map_type > &newDomainMap, Teuchos::RCP< const import_type > &newImporter)
Replace the current domain Map and Import with the given objects.
Teuchos::RCP< MV > getColumnMapMultiVector(const MV &X_domainMap, const bool force=false) const
Create a (or fetch a cached) column Map MultiVector.
Replace existing values with new values.
#define TPETRA_EFFICIENCY_WARNING(throw_exception_test, Exception, msg)
Print or throw an efficency warning.
Binary function that returns its second argument.
void reindexColumns(const Teuchos::RCP< const map_type > &newColMap, const Teuchos::RCP< const import_type > &newImport=Teuchos::null, const bool sortIndicesInEachRow=true)
Reindex the column indices in place, and replace the column Map. Optionally, replace the Import objec...
bool hasTransposeApply() const
Whether apply() allows applying the transpose or conjugate transpose.
Scalar v
Value of matrix entry.
void computeGlobalConstants()
Compute matrix properties that require collectives.
bool isFillActive() const
Whether the matrix is not fill complete.
bool isStaticGraph() const
Indicates that the graph is static, so that new entries cannot be added to this matrix.
Replace old values with zero.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
global_size_t getGlobalNumCols() const
The number of global columns in the matrix.
bool hasColMap() const
Indicates whether the matrix has a well-defined column map.
mag_type getFrobeniusNorm() const
Compute and return the Frobenius norm of the matrix.
Kokkos::Details::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
LocalOrdinal replaceGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace one or more entries' values, using global indices.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
void leftScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &x)
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Teuchos::RCP< MV > importMV_
Column Map MultiVector used in apply() and gaussSeidel().
Ordinal i
(Global) row index
Kokkos::DualView< impl_scalar_type **, Kokkos::LayoutLeft, typename execution_space::execution_space > dual_view_type
Kokkos::DualView specialization used by this class.
Describes a parallel distribution of objects over processes.
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
global_size_t getGlobalNumEntries() const
The global number of entries in this matrix.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects...
A read-only, row-oriented interface to a sparse matrix.
Scalar operator()(const Scalar &x, const Scalar &y)
Return the maximum of the magnitudes (absolute values) of x and y.
std::map< GlobalOrdinal, std::pair< Teuchos::Array< GlobalOrdinal >, Teuchos::Array< Scalar > > > nonlocals_
Nonlocal data added using insertGlobalValues().
A distributed dense vector.
Stand-alone utility functions and macros.
virtual void pack(const Teuchos::ArrayView< const LocalOrdinal > &exportLIDs, Teuchos::Array< char > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, Distributor &distor) const
Pack this object's data for an Import or Export.
void expertStaticFillComplete(const RCP< const map_type > &domainMap, const RCP< const map_type > &rangeMap, const RCP< const import_type > &importer=Teuchos::null, const RCP< const export_type > &exporter=Teuchos::null, const RCP< ParameterList > ¶ms=Teuchos::null)
Perform a fillComplete on a matrix that already has data.
Ordinal j
(Global) column index
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
size_t getNumVectors() const
Number of columns in the multivector.
void doExport(const SrcDistObject &source, const Export< LocalOrdinal, GlobalOrdinal, Node > &exporter, CombineMode CM)
Export data into this object using an Export object ("forward mode").
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
void globalAssemble()
Communicate nonlocal contributions to other processes.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
void gaussSeidelCopy(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &D, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps, const bool zeroInitialGuess) const
Version of gaussSeidel(), with fewer requirements on X.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
void applyNonTranspose(const MV &X_in, MV &Y_in, Scalar alpha, Scalar beta) const
Special case of apply() for mode == Teuchos::NO_TRANS.
Teuchos::RCP< MV > exportMV_
Row Map MultiVector used in apply().
void getLocalDiagOffsets(Teuchos::ArrayRCP< size_t > &offsets) const
Get offsets of the diagonal entries in the matrix.
void apply(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &X, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=ScalarTraits< Scalar >::one(), Scalar beta=ScalarTraits< Scalar >::zero()) const
Compute a sparse matrix-MultiVector multiply.
size_t getNodeNumCols() const
The number of columns connected to the locally owned rows of this matrix.
Teuchos::ArrayView< impl_scalar_type > getViewNonConst(RowInfo rowinfo)
Nonconst view of all entries (including extra space) in the given row.
void reorderedGaussSeidelCopy(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &D, const Teuchos::ArrayView< LocalOrdinal > &rowIndices, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps, const bool zeroInitialGuess) const
Version of reorderedGaussSeidel(), with fewer requirements on X.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.
size_t getNodeNumEntries() const
The local number of entries in this matrix.
virtual Teuchos::RCP< RowMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > add(const Scalar &alpha, const RowMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta, const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &domainMap, const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms) const
Implementation of RowMatrix::add: return alpha*A + beta*this.
void clearGlobalConstants()
Clear matrix properties that require collectives.
CrsIJV(Ordinal row, Ordinal col, const Scalar &val)
Standard constructor.
bool isGloballyIndexed() const
Whether the matrix is globally indexed on the calling process.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes the distribution of rows over processes.
void applyTranspose(const MV &X_in, MV &Y_in, const Teuchos::ETransp mode, Scalar alpha, Scalar beta) const
Special case of apply() for mode != Teuchos::NO_TRANS.
void fillComplete(const RCP< const map_type > &domainMap, const RCP< const map_type > &rangeMap, const RCP< ParameterList > ¶ms=null)
Signal that data entry is complete, specifying domain and range maps.
local_matrix_type lclMatrix_
The local sparse matrix.
void importAndFillComplete(Teuchos::RCP< CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > &destMatrix, const import_type &importer, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null) const
Import from this to the given destination matrix, and make the result fill complete.
void fillLocalGraphAndMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local graph and matrix.
Teuchos::RCP< const map_type > getRangeMap() const
The range Map of this matrix.
RowInfo getRowInfo(const size_t myRow) const
Get information about the locally owned row with local index myRow.
size_t getNodeMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.