42 #ifndef TPETRA_CRSMATRIX_DEF_HPP 43 #define TPETRA_CRSMATRIX_DEF_HPP 53 #include "Tpetra_RowMatrix.hpp" 58 #include "Tpetra_Details_getDiagCopyWithoutOffsets.hpp" 59 #include "Tpetra_Details_gathervPrint.hpp" 62 #include "Teuchos_SerialDenseMatrix.hpp" 63 #include "Kokkos_Sparse_getDiagCopy.hpp" 64 #include "Tpetra_Details_copyConvert.hpp" 65 #include "Tpetra_Details_Environment.hpp" 87 template<
class Scalar>
91 typedef Teuchos::ScalarTraits<Scalar> STS;
92 return std::max (STS::magnitude (x), STS::magnitude (y));
101 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
104 size_t maxNumEntriesPerRow,
106 const Teuchos::RCP<Teuchos::ParameterList>& params) :
111 fillComplete_ (false),
112 frobNorm_ (-STM::one ())
114 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, size_t, " 115 "ProfileType[, RCP<ParameterList>]): ";
116 Teuchos::RCP<crs_graph_type> graph;
118 graph = Teuchos::rcp (
new crs_graph_type (rowMap, maxNumEntriesPerRow,
121 catch (std::exception& e) {
122 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
123 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 124 "size_t, ProfileType[, RCP<ParameterList>]) threw an exception: " 131 staticGraph_ = myGraph_;
136 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
139 const Teuchos::ArrayRCP<const size_t>& NumEntriesPerRowToAlloc,
141 const Teuchos::RCP<Teuchos::ParameterList>& params) :
149 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, " 150 "ArrayRCP<const size_t>, ProfileType[, RCP<ParameterList>]): ";
151 Teuchos::RCP<crs_graph_type> graph;
153 graph = Teuchos::rcp (
new crs_graph_type (rowMap, NumEntriesPerRowToAlloc,
156 catch (std::exception &e) {
157 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
158 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 159 "ArrayRCP<const size_t>, ProfileType[, RCP<ParameterList>]) threw " 160 "an exception: " << e.what ());
166 staticGraph_ = graph;
171 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
174 const Teuchos::RCP<const map_type>& colMap,
175 size_t maxNumEntriesPerRow,
177 const Teuchos::RCP<Teuchos::ParameterList>& params) :
185 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, RCP<const Map>, " 186 "size_t, ProfileType[, RCP<ParameterList>]): ";
188 #ifdef HAVE_TPETRA_DEBUG 190 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
191 (! staticGraph_.is_null (), std::logic_error,
192 "staticGraph_ is not null at the beginning of the constructor. " 193 "Please report this bug to the Tpetra developers.");
194 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
195 (! myGraph_.is_null (), std::logic_error,
196 "myGraph_ is not null at the beginning of the constructor. " 197 "Please report this bug to the Tpetra developers.");
198 #endif // HAVE_TPETRA_DEBUG 200 Teuchos::RCP<crs_graph_type> graph;
206 catch (std::exception &e) {
207 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
208 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 209 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]) threw an " 210 "exception: " << e.what ());
216 staticGraph_ = myGraph_;
221 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
224 const Teuchos::RCP<const map_type>& colMap,
225 const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
227 const Teuchos::RCP<Teuchos::ParameterList>& params) :
235 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, RCP<const Map>, " 236 "ArrayRCP<const size_t>, ProfileType[, RCP<ParameterList>]): ";
237 Teuchos::RCP<crs_graph_type> graph;
239 graph = Teuchos::rcp (
new crs_graph_type (rowMap, colMap, numEntPerRow,
242 catch (std::exception &e) {
243 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
244 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 245 "RCP<const Map>, ArrayRCP<const size_t>, ProfileType[, " 246 "RCP<ParameterList>]) threw an exception: " << e.what ());
252 staticGraph_ = graph;
257 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
259 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
260 const Teuchos::RCP<Teuchos::ParameterList>& ) :
262 staticGraph_ (graph),
267 typedef typename local_matrix_type::values_type values_type;
268 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>[, " 269 "RCP<ParameterList>]): ";
270 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
271 (graph.is_null (), std::runtime_error,
"Input graph is null.");
272 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
273 (! graph->isFillComplete (), std::runtime_error,
"Input graph is not " 274 "fill complete. You must call fillComplete on the graph before using " 275 "it to construct a CrsMatrix. Note that calling resumeFill on the " 276 "graph makes it not fill complete, even if you had previously called " 277 "fillComplete. In that case, you must call fillComplete on the graph " 286 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
287 auto lclGraph = graph->getLocalGraph ();
288 const size_t numEnt = lclGraph.entries.dimension_0 ();
289 values_type val (
"Tpetra::CrsMatrix::val", numEnt);
292 numCols, val, lclGraph);
301 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
304 const Teuchos::RCP<const map_type>& colMap,
305 const typename local_matrix_type::row_map_type& rowPointers,
306 const typename local_graph_type::entries_type::non_const_type& columnIndices,
307 const typename local_matrix_type::values_type& values,
308 const Teuchos::RCP<Teuchos::ParameterList>& params) :
315 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, " 316 "RCP<const Map>, ptr, ind, val[, params]): ";
317 const char suffix[] =
". Please report this bug to the Tpetra developers.";
323 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
324 (values.dimension_0 () != columnIndices.dimension_0 (),
325 std::invalid_argument,
"Input arrays don't have matching dimensions. " 326 "values.dimension_0() = " << values.dimension_0 () <<
" != " 327 "columnIndices.dimension_0() = " << columnIndices.dimension_0 () <<
".");
328 #ifdef HAVE_TPETRA_DEBUG 329 if (rowPointers.dimension_0 () != 0) {
330 const size_t numEnt =
331 Details::getEntryOnHost (rowPointers, rowPointers.dimension_0 () - 1);
332 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
333 (numEnt != static_cast<size_t> (columnIndices.dimension_0 ()) ||
334 numEnt != static_cast<size_t> (values.dimension_0 ()),
335 std::invalid_argument,
"Last entry of rowPointers says that the matrix" 336 " has " << numEnt <<
" entr" << (numEnt != 1 ?
"ies" :
"y") <<
", but " 337 "the dimensions of columnIndices and values don't match this. " 338 "columnIndices.dimension_0() = " << columnIndices.dimension_0 () <<
339 " and values.dimension_0() = " << values.dimension_0 () <<
".");
341 #endif // HAVE_TPETRA_DEBUG 343 RCP<crs_graph_type> graph;
345 graph = Teuchos::rcp (
new crs_graph_type (rowMap, colMap, rowPointers,
346 columnIndices, params));
348 catch (std::exception& e) {
349 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
350 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 351 "RCP<const Map>, ptr, ind[, params]) threw an exception: " 359 auto lclGraph = graph->getLocalGraph ();
360 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
361 (lclGraph.row_map.dimension_0 () != rowPointers.dimension_0 () ||
362 lclGraph.entries.dimension_0 () != columnIndices.dimension_0 (),
363 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, " 364 "ind[, params]) did not set the local graph correctly." << suffix);
365 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
366 (lclGraph.entries.dimension_0 () != values.dimension_0 (),
367 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, ind[, " 368 "params]) did not set the local graph correctly. " 369 "lclGraph.entries.dimension_0() = " << lclGraph.entries.dimension_0 ()
370 <<
" != values.dimension_0() = " << values.dimension_0 () << suffix);
376 staticGraph_ = graph;
385 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
387 numCols, values, lclGraph);
388 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
389 (
lclMatrix_.values.dimension_0 () != values.dimension_0 (),
390 std::logic_error,
"Local matrix's constructor did not set the values " 391 "correctly. lclMatrix_.values.dimension_0() = " <<
392 lclMatrix_.values.dimension_0 () <<
" != values.dimension_0() = " <<
393 values.dimension_0 () << suffix);
403 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
406 const Teuchos::RCP<const map_type>& colMap,
407 const Teuchos::ArrayRCP<size_t>& ptr,
408 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
409 const Teuchos::ArrayRCP<Scalar>& val,
410 const Teuchos::RCP<Teuchos::ParameterList>& params) :
416 using Kokkos::Compat::getKokkosViewDeepCopy;
417 using Teuchos::av_reinterpret_cast;
419 typedef typename local_matrix_type::values_type values_type;
421 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, " 422 "RCP<const Map>, ptr, ind, val[, params]): ";
424 RCP<crs_graph_type> graph;
429 catch (std::exception& e) {
430 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
431 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 432 "RCP<const Map>, ArrayRCP<size_t>, ArrayRCP<LocalOrdinal>[, " 433 "RCP<ParameterList>]) threw an exception: " << e.what ());
439 staticGraph_ = graph;
452 auto lclGraph = staticGraph_->getLocalGraph ();
453 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
454 (static_cast<size_t> (lclGraph.row_map.dimension_0 ()) != static_cast<size_t> (ptr.size ()) ||
455 static_cast<size_t> (lclGraph.entries.dimension_0 ()) != static_cast<size_t> (ind.size ()),
456 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, " 457 "ind[, params]) did not set the local graph correctly. Please " 458 "report this bug to the Tpetra developers.");
460 const size_t numCols = staticGraph_->getColMap ()->getNodeNumElements ();
461 values_type valIn = getKokkosViewDeepCopy<device_type> (av_reinterpret_cast<IST> (val ()));
463 numCols, valIn, lclGraph);
472 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
475 const Teuchos::RCP<const map_type>& colMap,
477 const Teuchos::RCP<Teuchos::ParameterList>& params) :
480 k_values1D_ (lclMatrix.values),
485 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, " 486 "RCP<const Map>, local_matrix_type[, RCP<ParameterList>]): ";
487 Teuchos::RCP<crs_graph_type> graph;
490 lclMatrix.graph, params));
492 catch (std::exception& e) {
493 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
494 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, " 495 "RCP<const Map>, local_graph_type[, RCP<ParameterList>]) threw an " 496 "exception: " << e.what ());
498 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
499 (!graph->isFillComplete (), std::logic_error,
"CrsGraph constructor (RCP" 500 "<const Map>, RCP<const Map>, local_graph_type[, RCP<ParameterList>]) " 501 "did not produce a fill-complete graph. Please report this bug to the " 502 "Tpetra developers.");
507 staticGraph_ = graph;
511 #ifdef HAVE_TPETRA_DEBUG 512 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive (), std::logic_error,
513 "We're at the end of fillComplete(), but isFillActive() is true. " 514 "Please report this bug to the Tpetra developers.");
515 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete (), std::logic_error,
516 "We're at the end of fillComplete(), but isFillComplete() is false. " 517 "Please report this bug to the Tpetra developers.");
518 #endif // HAVE_TPETRA_DEBUG 522 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
527 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
528 Teuchos::RCP<const Teuchos::Comm<int> >
531 return getCrsGraphRef ().
getComm ();
534 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
538 return getCrsGraphRef ().
getNode ();
541 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
548 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
555 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
562 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
569 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
576 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
583 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
590 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
597 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
604 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
611 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
618 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
625 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
632 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
639 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
646 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
653 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
660 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
667 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
674 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
681 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
682 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
688 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
689 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
695 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
696 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
702 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
703 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
709 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
710 Teuchos::RCP<const RowGraph<LocalOrdinal, GlobalOrdinal, Node> >
713 if (staticGraph_ != Teuchos::null) {
719 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
720 Teuchos::RCP<const CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> >
723 if (staticGraph_ != Teuchos::null) {
729 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
733 if (! this->staticGraph_.is_null ()) {
734 return * (this->staticGraph_);
737 #ifdef HAVE_TPETRA_DEBUG 738 const char tfecfFuncName[] =
"getCrsGraphRef: ";
739 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
740 (this->myGraph_.is_null (), std::logic_error,
741 "Both staticGraph_ and myGraph_ are null. " 742 "Please report this bug to the Tpetra developers.");
743 #endif // HAVE_TPETRA_DEBUG 744 return * (this->myGraph_);
748 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
755 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
762 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
766 return myGraph_.is_null ();
769 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
776 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
783 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
788 using ::Tpetra::Details::ProfilingRegion;
789 const char tfecfFuncName[] =
"allocateValues: ";
790 ProfilingRegion regionAllocateValues (
"Tpetra::CrsMatrix::allocateValues");
792 #ifdef HAVE_TPETRA_DEBUG 793 const char suffix[] =
" Please report this bug to the Tpetra developers.";
795 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
796 (this->staticGraph_.is_null (), std::logic_error,
797 "staticGraph_ is null." << suffix);
802 if ((gas == GraphAlreadyAllocated) != this->staticGraph_->indicesAreAllocated ()) {
803 const char err1[] =
"The caller has asserted that the graph is ";
804 const char err2[] =
"already allocated, but the static graph says " 805 "that its indices are ";
806 const char err3[] =
"already allocated. Please report this bug to " 807 "the Tpetra developers.";
808 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
809 (gas == GraphAlreadyAllocated && ! this->staticGraph_->indicesAreAllocated (),
810 std::logic_error, err1 << err2 <<
"not " << err3);
811 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
812 (gas != GraphAlreadyAllocated && this->staticGraph_->indicesAreAllocated (),
813 std::logic_error, err1 <<
"not " << err2 << err3);
821 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
822 (! this->staticGraph_->indicesAreAllocated () &&
823 this->myGraph_.is_null (), std::logic_error,
824 "The static graph says that its indices are not allocated, " 825 "but the graph is not owned by the matrix." << suffix);
826 #endif // HAVE_TPETRA_DEBUG 828 if (gas == GraphNotYetAllocated) {
829 #ifdef HAVE_TPETRA_DEBUG 830 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
831 (this->myGraph_.is_null (), std::logic_error,
832 "gas = GraphNotYetAllocated, but myGraph_ is null." << suffix);
833 #endif // HAVE_TPETRA_DEBUG 835 this->myGraph_->allocateIndices (lg);
837 catch (std::exception& e) {
838 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
839 (
true, std::runtime_error,
"CrsGraph::allocateIndices " 840 "threw an exception: " << e.what ());
843 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
844 (
true, std::runtime_error,
"CrsGraph::allocateIndices " 845 "threw an exception not a subclass of std::exception.");
857 #ifdef HAVE_TPETRA_DEBUG 858 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
859 (this->staticGraph_.is_null (), std::logic_error,
860 "this->getProfileType() == StaticProfile, but staticGraph_ is null." 862 #endif // HAVE_TPETRA_DEBUG 864 const size_t lclNumRows = this->staticGraph_->getNodeNumRows ();
865 typename Graph::local_graph_type::row_map_type k_ptrs =
866 this->staticGraph_->k_rowPtrs_;
867 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
868 (k_ptrs.dimension_0 () != lclNumRows+1, std::logic_error,
869 "With StaticProfile, row offsets array has length " 870 << k_ptrs.dimension_0 () <<
" != (lclNumRows+1) = " 871 << (lclNumRows+1) <<
".");
873 const size_t lclTotalNumEntries =
874 Details::getEntryOnHost (k_ptrs, lclNumRows);
877 typedef typename local_matrix_type::values_type values_type;
879 values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
889 this->staticGraph_->template allocateValues2D<impl_scalar_type> ();
891 catch (std::exception& e) {
892 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
893 (
true, std::runtime_error,
"CrsGraph::allocateValues2D threw an " 894 "exception: " << e.what ());
897 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
898 (
true, std::runtime_error,
"CrsGraph::allocateValues2D threw an " 899 "exception not a subclass of std::exception.");
904 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
907 getAllValues (Teuchos::ArrayRCP<const size_t>& rowPointers,
908 Teuchos::ArrayRCP<const LocalOrdinal>& columnIndices,
909 Teuchos::ArrayRCP<const Scalar>& values)
const 912 const char tfecfFuncName[] =
"getAllValues: ";
913 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
914 columnIndices.size () != values.size (), std::runtime_error,
915 "Requires that columnIndices and values are the same size.");
917 RCP<const crs_graph_type> relevantGraph =
getCrsGraph ();
918 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
919 relevantGraph.is_null (), std::runtime_error,
920 "Requires that getCrsGraph() is not null.");
922 rowPointers = relevantGraph->getNodeRowPtrs ();
924 catch (std::exception &e) {
925 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
926 true, std::runtime_error,
927 "Caught exception while calling graph->getNodeRowPtrs(): " 931 columnIndices = relevantGraph->getNodePackedIndices ();
933 catch (std::exception &e) {
934 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
935 true, std::runtime_error,
936 "Caught exception while calling graph->getNodePackedIndices(): " 939 Teuchos::ArrayRCP<const impl_scalar_type> vals =
940 Kokkos::Compat::persistingView (k_values1D_);
941 values = Teuchos::arcp_reinterpret_cast<
const Scalar> (vals);
944 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
950 using ::Tpetra::Details::ProfilingRegion;
951 using Kokkos::create_mirror_view;
952 using Teuchos::arcp_const_cast;
953 using Teuchos::Array;
954 using Teuchos::ArrayRCP;
958 typedef typename local_matrix_type::row_map_type row_map_type;
959 typedef typename Graph::local_graph_type::entries_type::non_const_type lclinds_1d_type;
960 typedef typename local_matrix_type::values_type values_type;
961 ProfilingRegion regionFLGAM (
"Tpetra::CrsGraph::fillLocalGraphAndMatrix");
963 #ifdef HAVE_TPETRA_DEBUG 964 const char tfecfFuncName[] =
"fillLocalGraphAndMatrix (called from " 965 "fillComplete or expertStaticFillComplete): ";
966 #endif // HAVE_TPETRA_DEBUG 968 #ifdef HAVE_TPETRA_DEBUG 971 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
972 (myGraph_.is_null (), std::logic_error,
"The nonconst graph (myGraph_) " 973 "is null. This means that the matrix has a const (a.k.a. \"static\") " 974 "graph. fillComplete or expertStaticFillComplete should never call " 975 "fillLocalGraphAndMatrix in that case. " 976 "Please report this bug to the Tpetra developers.");
977 #endif // HAVE_TPETRA_DEBUG 987 typename row_map_type::non_const_type k_ptrs;
988 row_map_type k_ptrs_const;
989 lclinds_1d_type k_inds;
995 lclinds_1d_type k_lclInds1D_ = myGraph_->k_lclInds1D_;
997 typedef decltype (myGraph_->k_numRowEntries_) row_entries_type;
1018 typename row_entries_type::const_type numRowEnt_h =
1019 myGraph_->k_numRowEntries_;
1020 #ifdef HAVE_TPETRA_DEBUG 1021 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1022 (static_cast<size_t> (numRowEnt_h.dimension_0 ()) != lclNumRows,
1023 std::logic_error,
"(DynamicProfile branch) numRowEnt_h has the " 1024 "wrong length. numRowEnt_h.dimension_0() = " 1025 << numRowEnt_h.dimension_0 () <<
" != getNodeNumRows() = " 1026 << lclNumRows <<
".");
1027 #endif // HAVE_TPETRA_DEBUG 1032 k_ptrs =
typename row_map_type::non_const_type (
"Tpetra::CrsGraph::ptr",
1034 typename row_map_type::non_const_type::HostMirror h_ptrs =
1035 create_mirror_view (k_ptrs);
1043 const size_t lclTotalNumEntries =
1045 #ifdef HAVE_TPETRA_DEBUG 1046 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1047 (static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
1048 std::logic_error,
"(DynamicProfile branch) After packing h_ptrs, " 1049 "h_ptrs.dimension_0() = " << h_ptrs.dimension_0 () <<
" != " 1050 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1052 const size_t h_ptrs_lastEnt = h_ptrs(lclNumRows);
1053 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1054 (h_ptrs_lastEnt != lclTotalNumEntries, std::logic_error,
1055 "(DynamicProfile branch) After packing h_ptrs, h_ptrs(lclNumRows=" 1056 << lclNumRows <<
") = " << h_ptrs_lastEnt <<
" != total number " 1057 "of entries on the calling process = " << lclTotalNumEntries <<
".");
1059 #endif // HAVE_TPETRA_DEBUG 1062 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1063 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1066 typename lclinds_1d_type::HostMirror h_inds = create_mirror_view (k_inds);
1067 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
1070 ArrayRCP<Array<LocalOrdinal> > lclInds2D = myGraph_->lclInds2D_;
1071 for (
size_t row = 0; row < lclNumRows; ++row) {
1072 const size_t numEnt = numRowEnt_h(row);
1073 std::copy (lclInds2D[row].begin(),
1074 lclInds2D[row].begin() + numEnt,
1075 h_inds.ptr_on_device() + h_ptrs(row));
1076 std::copy (values2D_[row].begin(),
1077 values2D_[row].begin() + numEnt,
1078 h_vals.ptr_on_device() + h_ptrs(row));
1087 k_ptrs_const = k_ptrs;
1089 #ifdef HAVE_TPETRA_DEBUG 1091 if (k_ptrs.dimension_0 () != 0) {
1092 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
1093 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1094 (numOffsets != lclNumRows + 1, std::logic_error,
"(DynamicProfile " 1095 "branch) After copying into k_ptrs, k_ptrs.dimension_0() = " <<
1096 numOffsets <<
" != (lclNumRows+1) = " << (lclNumRows+1) <<
".");
1098 const auto valToCheck = Details::getEntryOnHost (k_ptrs, numOffsets-1);
1099 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1100 (static_cast<size_t> (valToCheck) != k_vals.dimension_0 (),
1101 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs(" 1102 << (numOffsets-1) <<
") = " << valToCheck <<
" != " 1103 "k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1104 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1105 (static_cast<size_t> (valToCheck) != k_inds.dimension_0 (),
1106 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs(" 1107 << (numOffsets-1) <<
") = " << valToCheck <<
" != " 1108 "k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1110 #endif // HAVE_TPETRA_DEBUG 1119 typename Graph::local_graph_type::row_map_type curRowOffsets =
1120 myGraph_->k_rowPtrs_;
1122 #ifdef HAVE_TPETRA_DEBUG 1123 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1124 (curRowOffsets.dimension_0 () == 0, std::logic_error,
1125 "(StaticProfile branch) curRowOffsets.dimension_0() == 0.");
1126 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1127 (curRowOffsets.dimension_0 () != lclNumRows + 1, std::logic_error,
1128 "(StaticProfile branch) curRowOffsets.dimension_0() = " 1129 << curRowOffsets.dimension_0 () <<
" != lclNumRows + 1 = " 1130 << (lclNumRows + 1) <<
".")
1132 const size_t numOffsets = curRowOffsets.dimension_0 ();
1133 const auto valToCheck =
1134 Details::getEntryOnHost (curRowOffsets, numOffsets - 1);
1135 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1137 myGraph_->k_lclInds1D_.dimension_0 () != valToCheck,
1138 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
1139 numOffsets <<
" != 0 and myGraph_->k_lclInds1D_.dimension_0() = " 1140 << myGraph_->k_lclInds1D_.dimension_0 () <<
" != curRowOffsets(" 1141 << numOffsets <<
") = " << valToCheck <<
".");
1143 #endif // HAVE_TPETRA_DEBUG 1145 if (myGraph_->nodeNumEntries_ != myGraph_->getNodeAllocationSize ()) {
1152 #ifdef HAVE_TPETRA_DEBUG 1153 if (curRowOffsets.dimension_0 () != 0) {
1154 const size_t numOffsets =
1155 static_cast<size_t> (curRowOffsets.dimension_0 ());
1156 const auto valToCheck =
1157 Details::getEntryOnHost (curRowOffsets, numOffsets-1);
1158 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1159 (static_cast<size_t> (valToCheck) !=
1160 static_cast<size_t> (k_values1D_.dimension_0 ()),
1161 std::logic_error,
"(StaticProfile unpacked branch) Before " 1162 "allocating or packing, curRowOffsets(" << (numOffsets-1) <<
") = " 1163 << valToCheck <<
" != k_values1D_.dimension_0()" 1164 " = " << k_values1D_.dimension_0 () <<
".");
1165 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1166 (static_cast<size_t> (valToCheck) !=
1167 static_cast<size_t> (myGraph_->k_lclInds1D_.dimension_0 ()),
1168 std::logic_error,
"(StaticProfile unpacked branch) Before " 1169 "allocating or packing, curRowOffsets(" << (numOffsets-1) <<
") = " 1171 <<
" != myGraph_->k_lclInds1D_.dimension_0() = " 1172 << myGraph_->k_lclInds1D_.dimension_0 () <<
".");
1174 #endif // HAVE_TPETRA_DEBUG 1182 size_t lclTotalNumEntries = 0;
1184 typename row_map_type::non_const_type::HostMirror h_ptrs;
1189 typename row_map_type::non_const_type
1190 packedRowOffsets (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
1191 typename row_entries_type::const_type numRowEnt_h =
1192 myGraph_->k_numRowEntries_;
1195 lclTotalNumEntries =
1199 k_ptrs = packedRowOffsets;
1200 k_ptrs_const = k_ptrs;
1203 #ifdef HAVE_TPETRA_DEBUG 1204 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1205 (static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
1207 "(StaticProfile unpacked branch) After packing k_ptrs, " 1208 "k_ptrs.dimension_0() = " << k_ptrs.dimension_0 () <<
" != " 1209 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
1211 const auto valToCheck = Details::getEntryOnHost (k_ptrs, lclNumRows);
1212 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1213 (valToCheck != lclTotalNumEntries, std::logic_error,
1214 "(StaticProfile unpacked branch) After filling k_ptrs, " 1215 "k_ptrs(lclNumRows=" << lclNumRows <<
") = " << valToCheck
1216 <<
" != total number of entries on the calling process = " 1217 << lclTotalNumEntries <<
".");
1219 #endif // HAVE_TPETRA_DEBUG 1222 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1223 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1235 typedef pack_functor<
typename Graph::local_graph_type::entries_type::non_const_type,
1236 typename Graph::local_graph_type::row_map_type>
1238 inds_packer_type indsPacker (k_inds, myGraph_->k_lclInds1D_,
1239 k_ptrs, curRowOffsets);
1241 typedef Kokkos::RangePolicy<exec_space, LocalOrdinal> range_type;
1242 Kokkos::parallel_for (range_type (0, lclNumRows), indsPacker);
1246 typedef pack_functor<values_type, row_map_type> vals_packer_type;
1247 vals_packer_type valsPacker (k_vals, this->k_values1D_,
1248 k_ptrs, curRowOffsets);
1249 Kokkos::parallel_for (range_type (0, lclNumRows), valsPacker);
1251 #ifdef HAVE_TPETRA_DEBUG 1252 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1253 (k_ptrs.dimension_0 () == 0, std::logic_error,
1254 "(StaticProfile \"Optimize Storage\" = " 1255 "true branch) After packing, k_ptrs.dimension_0() = 0. This " 1256 "probably means that k_rowPtrs_ was never allocated.");
1257 if (k_ptrs.dimension_0 () != 0) {
1258 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
1259 const auto valToCheck = Details::getEntryOnHost (k_ptrs, numOffsets - 1);
1260 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1261 (static_cast<size_t> (valToCheck) != k_vals.dimension_0 (),
1263 "(StaticProfile \"Optimize Storage\"=true branch) After packing, " 1264 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1265 " != k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1266 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1267 (static_cast<size_t> (valToCheck) != k_inds.dimension_0 (),
1269 "(StaticProfile \"Optimize Storage\"=true branch) After packing, " 1270 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1271 " != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1273 #endif // HAVE_TPETRA_DEBUG 1276 k_ptrs_const = myGraph_->k_rowPtrs_;
1277 k_inds = myGraph_->k_lclInds1D_;
1278 k_vals = this->k_values1D_;
1280 #ifdef HAVE_TPETRA_DEBUG 1281 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1282 (k_ptrs_const.dimension_0 () == 0, std::logic_error,
1283 "(StaticProfile \"Optimize Storage\"=false branch) " 1284 "k_ptrs_const.dimension_0() = 0. This probably means that " 1285 "k_rowPtrs_ was never allocated.");
1286 if (k_ptrs_const.dimension_0 () != 0) {
1287 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
1288 const auto valToCheck = Details::getEntryOnHost (k_ptrs_const, numOffsets - 1);
1289 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1290 (static_cast<size_t> (valToCheck) != k_vals.dimension_0 (),
1292 "(StaticProfile \"Optimize Storage\"=false branch) " 1293 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1294 <<
" != k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1295 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1296 (static_cast<size_t> (valToCheck) != k_inds.dimension_0 (),
1298 "(StaticProfile \"Optimize Storage\" = false branch) " 1299 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1300 <<
" != k_inds.dimension_0() = " << k_inds.dimension_0 () <<
".");
1302 #endif // HAVE_TPETRA_DEBUG 1306 #ifdef HAVE_TPETRA_DEBUG 1308 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1309 (static_cast<size_t> (k_ptrs_const.dimension_0 ()) != lclNumRows + 1,
1310 std::logic_error,
"After packing, k_ptrs_const.dimension_0() = " <<
1311 k_ptrs_const.dimension_0 () <<
" != lclNumRows+1 = " << (lclNumRows+1)
1313 if (k_ptrs_const.dimension_0 () != 0) {
1314 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.dimension_0 ());
1315 const size_t k_ptrs_const_numOffsetsMinus1 =
1316 Details::getEntryOnHost (k_ptrs_const, numOffsets - 1);
1317 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1318 (k_ptrs_const_numOffsetsMinus1 != k_vals.dimension_0 (),
1319 std::logic_error,
"After packing, k_ptrs_const(" << (numOffsets-1) <<
1320 ") = " << k_ptrs_const_numOffsetsMinus1 <<
" != k_vals.dimension_0()" 1321 " = " << k_vals.dimension_0 () <<
".");
1322 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1323 (k_ptrs_const_numOffsetsMinus1 != k_inds.dimension_0 (),
1324 std::logic_error,
"After packing, k_ptrs_const(" << (numOffsets-1) <<
1325 ") = " << k_ptrs_const_numOffsetsMinus1 <<
" != k_inds.dimension_0()" 1326 " = " << k_inds.dimension_0 () <<
".");
1328 #endif // HAVE_TPETRA_DEBUG 1334 const bool defaultOptStorage =
1336 const bool requestOptimizedStorage =
1337 (! params.is_null () && params->get (
"Optimize Storage", defaultOptStorage)) ||
1338 (params.is_null () && defaultOptStorage);
1345 if (requestOptimizedStorage) {
1351 myGraph_->lclInds2D_ = null;
1352 myGraph_->k_numRowEntries_ = row_entries_type ();
1355 this->values2D_ = null;
1358 myGraph_->k_rowPtrs_ = k_ptrs_const;
1359 myGraph_->k_lclInds1D_ = k_inds;
1360 this->k_values1D_ = k_vals;
1364 myGraph_->storageStatus_ = Details::STORAGE_1D_PACKED;
1376 myGraph_->lclGraph_ =
1382 myGraph_->lclGraph_);
1385 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1390 using ::Tpetra::Details::ProfilingRegion;
1391 using Kokkos::create_mirror_view;
1392 using Teuchos::ArrayRCP;
1393 using Teuchos::Array;
1394 using Teuchos::null;
1397 typedef LocalOrdinal LO;
1398 typedef typename Graph::local_graph_type::row_map_type row_map_type;
1399 typedef typename row_map_type::non_const_type non_const_row_map_type;
1400 typedef typename local_matrix_type::values_type values_type;
1401 #ifdef HAVE_TPETRA_DEBUG 1402 const char tfecfFuncName[] =
"fillLocalMatrix (called from fillComplete): ";
1403 #endif // HAVE_TPETRA_DEBUG 1404 ProfilingRegion regionFLM (
"Tpetra::CrsGraph::fillLocalMatrix");
1408 RCP<node_type> node = rowMap.
getNode ();
1419 ArrayRCP<Array<LO> > lclInds2D = staticGraph_->lclInds2D_;
1420 size_t nodeNumEntries = staticGraph_->nodeNumEntries_;
1421 size_t nodeNumAllocated = staticGraph_->getNodeAllocationSize ();
1422 row_map_type k_rowPtrs_ = staticGraph_->lclGraph_.row_map;
1424 row_map_type k_ptrs;
1430 bool requestOptimizedStorage =
true;
1431 const bool default_OptimizeStorage =
1433 if (! params.is_null () && ! params->get (
"Optimize Storage", default_OptimizeStorage)) {
1434 requestOptimizedStorage =
false;
1441 if (! staticGraph_->isStorageOptimized () && requestOptimizedStorage) {
1443 "You requested optimized storage by setting the" 1444 "\"Optimize Storage\" flag to \"true\" in the parameter list, or by virtue" 1445 "of default behavior. However, the associated CrsGraph was filled separately" 1446 "and requested not to optimize storage. Therefore, the CrsMatrix cannot" 1447 "optimize storage.");
1448 requestOptimizedStorage =
false;
1451 typedef decltype (staticGraph_->k_numRowEntries_) row_entries_type;
1476 size_t lclTotalNumEntries = 0;
1478 typename non_const_row_map_type::HostMirror h_ptrs;
1480 typename row_entries_type::const_type numRowEnt_h =
1481 staticGraph_->k_numRowEntries_;
1483 non_const_row_map_type packedRowOffsets (
"Tpetra::CrsGraph::ptr",
1487 h_ptrs = create_mirror_view (packedRowOffsets);
1491 k_ptrs = packedRowOffsets;
1494 #ifdef HAVE_TPETRA_DEBUG 1495 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1496 (static_cast<size_t> (k_ptrs.dimension_0 ()) != lclNumRows + 1,
1497 std::logic_error,
"In DynamicProfile branch, after packing k_ptrs, " 1498 "k_ptrs.dimension_0() = " << k_ptrs.dimension_0 () <<
" != " 1499 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1500 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1501 (static_cast<size_t> (h_ptrs.dimension_0 ()) != lclNumRows + 1,
1502 std::logic_error,
"In DynamicProfile branch, after packing h_ptrs, " 1503 "h_ptrs.dimension_0() = " << h_ptrs.dimension_0 () <<
" != " 1504 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1506 const auto valToCheck = Details::getEntryOnHost (k_ptrs, lclNumRows);
1507 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1508 (static_cast<size_t> (valToCheck) != lclTotalNumEntries,
1509 std::logic_error,
"(DynamicProfile branch) After packing k_ptrs, " 1510 "k_ptrs(lclNumRows = " << lclNumRows <<
") = " << valToCheck
1511 <<
" != total number of entries on the calling process = " 1512 << lclTotalNumEntries <<
".");
1514 #endif // HAVE_TPETRA_DEBUG 1517 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1519 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
1521 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1522 const size_t numEnt = numRowEnt_h(lclRow);
1523 std::copy (values2D_[lclRow].begin(),
1524 values2D_[lclRow].begin() + numEnt,
1525 h_vals.ptr_on_device() + h_ptrs(lclRow));
1530 #ifdef HAVE_TPETRA_DEBUG 1532 if (k_ptrs.dimension_0 () != 0) {
1533 const size_t numOffsets =
static_cast<size_t> (k_ptrs.dimension_0 ());
1534 const auto valToCheck =
1535 Details::getEntryOnHost (k_ptrs, numOffsets - 1);
1536 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1537 (static_cast<size_t> (valToCheck) != k_vals.dimension_0 (),
1538 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs(" 1539 << (numOffsets-1) <<
") = " << valToCheck <<
" != " 1540 "k_vals.dimension_0() = " << k_vals.dimension_0 () <<
".");
1542 #endif // HAVE_TPETRA_DEBUG 1562 if (nodeNumEntries != nodeNumAllocated) {
1565 non_const_row_map_type tmpk_ptrs (
"Tpetra::CrsGraph::ptr",
1570 size_t lclTotalNumEntries = 0;
1573 typename row_entries_type::const_type numRowEnt_d =
1574 staticGraph_->k_numRowEntries_;
1582 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1585 typedef pack_functor<values_type, row_map_type> packer_type;
1586 packer_type valsPacker (k_vals, k_values1D_, tmpk_ptrs, k_rowPtrs_);
1589 typedef Kokkos::RangePolicy<exec_space, LocalOrdinal> range_type;
1590 Kokkos::parallel_for (range_type (0, lclNumRows), valsPacker);
1593 k_vals = k_values1D_;
1598 if (requestOptimizedStorage) {
1602 k_values1D_ = k_vals;
1613 staticGraph_->getLocalGraph ());
1616 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1620 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1621 const Teuchos::ArrayView<const Scalar>& values)
1623 using Teuchos::Array;
1624 using Teuchos::ArrayView;
1625 using Teuchos::av_reinterpret_cast;
1626 using Teuchos::toString;
1628 const char tfecfFuncName[] =
"insertLocalValues";
1630 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillActive (), std::runtime_error,
1631 ": Fill is not active. After calling fillComplete, you must call " 1632 "resumeFill before you may insert entries into the matrix again.");
1633 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isStaticGraph (), std::runtime_error,
1634 " cannot insert indices with static graph; use replaceLocalValues() instead.");
1635 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(myGraph_->isGloballyIndexed(),
1636 std::runtime_error,
": graph indices are global; use insertGlobalValues().");
1637 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
hasColMap (), std::runtime_error,
1638 " cannot insert local indices without a column map.");
1639 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(values.size() != indices.size(),
1640 std::runtime_error,
": values.size() must equal indices.size().");
1641 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1642 !
getRowMap()->isNodeLocalElement(localRow), std::runtime_error,
1643 ": Local row index " << localRow <<
" does not belong to this process.");
1645 if (! myGraph_->indicesAreAllocated ()) {
1649 catch (std::exception& e) {
1650 TEUCHOS_TEST_FOR_EXCEPTION(
1651 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1652 "allocateValues(LocalIndices,GraphNotYetAllocated) threw an " 1653 "exception: " << e.what ());
1657 const size_t numEntriesToAdd =
static_cast<size_t> (indices.size ());
1658 #ifdef HAVE_TPETRA_DEBUG 1665 Array<LocalOrdinal> badColInds;
1666 bool allInColMap =
true;
1667 for (
size_t k = 0; k < numEntriesToAdd; ++k) {
1669 allInColMap =
false;
1670 badColInds.push_back (indices[k]);
1673 if (! allInColMap) {
1674 std::ostringstream os;
1675 os <<
"Tpetra::CrsMatrix::insertLocalValues: You attempted to insert " 1676 "entries in owned row " << localRow <<
", at the following column " 1677 "indices: " << toString (indices) <<
"." << endl;
1678 os <<
"Of those, the following indices are not in the column Map on " 1679 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 1680 "the matrix has a column Map already, it is invalid to insert " 1681 "entries at those locations.";
1682 TEUCHOS_TEST_FOR_EXCEPTION(! allInColMap, std::invalid_argument, os.str ());
1685 #endif // HAVE_TPETRA_DEBUG 1687 #ifdef HAVE_TPETRA_DEBUG 1690 rowInfo = myGraph_->getRowInfo (localRow);
1691 }
catch (std::exception& e) {
1692 TEUCHOS_TEST_FOR_EXCEPTION(
1693 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1694 "myGraph_->getRowInfo threw an exception: " << e.what ());
1697 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1698 #endif // HAVE_TPETRA_DEBUG 1700 const size_t curNumEntries = rowInfo.numEntries;
1701 const size_t newNumEntries = curNumEntries + numEntriesToAdd;
1702 if (newNumEntries > rowInfo.allocSize) {
1703 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1705 ": new indices exceed statically allocated graph structure.");
1709 rowInfo = myGraph_->template updateLocalAllocAndValues<impl_scalar_type> (rowInfo,
1711 values2D_[localRow]);
1712 }
catch (std::exception& e) {
1713 TEUCHOS_TEST_FOR_EXCEPTION(
1714 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1715 "myGraph_->updateGlobalAllocAndValues threw an exception: " 1719 typename Graph::SLocalGlobalViews indsView;
1720 indsView.linds = indices;
1722 #ifdef HAVE_TPETRA_DEBUG 1723 ArrayView<impl_scalar_type> valsView;
1726 }
catch (std::exception& e) {
1727 TEUCHOS_TEST_FOR_EXCEPTION(
1728 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1729 "getViewNonConst threw an exception: " << e.what ());
1732 ArrayView<impl_scalar_type> valsView = this->
getViewNonConst (rowInfo);
1733 #endif // HAVE_TPETRA_DEBUG 1735 ArrayView<const impl_scalar_type> valsIn =
1738 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, indsView,
1742 }
catch (std::exception& e) {
1743 TEUCHOS_TEST_FOR_EXCEPTION(
1744 true, std::runtime_error,
"Tpetra::CrsMatrix::insertLocalValues: " 1745 "myGraph_->insertIndicesAndValues threw an exception: " 1749 #ifdef HAVE_TPETRA_DEBUG 1750 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
1751 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1752 chkNewNumEntries != newNumEntries, std::logic_error,
1753 ": The row should have " << newNumEntries <<
" entries after insert, but " 1754 "instead has " << chkNewNumEntries <<
". Please report this bug to the " 1755 "Tpetra developers.");
1756 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isLocallyIndexed(), std::logic_error,
1757 ": At end of insertLocalValues(), this CrsMatrix is not locally indexed. " 1758 "Please report this bug to the Tpetra developers.");
1759 #endif // HAVE_TPETRA_DEBUG 1762 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1766 const LocalOrdinal numEnt,
1767 const Scalar vals[],
1768 const LocalOrdinal cols[])
1770 Teuchos::ArrayView<const LocalOrdinal> colsT (cols, numEnt);
1771 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
1775 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1779 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1780 const Teuchos::ArrayView<const Scalar>& values)
1782 using Teuchos::Array;
1783 using Teuchos::ArrayView;
1784 using Teuchos::av_reinterpret_cast;
1785 const char tfecfFuncName[] =
"insertLocalValues: ";
1787 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillActive (), std::runtime_error,
1788 "Requires that fill is active.");
1789 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isStaticGraph (), std::runtime_error,
1790 "Cannot insert indices with static graph; use replaceLocalValues() instead.");
1791 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(myGraph_->isGloballyIndexed(),
1792 std::runtime_error,
"Graph indices are global; use insertGlobalValues().");
1793 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1794 !
hasColMap (), std::runtime_error,
"The matrix has no column Map yet, " 1795 "so you cannot insert local indices. If you created the matrix without " 1796 "a column Map (or without a fill-complete graph), you must call " 1797 "fillComplete to create the column Map, before you may work with local " 1799 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1800 values.size () != indices.size (), std::runtime_error,
"values.size() = " 1801 << values.size () <<
" != indices.size() = " << indices.size ()<<
".");
1802 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1803 !
getRowMap()->isNodeLocalElement (localRow), std::runtime_error,
1804 "Local row index " << localRow <<
" does not belong to this process.");
1805 if (! myGraph_->indicesAreAllocated ()) {
1810 Array<LocalOrdinal> f_inds (indices);
1811 ArrayView<const impl_scalar_type> valsIn =
1813 Array<impl_scalar_type> f_vals (valsIn);
1814 const size_t numFilteredEntries =
1815 myGraph_->template filterLocalIndicesAndValues<impl_scalar_type> (f_inds (),
1817 if (numFilteredEntries > 0) {
1818 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1819 const size_t curNumEntries = rowInfo.numEntries;
1820 const size_t newNumEntries = curNumEntries + numFilteredEntries;
1821 if (newNumEntries > rowInfo.allocSize) {
1822 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1824 ": new indices exceed statically allocated graph structure. " 1825 "newNumEntries (" << newNumEntries <<
" > rowInfo.allocSize (" 1826 << rowInfo.allocSize <<
").");
1829 myGraph_->template updateLocalAllocAndValues<impl_scalar_type> (rowInfo,
1831 values2D_[localRow]);
1833 typename Graph::SLocalGlobalViews inds_view;
1834 inds_view.linds = f_inds (0, numFilteredEntries);
1835 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
1837 f_vals, LocalIndices,
1839 #ifdef HAVE_TPETRA_DEBUG 1840 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
1841 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
1842 std::logic_error,
": Internal logic error. Please contact Tpetra team.");
1843 #endif // HAVE_TPETRA_DEBUG 1845 #ifdef HAVE_TPETRA_DEBUG 1846 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isLocallyIndexed(), std::logic_error,
1847 ": At end of insertLocalValues(), this CrsMatrix is not locally indexed. " 1848 "Please report this bug to the Tpetra developers.");
1849 #endif // HAVE_TPETRA_DEBUG 1853 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1857 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
1858 const Teuchos::ArrayView<const Scalar>& values)
1860 using Teuchos::Array;
1861 using Teuchos::ArrayView;
1862 using Teuchos::av_reinterpret_cast;
1863 using Teuchos::toString;
1865 typedef LocalOrdinal LO;
1866 typedef GlobalOrdinal GO;
1867 typedef typename ArrayView<const GO>::size_type size_type;
1868 const char tfecfFuncName[] =
"insertGlobalValues: ";
1870 #ifdef HAVE_TPETRA_DEBUG 1871 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1872 values.size () != indices.size (), std::runtime_error,
1873 "values.size() = " << values.size() <<
" != indices.size() = " 1874 << indices.size() <<
".");
1875 #endif // HAVE_TPETRA_DEBUG 1877 const LO localRow =
getRowMap ()->getLocalElement (globalRow);
1879 if (localRow == OTL::invalid ()) {
1880 insertNonownedGlobalValues (globalRow, indices, values);
1885 std::ostringstream err;
1886 const int myRank =
getRowMap ()->getComm ()->getRank ();
1887 const int numProcs =
getRowMap ()->getComm ()->getSize ();
1889 err <<
"The matrix was constructed with a constant (\"static\") graph, " 1890 "yet the given global row index " << globalRow <<
" is in the row " 1891 "Map on the calling process (with rank " << myRank <<
", of " <<
1892 numProcs <<
" process(es)). In this case, you may not insert new " 1893 "entries into rows owned by the calling process.";
1895 if (!
getRowMap ()->isNodeGlobalElement (globalRow)) {
1896 err <<
" Furthermore, GID->LID conversion with the row Map claims that " 1897 "the global row index is owned on the calling process, yet " 1898 "getRowMap()->isNodeGlobalElement(globalRow) returns false. That's" 1899 " weird! This might indicate a Map bug. Please report this to the" 1900 " Tpetra developers.";
1902 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1906 if (! myGraph_->indicesAreAllocated ()) {
1910 catch (std::exception& e) {
1911 TEUCHOS_TEST_FOR_EXCEPTION(
1912 true, std::runtime_error,
"Tpetra::CrsMatrix::insertGlobalValues: " 1913 "allocateValues(GlobalIndices,GraphNotYetAllocated) threw an " 1914 "exception: " << e.what ());
1918 const size_type numEntriesToInsert = indices.size ();
1931 #ifdef HAVE_TPETRA_DEBUG 1932 Array<GO> badColInds;
1933 #endif // HAVE_TPETRA_DEBUG 1934 bool allInColMap =
true;
1935 for (size_type k = 0; k < numEntriesToInsert; ++k) {
1937 allInColMap =
false;
1938 #ifdef HAVE_TPETRA_DEBUG 1939 badColInds.push_back (indices[k]);
1942 #endif // HAVE_TPETRA_DEBUG 1945 if (! allInColMap) {
1946 std::ostringstream os;
1947 os <<
"You attempted to insert entries in owned row " << globalRow
1948 <<
", at the following column indices: " << toString (indices)
1950 #ifdef HAVE_TPETRA_DEBUG 1951 os <<
"Of those, the following indices are not in the column Map on " 1952 "this process: " << toString (badColInds) <<
"." << endl <<
"Since " 1953 "the matrix has a column Map already, it is invalid to insert " 1954 "entries at those locations.";
1956 os <<
"At least one of those indices is not in the column Map on this " 1957 "process." << endl <<
"It is invalid to insert into columns not in " 1958 "the column Map on the process that owns the row.";
1959 #endif // HAVE_TPETRA_DEBUG 1960 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1961 ! allInColMap, std::invalid_argument, os.str ());
1965 typename Graph::SLocalGlobalViews inds_view;
1966 ArrayView<const impl_scalar_type> vals_view;
1968 inds_view.ginds = indices;
1971 #ifdef HAVE_TPETRA_DEBUG 1974 rowInfo = myGraph_->getRowInfo (localRow);
1975 }
catch (std::exception& e) {
1976 TEUCHOS_TEST_FOR_EXCEPTION(
1977 true, std::runtime_error,
"myGraph_->getRowInfo(localRow=" << localRow
1978 <<
") threw an exception: " << e.what ());
1981 RowInfo rowInfo = myGraph_->getRowInfo (localRow);
1982 #endif // HAVE_TPETRA_DEBUG 1984 const size_t curNumEntries = rowInfo.numEntries;
1985 const size_t newNumEntries =
1986 curNumEntries +
static_cast<size_t> (numEntriesToInsert);
1987 if (newNumEntries > rowInfo.allocSize) {
1988 TEUCHOS_TEST_FOR_EXCEPTION(
1990 std::runtime_error,
"Tpetra::CrsMatrix::insertGlobalValues: new " 1991 "indices exceed statically allocated graph structure. curNumEntries" 1992 " (" << curNumEntries <<
") + numEntriesToInsert (" <<
1993 numEntriesToInsert <<
") > allocSize (" << rowInfo.allocSize <<
").");
1998 myGraph_->template updateGlobalAllocAndValues<impl_scalar_type> (rowInfo,
2000 values2D_[localRow]);
2001 }
catch (std::exception& e) {
2002 TEUCHOS_TEST_FOR_EXCEPTION(
2003 true, std::runtime_error,
"myGraph_->updateGlobalAllocAndValues" 2004 "(...) threw an exception: " << e.what ());
2012 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
2015 GlobalIndices, GlobalIndices);
2021 myGraph_->template insertIndicesAndValues<impl_scalar_type> (rowInfo, inds_view,
2024 GlobalIndices, LocalIndices);
2027 catch (std::exception& e) {
2028 TEUCHOS_TEST_FOR_EXCEPTION(
2029 true, std::runtime_error,
"myGraph_->insertIndicesAndValues(...) " 2030 "threw an exception: " << e.what ());
2033 #ifdef HAVE_TPETRA_DEBUG 2034 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (localRow);
2035 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
2036 std::logic_error,
": There should be a total of " << newNumEntries
2037 <<
" entries in the row, but the graph now reports " << chkNewNumEntries
2038 <<
" entries. Please report this bug to the Tpetra developers.");
2039 #endif // HAVE_TPETRA_DEBUG 2044 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2048 const LocalOrdinal numEnt,
2049 const Scalar vals[],
2050 const GlobalOrdinal inds[])
2052 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
2053 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
2058 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2062 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2063 const Teuchos::ArrayView<const Scalar>& values)
2065 using Teuchos::Array;
2066 using Teuchos::ArrayView;
2067 using Teuchos::av_reinterpret_cast;
2068 typedef LocalOrdinal LO;
2069 typedef GlobalOrdinal GO;
2071 const char tfecfFuncName[] =
"insertGlobalValuesFiltered: ";
2081 #ifdef HAVE_TPETRA_DEBUG 2082 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2083 values.size () != indices.size (), std::runtime_error,
2084 "values.size() = " << values.size() <<
" != indices.size() = " 2085 << indices.size() <<
".");
2086 #endif // HAVE_TPETRA_DEBUG 2088 ArrayView<const ST> valsIn = av_reinterpret_cast<
const ST> (values);
2089 const LO lrow =
getRowMap ()->getLocalElement (globalRow);
2091 if (lrow != Teuchos::OrdinalTraits<LO>::invalid ()) {
2094 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2096 "The matrix was constructed with a static graph. In that case, " 2097 "it is forbidden to insert new entries into rows owned by the " 2098 "calling process.");
2099 if (! myGraph_->indicesAreAllocated ()) {
2102 typename Graph::SLocalGlobalViews inds_view;
2103 ArrayView<const ST> vals_view;
2108 Array<GO> filtered_indices;
2109 Array<ST> filtered_values;
2113 filtered_indices.assign (indices.begin (), indices.end ());
2114 filtered_values.assign (valsIn.begin (), valsIn.end ());
2115 const size_t numFilteredEntries =
2116 myGraph_->template filterGlobalIndicesAndValues<ST> (filtered_indices (),
2117 filtered_values ());
2118 inds_view.ginds = filtered_indices (0, numFilteredEntries);
2119 vals_view = filtered_values (0, numFilteredEntries);
2122 inds_view.ginds = indices;
2125 const size_t numFilteredEntries = vals_view.size ();
2127 if (numFilteredEntries > 0) {
2128 RowInfo rowInfo = myGraph_->getRowInfo (lrow);
2129 const size_t curNumEntries = rowInfo.numEntries;
2130 const size_t newNumEntries = curNumEntries + numFilteredEntries;
2131 if (newNumEntries > rowInfo.allocSize) {
2132 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2134 "New indices exceed statically allocated graph structure.");
2137 rowInfo = myGraph_->template updateGlobalAllocAndValues<ST> (rowInfo,
2145 myGraph_->template insertIndicesAndValues<ST> (rowInfo, inds_view,
2148 GlobalIndices, GlobalIndices);
2154 myGraph_->template insertIndicesAndValues<ST> (rowInfo, inds_view,
2157 GlobalIndices, LocalIndices);
2159 #ifdef HAVE_TPETRA_DEBUG 2161 const size_t chkNewNumEntries = myGraph_->getNumEntriesInLocalRow (lrow);
2162 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(chkNewNumEntries != newNumEntries,
2163 std::logic_error,
": There should be a total of " << newNumEntries
2164 <<
" entries in the row, but the graph now reports " << chkNewNumEntries
2165 <<
" entries. Please report this bug to the Tpetra developers.");
2167 #endif // HAVE_TPETRA_DEBUG 2171 insertNonownedGlobalValues (globalRow, indices, values);
2176 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2180 const Teuchos::ArrayView<const LocalOrdinal>& lclCols,
2181 const Teuchos::ArrayView<const Scalar>& vals)
const 2183 using Kokkos::MemoryUnmanaged;
2186 typedef LocalOrdinal LO;
2188 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2190 typedef View<const IST*, HD, MemoryUnmanaged> ISVT;
2191 typedef View<const LO*, HD, MemoryUnmanaged> LIVT;
2193 LIVT lclColsIn (lclCols.getRawPtr (), lclCols.size ());
2194 const IST* valsRaw =
reinterpret_cast<const IST*
> (vals.getRawPtr ());
2195 ISVT valsIn (valsRaw, vals.size ());
2196 return this->
template replaceLocalValues<LIVT, ISVT> (localRow,
2201 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2205 const LocalOrdinal numEnt,
2206 const Scalar inputVals[],
2207 const LocalOrdinal inputCols[])
const 2209 using Kokkos::MemoryUnmanaged;
2212 typedef LocalOrdinal LO;
2214 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2216 typedef View<const LO*, HD, MemoryUnmanaged> LIVT;
2217 typedef View<const IST*, HD, MemoryUnmanaged> ISVT;
2219 LIVT indsK (inputCols, numEnt);
2220 ISVT valsK (reinterpret_cast<const IST*> (inputVals), numEnt);
2221 return this->
template replaceLocalValues<LIVT, ISVT> (localRow,
2226 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2230 const Teuchos::ArrayView<const GlobalOrdinal>& inputInds,
2231 const Teuchos::ArrayView<const Scalar>& inputVals)
const 2233 using Kokkos::MemoryUnmanaged;
2236 typedef GlobalOrdinal GO;
2238 typedef typename View<GO*, DD>::HostMirror::device_type HD;
2240 typedef View<const GO*, HD, MemoryUnmanaged> GIVT;
2241 typedef View<const IST*, HD, MemoryUnmanaged> ISVT;
2243 const IST* inputValsRaw =
2244 reinterpret_cast<const IST*
> (inputVals.getRawPtr ());
2245 GIVT indsK (inputInds.getRawPtr (), inputInds.size ());
2246 ISVT valsK (inputValsRaw, inputVals.size ());
2247 return this->
template replaceGlobalValues<GIVT, ISVT> (globalRow,
2253 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2257 const LocalOrdinal numEnt,
2258 const Scalar inputVals[],
2259 const GlobalOrdinal inputCols[])
const 2261 using Kokkos::MemoryUnmanaged;
2264 typedef GlobalOrdinal GO;
2266 typedef typename View<GO*, DD>::HostMirror::device_type HD;
2268 typedef View<const GO*, HD, MemoryUnmanaged> GIVT;
2269 typedef View<const IST*, HD, MemoryUnmanaged> ISVT;
2271 GIVT indsK (inputCols, numEnt);
2272 ISVT valsK (reinterpret_cast<const IST*> (inputVals), numEnt);
2273 return this->
template replaceGlobalValues<GIVT, ISVT> (globalRow,
2279 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2283 const Teuchos::ArrayView<const GlobalOrdinal>& gblInputInds,
2284 const Teuchos::ArrayView<const Scalar>& inputVals,
2287 using Kokkos::MemoryUnmanaged;
2290 typedef LocalOrdinal LO;
2291 typedef GlobalOrdinal GO;
2293 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2297 return Teuchos::OrdinalTraits<LO>::invalid ();
2304 const LO lclRow = this->staticGraph_.is_null () ?
2305 this->myGraph_->rowMap_->getLocalElement (gblRow) :
2306 this->staticGraph_->rowMap_->getLocalElement (gblRow);
2309 if (lclRow == Teuchos::OrdinalTraits<LO>::invalid ()) {
2314 this->insertNonownedGlobalValues (gblRow, gblInputInds, inputVals);
2321 return static_cast<LO
> (gblInputInds.size ());
2323 else if (this->staticGraph_.is_null ()) {
2324 return Teuchos::OrdinalTraits<LO>::invalid ();
2327 const RowInfo rowInfo = this->staticGraph_->getRowInfo (lclRow);
2328 auto curVals = this->getRowViewNonConst (rowInfo);
2329 const IST* inputValsRaw =
reinterpret_cast<const IST*
> (inputVals.getRawPtr ());
2331 View<const IST*, HD, MemoryUnmanaged> valsIn (inputValsRaw, inputVals.size ());
2332 View<const GO*, HD, MemoryUnmanaged> indsIn (gblInputInds.getRawPtr (),
2333 gblInputInds.size ());
2334 return staticGraph_->template sumIntoGlobalValues<IST, HD, DD> (rowInfo,
2343 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2347 const LocalOrdinal numEnt,
2348 const Scalar inputVals[],
2349 const GlobalOrdinal gblInputInds[],
2352 using Kokkos::MemoryUnmanaged;
2355 typedef LocalOrdinal LO;
2356 typedef GlobalOrdinal GO;
2358 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2362 return Teuchos::OrdinalTraits<LO>::invalid ();
2369 const LO lclRow = this->staticGraph_.is_null () ?
2370 this->myGraph_->rowMap_->getLocalElement (gblRow) :
2371 this->staticGraph_->rowMap_->getLocalElement (gblRow);
2374 if (lclRow == Teuchos::OrdinalTraits<LO>::invalid ()) {
2377 using Teuchos::ArrayView;
2378 ArrayView<const GO> gblInputInds_av (numEnt == 0 ? NULL : gblInputInds, numEnt);
2379 ArrayView<const Scalar> inputVals_av (numEnt == 0 ? NULL : inputVals, numEnt);
2385 this->insertNonownedGlobalValues (gblRow, gblInputInds_av, inputVals_av);
2394 else if (this->staticGraph_.is_null ()) {
2395 return Teuchos::OrdinalTraits<LO>::invalid ();
2398 const RowInfo rowInfo = this->staticGraph_->getRowInfo (lclRow);
2399 auto curVals = this->getRowViewNonConst (rowInfo);
2400 const IST* inputValsIST =
reinterpret_cast<const IST*
> (inputVals);
2401 View<const IST*, HD, MemoryUnmanaged> valsIn (numEnt == 0 ? NULL : inputValsIST, numEnt);
2402 View<const GO*, HD, MemoryUnmanaged> indsIn (numEnt == 0 ? NULL : gblInputInds, numEnt);
2403 return staticGraph_->template sumIntoGlobalValues<IST, HD, DD> (rowInfo,
2412 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2416 const Teuchos::ArrayView<const LocalOrdinal>& indices,
2417 const Teuchos::ArrayView<const Scalar>& values,
2418 const bool atomic)
const 2420 using Kokkos::MemoryUnmanaged;
2423 typedef LocalOrdinal LO;
2425 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2426 typedef View<const IST*, HD, MemoryUnmanaged> IVT;
2427 typedef View<const LO*, HD, MemoryUnmanaged> IIT;
2429 const IST* valsRaw =
reinterpret_cast<const IST*
> (values.getRawPtr ());
2430 IVT valsIn (valsRaw, values.size ());
2431 IIT indsIn (indices.getRawPtr (), indices.size ());
2432 return this->
template sumIntoLocalValues<IIT, IVT> (localRow, indsIn,
2436 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2440 const LocalOrdinal numEnt,
2441 const Scalar vals[],
2442 const LocalOrdinal cols[],
2443 const bool atomic)
const 2445 using Kokkos::MemoryUnmanaged;
2448 typedef LocalOrdinal LO;
2450 typedef typename View<LO*, DD>::HostMirror::device_type HD;
2451 typedef View<const IST*, HD, MemoryUnmanaged> IVT;
2452 typedef View<const LO*, HD, MemoryUnmanaged> IIT;
2454 const IST* valsRaw =
reinterpret_cast<const IST*
> (vals);
2455 IVT valsIn (valsRaw, numEnt);
2456 IIT indsIn (cols, numEnt);
2457 return this->
template sumIntoLocalValues<IIT, IVT> (localRow, indsIn,
2462 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2463 Teuchos::ArrayView<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type>
2467 using Kokkos::MemoryUnmanaged;
2469 using Teuchos::ArrayView;
2471 typedef std::pair<size_t, size_t> range_type;
2473 if (k_values1D_.dimension_0 () != 0 && rowinfo.allocSize > 0) {
2474 #ifdef HAVE_TPETRA_DEBUG 2475 TEUCHOS_TEST_FOR_EXCEPTION(
2476 rowinfo.offset1D + rowinfo.allocSize > k_values1D_.dimension_0 (),
2477 std::range_error,
"Tpetra::CrsMatrix::getView: Invalid access " 2478 "to 1-D storage of values." << std::endl <<
"rowinfo.offset1D (" <<
2479 rowinfo.offset1D <<
") + rowinfo.allocSize (" << rowinfo.allocSize <<
2480 ") > k_values1D_.dimension_0() (" << k_values1D_.dimension_0 () <<
").");
2481 #endif // HAVE_TPETRA_DEBUG 2482 range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
2483 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
2490 subview_type sv = Kokkos::subview (subview_type (k_values1D_), range);
2491 const ST*
const sv_raw = (rowinfo.allocSize == 0) ? NULL : sv.ptr_on_device ();
2492 return ArrayView<const ST> (sv_raw, rowinfo.allocSize);
2494 else if (values2D_ != Teuchos::null) {
2495 return values2D_[rowinfo.localRow] ();
2498 return ArrayView<impl_scalar_type> ();
2503 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2507 LocalOrdinal& numEnt,
2510 if (k_values1D_.dimension_0 () != 0 && rowinfo.allocSize > 0) {
2511 #ifdef HAVE_TPETRA_DEBUG 2512 if (rowinfo.offset1D + rowinfo.allocSize > k_values1D_.dimension_0 ()) {
2515 return Teuchos::OrdinalTraits<LocalOrdinal>::invalid ();
2517 #endif // HAVE_TPETRA_DEBUG 2518 vals = k_values1D_.ptr_on_device () + rowinfo.offset1D;
2519 numEnt = rowinfo.allocSize;
2521 else if (! values2D_.is_null ()) {
2522 #ifdef HAVE_TPETRA_DEBUG 2523 if (rowinfo.localRow >= static_cast<size_t> (values2D_.size ())) {
2526 return Teuchos::OrdinalTraits<LocalOrdinal>::invalid ();
2528 #endif // HAVE_TPETRA_DEBUG 2531 const auto& curRow = values2D_[rowinfo.localRow];
2532 vals = curRow.getRawPtr ();
2533 numEnt = curRow.size ();
2540 return static_cast<LocalOrdinal
> (0);
2543 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2547 LocalOrdinal& numEnt,
2551 const LocalOrdinal err = this->
getViewRawConst (valsConst, numEnt, rowinfo);
2556 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2557 Kokkos::View<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type*,
2559 Kokkos::MemoryUnmanaged>
2563 using Kokkos::MemoryUnmanaged;
2566 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
2567 typedef std::pair<size_t, size_t> range_type;
2569 if (k_values1D_.dimension_0 () != 0 && rowInfo.allocSize > 0) {
2570 #ifdef HAVE_TPETRA_DEBUG 2571 TEUCHOS_TEST_FOR_EXCEPTION
2572 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.dimension_0 (),
2573 std::range_error,
"Tpetra::CrsMatrix::getRowView: Invalid access " 2574 "to 1-D storage of values. rowInfo.offset1D (" 2575 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
2576 <<
") > this->k_values1D_.dimension_0() (" 2577 << this->k_values1D_.dimension_0 () <<
").");
2578 #endif // HAVE_TPETRA_DEBUG 2579 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
2586 return Kokkos::subview (subview_type (this->k_values1D_), range);
2588 else if (this->values2D_ != Teuchos::null) {
2592 auto& rowView = this->values2D_[rowInfo.localRow];
2593 return subview_type (rowView.getRawPtr (), rowView.size ());
2596 return subview_type ();
2600 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2601 Kokkos::View<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type*,
2602 typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::execution_space,
2603 Kokkos::MemoryUnmanaged>
2607 using Kokkos::MemoryUnmanaged;
2610 typedef View<ST*, execution_space, MemoryUnmanaged> subview_type;
2611 typedef std::pair<size_t, size_t> range_type;
2613 if (k_values1D_.dimension_0 () != 0 && rowInfo.allocSize > 0) {
2614 #ifdef HAVE_TPETRA_DEBUG 2615 TEUCHOS_TEST_FOR_EXCEPTION
2616 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.dimension_0 (),
2617 std::range_error,
"Tpetra::CrsMatrix::getRowViewNonConst: Invalid " 2618 "access to 1-D storage of values. rowInfo.offset1D (" 2619 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
2620 <<
") > this->k_values1D_.dimension_0() (" 2621 << this->k_values1D_.dimension_0 () <<
").");
2622 #endif // HAVE_TPETRA_DEBUG 2623 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
2630 return Kokkos::subview (subview_type (this->k_values1D_), range);
2632 else if (this->values2D_ != Teuchos::null) {
2636 auto& rowView = this->values2D_[rowInfo.localRow];
2637 return subview_type (rowView.getRawPtr (), rowView.size ());
2640 return subview_type ();
2644 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2645 Teuchos::ArrayView<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::impl_scalar_type>
2652 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2656 const Teuchos::ArrayView<LocalOrdinal>& indices,
2657 const Teuchos::ArrayView<Scalar>& values,
2658 size_t& numEntries)
const 2660 using Teuchos::ArrayView;
2661 using Teuchos::av_reinterpret_cast;
2662 const char tfecfFuncName[] =
"getLocalRowCopy: ";
2664 TEUCHOS_TEST_FOR_EXCEPTION(
2666 "Tpetra::CrsMatrix::getLocalRowCopy: The matrix is globally indexed and " 2667 "does not have a column Map yet. That means we don't have local indices " 2668 "for columns yet, so it doesn't make sense to call this method. If the " 2669 "matrix doesn't have a column Map yet, you should call fillComplete on " 2671 #ifdef HAVE_TPETRA_DEBUG 2672 TEUCHOS_TEST_FOR_EXCEPTION(
2673 ! staticGraph_->hasRowInfo (), std::runtime_error,
2674 "Tpetra::CrsMatrix::getLocalRowCopy: The graph's row information was " 2675 "deleted at fillComplete().");
2676 #endif // HAVE_TPETRA_DEBUG 2678 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
2679 const size_t theNumEntries = rowinfo.numEntries;
2680 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2681 (static_cast<size_t> (indices.size ()) < theNumEntries ||
2682 static_cast<size_t> (values.size ()) < theNumEntries,
2683 std::runtime_error,
"Row with local index " << localRow <<
" has " <<
2684 theNumEntries <<
" entry/ies, but indices.size() = " <<
2685 indices.size () <<
" and values.size() = " << values.size () <<
".");
2686 numEntries = theNumEntries;
2688 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2689 if (staticGraph_->isLocallyIndexed ()) {
2690 const LocalOrdinal* curLclInds;
2692 LocalOrdinal numSpots;
2697 #ifdef HAVE_TPETRA_DEBUG 2699 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
2700 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2701 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2702 "staticGraph_->getLocalViewRawConst returned nonzero error code " 2704 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2705 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
2706 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
2708 const LocalOrdinal numSpotsBefore = numSpots;
2710 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2711 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2712 "getViewRaw returned nonzero error code " << err <<
".");
2713 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2714 (numSpotsBefore != numSpots, std::logic_error,
2715 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = " 2716 << numSpots <<
".");
2718 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
2720 #endif // HAVE_TPETRA_DEBUG 2722 for (
size_t j = 0; j < theNumEntries; ++j) {
2723 values[j] = curVals[j];
2724 indices[j] = curLclInds[j];
2727 else if (staticGraph_->isGloballyIndexed ()) {
2728 const map_type& colMap = * (staticGraph_->colMap_);
2729 const GlobalOrdinal* curGblInds;
2731 LocalOrdinal numSpots;
2736 #ifdef HAVE_TPETRA_DEBUG 2738 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
2739 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2740 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2741 "staticGraph_->getGlobalViewRawConst returned nonzero error code " 2743 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2744 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
2745 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
2747 const LocalOrdinal numSpotsBefore = numSpots;
2749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2750 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2751 "getViewRawConst returned nonzero error code " << err <<
".");
2752 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2753 (numSpotsBefore != numSpots, std::logic_error,
2754 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = " 2755 << numSpots <<
".");
2757 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
2759 #endif //HAVE_TPETRA_DEBUG 2761 for (
size_t j = 0; j < theNumEntries; ++j) {
2762 values[j] = curVals[j];
2769 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2773 const Teuchos::ArrayView<GlobalOrdinal>& indices,
2774 const Teuchos::ArrayView<Scalar>& values,
2775 size_t& numEntries)
const 2777 using Teuchos::ArrayView;
2778 using Teuchos::av_reinterpret_cast;
2779 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
2782 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
2783 const size_t theNumEntries = rowinfo.numEntries;
2784 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2785 static_cast<size_t> (indices.size ()) < theNumEntries ||
2786 static_cast<size_t> (values.size ()) < theNumEntries,
2787 std::runtime_error,
"Row with global index " << globalRow <<
" has " 2788 << theNumEntries <<
" entry/ies, but indices.size() = " <<
2789 indices.size () <<
" and values.size() = " << values.size () <<
".");
2790 numEntries = theNumEntries;
2792 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
2793 if (staticGraph_->isLocallyIndexed ()) {
2794 const map_type& colMap = * (staticGraph_->colMap_);
2795 const LocalOrdinal* curLclInds;
2797 LocalOrdinal numSpots;
2802 #ifdef HAVE_TPETRA_DEBUG 2804 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
2805 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2806 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2807 "staticGraph_->getLocalViewRawConst returned nonzero error code " 2809 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2810 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
2811 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
2813 const LocalOrdinal numSpotsBefore = numSpots;
2815 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2816 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2817 "getViewRaw returned nonzero error code " << err <<
".");
2818 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2819 (numSpotsBefore != numSpots, std::logic_error,
2820 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = " 2821 << numSpots <<
".");
2823 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
2825 #endif //HAVE_TPETRA_DEBUG 2827 for (
size_t j = 0; j < theNumEntries; ++j) {
2828 values[j] = curVals[j];
2832 else if (staticGraph_->isGloballyIndexed ()) {
2833 const GlobalOrdinal* curGblInds;
2835 LocalOrdinal numSpots;
2840 #ifdef HAVE_TPETRA_DEBUG 2842 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
2843 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2844 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2845 "staticGraph_->getGlobalViewRawConst returned nonzero error code " 2847 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2848 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
2849 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
2851 const LocalOrdinal numSpotsBefore = numSpots;
2853 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2854 (err != static_cast<LocalOrdinal> (0), std::logic_error,
2855 "getViewRawConst returned nonzero error code " << err <<
".");
2856 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2857 (numSpotsBefore != numSpots, std::logic_error,
2858 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = " 2859 << numSpots <<
".");
2861 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
2863 #endif //HAVE_TPETRA_DEBUG 2865 for (
size_t j = 0; j < theNumEntries; ++j) {
2866 values[j] = curVals[j];
2867 indices[j] = curGblInds[j];
2873 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2877 Teuchos::ArrayView<const LocalOrdinal>& indices,
2878 Teuchos::ArrayView<const Scalar>& values)
const 2880 using Teuchos::ArrayView;
2881 using Teuchos::av_reinterpret_cast;
2882 typedef LocalOrdinal LO;
2883 const char tfecfFuncName[] =
"getLocalRowView: ";
2885 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2887 "its indices as global indices, so you cannot get a view with local " 2888 "column indices. If the matrix has a column Map, you may call " 2889 "getLocalRowCopy() to get local column indices; otherwise, you may get " 2890 "a view with global column indices by calling getGlobalRowCopy().");
2891 indices = Teuchos::null;
2892 values = Teuchos::null;
2893 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
2894 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
2895 rowinfo.numEntries > 0) {
2896 ArrayView<const LO> indTmp = staticGraph_->getLocalView (rowinfo);
2897 ArrayView<const Scalar> valTmp =
2898 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
2899 indices = indTmp (0, rowinfo.numEntries);
2900 values = valTmp (0, rowinfo.numEntries);
2903 #ifdef HAVE_TPETRA_DEBUG 2904 const char suffix[] =
". This should never happen. Please report this " 2905 "bug to the Tpetra developers.";
2906 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2907 (static_cast<size_t> (indices.size ()) !=
2908 static_cast<size_t> (values.size ()), std::logic_error,
2909 "At the end of this method, for local row " << localRow <<
", " 2910 "indices.size() = " << indices.size () <<
" != values.size () = " 2911 << values.size () << suffix);
2912 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2913 (static_cast<size_t> (indices.size ()) !=
2914 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
2915 "At the end of this method, for local row " << localRow <<
", " 2916 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = " 2917 << rowinfo.numEntries << suffix);
2919 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2920 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end " 2921 "of this method, for local row " << localRow <<
", rowinfo.numEntries = " 2922 << rowinfo.numEntries <<
" != getNumEntriesInLocalRow(localRow) = " <<
2923 expectedNumEntries << suffix);
2924 #endif // HAVE_TPETRA_DEBUG 2927 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2931 LocalOrdinal& numEnt,
2933 const LocalOrdinal*& ind)
const 2935 typedef LocalOrdinal LO;
2942 if (staticGraph_.is_null () || staticGraph_->isGloballyIndexed ()) {
2943 return Tpetra::Details::OrdinalTraits<LO>::invalid ();
2946 const RowInfo rowInfo = staticGraph_->getRowInfo (lclRow);
2947 if (rowInfo.localRow == Tpetra::Details::OrdinalTraits<size_t>::invalid ()) {
2952 return static_cast<LO
> (1);
2955 numEnt =
static_cast<LO
> (rowInfo.numEntries);
2956 auto lclColInds = staticGraph_->getLocalKokkosRowView (rowInfo);
2957 ind = lclColInds.ptr_on_device ();
2964 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2968 LocalOrdinal& numEnt,
2969 const LocalOrdinal*& lclColInds,
2970 const Scalar*& vals)
const 2973 const LocalOrdinal errCode =
2975 vals =
reinterpret_cast<const Scalar*
> (vals_ist);
2979 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2983 Teuchos::ArrayView<const GlobalOrdinal>& indices,
2984 Teuchos::ArrayView<const Scalar>& values)
const 2986 using Teuchos::ArrayView;
2987 using Teuchos::av_reinterpret_cast;
2988 typedef GlobalOrdinal GO;
2989 const char tfecfFuncName[] =
"getGlobalRowView: ";
2991 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2993 "The matrix is locally indexed, so we cannot return a view of the row " 2994 "with global column indices. Use getGlobalRowCopy() instead.");
2995 indices = Teuchos::null;
2996 values = Teuchos::null;
2998 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
2999 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3000 rowinfo.numEntries > 0) {
3001 ArrayView<const GO> indTmp = staticGraph_->getGlobalView (rowinfo);
3002 ArrayView<const Scalar> valTmp =
3003 av_reinterpret_cast<
const Scalar> (this->
getView (rowinfo));
3004 indices = indTmp (0, rowinfo.numEntries);
3005 values = valTmp (0, rowinfo.numEntries);
3008 #ifdef HAVE_TPETRA_DEBUG 3009 const char suffix[] =
". This should never happen. Please report this " 3010 "bug to the Tpetra developers.";
3011 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3012 (static_cast<size_t> (indices.size ()) !=
3013 static_cast<size_t> (values.size ()), std::logic_error,
3014 "At the end of this method, for global row " << globalRow <<
", " 3015 "indices.size() = " << indices.size () <<
" != values.size () = " 3016 << values.size () << suffix);
3017 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3018 (static_cast<size_t> (indices.size ()) !=
3019 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3020 "At the end of this method, for global row " << globalRow <<
", " 3021 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = " 3022 << rowinfo.numEntries << suffix);
3024 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3025 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end " 3026 "of this method, for global row " << globalRow <<
", rowinfo.numEntries " 3027 "= " << rowinfo.numEntries <<
" != getNumEntriesInGlobalRow(globalRow) =" 3028 " " << expectedNumEntries << suffix);
3029 #endif // HAVE_TPETRA_DEBUG 3032 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3037 typedef LocalOrdinal LO;
3038 typedef typename Teuchos::Array<Scalar>::size_type size_type;
3039 const char tfecfFuncName[] =
"scale: ";
3042 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3044 "Fill must be active before you may call this method. " 3045 "Please call resumeFill() to make fill active.");
3047 const size_t nlrs = staticGraph_->getNodeNumRows ();
3048 const size_t numEntries = staticGraph_->getNodeNumEntries ();
3049 if (! staticGraph_->indicesAreAllocated () ||
3050 nlrs == 0 || numEntries == 0) {
3056 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
3058 for (LO k = 0; k < row_i.length; ++k) {
3060 row_i.value (k) *= theAlpha;
3065 for (
size_t row = 0; row < nlrs; ++row) {
3067 Teuchos::ArrayView<impl_scalar_type> rowVals = values2D_[row] ();
3068 for (size_type k = 0; k < numEnt; ++k) {
3069 rowVals[k] *= theAlpha;
3076 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3081 const char tfecfFuncName[] =
"setAllToScalar: ";
3083 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3085 "Fill must be active before you may call this method. " 3086 "Please call resumeFill() to make fill active.");
3092 const size_t nlrs = staticGraph_->getNodeNumRows();
3093 const size_t numEntries = staticGraph_->getNodeNumEntries();
3094 if (! staticGraph_->indicesAreAllocated () || numEntries == 0) {
3098 const ProfileType profType = staticGraph_->getProfileType ();
3106 for (
size_t row = 0; row < nlrs; ++row) {
3107 std::fill (values2D_[row].begin (), values2D_[row].end (), theAlpha);
3113 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3117 const typename local_graph_type::entries_type::non_const_type& columnIndices,
3118 const typename local_matrix_type::values_type& values)
3120 const char tfecfFuncName[] =
"setAllValues: ";
3121 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3122 (columnIndices.size () != values.size (), std::invalid_argument,
3123 "columnIndices.size() = " << columnIndices.size () <<
" != values.size()" 3124 " = " << values.size () <<
".");
3125 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3126 (myGraph_.is_null (), std::runtime_error,
"myGraph_ must not be null.");
3129 myGraph_->setAllIndices (rowPointers, columnIndices);
3131 catch (std::exception &e) {
3132 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3133 (
true, std::runtime_error,
"myGraph_->setAllIndices() threw an " 3134 "exception: " << e.what ());
3140 auto lclGraph = myGraph_->getLocalGraph ();
3141 const size_t numEnt = lclGraph.entries.dimension_0 ();
3142 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3143 (lclGraph.row_map.dimension_0 () != rowPointers.dimension_0 () ||
3144 numEnt !=
static_cast<size_t> (columnIndices.dimension_0 ()),
3145 std::logic_error,
"myGraph_->setAllIndices() did not correctly create " 3146 "local graph. Please report this bug to the Tpetra developers.");
3148 const size_t numCols = myGraph_->getColMap ()->getNodeNumElements ();
3150 numCols, values, lclGraph);
3159 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3163 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
3164 const Teuchos::ArrayRCP<Scalar>& val)
3166 using Kokkos::Compat::getKokkosViewDeepCopy;
3167 using Teuchos::ArrayRCP;
3168 using Teuchos::av_reinterpret_cast;
3171 typedef typename local_matrix_type::row_map_type row_map_type;
3173 const char tfecfFuncName[] =
"setAllValues(ArrayRCP<size_t>, ArrayRCP<LO>, ArrayRCP<Scalar>): ";
3179 typename row_map_type::non_const_type ptrNative (
"ptr", ptr.size ());
3180 Kokkos::View<
const size_t*,
3181 typename row_map_type::array_layout,
3183 Kokkos::MemoryUnmanaged> ptrSizeT (ptr.getRawPtr (), ptr.size ());
3186 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3187 (ptrNative.dimension_0 () != ptrSizeT.dimension_0 (),
3188 std::logic_error,
"ptrNative.dimension_0() = " <<
3189 ptrNative.dimension_0 () <<
" != ptrSizeT.dimension_0() = " 3190 << ptrSizeT.dimension_0 () <<
". Please report this bug to the " 3191 "Tpetra developers.");
3193 auto indIn = getKokkosViewDeepCopy<DT> (ind ());
3194 auto valIn = getKokkosViewDeepCopy<DT> (av_reinterpret_cast<IST> (val ()));
3198 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3203 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
3204 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3205 (staticGraph_.is_null (), std::runtime_error,
"The matrix has no graph.");
3212 const size_t lclNumRows = staticGraph_->getNodeNumRows ();
3213 if (static_cast<size_t> (offsets.size ()) < lclNumRows) {
3214 offsets.resize (lclNumRows);
3220 typedef typename device_type::memory_space memory_space;
3221 if (std::is_same<memory_space, Kokkos::HostSpace>::value) {
3226 Kokkos::MemoryUnmanaged> output_type;
3227 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
3228 staticGraph_->getLocalDiagOffsets (offsetsOut);
3231 Kokkos::View<size_t*, device_type> offsetsTmp (
"diagOffsets", lclNumRows);
3232 staticGraph_->getLocalDiagOffsets (offsetsTmp);
3233 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
3234 Kokkos::MemoryUnmanaged> output_type;
3235 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
3240 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3245 using Teuchos::ArrayRCP;
3246 using Teuchos::ArrayView;
3247 using Teuchos::av_reinterpret_cast;
3248 const char tfecfFuncName[] =
"getLocalDiagCopy (1-arg): ";
3252 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3253 staticGraph_.is_null (), std::runtime_error,
3254 "This method requires that the matrix have a graph.");
3256 if (rowMapPtr.is_null () || rowMapPtr->getComm ().is_null ()) {
3263 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3264 (! this->
hasColMap () || colMapPtr.is_null (), std::runtime_error,
3265 "This method requires that the matrix have a column Map.");
3266 const map_type& rowMap = * rowMapPtr;
3267 const map_type& colMap = * colMapPtr;
3270 #ifdef HAVE_TPETRA_DEBUG 3273 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3274 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
3275 "The input Vector's Map must be compatible with the CrsMatrix's row " 3276 "Map. You may check this by using Map's isCompatible method: " 3277 "diag.getMap ()->isCompatible (A.getRowMap ());");
3278 #endif // HAVE_TPETRA_DEBUG 3281 diag.template modify<device_type> ();
3282 const auto D_lcl = diag.template getLocalView<device_type> ();
3284 const auto D_lcl_1d =
3285 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
3287 const auto lclRowMap = rowMap.getLocalMap ();
3292 lclColMap, lclMatrix);
3300 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3305 Kokkos::MemoryUnmanaged>& offsets)
const 3307 typedef LocalOrdinal LO;
3309 #ifdef HAVE_TPETRA_DEBUG 3310 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
3314 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3315 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
3316 "The input Vector's Map must be compatible with (in the sense of Map::" 3317 "isCompatible) the CrsMatrix's row Map.");
3318 #endif // HAVE_TPETRA_DEBUG 3327 diag.template modify<device_type> ();
3328 auto D_lcl = diag.template getLocalView<device_type> ();
3332 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
3334 KokkosSparse::getDiagCopy (D_lcl_1d, offsets, this->
lclMatrix_);
3337 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3341 const Teuchos::ArrayView<const size_t>& offsets)
const 3343 typedef LocalOrdinal LO;
3346 typedef typename vec_type::dual_view_type dual_view_type;
3347 typedef typename dual_view_type::host_mirror_space::execution_space host_execution_space;
3349 #ifdef HAVE_TPETRA_DEBUG 3350 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
3354 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3355 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
3356 "The input Vector's Map must be compatible with (in the sense of Map::" 3357 "isCompatible) the CrsMatrix's row Map.");
3358 #endif // HAVE_TPETRA_DEBUG 3364 diag_dv.modified_device () = 0;
3369 diag.template modify<host_execution_space> ();
3370 auto lclVecHost = diag.template getLocalView<host_execution_space> ();
3372 auto lclVecHost1d = Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
3374 Kokkos::View<
const size_t*, Kokkos::HostSpace,
3375 Kokkos::MemoryTraits<Kokkos::Unmanaged> >
3376 h_offsets (offsets.getRawPtr (), offsets.size ());
3379 typedef Kokkos::RangePolicy<host_execution_space, LO> policy_type;
3380 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
3382 Kokkos::parallel_for (policy_type (0, myNumRows), [&] (
const LO& lclRow) {
3383 lclVecHost1d(lclRow) = STS::zero ();
3384 if (h_offsets[lclRow] != INV) {
3386 lclVecHost1d(lclRow) =
static_cast<IST
> (curRow.value(h_offsets[lclRow]));
3389 diag.template sync<execution_space> ();
3393 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3398 using Teuchos::ArrayRCP;
3399 using Teuchos::ArrayView;
3400 using Teuchos::null;
3403 using Teuchos::rcpFromRef;
3405 const char tfecfFuncName[] =
"leftScale";
3409 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3411 ": matrix must be fill complete.");
3412 RCP<const vec_type> xp;
3419 if (getCrsGraphRef ().
getExporter () != Teuchos::null) {
3420 RCP<vec_type> tempVec = rcp (
new vec_type (
getRowMap ()));
3421 tempVec->doImport (x, * (getCrsGraphRef ().getExporter ()),
INSERT);
3425 xp = rcpFromRef (x);
3429 xp = rcpFromRef (x);
3432 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::invalid_argument,
": The " 3433 "input scaling vector x's Map must be the same as either the row Map or " 3434 "the range Map of the CrsMatrix.");
3436 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
3437 ArrayView<impl_scalar_type> rowValues = null;
3439 const LocalOrdinal lclNumRows =
3441 for (LocalOrdinal i = 0; i < lclNumRows; ++i) {
3442 const RowInfo rowinfo = staticGraph_->getRowInfo (i);
3445 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
3446 rowValues[j] *= scaleValue;
3451 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3456 using Teuchos::ArrayRCP;
3457 using Teuchos::ArrayView;
3458 using Teuchos::null;
3461 using Teuchos::rcpFromRef;
3463 const char tfecfFuncName[] =
"rightScale: ";
3467 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3468 !
isFillComplete (), std::runtime_error,
"Matrix must be fill complete.");
3469 RCP<const vec_type> xp;
3474 if (getCrsGraphRef ().
getImporter () != Teuchos::null) {
3475 RCP<vec_type> tempVec = rcp (
new vec_type (
getColMap ()));
3476 tempVec->doImport (x, * (getCrsGraphRef ().getImporter ()),
INSERT);
3480 xp = rcpFromRef (x);
3484 xp = rcpFromRef (x);
3486 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3487 true, std::runtime_error,
"The vector x must have the same Map as " 3488 "either the row Map or the range Map.");
3491 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
3492 ArrayView<impl_scalar_type> rowValues = null;
3494 const LocalOrdinal lclNumRows =
3496 for (LocalOrdinal i = 0; i < lclNumRows; ++i) {
3497 const RowInfo rowinfo = staticGraph_->getRowInfo (i);
3499 ArrayView<const LocalOrdinal> colInds;
3501 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
3507 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3512 using Teuchos::ArrayView;
3513 using Teuchos::outArg;
3514 using Teuchos::REDUCE_SUM;
3515 using Teuchos::reduceAll;
3516 typedef typename Teuchos::ArrayRCP<const impl_scalar_type>::size_type size_type;
3524 if (frobNorm == -STM::one ()) {
3530 const size_type numEntries =
3532 for (size_type k = 0; k < numEntries; ++k) {
3538 const mag_type val_abs = STS::abs (val);
3539 mySum += val_abs * val_abs;
3543 const LocalOrdinal numRows =
3545 for (LocalOrdinal r = 0; r < numRows; ++r) {
3546 const RowInfo rowInfo = myGraph_->getRowInfo (r);
3547 const size_type numEntries =
3548 static_cast<size_type
> (rowInfo.numEntries);
3549 ArrayView<const impl_scalar_type> A_r =
3550 this->
getView (rowInfo).view (0, numEntries);
3551 for (size_type k = 0; k < numEntries; ++k) {
3553 const mag_type val_abs = STS::abs (val);
3554 mySum += val_abs * val_abs;
3560 reduceAll<int, mag_type> (* (
getComm ()), REDUCE_SUM,
3561 mySum, outArg (totalSum));
3562 frobNorm = STM::sqrt (totalSum);
3573 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3578 const char tfecfFuncName[] =
"replaceColMap: ";
3582 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3583 myGraph_.is_null (), std::runtime_error,
3584 "This method does not work if the matrix has a const graph. The whole " 3585 "idea of a const graph is that you are not allowed to change it, but " 3586 "this method necessarily must modify the graph, since the graph owns " 3587 "the matrix's column Map.");
3588 myGraph_->replaceColMap (newColMap);
3591 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3595 const Teuchos::RCP<const map_type>& newColMap,
3596 const Teuchos::RCP<const import_type>& newImport,
3597 const bool sortEachRow)
3599 const char tfecfFuncName[] =
"reindexColumns: ";
3600 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3601 graph == NULL && myGraph_.is_null (), std::invalid_argument,
3602 "The input graph is NULL, but the matrix does not own its graph.");
3605 const bool sortGraph =
false;
3607 if (sortEachRow && theGraph.isLocallyIndexed () && ! theGraph.isSorted ()) {
3608 const LocalOrdinal lclNumRows =
3609 static_cast<LocalOrdinal
> (theGraph.getNodeNumRows ());
3610 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
3611 const RowInfo rowInfo = theGraph.getRowInfo (row);
3612 auto lclColInds = theGraph.getLocalKokkosRowViewNonConst (rowInfo);
3613 auto vals = this->getRowViewNonConst (rowInfo);
3616 sort2 (lclColInds.ptr_on_device (),
3617 lclColInds.ptr_on_device () + rowInfo.numEntries,
3618 vals.ptr_on_device ());
3620 theGraph.indicesAreSorted_ =
true;
3624 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3628 Teuchos::RCP<const import_type>& newImporter)
3630 const char tfecfFuncName[] =
"replaceDomainMapAndImporter: ";
3631 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3632 myGraph_.is_null (), std::runtime_error,
3633 "This method does not work if the matrix has a const graph. The whole " 3634 "idea of a const graph is that you are not allowed to change it, but this" 3635 " method necessarily must modify the graph, since the graph owns the " 3636 "matrix's domain Map and Import objects.");
3637 myGraph_->replaceDomainMapAndImporter (newDomainMap, newImporter);
3640 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3644 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
3645 const Teuchos::ArrayView<const Scalar>& values)
3647 using Teuchos::Array;
3648 typedef GlobalOrdinal GO;
3649 typedef typename Array<GO>::size_type size_type;
3651 const size_type numToInsert = indices.size ();
3654 std::pair<Array<GO>, Array<Scalar> >& curRow =
nonlocals_[globalRow];
3655 Array<GO>& curRowInds = curRow.first;
3656 Array<Scalar>& curRowVals = curRow.second;
3657 const size_type newCapacity = curRowInds.size () + numToInsert;
3658 curRowInds.reserve (newCapacity);
3659 curRowVals.reserve (newCapacity);
3660 for (size_type k = 0; k < numToInsert; ++k) {
3661 curRowInds.push_back (indices[k]);
3662 curRowVals.push_back (values[k]);
3666 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3671 using ::Tpetra::Details::ProfilingRegion;
3672 using Teuchos::Comm;
3673 using Teuchos::outArg;
3676 using Teuchos::REDUCE_MAX;
3677 using Teuchos::REDUCE_MIN;
3678 using Teuchos::reduceAll;
3681 typedef GlobalOrdinal GO;
3682 typedef typename Teuchos::Array<GO>::size_type size_type;
3683 const char tfecfFuncName[] =
"globalAssemble: ";
3684 ProfilingRegion regionGlobalAssemble (
"Tpetra::CrsMatrix::globalAssemble");
3686 RCP<const Comm<int> > comm =
getComm ();
3688 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3689 (!
isFillActive (), std::runtime_error,
"Fill must be active before " 3690 "you may call this method.");
3692 const size_t myNumNonlocalRows =
nonlocals_.size ();
3699 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
3700 int someoneHasNonlocalRows = 0;
3701 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
3702 outArg (someoneHasNonlocalRows));
3703 if (someoneHasNonlocalRows == 0) {
3717 RCP<const map_type> nonlocalRowMap;
3719 Teuchos::ArrayRCP<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
3721 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
3722 size_type curPos = 0;
3724 ++mapIter, ++curPos) {
3725 myNonlocalGblRows[curPos] = mapIter->first;
3728 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
3729 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
3736 sort2 (gblCols.begin (), gblCols.end (), vals.begin ());
3737 typename Teuchos::Array<GO>::iterator gblCols_newEnd;
3738 typename Teuchos::Array<Scalar>::iterator vals_newEnd;
3739 merge2 (gblCols_newEnd, vals_newEnd,
3740 gblCols.begin (), gblCols.end (),
3741 vals.begin (), vals.end ());
3742 gblCols.erase (gblCols_newEnd, gblCols.end ());
3743 vals.erase (vals_newEnd, vals.end ());
3744 numEntPerNonlocalRow[curPos] = gblCols.size ();
3755 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
3757 auto iter = std::min_element (myNonlocalGblRows.begin (),
3758 myNonlocalGblRows.end ());
3759 if (iter != myNonlocalGblRows.end ()) {
3760 myMinNonlocalGblRow = *iter;
3763 GO gblMinNonlocalGblRow = 0;
3764 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
3765 outArg (gblMinNonlocalGblRow));
3766 const GO indexBase = gblMinNonlocalGblRow;
3767 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
3768 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
3776 RCP<crs_matrix_type> nonlocalMatrix =
3777 rcp (
new crs_matrix_type (nonlocalRowMap, numEntPerNonlocalRow,
3780 size_type curPos = 0;
3782 ++mapIter, ++curPos) {
3783 const GO gblRow = mapIter->first;
3785 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
3786 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
3788 nonlocalMatrix->insertGlobalValues (gblRow, gblCols (), vals ());
3801 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
3803 int isLocallyComplete = 1;
3805 if (origRowMapIsOneToOne) {
3806 export_type exportToOrig (nonlocalRowMap, origRowMap);
3808 isLocallyComplete = 0;
3819 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
3821 isLocallyComplete = 0;
3828 crs_matrix_type oneToOneMatrix (oneToOneRowMap, 0);
3830 oneToOneMatrix.doExport (*nonlocalMatrix, exportToOneToOne,
Tpetra::ADD);
3834 nonlocalMatrix = Teuchos::null;
3837 import_type importToOrig (oneToOneRowMap, origRowMap);
3855 int isGloballyComplete = 0;
3856 reduceAll<int, int> (*comm, REDUCE_MIN, isLocallyComplete,
3857 outArg (isGloballyComplete));
3858 TEUCHOS_TEST_FOR_EXCEPTION
3859 (isGloballyComplete != 1, std::runtime_error,
"On at least one process, " 3860 "you called insertGlobalValues with a global row index which is not in " 3861 "the matrix's row Map on any process in its communicator.");
3864 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3870 myGraph_->resumeFill (params);
3876 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3890 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3897 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3912 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3917 const char tfecfFuncName[] =
"fillComplete(params): ";
3919 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3920 (this->
getCrsGraph ().is_null (), std::logic_error,
3921 "getCrsGraph() returns null. This should not happen at this point. " 3922 "Please report this bug to the Tpetra developers.");
3935 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3939 const Teuchos::RCP<const map_type>& rangeMap,
3940 const Teuchos::RCP<Teuchos::ParameterList>& params)
3942 using ::Tpetra::Details::ProfilingRegion;
3943 using Teuchos::ArrayRCP;
3946 const char tfecfFuncName[] =
"fillComplete";
3947 ProfilingRegion regionFillComplete (
"Tpetra::CrsMatrix::fillComplete");
3949 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3951 ": Matrix fill state must be active (isFillActive() " 3952 "must be true) before you may call fillComplete().");
3953 const int numProcs =
getComm ()->getSize ();
3961 bool assertNoNonlocalInserts =
false;
3964 bool sortGhosts =
true;
3966 if (! params.is_null ()) {
3967 assertNoNonlocalInserts = params->get (
"No Nonlocal Changes",
3968 assertNoNonlocalInserts);
3969 if (params->isParameter (
"sort column map ghost gids")) {
3970 sortGhosts = params->get (
"sort column map ghost gids", sortGhosts);
3972 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
3973 sortGhosts = params->get (
"Sort column Map ghost GIDs", sortGhosts);
3978 const bool needGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
3980 if (! myGraph_.is_null ()) {
3981 myGraph_->sortGhostsAssociatedWithEachProcessor_ = sortGhosts;
3984 if (! this->getCrsGraphRef ().indicesAreAllocated ()) {
3995 if (needGlobalAssemble) {
3999 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4001 std::runtime_error,
": cannot have nonlocal entries on a serial run. " 4002 "An invalid entry (i.e., with row index not in the row Map) must have " 4003 "been submitted to the CrsMatrix.");
4013 #ifdef HAVE_TPETRA_DEBUG 4031 const bool domainMapsMatch = staticGraph_->getDomainMap ()->isSameAs (*domainMap);
4032 const bool rangeMapsMatch = staticGraph_->getRangeMap ()->isSameAs (*rangeMap);
4034 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4035 ! domainMapsMatch, std::runtime_error,
4036 ": The CrsMatrix's domain Map does not match the graph's domain Map. " 4037 "The graph cannot be changed because it was given to the CrsMatrix " 4038 "constructor as const. You can fix this by passing in the graph's " 4039 "domain Map and range Map to the matrix's fillComplete call.");
4041 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4042 ! rangeMapsMatch, std::runtime_error,
4043 ": The CrsMatrix's range Map does not match the graph's range Map. " 4044 "The graph cannot be changed because it was given to the CrsMatrix " 4045 "constructor as const. You can fix this by passing in the graph's " 4046 "domain Map and range Map to the matrix's fillComplete call.");
4047 #endif // HAVE_TPETRA_DEBUG 4054 myGraph_->setDomainRangeMaps (domainMap, rangeMap);
4057 if (! myGraph_->hasColMap ()) {
4058 myGraph_->makeColMap ();
4063 myGraph_->makeIndicesLocal ();
4065 const bool sorted = myGraph_->isSorted ();
4066 const bool merged = myGraph_->isMerged ();
4070 myGraph_->makeImportExport ();
4071 myGraph_->computeGlobalConstants ();
4072 myGraph_->fillComplete_ =
true;
4073 myGraph_->checkInternalState ();
4077 if (myGraph_.is_null ()) {
4098 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4102 const Teuchos::RCP<const map_type> & rangeMap,
4103 const Teuchos::RCP<const import_type>& importer,
4104 const Teuchos::RCP<const export_type>& exporter,
4105 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
4107 #ifdef HAVE_TPETRA_MMM_TIMINGS 4109 if(!params.is_null())
4110 label = params->get(
"Timer Label",label);
4111 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
4112 using Teuchos::TimeMonitor;
4113 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-Graph"))));
4117 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
4119 std::runtime_error,
"Matrix fill state must be active (isFillActive() " 4120 "must be true) before calling fillComplete().");
4121 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4122 myGraph_.is_null (), std::logic_error,
"myGraph_ is null. This is not allowed.");
4126 myGraph_->expertStaticFillComplete (domainMap, rangeMap, importer, exporter,params);
4128 #ifdef HAVE_TPETRA_MMM_TIMINGS 4129 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cGC"))));
4131 if(params.is_null() || params->get(
"compute global constants",
true))
4134 #ifdef HAVE_TPETRA_MMM_TIMINGS 4135 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-fLGAM"))));
4147 #ifdef HAVE_TPETRA_DEBUG 4148 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive(), std::logic_error,
4149 ": We're at the end of fillComplete(), but isFillActive() is true. " 4150 "Please report this bug to the Tpetra developers.");
4151 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete(), std::logic_error,
4152 ": We're at the end of fillComplete(), but isFillActive() is true. " 4153 "Please report this bug to the Tpetra developers.");
4154 #endif // HAVE_TPETRA_DEBUG 4156 #ifdef HAVE_TPETRA_MMM_TIMINGS 4157 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cIS"))));
4163 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4169 #ifdef HAVE_TPETRA_DEBUG 4170 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
4171 #endif // HAVE_TPETRA_DEBUG 4173 auto rowValues = this->getRowViewNonConst (rowInfo);
4174 typedef typename std::decay<decltype (rowValues[0]) >::type value_type;
4175 value_type* rowValueIter = rowValues.data ();
4176 auto inds_view = graph.getLocalKokkosRowViewNonConst (rowInfo);
4179 LocalOrdinal* beg = inds_view.data ();
4180 LocalOrdinal* end = inds_view.data () + rowInfo.numEntries;
4182 #ifdef HAVE_TPETRA_DEBUG 4183 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4184 (rowInfo.allocSize != static_cast<size_t> (inds_view.dimension_0 ()) ||
4185 rowInfo.allocSize != static_cast<size_t> (rowValues.dimension_0 ()),
4186 std::runtime_error,
"rowInfo.allocSize = " << rowInfo.allocSize
4187 <<
" != inds_view.dimension_0() = " << inds_view.dimension_0 ()
4188 <<
" || rowInfo.allocSize = " << rowInfo.allocSize
4189 <<
" != rowValues.dimension_0() = " << rowValues.dimension_0 () <<
".");
4190 #endif // HAVE_TPETRA_DEBUG 4192 LocalOrdinal* newend = beg;
4194 LocalOrdinal* cur = beg + 1;
4195 value_type* vcur = rowValueIter + 1;
4196 value_type* vend = rowValueIter;
4198 while (cur != end) {
4199 if (*cur != *newend) {
4216 const size_t mergedEntries = newend - beg;
4218 const size_t numDups = rowInfo.numEntries - mergedEntries;
4222 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4227 using ::Tpetra::Details::ProfilingRegion;
4228 typedef LocalOrdinal LO;
4229 typedef typename Kokkos::View<LO*, device_type>::HostMirror::execution_space
4230 host_execution_space;
4231 typedef Kokkos::RangePolicy<host_execution_space, LO> range_type;
4233 const char tfecfFuncName[] =
"sortAndMergeIndicesAndValues: ";
4234 ProfilingRegion regionSAM (
"Tpetra::CrsMatrix::sortAndMergeIndicesAndValues");
4236 if (! sorted || ! merged) {
4237 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4238 (this->
isStaticGraph (), std::runtime_error,
"Cannot sort or merge with " 4239 "\"static\" (const) graph, since the matrix does not own the graph.");
4240 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4241 (this->myGraph_.is_null (), std::logic_error,
"myGraph_ is null, but " 4242 "this matrix claims ! isStaticGraph(). " 4243 "Please report this bug to the Tpetra developers.");
4244 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4246 "this method if the graph's storage has already been optimized. " 4247 "Please report this bug to the Tpetra developers.");
4251 size_t totalNumDups = 0;
4253 Kokkos::parallel_reduce (range_type (0, lclNumRows),
4254 [
this, &graph, sorted, merged] (
const LO& lclRow,
size_t& numDups) {
4257 auto lclColInds = graph.getLocalKokkosRowViewNonConst (rowInfo);
4258 auto vals = this->getRowViewNonConst (rowInfo);
4261 sort2 (lclColInds.ptr_on_device (),
4262 lclColInds.ptr_on_device () + rowInfo.numEntries,
4263 vals.ptr_on_device ());
4279 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4288 using Teuchos::null;
4291 using Teuchos::rcp_const_cast;
4292 using Teuchos::rcpFromRef;
4293 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4294 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
4300 if (alpha == ZERO) {
4303 }
else if (beta != ONE) {
4317 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
4318 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
4324 const bool Y_is_overwritten = (beta ==
ZERO);
4327 const bool Y_is_replicated =
4336 if (Y_is_replicated && this->
getComm ()->getRank () > 0) {
4343 RCP<const MV> X_colMap;
4344 if (importer.is_null ()) {
4354 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
4359 X_colMap = rcpFromRef (X_in);
4363 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply: Import");
4372 X_colMapNonConst->doImport (X_in, *importer,
INSERT);
4373 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
4387 if (! exporter.is_null ()) {
4388 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, ZERO);
4390 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply: Export");
4396 if (Y_is_overwritten) {
4429 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, beta);
4433 this->localApply (*X_colMap, Y_in, Teuchos::NO_TRANS, alpha, beta);
4441 if (Y_is_replicated) {
4442 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply: Reduce Y");
4447 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4452 const Teuchos::ETransp mode,
4457 using Teuchos::null;
4460 using Teuchos::rcp_const_cast;
4461 using Teuchos::rcpFromRef;
4462 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4465 if (alpha == ZERO) {
4488 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
4489 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
4495 const bool Y_is_overwritten = (beta ==
ZERO);
4496 if (Y_is_replicated && this->
getComm ()->getRank () > 0) {
4502 X = rcp (
new MV (X_in, Teuchos::Copy));
4504 X = rcpFromRef (X_in);
4508 if (importer != Teuchos::null) {
4516 if (exporter != Teuchos::null) {
4527 if (! exporter.is_null ()) {
4528 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply (transpose): Import");
4536 if (importer != Teuchos::null) {
4537 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply (transpose): Export");
4546 this->localApply (*X, *
importMV_, mode, alpha, ZERO);
4547 if (Y_is_overwritten) {
4564 MV Y (Y_in, Teuchos::Copy);
4565 this->localApply (*X, Y, mode, alpha, beta);
4568 this->localApply (*X, Y_in, mode, alpha, beta);
4575 if (Y_is_replicated) {
4576 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply (transpose): Reduce Y");
4581 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4586 const Teuchos::ETransp mode,
4587 const Scalar& alpha,
4588 const Scalar& beta)
const 4591 ProfilingRegion regionLocalApply (
"Tpetra::CrsMatrix::localApply");
4592 this->
template localMultiply<Scalar, Scalar> (X, Y, mode, alpha, beta);
4595 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4600 Teuchos::ETransp mode,
4605 const char fnName[] =
"Tpetra::CrsMatrix::apply";
4607 TEUCHOS_TEST_FOR_EXCEPTION
4609 fnName <<
": Cannot call apply() until fillComplete() " 4610 "has been called.");
4612 if (mode == Teuchos::NO_TRANS) {
4613 ProfilingRegion regionNonTranspose (fnName);
4617 ProfilingRegion regionTranspose (
"Tpetra::CrsMatrix::apply (transpose)");
4624 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4632 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4638 const Scalar& dampingFactor,
4640 const int numSweeps)
const 4645 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4651 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
4652 const Scalar& dampingFactor,
4654 const int numSweeps)
const 4656 using Teuchos::null;
4659 using Teuchos::rcp_const_cast;
4660 using Teuchos::rcpFromRef;
4663 TEUCHOS_TEST_FOR_EXCEPTION(
4665 "Tpetra::CrsMatrix::gaussSeidel: cannot call this method until " 4666 "fillComplete() has been called.");
4667 TEUCHOS_TEST_FOR_EXCEPTION(
4669 std::invalid_argument,
4670 "Tpetra::CrsMatrix::gaussSeidel: The number of sweeps must be , " 4671 "nonnegative but you provided numSweeps = " << numSweeps <<
" < 0.");
4675 KokkosClassic::ESweepDirection localDirection;
4676 if (direction == Forward) {
4677 localDirection = KokkosClassic::Forward;
4679 else if (direction == Backward) {
4680 localDirection = KokkosClassic::Backward;
4682 else if (direction == Symmetric) {
4684 localDirection = KokkosClassic::Forward;
4687 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
4688 "Tpetra::CrsMatrix::gaussSeidel: The 'direction' enum does not have " 4689 "any of its valid values: Forward, Backward, or Symmetric.");
4692 if (numSweeps == 0) {
4699 RCP<const import_type> importer = this->
getGraph()->getImporter();
4700 RCP<const export_type> exporter = this->
getGraph()->getExporter();
4701 TEUCHOS_TEST_FOR_EXCEPTION(
4702 ! exporter.is_null (), std::runtime_error,
4703 "Tpetra's gaussSeidel implementation requires that the row, domain, " 4704 "and range Maps be the same. This cannot be the case, because the " 4705 "matrix has a nontrivial Export object.");
4708 RCP<const map_type> rangeMap = this->
getRangeMap ();
4709 RCP<const map_type> rowMap = this->
getGraph ()->getRowMap ();
4710 RCP<const map_type> colMap = this->
getGraph ()->getColMap ();
4712 #ifdef HAVE_TEUCHOS_DEBUG 4717 TEUCHOS_TEST_FOR_EXCEPTION(
4718 ! X.
getMap ()->isSameAs (*domainMap),
4720 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4721 "multivector X be in the domain Map of the matrix.");
4722 TEUCHOS_TEST_FOR_EXCEPTION(
4723 ! B.
getMap ()->isSameAs (*rangeMap),
4725 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4726 "B be in the range Map of the matrix.");
4727 TEUCHOS_TEST_FOR_EXCEPTION(
4728 ! D.
getMap ()->isSameAs (*rowMap),
4730 "Tpetra::CrsMatrix::gaussSeidel requires that the input " 4731 "D be in the row Map of the matrix.");
4732 TEUCHOS_TEST_FOR_EXCEPTION(
4733 ! rowMap->isSameAs (*rangeMap),
4735 "Tpetra::CrsMatrix::gaussSeidel requires that the row Map and the " 4736 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
4737 TEUCHOS_TEST_FOR_EXCEPTION(
4738 ! domainMap->isSameAs (*rangeMap),
4740 "Tpetra::CrsMatrix::gaussSeidel requires that the domain Map and " 4741 "the range Map of the matrix be the same.");
4747 #endif // HAVE_TEUCHOS_DEBUG 4757 B_in = rcpFromRef (B);
4766 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
4771 "gaussSeidel: The current implementation of the Gauss-Seidel kernel " 4772 "requires that X and B both have constant stride. Since B does not " 4773 "have constant stride, we had to make a copy. This is a limitation of " 4774 "the current implementation and not your fault, but we still report it " 4775 "as an efficiency warning for your information.");
4784 RCP<MV> X_domainMap;
4786 bool copiedInput =
false;
4788 if (importer.is_null ()) {
4790 X_domainMap = rcpFromRef (X);
4791 X_colMap = X_domainMap;
4792 copiedInput =
false;
4799 X_domainMap = X_colMap;
4804 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the " 4805 "Gauss-Seidel kernel requires that X and B both have constant " 4806 "stride. Since X does not have constant stride, we had to make a " 4807 "copy. This is a limitation of the current implementation and not " 4808 "your fault, but we still report it as an efficiency warning for " 4809 "your information.");
4814 X_domainMap = rcpFromRef (X);
4818 X_colMap = X_domainMap->offsetViewNonConst (colMap, 0);
4828 X_colMap->doImport (X, *importer,
INSERT);
4829 copiedInput =
false;
4837 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
4838 X_colMap->doImport (X, *importer,
INSERT);
4842 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the " 4843 "Gauss-Seidel kernel requires that X and B both have constant stride. " 4844 "Since X does not have constant stride, we had to make a copy. " 4845 "This is a limitation of the current implementation and not your fault, " 4846 "but we still report it as an efficiency warning for your information.");
4850 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
4851 if (! importer.is_null () && sweep > 0) {
4853 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4857 if (direction != Symmetric) {
4858 if (rowIndices.is_null ()) {
4859 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4864 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4871 const bool doImportBetweenDirections =
false;
4872 if (rowIndices.is_null ()) {
4873 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4875 KokkosClassic::Forward);
4880 if (doImportBetweenDirections) {
4882 if (! importer.is_null ()) {
4883 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4886 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
4888 KokkosClassic::Backward);
4891 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4894 KokkosClassic::Forward);
4895 if (doImportBetweenDirections) {
4897 if (! importer.is_null ()) {
4898 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
4901 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
4904 KokkosClassic::Backward);
4914 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4920 const Scalar& dampingFactor,
4922 const int numSweeps,
4923 const bool zeroInitialGuess)
const 4926 numSweeps, zeroInitialGuess);
4929 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
4935 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
4936 const Scalar& dampingFactor,
4938 const int numSweeps,
4939 const bool zeroInitialGuess)
const 4941 using Teuchos::null;
4944 using Teuchos::rcpFromRef;
4945 using Teuchos::rcp_const_cast;
4947 const char prefix[] =
"Tpetra::CrsMatrix::(reordered)gaussSeidelCopy: ";
4948 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
4950 TEUCHOS_TEST_FOR_EXCEPTION(
4952 prefix <<
"The matrix is not fill complete.");
4953 TEUCHOS_TEST_FOR_EXCEPTION(
4954 numSweeps < 0, std::invalid_argument,
4955 prefix <<
"The number of sweeps must be nonnegative, " 4956 "but you provided numSweeps = " << numSweeps <<
" < 0.");
4960 KokkosClassic::ESweepDirection localDirection;
4961 if (direction == Forward) {
4962 localDirection = KokkosClassic::Forward;
4964 else if (direction == Backward) {
4965 localDirection = KokkosClassic::Backward;
4967 else if (direction == Symmetric) {
4969 localDirection = KokkosClassic::Forward;
4972 TEUCHOS_TEST_FOR_EXCEPTION(
4973 true, std::invalid_argument,
4974 prefix <<
"The 'direction' enum does not have any of its valid " 4975 "values: Forward, Backward, or Symmetric.");
4978 if (numSweeps == 0) {
4982 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
4983 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
4984 TEUCHOS_TEST_FOR_EXCEPTION(
4985 ! exporter.is_null (), std::runtime_error,
4986 "This method's implementation currently requires that the matrix's row, " 4987 "domain, and range Maps be the same. This cannot be the case, because " 4988 "the matrix has a nontrivial Export object.");
4991 RCP<const map_type> rangeMap = this->
getRangeMap ();
4992 RCP<const map_type> rowMap = this->
getGraph ()->getRowMap ();
4993 RCP<const map_type> colMap = this->
getGraph ()->getColMap ();
4995 #ifdef HAVE_TEUCHOS_DEBUG 5000 TEUCHOS_TEST_FOR_EXCEPTION(
5001 ! X.
getMap ()->isSameAs (*domainMap), std::runtime_error,
5002 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 5003 "multivector X be in the domain Map of the matrix.");
5004 TEUCHOS_TEST_FOR_EXCEPTION(
5005 ! B.
getMap ()->isSameAs (*rangeMap), std::runtime_error,
5006 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 5007 "B be in the range Map of the matrix.");
5008 TEUCHOS_TEST_FOR_EXCEPTION(
5009 ! D.
getMap ()->isSameAs (*rowMap), std::runtime_error,
5010 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input " 5011 "D be in the row Map of the matrix.");
5012 TEUCHOS_TEST_FOR_EXCEPTION(
5013 ! rowMap->isSameAs (*rangeMap), std::runtime_error,
5014 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the row Map and the " 5015 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
5016 TEUCHOS_TEST_FOR_EXCEPTION(
5017 ! domainMap->isSameAs (*rangeMap), std::runtime_error,
5018 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the domain Map and " 5019 "the range Map of the matrix be the same.");
5025 #endif // HAVE_TEUCHOS_DEBUG 5036 RCP<MV> X_domainMap;
5037 bool copyBackOutput =
false;
5038 if (importer.is_null ()) {
5040 X_colMap = rcpFromRef (X);
5041 X_domainMap = rcpFromRef (X);
5047 if (zeroInitialGuess) {
5048 X_colMap->putScalar (ZERO);
5060 X_domainMap = X_colMap;
5061 if (! zeroInitialGuess) {
5064 }
catch (std::exception& e) {
5065 std::ostringstream os;
5066 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: " 5067 "deep_copy(*X_domainMap, X) threw an exception: " 5068 << e.what () <<
".";
5069 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
5072 copyBackOutput =
true;
5076 "gaussSeidelCopy: The current implementation of the Gauss-Seidel " 5077 "kernel requires that X and B both have constant stride. Since X " 5078 "does not have constant stride, we had to make a copy. This is a " 5079 "limitation of the current implementation and not your fault, but we " 5080 "still report it as an efficiency warning for your information.");
5085 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
5087 #ifdef HAVE_TPETRA_DEBUG 5088 auto X_colMap_host_view =
5089 X_colMap->template getLocalView<Kokkos::HostSpace> ();
5090 auto X_domainMap_host_view =
5091 X_domainMap->template getLocalView<Kokkos::HostSpace> ();
5093 if (X_colMap->getLocalLength () != 0 && X_domainMap->getLocalLength ()) {
5094 TEUCHOS_TEST_FOR_EXCEPTION
5095 (X_colMap_host_view.ptr_on_device () != X_domainMap_host_view.ptr_on_device (),
5096 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: Pointer to " 5097 "start of column Map view of X is not equal to pointer to start of " 5098 "(domain Map view of) X. This may mean that Tpetra::MultiVector::" 5099 "offsetViewNonConst is broken. " 5100 "Please report this bug to the Tpetra developers.");
5103 TEUCHOS_TEST_FOR_EXCEPTION(
5104 X_colMap_host_view.dimension_0 () < X_domainMap_host_view.dimension_0 () ||
5105 X_colMap->getLocalLength () < X_domainMap->getLocalLength (),
5106 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: " 5107 "X_colMap has fewer local rows than X_domainMap. " 5108 "X_colMap_host_view.dimension_0() = " << X_colMap_host_view.dimension_0 ()
5109 <<
", X_domainMap_host_view.dimension_0() = " 5110 << X_domainMap_host_view.dimension_0 ()
5111 <<
", X_colMap->getLocalLength() = " << X_colMap->getLocalLength ()
5112 <<
", and X_domainMap->getLocalLength() = " 5113 << X_domainMap->getLocalLength ()
5114 <<
". This means that Tpetra::MultiVector::offsetViewNonConst " 5115 "is broken. Please report this bug to the Tpetra developers.");
5117 TEUCHOS_TEST_FOR_EXCEPTION(
5118 X_colMap->getNumVectors () != X_domainMap->getNumVectors (),
5119 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: " 5120 "X_colMap has a different number of columns than X_domainMap. " 5121 "X_colMap->getNumVectors() = " << X_colMap->getNumVectors ()
5122 <<
" != X_domainMap->getNumVectors() = " 5123 << X_domainMap->getNumVectors ()
5124 <<
". This means that Tpetra::MultiVector::offsetViewNonConst " 5125 "is broken. Please report this bug to the Tpetra developers.");
5126 #endif // HAVE_TPETRA_DEBUG 5128 if (zeroInitialGuess) {
5130 X_colMap->putScalar (ZERO);
5140 X_colMap->doImport (X, *importer,
INSERT);
5142 copyBackOutput =
true;
5150 B_in = rcpFromRef (B);
5159 }
catch (std::exception& e) {
5160 std::ostringstream os;
5161 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: " 5162 "deep_copy(*B_in_nonconst, B) threw an exception: " 5163 << e.what () <<
".";
5164 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
5166 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
5171 "gaussSeidelCopy: The current implementation requires that B have " 5172 "constant stride. Since B does not have constant stride, we had to " 5173 "copy it into a separate constant-stride multivector. This is a " 5174 "limitation of the current implementation and not your fault, but we " 5175 "still report it as an efficiency warning for your information.");
5178 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
5179 if (! importer.is_null () && sweep > 0) {
5182 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5186 if (direction != Symmetric) {
5187 if (rowIndices.is_null ()) {
5188 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5193 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5200 if (rowIndices.is_null ()) {
5201 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5203 KokkosClassic::Forward);
5209 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5211 KokkosClassic::Backward);
5214 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5217 KokkosClassic::Forward);
5218 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5221 KokkosClassic::Backward);
5227 if (copyBackOutput) {
5230 }
catch (std::exception& e) {
5231 TEUCHOS_TEST_FOR_EXCEPTION(
5232 true, std::runtime_error, prefix <<
"deep_copy(X, *X_domainMap) " 5233 "threw an exception: " << e.what ());
5238 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5240 Teuchos::RCP<CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node, classic> >
5245 typedef CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node,
5246 classic> output_matrix_type;
5247 const char tfecfFuncName[] =
"convert: ";
5249 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5250 (! this->
isFillComplete (), std::runtime_error,
"This matrix (the source " 5251 "of the conversion) is not fill complete. You must first call " 5252 "fillComplete() (possibly with the domain and range Map) without an " 5253 "intervening call to resumeFill(), before you may call this method.");
5254 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5255 (! this->
isStaticGraph (), std::logic_error,
"This matrix (the source " 5256 "of the conversion) claims to be fill complete, but does not have a " 5257 "static (i.e., constant) graph. Please report this bug to the Tpetra " 5260 RCP<output_matrix_type> newMatrix
5264 ::Tpetra::Details::copyConvert (newMatrix->lclMatrix_.values,
5265 this->lclMatrix_.values);
5275 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5280 #ifdef HAVE_TPETRA_DEBUG 5281 const char tfecfFuncName[] =
"checkInternalState: ";
5282 const char err[] =
"Internal state is not consistent. " 5283 "Please report this bug to the Tpetra developers.";
5287 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5288 staticGraph_.is_null (),
5289 std::logic_error, err);
5293 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5294 ! myGraph_.is_null () && myGraph_ != staticGraph_,
5295 std::logic_error, err);
5297 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5299 std::logic_error, err <<
" Specifically, the matrix is fill complete, " 5300 "but its graph is NOT fill complete.");
5302 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5304 std::logic_error, err);
5306 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5308 std::logic_error, err);
5310 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5312 std::logic_error, err);
5315 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5316 staticGraph_->indicesAreAllocated () &&
5317 staticGraph_->getNodeAllocationSize() > 0 &&
5318 staticGraph_->getNodeNumRows() > 0
5319 && values2D_.is_null () &&
5320 k_values1D_.dimension_0 () == 0,
5321 std::logic_error, err);
5323 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5324 k_values1D_.dimension_0 () > 0 && values2D_ != Teuchos::null,
5325 std::logic_error, err <<
" Specifically, k_values1D_ is allocated (has " 5326 "size " << k_values1D_.dimension_0 () <<
" > 0) and values2D_ is also " 5327 "allocated. CrsMatrix is not suppose to have both a 1-D and a 2-D " 5328 "allocation at the same time.");
5332 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5337 std::ostringstream os;
5339 os <<
"Tpetra::CrsMatrix (Kokkos refactor): {";
5340 if (this->getObjectLabel () !=
"") {
5341 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5344 os <<
"isFillComplete: true" 5351 os <<
"isFillComplete: false" 5358 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5362 const Teuchos::EVerbosityLevel verbLevel)
const 5366 using Teuchos::ArrayView;
5367 using Teuchos::Comm;
5369 using Teuchos::TypeNameTraits;
5370 using Teuchos::VERB_DEFAULT;
5371 using Teuchos::VERB_NONE;
5372 using Teuchos::VERB_LOW;
5373 using Teuchos::VERB_MEDIUM;
5374 using Teuchos::VERB_HIGH;
5375 using Teuchos::VERB_EXTREME;
5377 const Teuchos::EVerbosityLevel vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
5379 if (vl == VERB_NONE) {
5383 Teuchos::OSTab tab0 (out);
5385 RCP<const Comm<int> > comm = this->
getComm();
5386 const int myRank = comm->getRank();
5387 const int numProcs = comm->getSize();
5392 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5402 out <<
"Tpetra::CrsMatrix (Kokkos refactor):" << endl;
5404 Teuchos::OSTab tab1 (out);
5407 if (this->getObjectLabel () !=
"") {
5408 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5411 out <<
"Template parameters:" << endl;
5412 Teuchos::OSTab tab2 (out);
5413 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
5414 <<
"LocalOrdinal: " << TypeNameTraits<LocalOrdinal>::name () << endl
5415 <<
"GlobalOrdinal: " << TypeNameTraits<GlobalOrdinal>::name () << endl
5416 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
5419 out <<
"isFillComplete: true" << endl
5424 << endl <<
"Global max number of entries in a row: " 5428 out <<
"isFillComplete: false" << endl
5434 if (vl < VERB_MEDIUM) {
5440 out << endl <<
"Row Map:" << endl;
5444 out <<
"null" << endl;
5456 out <<
"Column Map: ";
5460 out <<
"null" << endl;
5464 out <<
"same as row Map" << endl;
5475 out <<
"Domain Map: ";
5479 out <<
"null" << endl;
5483 out <<
"same as row Map" << endl;
5487 out <<
"same as column Map" << endl;
5498 out <<
"Range Map: ";
5502 out <<
"null" << endl;
5506 out <<
"same as domain Map" << endl;
5510 out <<
"same as row Map" << endl;
5520 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5521 if (myRank == curRank) {
5522 out <<
"Process rank: " << curRank << endl;
5523 Teuchos::OSTab tab2 (out);
5524 if (! staticGraph_->indicesAreAllocated ()) {
5525 out <<
"Graph indices not allocated" << endl;
5528 out <<
"Number of allocated entries: " 5529 << staticGraph_->getNodeAllocationSize () << endl;
5544 if (vl < VERB_HIGH) {
5549 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5550 if (myRank == curRank) {
5551 out << std::setw(width) <<
"Proc Rank" 5552 << std::setw(width) <<
"Global Row" 5553 << std::setw(width) <<
"Num Entries";
5554 if (vl == VERB_EXTREME) {
5555 out << std::setw(width) <<
"(Index,Value)";
5560 GlobalOrdinal gid =
getRowMap()->getGlobalElement(r);
5561 out << std::setw(width) << myRank
5562 << std::setw(width) << gid
5563 << std::setw(width) << nE;
5564 if (vl == VERB_EXTREME) {
5566 ArrayView<const GlobalOrdinal> rowinds;
5567 ArrayView<const Scalar> rowvals;
5569 for (
size_t j = 0; j < nE; ++j) {
5570 out <<
" (" << rowinds[j]
5571 <<
", " << rowvals[j]
5576 ArrayView<const LocalOrdinal> rowinds;
5577 ArrayView<const Scalar> rowvals;
5579 for (
size_t j=0; j < nE; ++j) {
5580 out <<
" (" <<
getColMap()->getGlobalElement(rowinds[j])
5581 <<
", " << rowvals[j]
5597 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5610 const row_matrix_type* srcRowMat =
5611 dynamic_cast<const row_matrix_type*
> (&source);
5612 return (srcRowMat != NULL);
5615 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5620 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
5621 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs)
5624 using Teuchos::Array;
5625 using Teuchos::ArrayView;
5626 typedef LocalOrdinal LO;
5627 typedef GlobalOrdinal GO;
5630 const char tfecfFuncName[] =
"copyAndPermute: ";
5631 ProfilingRegion regionCAP (
"Tpetra::CrsMatrix::copyAndPermute");
5633 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5634 (permuteToLIDs.size () != permuteFromLIDs.size (),
5635 std::invalid_argument,
"permuteToLIDs.size() = " << permuteToLIDs.size ()
5636 <<
"!= permuteFromLIDs.size() = " << permuteFromLIDs.size () <<
".");
5641 const row_matrix_type& srcMat =
dynamic_cast<const row_matrix_type&
> (source);
5648 const map_type& srcRowMap = * (srcMat.getRowMap ());
5650 Array<Scalar> rowVals;
5651 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
5652 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
5657 const GO targetGID = sourceGID;
5660 ArrayView<const GO> rowIndsConstView;
5661 ArrayView<const Scalar> rowValsConstView;
5663 if (sourceIsLocallyIndexed) {
5664 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
5665 if (rowLength > static_cast<size_t> (rowInds.size())) {
5666 rowInds.resize (rowLength);
5667 rowVals.resize (rowLength);
5671 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
5672 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
5677 size_t checkRowLength = 0;
5678 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
5680 #ifdef HAVE_TPETRA_DEBUG 5681 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
5682 std::logic_error,
"For global row index " << sourceGID <<
", the source" 5683 " matrix's getNumEntriesInGlobalRow() method returns a row length of " 5684 << rowLength <<
", but the getGlobalRowCopy() method reports that " 5685 "the row length is " << checkRowLength <<
". Please report this bug " 5686 "to the Tpetra developers.");
5687 #endif // HAVE_TPETRA_DEBUG 5689 rowIndsConstView = rowIndsView.view (0, rowLength);
5690 rowValsConstView = rowValsView.view (0, rowLength);
5693 srcMat.getGlobalRowView (sourceGID, rowIndsConstView, rowValsConstView);
5700 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
REPLACE);
5706 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
INSERT);
5714 const size_t numPermuteToLIDs =
static_cast<size_t> (permuteToLIDs.size ());
5715 for (
size_t p = 0; p < numPermuteToLIDs; ++p) {
5720 ArrayView<const GO> rowIndsConstView;
5721 ArrayView<const Scalar> rowValsConstView;
5723 if (sourceIsLocallyIndexed) {
5724 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
5725 if (rowLength > static_cast<size_t> (rowInds.size ())) {
5726 rowInds.resize (rowLength);
5727 rowVals.resize (rowLength);
5731 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
5732 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
5737 size_t checkRowLength = 0;
5738 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
5740 #ifdef HAVE_TPETRA_DEBUG 5741 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
5742 std::logic_error,
"For the source matrix's global row index " 5743 << sourceGID <<
", the source matrix's getNumEntriesInGlobalRow() " 5744 "method returns a row length of " << rowLength <<
", but the " 5745 "getGlobalRowCopy() method reports that the row length is " 5746 << checkRowLength <<
". Please report this bug to the Tpetra " 5748 #endif // HAVE_TPETRA_DEBUG 5750 rowIndsConstView = rowIndsView.view (0, rowLength);
5751 rowValsConstView = rowValsView.view (0, rowLength);
5754 srcMat.getGlobalRowView (sourceGID, rowIndsConstView, rowValsConstView);
5759 this->combineGlobalValues (targetGID, rowIndsConstView,
5763 this->combineGlobalValues (targetGID, rowIndsConstView,
5764 rowValsConstView,
INSERT);
5769 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5773 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5774 Teuchos::Array<char>& exports,
5775 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5776 size_t& constantNumPackets,
5780 using Teuchos::Array;
5781 using Teuchos::ArrayView;
5782 using Teuchos::av_reinterpret_cast;
5783 typedef LocalOrdinal LO;
5784 typedef GlobalOrdinal GO;
5785 const char tfecfFuncName[] =
"packAndPrepare: ";
5786 ProfilingRegion regionPAP (
"Tpetra::CrsMatrix::packAndPrepare");
5809 const row_matrix_type* srcRowMat =
5810 dynamic_cast<const row_matrix_type*
> (&source);
5811 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5812 srcRowMat == NULL, std::invalid_argument,
5813 "The source object of the Import or Export operation is neither a " 5814 "CrsMatrix (with the same template parameters as the target object), " 5815 "nor a RowMatrix (with the same first four template parameters as the " 5817 #ifdef HAVE_TPETRA_DEBUG 5819 using Teuchos::reduceAll;
5820 std::ostringstream msg;
5823 srcRowMat->pack (exportLIDs, exports, numPacketsPerLID,
5824 constantNumPackets, distor);
5825 }
catch (std::exception& e) {
5830 const Teuchos::Comm<int>& comm = * (this->
getComm ());
5831 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
5832 lclBad, Teuchos::outArg (gblBad));
5834 const int myRank = comm.getRank ();
5835 const int numProcs = comm.getSize ();
5836 for (
int r = 0; r < numProcs; ++r) {
5837 if (r == myRank && lclBad != 0) {
5838 std::ostringstream os;
5839 os <<
"Proc " << myRank <<
": " << msg.str () << std::endl;
5840 std::cerr << os.str ();
5846 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5847 true, std::logic_error,
"pack() threw an exception on one or " 5848 "more participating processes.");
5852 srcRowMat->pack (exportLIDs, exports, numPacketsPerLID,
5853 constantNumPackets, distor);
5854 #endif // HAVE_TPETRA_DEBUG 5857 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5860 packRow (
char*
const numEntOut,
5863 const size_t numEnt,
5864 const LocalOrdinal lclRow)
const 5866 using Teuchos::ArrayView;
5867 typedef LocalOrdinal LO;
5868 typedef GlobalOrdinal GO;
5870 const LO numEntLO =
static_cast<LO
> (numEnt);
5871 memcpy (numEntOut, &numEntLO,
sizeof (LO));
5876 ArrayView<const LO> indIn;
5877 ArrayView<const Scalar> valIn;
5882 for (
size_t k = 0; k < numEnt; ++k) {
5884 memcpy (indOut + k *
sizeof (GO), &gblIndIn,
sizeof (GO));
5886 memcpy (valOut, valIn.getRawPtr (), numEnt *
sizeof (Scalar));
5894 ArrayView<const GO> indIn;
5895 ArrayView<const Scalar> valIn;
5899 memcpy (indOut, indIn.getRawPtr (), numEnt *
sizeof (GO));
5900 memcpy (valOut, valIn.getRawPtr (), numEnt *
sizeof (Scalar));
5910 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5914 GlobalOrdinal*
const indInTmp,
5915 const size_t tmpSize,
5916 const char*
const valIn,
5917 const char*
const indIn,
5918 const size_t numEnt,
5919 const LocalOrdinal lclRow,
5922 if (tmpSize < numEnt || (numEnt != 0 && (valInTmp == NULL || indInTmp == NULL))) {
5925 memcpy (valInTmp, valIn, numEnt *
sizeof (Scalar));
5926 memcpy (indInTmp, indIn, numEnt *
sizeof (GlobalOrdinal));
5938 this->combineGlobalValuesRaw (lclRow, numEnt, valInTmp, indInTmp,
5945 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5949 size_t& totalNumEntries,
5950 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs)
const 5953 typedef LocalOrdinal LO;
5954 typedef GlobalOrdinal GO;
5959 const LO numExportLIDs =
static_cast<LO
> (exportLIDs.size ());
5962 totalNumEntries = 0;
5963 for (LO i = 0; i < numExportLIDs; ++i) {
5964 const LO lclRow = exportLIDs[i];
5968 if (curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid ()) {
5971 totalNumEntries += curNumEntries;
5982 const size_t allocSize =
5983 static_cast<size_t> (numExportLIDs) *
sizeof (LO) +
5984 totalNumEntries * (
sizeof (IST) +
sizeof (GO));
5985 if (static_cast<size_t> (exports.size ()) < allocSize) {
5986 exports.resize (allocSize);
5990 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
5993 pack (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
5994 Teuchos::Array<char>& exports,
5995 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
5996 size_t& constantNumPackets,
6002 const map_type& colMap = * (this->staticGraph_->colMap_);
6005 colMap.
getComm ().is_null () ? 0 : colMap.
getComm ()->getRank ();
6006 std::unique_ptr<std::string> errStr;
6007 #ifdef HAVE_TPETRA_DEBUG 6008 using Teuchos::outArg;
6009 using Teuchos::REDUCE_MIN;
6010 using Teuchos::reduceAll;
6011 const bool locallyCorrect =
6013 exports, numPacketsPerLID, constantNumPackets,
6014 exportLIDs, myRank, dist);
6015 const int lclOK = locallyCorrect ? 1 : 0;
6017 if (! colMap.
getComm ().is_null ()) {
6018 reduceAll<int, int> (* (colMap.
getComm ()), REDUCE_MIN,
6019 lclOK, outArg (gblOK));
6021 std::ostringstream out;
6022 if (colMap.
getComm ()->getRank () == 0) {
6023 out <<
"Error in packCrsMatrix!" << std::endl;
6025 using ::Tpetra::Details::gathervPrint;
6026 const std::string errStr2 =
6027 errStr.get () == NULL ? std::string (
"") : *errStr;
6028 gathervPrint (out, errStr2, * (colMap.
getComm ()));
6029 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, out.str ());
6032 #else // NOT HAVE_TPETRA_DEBUG 6034 exports, numPacketsPerLID, constantNumPackets,
6035 exportLIDs, myRank, dist);
6036 #endif // HAVE_TPETRA_DEBUG 6039 this->packNonStatic (exportLIDs, exports, numPacketsPerLID,
6040 constantNumPackets, dist);
6044 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6047 packNonStatic (
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
6048 Teuchos::Array<char>& exports,
6049 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
6050 size_t& constantNumPackets,
6054 typedef LocalOrdinal LO;
6055 typedef GlobalOrdinal GO;
6056 const char tfecfFuncName[] =
"pack: ";
6058 const size_t numExportLIDs =
static_cast<size_t> (exportLIDs.size ());
6059 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6060 (numExportLIDs != static_cast<size_t> (numPacketsPerLID.size ()),
6061 std::invalid_argument,
"exportLIDs.size() = " << numExportLIDs
6062 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.size () <<
".");
6067 constantNumPackets = 0;
6072 size_t totalNumEntries = 0;
6073 this->allocatePackSpace (exports, totalNumEntries, exportLIDs);
6074 const size_t bufSize =
static_cast<size_t> (exports.size ());
6086 size_t firstBadIndex = 0;
6087 size_t firstBadOffset = 0;
6088 size_t firstBadNumBytes = 0;
6089 bool outOfBounds =
false;
6090 bool packErr =
false;
6092 char*
const exportsRawPtr = exports.getRawPtr ();
6094 for (
size_t i = 0; i < numExportLIDs; ++i) {
6095 const LO lclRow = exportLIDs[i];
6105 numPacketsPerLID[i] = 0;
6108 char*
const numEntBeg = exportsRawPtr + offset;
6109 char*
const numEntEnd = numEntBeg +
sizeof (LO);
6110 char*
const valBeg = numEntEnd;
6111 char*
const valEnd = valBeg + numEnt *
sizeof (Scalar);
6112 char*
const indBeg = valEnd;
6113 const size_t numBytes =
sizeof (LO) +
6114 numEnt * (
sizeof (IST) +
sizeof (GO));
6115 if (offset > bufSize || offset + numBytes > bufSize) {
6117 firstBadOffset = offset;
6118 firstBadNumBytes = numBytes;
6122 packErr = ! this->packRow (numEntBeg, valBeg, indBeg, numEnt, lclRow);
6125 firstBadOffset = offset;
6126 firstBadNumBytes = numBytes;
6132 numPacketsPerLID[i] = numBytes;
6137 TEUCHOS_TEST_FOR_EXCEPTION(
6138 outOfBounds, std::logic_error,
"First invalid offset into 'exports' " 6139 "pack buffer at index i = " << firstBadIndex <<
". exportLIDs[i]: " 6140 << exportLIDs[firstBadIndex] <<
", bufSize: " << bufSize <<
", offset: " 6141 << firstBadOffset <<
", numBytes: " << firstBadNumBytes <<
".");
6142 TEUCHOS_TEST_FOR_EXCEPTION(
6143 packErr, std::logic_error,
"First error in packRow() at index i = " 6144 << firstBadIndex <<
". exportLIDs[i]: " << exportLIDs[firstBadIndex]
6145 <<
", bufSize: " << bufSize <<
", offset: " << firstBadOffset
6146 <<
", numBytes: " << firstBadNumBytes <<
".");
6149 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6153 const LocalOrdinal numEnt,
6155 const GlobalOrdinal cols[],
6158 typedef GlobalOrdinal GO;
6163 const GO gblRow = this->myGraph_->rowMap_->getGlobalElement (lclRow);
6164 Teuchos::ArrayView<const GO> cols_av (numEnt == 0 ? NULL : cols, numEnt);
6165 Teuchos::ArrayView<const Scalar> vals_av (numEnt == 0 ? NULL : reinterpret_cast<const Scalar*> (vals), numEnt);
6170 this->combineGlobalValues (gblRow, cols_av, vals_av, combineMode);
6175 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6179 const Teuchos::ArrayView<const GlobalOrdinal>& columnIndices,
6180 const Teuchos::ArrayView<const Scalar>& values,
6183 const char tfecfFuncName[] =
"combineGlobalValues: ";
6189 if (combineMode ==
ADD) {
6192 else if (combineMode ==
REPLACE) {
6195 else if (combineMode ==
ABSMAX) {
6198 this->
template transformGlobalValues<AbsMax<Scalar> > (globalRowIndex,
6202 else if (combineMode ==
INSERT) {
6203 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6205 "INSERT combine mode is not allowed if the matrix has a static graph " 6206 "(i.e., was constructed with the CrsMatrix constructor that takes a " 6207 "const CrsGraph pointer).");
6210 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6211 true, std::logic_error,
"Invalid combine mode; should never get " 6212 "here! Please report this bug to the Tpetra developers.");
6216 if (combineMode ==
ADD || combineMode ==
INSERT) {
6223 insertGlobalValuesFiltered (globalRowIndex, columnIndices, values);
6234 else if (combineMode ==
ABSMAX) {
6235 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6237 "ABSMAX combine mode when the matrix has a dynamic graph is not yet " 6240 else if (combineMode ==
REPLACE) {
6241 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6243 "REPLACE combine mode when the matrix has a dynamic graph is not yet " 6247 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6248 true, std::logic_error,
"Should never get here! Please report this " 6249 "bug to the Tpetra developers.");
6255 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6259 const Teuchos::ArrayView<const char>& imports,
6260 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
6261 size_t constantNumPackets,
6266 ProfilingRegion regionUAC (
"Tpetra::CrsMatrix::unpackAndCombine");
6268 #ifdef HAVE_TPETRA_DEBUG 6269 const char tfecfFuncName[] =
"unpackAndCombine: ";
6271 const char* validModeNames[4] = {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT"};
6272 const int numValidModes = 4;
6274 if (std::find (validModes, validModes+numValidModes, combineMode) ==
6275 validModes+numValidModes) {
6276 std::ostringstream os;
6277 os <<
"Invalid combine mode. Valid modes are {";
6278 for (
int k = 0; k < numValidModes; ++k) {
6279 os << validModeNames[k];
6280 if (k < numValidModes - 1) {
6285 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6286 true, std::invalid_argument, os.str ());
6290 using Teuchos::reduceAll;
6291 std::ostringstream msg;
6294 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
6295 constantNumPackets, distor, combineMode);
6296 }
catch (std::exception& e) {
6301 const Teuchos::Comm<int>& comm = * (this->
getComm ());
6302 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
6303 lclBad, Teuchos::outArg (gblBad));
6305 const int myRank = comm.getRank ();
6306 std::ostringstream os;
6307 os <<
"Proc " << myRank <<
": " << msg.str () << std::endl;
6308 ::Tpetra::Details::gathervPrint (std::cerr, os.str (), comm);
6309 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6310 (
true, std::logic_error,
"unpackAndCombineImpl() threw an " 6311 "exception on one or more participating processes.");
6315 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
6316 constantNumPackets, distor, combineMode);
6317 #endif // HAVE_TPETRA_DEBUG 6320 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6324 const Teuchos::ArrayView<const char>& imports,
6325 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
6326 size_t constantNumPackets,
6333 const map_type& colMap = * (this->staticGraph_->colMap_);
6335 const Teuchos::Comm<int>& comm = * (this->
getComm ());
6336 const int myRank = comm.getRank ();
6337 std::unique_ptr<std::string> errStr;
6339 this->
lclMatrix_, lclColMap, errStr, importLIDs, imports,
6340 numPacketsPerLID, constantNumPackets, myRank, distor, combineMode, atomic);
6341 TEUCHOS_TEST_FOR_EXCEPTION(!locallyCorrect, std::runtime_error, *errStr);
6344 this->unpackAndCombineImplNonStatic (importLIDs, imports, numPacketsPerLID,
6345 constantNumPackets, distor, combineMode);
6349 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6353 const Teuchos::ArrayView<const LocalOrdinal>& importLIDs,
6354 const Teuchos::ArrayView<const char>& imports,
6355 const Teuchos::ArrayView<const size_t>& numPacketsPerLID,
6356 size_t constantNumPackets,
6361 typedef LocalOrdinal LO;
6362 typedef GlobalOrdinal GO;
6363 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
6364 const char tfecfFuncName[] =
"unpackAndCombine: ";
6366 const size_type numImportLIDs = importLIDs.size ();
6367 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6368 numImportLIDs != numPacketsPerLID.size (), std::invalid_argument,
6369 "importLIDs.size() = " << numImportLIDs <<
" != numPacketsPerLID.size()" 6370 <<
" = " << numPacketsPerLID.size () <<
".");
6376 size_type firstBadIndex = 0;
6377 size_t firstBadOffset = 0;
6378 size_t firstBadExpectedNumBytes = 0;
6379 size_t firstBadNumBytes = 0;
6380 LO firstBadNumEnt = 0;
6389 bool outOfBounds =
false;
6390 bool wrongNumBytes =
false;
6391 bool unpackErr =
false;
6393 const size_t bufSize =
static_cast<size_t> (imports.size ());
6394 const char*
const importsRawPtr = imports.getRawPtr ();
6403 std::vector<IST> valInTmp;
6404 std::vector<GO> indInTmp;
6405 for (size_type i = 0; i < numImportLIDs; ++i) {
6406 const LO lclRow = importLIDs[i];
6407 const size_t numBytes = numPacketsPerLID[i];
6410 const char*
const numEntBeg = importsRawPtr + offset;
6411 const char*
const numEntEnd = numEntBeg +
sizeof (LO);
6416 memcpy (&numEnt, numEntBeg,
sizeof (LO));
6418 const char*
const valBeg = numEntEnd;
6419 const char*
const valEnd =
6420 valBeg +
static_cast<size_t> (numEnt) *
sizeof (IST);
6421 const char*
const indBeg = valEnd;
6422 const size_t expectedNumBytes =
sizeof (LO) +
6423 static_cast<size_t> (numEnt) * (
sizeof (IST) +
sizeof (GO));
6425 if (expectedNumBytes > numBytes) {
6427 firstBadOffset = offset;
6428 firstBadExpectedNumBytes = expectedNumBytes;
6429 firstBadNumBytes = numBytes;
6430 firstBadNumEnt = numEnt;
6431 wrongNumBytes =
true;
6434 if (offset > bufSize || offset + numBytes > bufSize) {
6436 firstBadOffset = offset;
6437 firstBadExpectedNumBytes = expectedNumBytes;
6438 firstBadNumBytes = numBytes;
6439 firstBadNumEnt = numEnt;
6443 size_t tmpNumEnt =
static_cast<size_t> (valInTmp.size ());
6444 if (tmpNumEnt < static_cast<size_t> (numEnt) ||
6445 static_cast<size_t> (indInTmp.size ()) < static_cast<size_t> (numEnt)) {
6447 tmpNumEnt = std::max (static_cast<size_t> (numEnt), tmpNumEnt * 2);
6448 valInTmp.resize (tmpNumEnt);
6449 indInTmp.resize (tmpNumEnt);
6452 ! unpackRow (valInTmp.data (), indInTmp.data (), tmpNumEnt,
6453 valBeg, indBeg, numEnt, lclRow, combineMode);
6456 firstBadOffset = offset;
6457 firstBadExpectedNumBytes = expectedNumBytes;
6458 firstBadNumBytes = numBytes;
6459 firstBadNumEnt = numEnt;
6466 if (wrongNumBytes || outOfBounds || unpackErr) {
6467 std::ostringstream os;
6468 os <<
" importLIDs[i]: " << importLIDs[firstBadIndex]
6469 <<
", bufSize: " << bufSize
6470 <<
", offset: " << firstBadOffset
6471 <<
", numBytes: " << firstBadNumBytes
6472 <<
", expectedNumBytes: " << firstBadExpectedNumBytes
6473 <<
", numEnt: " << firstBadNumEnt;
6474 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6475 wrongNumBytes, std::logic_error,
"At index i = " << firstBadIndex
6476 <<
", expectedNumBytes > numBytes." << os.str ());
6477 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6478 outOfBounds, std::logic_error,
"First invalid offset into 'imports' " 6479 "unpack buffer at index i = " << firstBadIndex <<
"." << os.str ());
6480 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6481 unpackErr, std::logic_error,
"First error in unpackRow() at index i = " 6482 << firstBadIndex <<
"." << os.str ());
6486 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6487 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
6490 const bool force)
const 6492 using Teuchos::null;
6496 TEUCHOS_TEST_FOR_EXCEPTION(
6497 ! this->
hasColMap (), std::runtime_error,
"Tpetra::CrsMatrix::getColumn" 6498 "MapMultiVector: You may only call this method if the matrix has a " 6499 "column Map. If the matrix does not yet have a column Map, you should " 6500 "first call fillComplete (with domain and range Map if necessary).");
6504 TEUCHOS_TEST_FOR_EXCEPTION(
6506 "CrsMatrix::getColumnMapMultiVector: You may only call this method if " 6507 "this matrix's graph is fill complete.");
6510 RCP<const import_type> importer = this->
getGraph ()->getImporter ();
6511 RCP<const map_type> colMap = this->
getColMap ();
6524 if (! importer.is_null () || force) {
6526 X_colMap = rcp (
new MV (colMap, numVecs));
6543 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6544 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
6547 const bool force)
const 6549 using Teuchos::null;
6555 TEUCHOS_TEST_FOR_EXCEPTION(
6557 "CrsMatrix::getRowMapMultiVector: You may only call this method if this " 6558 "matrix's graph is fill complete.");
6561 RCP<const export_type> exporter = this->
getGraph ()->getExporter ();
6565 RCP<const map_type> rowMap = this->
getRowMap ();
6577 if (! exporter.is_null () || force) {
6579 Y_rowMap = rcp (
new MV (rowMap, numVecs));
6589 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6594 TEUCHOS_TEST_FOR_EXCEPTION(
6595 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::" 6596 "removeEmptyProcessesInPlace: This method does not work when the matrix " 6597 "was created with a constant graph (that is, when it was created using " 6598 "the version of its constructor that takes an RCP<const CrsGraph>). " 6599 "This is because the matrix is not allowed to modify the graph in that " 6600 "case, but removing empty processes requires modifying the graph.");
6601 myGraph_->removeEmptyProcessesInPlace (newMap);
6609 staticGraph_ = Teuchos::rcp_const_cast<
const Graph> (myGraph_);
6612 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6613 Teuchos::RCP<RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
6618 const Teuchos::RCP<const map_type>& domainMap,
6619 const Teuchos::RCP<const map_type>& rangeMap,
6620 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 6622 using Teuchos::Array;
6623 using Teuchos::ArrayRCP;
6624 using Teuchos::ArrayView;
6625 using Teuchos::ParameterList;
6628 using Teuchos::rcp_implicit_cast;
6629 using Teuchos::sublist;
6630 typedef LocalOrdinal LO;
6631 typedef GlobalOrdinal GO;
6635 const crs_matrix_type& B = *
this;
6636 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
6637 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
6644 RCP<const map_type> A_rangeMap = A.
getRangeMap ();
6645 RCP<const map_type> B_domainMap = B.getDomainMap ();
6646 RCP<const map_type> B_rangeMap = B.getRangeMap ();
6648 RCP<const map_type> theDomainMap = domainMap;
6649 RCP<const map_type> theRangeMap = rangeMap;
6651 if (domainMap.is_null ()) {
6652 if (B_domainMap.is_null ()) {
6653 TEUCHOS_TEST_FOR_EXCEPTION(
6654 A_domainMap.is_null (), std::invalid_argument,
6655 "Tpetra::CrsMatrix::add: If neither A nor B have a domain Map, " 6656 "then you must supply a nonnull domain Map to this method.");
6657 theDomainMap = A_domainMap;
6659 theDomainMap = B_domainMap;
6662 if (rangeMap.is_null ()) {
6663 if (B_rangeMap.is_null ()) {
6664 TEUCHOS_TEST_FOR_EXCEPTION(
6665 A_rangeMap.is_null (), std::invalid_argument,
6666 "Tpetra::CrsMatrix::add: If neither A nor B have a range Map, " 6667 "then you must supply a nonnull range Map to this method.");
6668 theRangeMap = A_rangeMap;
6670 theRangeMap = B_rangeMap;
6674 #ifdef HAVE_TPETRA_DEBUG 6678 if (! A_domainMap.is_null () && ! A_rangeMap.is_null ()) {
6679 if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
6680 TEUCHOS_TEST_FOR_EXCEPTION(
6681 ! B_domainMap->isSameAs (*A_domainMap), std::invalid_argument,
6682 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a domain Map " 6683 "which is the same as (isSameAs) this RowMatrix's domain Map.");
6684 TEUCHOS_TEST_FOR_EXCEPTION(
6685 ! B_rangeMap->isSameAs (*A_rangeMap), std::invalid_argument,
6686 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a range Map " 6687 "which is the same as (isSameAs) this RowMatrix's range Map.");
6688 TEUCHOS_TEST_FOR_EXCEPTION(
6689 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
6690 std::invalid_argument,
6691 "Tpetra::CrsMatrix::add: The input domain Map must be the same as " 6692 "(isSameAs) this RowMatrix's domain Map.");
6693 TEUCHOS_TEST_FOR_EXCEPTION(
6694 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
6695 std::invalid_argument,
6696 "Tpetra::CrsMatrix::add: The input range Map must be the same as " 6697 "(isSameAs) this RowMatrix's range Map.");
6700 else if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
6701 TEUCHOS_TEST_FOR_EXCEPTION(
6702 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
6703 std::invalid_argument,
6704 "Tpetra::CrsMatrix::add: The input domain Map must be the same as " 6705 "(isSameAs) this RowMatrix's domain Map.");
6706 TEUCHOS_TEST_FOR_EXCEPTION(
6707 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
6708 std::invalid_argument,
6709 "Tpetra::CrsMatrix::add: The input range Map must be the same as " 6710 "(isSameAs) this RowMatrix's range Map.");
6713 TEUCHOS_TEST_FOR_EXCEPTION(
6714 domainMap.is_null () || rangeMap.is_null (), std::invalid_argument,
6715 "Tpetra::CrsMatrix::add: If neither A nor B have a domain and range " 6716 "Map, then you must supply a nonnull domain and range Map to this " 6719 #endif // HAVE_TPETRA_DEBUG 6724 bool callFillComplete =
true;
6725 RCP<ParameterList> constructorSublist;
6726 RCP<ParameterList> fillCompleteSublist;
6727 if (! params.is_null ()) {
6728 callFillComplete = params->get (
"Call fillComplete", callFillComplete);
6729 constructorSublist = sublist (params,
"Constructor parameters");
6730 fillCompleteSublist = sublist (params,
"fillComplete parameters");
6733 RCP<const map_type> A_rowMap = A.
getRowMap ();
6734 RCP<const map_type> B_rowMap = B.getRowMap ();
6735 RCP<const map_type> C_rowMap = B_rowMap;
6736 RCP<crs_matrix_type> C;
6743 if (A_rowMap->isSameAs (*B_rowMap)) {
6744 const LO localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
6745 ArrayRCP<size_t> C_maxNumEntriesPerRow (localNumRows, 0);
6748 if (alpha != ZERO) {
6749 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
6751 C_maxNumEntriesPerRow[localRow] += A_numEntries;
6756 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
6757 const size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
6758 C_maxNumEntriesPerRow[localRow] += B_numEntries;
6762 if (constructorSublist.is_null ()) {
6763 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow,
6766 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow,
6777 if (constructorSublist.is_null ()) {
6781 constructorSublist));
6785 #ifdef HAVE_TPETRA_DEBUG 6786 TEUCHOS_TEST_FOR_EXCEPTION(C.is_null (), std::logic_error,
6787 "Tpetra::RowMatrix::add: C should not be null at this point. " 6788 "Please report this bug to the Tpetra developers.");
6789 #endif // HAVE_TPETRA_DEBUG 6796 if (alpha != ZERO) {
6797 const LO A_localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
6798 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
6800 const GO globalRow = A_rowMap->getGlobalElement (localRow);
6801 if (A_numEntries > static_cast<size_t> (ind.size ())) {
6802 ind.resize (A_numEntries);
6803 val.resize (A_numEntries);
6805 ArrayView<GO> indView = ind (0, A_numEntries);
6806 ArrayView<Scalar> valView = val (0, A_numEntries);
6810 for (
size_t k = 0; k < A_numEntries; ++k) {
6811 valView[k] *= alpha;
6814 C->insertGlobalValues (globalRow, indView, valView);
6819 const LO B_localNumRows =
static_cast<LO
> (B_rowMap->getNodeNumElements ());
6820 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
6821 size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
6822 const GO globalRow = B_rowMap->getGlobalElement (localRow);
6823 if (B_numEntries > static_cast<size_t> (ind.size ())) {
6824 ind.resize (B_numEntries);
6825 val.resize (B_numEntries);
6827 ArrayView<GO> indView = ind (0, B_numEntries);
6828 ArrayView<Scalar> valView = val (0, B_numEntries);
6829 B.getGlobalRowCopy (globalRow, indView, valView, B_numEntries);
6832 for (
size_t k = 0; k < B_numEntries; ++k) {
6836 C->insertGlobalValues (globalRow, indView, valView);
6840 if (callFillComplete) {
6841 if (fillCompleteSublist.is_null ()) {
6842 C->fillComplete (theDomainMap, theRangeMap);
6844 C->fillComplete (theDomainMap, theRangeMap, fillCompleteSublist);
6847 return rcp_implicit_cast<row_matrix_type> (C);
6850 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
6854 const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node>& rowTransfer,
6855 const Teuchos::RCP<const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node> > & domainTransfer,
6856 const Teuchos::RCP<const map_type>& domainMap,
6857 const Teuchos::RCP<const map_type>& rangeMap,
6858 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 6861 using Teuchos::ArrayRCP;
6862 using Teuchos::ArrayView;
6863 using Teuchos::Comm;
6864 using Teuchos::ParameterList;
6866 typedef LocalOrdinal LO;
6867 typedef GlobalOrdinal GO;
6872 #ifdef HAVE_TPETRA_MMM_TIMINGS 6874 if(!params.is_null())
6875 label = params->get(
"Timer Label",label);
6876 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
6877 using Teuchos::TimeMonitor;
6878 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Pack-1"))));
6888 TEUCHOS_TEST_FOR_EXCEPTION(
6889 xferAsImport == NULL && xferAsExport == NULL, std::invalid_argument,
6890 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' input " 6891 "argument must be either an Import or an Export, and its template " 6892 "parameters must match the corresponding template parameters of the " 6900 Teuchos::RCP<const import_type> xferDomainAsImport = Teuchos::rcp_dynamic_cast<
const import_type> (domainTransfer);
6901 Teuchos::RCP<const export_type> xferDomainAsExport = Teuchos::rcp_dynamic_cast<
const export_type> (domainTransfer);
6903 if(! domainTransfer.is_null()) {
6904 TEUCHOS_TEST_FOR_EXCEPTION(
6905 (xferDomainAsImport.is_null() && xferDomainAsExport.is_null()), std::invalid_argument,
6906 "Tpetra::CrsMatrix::transferAndFillComplete: The 'domainTransfer' input " 6907 "argument must be either an Import or an Export, and its template " 6908 "parameters must match the corresponding template parameters of the " 6911 TEUCHOS_TEST_FOR_EXCEPTION(
6912 ( xferAsImport != NULL || ! xferDomainAsImport.is_null() ) &&
6913 (( xferAsImport != NULL && xferDomainAsImport.is_null() ) ||
6914 ( xferAsImport == NULL && ! xferDomainAsImport.is_null() )), std::invalid_argument,
6915 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input " 6916 "arguments must be of the same type (either Import or Export).");
6918 TEUCHOS_TEST_FOR_EXCEPTION(
6919 ( xferAsExport != NULL || ! xferDomainAsExport.is_null() ) &&
6920 (( xferAsExport != NULL && xferDomainAsExport.is_null() ) ||
6921 ( xferAsExport == NULL && ! xferDomainAsExport.is_null() )), std::invalid_argument,
6922 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input " 6923 "arguments must be of the same type (either Import or Export).");
6929 const bool communication_needed = rowTransfer.getSourceMap ()->isDistributed ();
6935 bool reverseMode =
false;
6936 bool restrictComm =
false;
6937 RCP<ParameterList> matrixparams;
6938 if (! params.is_null ()) {
6939 reverseMode = params->get (
"Reverse Mode", reverseMode);
6940 restrictComm = params->get (
"Restrict Communicator", restrictComm);
6941 matrixparams = sublist (params,
"CrsMatrix");
6946 RCP<const map_type> MyRowMap = reverseMode ?
6947 rowTransfer.getSourceMap () : rowTransfer.getTargetMap ();
6948 RCP<const map_type> MyColMap;
6949 RCP<const map_type> MyDomainMap = ! domainMap.is_null () ?
6951 RCP<const map_type> MyRangeMap = ! rangeMap.is_null () ?
6953 RCP<const map_type> BaseRowMap = MyRowMap;
6954 RCP<const map_type> BaseDomainMap = MyDomainMap;
6962 if (! destMat.is_null ()) {
6973 const bool NewFlag = ! destMat->getGraph ()->isLocallyIndexed () &&
6974 ! destMat->getGraph ()->isGloballyIndexed ();
6975 TEUCHOS_TEST_FOR_EXCEPTION(
6976 ! NewFlag, std::invalid_argument,
"Tpetra::CrsMatrix::" 6977 "transferAndFillComplete: The input argument 'destMat' is only allowed " 6978 "to be nonnull, if its graph is empty (neither locally nor globally " 6987 TEUCHOS_TEST_FOR_EXCEPTION(
6988 ! destMat->getRowMap ()->isSameAs (*MyRowMap), std::invalid_argument,
6989 "Tpetra::CrsMatrix::transferAndFillComplete: The (row) Map of the " 6990 "input argument 'destMat' is not the same as the (row) Map specified " 6991 "by the input argument 'rowTransfer'.");
6992 TEUCHOS_TEST_FOR_EXCEPTION(
6993 ! destMat->checkSizes (*
this), std::invalid_argument,
6994 "Tpetra::CrsMatrix::transferAndFillComplete: You provided a nonnull " 6995 "destination matrix, but checkSizes() indicates that it is not a legal " 6996 "legal target for redistribution from the source matrix (*this). This " 6997 "may mean that they do not have the same dimensions.");
7011 TEUCHOS_TEST_FOR_EXCEPTION(
7012 ! (reverseMode ||
getRowMap ()->isSameAs (*rowTransfer.getSourceMap ())),
7013 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: " 7014 "rowTransfer->getSourceMap() must match this->getRowMap() in forward mode.");
7015 TEUCHOS_TEST_FOR_EXCEPTION(
7016 ! (! reverseMode ||
getRowMap ()->isSameAs (*rowTransfer.getTargetMap ())),
7017 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: " 7018 "rowTransfer->getTargetMap() must match this->getRowMap() in reverse mode.");
7021 TEUCHOS_TEST_FOR_EXCEPTION(
7022 ! xferDomainAsImport.is_null() && ! xferDomainAsImport->getTargetMap()->isSameAs(*domainMap),
7023 std::invalid_argument,
7024 "Tpetra::CrsMatrix::transferAndFillComplete: The target map of the 'domainTransfer' input " 7025 "argument must be the same as the rebalanced domain map 'domainMap'");
7027 TEUCHOS_TEST_FOR_EXCEPTION(
7028 ! xferDomainAsExport.is_null() && ! xferDomainAsExport->getSourceMap()->isSameAs(*domainMap),
7029 std::invalid_argument,
7030 "Tpetra::CrsMatrix::transferAndFillComplete: The source map of the 'domainTransfer' input " 7031 "argument must be the same as the rebalanced domain map 'domainMap'");
7044 const size_t NumSameIDs = rowTransfer.getNumSameIDs();
7045 ArrayView<const LO> ExportLIDs = reverseMode ?
7046 rowTransfer.getRemoteLIDs () : rowTransfer.getExportLIDs ();
7047 ArrayView<const LO> RemoteLIDs = reverseMode ?
7048 rowTransfer.getExportLIDs () : rowTransfer.getRemoteLIDs ();
7049 ArrayView<const LO> PermuteToLIDs = reverseMode ?
7050 rowTransfer.getPermuteFromLIDs () : rowTransfer.getPermuteToLIDs ();
7051 ArrayView<const LO> PermuteFromLIDs = reverseMode ?
7052 rowTransfer.getPermuteToLIDs () : rowTransfer.getPermuteFromLIDs ();
7053 Distributor& Distor = rowTransfer.getDistributor ();
7056 Teuchos::Array<int> SourcePids;
7057 Teuchos::Array<int> TargetPids;
7058 int MyPID =
getComm ()->getRank ();
7061 RCP<const map_type> ReducedRowMap, ReducedColMap,
7062 ReducedDomainMap, ReducedRangeMap;
7063 RCP<const Comm<int> > ReducedComm;
7067 if (destMat.is_null ()) {
7068 destMat = rcp (
new this_type (MyRowMap, 0,
StaticProfile, matrixparams));
7075 ReducedRowMap = MyRowMap->removeEmptyProcesses ();
7076 ReducedComm = ReducedRowMap.is_null () ?
7078 ReducedRowMap->getComm ();
7079 destMat->removeEmptyProcessesInPlace (ReducedRowMap);
7081 ReducedDomainMap = MyRowMap.getRawPtr () == MyDomainMap.getRawPtr () ?
7083 MyDomainMap->replaceCommWithSubset (ReducedComm);
7084 ReducedRangeMap = MyRowMap.getRawPtr () == MyRangeMap.getRawPtr () ?
7086 MyRangeMap->replaceCommWithSubset (ReducedComm);
7089 MyRowMap = ReducedRowMap;
7090 MyDomainMap = ReducedDomainMap;
7091 MyRangeMap = ReducedRangeMap;
7094 if (! ReducedComm.is_null ()) {
7095 MyPID = ReducedComm->getRank ();
7102 ReducedComm = MyRowMap->getComm ();
7108 #ifdef HAVE_TPETRA_MMM_TIMINGS 7109 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC ImportSetup"))));
7112 RCP<const import_type> MyImporter =
getGraph ()->getImporter ();
7115 bool bSameDomainMap = BaseDomainMap->isSameAs (*
getDomainMap ());
7117 if (! restrictComm && ! MyImporter.is_null () && bSameDomainMap ) {
7124 Import_Util::getPids (*MyImporter, SourcePids,
false);
7126 else if (restrictComm && ! MyImporter.is_null () && bSameDomainMap) {
7130 IntVectorType SourceCol_pids(
getColMap());
7132 SourceDomain_pids.putScalar(MyPID);
7134 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
7135 SourcePids.resize (
getColMap ()->getNodeNumElements ());
7136 SourceCol_pids.get1dCopy (SourcePids ());
7138 else if (MyImporter.is_null () && bSameDomainMap) {
7140 SourcePids.resize (
getColMap ()->getNodeNumElements ());
7141 SourcePids.assign (
getColMap ()->getNodeNumElements (), MyPID);
7143 else if ( ! MyImporter.is_null () &&
7144 ! domainTransfer.is_null () ) {
7151 IntVectorType TargetDomain_pids (domainMap);
7152 TargetDomain_pids.putScalar (MyPID);
7158 IntVectorType SourceCol_pids (
getColMap ());
7160 if (! reverseMode && ! xferDomainAsImport.is_null() ) {
7161 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
7163 else if (reverseMode && ! xferDomainAsExport.is_null() ) {
7164 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
7166 else if (! reverseMode && ! xferDomainAsExport.is_null() ) {
7167 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
7169 else if (reverseMode && ! xferDomainAsImport.is_null() ) {
7170 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
7173 TEUCHOS_TEST_FOR_EXCEPTION(
7174 true, std::logic_error,
"Tpetra::CrsMatrix::" 7175 "transferAndFillComplete: Should never get here! " 7176 "Please report this bug to a Tpetra developer.");
7178 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
7179 SourcePids.resize (
getColMap ()->getNodeNumElements ());
7180 SourceCol_pids.get1dCopy (SourcePids ());
7182 else if (BaseDomainMap->isSameAs (*BaseRowMap) &&
7185 IntVectorType TargetRow_pids (domainMap);
7186 IntVectorType SourceRow_pids (
getRowMap ());
7187 IntVectorType SourceCol_pids (
getColMap ());
7189 TargetRow_pids.putScalar (MyPID);
7190 if (! reverseMode && xferAsImport != NULL) {
7191 SourceRow_pids.doExport (TargetRow_pids, *xferAsImport,
INSERT);
7193 else if (reverseMode && xferAsExport != NULL) {
7194 SourceRow_pids.doExport (TargetRow_pids, *xferAsExport,
INSERT);
7196 else if (! reverseMode && xferAsExport != NULL) {
7197 SourceRow_pids.doImport (TargetRow_pids, *xferAsExport,
INSERT);
7199 else if (reverseMode && xferAsImport != NULL) {
7200 SourceRow_pids.doImport (TargetRow_pids, *xferAsImport,
INSERT);
7203 TEUCHOS_TEST_FOR_EXCEPTION(
7204 true, std::logic_error,
"Tpetra::CrsMatrix::" 7205 "transferAndFillComplete: Should never get here! " 7206 "Please report this bug to a Tpetra developer.");
7208 SourceCol_pids.doImport (SourceRow_pids, *MyImporter,
INSERT);
7209 SourcePids.resize (
getColMap ()->getNodeNumElements ());
7210 SourceCol_pids.get1dCopy (SourcePids ());
7213 TEUCHOS_TEST_FOR_EXCEPTION(
7214 true, std::invalid_argument,
"Tpetra::CrsMatrix::" 7215 "transferAndFillComplete: This method only allows either domainMap == " 7216 "getDomainMap (), or (domainMap == rowTransfer.getTargetMap () and " 7217 "getDomainMap () == getRowMap ()).");
7219 #ifdef HAVE_TPETRA_MMM_TIMINGS 7220 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Pack-2"))));
7224 size_t constantNumPackets = destMat->constantNumberOfPackets ();
7225 if (constantNumPackets == 0) {
7228 execution_space::fence ();
7229 destMat->numExportPacketsPerLID_ =
7230 decltype (destMat->numExportPacketsPerLID_) (
"numExportPacketsPerLID",
7231 ExportLIDs.size ());
7232 execution_space::fence ();
7233 destMat->numImportPacketsPerLID_ =
7234 decltype (destMat->numImportPacketsPerLID_) (
"numImportPacketsPerLID",
7235 RemoteLIDs.size ());
7236 execution_space::fence ();
7243 const size_t rbufLen = RemoteLIDs.size() * constantNumPackets;
7244 destMat->reallocImportsIfNeeded (rbufLen);
7248 #ifdef HAVE_TPETRA_DEBUG 7250 using Teuchos::outArg;
7251 using Teuchos::REDUCE_MAX;
7252 using Teuchos::reduceAll;
7255 RCP<const Teuchos::Comm<int> > comm = this->
getComm ();
7256 const int myRank = comm->getRank ();
7257 const int numProcs = comm->getSize ();
7259 std::ostringstream os;
7263 destMat->numExportPacketsPerLID_.template modify<Kokkos::HostSpace> ();
7264 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
7266 Import_Util::packAndPrepareWithOwningPIDs (*
this, ExportLIDs,
7268 numExportPacketsPerLID,
7269 constantNumPackets, Distor,
7272 catch (std::exception& e) {
7273 os <<
"Proc " << myRank <<
": " << e.what ();
7277 if (! comm.is_null ()) {
7278 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
7282 cerr <<
"packAndPrepareWithOwningPIDs threw an exception: " << endl;
7284 std::ostringstream err;
7285 for (
int r = 0; r < numProcs; ++r) {
7286 if (r == myRank && lclErr != 0) {
7287 cerr << os.str () << endl;
7294 TEUCHOS_TEST_FOR_EXCEPTION(
7295 true, std::logic_error,
"packAndPrepareWithOwningPIDs threw an " 7303 destMat->numExportPacketsPerLID_.template modify<Kokkos::HostSpace> ();
7304 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
7306 Import_Util::packAndPrepareWithOwningPIDs (*
this, ExportLIDs,
7308 numExportPacketsPerLID,
7309 constantNumPackets, Distor,
7312 #endif // HAVE_TPETRA_DEBUG 7315 #ifdef HAVE_TPETRA_MMM_TIMINGS 7316 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Transfer"))));
7319 if (communication_needed) {
7321 if (constantNumPackets == 0) {
7325 destMat->numExportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
7326 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
7328 destMat->numImportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
7329 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
7332 numImportPacketsPerLID);
7333 size_t totalImportPackets = 0;
7334 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
7335 totalImportPackets += numImportPacketsPerLID[i];
7340 destMat->reallocImportsIfNeeded (totalImportPackets);
7341 destMat->imports_.template modify<Kokkos::HostSpace> ();
7342 Teuchos::ArrayView<char> hostImports =
7346 destMat->exports_.template sync<Kokkos::HostSpace> ();
7347 Teuchos::ArrayView<const char> hostExports =
7350 numExportPacketsPerLID,
7352 numImportPacketsPerLID);
7355 destMat->imports_.template modify<Kokkos::HostSpace> ();
7356 Teuchos::ArrayView<char> hostImports =
7360 destMat->exports_.template sync<Kokkos::HostSpace> ();
7361 Teuchos::ArrayView<const char> hostExports =
7369 if (constantNumPackets == 0) {
7373 destMat->numExportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
7374 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
7376 destMat->numImportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
7377 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
7380 numImportPacketsPerLID);
7381 size_t totalImportPackets = 0;
7382 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
7383 totalImportPackets += numImportPacketsPerLID[i];
7388 destMat->reallocImportsIfNeeded (totalImportPackets);
7389 destMat->imports_.template modify<Kokkos::HostSpace> ();
7390 Teuchos::ArrayView<char> hostImports =
7394 destMat->exports_.template sync<Kokkos::HostSpace> ();
7395 Teuchos::ArrayView<const char> hostExports =
7398 numExportPacketsPerLID,
7400 numImportPacketsPerLID);
7403 destMat->imports_.template modify<Kokkos::HostSpace> ();
7404 Teuchos::ArrayView<char> hostImports =
7408 destMat->exports_.template sync<Kokkos::HostSpace> ();
7409 Teuchos::ArrayView<const char> hostExports =
7422 #ifdef HAVE_TPETRA_MMM_TIMINGS 7423 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-1"))));
7427 destMat->numImportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
7428 Teuchos::ArrayView<const size_t> numImportPacketsPerLID =
7430 destMat->imports_.template sync<Kokkos::HostSpace> ();
7431 Teuchos::ArrayView<const char> hostImports =
7434 Import_Util::unpackAndCombineWithOwningPIDsCount (*
this, RemoteLIDs,
7436 numImportPacketsPerLID,
7442 size_t N = BaseRowMap->getNodeNumElements ();
7445 ArrayRCP<size_t> CSR_rowptr(N+1);
7446 ArrayRCP<GO> CSR_colind_GID;
7447 ArrayRCP<LO> CSR_colind_LID;
7448 ArrayRCP<Scalar> CSR_vals;
7449 CSR_colind_GID.resize (mynnz);
7450 CSR_vals.resize (mynnz);
7454 if (
typeid (LO) ==
typeid (GO)) {
7455 CSR_colind_LID = Teuchos::arcp_reinterpret_cast<LO> (CSR_colind_GID);
7458 CSR_colind_LID.resize (mynnz);
7466 Import_Util::unpackAndCombineIntoCrsArrays (*
this, RemoteLIDs, hostImports,
7467 numImportPacketsPerLID,
7468 constantNumPackets, Distor,
INSERT, NumSameIDs,
7469 PermuteToLIDs, PermuteFromLIDs, N, mynnz, MyPID,
7470 CSR_rowptr (), CSR_colind_GID (), CSR_vals (),
7471 SourcePids (), TargetPids);
7476 #ifdef HAVE_TPETRA_MMM_TIMINGS 7477 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-2"))));
7482 Teuchos::Array<int> RemotePids;
7483 Import_Util::lowCommunicationMakeColMapAndReindex (CSR_rowptr (),
7487 TargetPids, RemotePids,
7494 ReducedColMap = (MyRowMap.getRawPtr () == MyColMap.getRawPtr ()) ?
7496 MyColMap->replaceCommWithSubset (ReducedComm);
7497 MyColMap = ReducedColMap;
7501 destMat->replaceColMap (MyColMap);
7508 if (ReducedComm.is_null ()) {
7515 #ifdef HAVE_TPETRA_MMM_TIMINGS 7516 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC Unpack-3"))));
7518 if ((! reverseMode && xferAsImport != NULL) ||
7519 (reverseMode && xferAsExport != NULL)) {
7520 Import_Util::sortCrsEntries (CSR_rowptr (),
7524 else if ((! reverseMode && xferAsExport != NULL) ||
7525 (reverseMode && xferAsImport != NULL)) {
7526 Import_Util::sortAndMergeCrsEntries (CSR_rowptr (),
7529 if (CSR_rowptr[N] != mynnz) {
7530 CSR_colind_LID.resize (CSR_rowptr[N]);
7531 CSR_vals.resize (CSR_rowptr[N]);
7535 TEUCHOS_TEST_FOR_EXCEPTION(
7536 true, std::logic_error,
"Tpetra::CrsMatrix::" 7537 "transferAndFillComplete: Should never get here! " 7538 "Please report this bug to a Tpetra developer.");
7549 destMat->setAllValues (CSR_rowptr, CSR_colind_LID, CSR_vals);
7555 Teuchos::ParameterList esfc_params;
7556 #ifdef HAVE_TPETRA_MMM_TIMINGS 7557 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC CreateImporter"))));
7559 RCP<import_type> MyImport = rcp (
new import_type (MyDomainMap, MyColMap, RemotePids));
7560 #ifdef HAVE_TPETRA_MMM_TIMINGS 7561 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC ESFC"))));
7563 esfc_params.set(
"Timer Label",prefix + std::string(
"TAFC"));
7565 if(!params.is_null())
7566 esfc_params.set(
"compute global constants",params->get(
"compute global constants",
true));
7568 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap, MyImport,Teuchos::null,rcp(&esfc_params,
false));
7571 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7576 const Teuchos::RCP<const map_type>& domainMap,
7577 const Teuchos::RCP<const map_type>& rangeMap,
7578 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7580 transferAndFillComplete (destMatrix, importer, Teuchos::null, domainMap, rangeMap, params);
7583 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7589 const Teuchos::RCP<const map_type>& domainMap,
7590 const Teuchos::RCP<const map_type>& rangeMap,
7591 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7593 transferAndFillComplete (destMatrix, rowImporter, Teuchos::rcpFromRef(domainImporter), domainMap, rangeMap, params);
7596 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7601 const Teuchos::RCP<const map_type>& domainMap,
7602 const Teuchos::RCP<const map_type>& rangeMap,
7603 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7605 transferAndFillComplete (destMatrix, exporter, Teuchos::null, domainMap, rangeMap, params);
7608 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
7614 const Teuchos::RCP<const map_type>& domainMap,
7615 const Teuchos::RCP<const map_type>& rangeMap,
7616 const Teuchos::RCP<Teuchos::ParameterList>& params)
const 7618 transferAndFillComplete (destMatrix, rowExporter, Teuchos::rcpFromRef(domainExporter), domainMap, rangeMap, params);
7629 #define TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR,LO,GO,NODE) \ 7631 template class CrsMatrix< SCALAR , LO , GO , NODE >; \ 7632 template Teuchos::RCP< CrsMatrix< SCALAR , LO , GO , NODE > > \ 7633 CrsMatrix< SCALAR , LO , GO , NODE >::convert< SCALAR > () const; 7635 #define TPETRA_CRSMATRIX_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \ 7637 template Teuchos::RCP< CrsMatrix< SO , LO , GO , NODE > > \ 7638 CrsMatrix< SI , LO , GO , NODE >::convert< SO > () const; 7640 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7642 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7643 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7644 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7645 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7646 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& importer, \ 7647 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7648 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7649 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7650 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7651 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7652 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7653 const Teuchos::RCP<Teuchos::ParameterList>& params); 7655 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \ 7657 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7658 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7659 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7660 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7661 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowImporter, \ 7662 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7663 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7664 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainImporter, \ 7665 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7666 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7667 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7668 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7669 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7670 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7671 const Teuchos::RCP<Teuchos::ParameterList>& params); 7674 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7676 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7677 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7678 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7679 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7680 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& exporter, \ 7681 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7682 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7683 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7684 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7685 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7686 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7687 const Teuchos::RCP<Teuchos::ParameterList>& params); 7689 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \ 7691 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \ 7692 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \ 7693 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7694 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7695 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowExporter, \ 7696 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7697 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7698 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainExporter, \ 7699 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7700 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7701 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \ 7702 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \ 7703 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \ 7704 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \ 7705 const Teuchos::RCP<Teuchos::ParameterList>& params); 7708 #define TPETRA_CRSMATRIX_INSTANT(SCALAR, LO, GO ,NODE) \ 7709 TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR, LO, GO, NODE) \ 7710 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7711 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \ 7712 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \ 7713 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) 7715 #endif // TPETRA_CRSMATRIX_DEF_HPP void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
ProfileType getProfileType() const
Returns true if the matrix was allocated with static data structures.
void doPostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the (forward) communication plan.
LocalOrdinal replaceGlobalValues(const GlobalOrdinal globalRow, const typename UnmanagedView< GlobalIndicesViewType >::type &inputInds, const typename UnmanagedView< ImplScalarViewType >::type &inputVals) const
Replace one or more entries' values, using global indices.
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...
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...
ProfileType getProfileType() const
Returns true if the graph was allocated with static data structures.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Functions for unpacking the entries of a Tpetra::CrsMatrix for communication, in the case where it is...
Functor for the the ABSMAX CombineMode of Import and Export operations.
size_t getNodeMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
void copyOffsets(const OutputViewType &dst, const InputViewType &src)
Copy row offsets (in a sparse graph or matrix) from src to dst. The offsets may have different types...
virtual bool isLocallyIndexed() const =0
Whether matrix indices are locally indexed.
dual_view_type getDualView() const
Get the Kokkos::DualView which implements local storage.
std::string description() const
A one-line description of this object.
mag_type getFrobeniusNorm() const
Compute and return the Frobenius norm of the matrix.
LocalOrdinal local_ordinal_type
This class' second template parameter; the type of local indices.
size_t getNodeNumEntries() const
The local number of entries in this matrix.
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
LocalOrdinal sumIntoLocalValues(const LocalOrdinal localRow, const typename UnmanagedView< LocalIndicesViewType >::type &inputInds, const typename UnmanagedView< ImplScalarViewType >::type &inputVals, const bool atomic=useAtomicUpdatesByDefault) const
Sum into one or more sparse matrix entries, using local row and column indices.
size_t getNodeNumEntries() const
Returns the local number of entries in the graph.
LocalOrdinal replaceLocalValues(const LocalOrdinal localRow, const typename UnmanagedView< LocalIndicesViewType >::type &inputInds, const typename UnmanagedView< ImplScalarViewType >::type &inputVals) const
Replace one or more entries' values, using local row and column indices.
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
Teuchos::RCP< const RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const
This matrix's graph, as a RowGraph.
global_size_t getGlobalNumDiags() const
Returns the number of global diagonal entries, based on global row/column index comparisons.
bool noRedundancies_
Whether the graph's indices are non-redundant (merged) in each row, on this process.
bool isFillActive() const
Whether the matrix is not fill complete.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in the graph.
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...
virtual void copyAndPermute(const SrcDistObject &source, size_t numSameIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteToLIDs, const Teuchos::ArrayView< const LocalOrdinal > &permuteFromLIDs)
Perform copies and permutations that are local to this process.
size_t getNodeNumDiags() const
Returns the number of local diagonal entries, based on global row/column index comparisons.
void resumeFill(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Resume operations that may change the values or structure of the matrix.
Teuchos::RCP< const map_type > getRowMap() const
Returns the Map that describes the row distribution in this graph.
Teuchos::ArrayView< const impl_scalar_type > getView(RowInfo rowinfo) const
Constant view of all entries (including extra space) in the given row.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
global_size_t getGlobalNumEntries() const
The global number of entries in this matrix.
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.
void rightScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &x)
bool isLocallyComplete() const
Do all source Map indices on the calling process exist on at least one process (not necessarily this ...
Details::EStorageStatus storageStatus_
Status of the matrix's storage, when not in a fill-complete state.
Teuchos::ArrayView< impl_scalar_type > getViewNonConst(const RowInfo &rowinfo) const
Nonconst view of all entries (including extra space) in the given row.
size_t getNodeNumCols() const
The number of columns connected to the locally owned rows of this matrix.
Teuchos::RCP< const map_type > getRowMap() const
The Map that describes the row distribution in this matrix.
bool hasColMap() const
Indicates whether the matrix has a well-defined column map.
bool packCrsMatrix(const LocalMatrixType &lclMatrix, const LocalMapType &lclColMap, std::unique_ptr< std::string > &errStr, Teuchos::Array< char > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, const Teuchos::ArrayView< const typename LocalMatrixType::ordinal_type > &exportLIDs, const int myRank, Distributor &)
Pack specified entries of the given local sparse matrix for communication.
Teuchos::RCP< const map_type > getRangeMap() const
Returns the Map associated with the domain of this graph.
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.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.
Teuchos::RCP< node_type > getNode() const
The Kokkos Node instance.
Declare and define Tpetra::Details::copyOffsets, an implementation detail of Tpetra (in particular...
global_size_t getGlobalNumRows() const
Returns the number of global rows in the graph.
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.
Teuchos::RCP< MV > getColumnMapMultiVector(const MV &X_domainMap, const bool force=false) const
Create a (or fetch a cached) column Map MultiVector.
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 getNodeNumDiags() const
Returns the number of local diagonal entries, based on global row/column index comparisons.
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=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Compute a sparse matrix-MultiVector multiply.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.
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.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the communicator.
size_t nodeNumEntries_
Local number of (populated) entries; must always be consistent.
local_map_type getLocalMap() const
Get the local Map for Kokkos kernels.
Node node_type
This class' fourth template parameter; the Kokkos device type.
bool fillComplete_
Whether the matrix is fill complete.
bool isLowerTriangular() const
Indicates whether the matrix is lower triangular.
Node::device_type device_type
The Kokkos device type.
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...
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
RowInfo getRowInfo(const LocalOrdinal myRow) const
Get information about the locally owned row with local index myRow.
virtual bool supportsRowViews() const
Return true if getLocalRowView() and getGlobalRowView() are valid for this object.
void getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &diag) const
Get a copy of the diagonal entries of the matrix.
Teuchos_Ordinal Array_size_type
Size type for Teuchos Array objects.
void doReversePostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the reverse communication plan.
Functions for packing the entries of a Tpetra::CrsMatrix for communication, in the case where it is v...
size_t getNodeNumCols() const
Returns the number of columns connected to the locally owned rows of this graph.
Teuchos::RCP< node_type > getNode() const
Returns the underlying node.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes owning zero rows from the Maps and their communicator.
device_type::execution_space execution_space
The Kokkos execution space.
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 column indices.
void reduce()
Sum values of a locally replicated multivector across all processes.
Teuchos::RCP< const map_type > getDomainMap() const
Returns the Map associated with the domain of this graph.
void fillLocalMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local matrix.
size_t global_size_t
Global size_t object.
LocalOrdinal sumIntoGlobalValues(const GlobalOrdinal globalRow, const Teuchos::ArrayView< const GlobalOrdinal > &cols, const Teuchos::ArrayView< const Scalar > &vals, const bool atomic=useAtomicUpdatesByDefault)
Sum into one or more sparse matrix entries, using global indices.
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2 valEnd)
Merge values in place, additively, with the same index.
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.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
Insert new values that don't currently exist.
Teuchos::RCP< const import_type > getImporter() const
Returns the importer associated with this graph.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createOneToOne(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &M)
Creates a one-to-one version of the given Map where each GID is owned by only one process...
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.
global_size_t getGlobalNumCols() const
The number of global columns in the matrix.
bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
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 getLocalDiagOffsets(Teuchos::ArrayRCP< size_t > &offsets) const
Get offsets of the diagonal entries in the matrix.
global_size_t getGlobalNumRows() const
Number of global elements in the row map of this matrix.
bool isFillComplete() const
Whether the matrix is fill complete.
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.
Declare and define the function Tpetra::Details::computeOffsetsFromCounts, an implementation detail o...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Teuchos::RCP< const export_type > getExporter() const
Returns the exporter associated with this graph.
void scale(const Scalar &alpha)
Scale the matrix's values: this := alpha*this.
bool unpackCrsMatrixAndCombine(LocalMatrixType &lclMatrix, const LocalMapType &lclColMap, std::unique_ptr< std::string > &errStr, const Teuchos::ArrayView< const typename LocalMatrixType::ordinal_type > &importLIDs, const Teuchos::ArrayView< const char > &imports, const Teuchos::ArrayView< const size_t > &numPacketsPerLID, size_t constantNumPackets, const int myRank, Distributor &, CombineMode combineMode, const bool atomic)
Unpack the imported column indices and values, and combine into 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.
bool isStorageOptimized() const
Returns true if storage has been optimized.
void getLocalRowView(const LocalOrdinal lclRow, Teuchos::ArrayView< const LocalOrdinal > &lclColInds) const
Get a const, non-persisting view of the given local row's local column indices, as a Teuchos::ArrayVi...
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
void setAllValues(const typename local_matrix_type::row_map_type &ptr, const typename local_graph_type::entries_type::non_const_type &ind, const typename local_matrix_type::values_type &val)
Set the local matrix using three (compressed sparse row) arrays.
Teuchos::RCP< const map_type > map_
The Map over which this object is distributed.
LocalOrdinal getLocalRowViewRaw(const LocalOrdinal lclRow, LocalOrdinal &numEnt, const LocalOrdinal *&lclColInds, const Scalar *&vals) const
Get a constant, nonpersisting, locally indexed view of the given row of the matrix, using "raw" pointers instead of Teuchos::ArrayView.
bool isUpperTriangular() const
Indicates whether the matrix is upper triangular.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
Utility functions for packing and unpacking sparse matrix entries.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
bool isStaticGraph() const
Indicates that the graph is static, so that new entries cannot be added to this matrix.
KokkosSparse::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...
virtual ~CrsMatrix()
Destructor.
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...
Replace old value with maximum of magnitudes of old and new values.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
Abstract base class for objects that can be the source of an Import or Export operation.
size_t getNodeNumRows() const
Returns the number of graph rows owned on the calling node.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
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.
static LocalMapType::local_ordinal_type getDiagCopyWithoutOffsets(const DiagType &D, const LocalMapType &rowMap, const LocalMapType &colMap, const CrsMatrixType &A)
Given a locally indexed, local sparse matrix, and corresponding local row and column Maps...
LocalOrdinal getViewRaw(impl_scalar_type *&vals, LocalOrdinal &numEnt, const RowInfo &rowinfo) const
Nonconst pointer to all entries (including extra space) in the given row.
void fillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Tell the matrix that you are done changing its structure or values, and that you are ready to do comp...
LO getLocalDiagCopyWithoutOffsetsNotFillComplete(::Tpetra::Vector< SC, LO, GO, NT > &diag, const ::Tpetra::RowMatrix< SC, LO, GO, NT > &A, const bool debug=false)
Given a locally indexed, global sparse matrix, extract the matrix's diagonal entries into a Tpetra::V...
Replace existing values with new values.
#define TPETRA_EFFICIENCY_WARNING(throw_exception_test, Exception, msg)
Print or throw an efficency warning.
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...
void computeGlobalConstants()
Compute matrix properties that require collectives.
bool hasTransposeApply() const
Whether apply() allows applying the transpose or conjugate transpose.
bool isLocallyIndexed() const
If graph indices are in the local range, this function returns true. Otherwise, this function returns...
Replace old values with zero.
size_t getNodeMaxNumRowEntries() const
Maximum number of entries in all rows owned by the calling process.
bool isUpperTriangular() const
Whether the graph is locally upper triangular.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
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 .
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.
size_t getGlobalMaxNumRowEntries() const
Maximum number of entries in all rows over all processes.
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...
bool isLowerTriangular() const
Whether the graph is locally lower triangular.
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...
Kokkos::Details::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
size_t getNodeNumRows() const
The number of matrix rows owned by the calling process.
bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
bool isGloballyIndexed() const
If graph indices are in the global range, this function returns true. Otherwise, this function return...
void leftScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &x)
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Teuchos::RCP< MV > importMV_
Column Map MultiVector used in apply() and gaussSeidel().
void checkInternalState() const
Check that this object's state is sane; throw if it's not.
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.
A parallel distribution of indices over processes.
Teuchos::RCP< const map_type > getColMap() const
Returns the Map that describes the column distribution in this graph.
Teuchos::ArrayView< typename DualViewType::t_dev::value_type > getArrayViewFromDualView(const DualViewType &x)
Get a Teuchos::ArrayView which views the host Kokkos::View of the input 1-D Kokkos::DualView.
void applyNonTranspose(const MV &X_in, MV &Y_in, Scalar alpha, Scalar beta) const
Special case of apply() for mode == Teuchos::NO_TRANS.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Get the number of entries in the given row (local index).
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects...
size_t getNumVectors() const
Number of columns in the multivector.
Teuchos::RCP< Node > getNode() const
Get this Map's Node object.
A read-only, row-oriented interface to a sparse matrix.
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
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().
size_t mergeRowIndicesAndValues(crs_graph_type &graph, const RowInfo &rowInfo)
Merge duplicate row indices in the given row, along with their corresponding values.
A distributed dense vector.
bool isGloballyIndexed() const
Whether the matrix is globally indexed on the calling 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 .
void insertLocalValues(const LocalOrdinal localRow, const Teuchos::ArrayView< const LocalOrdinal > &cols, const Teuchos::ArrayView< const Scalar > &vals)
Insert one or more entries into the matrix, using local column indices.
Teuchos::RCP< const map_type > getColMap() const
The Map that describes the column distribution in this matrix.
Teuchos::RCP< const map_type > getDomainMap() const
The domain Map of this matrix.
Kokkos::View< size_t *, Kokkos::LayoutLeft, device_type >::HostMirror k_numRowEntries_
The number of local entries in each locally owned row.
void doExport(const SrcDistObject &source, const Export< LocalOrdinal, GlobalOrdinal, Node > &exporter, CombineMode CM)
Export data into this object using an Export object ("forward mode").
void sortAndMergeIndicesAndValues(const bool sorted, const bool merged)
Sort and merge duplicate local column indices in all rows on the calling process, along with their co...
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.
Teuchos::RCP< MV > exportMV_
Row Map MultiVector used in apply().
Teuchos::RCP< MV > getRowMapMultiVector(const MV &Y_rangeMap, const bool force=false) const
Create a (or fetch a cached) row Map MultiVector.
bool isDistributed() const
Whether this is a globally distributed object.
Teuchos::RCP< const map_type > getRangeMap() const
The range Map of this matrix.
Declaration and definition of Tpetra::Details::getEntryOnHost.
void expertStaticFillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< const import_type > &importer=Teuchos::null, const Teuchos::RCP< const export_type > &exporter=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Perform a fillComplete on a matrix that already has data.
bool isStorageOptimized() const
Returns true if storage has been optimized.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
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.
Teuchos::RCP< const crs_graph_type > getCrsGraph() const
This matrix's graph, as a CrsGraph.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
void clearGlobalConstants()
Clear matrix properties that require collectives.
global_size_t getGlobalNumCols() const
Returns the number of global columns in the graph.
bool hasColMap() const
Whether the graph has a column Map.
global_size_t getGlobalNumDiags() const
Returns the number of global diagonal entries, based on global row/column index comparisons.
LocalOrdinal getViewRawConst(const impl_scalar_type *&vals, LocalOrdinal &numEnt, const RowInfo &rowinfo) const
Const pointer to all entries (including extra space) in the given row.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes the distribution of rows over processes.
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.
bool isLocallyIndexed() const
Whether the matrix is locally indexed on the calling process.
void doImport(const SrcDistObject &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM)
Import data into this object using an Import object ("forward mode").
local_matrix_type lclMatrix_
The local sparse matrix.
void fillLocalGraphAndMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local graph and matrix.
GlobalOrdinal getIndexBase() const
The index base for global indices for this matrix.