42 #ifndef TPETRA_CRSMATRIX_DEF_HPP
43 #define TPETRA_CRSMATRIX_DEF_HPP
53 #include "Tpetra_RowMatrix.hpp"
62 #include "Tpetra_Details_gathervPrint.hpp"
63 #include "Tpetra_Details_getDiagCopyWithoutOffsets.hpp"
64 #include "Tpetra_Details_leftScaleLocalCrsMatrix.hpp"
66 #include "Tpetra_Details_rightScaleLocalCrsMatrix.hpp"
67 #include "KokkosSparse_getDiagCopy.hpp"
68 #include "Tpetra_Details_copyConvert.hpp"
71 #include "Tpetra_Details_packCrsMatrix.hpp"
72 #include "Tpetra_Details_unpackCrsMatrixAndCombine.hpp"
73 #include "Teuchos_FancyOStream.hpp"
74 #include "Teuchos_RCP.hpp"
75 #include "Teuchos_SerialDenseMatrix.hpp"
82 using Teuchos::rcpFromRef;
88 template<
class T,
class BinaryFunction>
89 T atomic_binary_function_update (
volatile T*
const dest,
103 T newVal = f (assume, inputVal);
104 oldVal = Kokkos::atomic_compare_exchange (dest, assume, newVal);
105 }
while (assume != oldVal);
125 template<
class Scalar>
129 typedef Teuchos::ScalarTraits<Scalar> STS;
130 return std::max (STS::magnitude (x), STS::magnitude (y));
139 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
140 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
141 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
142 size_t maxNumEntriesPerRow,
144 const Teuchos::RCP<Teuchos::ParameterList>& params) :
146 storageStatus_ (pftype == StaticProfile ?
147 ::Tpetra::Details::STORAGE_1D_UNPACKED :
148 ::Tpetra::Details::STORAGE_2D),
149 fillComplete_ (false),
150 frobNorm_ (-STM::one ())
152 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, size_t, "
153 "ProfileType[, RCP<ParameterList>]): ";
154 Teuchos::RCP<crs_graph_type> graph;
156 graph = Teuchos::rcp (
new crs_graph_type (rowMap, maxNumEntriesPerRow,
159 catch (std::exception& e) {
160 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
161 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
162 "size_t, ProfileType[, RCP<ParameterList>]) threw an exception: "
169 staticGraph_ = myGraph_;
174 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
177 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
179 const Teuchos::RCP<Teuchos::ParameterList>& params) :
181 storageStatus_ (pftype == StaticProfile ?
182 ::Tpetra::Details::STORAGE_1D_UNPACKED :
183 ::Tpetra::Details::STORAGE_2D),
184 fillComplete_ (false),
185 frobNorm_ (-STM::one ())
187 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
188 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
189 Teuchos::RCP<crs_graph_type> graph;
191 graph = Teuchos::rcp (
new crs_graph_type (rowMap, numEntPerRowToAlloc,
194 catch (std::exception &e) {
195 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
196 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
197 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]) threw "
198 "an exception: " << e.what ());
204 staticGraph_ = graph;
209 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
210 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
212 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
213 const Teuchos::ArrayRCP<const size_t>& numEntPerRowToAlloc,
215 const Teuchos::RCP<Teuchos::ParameterList>& params) :
216 dist_object_type (rowMap),
217 storageStatus_ (pftype == StaticProfile ?
218 ::Tpetra::Details::STORAGE_1D_UNPACKED :
219 ::Tpetra::Details::STORAGE_2D),
220 fillComplete_ (false),
221 frobNorm_ (-STM::one ())
223 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
224 "ArrayRCP<const size_t>, ProfileType[, RCP<ParameterList>]): ";
225 Teuchos::RCP<crs_graph_type> graph;
227 graph = Teuchos::rcp (
new crs_graph_type (rowMap, numEntPerRowToAlloc (),
230 catch (std::exception &e) {
231 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
232 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
233 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]) threw "
234 "an exception: " << e.what ());
240 staticGraph_ = graph;
244 #endif // TPETRA_ENABLE_DEPRECATED_CODE
246 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
247 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
248 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
249 const Teuchos::RCP<const map_type>& colMap,
250 const size_t maxNumEntPerRow,
252 const Teuchos::RCP<Teuchos::ParameterList>& params) :
254 storageStatus_ (pftype == StaticProfile ?
255 ::Tpetra::Details::STORAGE_1D_UNPACKED :
256 ::Tpetra::Details::STORAGE_2D),
257 fillComplete_ (false),
258 frobNorm_ (-STM::one ())
260 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, RCP<const Map>, "
261 "size_t, ProfileType[, RCP<ParameterList>]): ";
263 #ifdef HAVE_TPETRA_DEBUG
265 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
266 (! staticGraph_.is_null (), std::logic_error,
267 "staticGraph_ is not null at the beginning of the constructor. "
268 "Please report this bug to the Tpetra developers.");
269 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
270 (! myGraph_.is_null (), std::logic_error,
271 "myGraph_ is not null at the beginning of the constructor. "
272 "Please report this bug to the Tpetra developers.");
273 #endif // HAVE_TPETRA_DEBUG
275 Teuchos::RCP<crs_graph_type> graph;
281 catch (std::exception &e) {
282 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
283 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
284 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]) threw an "
285 "exception: " << e.what ());
291 staticGraph_ = myGraph_;
296 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
299 const Teuchos::RCP<const map_type>& colMap,
300 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
302 const Teuchos::RCP<Teuchos::ParameterList>& params) :
304 storageStatus_ (pftype == StaticProfile ?
305 ::Tpetra::Details::STORAGE_1D_UNPACKED :
306 ::Tpetra::Details::STORAGE_2D),
307 fillComplete_ (false),
308 frobNorm_ (-STM::one ())
310 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, RCP<const Map>, "
311 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
312 Teuchos::RCP<crs_graph_type> graph;
318 catch (std::exception &e) {
319 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
320 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
321 "RCP<const Map>, ArrayView<const size_t>, ProfileType[, "
322 "RCP<ParameterList>]) threw an exception: " << e.what ());
328 staticGraph_ = graph;
333 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
334 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
336 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
337 const Teuchos::RCP<const map_type>& colMap,
338 const Teuchos::ArrayRCP<const size_t>& numEntPerRowToAlloc,
340 const Teuchos::RCP<Teuchos::ParameterList>& params) :
341 dist_object_type (rowMap),
342 storageStatus_ (pftype == StaticProfile ?
343 ::Tpetra::Details::STORAGE_1D_UNPACKED :
344 ::Tpetra::Details::STORAGE_2D),
345 fillComplete_ (false),
346 frobNorm_ (-STM::one ())
348 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, RCP<const Map>, "
349 "ArrayRCP<const size_t>, ProfileType[, RCP<ParameterList>]): ";
350 Teuchos::RCP<crs_graph_type> graph;
353 numEntPerRowToAlloc (),
356 catch (std::exception &e) {
357 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
358 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
359 "RCP<const Map>, ArrayView<const size_t>, ProfileType[, "
360 "RCP<ParameterList>]) threw an exception: " << e.what ());
366 staticGraph_ = graph;
370 #endif // TPETRA_ENABLE_DEPRECATED_CODE
372 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
373 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
374 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
375 const Teuchos::RCP<Teuchos::ParameterList>& ) :
377 staticGraph_ (graph),
378 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
379 fillComplete_ (false),
380 frobNorm_ (-STM::one ())
382 typedef typename local_matrix_type::values_type values_type;
383 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>[, "
384 "RCP<ParameterList>]): ";
385 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
386 (graph.is_null (), std::runtime_error,
"Input graph is null.");
387 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
388 (! graph->isFillComplete (), std::runtime_error,
"Input graph is not "
389 "fill complete. You must call fillComplete on the graph before using "
390 "it to construct a CrsMatrix. Note that calling resumeFill on the "
391 "graph makes it not fill complete, even if you had previously called "
392 "fillComplete. In that case, you must call fillComplete on the graph "
401 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
402 auto lclGraph = graph->getLocalGraph ();
403 const size_t numEnt = lclGraph.entries.extent (0);
404 values_type val (
"Tpetra::CrsMatrix::val", numEnt);
407 numCols, val, lclGraph);
416 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
418 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
419 const typename local_matrix_type::values_type& values,
420 const Teuchos::RCP<Teuchos::ParameterList>& ) :
422 staticGraph_ (graph),
423 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
424 fillComplete_ (false),
425 frobNorm_ (-STM::one ())
427 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>,local_matrix_type::values_type,[, "
428 "RCP<ParameterList>]): ";
429 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
430 (graph.is_null (), std::runtime_error,
"Input graph is null.");
431 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
432 (! graph->isFillComplete (), std::runtime_error,
"Input graph is not "
433 "fill complete. You must call fillComplete on the graph before using "
434 "it to construct a CrsMatrix. Note that calling resumeFill on the "
435 "graph makes it not fill complete, even if you had previously called "
436 "fillComplete. In that case, you must call fillComplete on the graph "
445 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
446 auto lclGraph = graph->getLocalGraph ();
448 numCols, values, lclGraph);
459 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
462 const Teuchos::RCP<const map_type>& colMap,
463 const typename local_matrix_type::row_map_type& rowPointers,
464 const typename local_graph_type::entries_type::non_const_type& columnIndices,
465 const typename local_matrix_type::values_type& values,
466 const Teuchos::RCP<Teuchos::ParameterList>& params) :
468 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
469 fillComplete_ (false),
470 frobNorm_ (-STM::one ())
473 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
474 "RCP<const Map>, ptr, ind, val[, params]): ";
475 const char suffix[] =
". Please report this bug to the Tpetra developers.";
481 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
482 (values.extent (0) != columnIndices.extent (0),
483 std::invalid_argument,
"Input arrays don't have matching dimensions. "
484 "values.extent(0) = " << values.extent (0) <<
" != "
485 "columnIndices.extent(0) = " << columnIndices.extent (0) <<
".");
486 #ifdef HAVE_TPETRA_DEBUG
487 if (rowPointers.extent (0) != 0) {
488 const size_t numEnt =
489 ::Tpetra::Details::getEntryOnHost (rowPointers, rowPointers.extent (0) - 1);
490 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
491 (numEnt != static_cast<size_t> (columnIndices.extent (0)) ||
492 numEnt != static_cast<size_t> (values.extent (0)),
493 std::invalid_argument,
"Last entry of rowPointers says that the matrix"
494 " has " << numEnt <<
" entr" << (numEnt != 1 ?
"ies" :
"y") <<
", but "
495 "the dimensions of columnIndices and values don't match this. "
496 "columnIndices.extent(0) = " << columnIndices.extent (0) <<
497 " and values.extent(0) = " << values.extent (0) <<
".");
499 #endif // HAVE_TPETRA_DEBUG
501 RCP<crs_graph_type> graph;
503 graph = Teuchos::rcp (
new crs_graph_type (rowMap, colMap, rowPointers,
504 columnIndices, params));
506 catch (std::exception& e) {
507 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
508 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
509 "RCP<const Map>, ptr, ind[, params]) threw an exception: "
517 auto lclGraph = graph->getLocalGraph ();
518 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
519 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
520 lclGraph.entries.extent (0) != columnIndices.extent (0),
521 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, "
522 "ind[, params]) did not set the local graph correctly." << suffix);
523 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
524 (lclGraph.entries.extent (0) != values.extent (0),
525 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, ind[, "
526 "params]) did not set the local graph correctly. "
527 "lclGraph.entries.extent(0) = " << lclGraph.entries.extent (0)
528 <<
" != values.extent(0) = " << values.extent (0) << suffix);
534 staticGraph_ = graph;
543 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
545 numCols, values, lclGraph);
546 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
547 (
lclMatrix_.values.extent (0) != values.extent (0),
548 std::logic_error,
"Local matrix's constructor did not set the values "
549 "correctly. lclMatrix_.values.extent(0) = " <<
550 lclMatrix_.values.extent (0) <<
" != values.extent(0) = " <<
551 values.extent (0) << suffix);
561 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
564 const Teuchos::RCP<const map_type>& colMap,
565 const Teuchos::ArrayRCP<size_t>& ptr,
566 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
567 const Teuchos::ArrayRCP<Scalar>& val,
568 const Teuchos::RCP<Teuchos::ParameterList>& params) :
570 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
571 fillComplete_ (false),
572 frobNorm_ (-STM::one ())
574 using Kokkos::Compat::getKokkosViewDeepCopy;
575 using Teuchos::av_reinterpret_cast;
577 typedef typename local_matrix_type::values_type values_type;
579 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
580 "RCP<const Map>, ptr, ind, val[, params]): ";
582 RCP<crs_graph_type> graph;
587 catch (std::exception& e) {
588 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
589 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
590 "RCP<const Map>, ArrayRCP<size_t>, ArrayRCP<LocalOrdinal>[, "
591 "RCP<ParameterList>]) threw an exception: " << e.what ());
597 staticGraph_ = graph;
610 auto lclGraph = staticGraph_->getLocalGraph ();
611 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
612 (static_cast<size_t> (lclGraph.row_map.extent (0)) != static_cast<size_t> (ptr.size ()) ||
613 static_cast<size_t> (lclGraph.entries.extent (0)) != static_cast<size_t> (ind.size ()),
614 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, "
615 "ind[, params]) did not set the local graph correctly. Please "
616 "report this bug to the Tpetra developers.");
618 const size_t numCols = staticGraph_->getColMap ()->getNodeNumElements ();
619 values_type valIn = getKokkosViewDeepCopy<device_type> (av_reinterpret_cast<IST> (val ()));
621 numCols, valIn, lclGraph);
630 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
633 const Teuchos::RCP<const map_type>& colMap,
635 const Teuchos::RCP<Teuchos::ParameterList>& params) :
637 lclMatrix_ (lclMatrix),
638 k_values1D_ (lclMatrix.values),
639 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
640 fillComplete_ (true),
641 frobNorm_ (-STM::one ())
643 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
644 "RCP<const Map>, local_matrix_type[, RCP<ParameterList>]): ";
645 Teuchos::RCP<crs_graph_type> graph;
648 lclMatrix.graph, params));
650 catch (std::exception& e) {
651 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
652 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
653 "RCP<const Map>, local_graph_type[, RCP<ParameterList>]) threw an "
654 "exception: " << e.what ());
656 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
657 (!graph->isFillComplete (), std::logic_error,
"CrsGraph constructor (RCP"
658 "<const Map>, RCP<const Map>, local_graph_type[, RCP<ParameterList>]) "
659 "did not produce a fill-complete graph. Please report this bug to the "
660 "Tpetra developers.");
665 staticGraph_ = graph;
667 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
668 params->get (
"compute global constants",
true);
669 if (callComputeGlobalConstants) {
674 #ifdef HAVE_TPETRA_DEBUG
675 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive (), std::logic_error,
676 "We're at the end of fillComplete(), but isFillActive() is true. "
677 "Please report this bug to the Tpetra developers.");
678 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete (), std::logic_error,
679 "We're at the end of fillComplete(), but isFillComplete() is false. "
680 "Please report this bug to the Tpetra developers.");
681 #endif // HAVE_TPETRA_DEBUG
685 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
688 const Teuchos::RCP<const map_type>& rowMap,
689 const Teuchos::RCP<const map_type>& colMap,
690 const Teuchos::RCP<const map_type>& domainMap,
691 const Teuchos::RCP<const map_type>& rangeMap,
692 const Teuchos::RCP<Teuchos::ParameterList>& params) :
694 lclMatrix_ (lclMatrix),
695 k_values1D_ (lclMatrix.values),
696 storageStatus_ (::Tpetra::Details::STORAGE_1D_PACKED),
697 fillComplete_ (true),
698 frobNorm_ (-STM::one ())
700 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
701 "RCP<const Map>, RCP<const Map>, RCP<const Map>, local_matrix_type[, "
702 "RCP<ParameterList>]): ";
703 Teuchos::RCP<crs_graph_type> graph;
705 graph = Teuchos::rcp (
new crs_graph_type (lclMatrix.graph, rowMap, colMap,
706 domainMap, rangeMap, params));
708 catch (std::exception& e) {
709 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
710 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
711 "RCP<const Map>, RCP<const Map>, RCP<const Map>, local_graph_type[, "
712 "RCP<ParameterList>]) threw an exception: " << e.what ());
714 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
715 (!graph->isFillComplete (), std::logic_error,
"CrsGraph constructor (RCP"
716 "<const Map>, RCP<const Map>, RCP<const Map>, RCP<const Map>, local_graph_type[, "
717 "RCP<ParameterList>]) did not produce a fill-complete graph. Please report this "
718 "bug to the Tpetra developers.");
723 staticGraph_ = graph;
725 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
726 params->get (
"compute global constants",
true);
727 if (callComputeGlobalConstants) {
732 #ifdef HAVE_TPETRA_DEBUG
733 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
isFillActive (), std::logic_error,
734 "We're at the end of fillComplete(), but isFillActive() is true. "
735 "Please report this bug to the Tpetra developers.");
736 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!
isFillComplete (), std::logic_error,
737 "We're at the end of fillComplete(), but isFillComplete() is false. "
738 "Please report this bug to the Tpetra developers.");
739 #endif // HAVE_TPETRA_DEBUG
744 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
746 const Teuchos::DataAccess copyOrView)
747 :
CrsMatrix(source.getCrsGraph(),source.getLocalValuesView())
749 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const CrsMatrix>&, const Teuchos::DataAccess): ";
750 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!source.
isFillComplete(),std::invalid_argument,
"Source graph must be fillComplete().");
752 if (copyOrView == Teuchos::Copy) {
754 typename local_matrix_type::values_type newvals;
755 Kokkos::resize(newvals,vals.extent(0));
757 k_values1D_ = newvals;
762 else if (copyOrView == Teuchos::View) {
766 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
767 true, std::invalid_argument,
"Second argument 'copyOrView' has an "
768 "invalid value " << copyOrView <<
". Valid values include "
769 "Teuchos::Copy = " << Teuchos::Copy <<
" and Teuchos::View = "
770 << Teuchos::View <<
".");
776 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
781 std::swap(crs_matrix.
importMV_, this->importMV_);
782 std::swap(crs_matrix.
exportMV_, this->exportMV_);
783 std::swap(crs_matrix.staticGraph_, this->staticGraph_);
784 std::swap(crs_matrix.myGraph_, this->myGraph_);
785 std::swap(crs_matrix.
lclMatrix_, this->lclMatrix_);
786 std::swap(crs_matrix.k_values1D_, this->k_values1D_);
787 std::swap(crs_matrix.values2D_, this->values2D_);
790 std::swap(crs_matrix.
nonlocals_, this->nonlocals_);
791 std::swap(crs_matrix.
frobNorm_, this->frobNorm_);
795 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
796 Teuchos::RCP<const Teuchos::Comm<int> >
799 return getCrsGraphRef ().getComm ();
802 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
803 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
808 return getCrsGraphRef ().getNode ();
810 #endif // TPETRA_ENABLE_DEPRECATED_CODE
812 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
816 return this->getCrsGraphRef ().getProfileType ();
819 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
823 return fillComplete_;
826 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
830 return ! fillComplete_;
833 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
837 return this->getCrsGraphRef ().isStorageOptimized ();
840 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
844 return getCrsGraphRef ().isLocallyIndexed ();
847 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
851 return getCrsGraphRef ().isGloballyIndexed ();
854 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
858 return getCrsGraphRef ().hasColMap ();
861 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
865 return getCrsGraphRef ().getGlobalNumEntries ();
868 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
872 return getCrsGraphRef ().getNodeNumEntries ();
875 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
879 return getCrsGraphRef ().getGlobalNumRows ();
882 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
886 return getCrsGraphRef ().getGlobalNumCols ();
889 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
893 return getCrsGraphRef ().getNodeNumRows ();
896 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
900 return getCrsGraphRef ().getNodeNumCols ();
903 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
904 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
908 return this->getGlobalNumDiagsImpl ();
911 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
912 size_t TPETRA_DEPRECATED
913 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
914 getNodeNumDiags ()
const {
915 return this->getNodeNumDiagsImpl ();
918 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
920 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
921 getGlobalNumDiagsImpl ()
const {
922 const crs_graph_type& G = this->getCrsGraphRef ();
923 using HDM = ::Tpetra::Details::HasDeprecatedMethods2630_WarningThisClassIsNotForUsers;
924 return dynamic_cast<const HDM&
> (G).getGlobalNumDiagsImpl ();
927 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
929 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
930 getNodeNumDiagsImpl ()
const {
931 const crs_graph_type& G = this->getCrsGraphRef ();
932 using HDM = ::Tpetra::Details::HasDeprecatedMethods2630_WarningThisClassIsNotForUsers;
933 return dynamic_cast<const HDM&
> (G).getNodeNumDiagsImpl ();
935 #endif // TPETRA_ENABLE_DEPRECATED_CODE
937 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
941 return getCrsGraphRef ().getNumEntriesInGlobalRow (globalRow);
944 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
948 return getCrsGraphRef ().getNumEntriesInLocalRow (localRow);
951 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
955 return getCrsGraphRef ().getGlobalMaxNumRowEntries ();
958 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
962 return getCrsGraphRef ().getNodeMaxNumRowEntries ();
965 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
969 return getRowMap ()->getIndexBase ();
972 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
973 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
976 return getCrsGraphRef ().getRowMap ();
979 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
980 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
983 return getCrsGraphRef ().getColMap ();
986 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
987 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
990 return getCrsGraphRef ().getDomainMap ();
993 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
994 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
997 return getCrsGraphRef ().getRangeMap ();
1000 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1001 Teuchos::RCP<const RowGraph<LocalOrdinal, GlobalOrdinal, Node> >
1004 if (staticGraph_ != Teuchos::null) {
1005 return staticGraph_;
1010 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1011 Teuchos::RCP<const CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
1014 if (staticGraph_ != Teuchos::null) {
1015 return staticGraph_;
1020 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1024 if (! this->staticGraph_.is_null ()) {
1025 return * (this->staticGraph_);
1028 #ifdef HAVE_TPETRA_DEBUG
1029 const char tfecfFuncName[] =
"getCrsGraphRef: ";
1030 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1031 (this->myGraph_.is_null (), std::logic_error,
1032 "Both staticGraph_ and myGraph_ are null. "
1033 "Please report this bug to the Tpetra developers.");
1034 #endif // HAVE_TPETRA_DEBUG
1035 return * (this->myGraph_);
1039 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
1040 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1041 bool TPETRA_DEPRECATED
1042 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1043 isLowerTriangular ()
const {
1044 return this->isLowerTriangularImpl ();
1047 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1048 bool TPETRA_DEPRECATED
1049 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1050 isUpperTriangular ()
const {
1051 return this->isUpperTriangularImpl ();
1054 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1056 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1057 isLowerTriangularImpl ()
const {
1058 const crs_graph_type& G = this->getCrsGraphRef ();
1059 using HDM = ::Tpetra::Details::HasDeprecatedMethods2630_WarningThisClassIsNotForUsers;
1060 return dynamic_cast<const HDM&
> (G).isLowerTriangularImpl ();
1063 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1065 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1066 isUpperTriangularImpl ()
const {
1067 const crs_graph_type& G = this->getCrsGraphRef ();
1068 using HDM = ::Tpetra::Details::HasDeprecatedMethods2630_WarningThisClassIsNotForUsers;
1069 return dynamic_cast<const HDM&
> (G).isUpperTriangularImpl ();
1071 #endif // TPETRA_ENABLE_DEPRECATED_CODE
1073 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1077 return myGraph_.is_null ();
1080 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1087 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1094 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1095 Teuchos::ArrayRCP<Teuchos::Array<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type> >
1099 using Teuchos::arcp;
1100 using Teuchos::Array;
1101 using Teuchos::ArrayRCP;
1102 typedef impl_scalar_type IST;
1103 typedef LocalOrdinal LO;
1104 const char tfecfFuncName[] =
"allocateValues2D: ";
1106 const crs_graph_type& graph = this->getCrsGraphRef ();
1107 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1108 (! graph.indicesAreAllocated (), std::runtime_error,
1109 "Graph indices must be allocated before values.");
1110 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1111 (graph.getProfileType () == StaticProfile, std::runtime_error,
1112 "Graph indices must be allocated in a dynamic profile.");
1114 const LO lclNumRows = graph.getNodeNumRows ();
1115 Teuchos::ArrayRCP<Teuchos::Array<IST> > values2D (lclNumRows);
1116 if (! graph.lclInds2D_.is_null ()) {
1117 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1118 values2D[lclRow].resize (graph.lclInds2D_[lclRow].size ());
1121 else if (! graph.gblInds2D_.is_null ()) {
1122 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1123 values2D[lclRow].resize (graph.gblInds2D_[lclRow].size ());
1129 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1134 using ::Tpetra::Details::ProfilingRegion;
1135 const char tfecfFuncName[] =
"allocateValues: ";
1136 ProfilingRegion regionAllocateValues (
"Tpetra::CrsMatrix::allocateValues");
1138 #ifdef HAVE_TPETRA_DEBUG
1139 const char suffix[] =
" Please report this bug to the Tpetra developers.";
1141 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1142 (this->staticGraph_.is_null (), std::logic_error,
1143 "staticGraph_ is null." << suffix);
1148 if ((gas == GraphAlreadyAllocated) != this->staticGraph_->indicesAreAllocated ()) {
1149 const char err1[] =
"The caller has asserted that the graph is ";
1150 const char err2[] =
"already allocated, but the static graph says "
1151 "that its indices are ";
1152 const char err3[] =
"already allocated. Please report this bug to "
1153 "the Tpetra developers.";
1154 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1155 (gas == GraphAlreadyAllocated && ! this->staticGraph_->indicesAreAllocated (),
1156 std::logic_error, err1 << err2 <<
"not " << err3);
1157 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1158 (gas != GraphAlreadyAllocated && this->staticGraph_->indicesAreAllocated (),
1159 std::logic_error, err1 <<
"not " << err2 << err3);
1167 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1168 (! this->staticGraph_->indicesAreAllocated () &&
1169 this->myGraph_.is_null (), std::logic_error,
1170 "The static graph says that its indices are not allocated, "
1171 "but the graph is not owned by the matrix." << suffix);
1172 #endif // HAVE_TPETRA_DEBUG
1174 if (gas == GraphNotYetAllocated) {
1175 #ifdef HAVE_TPETRA_DEBUG
1176 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1177 (this->myGraph_.is_null (), std::logic_error,
1178 "gas = GraphNotYetAllocated, but myGraph_ is null." << suffix);
1179 #endif // HAVE_TPETRA_DEBUG
1181 this->myGraph_->allocateIndices (lg);
1183 catch (std::exception& e) {
1184 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1185 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1186 "threw an exception: " << e.what ());
1189 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1190 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1191 "threw an exception not a subclass of std::exception.");
1196 if (this->getProfileType () == StaticProfile) {
1203 #ifdef HAVE_TPETRA_DEBUG
1204 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1205 (this->staticGraph_.is_null (), std::logic_error,
1206 "this->getProfileType() == StaticProfile, but staticGraph_ is null."
1208 #endif // HAVE_TPETRA_DEBUG
1210 const size_t lclNumRows = this->staticGraph_->getNodeNumRows ();
1211 typename Graph::local_graph_type::row_map_type k_ptrs =
1212 this->staticGraph_->k_rowPtrs_;
1213 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1214 (k_ptrs.extent (0) != lclNumRows+1, std::logic_error,
1215 "With StaticProfile, row offsets array has length "
1216 << k_ptrs.extent (0) <<
" != (lclNumRows+1) = "
1217 << (lclNumRows+1) <<
".");
1219 const size_t lclTotalNumEntries =
1220 ::Tpetra::Details::getEntryOnHost (k_ptrs, lclNumRows);
1223 typedef typename local_matrix_type::values_type values_type;
1225 values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1233 this->values2D_ = this->allocateValues2D ();
1237 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1240 getAllValues (Teuchos::ArrayRCP<const size_t>& rowPointers,
1241 Teuchos::ArrayRCP<const LocalOrdinal>& columnIndices,
1242 Teuchos::ArrayRCP<const Scalar>& values)
const
1245 const char tfecfFuncName[] =
"getAllValues: ";
1246 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1247 columnIndices.size () != values.size (), std::runtime_error,
1248 "Requires that columnIndices and values are the same size.");
1250 RCP<const crs_graph_type> relevantGraph = getCrsGraph ();
1251 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1252 relevantGraph.is_null (), std::runtime_error,
1253 "Requires that getCrsGraph() is not null.");
1255 rowPointers = relevantGraph->getNodeRowPtrs ();
1257 catch (std::exception &e) {
1258 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1259 true, std::runtime_error,
1260 "Caught exception while calling graph->getNodeRowPtrs(): "
1264 columnIndices = relevantGraph->getNodePackedIndices ();
1266 catch (std::exception &e) {
1267 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1268 true, std::runtime_error,
1269 "Caught exception while calling graph->getNodePackedIndices(): "
1272 Teuchos::ArrayRCP<const impl_scalar_type> vals =
1273 Kokkos::Compat::persistingView (k_values1D_);
1274 values = Teuchos::arcp_reinterpret_cast<
const Scalar> (vals);
1277 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1283 using ::Tpetra::Details::ProfilingRegion;
1284 using Kokkos::create_mirror_view;
1285 using Teuchos::arcp_const_cast;
1286 using Teuchos::Array;
1287 using Teuchos::ArrayRCP;
1288 using Teuchos::null;
1291 typedef typename local_matrix_type::row_map_type row_map_type;
1292 typedef typename Graph::local_graph_type::entries_type::non_const_type lclinds_1d_type;
1293 typedef typename local_matrix_type::values_type values_type;
1294 ProfilingRegion regionFLGAM (
"Tpetra::CrsGraph::fillLocalGraphAndMatrix");
1296 #ifdef HAVE_TPETRA_DEBUG
1297 const char tfecfFuncName[] =
"fillLocalGraphAndMatrix (called from "
1298 "fillComplete or expertStaticFillComplete): ";
1299 #endif // HAVE_TPETRA_DEBUG
1301 #ifdef HAVE_TPETRA_DEBUG
1304 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1305 (myGraph_.is_null (), std::logic_error,
"The nonconst graph (myGraph_) "
1306 "is null. This means that the matrix has a const (a.k.a. \"static\") "
1307 "graph. fillComplete or expertStaticFillComplete should never call "
1308 "fillLocalGraphAndMatrix in that case. "
1309 "Please report this bug to the Tpetra developers.");
1310 #endif // HAVE_TPETRA_DEBUG
1312 const size_t lclNumRows = this->getNodeNumRows ();
1320 typename row_map_type::non_const_type k_ptrs;
1321 row_map_type k_ptrs_const;
1322 lclinds_1d_type k_inds;
1328 lclinds_1d_type k_lclInds1D_ = myGraph_->k_lclInds1D_;
1330 typedef decltype (myGraph_->k_numRowEntries_) row_entries_type;
1332 if (getProfileType () != StaticProfile) {
1351 typename row_entries_type::const_type numRowEnt_h =
1352 myGraph_->k_numRowEntries_;
1353 #ifdef HAVE_TPETRA_DEBUG
1354 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1355 (static_cast<size_t> (numRowEnt_h.extent (0)) != lclNumRows,
1356 std::logic_error,
"(DynamicProfile branch) numRowEnt_h has the "
1357 "wrong length. numRowEnt_h.extent(0) = "
1358 << numRowEnt_h.extent (0) <<
" != getNodeNumRows() = "
1359 << lclNumRows <<
".");
1360 #endif // HAVE_TPETRA_DEBUG
1365 k_ptrs =
typename row_map_type::non_const_type (
"Tpetra::CrsGraph::ptr",
1367 typename row_map_type::non_const_type::HostMirror h_ptrs =
1368 create_mirror_view (k_ptrs);
1376 const size_t lclTotalNumEntries =
1378 #ifdef HAVE_TPETRA_DEBUG
1379 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1380 (static_cast<size_t> (h_ptrs.extent (0)) != lclNumRows + 1,
1381 std::logic_error,
"(DynamicProfile branch) After packing h_ptrs, "
1382 "h_ptrs.extent(0) = " << h_ptrs.extent (0) <<
" != "
1383 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1385 const size_t h_ptrs_lastEnt = h_ptrs(lclNumRows);
1386 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1387 (h_ptrs_lastEnt != lclTotalNumEntries, std::logic_error,
1388 "(DynamicProfile branch) After packing h_ptrs, h_ptrs(lclNumRows="
1389 << lclNumRows <<
") = " << h_ptrs_lastEnt <<
" != total number "
1390 "of entries on the calling process = " << lclTotalNumEntries <<
".");
1392 #endif // HAVE_TPETRA_DEBUG
1395 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1396 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1399 typename lclinds_1d_type::HostMirror h_inds = create_mirror_view (k_inds);
1400 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
1403 ArrayRCP<Array<LocalOrdinal> > lclInds2D = myGraph_->lclInds2D_;
1404 for (
size_t row = 0; row < lclNumRows; ++row) {
1405 const size_t numEnt = numRowEnt_h(row);
1406 std::copy (lclInds2D[row].begin(),
1407 lclInds2D[row].begin() + numEnt,
1408 h_inds.data() + h_ptrs(row));
1409 std::copy (values2D_[row].begin(),
1410 values2D_[row].begin() + numEnt,
1411 h_vals.data() + h_ptrs(row));
1420 k_ptrs_const = k_ptrs;
1422 #ifdef HAVE_TPETRA_DEBUG
1424 if (k_ptrs.extent (0) != 0) {
1425 const size_t numOffsets =
static_cast<size_t> (k_ptrs.extent (0));
1426 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1427 (numOffsets != lclNumRows + 1, std::logic_error,
"(DynamicProfile "
1428 "branch) After copying into k_ptrs, k_ptrs.extent(0) = " <<
1429 numOffsets <<
" != (lclNumRows+1) = " << (lclNumRows+1) <<
".");
1431 const auto valToCheck = ::Tpetra::Details::getEntryOnHost (k_ptrs, numOffsets-1);
1432 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1433 (static_cast<size_t> (valToCheck) != k_vals.extent (0),
1434 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs("
1435 << (numOffsets-1) <<
") = " << valToCheck <<
" != "
1436 "k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1437 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1438 (static_cast<size_t> (valToCheck) != k_inds.extent (0),
1439 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs("
1440 << (numOffsets-1) <<
") = " << valToCheck <<
" != "
1441 "k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1443 #endif // HAVE_TPETRA_DEBUG
1445 else if (getProfileType () == StaticProfile) {
1452 typename Graph::local_graph_type::row_map_type curRowOffsets =
1453 myGraph_->k_rowPtrs_;
1455 #ifdef HAVE_TPETRA_DEBUG
1456 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1457 (curRowOffsets.extent (0) == 0, std::logic_error,
1458 "(StaticProfile branch) curRowOffsets.extent(0) == 0.");
1459 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1460 (curRowOffsets.extent (0) != lclNumRows + 1, std::logic_error,
1461 "(StaticProfile branch) curRowOffsets.extent(0) = "
1462 << curRowOffsets.extent (0) <<
" != lclNumRows + 1 = "
1463 << (lclNumRows + 1) <<
".")
1465 const size_t numOffsets = curRowOffsets.extent (0);
1466 const auto valToCheck =
1467 ::Tpetra::Details::getEntryOnHost (curRowOffsets, numOffsets - 1);
1468 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1470 myGraph_->k_lclInds1D_.extent (0) != valToCheck,
1471 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
1472 numOffsets <<
" != 0 and myGraph_->k_lclInds1D_.extent(0) = "
1473 << myGraph_->k_lclInds1D_.extent (0) <<
" != curRowOffsets("
1474 << numOffsets <<
") = " << valToCheck <<
".");
1476 #endif // HAVE_TPETRA_DEBUG
1478 if (myGraph_->getNodeNumEntries () != myGraph_->getNodeAllocationSize ()) {
1485 #ifdef HAVE_TPETRA_DEBUG
1486 if (curRowOffsets.extent (0) != 0) {
1487 const size_t numOffsets =
1488 static_cast<size_t> (curRowOffsets.extent (0));
1489 const auto valToCheck =
1490 ::Tpetra::Details::getEntryOnHost (curRowOffsets, numOffsets-1);
1491 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1492 (static_cast<size_t> (valToCheck) !=
1493 static_cast<size_t> (k_values1D_.extent (0)),
1494 std::logic_error,
"(StaticProfile unpacked branch) Before "
1495 "allocating or packing, curRowOffsets(" << (numOffsets-1) <<
") = "
1496 << valToCheck <<
" != k_values1D_.extent(0)"
1497 " = " << k_values1D_.extent (0) <<
".");
1498 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1499 (static_cast<size_t> (valToCheck) !=
1500 static_cast<size_t> (myGraph_->k_lclInds1D_.extent (0)),
1501 std::logic_error,
"(StaticProfile unpacked branch) Before "
1502 "allocating or packing, curRowOffsets(" << (numOffsets-1) <<
") = "
1504 <<
" != myGraph_->k_lclInds1D_.extent(0) = "
1505 << myGraph_->k_lclInds1D_.extent (0) <<
".");
1507 #endif // HAVE_TPETRA_DEBUG
1515 size_t lclTotalNumEntries = 0;
1517 typename row_map_type::non_const_type::HostMirror h_ptrs;
1522 typename row_map_type::non_const_type
1523 packedRowOffsets (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
1524 typename row_entries_type::const_type numRowEnt_h =
1525 myGraph_->k_numRowEntries_;
1528 lclTotalNumEntries =
1532 k_ptrs = packedRowOffsets;
1533 k_ptrs_const = k_ptrs;
1536 #ifdef HAVE_TPETRA_DEBUG
1537 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1538 (static_cast<size_t> (k_ptrs.extent (0)) != lclNumRows + 1,
1540 "(StaticProfile unpacked branch) After packing k_ptrs, "
1541 "k_ptrs.extent(0) = " << k_ptrs.extent (0) <<
" != "
1542 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
1544 const auto valToCheck = ::Tpetra::Details::getEntryOnHost (k_ptrs, lclNumRows);
1545 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1546 (valToCheck != lclTotalNumEntries, std::logic_error,
1547 "(StaticProfile unpacked branch) After filling k_ptrs, "
1548 "k_ptrs(lclNumRows=" << lclNumRows <<
") = " << valToCheck
1549 <<
" != total number of entries on the calling process = "
1550 << lclTotalNumEntries <<
".");
1552 #endif // HAVE_TPETRA_DEBUG
1555 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1556 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1568 typedef pack_functor<
typename Graph::local_graph_type::entries_type::non_const_type,
1569 typename Graph::local_graph_type::row_map_type>
1571 inds_packer_type indsPacker (k_inds, myGraph_->k_lclInds1D_,
1572 k_ptrs, curRowOffsets);
1574 typedef Kokkos::RangePolicy<exec_space, LocalOrdinal> range_type;
1575 Kokkos::parallel_for (range_type (0, lclNumRows), indsPacker);
1579 typedef pack_functor<values_type, row_map_type> vals_packer_type;
1580 vals_packer_type valsPacker (k_vals, this->k_values1D_,
1581 k_ptrs, curRowOffsets);
1582 Kokkos::parallel_for (range_type (0, lclNumRows), valsPacker);
1584 #ifdef HAVE_TPETRA_DEBUG
1585 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1586 (k_ptrs.extent (0) == 0, std::logic_error,
1587 "(StaticProfile \"Optimize Storage\" = "
1588 "true branch) After packing, k_ptrs.extent(0) = 0. This "
1589 "probably means that k_rowPtrs_ was never allocated.");
1590 if (k_ptrs.extent (0) != 0) {
1591 const size_t numOffsets =
static_cast<size_t> (k_ptrs.extent (0));
1592 const auto valToCheck = ::Tpetra::Details::getEntryOnHost (k_ptrs, numOffsets - 1);
1593 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1594 (static_cast<size_t> (valToCheck) != k_vals.extent (0),
1596 "(StaticProfile \"Optimize Storage\"=true branch) After packing, "
1597 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1598 " != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1599 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1600 (static_cast<size_t> (valToCheck) != k_inds.extent (0),
1602 "(StaticProfile \"Optimize Storage\"=true branch) After packing, "
1603 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1604 " != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1606 #endif // HAVE_TPETRA_DEBUG
1609 k_ptrs_const = myGraph_->k_rowPtrs_;
1610 k_inds = myGraph_->k_lclInds1D_;
1611 k_vals = this->k_values1D_;
1613 #ifdef HAVE_TPETRA_DEBUG
1614 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1615 (k_ptrs_const.extent (0) == 0, std::logic_error,
1616 "(StaticProfile \"Optimize Storage\"=false branch) "
1617 "k_ptrs_const.extent(0) = 0. This probably means that "
1618 "k_rowPtrs_ was never allocated.");
1619 if (k_ptrs_const.extent (0) != 0) {
1620 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.extent (0));
1621 const auto valToCheck = ::Tpetra::Details::getEntryOnHost (k_ptrs_const, numOffsets - 1);
1622 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1623 (static_cast<size_t> (valToCheck) != k_vals.extent (0),
1625 "(StaticProfile \"Optimize Storage\"=false branch) "
1626 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1627 <<
" != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1628 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1629 (static_cast<size_t> (valToCheck) != k_inds.extent (0),
1631 "(StaticProfile \"Optimize Storage\" = false branch) "
1632 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1633 <<
" != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1635 #endif // HAVE_TPETRA_DEBUG
1639 #ifdef HAVE_TPETRA_DEBUG
1641 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1642 (static_cast<size_t> (k_ptrs_const.extent (0)) != lclNumRows + 1,
1643 std::logic_error,
"After packing, k_ptrs_const.extent(0) = " <<
1644 k_ptrs_const.extent (0) <<
" != lclNumRows+1 = " << (lclNumRows+1)
1646 if (k_ptrs_const.extent (0) != 0) {
1647 const size_t numOffsets =
static_cast<size_t> (k_ptrs_const.extent (0));
1648 const size_t k_ptrs_const_numOffsetsMinus1 =
1649 ::Tpetra::Details::getEntryOnHost (k_ptrs_const, numOffsets - 1);
1650 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1651 (k_ptrs_const_numOffsetsMinus1 != k_vals.extent (0),
1652 std::logic_error,
"After packing, k_ptrs_const(" << (numOffsets-1) <<
1653 ") = " << k_ptrs_const_numOffsetsMinus1 <<
" != k_vals.extent(0)"
1654 " = " << k_vals.extent (0) <<
".");
1655 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1656 (k_ptrs_const_numOffsetsMinus1 != k_inds.extent (0),
1657 std::logic_error,
"After packing, k_ptrs_const(" << (numOffsets-1) <<
1658 ") = " << k_ptrs_const_numOffsetsMinus1 <<
" != k_inds.extent(0)"
1659 " = " << k_inds.extent (0) <<
".");
1661 #endif // HAVE_TPETRA_DEBUG
1667 const bool defaultOptStorage =
1668 ! isStaticGraph () || staticGraph_->isStorageOptimized ();
1669 const bool requestOptimizedStorage =
1670 (! params.is_null () && params->get (
"Optimize Storage", defaultOptStorage)) ||
1671 (params.is_null () && defaultOptStorage);
1678 if (requestOptimizedStorage) {
1684 myGraph_->lclInds2D_ = null;
1685 myGraph_->k_numRowEntries_ = row_entries_type ();
1688 this->values2D_ = null;
1691 myGraph_->k_rowPtrs_ = k_ptrs_const;
1692 myGraph_->k_lclInds1D_ = k_inds;
1693 this->k_values1D_ = k_vals;
1696 myGraph_->pftype_ = StaticProfile;
1697 myGraph_->storageStatus_ = ::Tpetra::Details::STORAGE_1D_PACKED;
1698 this->storageStatus_ = ::Tpetra::Details::STORAGE_1D_PACKED;
1709 myGraph_->lclGraph_ =
1714 getNodeNumCols (), k_vals,
1715 myGraph_->lclGraph_);
1718 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1723 using ::Tpetra::Details::ProfilingRegion;
1724 using Kokkos::create_mirror_view;
1725 using Teuchos::ArrayRCP;
1726 using Teuchos::Array;
1727 using Teuchos::null;
1730 typedef LocalOrdinal LO;
1731 typedef typename Graph::local_graph_type::row_map_type row_map_type;
1732 typedef typename row_map_type::non_const_type non_const_row_map_type;
1733 typedef typename local_matrix_type::values_type values_type;
1734 #ifdef HAVE_TPETRA_DEBUG
1735 const char tfecfFuncName[] =
"fillLocalMatrix (called from fillComplete): ";
1736 #endif // HAVE_TPETRA_DEBUG
1737 ProfilingRegion regionFLM (
"Tpetra::CrsMatrix::fillLocalMatrix");
1739 const size_t lclNumRows = getNodeNumRows();
1750 ArrayRCP<Array<LO> > lclInds2D = staticGraph_->lclInds2D_;
1751 size_t nodeNumEntries = staticGraph_->getNodeNumEntries ();
1752 size_t nodeNumAllocated = staticGraph_->getNodeAllocationSize ();
1753 row_map_type k_rowPtrs_ = staticGraph_->lclGraph_.row_map;
1755 row_map_type k_ptrs;
1761 bool requestOptimizedStorage =
true;
1762 const bool default_OptimizeStorage =
1763 ! isStaticGraph () || staticGraph_->isStorageOptimized ();
1764 if (! params.is_null () && ! params->get (
"Optimize Storage", default_OptimizeStorage)) {
1765 requestOptimizedStorage =
false;
1772 if (! staticGraph_->isStorageOptimized () && requestOptimizedStorage) {
1774 "You requested optimized storage by setting the"
1775 "\"Optimize Storage\" flag to \"true\" in the parameter list, or by virtue"
1776 "of default behavior. However, the associated CrsGraph was filled separately"
1777 "and requested not to optimize storage. Therefore, the CrsMatrix cannot"
1778 "optimize storage.");
1779 requestOptimizedStorage =
false;
1782 typedef decltype (staticGraph_->k_numRowEntries_) row_entries_type;
1784 if (getProfileType() != StaticProfile) {
1807 size_t lclTotalNumEntries = 0;
1809 typename non_const_row_map_type::HostMirror h_ptrs;
1811 typename row_entries_type::const_type numRowEnt_h =
1812 staticGraph_->k_numRowEntries_;
1814 non_const_row_map_type packedRowOffsets (
"Tpetra::CrsGraph::ptr",
1818 h_ptrs = create_mirror_view (packedRowOffsets);
1822 k_ptrs = packedRowOffsets;
1825 #ifdef HAVE_TPETRA_DEBUG
1826 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1827 (static_cast<size_t> (k_ptrs.extent (0)) != lclNumRows + 1,
1828 std::logic_error,
"In DynamicProfile branch, after packing k_ptrs, "
1829 "k_ptrs.extent(0) = " << k_ptrs.extent (0) <<
" != "
1830 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1831 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1832 (static_cast<size_t> (h_ptrs.extent (0)) != lclNumRows + 1,
1833 std::logic_error,
"In DynamicProfile branch, after packing h_ptrs, "
1834 "h_ptrs.extent(0) = " << h_ptrs.extent (0) <<
" != "
1835 "(lclNumRows+1) = " << (lclNumRows+1) <<
".");
1837 const auto valToCheck = ::Tpetra::Details::getEntryOnHost (k_ptrs, lclNumRows);
1838 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1839 (static_cast<size_t> (valToCheck) != lclTotalNumEntries,
1840 std::logic_error,
"(DynamicProfile branch) After packing k_ptrs, "
1841 "k_ptrs(lclNumRows = " << lclNumRows <<
") = " << valToCheck
1842 <<
" != total number of entries on the calling process = "
1843 << lclTotalNumEntries <<
".");
1845 #endif // HAVE_TPETRA_DEBUG
1848 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1850 typename values_type::HostMirror h_vals = create_mirror_view (k_vals);
1852 for (
size_t lclRow = 0; lclRow < lclNumRows; ++lclRow) {
1853 const size_t numEnt = numRowEnt_h(lclRow);
1854 std::copy (values2D_[lclRow].begin(),
1855 values2D_[lclRow].begin() + numEnt,
1856 h_vals.data() + h_ptrs(lclRow));
1861 #ifdef HAVE_TPETRA_DEBUG
1863 if (k_ptrs.extent (0) != 0) {
1864 const size_t numOffsets =
static_cast<size_t> (k_ptrs.extent (0));
1865 const auto valToCheck =
1866 ::Tpetra::Details::getEntryOnHost (k_ptrs, numOffsets - 1);
1867 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1868 (static_cast<size_t> (valToCheck) != k_vals.extent (0),
1869 std::logic_error,
"(DynamicProfile branch) After packing, k_ptrs("
1870 << (numOffsets-1) <<
") = " << valToCheck <<
" != "
1871 "k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1873 #endif // HAVE_TPETRA_DEBUG
1875 else if (getProfileType () == StaticProfile) {
1893 if (nodeNumEntries != nodeNumAllocated) {
1896 non_const_row_map_type tmpk_ptrs (
"Tpetra::CrsGraph::ptr",
1901 size_t lclTotalNumEntries = 0;
1904 typename row_entries_type::const_type numRowEnt_d =
1905 staticGraph_->k_numRowEntries_;
1913 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1916 typedef pack_functor<values_type, row_map_type> packer_type;
1917 packer_type valsPacker (k_vals, k_values1D_, tmpk_ptrs, k_rowPtrs_);
1920 typedef Kokkos::RangePolicy<exec_space, LocalOrdinal> range_type;
1921 Kokkos::parallel_for (range_type (0, lclNumRows), valsPacker);
1924 k_vals = k_values1D_;
1929 if (requestOptimizedStorage) {
1933 k_values1D_ = k_vals;
1934 this->storageStatus_ = ::Tpetra::Details::STORAGE_1D_PACKED;
1942 getColMap ()->getNodeNumElements (),
1944 staticGraph_->getLocalGraph ());
1947 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1952 const typename crs_graph_type::SLocalGlobalViews& newInds,
1953 const Teuchos::ArrayView<impl_scalar_type>& oldRowVals,
1954 const Teuchos::ArrayView<const impl_scalar_type>& newRowVals,
1955 const ELocalGlobal lg,
1956 const ELocalGlobal I)
1958 const size_t oldNumEnt = rowInfo.numEntries;
1959 const size_t numInserted = graph.insertIndices (rowInfo, newInds, lg, I);
1965 if (numInserted > 0) {
1966 const size_t startOffset = oldNumEnt;
1967 memcpy (&oldRowVals[startOffset], &newRowVals[0],
1968 numInserted *
sizeof (impl_scalar_type));
1972 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1976 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1977 const Teuchos::ArrayView<const Scalar>& values)
1981 const char tfecfFuncName[] =
"insertLocalValues: ";
1983 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1984 (! this->isFillActive (), std::runtime_error,
1985 "Fill is not active. After calling fillComplete, you must call "
1986 "resumeFill before you may insert entries into the matrix again.");
1987 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1988 (this->isStaticGraph (), std::runtime_error,
1989 "Cannot insert indices with static graph; use replaceLocalValues() "
1993 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1994 (graph.
colMap_.is_null (), std::runtime_error,
1995 "Cannot insert local indices without a column map.");
1996 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1998 std::runtime_error,
"Graph indices are global; use "
1999 "insertGlobalValues().");
2000 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2001 (values.size () != indices.size (), std::runtime_error,
2002 "values.size() = " << values.size ()
2003 <<
" != indices.size() = " << indices.size () <<
".");
2004 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2005 ! graph.
rowMap_->isNodeLocalElement (lclRow), std::runtime_error,
2006 "Local row index " << lclRow <<
" does not belong to this process.");
2008 if (! graph.indicesAreAllocated ()) {
2009 this->allocateValues (LocalIndices, GraphNotYetAllocated);
2012 const size_t numEntriesToAdd =
static_cast<size_t> (indices.size ());
2013 #ifdef HAVE_TPETRA_DEBUG
2018 using Teuchos::toString;
2021 Teuchos::Array<LocalOrdinal> badColInds;
2022 bool allInColMap =
true;
2023 for (
size_t k = 0; k < numEntriesToAdd; ++k) {
2025 allInColMap =
false;
2026 badColInds.push_back (indices[k]);
2029 if (! allInColMap) {
2030 std::ostringstream os;
2031 os <<
"You attempted to insert entries in owned row " << lclRow
2032 <<
", at the following column indices: " << toString (indices)
2034 os <<
"Of those, the following indices are not in the column Map on "
2035 "this process: " << toString (badColInds) <<
"." << endl <<
"Since "
2036 "the matrix has a column Map already, it is invalid to insert "
2037 "entries at those locations.";
2038 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2039 (
true, std::invalid_argument, os.str ());
2042 #endif // HAVE_TPETRA_DEBUG
2046 if (this->getProfileType() == StaticProfile)
2048 Teuchos::ArrayView<IST> valsView = this->getViewNonConst(rowInfo);
2049 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset) {
2050 valsView[offset] += values[k]; };
2051 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2052 graph.insertLocalIndicesImpl(lclRow, indices, cb);
2057 const size_t curNumEnt = rowInfo.numEntries;
2058 const size_t newNumEnt = curNumEnt + numEntriesToAdd;
2059 if (newNumEnt > rowInfo.allocSize) {
2061 Teuchos::Array<IST>& curVals = this->values2D_[lclRow];
2065 graph.
lclInds2D_[rowInfo.localRow].resize (newNumEnt);
2066 curVals.resize (newNumEnt);
2067 rowInfo.allocSize = newNumEnt;
2069 typename crs_graph_type::SLocalGlobalViews indsView;
2070 indsView.linds = indices;
2072 Teuchos::ArrayView<IST> valsView = this->getViewNonConst (rowInfo);
2073 Teuchos::ArrayView<const IST> valsIn =
2074 Teuchos::av_reinterpret_cast<
const IST> (values);
2075 this->insertIndicesAndValues (graph, rowInfo, indsView, valsView,
2076 valsIn, LocalIndices, LocalIndices);
2077 #ifdef HAVE_TPETRA_DEBUG
2079 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2080 (chkNewNumEnt != newNumEnt, std::logic_error,
2081 "The row should have " << newNumEnt <<
" entries after insert, but "
2082 "instead has " << chkNewNumEnt <<
". Please report this bug to "
2083 "the Tpetra developers.");
2084 #endif // HAVE_TPETRA_DEBUG
2088 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2092 const LocalOrdinal numEnt,
2093 const Scalar vals[],
2094 const LocalOrdinal cols[])
2096 Teuchos::ArrayView<const LocalOrdinal> colsT (cols, numEnt);
2097 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
2098 this->insertLocalValues (localRow, colsT, valsT);
2101 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2106 const GlobalOrdinal gblColInds[],
2107 const impl_scalar_type vals[],
2108 const size_t numInputEnt)
2110 typedef impl_scalar_type IST;
2111 typedef GlobalOrdinal GO;
2112 #ifdef HAVE_TPETRA_DEBUG
2113 const char tfecfFuncName[] =
"insertGlobalValuesImpl: ";
2115 #endif // HAVE_TPETRA_DEBUG
2117 size_t newNumEnt = 0;
2118 const size_t curNumEnt = rowInfo.numEntries;
2120 if (! graph.indicesAreAllocated ()) {
2121 this->allocateValues (GlobalIndices, GraphNotYetAllocated);
2126 rowInfo = graph.getRowInfo (rowInfo.localRow);
2129 if (this->getProfileType () == StaticProfile) {
2130 Teuchos::ArrayView<IST> valsView = this->getViewNonConst(rowInfo);
2131 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset) {
2132 valsView[offset] += vals[k]; };
2133 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2135 graph.insertGlobalIndicesImpl(rowInfo, gblColInds, numInputEnt, cb);
2136 newNumEnt = curNumEnt + numInserted;
2140 newNumEnt = curNumEnt + numInputEnt;
2141 if (newNumEnt > rowInfo.allocSize) {
2144 Teuchos::Array<IST>& curVals = this->values2D_[rowInfo.localRow];
2147 graph.gblInds2D_[rowInfo.localRow].resize (newNumEnt);
2148 curVals.resize (newNumEnt);
2149 rowInfo.allocSize = newNumEnt;
2152 using Teuchos::ArrayView;
2153 typename crs_graph_type::SLocalGlobalViews inputIndsAV;
2154 inputIndsAV.ginds = ArrayView<const GO> (gblColInds, numInputEnt);
2155 ArrayView<IST> curValsAV = this->getViewNonConst (rowInfo);
2156 ArrayView<const IST> inputValsAV (vals, numInputEnt);
2158 const ELocalGlobal curIndexingStatus =
2159 this->isGloballyIndexed () ? GlobalIndices : LocalIndices;
2165 this->insertIndicesAndValues (graph, rowInfo, inputIndsAV, curValsAV,
2166 inputValsAV, GlobalIndices,
2170 #ifdef HAVE_TPETRA_DEBUG
2171 const size_t chkNewNumEnt =
2172 graph.getNumEntriesInLocalRow (rowInfo.localRow);
2173 if (chkNewNumEnt != newNumEnt) {
2174 std::ostringstream os;
2175 os << std::endl <<
"newNumEnt = " << newNumEnt
2176 <<
" != graph.getNumEntriesInLocalRow(" << rowInfo.localRow
2177 <<
") = " << chkNewNumEnt <<
"." << std::endl
2178 <<
"\torigNumEnt: " << origNumEnt << std::endl
2179 <<
"\tnumInputEnt: " << numInputEnt << std::endl
2180 <<
"\tgblColInds: [";
2181 for (
size_t k = 0; k < numInputEnt; ++k) {
2182 os << gblColInds[k];
2183 if (k +
size_t (1) < numInputEnt) {
2187 os <<
"]" << std::endl
2189 for (
size_t k = 0; k < numInputEnt; ++k) {
2191 if (k +
size_t (1) < numInputEnt) {
2195 os <<
"]" << std::endl;
2197 if (this->supportsRowViews ()) {
2198 Teuchos::ArrayView<const Scalar> vals2;
2199 if (this->isGloballyIndexed ()) {
2200 Teuchos::ArrayView<const GlobalOrdinal> gblColInds2;
2201 const GlobalOrdinal gblRow =
2202 graph.rowMap_->getGlobalElement (rowInfo.localRow);
2203 if (gblRow == Tpetra::Details::OrdinalTraits<GlobalOrdinal>::invalid ()) {
2204 os <<
"Local row index " << rowInfo.localRow <<
" is invalid!" << std::endl;
2207 bool getViewThrew =
false;
2209 this->getGlobalRowView (gblRow, gblColInds2, vals2);
2211 catch (std::exception& e) {
2212 getViewThrew =
true;
2213 os <<
"getGlobalRowView threw exception:" << std::endl
2214 << e.what () << std::endl;
2216 if (! getViewThrew) {
2217 os <<
"\tNew global column indices: "
2218 << Teuchos::toString (gblColInds2) << std::endl
2219 <<
"\tNew values: " << Teuchos::toString (vals2) << std::endl;
2223 else if (this->isLocallyIndexed ()) {
2224 Teuchos::ArrayView<const LocalOrdinal> lclColInds2;
2225 this->getLocalRowView (rowInfo.localRow, lclColInds2, vals2);
2226 os <<
"\tNew local column indices: " << Teuchos::toString (lclColInds2)
2228 os <<
"\tNew values: " << Teuchos::toString (vals2) << std::endl;
2232 os <<
"Please report this bug to the Tpetra developers.";
2233 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2234 (
true, std::logic_error, os.str ());
2236 #endif // HAVE_TPETRA_DEBUG
2239 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2243 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2244 const Teuchos::ArrayView<const Scalar>& values)
2246 using Teuchos::toString;
2249 typedef LocalOrdinal LO;
2250 typedef GlobalOrdinal GO;
2251 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2252 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
2253 const char tfecfFuncName[] =
"insertGlobalValues: ";
2255 #ifdef HAVE_TPETRA_DEBUG
2256 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2257 (values.size () != indices.size (), std::runtime_error,
2258 "values.size() = " << values.size () <<
" != indices.size() = "
2259 << indices.size () <<
".");
2260 #endif // HAVE_TPETRA_DEBUG
2264 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2267 if (lclRow == OTLO::invalid ()) {
2274 this->insertNonownedGlobalValues (gblRow, indices, values);
2277 if (this->isStaticGraph ()) {
2279 const int myRank = rowMap.getComm ()->getRank ();
2280 const int numProcs = rowMap.getComm ()->getSize ();
2281 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2282 (
true, std::runtime_error,
2283 "The matrix was constructed with a constant (\"static\") graph, "
2284 "yet the given global row index " << gblRow <<
" is in the row "
2285 "Map on the calling process (with rank " << myRank <<
", of " <<
2286 numProcs <<
" process(es)). In this case, you may not insert "
2287 "new entries into rows owned by the calling process.");
2291 const IST*
const inputVals =
2292 reinterpret_cast<const IST*
> (values.getRawPtr ());
2293 const GO*
const inputGblColInds = indices.getRawPtr ();
2294 const size_t numInputEnt = indices.size ();
2303 if (! graph.
colMap_.is_null ()) {
2309 #ifdef HAVE_TPETRA_DEBUG
2310 Teuchos::Array<GO> badColInds;
2311 #endif // HAVE_TPETRA_DEBUG
2312 const size_type numEntriesToInsert = indices.size ();
2313 bool allInColMap =
true;
2314 for (size_type k = 0; k < numEntriesToInsert; ++k) {
2316 allInColMap =
false;
2317 #ifdef HAVE_TPETRA_DEBUG
2318 badColInds.push_back (indices[k]);
2321 #endif // HAVE_TPETRA_DEBUG
2324 if (! allInColMap) {
2325 std::ostringstream os;
2326 os <<
"You attempted to insert entries in owned row " << gblRow
2327 <<
", at the following column indices: " << toString (indices)
2329 #ifdef HAVE_TPETRA_DEBUG
2330 os <<
"Of those, the following indices are not in the column Map "
2331 "on this process: " << toString (badColInds) <<
"." << endl
2332 <<
"Since the matrix has a column Map already, it is invalid "
2333 "to insert entries at those locations.";
2335 os <<
"At least one of those indices is not in the column Map "
2336 "on this process." << endl <<
"It is invalid to insert into "
2337 "columns not in the column Map on the process that owns the "
2339 #endif // HAVE_TPETRA_DEBUG
2340 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2341 (
true, std::invalid_argument, os.str ());
2345 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2346 inputVals, numInputEnt);
2351 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2355 const LocalOrdinal numEnt,
2356 const Scalar vals[],
2357 const GlobalOrdinal inds[])
2359 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
2360 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
2361 this->insertGlobalValues (globalRow, indsT, valsT);
2365 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2369 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2370 const Teuchos::ArrayView<const Scalar>& values)
2372 typedef impl_scalar_type IST;
2373 typedef LocalOrdinal LO;
2374 typedef GlobalOrdinal GO;
2375 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2376 const char tfecfFuncName[] =
"insertGlobalValuesFiltered: ";
2378 #ifdef HAVE_TPETRA_DEBUG
2379 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2380 (values.size () != indices.size (), std::runtime_error,
2381 "values.size() = " << values.size () <<
" != indices.size() = "
2382 << indices.size () <<
".");
2383 #endif // HAVE_TPETRA_DEBUG
2387 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2388 const LO lclRow = rowMap.getLocalElement (gblRow);
2390 if (lclRow == OTLO::invalid ()) {
2397 this->insertNonownedGlobalValues (gblRow, indices, values);
2400 if (this->isStaticGraph ()) {
2402 const int myRank = rowMap.getComm ()->getRank ();
2403 const int numProcs = rowMap.getComm ()->getSize ();
2404 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2405 (
true, std::runtime_error,
2406 "The matrix was constructed with a constant (\"static\") graph, "
2407 "yet the given global row index " << gblRow <<
" is in the row "
2408 "Map on the calling process (with rank " << myRank <<
", of " <<
2409 numProcs <<
" process(es)). In this case, you may not insert "
2410 "new entries into rows owned by the calling process.");
2413 crs_graph_type& graph = * (this->myGraph_);
2414 const IST*
const inputVals =
2415 reinterpret_cast<const IST*
> (values.getRawPtr ());
2416 const GO*
const inputGblColInds = indices.getRawPtr ();
2417 const size_t numInputEnt = indices.size ();
2418 RowInfo rowInfo = graph.getRowInfo (lclRow);
2420 if (! graph.colMap_.is_null ()) {
2421 const map_type& colMap = * (graph.colMap_);
2422 size_t curOffset = 0;
2423 while (curOffset < numInputEnt) {
2427 size_t endOffset = curOffset;
2428 for ( ; endOffset < numInputEnt &&
2429 colMap.getLocalElement (inputGblColInds[endOffset]) != OTLO::invalid ();
2435 const LO numIndInSeq = (endOffset - curOffset);
2436 if (numIndInSeq != 0) {
2437 this->insertGlobalValuesImpl (graph, rowInfo,
2438 inputGblColInds + curOffset,
2439 inputVals + curOffset,
2445 #ifdef HAVE_TPETRA_DEBUG
2446 const bool invariant = endOffset == numInputEnt ||
2447 colMap.getLocalElement (inputGblColInds[endOffset]) == OTLO::invalid ();
2448 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2449 (! invariant, std::logic_error, std::endl <<
"Invariant failed!");
2450 #endif // HAVE_TPETRA_DEBUG
2451 curOffset = endOffset + 1;
2455 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2456 inputVals, numInputEnt);
2461 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2463 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2464 replaceLocalValuesImpl (impl_scalar_type rowVals[],
2465 const crs_graph_type& graph,
2466 const RowInfo& rowInfo,
2467 const LocalOrdinal inds[],
2468 const impl_scalar_type newVals[],
2469 const LocalOrdinal numElts)
const
2471 if (graph.getProfileType() == StaticProfile)
2473 Teuchos::ArrayView<const LocalOrdinal> indsT(inds, numElts);
2475 [&](
size_t const k,
size_t const ,
size_t const offset) {
2476 rowVals[offset] = newVals[k];
2478 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2479 return graph.findLocalIndices(rowInfo, indsT, cb);
2484 typedef LocalOrdinal LO;
2485 typedef GlobalOrdinal GO;
2486 const bool sorted = graph.isSorted ();
2495 if (graph.isLocallyIndexed ()) {
2498 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2500 for (LO j = 0; j < numElts; ++j) {
2501 const LO lclColInd = inds[j];
2502 const size_t offset =
2503 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2504 lclColInd, hint, sorted);
2505 if (offset != rowInfo.numEntries) {
2506 rowVals[offset] = newVals[j];
2512 else if (graph.isGloballyIndexed ()) {
2513 if (graph.colMap_.is_null ()) {
2514 return Teuchos::OrdinalTraits<LO>::invalid ();
2516 const map_type colMap = * (graph.colMap_);
2520 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2522 for (LO j = 0; j < numElts; ++j) {
2523 const GO gblColInd = colMap.getGlobalElement (inds[j]);
2524 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2525 const size_t offset =
2526 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2527 gblColInd, hint, sorted);
2528 if (offset != rowInfo.numEntries) {
2529 rowVals[offset] = newVals[j];
2548 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2552 const Teuchos::ArrayView<const LocalOrdinal>& lclCols,
2553 const Teuchos::ArrayView<const Scalar>& vals)
const
2555 typedef LocalOrdinal LO;
2557 const LO numInputEnt =
static_cast<LO
> (lclCols.size ());
2558 if (static_cast<LO> (vals.size ()) != numInputEnt) {
2559 return Teuchos::OrdinalTraits<LO>::invalid ();
2561 const LO*
const inputInds = lclCols.getRawPtr ();
2562 const Scalar*
const inputVals = vals.getRawPtr ();
2563 return this->replaceLocalValues (localRow, numInputEnt,
2564 inputVals, inputInds);
2567 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2571 const LocalOrdinal numEnt,
2572 const Scalar inputVals[],
2573 const LocalOrdinal inputCols[])
const
2576 typedef LocalOrdinal LO;
2578 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2580 return Teuchos::OrdinalTraits<LO>::invalid ();
2585 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2588 return static_cast<LO
> (0);
2590 auto curRowVals = this->getRowViewNonConst (rowInfo);
2591 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2592 return this->replaceLocalValuesImpl (curRowVals.data (), graph, rowInfo,
2593 inputCols, inVals, numEnt);
2596 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2600 const crs_graph_type& graph,
2602 const GlobalOrdinal inds[],
2603 const impl_scalar_type newVals[],
2604 const LocalOrdinal numElts)
const
2606 if (graph.getProfileType() == StaticProfile)
2608 Teuchos::ArrayView<const GlobalOrdinal> indsT(inds, numElts);
2610 [&](
size_t const k,
size_t const ,
size_t const offset) {
2611 rowVals[offset] = newVals[k];
2613 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2614 return graph.findGlobalIndices(rowInfo, indsT, cb);
2619 typedef LocalOrdinal LO;
2620 typedef GlobalOrdinal GO;
2622 const bool sorted = graph.isSorted ();
2631 if (graph.isLocallyIndexed ()) {
2635 if (graph.colMap_.is_null ()) {
2641 const map_type& colMap = * (graph.colMap_);
2645 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2646 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2647 for (LO j = 0; j < numElts; ++j) {
2648 const LO lclColInd = colMap.getLocalElement (inds[j]);
2649 if (lclColInd != LINV) {
2650 const size_t offset =
2651 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2652 lclColInd, hint, sorted);
2653 if (offset != rowInfo.numEntries) {
2654 rowVals[offset] = newVals[j];
2661 else if (graph.isGloballyIndexed ()) {
2664 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2666 for (LO j = 0; j < numElts; ++j) {
2667 const GO gblColInd = inds[j];
2668 const size_t offset =
2669 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2670 gblColInd, hint, sorted);
2671 if (offset != rowInfo.numEntries) {
2672 rowVals[offset] = newVals[j];
2685 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2689 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2690 const Teuchos::ArrayView<const Scalar>& inputVals)
const
2692 typedef LocalOrdinal LO;
2694 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2695 if (static_cast<LO> (inputVals.size ()) != numInputEnt) {
2696 return Teuchos::OrdinalTraits<LO>::invalid ();
2698 return this->replaceGlobalValues (globalRow, numInputEnt,
2699 inputVals.getRawPtr (),
2700 inputGblColInds.getRawPtr ());
2703 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2707 const LocalOrdinal numEnt,
2708 const Scalar inputVals[],
2709 const GlobalOrdinal inputGblColInds[])
const
2712 typedef LocalOrdinal LO;
2714 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2716 return Teuchos::OrdinalTraits<LO>::invalid ();
2721 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2724 return static_cast<LO
> (0);
2727 auto curRowVals = this->getRowViewNonConst (rowInfo);
2728 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2729 return this->replaceGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2730 inputGblColInds, inVals, numEnt);
2733 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2737 const crs_graph_type& graph,
2739 const GlobalOrdinal inds[],
2740 const impl_scalar_type newVals[],
2741 const LocalOrdinal numElts,
2742 const bool atomic)
const
2744 if (graph.getProfileType() == StaticProfile)
2746 Teuchos::ArrayView<const GlobalOrdinal> indsT(inds, numElts);
2748 [&](
size_t const k,
size_t const ,
size_t const offset) {
2750 Kokkos::atomic_add(&rowVals[offset], newVals[k]);
2752 rowVals[offset] += newVals[k];
2754 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2755 return graph.findGlobalIndices(rowInfo, indsT, cb);
2760 typedef LocalOrdinal LO;
2761 typedef GlobalOrdinal GO;
2763 const bool sorted = graph.isSorted ();
2772 if (graph.isLocallyIndexed ()) {
2776 if (graph.colMap_.is_null ()) {
2782 const map_type& colMap = * (graph.colMap_);
2786 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2787 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2789 for (LO j = 0; j < numElts; ++j) {
2790 const LO lclColInd = colMap.getLocalElement (inds[j]);
2791 if (lclColInd != LINV) {
2792 const size_t offset =
2793 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2794 lclColInd, hint, sorted);
2795 if (offset != rowInfo.numEntries) {
2797 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2800 rowVals[offset] += newVals[j];
2808 else if (graph.isGloballyIndexed ()) {
2811 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2813 for (LO j = 0; j < numElts; ++j) {
2814 const GO gblColInd = inds[j];
2815 const size_t offset =
2816 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2817 gblColInd, hint, sorted);
2818 if (offset != rowInfo.numEntries) {
2820 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2823 rowVals[offset] += newVals[j];
2837 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2841 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2842 const Teuchos::ArrayView<const Scalar>& inputVals,
2845 typedef LocalOrdinal LO;
2847 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2848 if (static_cast<LO> (inputVals.size ()) != numInputEnt) {
2849 return Teuchos::OrdinalTraits<LO>::invalid ();
2851 return this->sumIntoGlobalValues (gblRow, numInputEnt,
2852 inputVals.getRawPtr (),
2853 inputGblColInds.getRawPtr (),
2857 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2861 const LocalOrdinal numInputEnt,
2862 const Scalar inputVals[],
2863 const GlobalOrdinal inputGblColInds[],
2867 typedef LocalOrdinal LO;
2868 typedef GlobalOrdinal GO;
2870 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2872 return Teuchos::OrdinalTraits<LO>::invalid ();
2877 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2882 using Teuchos::ArrayView;
2883 ArrayView<const GO> inputGblColInds_av (numInputEnt == 0 ? NULL :
2884 inputGblColInds, numInputEnt);
2885 ArrayView<const Scalar> inputVals_av (numInputEnt == 0 ? NULL :
2886 inputVals, numInputEnt);
2891 this->insertNonownedGlobalValues (gblRow, inputGblColInds_av,
2902 auto curRowVals = this->getRowViewNonConst (rowInfo);
2903 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2904 return this->sumIntoGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2905 inputGblColInds, inVals,
2906 numInputEnt, atomic);
2910 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2914 const LocalOrdinal numInputEnt,
2915 const impl_scalar_type inputVals[],
2916 const LocalOrdinal inputCols[],
2917 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2918 const bool atomic)
const
2920 using Tpetra::Details::OrdinalTraits;
2921 typedef LocalOrdinal LO;
2923 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2925 return Teuchos::OrdinalTraits<LO>::invalid ();
2927 const crs_graph_type& graph = * (this->staticGraph_);
2928 const RowInfo rowInfo = graph.getRowInfo (lclRow);
2930 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2933 return static_cast<LO
> (0);
2935 auto curRowVals = this->getRowViewNonConst (rowInfo);
2936 return this->transformLocalValues (curRowVals.data (), graph,
2937 rowInfo, inputCols, inputVals,
2938 numInputEnt, f, atomic);
2941 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2943 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2944 transformGlobalValues (
const GlobalOrdinal gblRow,
2945 const LocalOrdinal numInputEnt,
2946 const impl_scalar_type inputVals[],
2947 const GlobalOrdinal inputCols[],
2948 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2949 const bool atomic)
const
2951 using Tpetra::Details::OrdinalTraits;
2952 typedef LocalOrdinal LO;
2954 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2956 return OrdinalTraits<LO>::invalid ();
2958 const crs_graph_type& graph = * (this->staticGraph_);
2959 const RowInfo rowInfo = graph.getRowInfoFromGlobalRowIndex (gblRow);
2961 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2964 return static_cast<LO
> (0);
2966 auto curRowVals = this->getRowViewNonConst (rowInfo);
2967 return this->transformGlobalValues (curRowVals.data (), graph,
2968 rowInfo, inputCols, inputVals,
2969 numInputEnt, f, atomic);
2972 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2974 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2975 transformLocalValues (impl_scalar_type rowVals[],
2976 const crs_graph_type& graph,
2977 const RowInfo& rowInfo,
2978 const LocalOrdinal inds[],
2979 const impl_scalar_type newVals[],
2980 const LocalOrdinal numElts,
2981 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2982 const bool atomic)
const
2984 typedef impl_scalar_type ST;
2985 typedef LocalOrdinal LO;
2986 typedef GlobalOrdinal GO;
2988 if (graph.getProfileType() == StaticProfile)
2990 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset)
2996 volatile ST*
const dest = &rowVals[offset];
2997 (void) atomic_binary_function_update (dest, newVals[k], f);
3001 rowVals[offset] = f(rowVals[offset], newVals[k]);
3004 Teuchos::ArrayView<const LO> indsT(inds, numElts);
3005 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
3006 return graph.findLocalIndices(rowInfo, indsT, cb);
3017 const bool sorted = graph.isSorted ();
3022 if (graph.isLocallyIndexed ()) {
3025 auto colInds = graph.getLocalKokkosRowView (rowInfo);
3027 for (LO j = 0; j < numElts; ++j) {
3028 const LO lclColInd = inds[j];
3029 const size_t offset =
3030 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3031 lclColInd, hint, sorted);
3032 if (offset != rowInfo.numEntries) {
3041 volatile ST*
const dest = &rowVals[offset];
3042 (void) atomic_binary_function_update (dest, newVals[j], f);
3046 rowVals[offset] = f (rowVals[offset], newVals[j]);
3053 else if (graph.isGloballyIndexed ()) {
3057 if (graph.colMap_.is_null ()) {
3064 const map_type& colMap = * (graph.colMap_);
3067 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
3069 const GO GINV = Teuchos::OrdinalTraits<GO>::invalid ();
3070 for (LO j = 0; j < numElts; ++j) {
3071 const GO gblColInd = colMap.getGlobalElement (inds[j]);
3072 if (gblColInd != GINV) {
3073 const size_t offset =
3074 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3075 gblColInd, hint, sorted);
3076 if (offset != rowInfo.numEntries) {
3085 volatile ST*
const dest = &rowVals[offset];
3086 (void) atomic_binary_function_update (dest, newVals[j], f);
3090 rowVals[offset] = f (rowVals[offset], newVals[j]);
3105 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3107 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3108 transformGlobalValues (impl_scalar_type rowVals[],
3109 const crs_graph_type& graph,
3110 const RowInfo& rowInfo,
3111 const GlobalOrdinal inds[],
3112 const impl_scalar_type newVals[],
3113 const LocalOrdinal numElts,
3114 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
3115 const bool atomic)
const
3117 typedef impl_scalar_type ST;
3118 typedef LocalOrdinal LO;
3119 typedef GlobalOrdinal GO;
3121 if (graph.getProfileType() == StaticProfile)
3123 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset)
3126 volatile ST*
const dest = &rowVals[offset];
3127 (void) atomic_binary_function_update(dest, newVals[k], f);
3131 rowVals[offset] = f (rowVals[offset], newVals[k]);
3134 Teuchos::ArrayView<const GO> indsT(inds, numElts);
3135 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
3136 return graph.findGlobalIndices(rowInfo, indsT, cb);
3147 const bool sorted = graph.isSorted ();
3152 if (graph.isGloballyIndexed ()) {
3155 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
3157 for (LO j = 0; j < numElts; ++j) {
3158 const GO gblColInd = inds[j];
3159 const size_t offset =
3160 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3161 gblColInd, hint, sorted);
3162 if (offset != rowInfo.numEntries) {
3171 volatile ST*
const dest = &rowVals[offset];
3172 (void) atomic_binary_function_update (dest, newVals[j], f);
3176 rowVals[offset] = f (rowVals[offset], newVals[j]);
3183 else if (graph.isLocallyIndexed ()) {
3187 if (graph.colMap_.is_null ()) {
3193 const map_type& colMap = * (graph.colMap_);
3196 auto colInds = graph.getLocalKokkosRowView (rowInfo);
3198 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
3199 for (LO j = 0; j < numElts; ++j) {
3200 const LO lclColInd = colMap.getLocalElement (inds[j]);
3201 if (lclColInd != LINV) {
3202 const size_t offset =
3203 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3204 lclColInd, hint, sorted);
3205 if (offset != rowInfo.numEntries) {
3214 volatile ST*
const dest = &rowVals[offset];
3215 (void) atomic_binary_function_update (dest, newVals[j], f);
3219 rowVals[offset] = f (rowVals[offset], newVals[j]);
3234 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3236 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3237 sumIntoLocalValuesImpl (impl_scalar_type rowVals[],
3238 const crs_graph_type& graph,
3239 const RowInfo& rowInfo,
3240 const LocalOrdinal inds[],
3241 const impl_scalar_type newVals[],
3242 const LocalOrdinal numElts,
3243 const bool atomic)
const
3245 if (graph.getProfileType() == StaticProfile)
3247 Teuchos::ArrayView<const LocalOrdinal> indsT(inds, numElts);
3249 [&](
size_t const k,
size_t const ,
size_t const offset) {
3251 Kokkos::atomic_add(&rowVals[offset], newVals[k]);
3253 rowVals[offset] += newVals[k];
3255 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
3256 return graph.findLocalIndices(rowInfo, indsT, cb);
3262 typedef LocalOrdinal LO;
3263 typedef GlobalOrdinal GO;
3265 const bool sorted = graph.isSorted ();
3274 if (graph.isLocallyIndexed ()) {
3277 auto colInds = graph.getLocalKokkosRowView (rowInfo);
3279 for (LO j = 0; j < numElts; ++j) {
3280 const LO lclColInd = inds[j];
3281 const size_t offset =
3282 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3283 lclColInd, hint, sorted);
3284 if (offset != rowInfo.numEntries) {
3286 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3289 rowVals[offset] += newVals[j];
3296 else if (graph.isGloballyIndexed ()) {
3297 if (graph.colMap_.is_null ()) {
3298 return Teuchos::OrdinalTraits<LO>::invalid ();
3300 const map_type colMap = * (graph.colMap_);
3304 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
3306 for (LO j = 0; j < numElts; ++j) {
3307 const GO gblColInd = colMap.getGlobalElement (inds[j]);
3308 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
3309 const size_t offset =
3310 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3311 gblColInd, hint, sorted);
3312 if (offset != rowInfo.numEntries) {
3314 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3317 rowVals[offset] += newVals[j];
3337 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3341 const Teuchos::ArrayView<const LocalOrdinal>& indices,
3342 const Teuchos::ArrayView<const Scalar>& values,
3343 const bool atomic)
const
3345 typedef LocalOrdinal LO;
3347 const LO numInputEnt =
static_cast<LO
> (indices.size ());
3348 if (static_cast<LO> (values.size ()) != numInputEnt) {
3349 return Teuchos::OrdinalTraits<LO>::invalid ();
3351 const LO*
const inputInds = indices.getRawPtr ();
3352 const Scalar*
const inputVals = values.getRawPtr ();
3353 return this->sumIntoLocalValues (localRow, numInputEnt,
3354 inputVals, inputInds, atomic);
3357 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3361 const LocalOrdinal numEnt,
3362 const Scalar vals[],
3363 const LocalOrdinal cols[],
3364 const bool atomic)
const
3367 typedef LocalOrdinal LO;
3369 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
3371 return Teuchos::OrdinalTraits<LO>::invalid ();
3376 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
3379 return static_cast<LO
> (0);
3381 auto curRowVals = this->getRowViewNonConst (rowInfo);
3382 const IST*
const inputVals =
reinterpret_cast<const IST*
> (vals);
3383 return this->sumIntoLocalValuesImpl (curRowVals.data (), graph, rowInfo,
3384 cols, inputVals, numEnt, atomic);
3387 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3388 Teuchos::ArrayView<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type>
3392 using Kokkos::MemoryUnmanaged;
3394 using Teuchos::ArrayView;
3396 typedef std::pair<size_t, size_t> range_type;
3398 if (k_values1D_.extent (0) != 0 && rowinfo.allocSize > 0) {
3399 #ifdef HAVE_TPETRA_DEBUG
3400 TEUCHOS_TEST_FOR_EXCEPTION(
3401 rowinfo.offset1D + rowinfo.allocSize > k_values1D_.extent (0),
3402 std::range_error,
"Tpetra::CrsMatrix::getView: Invalid access "
3403 "to 1-D storage of values." << std::endl <<
"rowinfo.offset1D (" <<
3404 rowinfo.offset1D <<
") + rowinfo.allocSize (" << rowinfo.allocSize <<
3405 ") > k_values1D_.extent(0) (" << k_values1D_.extent (0) <<
").");
3406 #endif // HAVE_TPETRA_DEBUG
3407 range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
3408 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
3415 subview_type sv = Kokkos::subview (subview_type (k_values1D_), range);
3416 const ST*
const sv_raw = (rowinfo.allocSize == 0) ? NULL : sv.data ();
3417 return ArrayView<const ST> (sv_raw, rowinfo.allocSize);
3419 else if (values2D_ != Teuchos::null) {
3420 return values2D_[rowinfo.localRow] ();
3423 return ArrayView<impl_scalar_type> ();
3428 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3432 LocalOrdinal& numEnt,
3435 if (k_values1D_.extent (0) != 0 && rowinfo.allocSize > 0) {
3436 #ifdef HAVE_TPETRA_DEBUG
3437 if (rowinfo.offset1D + rowinfo.allocSize > k_values1D_.extent (0)) {
3440 return Teuchos::OrdinalTraits<LocalOrdinal>::invalid ();
3442 #endif // HAVE_TPETRA_DEBUG
3443 vals = k_values1D_.data () + rowinfo.offset1D;
3444 numEnt = rowinfo.allocSize;
3446 else if (! values2D_.is_null ()) {
3447 #ifdef HAVE_TPETRA_DEBUG
3448 if (rowinfo.localRow >= static_cast<size_t> (values2D_.size ())) {
3451 return Teuchos::OrdinalTraits<LocalOrdinal>::invalid ();
3453 #endif // HAVE_TPETRA_DEBUG
3456 const auto& curRow = values2D_[rowinfo.localRow];
3457 vals = curRow.getRawPtr ();
3458 numEnt = curRow.size ();
3465 return static_cast<LocalOrdinal
> (0);
3468 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3472 LocalOrdinal& numEnt,
3476 const LocalOrdinal err = this->getViewRawConst (valsConst, numEnt, rowinfo);
3481 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3482 Kokkos::View<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type*,
3484 Kokkos::MemoryUnmanaged>
3488 using Kokkos::MemoryUnmanaged;
3490 typedef impl_scalar_type ST;
3491 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
3492 typedef std::pair<size_t, size_t> range_type;
3494 if (k_values1D_.extent (0) != 0 && rowInfo.allocSize > 0) {
3495 #ifdef HAVE_TPETRA_DEBUG
3496 TEUCHOS_TEST_FOR_EXCEPTION
3497 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.extent (0),
3498 std::range_error,
"Tpetra::CrsMatrix::getRowView: Invalid access "
3499 "to 1-D storage of values. rowInfo.offset1D ("
3500 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
3501 <<
") > this->k_values1D_.extent(0) ("
3502 << this->k_values1D_.extent (0) <<
").");
3503 #endif // HAVE_TPETRA_DEBUG
3504 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
3511 return Kokkos::subview (subview_type (this->k_values1D_), range);
3513 else if (this->values2D_ != Teuchos::null) {
3517 auto& rowView = this->values2D_[rowInfo.localRow];
3518 return subview_type (rowView.getRawPtr (), rowView.size ());
3521 return subview_type ();
3525 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3526 Kokkos::View<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type*,
3527 typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::execution_space,
3528 Kokkos::MemoryUnmanaged>
3529 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3530 getRowViewNonConst (
const RowInfo& rowInfo)
const
3532 using Kokkos::MemoryUnmanaged;
3534 typedef impl_scalar_type ST;
3535 typedef View<ST*, execution_space, MemoryUnmanaged> subview_type;
3536 typedef std::pair<size_t, size_t> range_type;
3538 if (k_values1D_.extent (0) != 0 && rowInfo.allocSize > 0) {
3539 #ifdef HAVE_TPETRA_DEBUG
3540 TEUCHOS_TEST_FOR_EXCEPTION
3541 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.extent (0),
3542 std::range_error,
"Tpetra::CrsMatrix::getRowViewNonConst: Invalid "
3543 "access to 1-D storage of values. rowInfo.offset1D ("
3544 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
3545 <<
") > this->k_values1D_.extent(0) ("
3546 << this->k_values1D_.extent (0) <<
").");
3547 #endif // HAVE_TPETRA_DEBUG
3548 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
3555 return Kokkos::subview (subview_type (this->k_values1D_), range);
3557 else if (this->values2D_ != Teuchos::null) {
3561 auto& rowView = this->values2D_[rowInfo.localRow];
3562 return subview_type (rowView.getRawPtr (), rowView.size ());
3565 return subview_type ();
3569 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3570 Teuchos::ArrayView<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type>
3577 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3581 const Teuchos::ArrayView<LocalOrdinal>& indices,
3582 const Teuchos::ArrayView<Scalar>& values,
3583 size_t& numEntries)
const
3585 using Teuchos::ArrayView;
3586 using Teuchos::av_reinterpret_cast;
3587 const char tfecfFuncName[] =
"getLocalRowCopy: ";
3589 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3590 (! this->hasColMap (), std::runtime_error,
3591 "The matrix does not have a column Map yet. This means we don't have "
3592 "local indices for columns yet, so it doesn't make sense to call this "
3593 "method. If the matrix doesn't have a column Map yet, you should call "
3594 "fillComplete on it first.");
3596 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3597 const size_t theNumEntries = rowinfo.numEntries;
3598 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3599 (static_cast<size_t> (indices.size ()) < theNumEntries ||
3600 static_cast<size_t> (values.size ()) < theNumEntries,
3601 std::runtime_error,
"Row with local index " << localRow <<
" has " <<
3602 theNumEntries <<
" entry/ies, but indices.size() = " <<
3603 indices.size () <<
" and values.size() = " << values.size () <<
".");
3604 numEntries = theNumEntries;
3606 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3607 if (staticGraph_->isLocallyIndexed ()) {
3608 const LocalOrdinal* curLclInds;
3610 LocalOrdinal numSpots;
3615 #ifdef HAVE_TPETRA_DEBUG
3617 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3618 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3619 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3620 "staticGraph_->getLocalViewRawConst returned nonzero error code "
3622 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3623 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3624 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3626 const LocalOrdinal numSpotsBefore = numSpots;
3627 err = getViewRawConst (curVals, numSpots, rowinfo);
3628 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3629 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3630 "getViewRaw returned nonzero error code " << err <<
".");
3631 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3632 (numSpotsBefore != numSpots, std::logic_error,
3633 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3634 << numSpots <<
".");
3636 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3637 (void) getViewRawConst (curVals, numSpots, rowinfo);
3638 #endif // HAVE_TPETRA_DEBUG
3640 for (
size_t j = 0; j < theNumEntries; ++j) {
3641 values[j] = curVals[j];
3642 indices[j] = curLclInds[j];
3645 else if (staticGraph_->isGloballyIndexed ()) {
3647 const map_type& colMap = * (staticGraph_->colMap_);
3648 const GlobalOrdinal* curGblInds;
3650 LocalOrdinal numSpots;
3655 #ifdef HAVE_TPETRA_DEBUG
3657 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3658 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3659 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3660 "staticGraph_->getGlobalViewRawConst returned nonzero error code "
3662 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3663 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3664 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3666 const LocalOrdinal numSpotsBefore = numSpots;
3667 err = getViewRawConst (curVals, numSpots, rowinfo);
3668 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3669 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3670 "getViewRawConst returned nonzero error code " << err <<
".");
3671 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3672 (numSpotsBefore != numSpots, std::logic_error,
3673 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3674 << numSpots <<
".");
3676 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3677 (void) getViewRawConst (curVals, numSpots, rowinfo);
3678 #endif //HAVE_TPETRA_DEBUG
3680 for (
size_t j = 0; j < theNumEntries; ++j) {
3681 values[j] = curVals[j];
3688 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3692 const Teuchos::ArrayView<GlobalOrdinal>& indices,
3693 const Teuchos::ArrayView<Scalar>& values,
3694 size_t& numEntries)
const
3696 using Teuchos::ArrayView;
3697 using Teuchos::av_reinterpret_cast;
3698 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
3701 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3702 const size_t theNumEntries = rowinfo.numEntries;
3703 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3704 static_cast<size_t> (indices.size ()) < theNumEntries ||
3705 static_cast<size_t> (values.size ()) < theNumEntries,
3706 std::runtime_error,
"Row with global index " << globalRow <<
" has "
3707 << theNumEntries <<
" entry/ies, but indices.size() = " <<
3708 indices.size () <<
" and values.size() = " << values.size () <<
".");
3709 numEntries = theNumEntries;
3711 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3712 if (staticGraph_->isLocallyIndexed ()) {
3713 const map_type& colMap = * (staticGraph_->colMap_);
3714 const LocalOrdinal* curLclInds;
3716 LocalOrdinal numSpots;
3721 #ifdef HAVE_TPETRA_DEBUG
3723 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3724 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3725 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3726 "staticGraph_->getLocalViewRawConst returned nonzero error code "
3728 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3729 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3730 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3732 const LocalOrdinal numSpotsBefore = numSpots;
3733 err = getViewRawConst (curVals, numSpots, rowinfo);
3734 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3735 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3736 "getViewRaw returned nonzero error code " << err <<
".");
3737 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3738 (numSpotsBefore != numSpots, std::logic_error,
3739 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3740 << numSpots <<
".");
3742 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3743 (void) getViewRawConst (curVals, numSpots, rowinfo);
3744 #endif //HAVE_TPETRA_DEBUG
3746 for (
size_t j = 0; j < theNumEntries; ++j) {
3747 values[j] = curVals[j];
3751 else if (staticGraph_->isGloballyIndexed ()) {
3752 const GlobalOrdinal* curGblInds;
3754 LocalOrdinal numSpots;
3759 #ifdef HAVE_TPETRA_DEBUG
3761 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3762 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3763 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3764 "staticGraph_->getGlobalViewRawConst returned nonzero error code "
3766 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3767 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3768 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3770 const LocalOrdinal numSpotsBefore = numSpots;
3771 err = getViewRawConst (curVals, numSpots, rowinfo);
3772 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3773 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3774 "getViewRawConst returned nonzero error code " << err <<
".");
3775 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3776 (numSpotsBefore != numSpots, std::logic_error,
3777 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3778 << numSpots <<
".");
3780 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3781 (void) getViewRawConst (curVals, numSpots, rowinfo);
3782 #endif //HAVE_TPETRA_DEBUG
3784 for (
size_t j = 0; j < theNumEntries; ++j) {
3785 values[j] = curVals[j];
3786 indices[j] = curGblInds[j];
3792 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3796 Teuchos::ArrayView<const LocalOrdinal>& indices,
3797 Teuchos::ArrayView<const Scalar>& values)
const
3799 using Teuchos::ArrayView;
3800 using Teuchos::av_reinterpret_cast;
3801 typedef LocalOrdinal LO;
3802 const char tfecfFuncName[] =
"getLocalRowView: ";
3804 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3805 isGloballyIndexed (), std::runtime_error,
"The matrix currently stores "
3806 "its indices as global indices, so you cannot get a view with local "
3807 "column indices. If the matrix has a column Map, you may call "
3808 "getLocalRowCopy() to get local column indices; otherwise, you may get "
3809 "a view with global column indices by calling getGlobalRowCopy().");
3810 indices = Teuchos::null;
3811 values = Teuchos::null;
3812 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3813 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3814 rowinfo.numEntries > 0) {
3815 ArrayView<const LO> indTmp = staticGraph_->getLocalView (rowinfo);
3816 ArrayView<const Scalar> valTmp =
3817 av_reinterpret_cast<
const Scalar> (this->getView (rowinfo));
3818 indices = indTmp (0, rowinfo.numEntries);
3819 values = valTmp (0, rowinfo.numEntries);
3822 #ifdef HAVE_TPETRA_DEBUG
3823 const char suffix[] =
". This should never happen. Please report this "
3824 "bug to the Tpetra developers.";
3825 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3826 (static_cast<size_t> (indices.size ()) !=
3827 static_cast<size_t> (values.size ()), std::logic_error,
3828 "At the end of this method, for local row " << localRow <<
", "
3829 "indices.size() = " << indices.size () <<
" != values.size () = "
3830 << values.size () << suffix);
3831 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3832 (static_cast<size_t> (indices.size ()) !=
3833 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3834 "At the end of this method, for local row " << localRow <<
", "
3835 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3836 << rowinfo.numEntries << suffix);
3837 const size_t expectedNumEntries = getNumEntriesInLocalRow (localRow);
3838 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3839 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3840 "of this method, for local row " << localRow <<
", rowinfo.numEntries = "
3841 << rowinfo.numEntries <<
" != getNumEntriesInLocalRow(localRow) = " <<
3842 expectedNumEntries << suffix);
3843 #endif // HAVE_TPETRA_DEBUG
3846 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3850 LocalOrdinal& numEnt,
3852 const LocalOrdinal*& ind)
const
3854 typedef LocalOrdinal LO;
3861 if (staticGraph_.is_null () || staticGraph_->isGloballyIndexed ()) {
3862 return Tpetra::Details::OrdinalTraits<LO>::invalid ();
3865 const RowInfo rowInfo = staticGraph_->getRowInfo (lclRow);
3866 if (rowInfo.localRow == Tpetra::Details::OrdinalTraits<size_t>::invalid ()) {
3871 return static_cast<LO
> (1);
3874 numEnt =
static_cast<LO
> (rowInfo.numEntries);
3875 auto lclColInds = staticGraph_->getLocalKokkosRowView (rowInfo);
3876 ind = lclColInds.data ();
3877 const LO err = this->getViewRawConst (val, numEnt, rowInfo);
3883 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3887 LocalOrdinal& numEnt,
3888 const LocalOrdinal*& lclColInds,
3889 const Scalar*& vals)
const
3892 const LocalOrdinal errCode =
3893 this->getLocalRowView (lclRow, numEnt, vals_ist, lclColInds);
3894 vals =
reinterpret_cast<const Scalar*
> (vals_ist);
3898 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3902 Teuchos::ArrayView<const GlobalOrdinal>& indices,
3903 Teuchos::ArrayView<const Scalar>& values)
const
3905 using Teuchos::ArrayView;
3906 using Teuchos::av_reinterpret_cast;
3907 typedef GlobalOrdinal GO;
3908 const char tfecfFuncName[] =
"getGlobalRowView: ";
3910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3911 isLocallyIndexed (), std::runtime_error,
3912 "The matrix is locally indexed, so we cannot return a view of the row "
3913 "with global column indices. Use getGlobalRowCopy() instead.");
3914 indices = Teuchos::null;
3915 values = Teuchos::null;
3917 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3918 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3919 rowinfo.numEntries > 0) {
3920 ArrayView<const GO> indTmp = staticGraph_->getGlobalView (rowinfo);
3921 ArrayView<const Scalar> valTmp =
3922 av_reinterpret_cast<
const Scalar> (this->getView (rowinfo));
3923 #ifdef HAVE_TPETRA_DEBUG
3924 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3925 (static_cast<size_t> (indTmp.size ()) < rowinfo.numEntries ||
3926 static_cast<size_t> (valTmp.size ()) < rowinfo.numEntries,
3927 std::logic_error, std::endl <<
"rowinfo.numEntries not accurate. "
3928 << std::endl <<
"indTmp.size() = " << indTmp.size ()
3929 <<
", valTmp.size() = " << valTmp.size ()
3930 <<
", rowinfo.numEntries = " << rowinfo.numEntries <<
".");
3931 #endif // HAVE_TPETRA_DEBUG
3932 indices = indTmp (0, rowinfo.numEntries);
3933 values = valTmp (0, rowinfo.numEntries);
3936 #ifdef HAVE_TPETRA_DEBUG
3937 const char suffix[] =
". This should never happen. Please report this "
3938 "bug to the Tpetra developers.";
3939 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3940 (static_cast<size_t> (indices.size ()) !=
3941 static_cast<size_t> (values.size ()), std::logic_error,
3942 "At the end of this method, for global row " << globalRow <<
", "
3943 "indices.size() = " << indices.size () <<
" != values.size () = "
3944 << values.size () << suffix);
3945 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3946 (static_cast<size_t> (indices.size ()) !=
3947 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3948 "At the end of this method, for global row " << globalRow <<
", "
3949 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3950 << rowinfo.numEntries << suffix);
3951 const size_t expectedNumEntries = getNumEntriesInGlobalRow (globalRow);
3952 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3953 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3954 "of this method, for global row " << globalRow <<
", rowinfo.numEntries "
3955 "= " << rowinfo.numEntries <<
" != getNumEntriesInGlobalRow(globalRow) ="
3956 " " << expectedNumEntries << suffix);
3957 #endif // HAVE_TPETRA_DEBUG
3960 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3965 typedef LocalOrdinal LO;
3966 typedef typename Teuchos::Array<Scalar>::size_type size_type;
3967 const char tfecfFuncName[] =
"scale: ";
3970 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3971 ! isFillActive (), std::runtime_error,
3972 "Fill must be active before you may call this method. "
3973 "Please call resumeFill() to make fill active.");
3975 const size_t nlrs = staticGraph_->getNodeNumRows ();
3976 const size_t numEntries = staticGraph_->getNodeNumEntries ();
3977 if (! staticGraph_->indicesAreAllocated () ||
3978 nlrs == 0 || numEntries == 0) {
3982 if (staticGraph_->getProfileType () == StaticProfile) {
3983 const LO lclNumRows = lclMatrix_.numRows ();
3984 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
3985 auto row_i = lclMatrix_.row (lclRow);
3986 for (LO k = 0; k < row_i.length; ++k) {
3988 row_i.value (k) *= theAlpha;
3992 else if (staticGraph_->getProfileType () != StaticProfile) {
3993 for (
size_t row = 0; row < nlrs; ++row) {
3994 const size_type numEnt = getNumEntriesInLocalRow (row);
3995 Teuchos::ArrayView<impl_scalar_type> rowVals = values2D_[row] ();
3996 for (size_type k = 0; k < numEnt; ++k) {
3997 rowVals[k] *= theAlpha;
4004 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4009 const char tfecfFuncName[] =
"setAllToScalar: ";
4011 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4012 ! isFillActive (), std::runtime_error,
4013 "Fill must be active before you may call this method. "
4014 "Please call resumeFill() to make fill active.");
4020 const size_t nlrs = staticGraph_->getNodeNumRows();
4021 const size_t numEntries = staticGraph_->getNodeNumEntries();
4022 if (! staticGraph_->indicesAreAllocated () || numEntries == 0) {
4026 const ProfileType profType = staticGraph_->getProfileType ();
4027 if (profType == StaticProfile) {
4033 else if (profType != StaticProfile) {
4034 for (
size_t row = 0; row < nlrs; ++row) {
4035 std::fill (values2D_[row].begin (), values2D_[row].end (), theAlpha);
4041 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4045 const typename local_graph_type::entries_type::non_const_type& columnIndices,
4046 const typename local_matrix_type::values_type& values)
4048 const char tfecfFuncName[] =
"setAllValues: ";
4049 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4050 (columnIndices.size () != values.size (), std::invalid_argument,
4051 "columnIndices.size() = " << columnIndices.size () <<
" != values.size()"
4052 " = " << values.size () <<
".");
4053 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4054 (myGraph_.is_null (), std::runtime_error,
"myGraph_ must not be null.");
4057 myGraph_->setAllIndices (rowPointers, columnIndices);
4059 catch (std::exception &e) {
4060 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4061 (
true, std::runtime_error,
"myGraph_->setAllIndices() threw an "
4062 "exception: " << e.what ());
4068 auto lclGraph = myGraph_->getLocalGraph ();
4069 const size_t numEnt = lclGraph.entries.extent (0);
4070 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4071 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
4072 numEnt !=
static_cast<size_t> (columnIndices.extent (0)),
4073 std::logic_error,
"myGraph_->setAllIndices() did not correctly create "
4074 "local graph. Please report this bug to the Tpetra developers.");
4076 const size_t numCols = myGraph_->getColMap ()->getNodeNumElements ();
4078 numCols, values, lclGraph);
4082 this->k_values1D_ = this->lclMatrix_.values;
4086 this->storageStatus_ = ::Tpetra::Details::STORAGE_1D_PACKED;
4088 checkInternalState ();
4091 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4095 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
4096 const Teuchos::ArrayRCP<Scalar>& val)
4098 using Kokkos::Compat::getKokkosViewDeepCopy;
4099 using Teuchos::ArrayRCP;
4100 using Teuchos::av_reinterpret_cast;
4103 typedef typename local_matrix_type::row_map_type row_map_type;
4105 const char tfecfFuncName[] =
"setAllValues(ArrayRCP<size_t>, ArrayRCP<LO>, ArrayRCP<Scalar>): ";
4111 typename row_map_type::non_const_type ptrNative (
"ptr", ptr.size ());
4112 Kokkos::View<
const size_t*,
4113 typename row_map_type::array_layout,
4115 Kokkos::MemoryUnmanaged> ptrSizeT (ptr.getRawPtr (), ptr.size ());
4118 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4119 (ptrNative.extent (0) != ptrSizeT.extent (0),
4120 std::logic_error,
"ptrNative.extent(0) = " <<
4121 ptrNative.extent (0) <<
" != ptrSizeT.extent(0) = "
4122 << ptrSizeT.extent (0) <<
". Please report this bug to the "
4123 "Tpetra developers.");
4125 auto indIn = getKokkosViewDeepCopy<DT> (ind ());
4126 auto valIn = getKokkosViewDeepCopy<DT> (av_reinterpret_cast<IST> (val ()));
4127 this->setAllValues (ptrNative, indIn, valIn);
4130 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4135 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
4136 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4137 (staticGraph_.is_null (), std::runtime_error,
"The matrix has no graph.");
4144 const size_t lclNumRows = staticGraph_->getNodeNumRows ();
4145 if (static_cast<size_t> (offsets.size ()) < lclNumRows) {
4146 offsets.resize (lclNumRows);
4152 typedef typename device_type::memory_space memory_space;
4153 if (std::is_same<memory_space, Kokkos::HostSpace>::value) {
4158 Kokkos::MemoryUnmanaged> output_type;
4159 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
4160 staticGraph_->getLocalDiagOffsets (offsetsOut);
4163 Kokkos::View<size_t*, device_type> offsetsTmp (
"diagOffsets", lclNumRows);
4164 staticGraph_->getLocalDiagOffsets (offsetsTmp);
4165 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
4166 Kokkos::MemoryUnmanaged> output_type;
4167 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
4172 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4177 using Teuchos::ArrayRCP;
4178 using Teuchos::ArrayView;
4179 using Teuchos::av_reinterpret_cast;
4180 const char tfecfFuncName[] =
"getLocalDiagCopy (1-arg): ";
4184 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4185 staticGraph_.is_null (), std::runtime_error,
4186 "This method requires that the matrix have a graph.");
4187 auto rowMapPtr = this->getRowMap ();
4188 if (rowMapPtr.is_null () || rowMapPtr->getComm ().is_null ()) {
4194 auto colMapPtr = this->getColMap ();
4195 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4196 (! this->hasColMap () || colMapPtr.is_null (), std::runtime_error,
4197 "This method requires that the matrix have a column Map.");
4198 const map_type& rowMap = * rowMapPtr;
4199 const map_type& colMap = * colMapPtr;
4200 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4202 #ifdef HAVE_TPETRA_DEBUG
4205 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4206 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4207 "The input Vector's Map must be compatible with the CrsMatrix's row "
4208 "Map. You may check this by using Map's isCompatible method: "
4209 "diag.getMap ()->isCompatible (A.getRowMap ());");
4210 #endif // HAVE_TPETRA_DEBUG
4212 if (this->isFillComplete ()) {
4213 diag.template modify<device_type> ();
4214 const auto D_lcl = diag.template getLocalView<device_type> ();
4216 const auto D_lcl_1d =
4217 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
4219 const auto lclRowMap = rowMap.getLocalMap ();
4221 const auto lclMatrix = this->lclMatrix_;
4224 lclColMap, lclMatrix);
4232 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4237 Kokkos::MemoryUnmanaged>& offsets)
const
4239 typedef LocalOrdinal LO;
4241 #ifdef HAVE_TPETRA_DEBUG
4242 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
4243 const map_type& rowMap = * (this->getRowMap ());
4246 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4247 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4248 "The input Vector's Map must be compatible with (in the sense of Map::"
4249 "isCompatible) the CrsMatrix's row Map.");
4250 #endif // HAVE_TPETRA_DEBUG
4259 diag.template modify<device_type> ();
4260 auto D_lcl = diag.template getLocalView<device_type> ();
4261 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4264 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
4266 KokkosSparse::getDiagCopy (D_lcl_1d, offsets, this->lclMatrix_);
4269 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4273 const Teuchos::ArrayView<const size_t>& offsets)
const
4275 using LO = LocalOrdinal;
4276 using host_execution_space = Kokkos::DefaultHostExecutionSpace;
4279 #ifdef HAVE_TPETRA_DEBUG
4280 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
4281 const map_type& rowMap = * (this->getRowMap ());
4284 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4285 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4286 "The input Vector's Map must be compatible with (in the sense of Map::"
4287 "isCompatible) the CrsMatrix's row Map.");
4288 #endif // HAVE_TPETRA_DEBUG
4301 auto lclVecHost1d = Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
4303 using host_offsets_view_type =
4304 Kokkos::View<
const size_t*, Kokkos::HostSpace,
4305 Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
4306 host_offsets_view_type h_offsets (offsets.getRawPtr (), offsets.size ());
4308 using range_type = Kokkos::RangePolicy<host_execution_space, LO>;
4309 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4310 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
4311 Kokkos::parallel_for
4312 (
"Tpetra::CrsMatrix::getLocalDiagCopy",
4313 range_type (0, myNumRows),
4314 [&] (
const LO& lclRow) {
4315 lclVecHost1d(lclRow) = STS::zero ();
4316 if (h_offsets[lclRow] != INV) {
4317 auto curRow = lclMatrix_.rowConst (lclRow);
4318 lclVecHost1d(lclRow) =
static_cast<IST
> (curRow.value(h_offsets[lclRow]));
4325 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4330 using ::Tpetra::Details::ProfilingRegion;
4331 using Teuchos::ArrayRCP;
4332 using Teuchos::ArrayView;
4333 using Teuchos::null;
4336 using Teuchos::rcpFromRef;
4339 const char tfecfFuncName[] =
"leftScale: ";
4341 ProfilingRegion region (
"Tpetra::CrsMatrix::leftScale");
4343 RCP<const vec_type> xp;
4344 if (this->getRangeMap ()->isSameAs (* (x.
getMap ()))) {
4347 auto exporter = this->getCrsGraphRef ().getExporter ();
4348 if (exporter.get () !=
nullptr) {
4349 RCP<vec_type> tempVec (
new vec_type (this->getRowMap ()));
4350 tempVec->doImport (x, *exporter,
REPLACE);
4354 xp = rcpFromRef (x);
4357 else if (this->getRowMap ()->isSameAs (* (x.
getMap ()))) {
4358 xp = rcpFromRef (x);
4361 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4362 (
true, std::invalid_argument,
"x's Map must be the same as "
4363 "either the row Map or the range Map of the CrsMatrix.");
4371 const LO lclNumRows =
4372 static_cast<LO
> (this->getRowMap ()->getNodeNumElements ());
4373 const bool validLocalMatrix = this->lclMatrix_.numRows () == lclNumRows;
4375 if (validLocalMatrix) {
4376 using dev_memory_space =
typename device_type::memory_space;
4377 if (xp->template need_sync<dev_memory_space> ()) {
4378 using Teuchos::rcp_const_cast;
4379 rcp_const_cast<vec_type> (xp)->
template sync<dev_memory_space> ();
4381 auto x_lcl = xp->template getLocalView<dev_memory_space> ();
4382 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4383 ::Tpetra::Details::leftScaleLocalCrsMatrix (this->lclMatrix_, x_lcl_1d,
false,
false);
4386 execution_space::fence ();
4388 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
4389 ArrayView<impl_scalar_type> rowValues = Teuchos::null;
4390 for (LocalOrdinal i = 0; i < lclNumRows; ++i) {
4391 const RowInfo rowinfo = this->staticGraph_->getRowInfo (i);
4392 rowValues = this->getViewNonConst (rowinfo);
4394 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
4395 rowValues[j] *= scaleValue;
4398 execution_space::fence ();
4402 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4407 using ::Tpetra::Details::ProfilingRegion;
4408 using Teuchos::ArrayRCP;
4409 using Teuchos::ArrayView;
4410 using Teuchos::null;
4413 using Teuchos::rcpFromRef;
4416 const char tfecfFuncName[] =
"rightScale: ";
4418 ProfilingRegion region (
"Tpetra::CrsMatrix::rightScale");
4420 RCP<const vec_type> xp;
4421 if (this->getDomainMap ()->isSameAs (* (x.
getMap ()))) {
4424 auto importer = this->getCrsGraphRef ().getImporter ();
4425 if (importer.get () !=
nullptr) {
4426 RCP<vec_type> tempVec (
new vec_type (this->getColMap ()));
4427 tempVec->doImport (x, *importer,
REPLACE);
4431 xp = rcpFromRef (x);
4434 else if (this->getColMap ()->isSameAs (* (x.
getMap ()))) {
4435 xp = rcpFromRef (x);
4437 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4438 (
true, std::runtime_error,
"x's Map must be the same as "
4439 "either the domain Map or the column Map of the CrsMatrix.");
4447 const LO lclNumRows =
4448 static_cast<LO
> (this->getRowMap ()->getNodeNumElements ());
4449 const bool validLocalMatrix = this->lclMatrix_.numRows () == lclNumRows;
4451 if (validLocalMatrix) {
4452 using dev_memory_space =
typename device_type::memory_space;
4453 if (xp->template need_sync<dev_memory_space> ()) {
4454 using Teuchos::rcp_const_cast;
4455 rcp_const_cast<vec_type> (xp)->
template sync<dev_memory_space> ();
4457 auto x_lcl = xp->template getLocalView<dev_memory_space> ();
4458 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4459 ::Tpetra::Details::rightScaleLocalCrsMatrix (this->lclMatrix_, x_lcl_1d,
false,
false);
4462 execution_space::fence ();
4464 ArrayRCP<const Scalar> vectorVals = xp->getData (0);
4465 ArrayView<impl_scalar_type> rowValues = null;
4466 for (LO i = 0; i < lclNumRows; ++i) {
4467 const RowInfo rowinfo = this->staticGraph_->getRowInfo (i);
4468 rowValues = this->getViewNonConst (rowinfo);
4469 ArrayView<const LO> colInds;
4470 this->getCrsGraphRef ().getLocalRowView (i, colInds);
4471 for (
size_t j = 0; j < rowinfo.numEntries; ++j) {
4475 execution_space::fence ();
4479 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4484 using Teuchos::ArrayView;
4485 using Teuchos::outArg;
4486 using Teuchos::REDUCE_SUM;
4487 using Teuchos::reduceAll;
4488 typedef typename Teuchos::ArrayRCP<const impl_scalar_type>::size_type size_type;
4496 if (frobNorm == -STM::one ()) {
4498 if (getNodeNumEntries() > 0) {
4499 if (isStorageOptimized ()) {
4502 const size_type numEntries =
4503 static_cast<size_type
> (getNodeNumEntries ());
4504 for (size_type k = 0; k < numEntries; ++k) {
4510 const mag_type val_abs = STS::abs (val);
4511 mySum += val_abs * val_abs;
4515 const LocalOrdinal numRows =
4516 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
4517 for (LocalOrdinal r = 0; r < numRows; ++r) {
4518 const RowInfo rowInfo = myGraph_->getRowInfo (r);
4519 const size_type numEntries =
4520 static_cast<size_type
> (rowInfo.numEntries);
4521 ArrayView<const impl_scalar_type> A_r =
4522 this->getView (rowInfo).view (0, numEntries);
4523 for (size_type k = 0; k < numEntries; ++k) {
4525 const mag_type val_abs = STS::abs (val);
4526 mySum += val_abs * val_abs;
4532 reduceAll<int, mag_type> (* (getComm ()), REDUCE_SUM,
4533 mySum, outArg (totalSum));
4534 frobNorm = STM::sqrt (totalSum);
4536 if (isFillComplete ()) {
4540 frobNorm_ = frobNorm;
4545 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4550 const char tfecfFuncName[] =
"replaceColMap: ";
4554 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4555 myGraph_.is_null (), std::runtime_error,
4556 "This method does not work if the matrix has a const graph. The whole "
4557 "idea of a const graph is that you are not allowed to change it, but "
4558 "this method necessarily must modify the graph, since the graph owns "
4559 "the matrix's column Map.");
4560 myGraph_->replaceColMap (newColMap);
4563 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4567 const Teuchos::RCP<const map_type>& newColMap,
4568 const Teuchos::RCP<const import_type>& newImport,
4569 const bool sortEachRow)
4571 const char tfecfFuncName[] =
"reindexColumns: ";
4572 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4573 graph == NULL && myGraph_.is_null (), std::invalid_argument,
4574 "The input graph is NULL, but the matrix does not own its graph.");
4577 const bool sortGraph =
false;
4579 if (sortEachRow && theGraph.isLocallyIndexed () && ! theGraph.isSorted ()) {
4580 const LocalOrdinal lclNumRows =
4581 static_cast<LocalOrdinal
> (theGraph.getNodeNumRows ());
4582 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
4583 const RowInfo rowInfo = theGraph.getRowInfo (row);
4584 auto lclColInds = theGraph.getLocalKokkosRowViewNonConst (rowInfo);
4585 auto vals = this->getRowViewNonConst (rowInfo);
4588 sort2 (lclColInds.data (),
4589 lclColInds.data () + rowInfo.numEntries,
4592 theGraph.indicesAreSorted_ =
true;
4596 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4600 Teuchos::RCP<const import_type>& newImporter)
4602 const char tfecfFuncName[] =
"replaceDomainMapAndImporter: ";
4603 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4604 myGraph_.is_null (), std::runtime_error,
4605 "This method does not work if the matrix has a const graph. The whole "
4606 "idea of a const graph is that you are not allowed to change it, but this"
4607 " method necessarily must modify the graph, since the graph owns the "
4608 "matrix's domain Map and Import objects.");
4609 myGraph_->replaceDomainMapAndImporter (newDomainMap, newImporter);
4612 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4616 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
4617 const Teuchos::ArrayView<const Scalar>& values)
4619 using Teuchos::Array;
4620 typedef GlobalOrdinal GO;
4621 typedef typename Array<GO>::size_type size_type;
4623 const size_type numToInsert = indices.size ();
4626 std::pair<Array<GO>, Array<Scalar> >& curRow = nonlocals_[globalRow];
4627 Array<GO>& curRowInds = curRow.first;
4628 Array<Scalar>& curRowVals = curRow.second;
4629 const size_type newCapacity = curRowInds.size () + numToInsert;
4630 curRowInds.reserve (newCapacity);
4631 curRowVals.reserve (newCapacity);
4632 for (size_type k = 0; k < numToInsert; ++k) {
4633 curRowInds.push_back (indices[k]);
4634 curRowVals.push_back (values[k]);
4638 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4643 using ::Tpetra::Details::ProfilingRegion;
4644 using Teuchos::Comm;
4645 using Teuchos::outArg;
4648 using Teuchos::REDUCE_MAX;
4649 using Teuchos::REDUCE_MIN;
4650 using Teuchos::reduceAll;
4653 typedef GlobalOrdinal GO;
4654 typedef typename Teuchos::Array<GO>::size_type size_type;
4655 const char tfecfFuncName[] =
"globalAssemble: ";
4656 ProfilingRegion regionGlobalAssemble (
"Tpetra::CrsMatrix::globalAssemble");
4658 RCP<const Comm<int> > comm = getComm ();
4660 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4661 (! isFillActive (), std::runtime_error,
"Fill must be active before "
4662 "you may call this method.");
4664 const size_t myNumNonlocalRows = nonlocals_.size ();
4671 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
4672 int someoneHasNonlocalRows = 0;
4673 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
4674 outArg (someoneHasNonlocalRows));
4675 if (someoneHasNonlocalRows == 0) {
4689 RCP<const map_type> nonlocalRowMap;
4691 Teuchos::Array<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
4693 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
4694 size_type curPos = 0;
4695 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4696 ++mapIter, ++curPos) {
4697 myNonlocalGblRows[curPos] = mapIter->first;
4700 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4701 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4708 sort2 (gblCols.begin (), gblCols.end (), vals.begin ());
4709 typename Teuchos::Array<GO>::iterator gblCols_newEnd;
4710 typename Teuchos::Array<Scalar>::iterator vals_newEnd;
4711 merge2 (gblCols_newEnd, vals_newEnd,
4712 gblCols.begin (), gblCols.end (),
4713 vals.begin (), vals.end ());
4714 gblCols.erase (gblCols_newEnd, gblCols.end ());
4715 vals.erase (vals_newEnd, vals.end ());
4716 numEntPerNonlocalRow[curPos] = gblCols.size ();
4727 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
4729 auto iter = std::min_element (myNonlocalGblRows.begin (),
4730 myNonlocalGblRows.end ());
4731 if (iter != myNonlocalGblRows.end ()) {
4732 myMinNonlocalGblRow = *iter;
4735 GO gblMinNonlocalGblRow = 0;
4736 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
4737 outArg (gblMinNonlocalGblRow));
4738 const GO indexBase = gblMinNonlocalGblRow;
4739 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
4740 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
4748 RCP<crs_matrix_type> nonlocalMatrix =
4749 rcp (
new crs_matrix_type (nonlocalRowMap, numEntPerNonlocalRow (),
4752 size_type curPos = 0;
4753 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4754 ++mapIter, ++curPos) {
4755 const GO gblRow = mapIter->first;
4757 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4758 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4760 nonlocalMatrix->insertGlobalValues (gblRow, gblCols (), vals ());
4772 auto origRowMap = this->getRowMap ();
4773 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
4775 int isLocallyComplete = 1;
4777 if (origRowMapIsOneToOne) {
4778 export_type exportToOrig (nonlocalRowMap, origRowMap);
4780 isLocallyComplete = 0;
4782 this->doExport (*nonlocalMatrix, exportToOrig,
Tpetra::ADD);
4791 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
4793 isLocallyComplete = 0;
4800 crs_matrix_type oneToOneMatrix (oneToOneRowMap, 0);
4802 oneToOneMatrix.doExport (*nonlocalMatrix, exportToOneToOne,
Tpetra::ADD);
4806 nonlocalMatrix = Teuchos::null;
4809 import_type importToOrig (oneToOneRowMap, origRowMap);
4810 this->doImport (oneToOneMatrix, importToOrig,
Tpetra::ADD);
4817 decltype (nonlocals_) newNonlocals;
4818 std::swap (nonlocals_, newNonlocals);
4827 int isGloballyComplete = 0;
4828 reduceAll<int, int> (*comm, REDUCE_MIN, isLocallyComplete,
4829 outArg (isGloballyComplete));
4830 TEUCHOS_TEST_FOR_EXCEPTION
4831 (isGloballyComplete != 1, std::runtime_error,
"On at least one process, "
4832 "you called insertGlobalValues with a global row index which is not in "
4833 "the matrix's row Map on any process in its communicator.");
4836 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4841 if (! isStaticGraph ()) {
4842 myGraph_->resumeFill (params);
4844 clearGlobalConstants ();
4845 fillComplete_ =
false;
4848 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4862 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4866 return getCrsGraphRef ().haveGlobalConstants ();
4869 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4881 frobNorm_ = -STM::one ();
4884 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4889 const char tfecfFuncName[] =
"fillComplete(params): ";
4891 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4892 (this->getCrsGraph ().is_null (), std::logic_error,
4893 "getCrsGraph() returns null. This should not happen at this point. "
4894 "Please report this bug to the Tpetra developers.");
4904 Teuchos::RCP<const map_type> rangeMap = graph.
getRowMap ();
4905 Teuchos::RCP<const map_type> domainMap = rangeMap;
4906 this->fillComplete (domainMap, rangeMap, params);
4910 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4914 const Teuchos::RCP<const map_type>& rangeMap,
4915 const Teuchos::RCP<Teuchos::ParameterList>& params)
4917 using ::Tpetra::Details::ProfilingRegion;
4918 using Teuchos::ArrayRCP;
4921 const char tfecfFuncName[] =
"fillComplete: ";
4922 ProfilingRegion regionFillComplete (
"Tpetra::CrsMatrix::fillComplete");
4924 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4925 (! this->isFillActive () || this->isFillComplete (), std::runtime_error,
4926 "Matrix fill state must be active (isFillActive() "
4927 "must be true) before you may call fillComplete().");
4928 const int numProcs = this->getComm ()->getSize ();
4936 bool assertNoNonlocalInserts =
false;
4939 bool sortGhosts =
true;
4941 if (! params.is_null ()) {
4942 assertNoNonlocalInserts = params->get (
"No Nonlocal Changes",
4943 assertNoNonlocalInserts);
4944 if (params->isParameter (
"sort column map ghost gids")) {
4945 sortGhosts = params->get (
"sort column map ghost gids", sortGhosts);
4947 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
4948 sortGhosts = params->get (
"Sort column Map ghost GIDs", sortGhosts);
4953 const bool needGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
4955 if (! this->myGraph_.is_null ()) {
4956 this->myGraph_->sortGhostsAssociatedWithEachProcessor_ = sortGhosts;
4959 if (! this->getCrsGraphRef ().indicesAreAllocated ()) {
4960 if (this->hasColMap ()) {
4962 this->allocateValues (LocalIndices, GraphNotYetAllocated);
4965 this->allocateValues (GlobalIndices, GraphNotYetAllocated);
4970 if (needGlobalAssemble) {
4971 this->globalAssemble ();
4974 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4975 (numProcs == 1 && nonlocals_.size() > 0,
4976 std::runtime_error,
"Cannot have nonlocal entries on a serial run. "
4977 "An invalid entry (i.e., with row index not in the row Map) must have "
4978 "been submitted to the CrsMatrix.");
4981 if (this->isStaticGraph ()) {
4988 #ifdef HAVE_TPETRA_DEBUG
5006 const bool domainMapsMatch =
5007 this->staticGraph_->getDomainMap ()->isSameAs (*domainMap);
5008 const bool rangeMapsMatch =
5009 this->staticGraph_->getRangeMap ()->isSameAs (*rangeMap);
5011 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5012 (! domainMapsMatch, std::runtime_error,
5013 "The CrsMatrix's domain Map does not match the graph's domain Map. "
5014 "The graph cannot be changed because it was given to the CrsMatrix "
5015 "constructor as const. You can fix this by passing in the graph's "
5016 "domain Map and range Map to the matrix's fillComplete call.");
5018 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5019 (! rangeMapsMatch, std::runtime_error,
5020 "The CrsMatrix's range Map does not match the graph's range Map. "
5021 "The graph cannot be changed because it was given to the CrsMatrix "
5022 "constructor as const. You can fix this by passing in the graph's "
5023 "domain Map and range Map to the matrix's fillComplete call.");
5024 #endif // HAVE_TPETRA_DEBUG
5028 this->fillLocalMatrix (params);
5035 this->myGraph_->setDomainRangeMaps (domainMap, rangeMap);
5038 Teuchos::Array<int> remotePIDs (0);
5039 const bool mustBuildColMap = ! this->hasColMap ();
5040 if (mustBuildColMap) {
5041 this->myGraph_->makeColMap (remotePIDs);
5046 const std::pair<size_t, std::string> makeIndicesLocalResult =
5047 this->myGraph_->makeIndicesLocal ();
5052 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5053 (makeIndicesLocalResult.first != 0, std::runtime_error,
5054 makeIndicesLocalResult.second);
5056 const bool sorted = this->myGraph_->isSorted ();
5057 const bool merged = this->myGraph_->isMerged ();
5058 this->sortAndMergeIndicesAndValues (sorted, merged);
5063 this->myGraph_->makeImportExport (remotePIDs, mustBuildColMap);
5067 this->fillLocalGraphAndMatrix (params);
5069 const bool callGraphComputeGlobalConstants = params.get () ==
nullptr ||
5070 params->get (
"compute global constants",
true);
5071 const bool computeLocalTriangularConstants = params.get () ==
nullptr ||
5072 params->get (
"compute local triangular constants",
true);
5073 if (callGraphComputeGlobalConstants) {
5074 this->myGraph_->computeGlobalConstants (computeLocalTriangularConstants);
5077 this->myGraph_->computeLocalConstants (computeLocalTriangularConstants);
5079 this->myGraph_->fillComplete_ =
true;
5080 this->myGraph_->checkInternalState ();
5083 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
5084 params->get (
"compute global constants",
true);
5085 if (callComputeGlobalConstants) {
5086 this->computeGlobalConstants ();
5091 this->fillComplete_ =
true;
5092 this->checkInternalState ();
5095 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5099 const Teuchos::RCP<const map_type> & rangeMap,
5100 const Teuchos::RCP<const import_type>& importer,
5101 const Teuchos::RCP<const export_type>& exporter,
5102 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
5104 #ifdef HAVE_TPETRA_MMM_TIMINGS
5106 if(!params.is_null())
5107 label = params->get(
"Timer Label",label);
5108 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
5109 using Teuchos::TimeMonitor;
5111 Teuchos::TimeMonitor all(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-all")));
5114 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
5115 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! isFillActive() || isFillComplete(),
5116 std::runtime_error,
"Matrix fill state must be active (isFillActive() "
5117 "must be true) before calling fillComplete().");
5118 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5119 myGraph_.is_null (), std::logic_error,
"myGraph_ is null. This is not allowed.");
5122 #ifdef HAVE_TPETRA_MMM_TIMINGS
5123 Teuchos::TimeMonitor graph(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-Graph")));
5126 myGraph_->expertStaticFillComplete (domainMap, rangeMap, importer, exporter,params);
5129 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
5130 params->get (
"compute global constants",
true);
5131 if (callComputeGlobalConstants) {
5132 this->computeGlobalConstants ();
5136 #ifdef HAVE_TPETRA_MMM_TIMINGS
5137 TimeMonitor fLGAM(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-fLGAM")));
5140 fillLocalGraphAndMatrix (params);
5145 fillComplete_ =
true;
5148 #ifdef HAVE_TPETRA_DEBUG
5149 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(isFillActive(), std::logic_error,
5150 ": We're at the end of fillComplete(), but isFillActive() is true. "
5151 "Please report this bug to the Tpetra developers.");
5152 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(! isFillComplete(), std::logic_error,
5153 ": We're at the end of fillComplete(), but isFillActive() is true. "
5154 "Please report this bug to the Tpetra developers.");
5155 #endif // HAVE_TPETRA_DEBUG
5157 #ifdef HAVE_TPETRA_MMM_TIMINGS
5158 Teuchos::TimeMonitor cIS(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cIS")));
5161 checkInternalState();
5165 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5171 #ifdef HAVE_TPETRA_DEBUG
5172 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
5173 #endif // HAVE_TPETRA_DEBUG
5175 auto rowValues = this->getRowViewNonConst (rowInfo);
5176 typedef typename std::decay<decltype (rowValues[0]) >::type value_type;
5177 value_type* rowValueIter = rowValues.data ();
5178 auto inds_view = graph.getLocalKokkosRowViewNonConst (rowInfo);
5181 LocalOrdinal* beg = inds_view.data ();
5182 LocalOrdinal* end = inds_view.data () + rowInfo.numEntries;
5184 #ifdef HAVE_TPETRA_DEBUG
5185 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5186 (rowInfo.allocSize != static_cast<size_t> (inds_view.extent (0)) ||
5187 rowInfo.allocSize != static_cast<size_t> (rowValues.extent (0)),
5188 std::runtime_error,
"rowInfo.allocSize = " << rowInfo.allocSize
5189 <<
" != inds_view.extent(0) = " << inds_view.extent (0)
5190 <<
" || rowInfo.allocSize = " << rowInfo.allocSize
5191 <<
" != rowValues.extent(0) = " << rowValues.extent (0) <<
".");
5192 #endif // HAVE_TPETRA_DEBUG
5194 LocalOrdinal* newend = beg;
5196 LocalOrdinal* cur = beg + 1;
5197 value_type* vcur = rowValueIter + 1;
5198 value_type* vend = rowValueIter;
5200 while (cur != end) {
5201 if (*cur != *newend) {
5218 const size_t mergedEntries = newend - beg;
5220 const size_t numDups = rowInfo.numEntries - mergedEntries;
5224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5229 using ::Tpetra::Details::ProfilingRegion;
5230 typedef LocalOrdinal LO;
5231 typedef typename Kokkos::View<LO*, device_type>::HostMirror::execution_space
5232 host_execution_space;
5233 typedef Kokkos::RangePolicy<host_execution_space, LO> range_type;
5235 const char tfecfFuncName[] =
"sortAndMergeIndicesAndValues: ";
5236 ProfilingRegion regionSAM (
"Tpetra::CrsMatrix::sortAndMergeIndicesAndValues");
5238 if (! sorted || ! merged) {
5239 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5240 (this->isStaticGraph (), std::runtime_error,
"Cannot sort or merge with "
5241 "\"static\" (const) graph, since the matrix does not own the graph.");
5242 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5243 (this->myGraph_.is_null (), std::logic_error,
"myGraph_ is null, but "
5244 "this matrix claims ! isStaticGraph(). "
5245 "Please report this bug to the Tpetra developers.");
5246 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5247 (this->isStorageOptimized (), std::logic_error,
"It is invalid to call "
5248 "this method if the graph's storage has already been optimized. "
5249 "Please report this bug to the Tpetra developers.");
5252 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5253 size_t totalNumDups = 0;
5255 Kokkos::parallel_reduce (range_type (0, lclNumRows),
5256 [
this, &graph, sorted, merged] (
const LO& lclRow,
size_t& numDups) {
5259 auto lclColInds = graph.getLocalKokkosRowViewNonConst (rowInfo);
5260 auto vals = this->getRowViewNonConst (rowInfo);
5263 sort2 (lclColInds.data (),
5264 lclColInds.data () + rowInfo.numEntries,
5268 numDups += this->mergeRowIndicesAndValues (graph, rowInfo);
5280 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5291 using Teuchos::rcp_const_cast;
5292 using Teuchos::rcpFromRef;
5293 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5294 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
5300 if (alpha == ZERO) {
5303 }
else if (beta != ONE) {
5317 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5318 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5324 const bool Y_is_overwritten = (beta ==
ZERO);
5327 const bool Y_is_replicated =
5328 (! Y_in.
isDistributed () && this->getComm ()->getSize () != 1);
5336 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5343 RCP<const MV> X_colMap;
5344 if (importer.is_null ()) {
5352 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in,
true);
5354 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
5359 X_colMap = rcpFromRef (X_in);
5363 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply: Import");
5369 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in);
5372 X_colMapNonConst->doImport (X_in, *importer,
INSERT);
5373 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
5380 RCP<MV> Y_rowMap = getRowMapMultiVector (Y_in);
5387 if (! exporter.is_null ()) {
5388 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, ZERO);
5390 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply: Export");
5396 if (Y_is_overwritten) {
5422 Y_rowMap = getRowMapMultiVector (Y_in,
true);
5429 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, beta);
5433 this->localApply (*X_colMap, Y_in, Teuchos::NO_TRANS, alpha, beta);
5441 if (Y_is_replicated) {
5442 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply: Reduce Y");
5447 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5452 const Teuchos::ETransp mode,
5457 using Teuchos::null;
5460 using Teuchos::rcp_const_cast;
5461 using Teuchos::rcpFromRef;
5462 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5465 if (alpha == ZERO) {
5488 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5489 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5495 const bool Y_is_overwritten = (beta ==
ZERO);
5496 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5502 X = rcp (
new MV (X_in, Teuchos::Copy));
5504 X = rcpFromRef (X_in);
5508 if (importer != Teuchos::null) {
5509 if (importMV_ != Teuchos::null && importMV_->getNumVectors() != numVectors) {
5512 if (importMV_ == null) {
5513 importMV_ = rcp (
new MV (this->getColMap (), numVectors));
5516 if (exporter != Teuchos::null) {
5517 if (exportMV_ != Teuchos::null && exportMV_->getNumVectors() != numVectors) {
5520 if (exportMV_ == null) {
5521 exportMV_ = rcp (
new MV (this->getRowMap (), numVectors));
5527 if (! exporter.is_null ()) {
5528 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply (transpose): Import");
5529 exportMV_->doImport (X_in, *exporter,
INSERT);
5536 if (importer != Teuchos::null) {
5537 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply (transpose): Export");
5544 importMV_->putScalar (ZERO);
5546 this->localApply (*X, *importMV_, mode, alpha, ZERO);
5547 if (Y_is_overwritten) {
5564 MV Y (Y_in, Teuchos::Copy);
5565 this->localApply (*X, Y, mode, alpha, beta);
5568 this->localApply (*X, Y_in, mode, alpha, beta);
5575 if (Y_is_replicated) {
5576 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply (transpose): Reduce Y");
5581 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5586 const Teuchos::ETransp mode,
5587 const Scalar& alpha,
5588 const Scalar& beta)
const
5591 ProfilingRegion regionLocalApply (
"Tpetra::CrsMatrix::localApply");
5592 this->
template localMultiply<Scalar, Scalar> (X, Y, mode, alpha, beta);
5595 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5600 Teuchos::ETransp mode,
5605 const char fnName[] =
"Tpetra::CrsMatrix::apply";
5607 TEUCHOS_TEST_FOR_EXCEPTION
5608 (! isFillComplete (), std::runtime_error,
5609 fnName <<
": Cannot call apply() until fillComplete() "
5610 "has been called.");
5612 if (mode == Teuchos::NO_TRANS) {
5613 ProfilingRegion regionNonTranspose (fnName);
5614 this->applyNonTranspose (X, Y, alpha, beta);
5617 ProfilingRegion regionTranspose (
"Tpetra::CrsMatrix::apply (transpose)");
5624 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5628 this->applyTranspose (X, Y, mode, alpha, beta);
5632 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5638 const Scalar& dampingFactor,
5640 const int numSweeps)
const
5642 reorderedGaussSeidel (B, X, D, Teuchos::null, dampingFactor, direction, numSweeps);
5645 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5651 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
5652 const Scalar& dampingFactor,
5654 const int numSweeps)
const
5656 using Teuchos::null;
5659 using Teuchos::rcp_const_cast;
5660 using Teuchos::rcpFromRef;
5663 TEUCHOS_TEST_FOR_EXCEPTION(
5664 isFillComplete() ==
false, std::runtime_error,
5665 "Tpetra::CrsMatrix::gaussSeidel: cannot call this method until "
5666 "fillComplete() has been called.");
5667 TEUCHOS_TEST_FOR_EXCEPTION(
5669 std::invalid_argument,
5670 "Tpetra::CrsMatrix::gaussSeidel: The number of sweeps must be , "
5671 "nonnegative but you provided numSweeps = " << numSweeps <<
" < 0.");
5676 if (direction == Forward) {
5677 localDirection = Forward;
5679 else if (direction == Backward) {
5680 localDirection = Backward;
5682 else if (direction == Symmetric) {
5684 localDirection = Forward;
5687 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
5688 "Tpetra::CrsMatrix::gaussSeidel: The 'direction' enum does not have "
5689 "any of its valid values: Forward, Backward, or Symmetric.");
5692 if (numSweeps == 0) {
5699 RCP<const import_type> importer = this->getGraph()->getImporter();
5700 RCP<const export_type> exporter = this->getGraph()->getExporter();
5701 TEUCHOS_TEST_FOR_EXCEPTION(
5702 ! exporter.is_null (), std::runtime_error,
5703 "Tpetra's gaussSeidel implementation requires that the row, domain, "
5704 "and range Maps be the same. This cannot be the case, because the "
5705 "matrix has a nontrivial Export object.");
5707 RCP<const map_type> domainMap = this->getDomainMap ();
5708 RCP<const map_type> rangeMap = this->getRangeMap ();
5709 RCP<const map_type> rowMap = this->getGraph ()->getRowMap ();
5710 RCP<const map_type> colMap = this->getGraph ()->getColMap ();
5712 #ifdef HAVE_TEUCHOS_DEBUG
5717 TEUCHOS_TEST_FOR_EXCEPTION(
5718 ! X.
getMap ()->isSameAs (*domainMap),
5720 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5721 "multivector X be in the domain Map of the matrix.");
5722 TEUCHOS_TEST_FOR_EXCEPTION(
5723 ! B.
getMap ()->isSameAs (*rangeMap),
5725 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5726 "B be in the range Map of the matrix.");
5727 TEUCHOS_TEST_FOR_EXCEPTION(
5728 ! D.
getMap ()->isSameAs (*rowMap),
5730 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5731 "D be in the row Map of the matrix.");
5732 TEUCHOS_TEST_FOR_EXCEPTION(
5733 ! rowMap->isSameAs (*rangeMap),
5735 "Tpetra::CrsMatrix::gaussSeidel requires that the row Map and the "
5736 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
5737 TEUCHOS_TEST_FOR_EXCEPTION(
5738 ! domainMap->isSameAs (*rangeMap),
5740 "Tpetra::CrsMatrix::gaussSeidel requires that the domain Map and "
5741 "the range Map of the matrix be the same.");
5747 #endif // HAVE_TEUCHOS_DEBUG
5757 B_in = rcpFromRef (B);
5764 RCP<MV> B_in_nonconst = getRowMapMultiVector (B,
true);
5766 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
5771 "gaussSeidel: The current implementation of the Gauss-Seidel kernel "
5772 "requires that X and B both have constant stride. Since B does not "
5773 "have constant stride, we had to make a copy. This is a limitation of "
5774 "the current implementation and not your fault, but we still report it "
5775 "as an efficiency warning for your information.");
5784 RCP<MV> X_domainMap;
5786 bool copiedInput =
false;
5788 if (importer.is_null ()) {
5790 X_domainMap = rcpFromRef (X);
5791 X_colMap = X_domainMap;
5792 copiedInput =
false;
5798 X_colMap = getColumnMapMultiVector (X,
true);
5799 X_domainMap = X_colMap;
5804 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the "
5805 "Gauss-Seidel kernel requires that X and B both have constant "
5806 "stride. Since X does not have constant stride, we had to make a "
5807 "copy. This is a limitation of the current implementation and not "
5808 "your fault, but we still report it as an efficiency warning for "
5809 "your information.");
5814 X_domainMap = rcpFromRef (X);
5818 X_colMap = X_domainMap->offsetViewNonConst (colMap, 0);
5828 X_colMap->doImport (X, *importer,
INSERT);
5829 copiedInput =
false;
5836 X_colMap = getColumnMapMultiVector (X,
true);
5837 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
5838 X_colMap->doImport (X, *importer,
INSERT);
5842 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the "
5843 "Gauss-Seidel kernel requires that X and B both have constant stride. "
5844 "Since X does not have constant stride, we had to make a copy. "
5845 "This is a limitation of the current implementation and not your fault, "
5846 "but we still report it as an efficiency warning for your information.");
5850 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
5851 if (! importer.is_null () && sweep > 0) {
5853 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5857 if (direction != Symmetric) {
5858 if (rowIndices.is_null ()) {
5859 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5864 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5871 const bool doImportBetweenDirections =
false;
5872 if (rowIndices.is_null ()) {
5873 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5880 if (doImportBetweenDirections) {
5882 if (! importer.is_null ()) {
5883 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5886 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5891 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5895 if (doImportBetweenDirections) {
5897 if (! importer.is_null ()) {
5898 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5901 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5914 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5920 const Scalar& dampingFactor,
5922 const int numSweeps,
5923 const bool zeroInitialGuess)
const
5925 reorderedGaussSeidelCopy (X, B, D, Teuchos::null, dampingFactor, direction,
5926 numSweeps, zeroInitialGuess);
5929 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5935 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
5936 const Scalar& dampingFactor,
5938 const int numSweeps,
5939 const bool zeroInitialGuess)
const
5941 using Teuchos::null;
5944 using Teuchos::rcpFromRef;
5945 using Teuchos::rcp_const_cast;
5947 const char prefix[] =
"Tpetra::CrsMatrix::(reordered)gaussSeidelCopy: ";
5948 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5950 TEUCHOS_TEST_FOR_EXCEPTION(
5951 ! isFillComplete (), std::runtime_error,
5952 prefix <<
"The matrix is not fill complete.");
5953 TEUCHOS_TEST_FOR_EXCEPTION(
5954 numSweeps < 0, std::invalid_argument,
5955 prefix <<
"The number of sweeps must be nonnegative, "
5956 "but you provided numSweeps = " << numSweeps <<
" < 0.");
5961 if (direction == Forward) {
5962 localDirection = Forward;
5964 else if (direction == Backward) {
5965 localDirection = Backward;
5967 else if (direction == Symmetric) {
5969 localDirection = Forward;
5972 TEUCHOS_TEST_FOR_EXCEPTION(
5973 true, std::invalid_argument,
5974 prefix <<
"The 'direction' enum does not have any of its valid "
5975 "values: Forward, Backward, or Symmetric.");
5978 if (numSweeps == 0) {
5982 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5983 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5984 TEUCHOS_TEST_FOR_EXCEPTION(
5985 ! exporter.is_null (), std::runtime_error,
5986 "This method's implementation currently requires that the matrix's row, "
5987 "domain, and range Maps be the same. This cannot be the case, because "
5988 "the matrix has a nontrivial Export object.");
5990 RCP<const map_type> domainMap = this->getDomainMap ();
5991 RCP<const map_type> rangeMap = this->getRangeMap ();
5992 RCP<const map_type> rowMap = this->getGraph ()->getRowMap ();
5993 RCP<const map_type> colMap = this->getGraph ()->getColMap ();
5995 #ifdef HAVE_TEUCHOS_DEBUG
6000 TEUCHOS_TEST_FOR_EXCEPTION(
6001 ! X.
getMap ()->isSameAs (*domainMap), std::runtime_error,
6002 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
6003 "multivector X be in the domain Map of the matrix.");
6004 TEUCHOS_TEST_FOR_EXCEPTION(
6005 ! B.
getMap ()->isSameAs (*rangeMap), std::runtime_error,
6006 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
6007 "B be in the range Map of the matrix.");
6008 TEUCHOS_TEST_FOR_EXCEPTION(
6009 ! D.
getMap ()->isSameAs (*rowMap), std::runtime_error,
6010 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
6011 "D be in the row Map of the matrix.");
6012 TEUCHOS_TEST_FOR_EXCEPTION(
6013 ! rowMap->isSameAs (*rangeMap), std::runtime_error,
6014 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the row Map and the "
6015 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
6016 TEUCHOS_TEST_FOR_EXCEPTION(
6017 ! domainMap->isSameAs (*rangeMap), std::runtime_error,
6018 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the domain Map and "
6019 "the range Map of the matrix be the same.");
6025 #endif // HAVE_TEUCHOS_DEBUG
6036 RCP<MV> X_domainMap;
6037 bool copyBackOutput =
false;
6038 if (importer.is_null ()) {
6040 X_colMap = rcpFromRef (X);
6041 X_domainMap = rcpFromRef (X);
6047 if (zeroInitialGuess) {
6048 X_colMap->putScalar (ZERO);
6056 X_colMap = getColumnMapMultiVector (X,
true);
6060 X_domainMap = X_colMap;
6061 if (! zeroInitialGuess) {
6064 }
catch (std::exception& e) {
6065 std::ostringstream os;
6066 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: "
6067 "deep_copy(*X_domainMap, X) threw an exception: "
6068 << e.what () <<
".";
6069 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
6072 copyBackOutput =
true;
6076 "gaussSeidelCopy: The current implementation of the Gauss-Seidel "
6077 "kernel requires that X and B both have constant stride. Since X "
6078 "does not have constant stride, we had to make a copy. This is a "
6079 "limitation of the current implementation and not your fault, but we "
6080 "still report it as an efficiency warning for your information.");
6084 X_colMap = getColumnMapMultiVector (X);
6085 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
6087 #ifdef HAVE_TPETRA_DEBUG
6088 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
6089 auto X_colMap_host_view =
6090 X_colMap->template getLocalView<Kokkos::HostSpace> ();
6091 auto X_domainMap_host_view =
6092 X_domainMap->template getLocalView<Kokkos::HostSpace> ();
6094 auto X_colMap_host_view =
6095 X_colMap->getLocalViewHost ();
6096 auto X_domainMap_host_view =
6097 X_domainMap->getLocalViewHost ();
6100 if (X_colMap->getLocalLength () != 0 && X_domainMap->getLocalLength ()) {
6101 TEUCHOS_TEST_FOR_EXCEPTION
6102 (X_colMap_host_view.data () != X_domainMap_host_view.data (),
6103 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: Pointer to "
6104 "start of column Map view of X is not equal to pointer to start of "
6105 "(domain Map view of) X. This may mean that Tpetra::MultiVector::"
6106 "offsetViewNonConst is broken. "
6107 "Please report this bug to the Tpetra developers.");
6110 TEUCHOS_TEST_FOR_EXCEPTION(
6111 X_colMap_host_view.extent (0) < X_domainMap_host_view.extent (0) ||
6112 X_colMap->getLocalLength () < X_domainMap->getLocalLength (),
6113 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: "
6114 "X_colMap has fewer local rows than X_domainMap. "
6115 "X_colMap_host_view.extent(0) = " << X_colMap_host_view.extent (0)
6116 <<
", X_domainMap_host_view.extent(0) = "
6117 << X_domainMap_host_view.extent (0)
6118 <<
", X_colMap->getLocalLength() = " << X_colMap->getLocalLength ()
6119 <<
", and X_domainMap->getLocalLength() = "
6120 << X_domainMap->getLocalLength ()
6121 <<
". This means that Tpetra::MultiVector::offsetViewNonConst "
6122 "is broken. Please report this bug to the Tpetra developers.");
6124 TEUCHOS_TEST_FOR_EXCEPTION(
6125 X_colMap->getNumVectors () != X_domainMap->getNumVectors (),
6126 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: "
6127 "X_colMap has a different number of columns than X_domainMap. "
6128 "X_colMap->getNumVectors() = " << X_colMap->getNumVectors ()
6129 <<
" != X_domainMap->getNumVectors() = "
6130 << X_domainMap->getNumVectors ()
6131 <<
". This means that Tpetra::MultiVector::offsetViewNonConst "
6132 "is broken. Please report this bug to the Tpetra developers.");
6133 #endif // HAVE_TPETRA_DEBUG
6135 if (zeroInitialGuess) {
6137 X_colMap->putScalar (ZERO);
6147 X_colMap->doImport (X, *importer,
INSERT);
6149 copyBackOutput =
true;
6157 B_in = rcpFromRef (B);
6163 RCP<MV> B_in_nonconst = getRowMapMultiVector (B,
true);
6166 }
catch (std::exception& e) {
6167 std::ostringstream os;
6168 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: "
6169 "deep_copy(*B_in_nonconst, B) threw an exception: "
6170 << e.what () <<
".";
6171 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
6173 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
6178 "gaussSeidelCopy: The current implementation requires that B have "
6179 "constant stride. Since B does not have constant stride, we had to "
6180 "copy it into a separate constant-stride multivector. This is a "
6181 "limitation of the current implementation and not your fault, but we "
6182 "still report it as an efficiency warning for your information.");
6185 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
6186 if (! importer.is_null () && sweep > 0) {
6189 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
6193 if (direction != Symmetric) {
6194 if (rowIndices.is_null ()) {
6195 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6200 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6207 if (rowIndices.is_null ()) {
6208 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6216 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6221 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6225 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6234 if (copyBackOutput) {
6237 }
catch (std::exception& e) {
6238 TEUCHOS_TEST_FOR_EXCEPTION(
6239 true, std::runtime_error, prefix <<
"deep_copy(X, *X_domainMap) "
6240 "threw an exception: " << e.what ());
6245 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6247 Teuchos::RCP<CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node> >
6253 const char tfecfFuncName[] =
"convert: ";
6255 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6256 (! this->isFillComplete (), std::runtime_error,
"This matrix (the source "
6257 "of the conversion) is not fill complete. You must first call "
6258 "fillComplete() (possibly with the domain and range Map) without an "
6259 "intervening call to resumeFill(), before you may call this method.");
6260 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6261 (! this->isStaticGraph (), std::logic_error,
"This matrix (the source "
6262 "of the conversion) claims to be fill complete, but does not have a "
6263 "static (i.e., constant) graph. Please report this bug to the Tpetra "
6266 RCP<output_matrix_type> newMatrix
6267 (
new output_matrix_type (this->getCrsGraph ()));
6270 ::Tpetra::Details::copyConvert (newMatrix->lclMatrix_.values,
6271 this->lclMatrix_.values);
6275 newMatrix->fillComplete (this->getDomainMap (), this->getRangeMap ());
6281 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6286 #ifdef HAVE_TPETRA_DEBUG
6287 const char tfecfFuncName[] =
"checkInternalState: ";
6288 const char err[] =
"Internal state is not consistent. "
6289 "Please report this bug to the Tpetra developers.";
6293 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6294 staticGraph_.is_null (),
6295 std::logic_error, err);
6299 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6300 ! myGraph_.is_null () && myGraph_ != staticGraph_,
6301 std::logic_error, err);
6303 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6304 isFillComplete () && ! staticGraph_->isFillComplete (),
6305 std::logic_error, err <<
" Specifically, the matrix is fill complete, "
6306 "but its graph is NOT fill complete.");
6308 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6309 isStorageOptimized () && ! values2D_.is_null (),
6310 std::logic_error, err);
6312 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6313 getProfileType() == StaticProfile && values2D_ != Teuchos::null,
6314 std::logic_error, err);
6316 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6317 getProfileType() != StaticProfile && k_values1D_.extent (0) > 0,
6318 std::logic_error, err);
6321 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6322 staticGraph_->indicesAreAllocated () &&
6323 staticGraph_->getNodeAllocationSize() > 0 &&
6324 staticGraph_->getNodeNumRows() > 0
6325 && values2D_.is_null () &&
6326 k_values1D_.extent (0) == 0,
6327 std::logic_error, err);
6329 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
6330 k_values1D_.extent (0) > 0 && values2D_ != Teuchos::null,
6331 std::logic_error, err <<
" Specifically, k_values1D_ is allocated (has "
6332 "size " << k_values1D_.extent (0) <<
" > 0) and values2D_ is also "
6333 "allocated. CrsMatrix is not suppose to have both a 1-D and a 2-D "
6334 "allocation at the same time.");
6338 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6343 std::ostringstream os;
6345 os <<
"Tpetra::CrsMatrix (Kokkos refactor): {";
6346 if (this->getObjectLabel () !=
"") {
6347 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
6349 if (isFillComplete ()) {
6350 os <<
"isFillComplete: true"
6351 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
6352 << getGlobalNumCols () <<
"]"
6353 <<
", global number of entries: " << getGlobalNumEntries ()
6357 os <<
"isFillComplete: false"
6358 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
6359 << getGlobalNumCols () <<
"]}";
6364 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6368 const Teuchos::EVerbosityLevel verbLevel)
const
6372 using Teuchos::ArrayView;
6373 using Teuchos::Comm;
6375 using Teuchos::TypeNameTraits;
6376 using Teuchos::VERB_DEFAULT;
6377 using Teuchos::VERB_NONE;
6378 using Teuchos::VERB_LOW;
6379 using Teuchos::VERB_MEDIUM;
6380 using Teuchos::VERB_HIGH;
6381 using Teuchos::VERB_EXTREME;
6383 const Teuchos::EVerbosityLevel vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
6385 if (vl == VERB_NONE) {
6390 Teuchos::OSTab tab0 (out);
6392 RCP<const Comm<int> > comm = this->getComm();
6393 const int myRank = comm->getRank();
6394 const int numProcs = comm->getSize();
6396 for (
size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
6399 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
6409 out <<
"Tpetra::CrsMatrix (Kokkos refactor):" << endl;
6411 Teuchos::OSTab tab1 (out);
6414 if (this->getObjectLabel () !=
"") {
6415 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
6418 out <<
"Template parameters:" << endl;
6419 Teuchos::OSTab tab2 (out);
6420 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
6421 <<
"LocalOrdinal: " << TypeNameTraits<LocalOrdinal>::name () << endl
6422 <<
"GlobalOrdinal: " << TypeNameTraits<GlobalOrdinal>::name () << endl
6423 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
6425 if (isFillComplete()) {
6426 out <<
"isFillComplete: true" << endl
6427 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
6428 << getGlobalNumCols () <<
"]" << endl
6429 <<
"Global number of entries: " << getGlobalNumEntries () << endl
6430 << endl <<
"Global max number of entries in a row: "
6431 << getGlobalMaxNumRowEntries () << endl;
6434 out <<
"isFillComplete: false" << endl
6435 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
6436 << getGlobalNumCols () <<
"]" << endl;
6440 if (vl < VERB_MEDIUM) {
6446 out << endl <<
"Row Map:" << endl;
6448 if (getRowMap ().is_null ()) {
6450 out <<
"null" << endl;
6457 getRowMap ()->describe (out, vl);
6462 out <<
"Column Map: ";
6464 if (getColMap ().is_null ()) {
6466 out <<
"null" << endl;
6468 }
else if (getColMap () == getRowMap ()) {
6470 out <<
"same as row Map" << endl;
6476 getColMap ()->describe (out, vl);
6481 out <<
"Domain Map: ";
6483 if (getDomainMap ().is_null ()) {
6485 out <<
"null" << endl;
6487 }
else if (getDomainMap () == getRowMap ()) {
6489 out <<
"same as row Map" << endl;
6491 }
else if (getDomainMap () == getColMap ()) {
6493 out <<
"same as column Map" << endl;
6499 getDomainMap ()->describe (out, vl);
6504 out <<
"Range Map: ";
6506 if (getRangeMap ().is_null ()) {
6508 out <<
"null" << endl;
6510 }
else if (getRangeMap () == getDomainMap ()) {
6512 out <<
"same as domain Map" << endl;
6514 }
else if (getRangeMap () == getRowMap ()) {
6516 out <<
"same as row Map" << endl;
6522 getRangeMap ()->describe (out, vl);
6526 for (
int curRank = 0; curRank < numProcs; ++curRank) {
6527 if (myRank == curRank) {
6528 out <<
"Process rank: " << curRank << endl;
6529 Teuchos::OSTab tab2 (out);
6530 if (! staticGraph_->indicesAreAllocated ()) {
6531 out <<
"Graph indices not allocated" << endl;
6534 out <<
"Number of allocated entries: "
6535 << staticGraph_->getNodeAllocationSize () << endl;
6537 out <<
"Number of entries: " << getNodeNumEntries () << endl
6538 <<
"Max number of entries per row: " << getNodeMaxNumRowEntries ()
6547 if (vl < VERB_HIGH) {
6552 for (
int curRank = 0; curRank < numProcs; ++curRank) {
6553 if (myRank == curRank) {
6554 out << std::setw(width) <<
"Proc Rank"
6555 << std::setw(width) <<
"Global Row"
6556 << std::setw(width) <<
"Num Entries";
6557 if (vl == VERB_EXTREME) {
6558 out << std::setw(width) <<
"(Index,Value)";
6561 for (
size_t r = 0; r < getNodeNumRows (); ++r) {
6562 const size_t nE = getNumEntriesInLocalRow(r);
6563 GlobalOrdinal gid = getRowMap()->getGlobalElement(r);
6564 out << std::setw(width) << myRank
6565 << std::setw(width) << gid
6566 << std::setw(width) << nE;
6567 if (vl == VERB_EXTREME) {
6568 if (isGloballyIndexed()) {
6569 ArrayView<const GlobalOrdinal> rowinds;
6570 ArrayView<const Scalar> rowvals;
6571 getGlobalRowView (gid, rowinds, rowvals);
6572 for (
size_t j = 0; j < nE; ++j) {
6573 out <<
" (" << rowinds[j]
6574 <<
", " << rowvals[j]
6578 else if (isLocallyIndexed()) {
6579 ArrayView<const LocalOrdinal> rowinds;
6580 ArrayView<const Scalar> rowvals;
6581 getLocalRowView (r, rowinds, rowvals);
6582 for (
size_t j=0; j < nE; ++j) {
6583 out <<
" (" << getColMap()->getGlobalElement(rowinds[j])
6584 <<
", " << rowvals[j]
6600 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6613 const row_matrix_type* srcRowMat =
6614 dynamic_cast<const row_matrix_type*
> (&source);
6615 return (srcRowMat != NULL);
6618 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6622 const size_t numSameIDs,
6623 const LocalOrdinal permuteToLIDs[],
6624 const LocalOrdinal permuteFromLIDs[],
6625 const size_t numPermutes)
6628 using Teuchos::Array;
6629 using Teuchos::ArrayView;
6630 typedef LocalOrdinal LO;
6631 typedef GlobalOrdinal GO;
6632 #ifdef HAVE_TPETRA_DEBUG
6634 const char tfecfFuncName[] =
"copyAndPermuteImpl: ";
6635 #endif // HAVE_TPETRA_DEBUG
6637 ProfilingRegion regionCAP (
"Tpetra::CrsMatrix::copyAndPermuteImpl");
6644 const map_type& srcRowMap = * (srcMat.
getRowMap ());
6646 Array<Scalar> rowVals;
6647 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
6648 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
6652 const GO sourceGID = srcRowMap.getGlobalElement (sourceLID);
6653 const GO targetGID = sourceGID;
6656 ArrayView<const GO> rowIndsConstView;
6657 ArrayView<const Scalar> rowValsConstView;
6659 if (sourceIsLocallyIndexed) {
6661 if (rowLength > static_cast<size_t> (rowInds.size())) {
6662 rowInds.resize (rowLength);
6663 rowVals.resize (rowLength);
6667 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
6668 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
6673 size_t checkRowLength = 0;
6674 srcMat.
getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
6676 #ifdef HAVE_TPETRA_DEBUG
6677 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
6678 std::logic_error,
"For global row index " << sourceGID <<
", the source"
6679 " matrix's getNumEntriesInGlobalRow() method returns a row length of "
6680 << rowLength <<
", but the getGlobalRowCopy() method reports that "
6681 "the row length is " << checkRowLength <<
". Please report this bug "
6682 "to the Tpetra developers.");
6683 #endif // HAVE_TPETRA_DEBUG
6685 rowIndsConstView = rowIndsView.view (0, rowLength);
6686 rowValsConstView = rowValsView.view (0, rowLength);
6693 if (this->isStaticGraph ()) {
6696 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
REPLACE);
6702 combineGlobalValues (targetGID, rowIndsConstView, rowValsConstView,
INSERT);
6709 const map_type& tgtRowMap = * (this->getRowMap ());
6710 for (
size_t p = 0; p < numPermutes; ++p) {
6711 const GO sourceGID = srcRowMap.getGlobalElement (permuteFromLIDs[p]);
6712 const GO targetGID = tgtRowMap.getGlobalElement (permuteToLIDs[p]);
6715 ArrayView<const GO> rowIndsConstView;
6716 ArrayView<const Scalar> rowValsConstView;
6718 if (sourceIsLocallyIndexed) {
6720 if (rowLength > static_cast<size_t> (rowInds.size ())) {
6721 rowInds.resize (rowLength);
6722 rowVals.resize (rowLength);
6726 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
6727 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
6732 size_t checkRowLength = 0;
6733 srcMat.
getGlobalRowCopy (sourceGID, rowIndsView, rowValsView, checkRowLength);
6735 #ifdef HAVE_TPETRA_DEBUG
6736 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(rowLength != checkRowLength,
6737 std::logic_error,
"For the source matrix's global row index "
6738 << sourceGID <<
", the source matrix's getNumEntriesInGlobalRow() "
6739 "method returns a row length of " << rowLength <<
", but the "
6740 "getGlobalRowCopy() method reports that the row length is "
6741 << checkRowLength <<
". Please report this bug to the Tpetra "
6743 #endif // HAVE_TPETRA_DEBUG
6745 rowIndsConstView = rowIndsView.view (0, rowLength);
6746 rowValsConstView = rowValsView.view (0, rowLength);
6753 if (isStaticGraph()) {
6754 this->combineGlobalValues (targetGID, rowIndsConstView,
6758 this->combineGlobalValues (targetGID, rowIndsConstView,
6759 rowValsConstView,
INSERT);
6764 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6766 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6767 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
6769 #else // TPETRA_ENABLE_DEPRECATED_CODE
6771 #endif // TPETRA_ENABLE_DEPRECATED_CODE
6772 (
const SrcDistObject& srcObj,
6773 const size_t numSameIDs,
6774 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs,
6775 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs)
6782 const char tfecfFuncName[] =
"copyAndPermute: ";
6783 ProfilingRegion regionCAP (
"Tpetra::CrsMatrix::copyAndPermute");
6786 std::unique_ptr<std::string> prefix;
6789 auto map = this->getMap ();
6790 if (! map.is_null ()) {
6791 auto comm = map->getComm ();
6792 if (! comm.is_null ()) {
6793 myRank = comm->getRank ();
6796 prefix = [myRank] () {
6797 std::ostringstream pfxStrm;
6798 pfxStrm <<
"Proc " << myRank <<
": Tpetra::CrsMatrix::copyAndPermute: ";
6799 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
6801 std::ostringstream os;
6802 os << *prefix << endl
6807 std::cerr << os.str ();
6810 const auto numPermute = permuteToLIDs.extent (0);
6811 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6812 (numPermute != permuteFromLIDs.extent (0),
6813 std::invalid_argument,
"permuteToLIDs.extent(0) = "
6814 << numPermute <<
"!= permuteFromLIDs.extent(0) = "
6815 << permuteFromLIDs.extent (0) <<
".");
6817 TEUCHOS_ASSERT( ! permuteToLIDs.need_sync_host () );
6818 auto permuteToLIDs_h = permuteToLIDs.view_host ();
6819 TEUCHOS_ASSERT( ! permuteFromLIDs.need_sync_host () );
6820 auto permuteFromLIDs_h = permuteFromLIDs.view_host ();
6825 const RMT& srcMat =
dynamic_cast<const RMT&
> (srcObj);
6828 std::ostringstream os;
6829 os << *prefix <<
"Call copyAndPermuteImpl" << endl;
6830 std::cerr << os.str ();
6832 this->copyAndPermuteImpl (srcMat, numSameIDs, permuteToLIDs_h.data (),
6833 permuteFromLIDs_h.data (), numPermute);
6836 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6838 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6839 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
6841 #else // TPETRA_ENABLE_DEPRECATED_CODE
6843 #endif // TPETRA_ENABLE_DEPRECATED_CODE
6844 (
const SrcDistObject& source,
6845 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
6846 Kokkos::DualView<char*, buffer_device_type>& exports,
6847 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
6848 size_t& constantNumPackets,
6849 Distributor& distor)
6853 using Teuchos::outArg;
6854 using Teuchos::REDUCE_MAX;
6855 using Teuchos::reduceAll;
6857 typedef LocalOrdinal LO;
6858 typedef GlobalOrdinal GO;
6859 const char tfecfFuncName[] =
"packAndPrepare: ";
6860 ProfilingRegion regionPAP (
"Tpetra::CrsMatrix::packAndPrepare");
6866 Teuchos::RCP<const Teuchos::Comm<int> > pComm = this->getComm ();
6867 if (pComm.is_null ()) {
6870 const Teuchos::Comm<int>& comm = *pComm;
6871 const int myRank = comm.getSize ();
6873 std::unique_ptr<std::string> prefix;
6875 prefix = [myRank] () {
6876 std::ostringstream pfxStrm;
6877 pfxStrm <<
"Proc " << myRank <<
": Tpetra::CrsMatrix::packAndPrepare: ";
6878 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
6880 std::ostringstream os;
6881 os << *prefix <<
"Start" << endl
6891 std::cerr << os.str ();
6914 std::ostringstream msg;
6917 using crs_matrix_type = CrsMatrix<Scalar, LO, GO, Node>;
6918 const crs_matrix_type* srcCrsMat =
6919 dynamic_cast<const crs_matrix_type*
> (&source);
6920 if (srcCrsMat !=
nullptr) {
6922 std::ostringstream os;
6923 os << *prefix <<
"Source matrix same (CrsMatrix) type as target; "
6924 "calling packNew" << endl;
6925 std::cerr << os.str ();
6928 srcCrsMat->packNew (exportLIDs, exports, numPacketsPerLID,
6929 constantNumPackets, distor);
6931 catch (std::exception& e) {
6933 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
6937 using Kokkos::HostSpace;
6938 using Kokkos::subview;
6939 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
6940 using range_type = Kokkos::pair<size_t, size_t>;
6943 std::ostringstream os;
6944 os << *prefix <<
"Source matrix NOT same (CrsMatrix) type as target"
6946 std::cerr << os.str ();
6949 using row_matrix_type = RowMatrix<Scalar, LO, GO, Node>;
6950 const row_matrix_type* srcRowMat =
6951 dynamic_cast<const row_matrix_type*
> (&source);
6952 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6953 (srcRowMat ==
nullptr, std::invalid_argument,
6954 "The source object of the Import or Export operation is neither a "
6955 "CrsMatrix (with the same template parameters as the target object), "
6956 "nor a RowMatrix (with the same first four template parameters as the "
6967 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
6968 auto exportLIDs_h = exportLIDs.view_host ();
6969 Teuchos::ArrayView<const LO> exportLIDs_av (exportLIDs_h.data (),
6970 exportLIDs_h.size ());
6974 Teuchos::Array<char> exports_a;
6980 numPacketsPerLID.clear_sync_state ();
6981 numPacketsPerLID.modify_host ();
6982 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
6983 Teuchos::ArrayView<size_t> numPacketsPerLID_av (numPacketsPerLID_h.data (),
6984 numPacketsPerLID_h.size ());
6989 srcRowMat->pack (exportLIDs_av, exports_a, numPacketsPerLID_av,
6990 constantNumPackets, distor);
6992 catch (std::exception& e) {
6994 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
6998 const size_t newAllocSize =
static_cast<size_t> (exports_a.size ());
6999 if (static_cast<size_t> (exports.extent (0)) < newAllocSize) {
7000 const std::string oldLabel = exports.d_view.label ();
7001 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
7002 exports = exports_type (newLabel, newAllocSize);
7007 exports.modify_host();
7009 auto exports_h = exports.view_host ();
7010 auto exports_h_sub = subview (exports_h, range_type (0, newAllocSize));
7014 typedef typename exports_type::t_host::execution_space HES;
7015 typedef Kokkos::Device<HES, HostSpace> host_device_type;
7016 Kokkos::View<const char*, host_device_type>
7017 exports_a_kv (exports_a.getRawPtr (), newAllocSize);
7023 reduceAll<int, int> (comm, REDUCE_MAX, lclBad, outArg (gblBad));
7026 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7027 (
true, std::logic_error,
"packNew() or pack() threw an exception on "
7028 "one or more participating processes.");
7032 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7033 (lclBad != 0, std::logic_error,
"packNew threw an exception on one "
7034 "or more participating processes. Here is this process' error "
7035 "message: " << msg.str ());
7039 std::ostringstream os;
7040 os << *prefix <<
"packAndPrepare: Done!" << endl
7050 std::cerr << os.str ();
7054 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7056 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7057 packRow (
char exports[],
7058 const size_t offset,
7059 const size_t numEnt,
7060 const GlobalOrdinal gidsIn[],
7061 const impl_scalar_type valsIn[],
7062 const size_t numBytesPerValue)
const
7065 using Kokkos::subview;
7067 typedef LocalOrdinal LO;
7068 typedef GlobalOrdinal GO;
7069 typedef impl_scalar_type ST;
7070 typedef typename View<int*, device_type>::HostMirror::execution_space HES;
7078 const LO numEntLO =
static_cast<size_t> (numEnt);
7080 const size_t numEntBeg = offset;
7081 const size_t numEntLen = PackTraits<LO, HES>::packValueCount (numEntLO);
7082 const size_t gidsBeg = numEntBeg + numEntLen;
7083 const size_t gidsLen = numEnt * PackTraits<GO, HES>::packValueCount (gid);
7084 const size_t valsBeg = gidsBeg + gidsLen;
7085 const size_t valsLen = numEnt * numBytesPerValue;
7087 char*
const numEntOut = exports + numEntBeg;
7088 char*
const gidsOut = exports + gidsBeg;
7089 char*
const valsOut = exports + valsBeg;
7091 size_t numBytesOut = 0;
7093 numBytesOut += PackTraits<LO, HES>::packValue (numEntOut, numEntLO);
7096 Kokkos::pair<int, size_t> p;
7097 p = PackTraits<GO, HES>::packArray (gidsOut, gidsIn, numEnt);
7098 errorCode += p.first;
7099 numBytesOut += p.second;
7101 p = PackTraits<ST, HES>::packArray (valsOut, valsIn, numEnt);
7102 errorCode += p.first;
7103 numBytesOut += p.second;
7106 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
7107 TEUCHOS_TEST_FOR_EXCEPTION
7108 (numBytesOut != expectedNumBytes, std::logic_error,
"packRow: "
7109 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
7110 << expectedNumBytes <<
".");
7111 TEUCHOS_TEST_FOR_EXCEPTION
7112 (errorCode != 0, std::runtime_error,
"packRow: "
7113 "PackTraits::packArray returned a nonzero error code");
7118 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7120 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7121 unpackRow (GlobalOrdinal gidsOut[],
7122 impl_scalar_type valsOut[],
7123 const char imports[],
7124 const size_t offset,
7125 const size_t numBytes,
7126 const size_t numEnt,
7127 const size_t numBytesPerValue)
7130 using Kokkos::subview;
7132 typedef LocalOrdinal LO;
7133 typedef GlobalOrdinal GO;
7134 typedef impl_scalar_type ST;
7135 typedef typename View<int*, device_type>::HostMirror::execution_space HES;
7137 if (numBytes == 0) {
7140 const int myRank = this->getMap ()->getComm ()->getRank ();
7141 TEUCHOS_TEST_FOR_EXCEPTION
7142 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
7143 "unpackRow: The number of bytes to unpack numBytes=0, but the "
7144 "number of entries to unpack (as reported by numPacketsPerLID) "
7145 "for this row numEnt=" << numEnt <<
" != 0.");
7150 if (numEnt == 0 && numBytes != 0) {
7151 const int myRank = this->getMap ()->getComm ()->getRank ();
7152 TEUCHOS_TEST_FOR_EXCEPTION
7153 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
7154 "unpackRow: The number of entries to unpack (as reported by "
7155 "numPacketsPerLID) numEnt=0, but the number of bytes to unpack "
7156 "numBytes=" << numBytes <<
" != 0.");
7162 const size_t numEntBeg = offset;
7163 const size_t numEntLen = PackTraits<LO, HES>::packValueCount (lid);
7164 const size_t gidsBeg = numEntBeg + numEntLen;
7165 const size_t gidsLen = numEnt * PackTraits<GO, HES>::packValueCount (gid);
7166 const size_t valsBeg = gidsBeg + gidsLen;
7167 const size_t valsLen = numEnt * numBytesPerValue;
7169 const char*
const numEntIn = imports + numEntBeg;
7170 const char*
const gidsIn = imports + gidsBeg;
7171 const char*
const valsIn = imports + valsBeg;
7173 size_t numBytesOut = 0;
7176 numBytesOut += PackTraits<LO, HES>::unpackValue (numEntOut, numEntIn);
7177 if (static_cast<size_t> (numEntOut) != numEnt ||
7178 numEntOut == static_cast<LO> (0)) {
7179 const int myRank = this->getMap ()->getComm ()->getRank ();
7180 std::ostringstream os;
7181 os <<
"(Proc " << myRank <<
") CrsMatrix::unpackRow: ";
7182 bool firstErrorCondition =
false;
7183 if (static_cast<size_t> (numEntOut) != numEnt) {
7184 os <<
"Number of entries from numPacketsPerLID numEnt=" << numEnt
7185 <<
" does not equal number of entries unpacked from imports "
7186 "buffer numEntOut=" << numEntOut <<
".";
7187 firstErrorCondition =
true;
7189 if (numEntOut == static_cast<LO> (0)) {
7190 if (firstErrorCondition) {
7193 os <<
"Number of entries unpacked from imports buffer numEntOut=0, "
7194 "but number of bytes to unpack for this row numBytes=" << numBytes
7195 <<
" != 0. This should never happen, since packRow should only "
7196 "ever pack rows with a nonzero number of entries. In this case, "
7197 "the number of entries from numPacketsPerLID is numEnt=" << numEnt
7200 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, os.str ());
7204 Kokkos::pair<int, size_t> p;
7205 p = PackTraits<GO, HES>::unpackArray (gidsOut, gidsIn, numEnt);
7206 errorCode += p.first;
7207 numBytesOut += p.second;
7209 p = PackTraits<ST, HES>::unpackArray (valsOut, valsIn, numEnt);
7210 errorCode += p.first;
7211 numBytesOut += p.second;
7214 TEUCHOS_TEST_FOR_EXCEPTION
7215 (numBytesOut != numBytes, std::logic_error,
"unpackRow: numBytesOut = "
7216 << numBytesOut <<
" != numBytes = " << numBytes <<
".");
7218 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
7219 TEUCHOS_TEST_FOR_EXCEPTION
7220 (numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: "
7221 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
7222 << expectedNumBytes <<
".");
7224 TEUCHOS_TEST_FOR_EXCEPTION
7225 (errorCode != 0, std::runtime_error,
"unpackRow: "
7226 "PackTraits::unpackArray returned a nonzero error code");
7231 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7233 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7234 allocatePackSpaceNew (Kokkos::DualView<char*, buffer_device_type>& exports,
7235 size_t& totalNumEntries,
7236 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs)
const
7240 typedef impl_scalar_type IST;
7241 typedef LocalOrdinal LO;
7242 typedef GlobalOrdinal GO;
7249 std::unique_ptr<std::string> prefix;
7252 auto map = this->getMap ();
7253 if (! map.is_null ()) {
7254 auto comm = map->getComm ();
7255 if (! comm.is_null ()) {
7256 myRank = comm->getRank ();
7260 prefix = [myRank] () {
7261 std::ostringstream pfxStrm;
7262 pfxStrm <<
"Proc " << myRank <<
": Tpetra::CrsMatrix::allocatePackSpaceNew: ";
7263 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
7266 std::ostringstream os;
7267 os << *prefix <<
"Before:"
7275 std::cerr << os.str ();
7280 const LO numExportLIDs =
static_cast<LO
> (exportLIDs.extent (0));
7282 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
7283 auto exportLIDs_h = exportLIDs.view_host ();
7286 totalNumEntries = 0;
7287 for (LO i = 0; i < numExportLIDs; ++i) {
7288 const LO lclRow = exportLIDs_h[i];
7289 size_t curNumEntries = this->getNumEntriesInLocalRow (lclRow);
7292 if (curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7295 totalNumEntries += curNumEntries;
7306 const size_t allocSize =
7307 static_cast<size_t> (numExportLIDs) *
sizeof (LO) +
7308 totalNumEntries * (
sizeof (IST) +
sizeof (GO));
7309 if (static_cast<size_t> (exports.extent (0)) < allocSize) {
7310 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
7312 const std::string oldLabel = exports.d_view.label ();
7313 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
7314 exports = exports_type (newLabel, allocSize);
7318 std::ostringstream os;
7319 os << *prefix <<
"After:"
7327 std::cerr << os.str ();
7331 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7334 packNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7335 Kokkos::DualView<char*, buffer_device_type>& exports,
7336 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7337 size_t& constantNumPackets,
7341 if (this->isStaticGraph ()) {
7342 using ::Tpetra::Details::packCrsMatrixNew;
7343 packCrsMatrixNew (*
this, exports, numPacketsPerLID, exportLIDs,
7344 constantNumPackets, dist);
7347 this->packNonStaticNew (exportLIDs, exports, numPacketsPerLID,
7348 constantNumPackets, dist);
7352 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7355 packNonStaticNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7356 Kokkos::DualView<char*, buffer_device_type>& exports,
7357 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7358 size_t& constantNumPackets,
7366 typedef LocalOrdinal LO;
7367 typedef GlobalOrdinal GO;
7368 typedef impl_scalar_type ST;
7369 typedef typename View<int*, device_type>::HostMirror::execution_space HES;
7370 const char tfecfFuncName[] =
"packNonStaticNew: ";
7376 std::unique_ptr<std::string> prefix;
7379 auto map = this->getMap ();
7380 if (! map.is_null ()) {
7381 auto comm = map->getComm ();
7382 if (! comm.is_null ()) {
7383 myRank = comm->getRank ();
7387 prefix = [myRank] () {
7388 std::ostringstream pfxStrm;
7389 pfxStrm <<
"(Proc " << myRank <<
") ";
7390 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
7393 std::ostringstream os;
7394 os << *prefix <<
"Tpetra::CrsMatrix::packNonStaticNew:" << endl;
7395 std::cerr << os.str ();
7398 const size_t numExportLIDs =
static_cast<size_t> (exportLIDs.extent (0));
7399 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7400 (numExportLIDs != static_cast<size_t> (numPacketsPerLID.extent (0)),
7401 std::invalid_argument,
"exportLIDs.size() = " << numExportLIDs
7402 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.extent (0)
7408 constantNumPackets = 0;
7413 size_t totalNumEntries = 0;
7414 this->allocatePackSpaceNew (exports, totalNumEntries, exportLIDs);
7415 const size_t bufSize =
static_cast<size_t> (exports.extent (0));
7418 exports.clear_sync_state();
7419 exports.modify_host();
7420 auto exports_h = exports.view_host ();
7422 std::ostringstream os;
7423 os << *prefix <<
"After marking exports as modified on host, "
7425 std::cerr << os.str ();
7429 auto exportLIDs_h = exportLIDs.view_host ();
7432 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->clear_sync_state();
7433 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->modify_host();
7434 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
7440 for (
size_t i = 0; i < numExportLIDs; ++i) {
7441 const LO lclRow = exportLIDs_h[i];
7444 numEnt = this->getNumEntriesInLocalRow (lclRow);
7451 numPacketsPerLID_h[i] = 0;
7456 View<GO*, HES> gidsIn_k;
7459 gidsIn_k = PackTraits<GO, HES>::allocateArray(gid, numEnt,
"gids");
7462 Teuchos::ArrayView<const Scalar> valsIn;
7463 if (this->isLocallyIndexed ()) {
7467 Teuchos::ArrayView<const LO> lidsIn;
7468 this->getLocalRowView (lclRow, lidsIn, valsIn);
7469 const map_type& colMap = * (this->getColMap ());
7470 for (
size_t k = 0; k < numEnt; ++k) {
7471 gidsIn_k[k] = colMap.getGlobalElement (lidsIn[k]);
7474 else if (this->isGloballyIndexed ()) {
7480 Teuchos::ArrayView<const GO> gblIndView;;
7481 const map_type& rowMap = * (this->getRowMap ());
7482 const GO gblRow = rowMap.getGlobalElement (lclRow);
7483 this->getGlobalRowView (gblRow, gblIndView, valsIn);
7484 for (
size_t k = 0; k < numEnt; ++k) {
7485 gidsIn_k[k] = gblIndView[k];
7492 typename HES::device_type outputDevice;
7495 reinterpret_cast<const ST*> (valsIn.getRawPtr ()),
7498 const size_t numBytesPerValue =
7499 PackTraits<ST,HES>::packValueCount (valsIn[0]);
7500 const size_t numBytes =
7501 this->packRow (exports_h.data (), offset, numEnt, gidsIn_k.data (),
7502 valsIn_k.data (), numBytesPerValue);
7503 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7504 (offset > bufSize || offset + numBytes > bufSize, std::logic_error,
7505 "First invalid offset into 'exports' pack buffer at index i = " << i
7506 <<
". exportLIDs_h[i]: " << exportLIDs_h[i] <<
", bufSize: " <<
7507 bufSize <<
", offset: " << offset <<
", numBytes: " << numBytes <<
7512 numPacketsPerLID_h[i] = numBytes;
7517 std::ostringstream os;
7518 os << *prefix <<
"Tpetra::CrsMatrix::packNonStaticNew: After:" << endl
7525 std::cerr << os.str ();
7529 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7531 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7532 combineGlobalValuesRaw (
const LocalOrdinal lclRow,
7533 const LocalOrdinal numEnt,
7534 const impl_scalar_type vals[],
7535 const GlobalOrdinal cols[],
7538 typedef GlobalOrdinal GO;
7543 const GO gblRow = this->myGraph_->rowMap_->getGlobalElement (lclRow);
7544 Teuchos::ArrayView<const GO> cols_av (numEnt == 0 ? NULL : cols, numEnt);
7545 Teuchos::ArrayView<const Scalar> vals_av (numEnt == 0 ? NULL : reinterpret_cast<const Scalar*> (vals), numEnt);
7550 this->combineGlobalValues (gblRow, cols_av, vals_av, combineMode);
7554 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7556 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7557 combineGlobalValues (
const GlobalOrdinal globalRowIndex,
7558 const Teuchos::ArrayView<const GlobalOrdinal>& columnIndices,
7559 const Teuchos::ArrayView<const Scalar>& values,
7562 const char tfecfFuncName[] =
"combineGlobalValues: ";
7564 if (isStaticGraph ()) {
7568 if (combineMode ==
ADD) {
7569 sumIntoGlobalValues (globalRowIndex, columnIndices, values);
7571 else if (combineMode ==
REPLACE) {
7572 replaceGlobalValues (globalRowIndex, columnIndices, values);
7574 else if (combineMode ==
ABSMAX) {
7575 using ::Tpetra::Details::AbsMax;
7577 this->
template transformGlobalValues<AbsMax<Scalar> > (globalRowIndex,
7581 else if (combineMode ==
INSERT) {
7582 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7583 isStaticGraph () && combineMode ==
INSERT, std::invalid_argument,
7584 "INSERT combine mode is not allowed if the matrix has a static graph "
7585 "(i.e., was constructed with the CrsMatrix constructor that takes a "
7586 "const CrsGraph pointer).");
7589 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7590 true, std::logic_error,
"Invalid combine mode; should never get "
7591 "here! Please report this bug to the Tpetra developers.");
7595 if (combineMode ==
ADD || combineMode ==
INSERT) {
7603 this->insertGlobalValuesFiltered (globalRowIndex, columnIndices,
7606 catch (std::exception& e) {
7607 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7608 (
true, std::runtime_error, std::endl
7609 <<
"insertGlobalValuesFiltered(" << globalRowIndex <<
", "
7610 << std::endl << Teuchos::toString (columnIndices) <<
", "
7611 << std::endl << Teuchos::toString (values)
7612 <<
") threw an exception: " << std::endl << e.what ());
7624 else if (combineMode ==
ABSMAX) {
7625 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7626 ! isStaticGraph () && combineMode ==
ABSMAX, std::logic_error,
7627 "ABSMAX combine mode when the matrix has a dynamic graph is not yet "
7630 else if (combineMode ==
REPLACE) {
7631 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7632 ! isStaticGraph () && combineMode ==
REPLACE, std::logic_error,
7633 "REPLACE combine mode when the matrix has a dynamic graph is not yet "
7637 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7638 true, std::logic_error,
"Should never get here! Please report this "
7639 "bug to the Tpetra developers.");
7644 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7646 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7647 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
7649 #else // TPETRA_ENABLE_DEPRECATED_CODE
7651 #endif // TPETRA_ENABLE_DEPRECATED_CODE
7652 (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& importLIDs,
7653 Kokkos::DualView<char*, buffer_device_type> imports,
7654 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7655 const size_t constantNumPackets,
7656 Distributor& distor,
7662 const char tfecfFuncName[] =
"unpackAndCombine: ";
7663 ProfilingRegion regionUAC (
"Tpetra::CrsMatrix::unpackAndCombine");
7667 constexpr
int numValidModes = 5;
7670 const char* validModeNames[numValidModes] =
7671 {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT",
"ZERO"};
7673 std::unique_ptr<std::string> prefix;
7676 auto map = this->getMap ();
7677 if (! map.is_null ()) {
7678 auto comm = map->getComm ();
7679 if (! comm.is_null ()) {
7680 myRank = comm->getRank ();
7683 prefix = [myRank] () {
7684 std::ostringstream pfxStrm;
7685 pfxStrm <<
"Proc " << myRank <<
": Tpetra::CrsMatrix::unpackAndCombine: ";
7686 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
7688 std::ostringstream os;
7689 os << *prefix <<
"Start:" << endl
7699 << *prefix <<
" constantNumPackets: " << constantNumPackets
7703 std::cerr << os.str ();
7707 if (std::find (validModes, validModes+numValidModes, combineMode) ==
7708 validModes+numValidModes) {
7709 std::ostringstream os;
7710 os <<
"Invalid combine mode. Valid modes are {";
7711 for (
int k = 0; k < numValidModes; ++k) {
7712 os << validModeNames[k];
7713 if (k < numValidModes - 1) {
7718 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7719 (
true, std::invalid_argument, os.str ());
7723 if (combineMode ==
ZERO) {
7728 using Teuchos::reduceAll;
7729 std::unique_ptr<std::ostringstream> msg (
new std::ostringstream ());
7732 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
7733 constantNumPackets, distor, combineMode);
7734 }
catch (std::exception& e) {
7739 const Teuchos::Comm<int>& comm = * (this->getComm ());
7740 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
7741 lclBad, Teuchos::outArg (gblBad));
7747 std::ostringstream os;
7748 os <<
"(Proc " << comm.getRank () <<
") " << msg->str () << endl;
7749 msg = std::unique_ptr<std::ostringstream> (
new std::ostringstream ());
7750 ::Tpetra::Details::gathervPrint (*msg, os.str (), comm);
7751 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7752 (
true, std::logic_error, std::endl <<
"unpackAndCombineImpl "
7753 "threw an exception on one or more participating processes: "
7754 << endl << msg->str ());
7758 this->unpackAndCombineImpl (importLIDs, imports, numPacketsPerLID,
7759 constantNumPackets, distor, combineMode);
7763 std::ostringstream os;
7764 os << *prefix <<
"Done!" << endl
7774 std::cerr << os.str ();
7778 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7780 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7781 unpackAndCombineImpl (
const Kokkos::DualView<
const local_ordinal_type*,
7782 buffer_device_type>& importLIDs,
7783 const Kokkos::DualView<
const char*,
7784 buffer_device_type>& imports,
7785 const Kokkos::DualView<
const size_t*,
7786 buffer_device_type>& numPacketsPerLID,
7787 const size_t constantNumPackets,
7788 Distributor & distor,
7794 if (this->isStaticGraph ()) {
7795 using ::Tpetra::Details::unpackCrsMatrixAndCombineNew;
7796 unpackCrsMatrixAndCombineNew (*
this, imports, numPacketsPerLID,
7797 importLIDs, constantNumPackets,
7798 distor, combineMode, atomic);
7801 this->unpackAndCombineImplNonStatic (importLIDs, imports,
7804 distor, combineMode);
7808 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7810 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7811 unpackAndCombineImplNonStatic (
const Kokkos::DualView<
const local_ordinal_type*,
7812 buffer_device_type>& importLIDs,
7813 const Kokkos::DualView<
const char*,
7814 buffer_device_type>& imports,
7815 const Kokkos::DualView<
const size_t*,
7816 buffer_device_type>& numPacketsPerLID,
7822 using Kokkos::subview;
7823 using Kokkos::MemoryUnmanaged;
7828 typedef LocalOrdinal LO;
7829 typedef GlobalOrdinal GO;
7830 typedef impl_scalar_type ST;
7831 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
7832 typedef typename View<int*, device_type>::HostMirror::execution_space HES;
7833 typedef std::pair<typename View<int*, HES>::size_type,
7834 typename View<int*, HES>::size_type> pair_type;
7835 typedef View<GO*, HES, MemoryUnmanaged> gids_out_type;
7836 typedef View<ST*, HES, MemoryUnmanaged> vals_out_type;
7837 const char tfecfFuncName[] =
"unpackAndCombineImplNonStatic: ";
7843 std::unique_ptr<std::string> prefix;
7846 auto map = this->getMap ();
7847 if (! map.is_null ()) {
7848 auto comm = map->getComm ();
7849 if (! comm.is_null ()) {
7850 myRank = comm->getRank ();
7854 prefix = [myRank] () {
7855 std::ostringstream pfxStrm;
7856 pfxStrm <<
"Proc " << myRank <<
": Tpetra::CrsMatrix::"
7857 "unpackAndCombineImplNonStatic: ";
7858 return std::unique_ptr<std::string> (
new std::string (pfxStrm.str ()));
7861 std::ostringstream os;
7862 os << *prefix << endl;
7863 std::cerr << os.str ();
7866 const size_type numImportLIDs = importLIDs.extent (0);
7867 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7868 (numImportLIDs != static_cast<size_type> (numPacketsPerLID.extent (0)),
7869 std::invalid_argument,
"importLIDs.size() = " << numImportLIDs
7870 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.extent (0)
7872 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7874 combineMode !=
ABSMAX && combineMode !=
ZERO, std::invalid_argument,
7875 "Invalid CombineMode value " << combineMode <<
". Valid "
7876 <<
"values include ADD, INSERT, REPLACE, ABSMAX, and ZERO.");
7877 if (combineMode ==
ZERO || numImportLIDs == 0) {
7884 imports_nc.sync_host ();
7886 auto imports_h = imports.view_host ();
7891 numPacketsPerLID_nc.sync_host ();
7893 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
7895 TEUCHOS_ASSERT( ! importLIDs.need_sync_host () );
7896 auto importLIDs_h = importLIDs.view_host ();
7898 size_t numBytesPerValue;
7909 numBytesPerValue = PackTraits<ST, HES>::packValueCount (val);
7914 size_t maxRowNumEnt = 0;
7915 for (size_type i = 0; i < numImportLIDs; ++i) {
7916 const size_t numBytes = numPacketsPerLID_h[i];
7917 if (numBytes == 0) {
7921 #ifdef HAVE_TPETRA_DEBUG
7922 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7923 (offset + numBytes > static_cast<size_t> (imports_h.extent (0)),
7924 std::logic_error,
"At local row index importLIDs_h[i=" << i <<
"]="
7925 << importLIDs_h[i] <<
", offset (=" << offset <<
") + numBytes (="
7926 << numBytes <<
") > imports_h.extent(0)="
7927 << imports_h.extent (0) <<
".");
7928 #endif // HAVE_TPETRA_DEBUG
7932 #ifdef HAVE_TPETRA_DEBUG
7933 const size_t theNumBytes = PackTraits<LO, HES>::packValueCount (numEntLO);
7934 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7935 (theNumBytes > numBytes, std::logic_error,
"theNumBytes = "
7936 << theNumBytes <<
" > numBytes = " << numBytes <<
".");
7937 #endif // HAVE_TPETRA_DEBUG
7939 const char*
const inBuf = imports_h.data () + offset;
7940 const size_t actualNumBytes =
7941 PackTraits<LO, HES>::unpackValue (numEntLO, inBuf);
7943 #ifdef HAVE_TPETRA_DEBUG
7944 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7945 (actualNumBytes > numBytes, std::logic_error,
"At i = " << i
7946 <<
", actualNumBytes=" << actualNumBytes
7947 <<
" > numBytes=" << numBytes <<
".");
7948 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7949 (numEntLO == 0, std::logic_error,
"At local row index importLIDs_h[i="
7950 << i <<
"]=" << importLIDs_h[i] <<
", the number of entries read "
7951 "from the packed data is numEntLO=" << numEntLO <<
", but numBytes="
7952 << numBytes <<
" != 0.");
7954 (void) actualNumBytes;
7955 #endif // HAVE_TPETRA_DEBUG
7957 maxRowNumEnt = std::max (static_cast<size_t> (numEntLO), maxRowNumEnt);
7965 View<GO*, HES> gblColInds;
7966 View<LO*, HES> lclColInds;
7967 View<ST*, HES> vals;
7980 gblColInds = PackTraits<GO, HES>::allocateArray (gid, maxRowNumEnt,
"gids");
7981 lclColInds = PackTraits<LO, HES>::allocateArray (lid, maxRowNumEnt,
"lids");
7982 vals = PackTraits<ST, HES>::allocateArray (val, maxRowNumEnt,
"vals");
7986 for (size_type i = 0; i < numImportLIDs; ++i) {
7987 const size_t numBytes = numPacketsPerLID_h[i];
7988 if (numBytes == 0) {
7992 const char*
const inBuf = imports_h.data () + offset;
7993 const size_t actualNumBytes = PackTraits<LO, HES>::unpackValue (numEntLO, inBuf);
7994 (void) actualNumBytes;
7996 const size_t numEnt =
static_cast<size_t>(numEntLO);;
7997 const LO lclRow = importLIDs_h[i];
7999 gids_out_type gidsOut = subview (gblColInds, pair_type (0, numEnt));
8000 vals_out_type valsOut = subview (vals, pair_type (0, numEnt));
8002 const size_t numBytesOut =
8003 unpackRow (gidsOut.data (), valsOut.data (), imports_h.data (),
8004 offset, numBytes, numEnt, numBytesPerValue);
8005 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8006 (numBytes != numBytesOut, std::logic_error,
"At i = " << i <<
", "
8007 <<
"numBytes = " << numBytes <<
" != numBytesOut = " << numBytesOut
8010 const ST*
const valsRaw =
const_cast<const ST*
> (valsOut.data ());
8011 const GO*
const gidsRaw =
const_cast<const GO*
> (gidsOut.data ());
8012 this->combineGlobalValuesRaw (lclRow, numEnt, valsRaw, gidsRaw, combineMode);
8019 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8020 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8023 const bool force)
const
8025 using Teuchos::null;
8029 TEUCHOS_TEST_FOR_EXCEPTION(
8030 ! this->hasColMap (), std::runtime_error,
"Tpetra::CrsMatrix::getColumn"
8031 "MapMultiVector: You may only call this method if the matrix has a "
8032 "column Map. If the matrix does not yet have a column Map, you should "
8033 "first call fillComplete (with domain and range Map if necessary).");
8037 TEUCHOS_TEST_FOR_EXCEPTION(
8038 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
8039 "CrsMatrix::getColumnMapMultiVector: You may only call this method if "
8040 "this matrix's graph is fill complete.");
8043 RCP<const import_type> importer = this->getGraph ()->getImporter ();
8044 RCP<const map_type> colMap = this->getColMap ();
8057 if (! importer.is_null () || force) {
8058 if (importMV_.is_null () || importMV_->getNumVectors () != numVecs) {
8059 X_colMap = rcp (
new MV (colMap, numVecs));
8062 importMV_ = X_colMap;
8065 X_colMap = importMV_;
8076 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8077 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8080 const bool force)
const
8082 using Teuchos::null;
8088 TEUCHOS_TEST_FOR_EXCEPTION(
8089 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
8090 "CrsMatrix::getRowMapMultiVector: You may only call this method if this "
8091 "matrix's graph is fill complete.");
8094 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
8098 RCP<const map_type> rowMap = this->getRowMap ();
8110 if (! exporter.is_null () || force) {
8111 if (exportMV_.is_null () || exportMV_->getNumVectors () != numVecs) {
8112 Y_rowMap = rcp (
new MV (rowMap, numVecs));
8113 exportMV_ = Y_rowMap;
8116 Y_rowMap = exportMV_;
8122 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8127 TEUCHOS_TEST_FOR_EXCEPTION(
8128 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::"
8129 "removeEmptyProcessesInPlace: This method does not work when the matrix "
8130 "was created with a constant graph (that is, when it was created using "
8131 "the version of its constructor that takes an RCP<const CrsGraph>). "
8132 "This is because the matrix is not allowed to modify the graph in that "
8133 "case, but removing empty processes requires modifying the graph.");
8134 myGraph_->removeEmptyProcessesInPlace (newMap);
8138 this->map_ = this->getRowMap ();
8142 staticGraph_ = Teuchos::rcp_const_cast<
const Graph> (myGraph_);
8145 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8146 Teuchos::RCP<RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8151 const Teuchos::RCP<const map_type>& domainMap,
8152 const Teuchos::RCP<const map_type>& rangeMap,
8153 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
8155 using Teuchos::Array;
8156 using Teuchos::ArrayView;
8157 using Teuchos::ParameterList;
8160 using Teuchos::rcp_implicit_cast;
8161 using Teuchos::sublist;
8162 typedef LocalOrdinal LO;
8163 typedef GlobalOrdinal GO;
8167 const crs_matrix_type& B = *
this;
8168 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
8169 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
8176 RCP<const map_type> A_rangeMap = A.
getRangeMap ();
8177 RCP<const map_type> B_domainMap = B.getDomainMap ();
8178 RCP<const map_type> B_rangeMap = B.getRangeMap ();
8180 RCP<const map_type> theDomainMap = domainMap;
8181 RCP<const map_type> theRangeMap = rangeMap;
8183 if (domainMap.is_null ()) {
8184 if (B_domainMap.is_null ()) {
8185 TEUCHOS_TEST_FOR_EXCEPTION(
8186 A_domainMap.is_null (), std::invalid_argument,
8187 "Tpetra::CrsMatrix::add: If neither A nor B have a domain Map, "
8188 "then you must supply a nonnull domain Map to this method.");
8189 theDomainMap = A_domainMap;
8191 theDomainMap = B_domainMap;
8194 if (rangeMap.is_null ()) {
8195 if (B_rangeMap.is_null ()) {
8196 TEUCHOS_TEST_FOR_EXCEPTION(
8197 A_rangeMap.is_null (), std::invalid_argument,
8198 "Tpetra::CrsMatrix::add: If neither A nor B have a range Map, "
8199 "then you must supply a nonnull range Map to this method.");
8200 theRangeMap = A_rangeMap;
8202 theRangeMap = B_rangeMap;
8206 #ifdef HAVE_TPETRA_DEBUG
8210 if (! A_domainMap.is_null () && ! A_rangeMap.is_null ()) {
8211 if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
8212 TEUCHOS_TEST_FOR_EXCEPTION(
8213 ! B_domainMap->isSameAs (*A_domainMap), std::invalid_argument,
8214 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a domain Map "
8215 "which is the same as (isSameAs) this RowMatrix's domain Map.");
8216 TEUCHOS_TEST_FOR_EXCEPTION(
8217 ! B_rangeMap->isSameAs (*A_rangeMap), std::invalid_argument,
8218 "Tpetra::CrsMatrix::add: The input RowMatrix A must have a range Map "
8219 "which is the same as (isSameAs) this RowMatrix's range Map.");
8220 TEUCHOS_TEST_FOR_EXCEPTION(
8221 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
8222 std::invalid_argument,
8223 "Tpetra::CrsMatrix::add: The input domain Map must be the same as "
8224 "(isSameAs) this RowMatrix's domain Map.");
8225 TEUCHOS_TEST_FOR_EXCEPTION(
8226 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
8227 std::invalid_argument,
8228 "Tpetra::CrsMatrix::add: The input range Map must be the same as "
8229 "(isSameAs) this RowMatrix's range Map.");
8232 else if (! B_domainMap.is_null () && ! B_rangeMap.is_null ()) {
8233 TEUCHOS_TEST_FOR_EXCEPTION(
8234 ! domainMap.is_null () && ! domainMap->isSameAs (*B_domainMap),
8235 std::invalid_argument,
8236 "Tpetra::CrsMatrix::add: The input domain Map must be the same as "
8237 "(isSameAs) this RowMatrix's domain Map.");
8238 TEUCHOS_TEST_FOR_EXCEPTION(
8239 ! rangeMap.is_null () && ! rangeMap->isSameAs (*B_rangeMap),
8240 std::invalid_argument,
8241 "Tpetra::CrsMatrix::add: The input range Map must be the same as "
8242 "(isSameAs) this RowMatrix's range Map.");
8245 TEUCHOS_TEST_FOR_EXCEPTION(
8246 domainMap.is_null () || rangeMap.is_null (), std::invalid_argument,
8247 "Tpetra::CrsMatrix::add: If neither A nor B have a domain and range "
8248 "Map, then you must supply a nonnull domain and range Map to this "
8251 #endif // HAVE_TPETRA_DEBUG
8256 bool callFillComplete =
true;
8257 RCP<ParameterList> constructorSublist;
8258 RCP<ParameterList> fillCompleteSublist;
8259 if (! params.is_null ()) {
8260 callFillComplete = params->get (
"Call fillComplete", callFillComplete);
8261 constructorSublist = sublist (params,
"Constructor parameters");
8262 fillCompleteSublist = sublist (params,
"fillComplete parameters");
8265 RCP<const map_type> A_rowMap = A.
getRowMap ();
8266 RCP<const map_type> B_rowMap = B.getRowMap ();
8267 RCP<const map_type> C_rowMap = B_rowMap;
8268 RCP<crs_matrix_type> C;
8275 if (A_rowMap->isSameAs (*B_rowMap)) {
8276 const LO localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8277 Array<size_t> C_maxNumEntriesPerRow (localNumRows, 0);
8280 if (alpha != ZERO) {
8281 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8283 C_maxNumEntriesPerRow[localRow] += A_numEntries;
8288 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8289 const size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8290 C_maxNumEntriesPerRow[localRow] += B_numEntries;
8294 if (constructorSublist.is_null ()) {
8295 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8298 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8299 StaticProfile, constructorSublist));
8309 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
8310 if (constructorSublist.is_null ()) {
8311 C = rcp (
new crs_matrix_type (C_rowMap, 0, DynamicProfile));
8313 C = rcp (
new crs_matrix_type (C_rowMap, 0, DynamicProfile,
8314 constructorSublist));
8319 #ifdef HAVE_TPETRA_DEBUG
8320 TEUCHOS_TEST_FOR_EXCEPTION(C.is_null (), std::logic_error,
8321 "Tpetra::RowMatrix::add: C should not be null at this point. "
8322 "Please report this bug to the Tpetra developers.");
8323 #endif // HAVE_TPETRA_DEBUG
8330 if (alpha != ZERO) {
8331 const LO A_localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8332 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
8334 const GO globalRow = A_rowMap->getGlobalElement (localRow);
8335 if (A_numEntries > static_cast<size_t> (ind.size ())) {
8336 ind.resize (A_numEntries);
8337 val.resize (A_numEntries);
8339 ArrayView<GO> indView = ind (0, A_numEntries);
8340 ArrayView<Scalar> valView = val (0, A_numEntries);
8344 for (
size_t k = 0; k < A_numEntries; ++k) {
8345 valView[k] *= alpha;
8348 C->insertGlobalValues (globalRow, indView, valView);
8353 const LO B_localNumRows =
static_cast<LO
> (B_rowMap->getNodeNumElements ());
8354 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
8355 size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8356 const GO globalRow = B_rowMap->getGlobalElement (localRow);
8357 if (B_numEntries > static_cast<size_t> (ind.size ())) {
8358 ind.resize (B_numEntries);
8359 val.resize (B_numEntries);
8361 ArrayView<GO> indView = ind (0, B_numEntries);
8362 ArrayView<Scalar> valView = val (0, B_numEntries);
8363 B.getGlobalRowCopy (globalRow, indView, valView, B_numEntries);
8366 for (
size_t k = 0; k < B_numEntries; ++k) {
8370 C->insertGlobalValues (globalRow, indView, valView);
8374 if (callFillComplete) {
8375 if (fillCompleteSublist.is_null ()) {
8376 C->fillComplete (theDomainMap, theRangeMap);
8378 C->fillComplete (theDomainMap, theRangeMap, fillCompleteSublist);
8381 return rcp_implicit_cast<row_matrix_type> (C);
8386 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8390 const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node>& rowTransfer,
8391 const Teuchos::RCP<const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node> > & domainTransfer,
8392 const Teuchos::RCP<const map_type>& domainMap,
8393 const Teuchos::RCP<const map_type>& rangeMap,
8394 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
8400 using Teuchos::ArrayRCP;
8401 using Teuchos::ArrayView;
8402 using Teuchos::Comm;
8403 using Teuchos::ParameterList;
8405 typedef LocalOrdinal LO;
8406 typedef GlobalOrdinal GO;
8407 typedef node_type NT;
8414 int MyPID = getComm ()->getRank ();
8416 std::unique_ptr<std::string> verbosePrefix;
8418 std::ostringstream os;
8419 os <<
"Proc " << MyPID <<
": transferAndFillComplete: ";
8420 verbosePrefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
8422 os <<
"start" << std::endl;
8423 std::cerr << os.str ();
8430 bool reverseMode =
false;
8431 bool restrictComm =
false;
8434 RCP<ParameterList> matrixparams;
8435 bool overrideAllreduce =
false;
8436 if (! params.is_null ()) {
8437 matrixparams = sublist (params,
"CrsMatrix");
8438 reverseMode = params->get (
"Reverse Mode", reverseMode);
8439 restrictComm = params->get (
"Restrict Communicator", restrictComm);
8440 auto & slist = params->sublist(
"matrixmatrix: kernel params",
false);
8441 isMM = slist.get(
"isMatrixMatrix_TransferAndFillComplete",
false);
8442 mm_optimization_core_count = slist.get(
"MM_TAFC_OptimizationCoreCount",mm_optimization_core_count);
8444 overrideAllreduce = slist.get(
"MM_TAFC_OverrideAllreduceCheck",
false);
8445 if(getComm()->getSize() < mm_optimization_core_count && isMM) isMM =
false;
8446 if(reverseMode) isMM =
false;
8450 std::shared_ptr< ::Tpetra::Details::CommRequest> iallreduceRequest;
8452 int reduced_mismatch = 0;
8453 if (isMM && !overrideAllreduce) {
8456 const bool source_vals = ! getGraph ()->getImporter ().is_null();
8457 const bool target_vals = ! (rowTransfer.getExportLIDs ().size() == 0 ||
8458 rowTransfer.getRemoteLIDs ().size() == 0);
8459 mismatch = (source_vals != target_vals) ? 1 : 0;
8462 Teuchos::REDUCE_MAX, * (getComm ()));
8465 #ifdef HAVE_TPETRA_MMM_TIMINGS
8466 using Teuchos::TimeMonitor;
8468 if(!params.is_null())
8469 label = params->get(
"Timer Label",label);
8470 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
8473 std::ostringstream os;
8474 if(isMM) os<<
":MMOpt";
8475 else os<<
":MMLegacy";
8479 Teuchos::TimeMonitor MMall(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC All") +tlstr ));
8487 const import_type* xferAsImport =
dynamic_cast<const import_type*
> (&rowTransfer);
8488 const export_type* xferAsExport =
dynamic_cast<const export_type*
> (&rowTransfer);
8489 TEUCHOS_TEST_FOR_EXCEPTION(
8490 xferAsImport == NULL && xferAsExport == NULL, std::invalid_argument,
8491 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' input "
8492 "argument must be either an Import or an Export, and its template "
8493 "parameters must match the corresponding template parameters of the "
8501 Teuchos::RCP<const import_type> xferDomainAsImport = Teuchos::rcp_dynamic_cast<
const import_type> (domainTransfer);
8502 Teuchos::RCP<const export_type> xferDomainAsExport = Teuchos::rcp_dynamic_cast<
const export_type> (domainTransfer);
8504 if(! domainTransfer.is_null()) {
8505 TEUCHOS_TEST_FOR_EXCEPTION(
8506 (xferDomainAsImport.is_null() && xferDomainAsExport.is_null()), std::invalid_argument,
8507 "Tpetra::CrsMatrix::transferAndFillComplete: The 'domainTransfer' input "
8508 "argument must be either an Import or an Export, and its template "
8509 "parameters must match the corresponding template parameters of the "
8512 TEUCHOS_TEST_FOR_EXCEPTION(
8513 ( xferAsImport != NULL || ! xferDomainAsImport.is_null() ) &&
8514 (( xferAsImport != NULL && xferDomainAsImport.is_null() ) ||
8515 ( xferAsImport == NULL && ! xferDomainAsImport.is_null() )), std::invalid_argument,
8516 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8517 "arguments must be of the same type (either Import or Export).");
8519 TEUCHOS_TEST_FOR_EXCEPTION(
8520 ( xferAsExport != NULL || ! xferDomainAsExport.is_null() ) &&
8521 (( xferAsExport != NULL && xferDomainAsExport.is_null() ) ||
8522 ( xferAsExport == NULL && ! xferDomainAsExport.is_null() )), std::invalid_argument,
8523 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8524 "arguments must be of the same type (either Import or Export).");
8530 const bool communication_needed = rowTransfer.getSourceMap ()->isDistributed ();
8534 RCP<const map_type> MyRowMap = reverseMode ?
8535 rowTransfer.getSourceMap () : rowTransfer.getTargetMap ();
8536 RCP<const map_type> MyColMap;
8537 RCP<const map_type> MyDomainMap = ! domainMap.is_null () ?
8538 domainMap : getDomainMap ();
8539 RCP<const map_type> MyRangeMap = ! rangeMap.is_null () ?
8540 rangeMap : getRangeMap ();
8541 RCP<const map_type> BaseRowMap = MyRowMap;
8542 RCP<const map_type> BaseDomainMap = MyDomainMap;
8550 if (! destMat.is_null ()) {
8561 const bool NewFlag = ! destMat->getGraph ()->isLocallyIndexed () &&
8562 ! destMat->getGraph ()->isGloballyIndexed ();
8563 TEUCHOS_TEST_FOR_EXCEPTION(
8564 ! NewFlag, std::invalid_argument,
"Tpetra::CrsMatrix::"
8565 "transferAndFillComplete: The input argument 'destMat' is only allowed "
8566 "to be nonnull, if its graph is empty (neither locally nor globally "
8575 TEUCHOS_TEST_FOR_EXCEPTION(
8576 ! destMat->getRowMap ()->isSameAs (*MyRowMap), std::invalid_argument,
8577 "Tpetra::CrsMatrix::transferAndFillComplete: The (row) Map of the "
8578 "input argument 'destMat' is not the same as the (row) Map specified "
8579 "by the input argument 'rowTransfer'.");
8580 TEUCHOS_TEST_FOR_EXCEPTION(
8581 ! destMat->checkSizes (*
this), std::invalid_argument,
8582 "Tpetra::CrsMatrix::transferAndFillComplete: You provided a nonnull "
8583 "destination matrix, but checkSizes() indicates that it is not a legal "
8584 "legal target for redistribution from the source matrix (*this). This "
8585 "may mean that they do not have the same dimensions.");
8599 TEUCHOS_TEST_FOR_EXCEPTION(
8600 ! (reverseMode || getRowMap ()->isSameAs (*rowTransfer.getSourceMap ())),
8601 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8602 "rowTransfer->getSourceMap() must match this->getRowMap() in forward mode.");
8603 TEUCHOS_TEST_FOR_EXCEPTION(
8604 ! (! reverseMode || getRowMap ()->isSameAs (*rowTransfer.getTargetMap ())),
8605 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8606 "rowTransfer->getTargetMap() must match this->getRowMap() in reverse mode.");
8609 TEUCHOS_TEST_FOR_EXCEPTION(
8610 ! xferDomainAsImport.is_null() && ! xferDomainAsImport->getTargetMap()->isSameAs(*domainMap),
8611 std::invalid_argument,
8612 "Tpetra::CrsMatrix::transferAndFillComplete: The target map of the 'domainTransfer' input "
8613 "argument must be the same as the rebalanced domain map 'domainMap'");
8615 TEUCHOS_TEST_FOR_EXCEPTION(
8616 ! xferDomainAsExport.is_null() && ! xferDomainAsExport->getSourceMap()->isSameAs(*domainMap),
8617 std::invalid_argument,
8618 "Tpetra::CrsMatrix::transferAndFillComplete: The source map of the 'domainTransfer' input "
8619 "argument must be the same as the rebalanced domain map 'domainMap'");
8632 const size_t NumSameIDs = rowTransfer.getNumSameIDs();
8633 ArrayView<const LO> ExportLIDs = reverseMode ?
8634 rowTransfer.getRemoteLIDs () : rowTransfer.getExportLIDs ();
8635 ArrayView<const LO> RemoteLIDs = reverseMode ?
8636 rowTransfer.getExportLIDs () : rowTransfer.getRemoteLIDs ();
8637 ArrayView<const LO> PermuteToLIDs = reverseMode ?
8638 rowTransfer.getPermuteFromLIDs () : rowTransfer.getPermuteToLIDs ();
8639 ArrayView<const LO> PermuteFromLIDs = reverseMode ?
8640 rowTransfer.getPermuteToLIDs () : rowTransfer.getPermuteFromLIDs ();
8641 Distributor& Distor = rowTransfer.getDistributor ();
8644 Teuchos::Array<int> SourcePids;
8645 Teuchos::Array<int> TargetPids;
8648 RCP<const map_type> ReducedRowMap, ReducedColMap,
8649 ReducedDomainMap, ReducedRangeMap;
8650 RCP<const Comm<int> > ReducedComm;
8654 if (destMat.is_null ()) {
8655 destMat = rcp (
new this_type (MyRowMap, 0, StaticProfile, matrixparams));
8662 ReducedRowMap = MyRowMap->removeEmptyProcesses ();
8663 ReducedComm = ReducedRowMap.is_null () ?
8665 ReducedRowMap->getComm ();
8666 destMat->removeEmptyProcessesInPlace (ReducedRowMap);
8668 ReducedDomainMap = MyRowMap.getRawPtr () == MyDomainMap.getRawPtr () ?
8670 MyDomainMap->replaceCommWithSubset (ReducedComm);
8671 ReducedRangeMap = MyRowMap.getRawPtr () == MyRangeMap.getRawPtr () ?
8673 MyRangeMap->replaceCommWithSubset (ReducedComm);
8676 MyRowMap = ReducedRowMap;
8677 MyDomainMap = ReducedDomainMap;
8678 MyRangeMap = ReducedRangeMap;
8681 if (! ReducedComm.is_null ()) {
8682 MyPID = ReducedComm->getRank ();
8689 ReducedComm = MyRowMap->getComm ();
8698 RCP<const import_type> MyImporter = getGraph ()->getImporter ();
8701 bool bSameDomainMap = BaseDomainMap->isSameAs (*getDomainMap ());
8703 if (! restrictComm && ! MyImporter.is_null () && bSameDomainMap ) {
8710 Import_Util::getPids (*MyImporter, SourcePids,
false);
8712 else if (restrictComm && ! MyImporter.is_null () && bSameDomainMap) {
8715 IntVectorType SourceDomain_pids(getDomainMap (),
true);
8716 IntVectorType SourceCol_pids(getColMap());
8718 SourceDomain_pids.putScalar(MyPID);
8720 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8721 SourcePids.resize (getColMap ()->getNodeNumElements ());
8722 SourceCol_pids.get1dCopy (SourcePids ());
8724 else if (MyImporter.is_null () && bSameDomainMap) {
8726 SourcePids.resize (getColMap ()->getNodeNumElements ());
8727 SourcePids.assign (getColMap ()->getNodeNumElements (), MyPID);
8729 else if ( ! MyImporter.is_null () &&
8730 ! domainTransfer.is_null () ) {
8737 IntVectorType TargetDomain_pids (domainMap);
8738 TargetDomain_pids.putScalar (MyPID);
8741 IntVectorType SourceDomain_pids (getDomainMap ());
8744 IntVectorType SourceCol_pids (getColMap ());
8746 if (! reverseMode && ! xferDomainAsImport.is_null() ) {
8747 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8749 else if (reverseMode && ! xferDomainAsExport.is_null() ) {
8750 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8752 else if (! reverseMode && ! xferDomainAsExport.is_null() ) {
8753 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8755 else if (reverseMode && ! xferDomainAsImport.is_null() ) {
8756 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8759 TEUCHOS_TEST_FOR_EXCEPTION(
8760 true, std::logic_error,
"Tpetra::CrsMatrix::"
8761 "transferAndFillComplete: Should never get here! "
8762 "Please report this bug to a Tpetra developer.");
8764 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8765 SourcePids.resize (getColMap ()->getNodeNumElements ());
8766 SourceCol_pids.get1dCopy (SourcePids ());
8768 else if ( ! MyImporter.is_null () &&
8769 BaseDomainMap->isSameAs (*BaseRowMap) &&
8770 getDomainMap ()->isSameAs (*getRowMap ())) {
8773 IntVectorType TargetRow_pids (domainMap);
8774 IntVectorType SourceRow_pids (getRowMap ());
8775 IntVectorType SourceCol_pids (getColMap ());
8777 TargetRow_pids.putScalar (MyPID);
8778 if (! reverseMode && xferAsImport != NULL) {
8779 SourceRow_pids.doExport (TargetRow_pids, *xferAsImport,
INSERT);
8781 else if (reverseMode && xferAsExport != NULL) {
8782 SourceRow_pids.doExport (TargetRow_pids, *xferAsExport,
INSERT);
8784 else if (! reverseMode && xferAsExport != NULL) {
8785 SourceRow_pids.doImport (TargetRow_pids, *xferAsExport,
INSERT);
8787 else if (reverseMode && xferAsImport != NULL) {
8788 SourceRow_pids.doImport (TargetRow_pids, *xferAsImport,
INSERT);
8791 TEUCHOS_TEST_FOR_EXCEPTION(
8792 true, std::logic_error,
"Tpetra::CrsMatrix::"
8793 "transferAndFillComplete: Should never get here! "
8794 "Please report this bug to a Tpetra developer.");
8797 SourceCol_pids.doImport (SourceRow_pids, *MyImporter,
INSERT);
8798 SourcePids.resize (getColMap ()->getNodeNumElements ());
8799 SourceCol_pids.get1dCopy (SourcePids ());
8802 TEUCHOS_TEST_FOR_EXCEPTION(
8803 true, std::invalid_argument,
"Tpetra::CrsMatrix::"
8804 "transferAndFillComplete: This method only allows either domainMap == "
8805 "getDomainMap (), or (domainMap == rowTransfer.getTargetMap () and "
8806 "getDomainMap () == getRowMap ()).");
8810 size_t constantNumPackets = destMat->constantNumberOfPackets ();
8811 if (constantNumPackets == 0) {
8812 destMat->reallocArraysForNumPacketsPerLid (ExportLIDs.size (),
8813 RemoteLIDs.size ());
8820 const size_t rbufLen = RemoteLIDs.size() * constantNumPackets;
8821 destMat->reallocImportsIfNeeded (rbufLen,
false,
nullptr);
8826 using Teuchos::outArg;
8827 using Teuchos::REDUCE_MAX;
8828 using Teuchos::reduceAll;
8831 RCP<const Teuchos::Comm<int> > comm = this->getComm ();
8832 const int myRank = comm->getRank ();
8834 std::ostringstream errStrm;
8838 Teuchos::ArrayView<size_t> numExportPacketsPerLID;
8841 destMat->numExportPacketsPerLID_.modify_host ();
8842 numExportPacketsPerLID =
8845 catch (std::exception& e) {
8846 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw: "
8847 << e.what () << std::endl;
8851 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw "
8852 "an exception not a subclass of std::exception" << std::endl;
8856 if (! comm.is_null ()) {
8857 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
8860 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
8861 TEUCHOS_TEST_FOR_EXCEPTION(
8862 true, std::runtime_error,
"getArrayViewFromDualView threw an "
8863 "exception on at least one process.");
8867 std::ostringstream os;
8868 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
8870 std::cerr << os.str ();
8875 numExportPacketsPerLID,
8881 catch (std::exception& e) {
8882 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw: "
8883 << e.what () << std::endl;
8887 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw "
8888 "an exception not a subclass of std::exception" << std::endl;
8893 std::ostringstream os;
8894 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
8896 std::cerr << os.str ();
8899 if (! comm.is_null ()) {
8900 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
8903 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
8904 TEUCHOS_TEST_FOR_EXCEPTION(
8905 true, std::runtime_error,
"packCrsMatrixWithOwningPIDs threw an "
8906 "exception on at least one process.");
8911 destMat->numExportPacketsPerLID_.modify_host ();
8912 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
8915 std::ostringstream os;
8916 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
8918 std::cerr << os.str ();
8922 numExportPacketsPerLID,
8928 std::ostringstream os;
8929 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
8931 std::cerr << os.str ();
8936 if (! communication_needed) {
8938 std::ostringstream os;
8939 os << *verbosePrefix <<
"Communication not needed" << std::endl;
8940 std::cerr << os.str ();
8945 if (constantNumPackets == 0) {
8947 std::ostringstream os;
8948 os << *verbosePrefix <<
"Reverse mode, variable # packets / LID"
8950 std::cerr << os.str ();
8955 destMat->numExportPacketsPerLID_.sync_host ();
8956 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
8958 destMat->numImportPacketsPerLID_.sync_host ();
8959 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
8963 std::ostringstream os;
8964 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
8966 std::cerr << os.str ();
8968 Distor.doReversePostsAndWaits (numExportPacketsPerLID, 1,
8969 numImportPacketsPerLID);
8971 std::ostringstream os;
8972 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
8974 std::cerr << os.str ();
8977 size_t totalImportPackets = 0;
8978 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
8979 totalImportPackets += numImportPacketsPerLID[i];
8984 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
8985 verbosePrefix.get ());
8986 destMat->imports_.modify_host ();
8987 Teuchos::ArrayView<char> hostImports =
8991 destMat->exports_.sync_host ();
8992 Teuchos::ArrayView<const char> hostExports =
8995 std::ostringstream os;
8996 os << *verbosePrefix <<
"Calling 4-arg doReversePostsAndWaits"
8998 std::cerr << os.str ();
9000 Distor.doReversePostsAndWaits (hostExports,
9001 numExportPacketsPerLID,
9003 numImportPacketsPerLID);
9005 std::ostringstream os;
9006 os << *verbosePrefix <<
"Finished 4-arg doReversePostsAndWaits"
9008 std::cerr << os.str ();
9013 std::ostringstream os;
9014 os << *verbosePrefix <<
"Reverse mode, constant # packets / LID"
9016 std::cerr << os.str ();
9018 destMat->imports_.modify_host ();
9019 Teuchos::ArrayView<char> hostImports =
9023 destMat->exports_.sync_host ();
9024 Teuchos::ArrayView<const char> hostExports =
9027 std::ostringstream os;
9028 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
9030 std::cerr << os.str ();
9032 Distor.doReversePostsAndWaits (hostExports,
9036 std::ostringstream os;
9037 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
9039 std::cerr << os.str ();
9044 if (constantNumPackets == 0) {
9046 std::ostringstream os;
9047 os << *verbosePrefix <<
"Forward mode, variable # packets / LID"
9049 std::cerr << os.str ();
9054 destMat->numExportPacketsPerLID_.sync_host ();
9055 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
9057 destMat->numImportPacketsPerLID_.sync_host ();
9058 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
9061 std::ostringstream os;
9062 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
9064 std::cerr << os.str ();
9066 Distor.doPostsAndWaits (numExportPacketsPerLID, 1,
9067 numImportPacketsPerLID);
9069 std::ostringstream os;
9070 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
9072 std::cerr << os.str ();
9075 size_t totalImportPackets = 0;
9076 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
9077 totalImportPackets += numImportPacketsPerLID[i];
9082 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
9083 verbosePrefix.get ());
9084 destMat->imports_.modify_host ();
9085 Teuchos::ArrayView<char> hostImports =
9089 destMat->exports_.sync_host ();
9090 Teuchos::ArrayView<const char> hostExports =
9093 std::ostringstream os;
9094 os << *verbosePrefix <<
"Calling 4-arg doPostsAndWaits"
9096 std::cerr << os.str ();
9098 Distor.doPostsAndWaits (hostExports,
9099 numExportPacketsPerLID,
9101 numImportPacketsPerLID);
9103 std::ostringstream os;
9104 os << *verbosePrefix <<
"Finished 4-arg doPostsAndWaits"
9106 std::cerr << os.str ();
9111 std::ostringstream os;
9112 os << *verbosePrefix <<
"Forward mode, constant # packets / LID"
9114 std::cerr << os.str ();
9116 destMat->imports_.modify_host ();
9117 Teuchos::ArrayView<char> hostImports =
9121 destMat->exports_.sync_host ();
9122 Teuchos::ArrayView<const char> hostExports =
9125 std::ostringstream os;
9126 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
9128 std::cerr << os.str ();
9130 Distor.doPostsAndWaits (hostExports,
9134 std::ostringstream os;
9135 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
9137 std::cerr << os.str ();
9148 destMat->numImportPacketsPerLID_.sync_host ();
9149 Teuchos::ArrayView<const size_t> numImportPacketsPerLID =
9151 destMat->imports_.sync_host ();
9152 Teuchos::ArrayView<const char> hostImports =
9156 std::ostringstream os;
9157 os << *verbosePrefix <<
"Calling unpackAndCombineWithOwningPIDsCount"
9159 std::cerr << os.str ();
9165 numImportPacketsPerLID,
9173 std::ostringstream os;
9174 os << *verbosePrefix <<
"unpackAndCombineWithOwningPIDsCount returned "
9175 << mynnz << std::endl;
9176 std::cerr << os.str ();
9178 size_t N = BaseRowMap->getNodeNumElements ();
9181 ArrayRCP<size_t> CSR_rowptr(N+1);
9182 ArrayRCP<GO> CSR_colind_GID;
9183 ArrayRCP<LO> CSR_colind_LID;
9184 ArrayRCP<Scalar> CSR_vals;
9185 CSR_colind_GID.resize (mynnz);
9186 CSR_vals.resize (mynnz);
9190 if (
typeid (LO) ==
typeid (GO)) {
9191 CSR_colind_LID = Teuchos::arcp_reinterpret_cast<LO> (CSR_colind_GID);
9194 CSR_colind_LID.resize (mynnz);
9198 std::ostringstream os;
9199 os << *verbosePrefix <<
"Calling unpackAndCombineIntoCrsArrays"
9201 std::cerr << os.str ();
9211 numImportPacketsPerLID,
9223 Teuchos::av_reinterpret_cast<impl_scalar_type> (CSR_vals ()),
9233 Teuchos::Array<int> RemotePids;
9235 std::ostringstream os;
9236 os << *verbosePrefix <<
"Calling lowCommunicationMakeColMapAndReindex"
9238 std::cerr << os.str ();
9240 Import_Util::lowCommunicationMakeColMapAndReindex (CSR_rowptr (),
9249 std::ostringstream os;
9250 os << *verbosePrefix <<
"restrictComm="
9251 << (restrictComm ?
"true" :
"false") << std::endl;
9252 std::cerr << os.str ();
9259 ReducedColMap = (MyRowMap.getRawPtr () == MyColMap.getRawPtr ()) ?
9261 MyColMap->replaceCommWithSubset (ReducedComm);
9262 MyColMap = ReducedColMap;
9267 std::ostringstream os;
9268 os << *verbosePrefix <<
"Calling replaceColMap" << std::endl;
9269 std::cerr << os.str ();
9271 destMat->replaceColMap (MyColMap);
9278 if (ReducedComm.is_null ()) {
9280 std::ostringstream os;
9281 os << *verbosePrefix <<
"I am no longer in the communicator; "
9282 "returning" << std::endl;
9283 std::cerr << os.str ();
9291 if ((! reverseMode && xferAsImport != NULL) ||
9292 (reverseMode && xferAsExport != NULL)) {
9294 std::ostringstream os;
9295 os << *verbosePrefix <<
"Calling sortCrsEntries" << std::endl;
9296 std::cerr << os.str ();
9298 Import_Util::sortCrsEntries (CSR_rowptr (),
9302 else if ((! reverseMode && xferAsExport != NULL) ||
9303 (reverseMode && xferAsImport != NULL)) {
9305 std::ostringstream os;
9306 os << *verbosePrefix <<
"Calling sortAndMergeCrsEntries" << std::endl;
9307 std::cerr << os.str ();
9309 Import_Util::sortAndMergeCrsEntries (CSR_rowptr (),
9312 if (CSR_rowptr[N] != mynnz) {
9313 CSR_colind_LID.resize (CSR_rowptr[N]);
9314 CSR_vals.resize (CSR_rowptr[N]);
9318 TEUCHOS_TEST_FOR_EXCEPTION(
9319 true, std::logic_error,
"Tpetra::CrsMatrix::"
9320 "transferAndFillComplete: Should never get here! "
9321 "Please report this bug to a Tpetra developer.");
9328 std::ostringstream os;
9329 os << *verbosePrefix <<
"Calling destMat->setAllValues" << std::endl;
9330 std::cerr << os.str ();
9338 destMat->setAllValues (CSR_rowptr, CSR_colind_LID, CSR_vals);
9344 Teuchos::ParameterList esfc_params;
9346 RCP<import_type> MyImport;
9349 if (iallreduceRequest.get () !=
nullptr) {
9351 std::ostringstream os;
9352 os << *verbosePrefix <<
"Calling iallreduceRequest->wait()" << std::endl;
9353 std::cerr << os.str ();
9355 iallreduceRequest->wait ();
9356 if (reduced_mismatch != 0) {
9362 #ifdef HAVE_TPETRA_MMM_TIMINGS
9363 Teuchos::TimeMonitor MMisMM (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM Block")));
9368 std::ostringstream os;
9369 os << *verbosePrefix <<
"Calling getAllValues" << std::endl;
9370 std::cerr << os.str ();
9373 Teuchos::ArrayRCP<LocalOrdinal> type3LIDs;
9374 Teuchos::ArrayRCP<int> type3PIDs;
9375 Teuchos::ArrayRCP<const size_t> rowptr;
9376 Teuchos::ArrayRCP<const LO> colind;
9377 Teuchos::ArrayRCP<const Scalar> vals;
9379 #ifdef HAVE_TPETRA_MMM_TIMINGS
9380 TimeMonitor tm_getAllValues (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMgetAllValues")));
9382 getAllValues(rowptr,colind,vals);
9386 std::ostringstream os;
9387 os << *verbosePrefix <<
"Calling reverseNeighborDiscovery" << std::endl;
9388 std::cerr << os.str ();
9392 #ifdef HAVE_TPETRA_MMM_TIMINGS
9393 TimeMonitor tm_rnd (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMrevNeighDis")));
9395 Import_Util::reverseNeighborDiscovery(*
this,
9407 std::ostringstream os;
9408 os << *verbosePrefix <<
"Done with reverseNeighborDiscovery" << std::endl;
9409 std::cerr << os.str ();
9412 Teuchos::ArrayView<const int> EPID1 = MyImporter.is_null() ? Teuchos::ArrayView<const int>() : MyImporter->getExportPIDs();
9413 Teuchos::ArrayView<const LO> ELID1 = MyImporter.is_null() ? Teuchos::ArrayView<const int>() : MyImporter->getExportLIDs();
9415 Teuchos::ArrayView<const int> TEPID2 = rowTransfer.getExportPIDs();
9416 Teuchos::ArrayView<const LO> TELID2 = rowTransfer.getExportLIDs();
9418 const int numCols = getGraph()->getColMap()->getNodeNumElements();
9420 std::vector<bool> IsOwned(numCols,
true);
9421 std::vector<int> SentTo(numCols,-1);
9422 if (! MyImporter.is_null ()) {
9423 for (
auto && rlid : MyImporter->getRemoteLIDs()) {
9424 IsOwned[rlid]=
false;
9428 std::vector<std::pair<int,GO> > usrtg;
9429 usrtg.reserve(TEPID2.size());
9432 const auto& colMap = * (this->getColMap ());
9434 const LO row = TELID2[i];
9435 const int pid = TEPID2[i];
9436 for (
auto j = rowptr[row]; j < rowptr[row+1]; ++j) {
9437 const int col = colind[j];
9438 if (IsOwned[col] && SentTo[col] != pid) {
9440 GO gid = colMap.getGlobalElement (col);
9441 usrtg.push_back (std::pair<int,GO> (pid, gid));
9448 std::sort(usrtg.begin(),usrtg.end());
9449 auto eopg = std ::unique(usrtg.begin(),usrtg.end());
9451 usrtg.erase(eopg,usrtg.end());
9454 Teuchos::ArrayRCP<int> EPID2=Teuchos::arcp(
new int[type2_us_size],0,type2_us_size,
true);
9455 Teuchos::ArrayRCP< LO> ELID2=Teuchos::arcp(
new LO[type2_us_size],0,type2_us_size,
true);
9458 for(
auto && p : usrtg) {
9459 EPID2[pos]= p.first;
9460 ELID2[pos]= this->getDomainMap()->getLocalElement(p.second);
9464 Teuchos::ArrayView<int> EPID3 = type3PIDs();
9465 Teuchos::ArrayView< LO> ELID3 = type3LIDs();
9466 GO InfGID = std::numeric_limits<GO>::max();
9467 int InfPID = INT_MAX;
9470 #endif // TPETRA_MIN3
9471 #define TPETRA_MIN3(x,y,z) ((x)<(y)?(std::min(x,z)):(std::min(y,z)))
9472 int i1=0, i2=0, i3=0;
9473 int Len1 = EPID1.size();
9474 int Len2 = EPID2.size();
9475 int Len3 = EPID3.size();
9477 int MyLen=Len1+Len2+Len3;
9478 Teuchos::ArrayRCP<LO> userExportLIDs = Teuchos::arcp(
new LO[MyLen],0,MyLen,
true);
9479 Teuchos::ArrayRCP<int> userExportPIDs = Teuchos::arcp(
new int[MyLen],0,MyLen,
true);
9482 while(i1 < Len1 || i2 < Len2 || i3 < Len3){
9483 int PID1 = (i1<Len1)?(EPID1[i1]):InfPID;
9484 int PID2 = (i2<Len2)?(EPID2[i2]):InfPID;
9485 int PID3 = (i3<Len3)?(EPID3[i3]):InfPID;
9487 GO GID1 = (i1<Len1)?getDomainMap()->getGlobalElement(ELID1[i1]):InfGID;
9488 GO GID2 = (i2<Len2)?getDomainMap()->getGlobalElement(ELID2[i2]):InfGID;
9489 GO GID3 = (i3<Len3)?getDomainMap()->getGlobalElement(ELID3[i3]):InfGID;
9491 int MIN_PID = TPETRA_MIN3(PID1,PID2,PID3);
9492 GO MIN_GID = TPETRA_MIN3( ((PID1==MIN_PID)?GID1:InfGID), ((PID2==MIN_PID)?GID2:InfGID), ((PID3==MIN_PID)?GID3:InfGID));
9495 #endif // TPETRA_MIN3
9496 bool added_entry=
false;
9498 if(PID1 == MIN_PID && GID1 == MIN_GID){
9499 userExportLIDs[iloc]=ELID1[i1];
9500 userExportPIDs[iloc]=EPID1[i1];
9505 if(PID2 == MIN_PID && GID2 == MIN_GID){
9507 userExportLIDs[iloc]=ELID2[i2];
9508 userExportPIDs[iloc]=EPID2[i2];
9514 if(PID3 == MIN_PID && GID3 == MIN_GID){
9516 userExportLIDs[iloc]=ELID3[i3];
9517 userExportPIDs[iloc]=EPID3[i3];
9525 std::ostringstream os;
9526 os << *verbosePrefix <<
"Create Import" << std::endl;
9527 std::cerr << os.str ();
9530 #ifdef HAVE_TPETRA_MMM_TIMINGS
9531 auto ismmIctor(*TimeMonitor::getNewTimer(prefix + std::string(
"isMMIportCtor")));
9533 Teuchos::RCP<Teuchos::ParameterList> plist = rcp(
new Teuchos::ParameterList());
9535 MyImport = rcp (
new import_type (MyDomainMap,
9538 userExportLIDs.view(0,iloc).getConst(),
9539 userExportPIDs.view(0,iloc).getConst(),
9544 std::ostringstream os;
9545 os << *verbosePrefix <<
"Call expertStaticFillComplete" << std::endl;
9546 std::cerr << os.str ();
9550 #ifdef HAVE_TPETRA_MMM_TIMINGS
9551 TimeMonitor esfc (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM::destMat->eSFC")));
9552 esfc_params.set(
"Timer Label",label+std::string(
"isMM eSFC"));
9554 if(!params.is_null())
9555 esfc_params.set(
"compute global constants",params->get(
"compute global constants",
true));
9556 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap, MyImport,Teuchos::null,rcp(
new Teuchos::ParameterList(esfc_params)));
9562 #ifdef HAVE_TPETRA_MMM_TIMINGS
9563 TimeMonitor MMnotMMblock (*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMblock")));
9566 std::ostringstream os;
9567 os << *verbosePrefix <<
"Create Import" << std::endl;
9568 std::cerr << os.str ();
9571 #ifdef HAVE_TPETRA_MMM_TIMINGS
9572 TimeMonitor notMMIcTor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMCreateImporter")));
9574 Teuchos::RCP<Teuchos::ParameterList> mypars = rcp(
new Teuchos::ParameterList);
9575 mypars->set(
"Timer Label",
"notMMFrom_tAFC");
9576 MyImport = rcp (
new import_type (MyDomainMap, MyColMap, RemotePids, mypars));
9579 std::ostringstream os;
9580 os << *verbosePrefix <<
"Call expertStaticFillComplete" << std::endl;
9581 std::cerr << os.str ();
9584 #ifdef HAVE_TPETRA_MMM_TIMINGS
9585 TimeMonitor esfcnotmm(*TimeMonitor::getNewTimer(prefix + std::string(
"notMMdestMat->expertStaticFillComplete")));
9586 esfc_params.set(
"Timer Label",prefix+std::string(
"notMM eSFC"));
9588 esfc_params.set(
"Timer Label",std::string(
"notMM eSFC"));
9591 if (!params.is_null ()) {
9592 esfc_params.set (
"compute global constants",
9593 params->get (
"compute global constants",
true));
9595 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap,
9596 MyImport, Teuchos::null,
9597 rcp (
new Teuchos::ParameterList (esfc_params)));
9601 std::ostringstream os;
9602 os << *verbosePrefix <<
"Done!" << std::endl;
9603 std::cerr << os.str ();
9608 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9613 const Teuchos::RCP<const map_type>& domainMap,
9614 const Teuchos::RCP<const map_type>& rangeMap,
9615 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9617 transferAndFillComplete (destMatrix, importer, Teuchos::null, domainMap, rangeMap, params);
9620 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9626 const Teuchos::RCP<const map_type>& domainMap,
9627 const Teuchos::RCP<const map_type>& rangeMap,
9628 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9630 transferAndFillComplete (destMatrix, rowImporter, Teuchos::rcpFromRef(domainImporter), domainMap, rangeMap, params);
9633 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9638 const Teuchos::RCP<const map_type>& domainMap,
9639 const Teuchos::RCP<const map_type>& rangeMap,
9640 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9642 transferAndFillComplete (destMatrix, exporter, Teuchos::null, domainMap, rangeMap, params);
9645 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9651 const Teuchos::RCP<const map_type>& domainMap,
9652 const Teuchos::RCP<const map_type>& rangeMap,
9653 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9655 transferAndFillComplete (destMatrix, rowExporter, Teuchos::rcpFromRef(domainExporter), domainMap, rangeMap, params);
9667 #define TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR,LO,GO,NODE) \
9669 template class CrsMatrix< SCALAR , LO , GO , NODE >; \
9670 template Teuchos::RCP< CrsMatrix< SCALAR , LO , GO , NODE > > \
9671 CrsMatrix< SCALAR , LO , GO , NODE >::convert< SCALAR > () const;
9673 #define TPETRA_CRSMATRIX_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \
9675 template Teuchos::RCP< CrsMatrix< SO , LO , GO , NODE > > \
9676 CrsMatrix< SI , LO , GO , NODE >::convert< SO > () const;
9678 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9680 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9681 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9682 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9683 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9684 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& importer, \
9685 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9686 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9687 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9688 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9689 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9690 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9691 const Teuchos::RCP<Teuchos::ParameterList>& params);
9693 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9695 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9696 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9697 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9698 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9699 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowImporter, \
9700 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9701 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9702 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainImporter, \
9703 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9704 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9705 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9706 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9707 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9708 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9709 const Teuchos::RCP<Teuchos::ParameterList>& params);
9712 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9714 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9715 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9716 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9717 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9718 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& exporter, \
9719 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9720 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9721 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9722 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9723 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9724 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9725 const Teuchos::RCP<Teuchos::ParameterList>& params);
9727 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9729 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9730 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9731 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9732 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9733 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowExporter, \
9734 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9735 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9736 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainExporter, \
9737 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9738 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9739 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9740 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9741 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9742 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9743 const Teuchos::RCP<Teuchos::ParameterList>& params);
9746 #define TPETRA_CRSMATRIX_INSTANT(SCALAR, LO, GO ,NODE) \
9747 TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR, LO, GO, NODE) \
9748 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9749 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9750 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9751 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE)
9753 #endif // TPETRA_CRSMATRIX_DEF_HPP
Teuchos::ArrayRCP< Teuchos::Array< local_ordinal_type > > lclInds2D_
Local column indices for all rows.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::RCP< const map_type > getRowMap() const override
Returns the Map that describes the row distribution in this graph.
dual_view_type::t_host getLocalViewHost() const
A local Kokkos::View of host memory.
bool hasColMap() const override
Whether the matrix has a well-defined column Map.
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
static int TAFC_OptimizationCoreCount()
The core count above which Tpetra::CrsMatrix::transferAndFillComplere will attempt to do advanced nei...
global_size_t getGlobalNumCols() const override
The number of global columns in the matrix.
Impl::CreateMirrorViewFromUnmanagedHostArray< ValueType, OutputDeviceType >::output_view_type create_mirror_view_from_raw_host_array(const OutputDeviceType &, ValueType *inPtr, const size_t inSize, const bool copy=true, const char label[]="")
Variant of Kokkos::create_mirror_view that takes a raw host 1-d array as input.
Functor for the the ABSMAX CombineMode of Import and Export operations.
void checkInternalState() const
Check that this object's state is sane; throw if it's not.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
size_t getNodeNumCols() const override
The number of columns connected to the locally owned rows of this matrix.
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...
CrsGraph< LocalOrdinal, GlobalOrdinal, Node > crs_graph_type
The CrsGraph specialization suitable for this CrsMatrix specialization.
virtual bool isLocallyIndexed() const =0
Whether matrix indices are locally indexed.
void replaceColMap(const Teuchos::RCP< const map_type > &newColMap)
Replace the matrix's column Map with the given Map.
virtual bool supportsRowViews() const override
Return true if getLocalRowView() and getGlobalRowView() are valid for this object.
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 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.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2)
Merge values in place, additively, with the same index.
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.
Teuchos::RCP< const map_type > getRangeMap() const override
The range Map of this matrix.
global_size_t getGlobalNumRows() const override
Number of global elements in the row map of this matrix.
std::map< GlobalOrdinal, std::pair< Teuchos::Array< GlobalOrdinal >, Teuchos::Array< Scalar > > > nonlocals_
Nonlocal data added using insertGlobalValues().
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...
typename device_type::execution_space execution_space
The Kokkos execution space.
void getLocalRowCopy(LocalOrdinal localRow, const Teuchos::ArrayView< LocalOrdinal > &colInds, const Teuchos::ArrayView< Scalar > &vals, size_t &numEntries) const override
Fill given arrays with a deep copy of the locally owned entries of the matrix in a given row...
void clear_sync_state()
Clear "modified" flags on both host and device sides.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const override
Get the number of entries in the given row (local index).
typename Kokkos::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
size_t getNumVectors() const
Number of columns in the multivector.
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
Traits class for packing / unpacking data of type T, using Kokkos data structures that live in the gi...
One or more distributed dense vectors.
size_t getNodeNumEntries() const override
The local number of entries in this matrix.
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0
The current number of entries on the calling process in the specified local row.
void scale(const Scalar &alpha)
Scale the matrix's values: this := alpha*this.
Teuchos::RCP< const map_type > getDomainMap() const override
Returns the Map associated with the domain of this graph.
Declare and define Tpetra::Details::copyOffsets, an implementation detail of Tpetra (in particular...
size_t getNodeNumRows() const override
The number of matrix rows owned by the calling process.
void fillLocalGraphAndMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local graph and matrix.
void resumeFill(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Resume operations that may change the values or structure of the matrix.
void leftScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x) override
Scale the matrix on the left with the given Vector.
bool noRedundancies_
Whether the graph's indices are non-redundant (merged) in each row, on this process.
local_matrix_type lclMatrix_
The local sparse matrix.
bool isDistributed() const
Whether this is a globally distributed object.
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...
void packCrsMatrixWithOwningPIDs(const CrsMatrix< ST, LO, GO, NT > &sourceMatrix, Kokkos::DualView< char *, typename DistObject< char, LO, GO, NT >::buffer_device_type > &exports_dv, const Teuchos::ArrayView< size_t > &numPacketsPerLID, const Teuchos::ArrayView< const LO > &exportLIDs, const Teuchos::ArrayView< const int > &sourcePIDs, size_t &constantNumPackets, Distributor &distor)
Pack specified entries of the given local sparse matrix for communication.
void getGlobalRowCopy(GlobalOrdinal GlobalRow, const Teuchos::ArrayView< GlobalOrdinal > &Indices, const Teuchos::ArrayView< Scalar > &Values, size_t &NumEntries) const override
Fill given arrays with a deep copy of the locally owned entries of the matrix in a given row...
Teuchos::RCP< const crs_graph_type > getCrsGraph() const
This matrix's graph, as a CrsGraph.
static bool debug()
Whether Tpetra is in debug mode.
size_t getGlobalMaxNumRowEntries() const override
Maximum number of entries in any row of the matrix, over all processes in the matrix's communicator...
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...
void applyNonTranspose(const MV &X_in, MV &Y_in, Scalar alpha, Scalar beta) const
Special case of apply() for mode == Teuchos::NO_TRANS.
Teuchos::RCP< CrsMatrix< T, LocalOrdinal, GlobalOrdinal, Node > > convert() const
Return another CrsMatrix with the same entries, but converted to a different Scalar type T...
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
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.
void swap(CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &matrix)
Swaps the data from *this with the data and maps from crsMatrix.
void fillLocalMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local matrix.
size_t unpackAndCombineWithOwningPIDsCount(const CrsGraph< LO, GO, NT > &sourceGraph, const Teuchos::ArrayView< const LO > &importLIDs, const Teuchos::ArrayView< const typename CrsGraph< LO, GO, NT >::packet_type > &imports, const Teuchos::ArrayView< const size_t > &numPacketsPerLID, size_t constantNumPackets, Distributor &distor, CombineMode combineMode, size_t numSameIDs, const Teuchos::ArrayView< const LO > &permuteToLIDs, const Teuchos::ArrayView< const LO > &permuteFromLIDs)
Special version of Tpetra::Details::unpackCrsGraphAndCombine that also unpacks owning process ranks...
bool isGloballyIndexed() const override
Whether the graph's column indices are stored as global indices.
Teuchos_Ordinal Array_size_type
Size type for Teuchos Array objects.
void globalAssemble()
Communicate nonlocal contributions to other processes.
void getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &diag) const override
Get a copy of the diagonal entries of the matrix.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
void gaussSeidel(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &D, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps) const
"Hybrid" Jacobi + (Gauss-Seidel or SOR) on .
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator, in rank order.
bool isFillActive() const
Whether the matrix is not fill complete.
Teuchos::RCP< MV > importMV_
Column Map MultiVector used in apply() and gaussSeidel().
typename Kokkos::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
bool isStaticGraph() const
Indicates that the graph is static, so that new entries cannot be added to this matrix.
size_t global_size_t
Global size_t object.
bool hasTransposeApply() const override
Whether apply() allows applying the transpose or conjugate transpose.
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 deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
virtual void getGlobalRowView(GlobalOrdinal GlobalRow, Teuchos::ArrayView< const GlobalOrdinal > &indices, Teuchos::ArrayView< const Scalar > &values) const =0
Get a constant, nonpersisting, globally indexed view of the given row of the matrix.
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.
void clearGlobalConstants()
Clear matrix properties that require collectives.
void gaussSeidelCopy(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &D, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps, const bool zeroInitialGuess) const
Version of gaussSeidel(), with fewer requirements on X.
LocalOrdinal getLocalRowViewRaw(const LocalOrdinal lclRow, LocalOrdinal &numEnt, const LocalOrdinal *&lclColInds, const Scalar *&vals) const override
Get a constant, nonpersisting, locally indexed view of the given row of the matrix, using "raw" pointers instead of Teuchos::ArrayView.
void allocateValues(ELocalGlobal lg, GraphAllocationStatus gas)
Allocate values (and optionally indices) using the Node.
void exportAndFillComplete(Teuchos::RCP< CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &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.
Insert new values that don't currently exist.
bool isFillComplete() const override
Whether the matrix is fill complete.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
The communicator over which the matrix is distributed.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createOneToOne(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &M)
Nonmember constructor for a contiguous Map with user-defined weights and a user-specified, possibly nondefault Kokkos Node type.
void importAndFillComplete(Teuchos::RCP< CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &destMatrix, const import_type &importer, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null) const
Import from this to the given destination matrix, and make the result fill complete.
void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
Teuchos::RCP< const map_type > rowMap_
The Map describing the distribution of rows of the graph.
void packNew(const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &exportLIDs, Kokkos::DualView< char *, buffer_device_type > &exports, const Kokkos::DualView< size_t *, buffer_device_type > &numPacketsPerLID, size_t &constantNumPackets, Distributor &dist) const
Pack this object's data for an Import or Export.
num_row_entries_type k_numRowEntries_
The number of local entries in each locally owned row.
void reorderedGaussSeidelCopy(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &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.
ESweepDirection
Sweep direction for Gauss-Seidel or Successive Over-Relaxation (SOR).
GlobalOrdinal getIndexBase() const override
The index base for global indices for this matrix.
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...
Kokkos::StaticCrsGraph< local_ordinal_type, Kokkos::LayoutLeft, execution_space > local_graph_type
The type of the part of the sparse graph on each MPI process.
virtual size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const =0
The current number of entries on the calling process in the specified global row. ...
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...
Teuchos::RCP< MV > getColumnMapMultiVector(const MV &X_domainMap, const bool force=false) const
Create a (or fetch a cached) column Map MultiVector.
#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...
Sets up and executes a communication plan for a Tpetra DistObject.
mag_type frobNorm_
Cached Frobenius norm of the (global) matrix.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const override
Print this object with the given verbosity level to the given output stream.
Teuchos::RCP< const RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const override
This matrix's graph, as a RowGraph.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
static bool verbose()
Whether Tpetra is in verbose mode.
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
void unpackAndCombineIntoCrsArrays(const CrsGraph< LO, GO, NT > &sourceGraph, const Teuchos::ArrayView< const LO > &importLIDs, const Teuchos::ArrayView< const typename CrsGraph< LO, GO, NT >::packet_type > &imports, const Teuchos::ArrayView< const size_t > &numPacketsPerLID, const size_t constantNumPackets, Distributor &distor, const CombineMode combineMode, const size_t numSameIDs, const Teuchos::ArrayView< const LO > &permuteToLIDs, const Teuchos::ArrayView< const LO > &permuteFromLIDs, size_t TargetNumRows, size_t TargetNumNonzeros, const int MyTargetPID, const Teuchos::ArrayView< size_t > &CRS_rowptr, const Teuchos::ArrayView< GO > &CRS_colind, const Teuchos::ArrayView< const int > &SourcePids, Teuchos::Array< int > &TargetPids)
unpackAndCombineIntoCrsArrays
bool isFillComplete() const override
Whether fillComplete() has been called and the graph is in compute mode.
bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
CrsGraphType::global_ordinal_type getGlobalNumDiags(const CrsGraphType &G)
Number of populated diagonal entries in the given sparse graph, over all processes in the graph's (MP...
bool isGloballyIndexed() const override
Whether the matrix is globally indexed on the calling process.
RowInfo getRowInfoFromGlobalRowIndex(const global_ordinal_type gblRow) const
Get information about the locally owned row with global index gblRow.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
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.
Utility functions for packing and unpacking sparse matrix entries.
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 override
Implementation of RowMatrix::add: return alpha*A + beta*this.
bool fillComplete_
Whether the matrix is fill complete.
Replace old value with maximum of magnitudes of old and new values.
Abstract base class for objects that can be the source of an Import or Export operation.
typename Node::device_type device_type
The Kokkos device type.
size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const override
Number of entries in the sparse matrix in the given local row, on the calling (MPI) process...
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...
Teuchos::RCP< MV > getRowMapMultiVector(const MV &Y_rangeMap, const bool force=false) const
Create a (or fetch a cached) row Map MultiVector.
std::string description() const override
A one-line description of this object.
void getLocalDiagOffsets(Teuchos::ArrayRCP< size_t > &offsets) const
Get offsets of the diagonal entries in the matrix.
void apply(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const override
Compute a sparse matrix-MultiVector multiply.
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.
void computeGlobalConstants()
Compute matrix properties that require collectives.
#define TPETRA_EFFICIENCY_WARNING(throw_exception_test, Exception, msg)
Print or throw an efficency warning.
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...
Teuchos::RCP< const map_type > getRangeMap() const override
Returns the Map associated with the domain of this graph.
Replace old values with zero.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
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 modify_host()
Mark data as modified on the host side.
bool isLocallyComplete() const
Is this Export or Import locally complete?
local_matrix_type::values_type getLocalValuesView() const
Get the Kokkos local values.
RowInfo getRowInfo(const local_ordinal_type myRow) const
Get information about the locally owned row with local index myRow.
ProfileType getProfileType() const
Returns true if the matrix was allocated with static data structures.
void getGlobalRowView(GlobalOrdinal GlobalRow, Teuchos::ArrayView< const GlobalOrdinal > &indices, Teuchos::ArrayView< const Scalar > &values) const override
Get a constant, nonpersisting view of a row of this matrix, using global row and column indices...
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap) override
Remove processes owning zero rows from the Maps and their communicator.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
virtual bool checkSizes(const SrcDistObject &source) override
Compare the source and target (this) objects for compatibility.
local_map_type getLocalMap() const
Get the local Map for Kokkos kernels.
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.
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.
A parallel distribution of indices over processes.
void doExport(const SrcDistObject &source, const Export< LocalOrdinal, GlobalOrdinal, Node > &exporter, const CombineMode CM, const bool restrictedMode=false)
Export data into this object using an Export object ("forward mode").
Teuchos::RCP< const map_type > getDomainMap() const override
The domain Map of this matrix.
Teuchos::ArrayView< const impl_scalar_type > getView(RowInfo rowinfo) const
Constant view of all entries (including extra space) in the given row.
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.
KokkosSparse::CrsMatrix< impl_scalar_type, local_ordinal_type, 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...
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.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects...
A read-only, row-oriented interface to a sparse matrix.
void getLocalRowView(LocalOrdinal LocalRow, Teuchos::ArrayView< const LocalOrdinal > &indices, Teuchos::ArrayView< const Scalar > &values) const override
Get a constant, nonpersisting view of a row of this matrix, using local row and column indices...
void rightScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x) override
Scale the matrix on the right with the given Vector.
size_t getNodeMaxNumRowEntries() const override
Maximum number of entries in any row of the matrix, on this process.
Scalar operator()(const Scalar &x, const Scalar &y)
Return the maximum of the magnitudes (absolute values) of x and y.
A distributed dense vector.
Declaration of Tpetra::Details::iallreduce.
void reduce()
Sum values of a locally replicated multivector across all processes.
Declaration and definition of Tpetra::Details::castAwayConstDualView, an implementation detail of Tpe...
std::shared_ptr< CommRequest > iallreduce(const InputViewType &sendbuf, const OutputViewType &recvbuf, const ::Teuchos::EReductionType op, const ::Teuchos::Comm< int > &comm)
Nonblocking all-reduce, for either rank-1 or rank-0 Kokkos::View objects.
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.
Kokkos::DualView< ValueType *, DeviceType > castAwayConstDualView(const Kokkos::DualView< const ValueType *, DeviceType > &input_dv)
Cast away const-ness of a 1-D Kokkos::DualView.
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.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const override
Number of entries in the sparse matrix in the given global row, on the calling (MPI) process...
size_t mergeRowIndicesAndValues(crs_graph_type &graph, const RowInfo &rowInfo)
Merge duplicate row indices in the given row, along with their corresponding values.
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.
bool isLocallyIndexed() const override
Whether the matrix is locally indexed on the calling process.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
void reorderedGaussSeidel(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &D, const Teuchos::ArrayView< LocalOrdinal > &rowIndices, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps) const
Reordered "Hybrid" Jacobi + (Gauss-Seidel or SOR) on .
Declaration and definition of Tpetra::Details::getEntryOnHost.
Teuchos::ArrayView< impl_scalar_type > getViewNonConst(const RowInfo &rowinfo) const
Nonconst view of all entries (including extra space) in the given row.
Teuchos::RCP< const map_type > colMap_
The Map describing the distribution of columns of the graph.
LocalOrdinal local_ordinal_type
The type of each local index in the matrix.
mag_type getFrobeniusNorm() const override
Compute and return the Frobenius norm of the matrix.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes the distribution of rows over processes.
::Tpetra::Details::EStorageStatus storageStatus_
Status of the matrix's storage, when not in a fill-complete state.
void localApply(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Y, const Teuchos::ETransp mode=Teuchos::NO_TRANS, const Scalar &alpha=Teuchos::ScalarTraits< Scalar >::one(), const Scalar &beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Compute the local part of a sparse matrix-(Multi)Vector multiply.
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.
bool isStorageOptimized() const
Returns true if storage has been optimized.
Functions that wrap Kokkos::create_mirror_view, in order to avoid deep copies when not necessary...
void sync_device()
Synchronize to Device.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Teuchos::RCP< MV > exportMV_
Row Map MultiVector used in apply().
Teuchos::RCP< const map_type > getRowMap() const override
The Map that describes the row distribution in this matrix.
global_size_t getGlobalNumEntries() const override
The global number of entries in this matrix.