40 #ifndef TPETRA_CRSMATRIX_DEF_HPP
41 #define TPETRA_CRSMATRIX_DEF_HPP
53 #include "Tpetra_RowMatrix.hpp"
54 #include "Tpetra_LocalCrsMatrixOperator.hpp"
62 #include "Tpetra_Details_getDiagCopyWithoutOffsets.hpp"
67 #include "KokkosSparse_getDiagCopy.hpp"
71 #include "Tpetra_Details_packCrsMatrix.hpp"
72 #include "Tpetra_Details_unpackCrsMatrixAndCombine.hpp"
74 #include "Teuchos_FancyOStream.hpp"
75 #include "Teuchos_RCP.hpp"
76 #include "Teuchos_DataAccess.hpp"
77 #include "Teuchos_SerialDenseMatrix.hpp"
85 using Teuchos::rcpFromRef;
91 template<
class T,
class BinaryFunction>
92 T atomic_binary_function_update (
volatile T*
const dest,
106 T newVal = f (assume, inputVal);
107 oldVal = Kokkos::atomic_compare_exchange (dest, assume, newVal);
108 }
while (assume != oldVal);
128 template<
class Scalar>
132 typedef Teuchos::ScalarTraits<Scalar> STS;
133 return std::max (STS::magnitude (x), STS::magnitude (y));
142 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
143 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
144 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
145 size_t maxNumEntriesPerRow,
147 const Teuchos::RCP<Teuchos::ParameterList>& params) :
150 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, size_t, "
151 "ProfileType[, RCP<ParameterList>]): ";
152 Teuchos::RCP<crs_graph_type> graph;
154 graph = Teuchos::rcp (
new crs_graph_type (rowMap, maxNumEntriesPerRow,
157 catch (std::exception& e) {
158 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
159 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
160 "size_t, ProfileType[, RCP<ParameterList>]) threw an exception: "
167 staticGraph_ = myGraph_;
172 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
177 const Teuchos::RCP<Teuchos::ParameterList>& params) :
180 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
181 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
182 Teuchos::RCP<crs_graph_type> graph;
188 catch (std::exception& e) {
189 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
190 (
true, std::runtime_error,
"CrsGraph constructor "
191 "(RCP<const Map>, ArrayView<const size_t>, "
192 "ProfileType[, RCP<ParameterList>]) threw an exception: "
199 staticGraph_ = graph;
205 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
208 const Teuchos::RCP<const map_type>& colMap,
209 const size_t maxNumEntPerRow,
211 const Teuchos::RCP<Teuchos::ParameterList>& params) :
214 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
215 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]): ";
216 const char suffix[] =
217 " Please report this bug to the Tpetra developers.";
220 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
221 (! staticGraph_.is_null (), std::logic_error,
222 "staticGraph_ is not null at the beginning of the constructor."
224 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
225 (! myGraph_.is_null (), std::logic_error,
226 "myGraph_ is not null at the beginning of the constructor."
228 Teuchos::RCP<crs_graph_type> graph;
234 catch (std::exception& e) {
235 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
236 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
237 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]) threw an "
238 "exception: " << e.what ());
244 staticGraph_ = myGraph_;
249 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
252 const Teuchos::RCP<const map_type>& colMap,
253 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
255 const Teuchos::RCP<Teuchos::ParameterList>& params) :
258 const char tfecfFuncName[] =
259 "CrsMatrix(RCP<const Map>, RCP<const Map>, "
260 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
261 Teuchos::RCP<crs_graph_type> graph;
267 catch (std::exception& e) {
268 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
269 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
270 "RCP<const Map>, ArrayView<const size_t>, ProfileType[, "
271 "RCP<ParameterList>]) threw an exception: " << e.what ());
277 staticGraph_ = graph;
283 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
285 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
286 const Teuchos::RCP<Teuchos::ParameterList>& ) :
288 staticGraph_ (graph),
289 storageStatus_ (Details::STORAGE_1D_PACKED)
292 typedef typename local_matrix_type::values_type values_type;
293 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>[, "
294 "RCP<ParameterList>]): ";
297 std::unique_ptr<std::string> prefix;
299 prefix = this->createPrefix(
"CrsMatrix",
"CrsMatrix(graph,params)");
300 std::ostringstream os;
301 os << *prefix <<
"Start" << endl;
302 std::cerr << os.str ();
305 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
306 (graph.is_null (), std::runtime_error,
"Input graph is null.");
307 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
308 (! graph->isFillComplete (), std::runtime_error,
"Input graph "
309 "is not fill complete. You must call fillComplete on the "
310 "graph before using it to construct a CrsMatrix. Note that "
311 "calling resumeFill on the graph makes it not fill complete, "
312 "even if you had previously called fillComplete. In that "
313 "case, you must call fillComplete on the graph again.");
321 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
322 auto lclGraph = graph->getLocalGraph ();
323 const size_t numEnt = lclGraph.entries.extent (0);
325 std::ostringstream os;
326 os << *prefix <<
"Allocate values: " << numEnt << endl;
327 std::cerr << os.str ();
329 values_type val (
"Tpetra::CrsMatrix::val", numEnt);
331 auto lclMat = std::make_shared<local_matrix_type>
332 (
"Tpetra::CrsMatrix::lclMatrix_", numCols, val, lclGraph);
333 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
339 std::ostringstream os;
340 os << *prefix <<
"Assign k_values1D_: old="
342 << lclMat->values.extent(0) << endl;
343 std::cerr << os.str ();
350 std::ostringstream os;
351 os << *prefix <<
"Done" << endl;
352 std::cerr << os.str ();
356 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
358 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
359 const typename local_matrix_type::values_type& values,
360 const Teuchos::RCP<Teuchos::ParameterList>& ) :
362 staticGraph_ (graph),
363 storageStatus_ (Details::STORAGE_1D_PACKED)
365 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>, "
366 "local_matrix_type::values_type, "
367 "[,RCP<ParameterList>]): ";
368 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
369 (graph.is_null (), std::runtime_error,
"Input graph is null.");
370 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
371 (! graph->isFillComplete (), std::runtime_error,
"Input graph "
372 "is not fill complete. You must call fillComplete on the "
373 "graph before using it to construct a CrsMatrix. Note that "
374 "calling resumeFill on the graph makes it not fill complete, "
375 "even if you had previously called fillComplete. In that "
376 "case, you must call fillComplete on the graph again.");
384 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
385 auto lclGraph = graph->getLocalGraph ();
387 auto lclMat = std::make_shared<local_matrix_type>
388 (
"Tpetra::CrsMatrix::lclMatrix_", numCols, values, lclGraph);
389 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
399 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
402 const Teuchos::RCP<const map_type>& colMap,
403 const typename local_matrix_type::row_map_type& rowPointers,
404 const typename local_graph_type::entries_type::non_const_type& columnIndices,
405 const typename local_matrix_type::values_type& values,
406 const Teuchos::RCP<Teuchos::ParameterList>& params) :
408 storageStatus_ (Details::STORAGE_1D_PACKED)
410 using Details::getEntryOnHost;
413 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
414 "RCP<const Map>, ptr, ind, val[, params]): ";
415 const char suffix[] =
416 ". Please report this bug to the Tpetra developers.";
420 std::unique_ptr<std::string> prefix;
422 prefix = this->createPrefix(
423 "CrsMatrix",
"CrsMatrix(rowMap,colMap,ptr,ind,val[,params])");
424 std::ostringstream os;
425 os << *prefix <<
"Start" << endl;
426 std::cerr << os.str ();
433 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
434 (values.extent(0) != columnIndices.extent(0),
435 std::invalid_argument,
"values.extent(0)=" << values.extent(0)
436 <<
" != columnIndices.extent(0) = " << columnIndices.extent(0)
438 if (debug && rowPointers.extent(0) != 0) {
439 const size_t numEnt =
440 getEntryOnHost(rowPointers, rowPointers.extent(0) - 1);
441 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
442 (numEnt !=
size_t(columnIndices.extent(0)) ||
443 numEnt !=
size_t(values.extent(0)),
444 std::invalid_argument,
"Last entry of rowPointers says that "
445 "the matrix has " << numEnt <<
" entr"
446 << (numEnt != 1 ?
"ies" :
"y") <<
", but the dimensions of "
447 "columnIndices and values don't match this. "
448 "columnIndices.extent(0)=" << columnIndices.extent (0)
449 <<
" and values.extent(0)=" << values.extent (0) <<
".");
452 RCP<crs_graph_type> graph;
454 graph = Teuchos::rcp (
new crs_graph_type (rowMap, colMap, rowPointers,
455 columnIndices, params));
457 catch (std::exception& e) {
458 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
459 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
460 "RCP<const Map>, ptr, ind[, params]) threw an exception: "
468 auto lclGraph = graph->getLocalGraph ();
469 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
470 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
471 lclGraph.entries.extent (0) != columnIndices.extent (0),
472 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, "
473 "ind[, params]) did not set the local graph correctly." << suffix);
474 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
475 (lclGraph.entries.extent (0) != values.extent (0),
476 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, ind[, "
477 "params]) did not set the local graph correctly. "
478 "lclGraph.entries.extent(0) = " << lclGraph.entries.extent (0)
479 <<
" != values.extent(0) = " << values.extent (0) << suffix);
485 staticGraph_ = graph;
494 const size_t numCols = graph->getColMap ()->getNodeNumElements ();
496 auto lclMat = std::make_shared<local_matrix_type>
497 (
"Tpetra::CrsMatrix::lclMatrix_", numCols, values, lclGraph);
498 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
500 auto newValues = lclMat->values;
501 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
502 (newValues.extent (0) != values.extent (0),
503 std::logic_error,
"Local matrix's constructor did not set the "
504 "values correctly. newValues.extent(0) = " <<
505 newValues.extent (0) <<
" != values.extent(0) = " <<
506 values.extent (0) << suffix);
515 std::ostringstream os;
516 os << *prefix <<
"Done" << endl;
517 std::cerr << os.str();
521 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
524 const Teuchos::RCP<const map_type>& colMap,
525 const Teuchos::ArrayRCP<size_t>& ptr,
526 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
527 const Teuchos::ArrayRCP<Scalar>& val,
528 const Teuchos::RCP<Teuchos::ParameterList>& params) :
530 storageStatus_ (Details::STORAGE_1D_PACKED)
532 using Kokkos::Compat::getKokkosViewDeepCopy;
533 using Teuchos::av_reinterpret_cast;
535 using values_type =
typename local_matrix_type::values_type;
537 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
538 "RCP<const Map>, ptr, ind, val[, params]): ";
540 RCP<crs_graph_type> graph;
545 catch (std::exception& e) {
546 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
547 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
548 "RCP<const Map>, ArrayRCP<size_t>, ArrayRCP<LocalOrdinal>[, "
549 "RCP<ParameterList>]) threw an exception: " << e.what ());
555 staticGraph_ = graph;
568 auto lclGraph = staticGraph_->getLocalGraph ();
569 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
570 (
size_t (lclGraph.row_map.extent (0)) !=
size_t (ptr.size ()) ||
571 size_t (lclGraph.entries.extent (0)) !=
size_t (ind.size ()),
572 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, "
573 "ptr, ind[, params]) did not set the local graph correctly. "
574 "Please report this bug to the Tpetra developers.");
576 const size_t numCols =
577 staticGraph_->getColMap ()->getNodeNumElements ();
579 getKokkosViewDeepCopy<device_type> (av_reinterpret_cast<IST> (val ()));
581 auto lclMat = std::make_shared<local_matrix_type>
582 (
"Tpetra::CrsMatrix::lclMatrix_", numCols, valIn, lclGraph);
583 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
593 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
596 const Teuchos::RCP<const map_type>& colMap,
598 const Teuchos::RCP<Teuchos::ParameterList>& params) :
602 k_values1D_ (lclMatrix.values),
603 storageStatus_ (Details::STORAGE_1D_PACKED),
606 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
607 "RCP<const Map>, local_matrix_type[, RCP<ParameterList>]): ";
608 const char suffix[] =
609 " Please report this bug to the Tpetra developers.";
611 Teuchos::RCP<crs_graph_type> graph;
614 lclMatrix.graph, params));
616 catch (std::exception& e) {
617 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
618 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
619 "RCP<const Map>, local_graph_type[, RCP<ParameterList>]) threw an "
620 "exception: " << e.what ());
622 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
623 (!graph->isFillComplete (), std::logic_error,
"CrsGraph constructor (RCP"
624 "<const Map>, RCP<const Map>, local_graph_type[, RCP<ParameterList>]) "
625 "did not produce a fill-complete graph. Please report this bug to the "
626 "Tpetra developers.");
631 staticGraph_ = graph;
633 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
634 params->get (
"compute global constants",
true);
635 if (callComputeGlobalConstants) {
639 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
641 "At the end of a CrsMatrix constructor that should produce "
642 "a fillComplete matrix, isFillActive() is true." << suffix);
643 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
645 "CrsMatrix constructor that should produce a fillComplete "
646 "matrix, isFillComplete() is false." << suffix);
650 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
653 const Teuchos::RCP<const map_type>& rowMap,
654 const Teuchos::RCP<const map_type>& colMap,
655 const Teuchos::RCP<const map_type>& domainMap,
656 const Teuchos::RCP<const map_type>& rangeMap,
657 const Teuchos::RCP<Teuchos::ParameterList>& params) :
661 k_values1D_ (lclMatrix.values),
662 storageStatus_ (Details::STORAGE_1D_PACKED),
665 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
666 "RCP<const Map>, RCP<const Map>, RCP<const Map>, "
667 "local_matrix_type[, RCP<ParameterList>]): ";
668 const char suffix[] =
669 " Please report this bug to the Tpetra developers.";
671 Teuchos::RCP<crs_graph_type> graph;
673 graph = Teuchos::rcp (
new crs_graph_type (lclMatrix.graph, rowMap, colMap,
674 domainMap, rangeMap, params));
676 catch (std::exception& e) {
677 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
678 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
679 "RCP<const Map>, RCP<const Map>, RCP<const Map>, local_graph_type[, "
680 "RCP<ParameterList>]) threw an exception: " << e.what ());
682 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
683 (! graph->isFillComplete (), std::logic_error,
"CrsGraph "
684 "constructor (RCP<const Map>, RCP<const Map>, RCP<const Map>, "
685 "RCP<const Map>, local_graph_type[, RCP<ParameterList>]) did "
686 "not produce a fillComplete graph." << suffix);
691 staticGraph_ = graph;
693 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
694 params->get (
"compute global constants",
true);
695 if (callComputeGlobalConstants) {
699 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
701 "At the end of a CrsMatrix constructor that should produce "
702 "a fillComplete matrix, isFillActive() is true." << suffix);
703 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
705 "CrsMatrix constructor that should produce a fillComplete "
706 "matrix, isFillComplete() is false." << suffix);
710 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
713 const Teuchos::RCP<const map_type>& rowMap,
714 const Teuchos::RCP<const map_type>& colMap,
715 const Teuchos::RCP<const map_type>& domainMap,
716 const Teuchos::RCP<const map_type>& rangeMap,
717 const Teuchos::RCP<const import_type>& importer,
718 const Teuchos::RCP<const export_type>& exporter,
719 const Teuchos::RCP<Teuchos::ParameterList>& params) :
723 k_values1D_ (lclMatrix.values),
724 storageStatus_ (Details::STORAGE_1D_PACKED),
728 const char tfecfFuncName[] =
"Tpetra::CrsMatrix"
729 "(lclMat,Map,Map,Map,Map,Import,Export,params): ";
730 const char suffix[] =
731 " Please report this bug to the Tpetra developers.";
733 Teuchos::RCP<crs_graph_type> graph;
736 domainMap, rangeMap, importer,
739 catch (std::exception& e) {
740 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
741 (
true, std::runtime_error,
"CrsGraph constructor "
742 "(local_graph_type, Map, Map, Map, Map, Import, Export, "
743 "params) threw: " << e.what ());
745 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
746 (!graph->isFillComplete (), std::logic_error,
"CrsGraph "
747 "constructor (local_graph_type, Map, Map, Map, Map, Import, "
748 "Export, params) did not produce a fill-complete graph. "
749 "Please report this bug to the Tpetra developers.");
754 staticGraph_ = graph;
756 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
757 params->get (
"compute global constants",
true);
758 if (callComputeGlobalConstants) {
762 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
764 "At the end of a CrsMatrix constructor that should produce "
765 "a fillComplete matrix, isFillActive() is true." << suffix);
766 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
768 "CrsMatrix constructor that should produce a fillComplete "
769 "matrix, isFillComplete() is false." << suffix);
773 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
776 const Teuchos::DataAccess copyOrView)
777 :
CrsMatrix (source.getCrsGraph (), source.getLocalValuesView ())
779 const char tfecfFuncName[] =
"Tpetra::CrsMatrix("
780 "const CrsMatrix&, const Teuchos::DataAccess): ";
781 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
783 "Source graph must be fillComplete().");
785 if (copyOrView == Teuchos::Copy) {
786 using values_type =
typename local_matrix_type::values_type;
788 using Kokkos::view_alloc;
789 using Kokkos::WithoutInitializing;
790 values_type newvals (view_alloc (
"val", WithoutInitializing),
798 else if (copyOrView == Teuchos::View) {
802 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
803 (
true, std::invalid_argument,
"Second argument 'copyOrView' "
804 "has an invalid value " << copyOrView <<
". Valid values "
805 "include Teuchos::Copy = " << Teuchos::Copy <<
" and "
806 "Teuchos::View = " << Teuchos::View <<
".");
810 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
815 std::swap(crs_matrix.
importMV_, this->importMV_);
816 std::swap(crs_matrix.
exportMV_, this->exportMV_);
817 std::swap(crs_matrix.staticGraph_, this->staticGraph_);
818 std::swap(crs_matrix.myGraph_, this->myGraph_);
819 std::swap(crs_matrix.
lclMatrix_, this->lclMatrix_);
820 std::swap(crs_matrix.
k_values1D_, this->k_values1D_);
823 std::swap(crs_matrix.
nonlocals_, this->nonlocals_);
824 std::swap(crs_matrix.
frobNorm_, this->frobNorm_);
827 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
828 Teuchos::RCP<const Teuchos::Comm<int> >
831 return getCrsGraphRef ().getComm ();
834 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
838 return this->getCrsGraphRef ().getProfileType ();
841 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
845 return fillComplete_;
848 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
852 return ! fillComplete_;
855 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
859 return this->getCrsGraphRef ().isStorageOptimized ();
862 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
866 return getCrsGraphRef ().isLocallyIndexed ();
869 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
873 return getCrsGraphRef ().isGloballyIndexed ();
876 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
880 return getCrsGraphRef ().hasColMap ();
883 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
887 return getCrsGraphRef ().getGlobalNumEntries ();
890 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
894 return getCrsGraphRef ().getNodeNumEntries ();
897 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
901 return getCrsGraphRef ().getGlobalNumRows ();
904 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
908 return getCrsGraphRef ().getGlobalNumCols ();
911 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
915 return getCrsGraphRef ().getNodeNumRows ();
918 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
922 return getCrsGraphRef ().getNodeNumCols ();
926 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
930 return getCrsGraphRef ().getNumEntriesInGlobalRow (globalRow);
933 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
937 return getCrsGraphRef ().getNumEntriesInLocalRow (localRow);
940 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
944 return getCrsGraphRef ().getGlobalMaxNumRowEntries ();
947 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
951 return getCrsGraphRef ().getNodeMaxNumRowEntries ();
954 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
958 return getRowMap ()->getIndexBase ();
961 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
962 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
965 return getCrsGraphRef ().getRowMap ();
968 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
969 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
972 return getCrsGraphRef ().getColMap ();
975 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
976 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
979 return getCrsGraphRef ().getDomainMap ();
982 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
983 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
986 return getCrsGraphRef ().getRangeMap ();
989 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
990 Teuchos::RCP<const RowGraph<LocalOrdinal, GlobalOrdinal, Node> >
993 if (staticGraph_ != Teuchos::null) {
999 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1000 Teuchos::RCP<const CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
1003 if (staticGraph_ != Teuchos::null) {
1004 return staticGraph_;
1009 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1014 #ifdef HAVE_TPETRA_DEBUG
1015 constexpr
bool debug =
true;
1017 constexpr
bool debug =
false;
1018 #endif // HAVE_TPETRA_DEBUG
1020 if (! this->staticGraph_.is_null ()) {
1021 return * (this->staticGraph_);
1025 const char tfecfFuncName[] =
"getCrsGraphRef: ";
1026 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1027 (this->myGraph_.is_null (), std::logic_error,
1028 "Both staticGraph_ and myGraph_ are null. "
1029 "Please report this bug to the Tpetra developers.");
1031 return * (this->myGraph_);
1035 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1036 typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_matrix_type
1040 return lclMatrix_.get () ==
nullptr ?
1042 lclMatrix_->getLocalMatrix ();
1045 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1046 std::shared_ptr<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_multiply_op_type>
1053 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1057 return myGraph_.is_null ();
1060 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1067 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1074 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1083 const char tfecfFuncName[] =
"allocateValues: ";
1084 const char suffix[] =
1085 " Please report this bug to the Tpetra developers.";
1086 ProfilingRegion region(
"Tpetra::CrsMatrix::allocateValues");
1088 std::unique_ptr<std::string> prefix;
1090 prefix = this->createPrefix(
"CrsMatrix",
"allocateValues");
1091 std::ostringstream os;
1092 os << *prefix <<
"lg: "
1093 << (lg == LocalIndices ?
"Local" :
"Global") <<
"Indices"
1095 << (gas == GraphAlreadyAllocated ?
"Already" :
"NotYet")
1096 <<
"Allocated" << endl;
1097 std::cerr << os.str();
1100 const bool debug = Behavior::debug(
"CrsMatrix");
1102 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1103 (this->staticGraph_.is_null (), std::logic_error,
1104 "staticGraph_ is null." << suffix);
1109 if ((gas == GraphAlreadyAllocated) !=
1110 staticGraph_->indicesAreAllocated ()) {
1111 const char err1[] =
"The caller has asserted that the graph "
1113 const char err2[] =
"already allocated, but the static graph "
1114 "says that its indices are ";
1115 const char err3[] =
"already allocated. ";
1116 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1117 (gas == GraphAlreadyAllocated &&
1118 ! staticGraph_->indicesAreAllocated (), std::logic_error,
1119 err1 << err2 <<
"not " << err3 << suffix);
1120 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1121 (gas != GraphAlreadyAllocated &&
1122 staticGraph_->indicesAreAllocated (), std::logic_error,
1123 err1 <<
"not " << err2 << err3 << suffix);
1131 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1132 (! this->staticGraph_->indicesAreAllocated () &&
1133 this->myGraph_.is_null (), std::logic_error,
1134 "The static graph says that its indices are not allocated, "
1135 "but the graph is not owned by the matrix." << suffix);
1138 if (gas == GraphNotYetAllocated) {
1140 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1141 (this->myGraph_.is_null (), std::logic_error,
1142 "gas = GraphNotYetAllocated, but myGraph_ is null." << suffix);
1145 this->myGraph_->allocateIndices (lg, verbose);
1147 catch (std::exception& e) {
1148 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1149 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1150 "threw an exception: " << e.what ());
1153 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1154 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1155 "threw an exception not a subclass of std::exception.");
1167 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1168 (this->staticGraph_.is_null (), std::logic_error,
1169 "this->getProfileType() == StaticProfile, but staticGraph_ "
1170 "is null." << suffix);
1173 const size_t lclNumRows = this->staticGraph_->getNodeNumRows ();
1174 typename Graph::local_graph_type::row_map_type k_ptrs =
1175 this->staticGraph_->k_rowPtrs_;
1176 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1177 (k_ptrs.extent (0) != lclNumRows+1, std::logic_error,
1178 "With StaticProfile, row offsets array has length "
1179 << k_ptrs.extent (0) <<
" != (lclNumRows+1) = "
1180 << (lclNumRows+1) <<
".");
1182 const size_t lclTotalNumEntries =
1183 ::Tpetra::Details::getEntryOnHost (k_ptrs, lclNumRows);
1186 using values_type =
typename local_matrix_type::values_type;
1188 std::ostringstream os;
1189 os << *prefix <<
"Allocate k_values1D_: Pre "
1190 << k_values1D_.extent(0) <<
", post "
1191 << lclTotalNumEntries << endl;
1192 std::cerr << os.str();
1195 values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1198 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1201 getAllValues (Teuchos::ArrayRCP<const size_t>& rowPointers,
1202 Teuchos::ArrayRCP<const LocalOrdinal>& columnIndices,
1203 Teuchos::ArrayRCP<const Scalar>& values)
const
1206 const char tfecfFuncName[] =
"getAllValues: ";
1207 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1208 columnIndices.size () != values.size (), std::runtime_error,
1209 "Requires that columnIndices and values are the same size.");
1211 RCP<const crs_graph_type> relevantGraph = getCrsGraph ();
1212 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1213 relevantGraph.is_null (), std::runtime_error,
1214 "Requires that getCrsGraph() is not null.");
1216 rowPointers = relevantGraph->getNodeRowPtrs ();
1218 catch (std::exception &e) {
1219 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1220 true, std::runtime_error,
1221 "Caught exception while calling graph->getNodeRowPtrs(): "
1225 columnIndices = relevantGraph->getNodePackedIndices ();
1227 catch (std::exception &e) {
1228 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1229 true, std::runtime_error,
1230 "Caught exception while calling graph->getNodePackedIndices(): "
1233 Teuchos::ArrayRCP<const impl_scalar_type> vals =
1234 Kokkos::Compat::persistingView (k_values1D_);
1235 values = Teuchos::arcp_reinterpret_cast<
const Scalar> (vals);
1238 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1244 using ::Tpetra::Details::getEntryOnHost;
1245 using Kokkos::create_mirror_view;
1246 using Teuchos::arcp_const_cast;
1247 using Teuchos::Array;
1248 using Teuchos::ArrayRCP;
1249 using Teuchos::null;
1253 using row_map_type =
typename local_matrix_type::row_map_type;
1254 using lclinds_1d_type =
typename Graph::local_graph_type::entries_type::non_const_type;
1255 using values_type =
typename local_matrix_type::values_type;
1257 (
"Tpetra::CrsGraph::fillLocalGraphAndMatrix");
1259 const char tfecfFuncName[] =
"fillLocalGraphAndMatrix (called from "
1260 "fillComplete or expertStaticFillComplete): ";
1261 const char suffix[] =
1262 " Please report this bug to the Tpetra developers.";
1266 std::unique_ptr<std::string> prefix;
1268 prefix = this->createPrefix(
"CrsMatrix",
"fillLocalGraphAndMatrix");
1269 std::ostringstream os;
1270 os << *prefix << endl;
1271 std::cerr << os.str ();
1277 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1278 (myGraph_.is_null (), std::logic_error,
"The nonconst graph "
1279 "(myGraph_) is null. This means that the matrix has a "
1280 "const (a.k.a. \"static\") graph. fillComplete or "
1281 "expertStaticFillComplete should never call "
1282 "fillLocalGraphAndMatrix in that case." << suffix);
1285 const size_t lclNumRows = this->getNodeNumRows ();
1293 typename row_map_type::non_const_type k_ptrs;
1294 row_map_type k_ptrs_const;
1295 lclinds_1d_type k_inds;
1301 lclinds_1d_type k_lclInds1D_ = myGraph_->k_lclInds1D_;
1303 typedef decltype (myGraph_->k_numRowEntries_) row_entries_type;
1311 typename Graph::local_graph_type::row_map_type curRowOffsets =
1312 myGraph_->k_rowPtrs_;
1315 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1316 (curRowOffsets.extent (0) == 0, std::logic_error,
1317 "(StaticProfile branch) curRowOffsets.extent(0) == 0.");
1318 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1319 (curRowOffsets.extent (0) != lclNumRows + 1, std::logic_error,
1320 "(StaticProfile branch) curRowOffsets.extent(0) = "
1321 << curRowOffsets.extent (0) <<
" != lclNumRows + 1 = "
1322 << (lclNumRows + 1) <<
".");
1323 const size_t numOffsets = curRowOffsets.extent (0);
1324 const auto valToCheck =
1325 getEntryOnHost (curRowOffsets, numOffsets - 1);
1326 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1328 myGraph_->k_lclInds1D_.extent (0) != valToCheck,
1329 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
1330 numOffsets <<
" != 0 and myGraph_->k_lclInds1D_.extent(0) = "
1331 << myGraph_->k_lclInds1D_.extent (0) <<
" != curRowOffsets("
1332 << numOffsets <<
") = " << valToCheck <<
".");
1335 if (myGraph_->getNodeNumEntries() !=
1336 myGraph_->getNodeAllocationSize()) {
1338 std::ostringstream os;
1339 const auto numEnt = myGraph_->getNodeNumEntries();
1340 const auto allocSize = myGraph_->getNodeAllocationSize();
1341 os << *prefix <<
"Unpacked 1-D storage: numEnt=" << numEnt
1342 <<
", allocSize=" << allocSize << endl;
1343 std::cerr << os.str ();
1351 if (debug && curRowOffsets.extent (0) != 0) {
1352 const size_t numOffsets =
1353 static_cast<size_t> (curRowOffsets.extent (0));
1354 const auto valToCheck =
1355 getEntryOnHost (curRowOffsets, numOffsets - 1);
1356 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1357 (static_cast<size_t> (valToCheck) !=
1358 static_cast<size_t> (k_values1D_.extent (0)),
1359 std::logic_error,
"(StaticProfile unpacked branch) Before "
1360 "allocating or packing, curRowOffsets(" << (numOffsets-1)
1361 <<
") = " << valToCheck <<
" != k_values1D_.extent(0)"
1362 " = " << k_values1D_.extent (0) <<
".");
1363 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1364 (static_cast<size_t> (valToCheck) !=
1365 static_cast<size_t> (myGraph_->k_lclInds1D_.extent (0)),
1366 std::logic_error,
"(StaticProfile unpacked branch) Before "
1367 "allocating or packing, curRowOffsets(" << (numOffsets-1)
1368 <<
") = " << valToCheck
1369 <<
" != myGraph_->k_lclInds1D_.extent(0) = "
1370 << myGraph_->k_lclInds1D_.extent (0) <<
".");
1378 size_t lclTotalNumEntries = 0;
1380 typename row_map_type::non_const_type::HostMirror h_ptrs;
1386 std::ostringstream os;
1387 os << *prefix <<
"Allocate packed row offsets: "
1388 << (lclNumRows+1) << endl;
1389 std::cerr << os.str ();
1391 typename row_map_type::non_const_type
1392 packedRowOffsets (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
1393 typename row_entries_type::const_type numRowEnt_h =
1394 myGraph_->k_numRowEntries_;
1397 lclTotalNumEntries =
1401 k_ptrs = packedRowOffsets;
1402 k_ptrs_const = k_ptrs;
1406 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1407 (static_cast<size_t> (k_ptrs.extent (0)) != lclNumRows + 1,
1409 "(StaticProfile unpacked branch) After packing k_ptrs, "
1410 "k_ptrs.extent(0) = " << k_ptrs.extent (0) <<
" != "
1411 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
1412 const auto valToCheck = getEntryOnHost (k_ptrs, lclNumRows);
1413 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1414 (valToCheck != lclTotalNumEntries, std::logic_error,
1415 "(StaticProfile unpacked branch) After filling k_ptrs, "
1416 "k_ptrs(lclNumRows=" << lclNumRows <<
") = " << valToCheck
1417 <<
" != total number of entries on the calling process = "
1418 << lclTotalNumEntries <<
".");
1423 std::ostringstream os;
1424 os << *prefix <<
"Allocate packed local column indices: "
1425 << lclTotalNumEntries << endl;
1426 std::cerr << os.str ();
1428 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::ind", lclTotalNumEntries);
1430 std::ostringstream os;
1431 os << *prefix <<
"Allocate packed values: "
1432 << lclTotalNumEntries << endl;
1433 std::cerr << os.str ();
1435 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1447 using inds_packer_type = pack_functor<
1448 typename Graph::local_graph_type::entries_type::non_const_type,
1449 typename Graph::local_graph_type::row_map_type>;
1450 inds_packer_type indsPacker (k_inds, myGraph_->k_lclInds1D_,
1451 k_ptrs, curRowOffsets);
1453 using range_type = Kokkos::RangePolicy<exec_space, LocalOrdinal>;
1454 Kokkos::parallel_for
1455 (
"Tpetra::CrsMatrix pack column indices",
1456 range_type (0, lclNumRows), indsPacker);
1460 using vals_packer_type = pack_functor<values_type, row_map_type>;
1461 vals_packer_type valsPacker (k_vals, this->k_values1D_,
1462 k_ptrs, curRowOffsets);
1463 Kokkos::parallel_for (
"Tpetra::CrsMatrix pack values",
1464 range_type (0, lclNumRows), valsPacker);
1467 const char myPrefix[] =
"(StaticProfile \"Optimize Storage\""
1468 "=true branch) After packing, ";
1469 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1470 (k_ptrs.extent (0) == 0, std::logic_error, myPrefix
1471 <<
"k_ptrs.extent(0) = 0. This probably means that "
1472 "k_rowPtrs_ was never allocated.");
1473 if (k_ptrs.extent (0) != 0) {
1474 const size_t numOffsets (k_ptrs.extent (0));
1475 const auto valToCheck =
1476 getEntryOnHost (k_ptrs, numOffsets - 1);
1477 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1478 (
size_t (valToCheck) != k_vals.extent (0),
1479 std::logic_error, myPrefix <<
1480 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1481 " != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1482 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1483 (
size_t (valToCheck) != k_inds.extent (0),
1484 std::logic_error, myPrefix <<
1485 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1486 " != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1492 std::ostringstream os;
1493 os << *prefix <<
"Storage already packed: k_rowPtrs_: "
1494 << myGraph_->k_rowPtrs_.extent(0) <<
", k_lclInds1D_: "
1495 << myGraph_->k_lclInds1D_.extent(0) <<
", k_values1D_: "
1496 << k_values1D_.extent(0) << endl;
1497 std::cerr << os.str();
1499 k_ptrs_const = myGraph_->k_rowPtrs_;
1500 k_inds = myGraph_->k_lclInds1D_;
1501 k_vals = this->k_values1D_;
1504 const char myPrefix[] =
1505 "(StaticProfile \"Optimize Storage\"=false branch) ";
1506 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1507 (k_ptrs_const.extent (0) == 0, std::logic_error, myPrefix
1508 <<
"k_ptrs_const.extent(0) = 0. This probably means "
1509 "that k_rowPtrs_ was never allocated.");
1510 if (k_ptrs_const.extent (0) != 0) {
1511 const size_t numOffsets (k_ptrs_const.extent (0));
1512 const auto valToCheck =
1513 getEntryOnHost (k_ptrs_const, numOffsets - 1);
1514 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1515 (
size_t (valToCheck) != k_vals.extent (0),
1516 std::logic_error, myPrefix <<
1517 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1518 <<
" != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1519 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1520 (
size_t (valToCheck) != k_inds.extent (0),
1521 std::logic_error, myPrefix <<
1522 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1523 <<
" != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1529 const char myPrefix[] =
"After packing, ";
1530 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1531 (
size_t (k_ptrs_const.extent (0)) !=
size_t (lclNumRows + 1),
1532 std::logic_error, myPrefix <<
"k_ptrs_const.extent(0) = "
1533 << k_ptrs_const.extent (0) <<
" != lclNumRows+1 = " <<
1534 (lclNumRows+1) <<
".");
1535 if (k_ptrs_const.extent (0) != 0) {
1536 const size_t numOffsets (k_ptrs_const.extent (0));
1537 const size_t k_ptrs_const_numOffsetsMinus1 =
1538 getEntryOnHost (k_ptrs_const, numOffsets - 1);
1539 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1540 (k_ptrs_const_numOffsetsMinus1 !=
size_t (k_vals.extent (0)),
1541 std::logic_error, myPrefix <<
"k_ptrs_const(" <<
1542 (numOffsets-1) <<
") = " << k_ptrs_const_numOffsetsMinus1
1543 <<
" != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1544 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1545 (k_ptrs_const_numOffsetsMinus1 !=
size_t (k_inds.extent (0)),
1546 std::logic_error, myPrefix <<
"k_ptrs_const(" <<
1547 (numOffsets-1) <<
") = " << k_ptrs_const_numOffsetsMinus1
1548 <<
" != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1556 const bool defaultOptStorage =
1557 ! isStaticGraph () || staticGraph_->isStorageOptimized ();
1558 const bool requestOptimizedStorage =
1559 (! params.is_null () &&
1560 params->get (
"Optimize Storage", defaultOptStorage)) ||
1561 (params.is_null () && defaultOptStorage);
1568 if (requestOptimizedStorage) {
1575 std::ostringstream os;
1576 os << *prefix <<
"Optimizing storage: free k_numRowEntries_: "
1577 << myGraph_->k_numRowEntries_.extent(0) << endl;
1578 std::cerr << os.str();
1580 myGraph_->k_numRowEntries_ = row_entries_type ();
1584 std::ostringstream os;
1585 os << *prefix <<
"Assign k_rowPtrs_: old="
1586 << myGraph_->k_rowPtrs_.extent(0) <<
", new="
1587 << k_ptrs_const.extent(0) << endl;
1588 std::cerr << os.str();
1590 myGraph_->k_rowPtrs_ = k_ptrs_const;
1592 std::ostringstream os;
1593 os << *prefix <<
"Assign k_lclInds1D_: old="
1594 << myGraph_->k_lclInds1D_.extent(0) <<
", new="
1595 << k_inds.extent(0) << endl;
1596 std::cerr << os.str();
1598 myGraph_->k_lclInds1D_ = k_inds;
1600 std::ostringstream os;
1601 os << *prefix <<
"Assign k_values1D_: old="
1602 << k_values1D_.extent(0) <<
", new="
1603 << k_vals.extent(0) << endl;
1604 std::cerr << os.str();
1606 this->k_values1D_ = k_vals;
1608 myGraph_->storageStatus_ = Details::STORAGE_1D_PACKED;
1609 this->storageStatus_ = Details::STORAGE_1D_PACKED;
1613 std::ostringstream os;
1614 os << *prefix <<
"User requestetd NOT to optimize storage"
1616 std::cerr << os.str();
1628 myGraph_->lclGraph_ =
1632 auto lclMat = std::make_shared<local_matrix_type>
1633 (
"Tpetra::CrsMatrix::lclMatrix_", getNodeNumCols (),
1634 k_vals, myGraph_->lclGraph_);
1635 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
1638 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1643 using ::Tpetra::Details::ProfilingRegion;
1644 using Kokkos::create_mirror_view;
1645 using Teuchos::ArrayRCP;
1646 using Teuchos::Array;
1647 using Teuchos::null;
1651 using row_map_type =
typename Graph::local_graph_type::row_map_type;
1652 using non_const_row_map_type =
typename row_map_type::non_const_type;
1653 using values_type =
typename local_matrix_type::values_type;
1654 ProfilingRegion regionFLM(
"Tpetra::CrsMatrix::fillLocalMatrix");
1655 const size_t lclNumRows = getNodeNumRows();
1658 std::unique_ptr<std::string> prefix;
1660 prefix = this->createPrefix(
"CrsMatrix",
"fillLocalMatrix");
1661 std::ostringstream os;
1662 os << *prefix <<
"lclNumRows: " << lclNumRows << endl;
1663 std::cerr << os.str ();
1675 size_t nodeNumEntries = staticGraph_->getNodeNumEntries ();
1676 size_t nodeNumAllocated = staticGraph_->getNodeAllocationSize ();
1677 row_map_type k_rowPtrs_ = staticGraph_->lclGraph_.row_map;
1679 row_map_type k_ptrs;
1685 bool requestOptimizedStorage =
true;
1686 const bool default_OptimizeStorage =
1687 ! isStaticGraph() || staticGraph_->isStorageOptimized();
1688 if (! params.is_null() &&
1689 ! params->get(
"Optimize Storage", default_OptimizeStorage)) {
1690 requestOptimizedStorage =
false;
1697 if (! staticGraph_->isStorageOptimized () &&
1698 requestOptimizedStorage) {
1700 (
true, std::runtime_error,
"You requested optimized storage "
1701 "by setting the \"Optimize Storage\" flag to \"true\" in "
1702 "the ParameterList, or by virtue of default behavior. "
1703 "However, the associated CrsGraph was filled separately and "
1704 "requested not to optimize storage. Therefore, the "
1705 "CrsMatrix cannot optimize storage.");
1706 requestOptimizedStorage =
false;
1709 using row_entries_type = decltype (staticGraph_->k_numRowEntries_);
1728 if (nodeNumEntries != nodeNumAllocated) {
1730 std::ostringstream os;
1731 os << *prefix <<
"Unpacked 1-D storage: numEnt="
1732 << nodeNumEntries <<
", allocSize=" << nodeNumAllocated
1734 std::cerr << os.str();
1739 std::ostringstream os;
1740 os << *prefix <<
"Allocate packed row offsets: "
1741 << (lclNumRows+1) << endl;
1742 std::cerr << os.str();
1744 non_const_row_map_type tmpk_ptrs (
"Tpetra::CrsGraph::ptr",
1749 size_t lclTotalNumEntries = 0;
1752 typename row_entries_type::const_type numRowEnt_d =
1753 staticGraph_->k_numRowEntries_;
1755 lclTotalNumEntries =
1762 std::ostringstream os;
1763 os << *prefix <<
"Allocate packed values: "
1764 << lclTotalNumEntries << endl;
1765 std::cerr << os.str ();
1767 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1770 pack_functor<values_type, row_map_type> valsPacker
1771 (k_vals, k_values1D_, tmpk_ptrs, k_rowPtrs_);
1774 using range_type = Kokkos::RangePolicy<exec_space, LocalOrdinal>;
1775 Kokkos::parallel_for (
"Tpetra::CrsMatrix pack values",
1776 range_type (0, lclNumRows), valsPacker);
1780 std::ostringstream os;
1781 os << *prefix <<
"Storage already packed: "
1782 <<
"k_values1D_: " << k_values1D_.extent(0) << endl;
1783 std::cerr << os.str();
1785 k_vals = k_values1D_;
1789 if (requestOptimizedStorage) {
1792 k_values1D_ = k_vals;
1793 this->storageStatus_ = Details::STORAGE_1D_PACKED;
1800 auto lclMat = std::make_shared<local_matrix_type>
1801 (
"Tpetra::CrsMatrix::lclMatrix_",
1802 getColMap ()->getNodeNumElements (),
1803 k_vals, staticGraph_->getLocalGraph ());
1804 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
1807 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1812 const typename crs_graph_type::SLocalGlobalViews& newInds,
1813 const Teuchos::ArrayView<impl_scalar_type>& oldRowVals,
1814 const Teuchos::ArrayView<const impl_scalar_type>& newRowVals,
1815 const ELocalGlobal lg,
1816 const ELocalGlobal I)
1818 const size_t oldNumEnt = rowInfo.numEntries;
1819 const size_t numInserted = graph.insertIndices (rowInfo, newInds, lg, I);
1825 if (numInserted > 0) {
1826 const size_t startOffset = oldNumEnt;
1827 memcpy (&oldRowVals[startOffset], &newRowVals[0],
1828 numInserted *
sizeof (impl_scalar_type));
1832 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1836 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1837 const Teuchos::ArrayView<const Scalar>& values)
1841 const char tfecfFuncName[] =
"insertLocalValues: ";
1843 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1844 (! this->isFillActive (), std::runtime_error,
1845 "Fill is not active. After calling fillComplete, you must call "
1846 "resumeFill before you may insert entries into the matrix again.");
1847 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1848 (this->isStaticGraph (), std::runtime_error,
1849 "Cannot insert indices with static graph; use replaceLocalValues() "
1853 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1854 (graph.
colMap_.is_null (), std::runtime_error,
1855 "Cannot insert local indices without a column map.");
1856 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1858 std::runtime_error,
"Graph indices are global; use "
1859 "insertGlobalValues().");
1860 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1861 (values.size () != indices.size (), std::runtime_error,
1862 "values.size() = " << values.size ()
1863 <<
" != indices.size() = " << indices.size () <<
".");
1864 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1865 ! graph.
rowMap_->isNodeLocalElement (lclRow), std::runtime_error,
1866 "Local row index " << lclRow <<
" does not belong to this process.");
1868 if (! graph.indicesAreAllocated ()) {
1872 this->allocateValues (LocalIndices, GraphNotYetAllocated, verbose);
1875 #ifdef HAVE_TPETRA_DEBUG
1876 const size_t numEntriesToAdd =
static_cast<size_t> (indices.size ());
1881 using Teuchos::toString;
1884 Teuchos::Array<LocalOrdinal> badColInds;
1885 bool allInColMap =
true;
1886 for (
size_t k = 0; k < numEntriesToAdd; ++k) {
1888 allInColMap =
false;
1889 badColInds.push_back (indices[k]);
1892 if (! allInColMap) {
1893 std::ostringstream os;
1894 os <<
"You attempted to insert entries in owned row " << lclRow
1895 <<
", at the following column indices: " << toString (indices)
1897 os <<
"Of those, the following indices are not in the column Map on "
1898 "this process: " << toString (badColInds) <<
"." << endl <<
"Since "
1899 "the matrix has a column Map already, it is invalid to insert "
1900 "entries at those locations.";
1901 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1902 (
true, std::invalid_argument, os.str ());
1905 #endif // HAVE_TPETRA_DEBUG
1909 Teuchos::ArrayView<IST> valsView = this->getViewNonConst(rowInfo);
1910 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset) {
1911 valsView[offset] += values[k]; };
1912 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
1913 graph.insertLocalIndicesImpl(lclRow, indices, cb);
1916 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1920 const LocalOrdinal numEnt,
1921 const Scalar vals[],
1922 const LocalOrdinal cols[])
1924 Teuchos::ArrayView<const LocalOrdinal> colsT (cols, numEnt);
1925 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
1926 this->insertLocalValues (localRow, colsT, valsT);
1929 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1934 const GlobalOrdinal gblColInds[],
1935 const impl_scalar_type vals[],
1936 const size_t numInputEnt)
1938 typedef impl_scalar_type IST;
1939 #ifdef HAVE_TPETRA_DEBUG
1940 const char tfecfFuncName[] =
"insertGlobalValuesImpl: ";
1942 const size_t curNumEnt = rowInfo.numEntries;
1943 #endif // HAVE_TPETRA_DEBUG
1945 if (! graph.indicesAreAllocated ()) {
1948 using ::Tpetra::Details::Behavior;
1949 const bool verbose = Behavior::verbose(
"CrsMatrix");
1950 this->allocateValues (GlobalIndices, GraphNotYetAllocated, verbose);
1955 rowInfo = graph.getRowInfo (rowInfo.localRow);
1958 Teuchos::ArrayView<IST> valsView = this->getViewNonConst(rowInfo);
1959 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset) {
1960 valsView[offset] += vals[k];
1962 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
1963 #ifdef HAVE_TPETRA_DEBUG
1967 graph.insertGlobalIndicesImpl(rowInfo, gblColInds, numInputEnt, cb);
1969 #ifdef HAVE_TPETRA_DEBUG
1970 size_t newNumEnt = curNumEnt + numInserted;
1971 const size_t chkNewNumEnt =
1972 graph.getNumEntriesInLocalRow (rowInfo.localRow);
1973 if (chkNewNumEnt != newNumEnt) {
1974 std::ostringstream os;
1975 os << std::endl <<
"newNumEnt = " << newNumEnt
1976 <<
" != graph.getNumEntriesInLocalRow(" << rowInfo.localRow
1977 <<
") = " << chkNewNumEnt <<
"." << std::endl
1978 <<
"\torigNumEnt: " << origNumEnt << std::endl
1979 <<
"\tnumInputEnt: " << numInputEnt << std::endl
1980 <<
"\tgblColInds: [";
1981 for (
size_t k = 0; k < numInputEnt; ++k) {
1982 os << gblColInds[k];
1983 if (k +
size_t (1) < numInputEnt) {
1987 os <<
"]" << std::endl
1989 for (
size_t k = 0; k < numInputEnt; ++k) {
1991 if (k +
size_t (1) < numInputEnt) {
1995 os <<
"]" << std::endl;
1997 if (this->supportsRowViews ()) {
1998 Teuchos::ArrayView<const Scalar> vals2;
1999 if (this->isGloballyIndexed ()) {
2000 Teuchos::ArrayView<const GlobalOrdinal> gblColInds2;
2001 const GlobalOrdinal gblRow =
2002 graph.rowMap_->getGlobalElement (rowInfo.localRow);
2003 if (gblRow == Tpetra::Details::OrdinalTraits<GlobalOrdinal>::invalid ()) {
2004 os <<
"Local row index " << rowInfo.localRow <<
" is invalid!" << std::endl;
2007 bool getViewThrew =
false;
2009 this->getGlobalRowView (gblRow, gblColInds2, vals2);
2011 catch (std::exception& e) {
2012 getViewThrew =
true;
2013 os <<
"getGlobalRowView threw exception:" << std::endl
2014 << e.what () << std::endl;
2016 if (! getViewThrew) {
2017 os <<
"\tNew global column indices: "
2018 << Teuchos::toString (gblColInds2) << std::endl
2019 <<
"\tNew values: " << Teuchos::toString (vals2) << std::endl;
2023 else if (this->isLocallyIndexed ()) {
2024 Teuchos::ArrayView<const LocalOrdinal> lclColInds2;
2025 this->getLocalRowView (rowInfo.localRow, lclColInds2, vals2);
2026 os <<
"\tNew local column indices: " << Teuchos::toString (lclColInds2)
2028 os <<
"\tNew values: " << Teuchos::toString (vals2) << std::endl;
2032 os <<
"Please report this bug to the Tpetra developers.";
2033 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2034 (
true, std::logic_error, os.str ());
2036 #endif // HAVE_TPETRA_DEBUG
2039 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2043 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2044 const Teuchos::ArrayView<const Scalar>& values)
2046 using Teuchos::toString;
2049 typedef LocalOrdinal LO;
2050 typedef GlobalOrdinal GO;
2051 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2052 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
2053 const char tfecfFuncName[] =
"insertGlobalValues: ";
2055 #ifdef HAVE_TPETRA_DEBUG
2056 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2057 (values.size () != indices.size (), std::runtime_error,
2058 "values.size() = " << values.size () <<
" != indices.size() = "
2059 << indices.size () <<
".");
2060 #endif // HAVE_TPETRA_DEBUG
2064 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2067 if (lclRow == OTLO::invalid ()) {
2074 this->insertNonownedGlobalValues (gblRow, indices, values);
2077 if (this->isStaticGraph ()) {
2079 const int myRank = rowMap.getComm ()->getRank ();
2080 const int numProcs = rowMap.getComm ()->getSize ();
2081 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2082 (
true, std::runtime_error,
2083 "The matrix was constructed with a constant (\"static\") graph, "
2084 "yet the given global row index " << gblRow <<
" is in the row "
2085 "Map on the calling process (with rank " << myRank <<
", of " <<
2086 numProcs <<
" process(es)). In this case, you may not insert "
2087 "new entries into rows owned by the calling process.");
2091 const IST*
const inputVals =
2092 reinterpret_cast<const IST*
> (values.getRawPtr ());
2093 const GO*
const inputGblColInds = indices.getRawPtr ();
2094 const size_t numInputEnt = indices.size ();
2103 if (! graph.
colMap_.is_null ()) {
2109 #ifdef HAVE_TPETRA_DEBUG
2110 Teuchos::Array<GO> badColInds;
2111 #endif // HAVE_TPETRA_DEBUG
2112 const size_type numEntriesToInsert = indices.size ();
2113 bool allInColMap =
true;
2114 for (size_type k = 0; k < numEntriesToInsert; ++k) {
2116 allInColMap =
false;
2117 #ifdef HAVE_TPETRA_DEBUG
2118 badColInds.push_back (indices[k]);
2121 #endif // HAVE_TPETRA_DEBUG
2124 if (! allInColMap) {
2125 std::ostringstream os;
2126 os <<
"You attempted to insert entries in owned row " << gblRow
2127 <<
", at the following column indices: " << toString (indices)
2129 #ifdef HAVE_TPETRA_DEBUG
2130 os <<
"Of those, the following indices are not in the column Map "
2131 "on this process: " << toString (badColInds) <<
"." << endl
2132 <<
"Since the matrix has a column Map already, it is invalid "
2133 "to insert entries at those locations.";
2135 os <<
"At least one of those indices is not in the column Map "
2136 "on this process." << endl <<
"It is invalid to insert into "
2137 "columns not in the column Map on the process that owns the "
2139 #endif // HAVE_TPETRA_DEBUG
2140 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2141 (
true, std::invalid_argument, os.str ());
2145 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2146 inputVals, numInputEnt);
2151 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2155 const LocalOrdinal numEnt,
2156 const Scalar vals[],
2157 const GlobalOrdinal inds[])
2159 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
2160 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
2161 this->insertGlobalValues (globalRow, indsT, valsT);
2165 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2169 const GlobalOrdinal gblRow,
2170 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2171 const Teuchos::ArrayView<const Scalar>& values,
2174 typedef impl_scalar_type IST;
2175 typedef LocalOrdinal LO;
2176 typedef GlobalOrdinal GO;
2177 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2178 const char tfecfFuncName[] =
"insertGlobalValuesFiltered: ";
2181 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2182 (values.size () != indices.size (), std::runtime_error,
2183 "values.size() = " << values.size () <<
" != indices.size() = "
2184 << indices.size () <<
".");
2189 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2190 const LO lclRow = rowMap.getLocalElement (gblRow);
2191 if (lclRow == OTLO::invalid ()) {
2198 this->insertNonownedGlobalValues (gblRow, indices, values);
2201 if (this->isStaticGraph ()) {
2203 const int myRank = rowMap.getComm ()->getRank ();
2204 const int numProcs = rowMap.getComm ()->getSize ();
2205 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2206 (
true, std::runtime_error,
2207 "The matrix was constructed with a constant (\"static\") graph, "
2208 "yet the given global row index " << gblRow <<
" is in the row "
2209 "Map on the calling process (with rank " << myRank <<
", of " <<
2210 numProcs <<
" process(es)). In this case, you may not insert "
2211 "new entries into rows owned by the calling process.");
2214 crs_graph_type& graph = * (this->myGraph_);
2215 const IST*
const inputVals =
2216 reinterpret_cast<const IST*
> (values.getRawPtr ());
2217 const GO*
const inputGblColInds = indices.getRawPtr ();
2218 const size_t numInputEnt = indices.size ();
2219 RowInfo rowInfo = graph.getRowInfo (lclRow);
2221 if (!graph.colMap_.is_null() && graph.isLocallyIndexed()) {
2228 const map_type& colMap = * (graph.colMap_);
2229 size_t curOffset = 0;
2230 while (curOffset < numInputEnt) {
2234 Teuchos::Array<LO> lclIndices;
2235 size_t endOffset = curOffset;
2236 for ( ; endOffset < numInputEnt; ++endOffset) {
2237 auto lclIndex = colMap.getLocalElement(inputGblColInds[endOffset]);
2238 if (lclIndex != OTLO::invalid())
2239 lclIndices.push_back(lclIndex);
2246 const LO numIndInSeq = (endOffset - curOffset);
2247 if (numIndInSeq != 0) {
2248 this->insertLocalValues(lclRow, lclIndices(), values(curOffset, numIndInSeq));
2254 const bool invariant = endOffset == numInputEnt ||
2255 colMap.getLocalElement (inputGblColInds[endOffset]) == OTLO::invalid ();
2256 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2257 (! invariant, std::logic_error, std::endl <<
"Invariant failed!");
2259 curOffset = endOffset + 1;
2262 else if (! graph.colMap_.is_null ()) {
2263 const map_type& colMap = * (graph.colMap_);
2264 size_t curOffset = 0;
2265 while (curOffset < numInputEnt) {
2269 size_t endOffset = curOffset;
2270 for ( ; endOffset < numInputEnt &&
2271 colMap.getLocalElement (inputGblColInds[endOffset]) != OTLO::invalid ();
2277 const LO numIndInSeq = (endOffset - curOffset);
2278 if (numIndInSeq != 0) {
2279 rowInfo = graph.getRowInfo(lclRow);
2280 this->insertGlobalValuesImpl (graph, rowInfo,
2281 inputGblColInds + curOffset,
2282 inputVals + curOffset,
2289 const bool invariant = endOffset == numInputEnt ||
2290 colMap.getLocalElement (inputGblColInds[endOffset]) == OTLO::invalid ();
2291 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2292 (! invariant, std::logic_error, std::endl <<
"Invariant failed!");
2294 curOffset = endOffset + 1;
2298 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2299 inputVals, numInputEnt);
2304 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2306 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2307 insertGlobalValuesFilteredChecked(
2308 const GlobalOrdinal gblRow,
2309 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2310 const Teuchos::ArrayView<const Scalar>& values,
2311 const char*
const prefix,
2319 insertGlobalValuesFiltered(gblRow, indices, values, debug);
2321 catch(std::exception& e) {
2322 std::ostringstream os;
2324 const size_t maxNumToPrint =
2326 os << *prefix <<
": insertGlobalValuesFiltered threw an "
2327 "exception: " << e.what() << endl
2328 <<
"Global row index: " << gblRow << endl;
2336 os <<
": insertGlobalValuesFiltered threw an exception: "
2339 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, os.str());
2343 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2345 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2346 replaceLocalValuesImpl (impl_scalar_type rowVals[],
2347 const crs_graph_type& graph,
2348 const RowInfo& rowInfo,
2349 const LocalOrdinal inds[],
2350 const impl_scalar_type newVals[],
2351 const LocalOrdinal numElts)
const
2353 typedef LocalOrdinal LO;
2354 typedef GlobalOrdinal GO;
2355 const bool sorted = graph.isSorted ();
2364 if (graph.isLocallyIndexed ()) {
2367 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2369 for (LO j = 0; j < numElts; ++j) {
2370 const LO lclColInd = inds[j];
2371 const size_t offset =
2372 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2373 lclColInd, hint, sorted);
2374 if (offset != rowInfo.numEntries) {
2375 rowVals[offset] = newVals[j];
2381 else if (graph.isGloballyIndexed ()) {
2382 if (graph.colMap_.is_null ()) {
2383 return Teuchos::OrdinalTraits<LO>::invalid ();
2385 const map_type colMap = * (graph.colMap_);
2389 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2391 for (LO j = 0; j < numElts; ++j) {
2392 const GO gblColInd = colMap.getGlobalElement (inds[j]);
2393 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2394 const size_t offset =
2395 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2396 gblColInd, hint, sorted);
2397 if (offset != rowInfo.numEntries) {
2398 rowVals[offset] = newVals[j];
2417 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2421 const Teuchos::ArrayView<const LocalOrdinal>& lclCols,
2422 const Teuchos::ArrayView<const Scalar>& vals)
const
2424 typedef LocalOrdinal LO;
2426 const LO numInputEnt =
static_cast<LO
> (lclCols.size ());
2427 if (static_cast<LO> (vals.size ()) != numInputEnt) {
2428 return Teuchos::OrdinalTraits<LO>::invalid ();
2430 const LO*
const inputInds = lclCols.getRawPtr ();
2431 const Scalar*
const inputVals = vals.getRawPtr ();
2432 return this->replaceLocalValues (localRow, numInputEnt,
2433 inputVals, inputInds);
2436 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2442 const Kokkos::View<const local_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
2443 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals)
const
2446 const LO numInputEnt = inputInds.extent(0);
2447 if (numInputEnt != static_cast<LO>(inputVals.extent(0))) {
2448 return Teuchos::OrdinalTraits<LO>::invalid();
2450 const Scalar*
const inVals =
2451 reinterpret_cast<const Scalar*
>(inputVals.data());
2452 return this->replaceLocalValues(localRow, numInputEnt,
2453 inVals, inputInds.data());
2456 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2460 const LocalOrdinal numEnt,
2461 const Scalar inputVals[],
2462 const LocalOrdinal inputCols[])
const
2465 typedef LocalOrdinal LO;
2467 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2469 return Teuchos::OrdinalTraits<LO>::invalid ();
2474 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2477 return static_cast<LO
> (0);
2479 auto curRowVals = this->getRowViewNonConst (rowInfo);
2480 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2481 return this->replaceLocalValuesImpl (curRowVals.data (), graph, rowInfo,
2482 inputCols, inVals, numEnt);
2485 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2489 const crs_graph_type& graph,
2491 const GlobalOrdinal inds[],
2492 const impl_scalar_type newVals[],
2493 const LocalOrdinal numElts)
const
2495 Teuchos::ArrayView<const GlobalOrdinal> indsT(inds, numElts);
2497 [&](
size_t const k,
size_t const ,
size_t const offset) {
2498 rowVals[offset] = newVals[k];
2500 std::function<void(size_t const, size_t const, size_t const)> cb(std::ref(fun));
2501 return graph.findGlobalIndices(rowInfo, indsT, cb);
2504 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2508 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2509 const Teuchos::ArrayView<const Scalar>& inputVals)
const
2511 typedef LocalOrdinal LO;
2513 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2514 if (static_cast<LO> (inputVals.size ()) != numInputEnt) {
2515 return Teuchos::OrdinalTraits<LO>::invalid ();
2517 return this->replaceGlobalValues (globalRow, numInputEnt,
2518 inputVals.getRawPtr (),
2519 inputGblColInds.getRawPtr ());
2522 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2526 const LocalOrdinal numEnt,
2527 const Scalar inputVals[],
2528 const GlobalOrdinal inputGblColInds[])
const
2531 typedef LocalOrdinal LO;
2533 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2535 return Teuchos::OrdinalTraits<LO>::invalid ();
2540 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2543 return static_cast<LO
> (0);
2546 auto curRowVals = this->getRowViewNonConst (rowInfo);
2547 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2548 return this->replaceGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2549 inputGblColInds, inVals, numEnt);
2552 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2558 const Kokkos::View<const global_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
2559 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals)
const
2568 const LO numInputEnt =
static_cast<LO
>(inputInds.extent(0));
2569 if (static_cast<LO>(inputVals.extent(0)) != numInputEnt) {
2570 return Teuchos::OrdinalTraits<LO>::invalid();
2572 const Scalar*
const inVals =
2573 reinterpret_cast<const Scalar*
>(inputVals.data());
2574 return this->replaceGlobalValues(globalRow, numInputEnt, inVals,
2578 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2582 const crs_graph_type& graph,
2584 const GlobalOrdinal inds[],
2585 const impl_scalar_type newVals[],
2586 const LocalOrdinal numElts,
2587 const bool atomic)
const
2589 typedef LocalOrdinal LO;
2590 typedef GlobalOrdinal GO;
2592 const bool sorted = graph.isSorted ();
2601 if (graph.isLocallyIndexed ()) {
2605 if (graph.colMap_.is_null ()) {
2611 const map_type& colMap = * (graph.colMap_);
2615 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2616 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2618 for (LO j = 0; j < numElts; ++j) {
2619 const LO lclColInd = colMap.getLocalElement (inds[j]);
2620 if (lclColInd != LINV) {
2621 const size_t offset =
2622 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2623 lclColInd, hint, sorted);
2624 if (offset != rowInfo.numEntries) {
2626 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2629 rowVals[offset] += newVals[j];
2637 else if (graph.isGloballyIndexed ()) {
2640 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2642 for (LO j = 0; j < numElts; ++j) {
2643 const GO gblColInd = inds[j];
2644 const size_t offset =
2645 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2646 gblColInd, hint, sorted);
2647 if (offset != rowInfo.numEntries) {
2649 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2652 rowVals[offset] += newVals[j];
2666 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2670 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2671 const Teuchos::ArrayView<const Scalar>& inputVals,
2674 typedef LocalOrdinal LO;
2676 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2677 if (static_cast<LO> (inputVals.size ()) != numInputEnt) {
2678 return Teuchos::OrdinalTraits<LO>::invalid ();
2680 return this->sumIntoGlobalValues (gblRow, numInputEnt,
2681 inputVals.getRawPtr (),
2682 inputGblColInds.getRawPtr (),
2686 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2690 const LocalOrdinal numInputEnt,
2691 const Scalar inputVals[],
2692 const GlobalOrdinal inputGblColInds[],
2696 typedef LocalOrdinal LO;
2697 typedef GlobalOrdinal GO;
2699 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2701 return Teuchos::OrdinalTraits<LO>::invalid ();
2706 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2711 using Teuchos::ArrayView;
2712 ArrayView<const GO> inputGblColInds_av(
2713 numInputEnt == 0 ?
nullptr : inputGblColInds,
2715 ArrayView<const Scalar> inputVals_av(
2716 numInputEnt == 0 ?
nullptr :
2717 inputVals, numInputEnt);
2722 this->insertNonownedGlobalValues (gblRow, inputGblColInds_av,
2733 auto curRowVals = this->getRowViewNonConst (rowInfo);
2734 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2735 return this->sumIntoGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2736 inputGblColInds, inVals,
2737 numInputEnt, atomic);
2741 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2745 const LocalOrdinal numInputEnt,
2746 const impl_scalar_type inputVals[],
2747 const LocalOrdinal inputCols[],
2748 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2749 const bool atomic)
const
2751 using Tpetra::Details::OrdinalTraits;
2752 typedef LocalOrdinal LO;
2754 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2756 return Teuchos::OrdinalTraits<LO>::invalid ();
2758 const crs_graph_type& graph = * (this->staticGraph_);
2759 const RowInfo rowInfo = graph.getRowInfo (lclRow);
2761 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2764 return static_cast<LO
> (0);
2766 auto curRowVals = this->getRowViewNonConst (rowInfo);
2767 return this->transformLocalValues (curRowVals.data (), graph,
2768 rowInfo, inputCols, inputVals,
2769 numInputEnt, f, atomic);
2772 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2774 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2775 transformGlobalValues (
const GlobalOrdinal gblRow,
2776 const LocalOrdinal numInputEnt,
2777 const impl_scalar_type inputVals[],
2778 const GlobalOrdinal inputCols[],
2779 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2780 const bool atomic)
const
2782 using Tpetra::Details::OrdinalTraits;
2783 typedef LocalOrdinal LO;
2785 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2787 return OrdinalTraits<LO>::invalid ();
2789 const crs_graph_type& graph = * (this->staticGraph_);
2790 const RowInfo rowInfo = graph.getRowInfoFromGlobalRowIndex (gblRow);
2792 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2795 return static_cast<LO
> (0);
2797 auto curRowVals = this->getRowViewNonConst (rowInfo);
2798 return this->transformGlobalValues (curRowVals.data (), graph,
2799 rowInfo, inputCols, inputVals,
2800 numInputEnt, f, atomic);
2803 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2805 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2806 transformLocalValues (impl_scalar_type rowVals[],
2807 const crs_graph_type& graph,
2808 const RowInfo& rowInfo,
2809 const LocalOrdinal inds[],
2810 const impl_scalar_type newVals[],
2811 const LocalOrdinal numElts,
2812 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2813 const bool atomic)
const
2815 typedef impl_scalar_type ST;
2816 typedef LocalOrdinal LO;
2817 typedef GlobalOrdinal GO;
2824 const bool sorted = graph.isSorted ();
2829 if (graph.isLocallyIndexed ()) {
2832 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2834 for (LO j = 0; j < numElts; ++j) {
2835 const LO lclColInd = inds[j];
2836 const size_t offset =
2837 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2838 lclColInd, hint, sorted);
2839 if (offset != rowInfo.numEntries) {
2848 volatile ST*
const dest = &rowVals[offset];
2849 (void) atomic_binary_function_update (dest, newVals[j], f);
2853 rowVals[offset] = f (rowVals[offset], newVals[j]);
2860 else if (graph.isGloballyIndexed ()) {
2864 if (graph.colMap_.is_null ()) {
2871 const map_type& colMap = * (graph.colMap_);
2874 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2876 const GO GINV = Teuchos::OrdinalTraits<GO>::invalid ();
2877 for (LO j = 0; j < numElts; ++j) {
2878 const GO gblColInd = colMap.getGlobalElement (inds[j]);
2879 if (gblColInd != GINV) {
2880 const size_t offset =
2881 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2882 gblColInd, hint, sorted);
2883 if (offset != rowInfo.numEntries) {
2892 volatile ST*
const dest = &rowVals[offset];
2893 (void) atomic_binary_function_update (dest, newVals[j], f);
2897 rowVals[offset] = f (rowVals[offset], newVals[j]);
2912 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2914 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2915 transformGlobalValues (impl_scalar_type rowVals[],
2916 const crs_graph_type& graph,
2917 const RowInfo& rowInfo,
2918 const GlobalOrdinal inds[],
2919 const impl_scalar_type newVals[],
2920 const LocalOrdinal numElts,
2921 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2922 const bool atomic)
const
2924 typedef impl_scalar_type ST;
2925 typedef LocalOrdinal LO;
2926 typedef GlobalOrdinal GO;
2933 const bool sorted = graph.isSorted ();
2938 if (graph.isGloballyIndexed ()) {
2941 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
2943 for (LO j = 0; j < numElts; ++j) {
2944 const GO gblColInd = inds[j];
2945 const size_t offset =
2946 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2947 gblColInd, hint, sorted);
2948 if (offset != rowInfo.numEntries) {
2957 volatile ST*
const dest = &rowVals[offset];
2958 (void) atomic_binary_function_update (dest, newVals[j], f);
2962 rowVals[offset] = f (rowVals[offset], newVals[j]);
2969 else if (graph.isLocallyIndexed ()) {
2973 if (graph.colMap_.is_null ()) {
2979 const map_type& colMap = * (graph.colMap_);
2982 auto colInds = graph.getLocalKokkosRowView (rowInfo);
2984 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2985 for (LO j = 0; j < numElts; ++j) {
2986 const LO lclColInd = colMap.getLocalElement (inds[j]);
2987 if (lclColInd != LINV) {
2988 const size_t offset =
2989 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2990 lclColInd, hint, sorted);
2991 if (offset != rowInfo.numEntries) {
3000 volatile ST*
const dest = &rowVals[offset];
3001 (void) atomic_binary_function_update (dest, newVals[j], f);
3005 rowVals[offset] = f (rowVals[offset], newVals[j]);
3020 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3022 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3023 sumIntoLocalValuesImpl (impl_scalar_type rowVals[],
3024 const crs_graph_type& graph,
3025 const RowInfo& rowInfo,
3026 const LocalOrdinal inds[],
3027 const impl_scalar_type newVals[],
3028 const LocalOrdinal numElts,
3029 const bool atomic)
const
3031 typedef LocalOrdinal LO;
3032 typedef GlobalOrdinal GO;
3034 const bool sorted = graph.isSorted ();
3043 if (graph.isLocallyIndexed ()) {
3046 auto colInds = graph.getLocalKokkosRowView (rowInfo);
3048 for (LO j = 0; j < numElts; ++j) {
3049 const LO lclColInd = inds[j];
3050 const size_t offset =
3051 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3052 lclColInd, hint, sorted);
3053 if (offset != rowInfo.numEntries) {
3055 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3058 rowVals[offset] += newVals[j];
3065 else if (graph.isGloballyIndexed ()) {
3066 if (graph.colMap_.is_null ()) {
3067 return Teuchos::OrdinalTraits<LO>::invalid ();
3069 const map_type colMap = * (graph.colMap_);
3073 auto colInds = graph.getGlobalKokkosRowView (rowInfo);
3075 for (LO j = 0; j < numElts; ++j) {
3076 const GO gblColInd = colMap.getGlobalElement (inds[j]);
3077 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
3078 const size_t offset =
3079 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3080 gblColInd, hint, sorted);
3081 if (offset != rowInfo.numEntries) {
3083 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3086 rowVals[offset] += newVals[j];
3106 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3110 const Teuchos::ArrayView<const LocalOrdinal>& indices,
3111 const Teuchos::ArrayView<const Scalar>& values,
3112 const bool atomic)
const
3115 const LO numInputEnt =
static_cast<LO
>(indices.size());
3116 if (static_cast<LO>(values.size()) != numInputEnt) {
3117 return Teuchos::OrdinalTraits<LO>::invalid();
3119 const LO*
const inputInds = indices.getRawPtr();
3120 const scalar_type*
const inputVals = values.getRawPtr();
3121 return this->sumIntoLocalValues(localRow, numInputEnt,
3122 inputVals, inputInds, atomic);
3125 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3131 const Kokkos::View<const local_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
3132 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals,
3133 const bool atomic)
const
3136 const LO numInputEnt =
static_cast<LO
>(inputInds.extent(0));
3137 if (static_cast<LO>(inputVals.extent(0)) != numInputEnt) {
3138 return Teuchos::OrdinalTraits<LO>::invalid();
3141 reinterpret_cast<const scalar_type*
>(inputVals.data());
3142 return this->sumIntoLocalValues(localRow, numInputEnt, inVals,
3143 inputInds.data(), atomic);
3146 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3150 const LocalOrdinal numEnt,
3151 const Scalar vals[],
3152 const LocalOrdinal cols[],
3153 const bool atomic)
const
3156 typedef LocalOrdinal LO;
3158 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
3160 return Teuchos::OrdinalTraits<LO>::invalid ();
3165 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
3168 return static_cast<LO
> (0);
3170 auto curRowVals = this->getRowViewNonConst (rowInfo);
3171 const IST*
const inputVals =
reinterpret_cast<const IST*
> (vals);
3172 return this->sumIntoLocalValuesImpl (curRowVals.data (), graph, rowInfo,
3173 cols, inputVals, numEnt, atomic);
3176 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3177 Teuchos::ArrayView<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type>
3181 using Kokkos::MemoryUnmanaged;
3183 using Teuchos::ArrayView;
3185 using range_type = std::pair<size_t, size_t>;
3187 if (k_values1D_.extent (0) != 0 && rowinfo.allocSize > 0) {
3188 #ifdef HAVE_TPETRA_DEBUG
3189 TEUCHOS_TEST_FOR_EXCEPTION(
3190 rowinfo.offset1D + rowinfo.allocSize > k_values1D_.extent (0),
3191 std::range_error,
"Tpetra::CrsMatrix::getView: Invalid access "
3192 "to 1-D storage of values." << std::endl <<
"rowinfo.offset1D (" <<
3193 rowinfo.offset1D <<
") + rowinfo.allocSize (" << rowinfo.allocSize <<
3194 ") > k_values1D_.extent(0) (" << k_values1D_.extent (0) <<
").");
3195 #endif // HAVE_TPETRA_DEBUG
3196 range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
3197 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
3204 subview_type sv = Kokkos::subview (subview_type (k_values1D_), range);
3205 const ST*
const sv_raw = (rowinfo.allocSize == 0) ?
nullptr : sv.data ();
3206 return ArrayView<const ST> (sv_raw, rowinfo.allocSize);
3209 return ArrayView<impl_scalar_type> ();
3214 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3218 LocalOrdinal& numEnt,
3221 #ifdef HAVE_TPETRA_DEBUG
3222 constexpr
bool debug =
true;
3224 constexpr
bool debug =
false;
3225 #endif // HAVE_TPETRA_DEBUG
3227 if (k_values1D_.extent (0) != 0 && rowinfo.allocSize > 0) {
3229 if (rowinfo.offset1D + rowinfo.allocSize > k_values1D_.extent (0)) {
3232 return Teuchos::OrdinalTraits<LocalOrdinal>::invalid ();
3235 vals = k_values1D_.data () + rowinfo.offset1D;
3236 numEnt = rowinfo.allocSize;
3243 return static_cast<LocalOrdinal
> (0);
3246 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3250 LocalOrdinal& numEnt,
3254 const LocalOrdinal err = this->getViewRawConst (valsConst, numEnt, rowinfo);
3259 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3260 Kokkos::View<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type*,
3262 Kokkos::MemoryUnmanaged>
3266 using Kokkos::MemoryUnmanaged;
3268 typedef impl_scalar_type ST;
3269 typedef View<const ST*, execution_space, MemoryUnmanaged> subview_type;
3270 typedef std::pair<size_t, size_t> range_type;
3272 if (k_values1D_.extent (0) != 0 && rowInfo.allocSize > 0) {
3273 #ifdef HAVE_TPETRA_DEBUG
3274 TEUCHOS_TEST_FOR_EXCEPTION
3275 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.extent (0),
3276 std::range_error,
"Tpetra::CrsMatrix::getRowView: Invalid access "
3277 "to 1-D storage of values. rowInfo.offset1D ("
3278 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
3279 <<
") > this->k_values1D_.extent(0) ("
3280 << this->k_values1D_.extent (0) <<
").");
3281 #endif // HAVE_TPETRA_DEBUG
3282 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
3289 return Kokkos::subview (subview_type (this->k_values1D_), range);
3292 return subview_type ();
3296 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3297 Kokkos::View<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type*,
3298 typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::execution_space,
3299 Kokkos::MemoryUnmanaged>
3300 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3301 getRowViewNonConst (
const RowInfo& rowInfo)
const
3303 using Kokkos::MemoryUnmanaged;
3305 typedef impl_scalar_type ST;
3306 typedef View<ST*, execution_space, MemoryUnmanaged> subview_type;
3307 typedef std::pair<size_t, size_t> range_type;
3309 if (k_values1D_.extent (0) != 0 && rowInfo.allocSize > 0) {
3310 #ifdef HAVE_TPETRA_DEBUG
3311 TEUCHOS_TEST_FOR_EXCEPTION
3312 (rowInfo.offset1D + rowInfo.allocSize > this->k_values1D_.extent (0),
3313 std::range_error,
"Tpetra::CrsMatrix::getRowViewNonConst: Invalid "
3314 "access to 1-D storage of values. rowInfo.offset1D ("
3315 << rowInfo.offset1D <<
") + rowInfo.allocSize (" << rowInfo.allocSize
3316 <<
") > this->k_values1D_.extent(0) ("
3317 << this->k_values1D_.extent (0) <<
").");
3318 #endif // HAVE_TPETRA_DEBUG
3319 range_type range (rowInfo.offset1D, rowInfo.offset1D + rowInfo.allocSize);
3326 return Kokkos::subview (subview_type (this->k_values1D_), range);
3329 return subview_type ();
3333 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3334 Teuchos::ArrayView<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type>
3341 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3345 const Teuchos::ArrayView<LocalOrdinal>& indices,
3346 const Teuchos::ArrayView<Scalar>& values,
3347 size_t& numEntries)
const
3349 using Teuchos::ArrayView;
3350 using Teuchos::av_reinterpret_cast;
3351 const char tfecfFuncName[] =
"getLocalRowCopy: ";
3353 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3354 (! this->hasColMap (), std::runtime_error,
3355 "The matrix does not have a column Map yet. This means we don't have "
3356 "local indices for columns yet, so it doesn't make sense to call this "
3357 "method. If the matrix doesn't have a column Map yet, you should call "
3358 "fillComplete on it first.");
3360 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3361 const size_t theNumEntries = rowinfo.numEntries;
3362 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3363 (static_cast<size_t> (indices.size ()) < theNumEntries ||
3364 static_cast<size_t> (values.size ()) < theNumEntries,
3365 std::runtime_error,
"Row with local index " << localRow <<
" has " <<
3366 theNumEntries <<
" entry/ies, but indices.size() = " <<
3367 indices.size () <<
" and values.size() = " << values.size () <<
".");
3368 numEntries = theNumEntries;
3370 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3371 if (staticGraph_->isLocallyIndexed ()) {
3372 const LocalOrdinal* curLclInds;
3374 LocalOrdinal numSpots;
3379 #ifdef HAVE_TPETRA_DEBUG
3381 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3382 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3383 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3384 "staticGraph_->getLocalViewRawConst returned nonzero error code "
3386 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3387 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3388 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3390 const LocalOrdinal numSpotsBefore = numSpots;
3391 err = getViewRawConst (curVals, numSpots, rowinfo);
3392 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3393 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3394 "getViewRaw returned nonzero error code " << err <<
".");
3395 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3396 (numSpotsBefore != numSpots, std::logic_error,
3397 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3398 << numSpots <<
".");
3400 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3401 (void) getViewRawConst (curVals, numSpots, rowinfo);
3402 #endif // HAVE_TPETRA_DEBUG
3404 for (
size_t j = 0; j < theNumEntries; ++j) {
3405 values[j] = curVals[j];
3406 indices[j] = curLclInds[j];
3409 else if (staticGraph_->isGloballyIndexed ()) {
3411 const map_type& colMap = * (staticGraph_->colMap_);
3412 const GlobalOrdinal* curGblInds;
3414 LocalOrdinal numSpots;
3419 #ifdef HAVE_TPETRA_DEBUG
3421 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3422 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3423 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3424 "staticGraph_->getGlobalViewRawConst returned nonzero error code "
3426 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3427 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3428 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3430 const LocalOrdinal numSpotsBefore = numSpots;
3431 err = getViewRawConst (curVals, numSpots, rowinfo);
3432 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3433 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3434 "getViewRawConst returned nonzero error code " << err <<
".");
3435 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3436 (numSpotsBefore != numSpots, std::logic_error,
3437 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3438 << numSpots <<
".");
3440 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3441 (void) getViewRawConst (curVals, numSpots, rowinfo);
3442 #endif //HAVE_TPETRA_DEBUG
3444 for (
size_t j = 0; j < theNumEntries; ++j) {
3445 values[j] = curVals[j];
3452 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3456 const Teuchos::ArrayView<GlobalOrdinal>& indices,
3457 const Teuchos::ArrayView<Scalar>& values,
3458 size_t& numEntries)
const
3460 using Teuchos::ArrayView;
3461 using Teuchos::av_reinterpret_cast;
3462 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
3465 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3466 const size_t theNumEntries = rowinfo.numEntries;
3467 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3468 static_cast<size_t> (indices.size ()) < theNumEntries ||
3469 static_cast<size_t> (values.size ()) < theNumEntries,
3470 std::runtime_error,
"Row with global index " << globalRow <<
" has "
3471 << theNumEntries <<
" entry/ies, but indices.size() = " <<
3472 indices.size () <<
" and values.size() = " << values.size () <<
".");
3473 numEntries = theNumEntries;
3475 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3476 if (staticGraph_->isLocallyIndexed ()) {
3477 const map_type& colMap = * (staticGraph_->colMap_);
3478 const LocalOrdinal* curLclInds;
3480 LocalOrdinal numSpots;
3485 #ifdef HAVE_TPETRA_DEBUG
3487 staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3488 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3489 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3490 "staticGraph_->getLocalViewRawConst returned nonzero error code "
3492 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3493 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3494 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3496 const LocalOrdinal numSpotsBefore = numSpots;
3497 err = getViewRawConst (curVals, numSpots, rowinfo);
3498 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3499 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3500 "getViewRaw returned nonzero error code " << err <<
".");
3501 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3502 (numSpotsBefore != numSpots, std::logic_error,
3503 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3504 << numSpots <<
".");
3506 (void) staticGraph_->getLocalViewRawConst (curLclInds, numSpots, rowinfo);
3507 (void) getViewRawConst (curVals, numSpots, rowinfo);
3508 #endif //HAVE_TPETRA_DEBUG
3510 for (
size_t j = 0; j < theNumEntries; ++j) {
3511 values[j] = curVals[j];
3515 else if (staticGraph_->isGloballyIndexed ()) {
3516 const GlobalOrdinal* curGblInds;
3518 LocalOrdinal numSpots;
3523 #ifdef HAVE_TPETRA_DEBUG
3525 staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3526 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3527 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3528 "staticGraph_->getGlobalViewRawConst returned nonzero error code "
3530 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3531 (static_cast<size_t> (numSpots) < theNumEntries, std::logic_error,
3532 "numSpots = " << numSpots <<
" < theNumEntries = " << theNumEntries
3534 const LocalOrdinal numSpotsBefore = numSpots;
3535 err = getViewRawConst (curVals, numSpots, rowinfo);
3536 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3537 (err != static_cast<LocalOrdinal> (0), std::logic_error,
3538 "getViewRawConst returned nonzero error code " << err <<
".");
3539 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3540 (numSpotsBefore != numSpots, std::logic_error,
3541 "numSpotsBefore = " << numSpotsBefore <<
" != numSpots = "
3542 << numSpots <<
".");
3544 (void) staticGraph_->getGlobalViewRawConst (curGblInds, numSpots, rowinfo);
3545 (void) getViewRawConst (curVals, numSpots, rowinfo);
3546 #endif //HAVE_TPETRA_DEBUG
3548 for (
size_t j = 0; j < theNumEntries; ++j) {
3549 values[j] = curVals[j];
3550 indices[j] = curGblInds[j];
3556 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3560 Teuchos::ArrayView<const LocalOrdinal>& indices,
3561 Teuchos::ArrayView<const Scalar>& values)
const
3563 using Teuchos::ArrayView;
3564 using Teuchos::av_reinterpret_cast;
3565 typedef LocalOrdinal LO;
3566 const char tfecfFuncName[] =
"getLocalRowView: ";
3568 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3569 isGloballyIndexed (), std::runtime_error,
"The matrix currently stores "
3570 "its indices as global indices, so you cannot get a view with local "
3571 "column indices. If the matrix has a column Map, you may call "
3572 "getLocalRowCopy() to get local column indices; otherwise, you may get "
3573 "a view with global column indices by calling getGlobalRowCopy().");
3574 indices = Teuchos::null;
3575 values = Teuchos::null;
3576 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3577 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3578 rowinfo.numEntries > 0) {
3579 ArrayView<const LO> indTmp = staticGraph_->getLocalView (rowinfo);
3580 ArrayView<const Scalar> valTmp =
3581 av_reinterpret_cast<
const Scalar> (this->getView (rowinfo));
3582 indices = indTmp (0, rowinfo.numEntries);
3583 values = valTmp (0, rowinfo.numEntries);
3586 #ifdef HAVE_TPETRA_DEBUG
3587 const char suffix[] =
". This should never happen. Please report this "
3588 "bug to the Tpetra developers.";
3589 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3590 (static_cast<size_t> (indices.size ()) !=
3591 static_cast<size_t> (values.size ()), std::logic_error,
3592 "At the end of this method, for local row " << localRow <<
", "
3593 "indices.size() = " << indices.size () <<
" != values.size () = "
3594 << values.size () << suffix);
3595 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3596 (static_cast<size_t> (indices.size ()) !=
3597 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3598 "At the end of this method, for local row " << localRow <<
", "
3599 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3600 << rowinfo.numEntries << suffix);
3601 const size_t expectedNumEntries = getNumEntriesInLocalRow (localRow);
3602 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3603 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3604 "of this method, for local row " << localRow <<
", rowinfo.numEntries = "
3605 << rowinfo.numEntries <<
" != getNumEntriesInLocalRow(localRow) = " <<
3606 expectedNumEntries << suffix);
3607 #endif // HAVE_TPETRA_DEBUG
3610 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3614 LocalOrdinal& numEnt,
3616 const LocalOrdinal*& ind)
const
3618 typedef LocalOrdinal LO;
3625 if (staticGraph_.is_null () || staticGraph_->isGloballyIndexed ()) {
3626 return Tpetra::Details::OrdinalTraits<LO>::invalid ();
3629 const RowInfo rowInfo = staticGraph_->getRowInfo (lclRow);
3630 if (rowInfo.localRow == Tpetra::Details::OrdinalTraits<size_t>::invalid ()) {
3635 return static_cast<LO
> (1);
3638 numEnt =
static_cast<LO
> (rowInfo.numEntries);
3639 auto lclColInds = staticGraph_->getLocalKokkosRowView (rowInfo);
3640 ind = lclColInds.data ();
3641 const LO err = this->getViewRawConst (val, numEnt, rowInfo);
3647 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3651 LocalOrdinal& numEnt,
3652 const LocalOrdinal*& lclColInds,
3653 const Scalar*& vals)
const
3656 const LocalOrdinal errCode =
3657 this->getLocalRowView (lclRow, numEnt, vals_ist, lclColInds);
3658 vals =
reinterpret_cast<const Scalar*
> (vals_ist);
3662 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3666 Teuchos::ArrayView<const GlobalOrdinal>& indices,
3667 Teuchos::ArrayView<const Scalar>& values)
const
3669 using Teuchos::ArrayView;
3670 using Teuchos::av_reinterpret_cast;
3671 typedef GlobalOrdinal GO;
3672 const char tfecfFuncName[] =
"getGlobalRowView: ";
3674 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3675 isLocallyIndexed (), std::runtime_error,
3676 "The matrix is locally indexed, so we cannot return a view of the row "
3677 "with global column indices. Use getGlobalRowCopy() instead.");
3678 indices = Teuchos::null;
3679 values = Teuchos::null;
3681 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3682 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3683 rowinfo.numEntries > 0) {
3684 ArrayView<const GO> indTmp = staticGraph_->getGlobalView (rowinfo);
3685 ArrayView<const Scalar> valTmp =
3686 av_reinterpret_cast<
const Scalar> (this->getView (rowinfo));
3687 #ifdef HAVE_TPETRA_DEBUG
3688 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3689 (static_cast<size_t> (indTmp.size ()) < rowinfo.numEntries ||
3690 static_cast<size_t> (valTmp.size ()) < rowinfo.numEntries,
3691 std::logic_error, std::endl <<
"rowinfo.numEntries not accurate. "
3692 << std::endl <<
"indTmp.size() = " << indTmp.size ()
3693 <<
", valTmp.size() = " << valTmp.size ()
3694 <<
", rowinfo.numEntries = " << rowinfo.numEntries <<
".");
3695 #endif // HAVE_TPETRA_DEBUG
3696 indices = indTmp (0, rowinfo.numEntries);
3697 values = valTmp (0, rowinfo.numEntries);
3700 #ifdef HAVE_TPETRA_DEBUG
3701 const char suffix[] =
". This should never happen. Please report this "
3702 "bug to the Tpetra developers.";
3703 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3704 (static_cast<size_t> (indices.size ()) !=
3705 static_cast<size_t> (values.size ()), std::logic_error,
3706 "At the end of this method, for global row " << globalRow <<
", "
3707 "indices.size() = " << indices.size () <<
" != values.size () = "
3708 << values.size () << suffix);
3709 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3710 (static_cast<size_t> (indices.size ()) !=
3711 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3712 "At the end of this method, for global row " << globalRow <<
", "
3713 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3714 << rowinfo.numEntries << suffix);
3715 const size_t expectedNumEntries = getNumEntriesInGlobalRow (globalRow);
3716 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3717 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3718 "of this method, for global row " << globalRow <<
", rowinfo.numEntries "
3719 "= " << rowinfo.numEntries <<
" != getNumEntriesInGlobalRow(globalRow) ="
3720 " " << expectedNumEntries << suffix);
3721 #endif // HAVE_TPETRA_DEBUG
3724 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3729 typedef LocalOrdinal LO;
3730 const char tfecfFuncName[] =
"scale: ";
3733 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3734 ! isFillActive (), std::runtime_error,
3735 "Fill must be active before you may call this method. "
3736 "Please call resumeFill() to make fill active.");
3738 const size_t nlrs = staticGraph_->getNodeNumRows ();
3739 const size_t numEntries = staticGraph_->getNodeNumEntries ();
3740 if (! staticGraph_->indicesAreAllocated () ||
3741 nlrs == 0 || numEntries == 0) {
3745 auto lclMat = this->getLocalMatrix ();
3747 const LO lclNumRows = lclMat.numRows ();
3748 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
3749 auto row_i = lclMat.row (lclRow);
3750 for (LO k = 0; k < row_i.length; ++k) {
3752 row_i.value (k) *= theAlpha;
3758 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3763 const char tfecfFuncName[] =
"setAllToScalar: ";
3765 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3766 ! isFillActive (), std::runtime_error,
3767 "Fill must be active before you may call this method. "
3768 "Please call resumeFill() to make fill active.");
3774 const size_t numEntries = staticGraph_->getNodeNumEntries();
3775 if (! staticGraph_->indicesAreAllocated () || numEntries == 0) {
3786 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3790 const typename local_graph_type::entries_type::non_const_type& columnIndices,
3791 const typename local_matrix_type::values_type& values)
3793 const char tfecfFuncName[] =
"setAllValues: ";
3794 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3795 (columnIndices.size () != values.size (), std::invalid_argument,
3796 "columnIndices.size() = " << columnIndices.size () <<
" != values.size()"
3797 " = " << values.size () <<
".");
3798 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3799 (myGraph_.is_null (), std::runtime_error,
"myGraph_ must not be null.");
3802 myGraph_->setAllIndices (rowPointers, columnIndices);
3804 catch (std::exception &e) {
3805 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3806 (
true, std::runtime_error,
"myGraph_->setAllIndices() threw an "
3807 "exception: " << e.what ());
3813 auto lclGraph = myGraph_->getLocalGraph ();
3814 const size_t numEnt = lclGraph.entries.extent (0);
3815 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3816 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
3817 numEnt !=
static_cast<size_t> (columnIndices.extent (0)),
3818 std::logic_error,
"myGraph_->setAllIndices() did not correctly create "
3819 "local graph. Please report this bug to the Tpetra developers.");
3821 const size_t numCols = myGraph_->getColMap ()->getNodeNumElements ();
3823 auto lclMat = std::make_shared<local_matrix_type>
3824 (
"Tpetra::CrsMatrix::lclMatrix_", numCols, values, lclGraph);
3825 lclMatrix_ = std::make_shared<local_multiply_op_type> (lclMat);
3830 k_values1D_ = lclMat->values;
3834 this->storageStatus_ = Details::STORAGE_1D_PACKED;
3836 checkInternalState ();
3839 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3843 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
3844 const Teuchos::ArrayRCP<Scalar>& val)
3846 using Kokkos::Compat::getKokkosViewDeepCopy;
3847 using Teuchos::ArrayRCP;
3848 using Teuchos::av_reinterpret_cast;
3851 typedef typename local_matrix_type::row_map_type row_map_type;
3853 const char tfecfFuncName[] =
"setAllValues(ArrayRCP<size_t>, ArrayRCP<LO>, ArrayRCP<Scalar>): ";
3859 typename row_map_type::non_const_type ptrNative (
"ptr", ptr.size ());
3860 Kokkos::View<
const size_t*,
3861 typename row_map_type::array_layout,
3863 Kokkos::MemoryUnmanaged> ptrSizeT (ptr.getRawPtr (), ptr.size ());
3866 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3867 (ptrNative.extent (0) != ptrSizeT.extent (0),
3868 std::logic_error,
"ptrNative.extent(0) = " <<
3869 ptrNative.extent (0) <<
" != ptrSizeT.extent(0) = "
3870 << ptrSizeT.extent (0) <<
". Please report this bug to the "
3871 "Tpetra developers.");
3873 auto indIn = getKokkosViewDeepCopy<DT> (ind ());
3874 auto valIn = getKokkosViewDeepCopy<DT> (av_reinterpret_cast<IST> (val ()));
3875 this->setAllValues (ptrNative, indIn, valIn);
3878 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3883 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
3884 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3885 (staticGraph_.is_null (), std::runtime_error,
"The matrix has no graph.");
3892 const size_t lclNumRows = staticGraph_->getNodeNumRows ();
3893 if (static_cast<size_t> (offsets.size ()) < lclNumRows) {
3894 offsets.resize (lclNumRows);
3900 typedef typename device_type::memory_space memory_space;
3901 if (std::is_same<memory_space, Kokkos::HostSpace>::value) {
3906 Kokkos::MemoryUnmanaged> output_type;
3907 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
3908 staticGraph_->getLocalDiagOffsets (offsetsOut);
3911 Kokkos::View<size_t*, device_type> offsetsTmp (
"diagOffsets", lclNumRows);
3912 staticGraph_->getLocalDiagOffsets (offsetsTmp);
3913 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
3914 Kokkos::MemoryUnmanaged> output_type;
3915 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
3920 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3925 using Teuchos::ArrayRCP;
3926 using Teuchos::ArrayView;
3927 using Teuchos::av_reinterpret_cast;
3928 const char tfecfFuncName[] =
"getLocalDiagCopy (1-arg): ";
3932 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3933 staticGraph_.is_null (), std::runtime_error,
3934 "This method requires that the matrix have a graph.");
3935 auto rowMapPtr = this->getRowMap ();
3936 if (rowMapPtr.is_null () || rowMapPtr->getComm ().is_null ()) {
3942 auto colMapPtr = this->getColMap ();
3943 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3944 (! this->hasColMap () || colMapPtr.is_null (), std::runtime_error,
3945 "This method requires that the matrix have a column Map.");
3946 const map_type& rowMap = * rowMapPtr;
3947 const map_type& colMap = * colMapPtr;
3948 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
3950 #ifdef HAVE_TPETRA_DEBUG
3953 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3954 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
3955 "The input Vector's Map must be compatible with the CrsMatrix's row "
3956 "Map. You may check this by using Map's isCompatible method: "
3957 "diag.getMap ()->isCompatible (A.getRowMap ());");
3958 #endif // HAVE_TPETRA_DEBUG
3960 if (this->isFillComplete ()) {
3961 diag.template modify<device_type> ();
3962 const auto D_lcl = diag.template getLocalView<device_type> ();
3964 const auto D_lcl_1d =
3965 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
3967 const auto lclRowMap = rowMap.getLocalMap ();
3972 lclMatrix_->getLocalMatrix ());
3980 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3985 Kokkos::MemoryUnmanaged>& offsets)
const
3987 typedef LocalOrdinal LO;
3989 #ifdef HAVE_TPETRA_DEBUG
3990 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
3991 const map_type& rowMap = * (this->getRowMap ());
3994 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3995 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
3996 "The input Vector's Map must be compatible with (in the sense of Map::"
3997 "isCompatible) the CrsMatrix's row Map.");
3998 #endif // HAVE_TPETRA_DEBUG
4007 diag.template modify<device_type> ();
4008 auto D_lcl = diag.template getLocalView<device_type> ();
4009 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4012 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
4014 KokkosSparse::getDiagCopy (D_lcl_1d, offsets,
4015 lclMatrix_->getLocalMatrix ());
4018 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4022 const Teuchos::ArrayView<const size_t>& offsets)
const
4024 using LO = LocalOrdinal;
4025 using host_execution_space = Kokkos::DefaultHostExecutionSpace;
4028 #ifdef HAVE_TPETRA_DEBUG
4029 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
4030 const map_type& rowMap = * (this->getRowMap ());
4033 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4034 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4035 "The input Vector's Map must be compatible with (in the sense of Map::"
4036 "isCompatible) the CrsMatrix's row Map.");
4037 #endif // HAVE_TPETRA_DEBUG
4050 auto lclVecHost1d = Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
4052 using host_offsets_view_type =
4053 Kokkos::View<
const size_t*, Kokkos::HostSpace,
4054 Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
4055 host_offsets_view_type h_offsets (offsets.getRawPtr (), offsets.size ());
4057 using range_type = Kokkos::RangePolicy<host_execution_space, LO>;
4058 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4059 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
4062 Kokkos::parallel_for
4063 (
"Tpetra::CrsMatrix::getLocalDiagCopy",
4064 range_type (0, myNumRows),
4065 [&] (
const LO lclRow) {
4066 lclVecHost1d(lclRow) = STS::zero ();
4067 if (h_offsets[lclRow] != INV) {
4068 auto curRow = lclMat.rowConst (lclRow);
4069 lclVecHost1d(lclRow) =
static_cast<IST
> (curRow.value(h_offsets[lclRow]));
4076 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4081 using ::Tpetra::Details::ProfilingRegion;
4082 using Teuchos::ArrayRCP;
4083 using Teuchos::ArrayView;
4084 using Teuchos::null;
4087 using Teuchos::rcpFromRef;
4090 const char tfecfFuncName[] =
"leftScale: ";
4092 ProfilingRegion region (
"Tpetra::CrsMatrix::leftScale");
4094 RCP<const vec_type> xp;
4095 if (this->getRangeMap ()->isSameAs (* (x.
getMap ()))) {
4098 auto exporter = this->getCrsGraphRef ().getExporter ();
4099 if (exporter.get () !=
nullptr) {
4100 RCP<vec_type> tempVec (
new vec_type (this->getRowMap ()));
4101 tempVec->doImport (x, *exporter,
REPLACE);
4105 xp = rcpFromRef (x);
4108 else if (this->getRowMap ()->isSameAs (* (x.
getMap ()))) {
4109 xp = rcpFromRef (x);
4112 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4113 (
true, std::invalid_argument,
"x's Map must be the same as "
4114 "either the row Map or the range Map of the CrsMatrix.");
4117 if (this->isFillComplete()) {
4118 using dev_memory_space =
typename device_type::memory_space;
4119 if (xp->template need_sync<dev_memory_space> ()) {
4120 using Teuchos::rcp_const_cast;
4121 rcp_const_cast<vec_type> (xp)->
template sync<dev_memory_space> ();
4123 auto x_lcl = xp->template getLocalView<dev_memory_space> ();
4124 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4127 x_lcl_1d,
false,
false);
4131 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4132 (
true, std::runtime_error,
"CrsMatrix::leftScale requires matrix to be"
4137 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4142 using ::Tpetra::Details::ProfilingRegion;
4143 using Teuchos::ArrayRCP;
4144 using Teuchos::ArrayView;
4145 using Teuchos::null;
4148 using Teuchos::rcpFromRef;
4151 const char tfecfFuncName[] =
"rightScale: ";
4153 ProfilingRegion region (
"Tpetra::CrsMatrix::rightScale");
4155 RCP<const vec_type> xp;
4156 if (this->getDomainMap ()->isSameAs (* (x.
getMap ()))) {
4159 auto importer = this->getCrsGraphRef ().getImporter ();
4160 if (importer.get () !=
nullptr) {
4161 RCP<vec_type> tempVec (
new vec_type (this->getColMap ()));
4162 tempVec->doImport (x, *importer,
REPLACE);
4166 xp = rcpFromRef (x);
4169 else if (this->getColMap ()->isSameAs (* (x.
getMap ()))) {
4170 xp = rcpFromRef (x);
4172 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4173 (
true, std::runtime_error,
"x's Map must be the same as "
4174 "either the domain Map or the column Map of the CrsMatrix.");
4177 if (this->isFillComplete()) {
4178 using dev_memory_space =
typename device_type::memory_space;
4179 if (xp->template need_sync<dev_memory_space> ()) {
4180 using Teuchos::rcp_const_cast;
4181 rcp_const_cast<vec_type> (xp)->
template sync<dev_memory_space> ();
4183 auto x_lcl = xp->template getLocalView<dev_memory_space> ();
4184 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4187 x_lcl_1d,
false,
false);
4191 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4192 (
true, std::runtime_error,
"CrsMatrix::rightScale requires matrix to be"
4197 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4202 using Teuchos::ArrayView;
4203 using Teuchos::outArg;
4204 using Teuchos::REDUCE_SUM;
4205 using Teuchos::reduceAll;
4206 typedef typename Teuchos::ArrayRCP<const impl_scalar_type>::size_type size_type;
4214 if (frobNorm == -STM::one ()) {
4216 if (getNodeNumEntries() > 0) {
4217 if (isStorageOptimized ()) {
4220 const size_type numEntries =
4221 static_cast<size_type
> (getNodeNumEntries ());
4222 for (size_type k = 0; k < numEntries; ++k) {
4228 const mag_type val_abs = STS::abs (val);
4229 mySum += val_abs * val_abs;
4233 const LocalOrdinal numRows =
4234 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
4235 for (LocalOrdinal r = 0; r < numRows; ++r) {
4236 const RowInfo rowInfo = myGraph_->getRowInfo (r);
4237 const size_type numEntries =
4238 static_cast<size_type
> (rowInfo.numEntries);
4239 ArrayView<const impl_scalar_type> A_r =
4240 this->getView (rowInfo).view (0, numEntries);
4241 for (size_type k = 0; k < numEntries; ++k) {
4243 const mag_type val_abs = STS::abs (val);
4244 mySum += val_abs * val_abs;
4250 reduceAll<int, mag_type> (* (getComm ()), REDUCE_SUM,
4251 mySum, outArg (totalSum));
4252 frobNorm = STM::sqrt (totalSum);
4254 if (isFillComplete ()) {
4258 frobNorm_ = frobNorm;
4263 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4268 const char tfecfFuncName[] =
"replaceColMap: ";
4272 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4273 myGraph_.is_null (), std::runtime_error,
4274 "This method does not work if the matrix has a const graph. The whole "
4275 "idea of a const graph is that you are not allowed to change it, but "
4276 "this method necessarily must modify the graph, since the graph owns "
4277 "the matrix's column Map.");
4278 myGraph_->replaceColMap (newColMap);
4281 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4285 const Teuchos::RCP<const map_type>& newColMap,
4286 const Teuchos::RCP<const import_type>& newImport,
4287 const bool sortEachRow)
4289 const char tfecfFuncName[] =
"reindexColumns: ";
4290 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4291 graph ==
nullptr && myGraph_.is_null (), std::invalid_argument,
4292 "The input graph is null, but the matrix does not own its graph.");
4294 crs_graph_type& theGraph = (graph ==
nullptr) ? *myGraph_ : *graph;
4295 const bool sortGraph =
false;
4297 if (sortEachRow && theGraph.isLocallyIndexed () && ! theGraph.isSorted ()) {
4298 const LocalOrdinal lclNumRows =
4299 static_cast<LocalOrdinal
> (theGraph.getNodeNumRows ());
4300 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
4301 const RowInfo rowInfo = theGraph.getRowInfo (row);
4302 auto lclColInds = theGraph.getLocalKokkosRowViewNonConst (rowInfo);
4303 auto vals = this->getRowViewNonConst (rowInfo);
4306 sort2 (lclColInds.data (),
4307 lclColInds.data () + rowInfo.numEntries,
4310 theGraph.indicesAreSorted_ =
true;
4314 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4318 Teuchos::RCP<const import_type>& newImporter)
4320 const char tfecfFuncName[] =
"replaceDomainMapAndImporter: ";
4321 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4322 myGraph_.is_null (), std::runtime_error,
4323 "This method does not work if the matrix has a const graph. The whole "
4324 "idea of a const graph is that you are not allowed to change it, but this"
4325 " method necessarily must modify the graph, since the graph owns the "
4326 "matrix's domain Map and Import objects.");
4327 myGraph_->replaceDomainMapAndImporter (newDomainMap, newImporter);
4330 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4334 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
4335 const Teuchos::ArrayView<const Scalar>& values)
4337 using Teuchos::Array;
4338 typedef GlobalOrdinal GO;
4339 typedef typename Array<GO>::size_type size_type;
4341 const size_type numToInsert = indices.size ();
4344 std::pair<Array<GO>, Array<Scalar> >& curRow = nonlocals_[globalRow];
4345 Array<GO>& curRowInds = curRow.first;
4346 Array<Scalar>& curRowVals = curRow.second;
4347 const size_type newCapacity = curRowInds.size () + numToInsert;
4348 curRowInds.reserve (newCapacity);
4349 curRowVals.reserve (newCapacity);
4350 for (size_type k = 0; k < numToInsert; ++k) {
4351 curRowInds.push_back (indices[k]);
4352 curRowVals.push_back (values[k]);
4356 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4363 using Teuchos::Comm;
4364 using Teuchos::outArg;
4367 using Teuchos::REDUCE_MAX;
4368 using Teuchos::REDUCE_MIN;
4369 using Teuchos::reduceAll;
4373 typedef GlobalOrdinal GO;
4374 typedef typename Teuchos::Array<GO>::size_type size_type;
4375 const char tfecfFuncName[] =
"globalAssemble: ";
4376 ProfilingRegion regionGlobalAssemble (
"Tpetra::CrsMatrix::globalAssemble");
4378 const bool verbose = Behavior::verbose(
"CrsMatrix");
4379 std::unique_ptr<std::string> prefix;
4381 prefix = this->createPrefix(
"CrsMatrix",
"globalAssemble");
4382 std::ostringstream os;
4383 os << *prefix <<
"nonlocals_.size()=" << nonlocals_.size()
4385 std::cerr << os.str();
4387 RCP<const Comm<int> > comm = getComm ();
4389 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4390 (! isFillActive (), std::runtime_error,
"Fill must be active before "
4391 "you may call this method.");
4393 const size_t myNumNonlocalRows = nonlocals_.size ();
4400 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
4401 int someoneHasNonlocalRows = 0;
4402 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
4403 outArg (someoneHasNonlocalRows));
4404 if (someoneHasNonlocalRows == 0) {
4418 RCP<const map_type> nonlocalRowMap;
4420 Teuchos::Array<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
4422 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
4423 size_type curPos = 0;
4424 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4425 ++mapIter, ++curPos) {
4426 myNonlocalGblRows[curPos] = mapIter->first;
4429 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4430 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4437 sort2 (gblCols.begin (), gblCols.end (), vals.begin ());
4438 typename Teuchos::Array<GO>::iterator gblCols_newEnd;
4439 typename Teuchos::Array<Scalar>::iterator vals_newEnd;
4440 merge2 (gblCols_newEnd, vals_newEnd,
4441 gblCols.begin (), gblCols.end (),
4442 vals.begin (), vals.end ());
4443 gblCols.erase (gblCols_newEnd, gblCols.end ());
4444 vals.erase (vals_newEnd, vals.end ());
4445 numEntPerNonlocalRow[curPos] = gblCols.size ();
4456 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
4458 auto iter = std::min_element (myNonlocalGblRows.begin (),
4459 myNonlocalGblRows.end ());
4460 if (iter != myNonlocalGblRows.end ()) {
4461 myMinNonlocalGblRow = *iter;
4464 GO gblMinNonlocalGblRow = 0;
4465 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
4466 outArg (gblMinNonlocalGblRow));
4467 const GO indexBase = gblMinNonlocalGblRow;
4468 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
4469 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
4478 std::ostringstream os;
4479 os << *prefix <<
"Create nonlocal matrix" << endl;
4480 std::cerr << os.str();
4482 RCP<crs_matrix_type> nonlocalMatrix =
4483 rcp (
new crs_matrix_type (nonlocalRowMap, numEntPerNonlocalRow (),
4486 size_type curPos = 0;
4487 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4488 ++mapIter, ++curPos) {
4489 const GO gblRow = mapIter->first;
4491 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4492 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4494 nonlocalMatrix->insertGlobalValues (gblRow, gblCols (), vals ());
4506 auto origRowMap = this->getRowMap ();
4507 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
4509 int isLocallyComplete = 1;
4511 if (origRowMapIsOneToOne) {
4513 std::ostringstream os;
4514 os << *prefix <<
"Original row Map is 1-to-1" << endl;
4515 std::cerr << os.str();
4517 export_type exportToOrig (nonlocalRowMap, origRowMap);
4519 isLocallyComplete = 0;
4522 std::ostringstream os;
4523 os << *prefix <<
"doExport from nonlocalMatrix" << endl;
4524 std::cerr << os.str();
4526 this->doExport (*nonlocalMatrix, exportToOrig,
Tpetra::ADD);
4531 std::ostringstream os;
4532 os << *prefix <<
"Original row Map is NOT 1-to-1" << endl;
4533 std::cerr << os.str();
4540 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
4542 isLocallyComplete = 0;
4550 std::ostringstream os;
4551 os << *prefix <<
"Create & doExport into 1-to-1 matrix"
4553 std::cerr << os.str();
4555 crs_matrix_type oneToOneMatrix (oneToOneRowMap, 0);
4557 oneToOneMatrix.doExport(*nonlocalMatrix, exportToOneToOne,
4563 std::ostringstream os;
4564 os << *prefix <<
"Free nonlocalMatrix" << endl;
4565 std::cerr << os.str();
4567 nonlocalMatrix = Teuchos::null;
4571 std::ostringstream os;
4572 os << *prefix <<
"doImport from 1-to-1 matrix" << endl;
4573 std::cerr << os.str();
4575 import_type importToOrig (oneToOneRowMap, origRowMap);
4576 this->doImport (oneToOneMatrix, importToOrig,
Tpetra::ADD);
4584 std::ostringstream os;
4585 os << *prefix <<
"Free nonlocals_ (std::map)" << endl;
4586 std::cerr << os.str();
4588 decltype (nonlocals_) newNonlocals;
4589 std::swap (nonlocals_, newNonlocals);
4598 int isGloballyComplete = 0;
4599 reduceAll<int, int> (*comm, REDUCE_MIN, isLocallyComplete,
4600 outArg (isGloballyComplete));
4601 TEUCHOS_TEST_FOR_EXCEPTION
4602 (isGloballyComplete != 1, std::runtime_error,
"On at least one process, "
4603 "you called insertGlobalValues with a global row index which is not in "
4604 "the matrix's row Map on any process in its communicator.");
4607 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4612 if (! isStaticGraph ()) {
4613 myGraph_->resumeFill (params);
4615 clearGlobalConstants ();
4616 fillComplete_ =
false;
4619 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4633 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4637 return getCrsGraphRef ().haveGlobalConstants ();
4640 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4652 frobNorm_ = -STM::one ();
4655 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4660 const char tfecfFuncName[] =
"fillComplete(params): ";
4662 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4663 (this->getCrsGraph ().is_null (), std::logic_error,
4664 "getCrsGraph() returns null. This should not happen at this point. "
4665 "Please report this bug to the Tpetra developers.");
4675 Teuchos::RCP<const map_type> rangeMap = graph.
getRowMap ();
4676 Teuchos::RCP<const map_type> domainMap = rangeMap;
4677 this->fillComplete (domainMap, rangeMap, params);
4681 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4685 const Teuchos::RCP<const map_type>& rangeMap,
4686 const Teuchos::RCP<Teuchos::ParameterList>& params)
4690 using Teuchos::ArrayRCP;
4694 const char tfecfFuncName[] =
"fillComplete: ";
4695 ProfilingRegion regionFillComplete
4696 (
"Tpetra::CrsMatrix::fillComplete");
4697 const bool verbose = Behavior::verbose(
"CrsMatrix");
4698 std::unique_ptr<std::string> prefix;
4700 prefix = this->createPrefix(
"CrsMatrix",
"fillComplete(dom,ran,p)");
4701 std::ostringstream os;
4702 os << *prefix << endl;
4703 std::cerr << os.str ();
4706 "Tpetra::CrsMatrix::fillCompete",
4709 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4710 (! this->isFillActive () || this->isFillComplete (), std::runtime_error,
4711 "Matrix fill state must be active (isFillActive() "
4712 "must be true) before you may call fillComplete().");
4713 const int numProcs = this->getComm ()->getSize ();
4723 bool assertNoNonlocalInserts =
false;
4726 bool sortGhosts =
true;
4728 if (! params.is_null ()) {
4729 assertNoNonlocalInserts = params->get (
"No Nonlocal Changes",
4730 assertNoNonlocalInserts);
4731 if (params->isParameter (
"sort column map ghost gids")) {
4732 sortGhosts = params->get (
"sort column map ghost gids", sortGhosts);
4734 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
4735 sortGhosts = params->get (
"Sort column Map ghost GIDs", sortGhosts);
4740 const bool needGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
4742 if (! this->myGraph_.is_null ()) {
4743 this->myGraph_->sortGhostsAssociatedWithEachProcessor_ = sortGhosts;
4746 if (! this->getCrsGraphRef ().indicesAreAllocated ()) {
4747 if (this->hasColMap ()) {
4748 allocateValues(LocalIndices, GraphNotYetAllocated, verbose);
4751 allocateValues(GlobalIndices, GraphNotYetAllocated, verbose);
4756 if (needGlobalAssemble) {
4757 this->globalAssemble ();
4760 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4761 (numProcs == 1 && nonlocals_.size() > 0,
4762 std::runtime_error,
"Cannot have nonlocal entries on a serial run. "
4763 "An invalid entry (i.e., with row index not in the row Map) must have "
4764 "been submitted to the CrsMatrix.");
4767 if (this->isStaticGraph ()) {
4775 #ifdef HAVE_TPETRA_DEBUG
4793 const bool domainMapsMatch =
4794 this->staticGraph_->getDomainMap ()->isSameAs (*domainMap);
4795 const bool rangeMapsMatch =
4796 this->staticGraph_->getRangeMap ()->isSameAs (*rangeMap);
4798 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4799 (! domainMapsMatch, std::runtime_error,
4800 "The CrsMatrix's domain Map does not match the graph's domain Map. "
4801 "The graph cannot be changed because it was given to the CrsMatrix "
4802 "constructor as const. You can fix this by passing in the graph's "
4803 "domain Map and range Map to the matrix's fillComplete call.");
4805 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4806 (! rangeMapsMatch, std::runtime_error,
4807 "The CrsMatrix's range Map does not match the graph's range Map. "
4808 "The graph cannot be changed because it was given to the CrsMatrix "
4809 "constructor as const. You can fix this by passing in the graph's "
4810 "domain Map and range Map to the matrix's fillComplete call.");
4811 #endif // HAVE_TPETRA_DEBUG
4815 this->fillLocalMatrix (params);
4823 this->myGraph_->setDomainRangeMaps (domainMap, rangeMap);
4826 Teuchos::Array<int> remotePIDs (0);
4827 const bool mustBuildColMap = ! this->hasColMap ();
4828 if (mustBuildColMap) {
4829 this->myGraph_->makeColMap (remotePIDs);
4834 const std::pair<size_t, std::string> makeIndicesLocalResult =
4835 this->myGraph_->makeIndicesLocal(verbose);
4840 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4841 (makeIndicesLocalResult.first != 0, std::runtime_error,
4842 makeIndicesLocalResult.second);
4844 const bool sorted = this->myGraph_->isSorted ();
4845 const bool merged = this->myGraph_->isMerged ();
4846 this->sortAndMergeIndicesAndValues (sorted, merged);
4851 this->myGraph_->makeImportExport (remotePIDs, mustBuildColMap);
4855 this->fillLocalGraphAndMatrix (params);
4857 const bool callGraphComputeGlobalConstants = params.get () ==
nullptr ||
4858 params->get (
"compute global constants",
true);
4859 if (callGraphComputeGlobalConstants) {
4860 this->myGraph_->computeGlobalConstants ();
4863 this->myGraph_->computeLocalConstants ();
4865 this->myGraph_->fillComplete_ =
true;
4866 this->myGraph_->checkInternalState ();
4871 "Tpetra::CrsMatrix::fillCompete",
"callComputeGlobalConstamnts"
4873 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
4874 params->get (
"compute global constants",
true);
4875 if (callComputeGlobalConstants) {
4876 this->computeGlobalConstants ();
4882 this->fillComplete_ =
true;
4885 "Tpetra::CrsMatrix::fillCompete",
"checkInternalState"
4887 this->checkInternalState ();
4891 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4895 const Teuchos::RCP<const map_type> & rangeMap,
4896 const Teuchos::RCP<const import_type>& importer,
4897 const Teuchos::RCP<const export_type>& exporter,
4898 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
4900 #ifdef HAVE_TPETRA_MMM_TIMINGS
4902 if(!params.is_null())
4903 label = params->get(
"Timer Label",label);
4904 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
4905 using Teuchos::TimeMonitor;
4907 Teuchos::TimeMonitor all(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-all")));
4910 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
4911 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! isFillActive() || isFillComplete(),
4912 std::runtime_error,
"Matrix fill state must be active (isFillActive() "
4913 "must be true) before calling fillComplete().");
4914 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4915 myGraph_.is_null (), std::logic_error,
"myGraph_ is null. This is not allowed.");
4918 #ifdef HAVE_TPETRA_MMM_TIMINGS
4919 Teuchos::TimeMonitor graph(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-Graph")));
4922 myGraph_->expertStaticFillComplete (domainMap, rangeMap, importer, exporter,params);
4925 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
4926 params->get (
"compute global constants",
true);
4927 if (callComputeGlobalConstants) {
4928 this->computeGlobalConstants ();
4932 #ifdef HAVE_TPETRA_MMM_TIMINGS
4933 TimeMonitor fLGAM(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-fLGAM")));
4936 fillLocalGraphAndMatrix (params);
4941 fillComplete_ =
true;
4944 #ifdef HAVE_TPETRA_DEBUG
4945 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(isFillActive(), std::logic_error,
4946 ": We're at the end of fillComplete(), but isFillActive() is true. "
4947 "Please report this bug to the Tpetra developers.");
4948 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(! isFillComplete(), std::logic_error,
4949 ": We're at the end of fillComplete(), but isFillActive() is true. "
4950 "Please report this bug to the Tpetra developers.");
4951 #endif // HAVE_TPETRA_DEBUG
4953 #ifdef HAVE_TPETRA_MMM_TIMINGS
4954 Teuchos::TimeMonitor cIS(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cIS")));
4957 checkInternalState();
4961 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4967 #ifdef HAVE_TPETRA_DEBUG
4968 const char tfecfFuncName[] =
"mergeRowIndicesAndValues: ";
4969 #endif // HAVE_TPETRA_DEBUG
4971 auto rowValues = this->getRowViewNonConst (rowInfo);
4972 typedef typename std::decay<decltype (rowValues[0]) >::type value_type;
4973 value_type* rowValueIter = rowValues.data ();
4974 auto inds_view = graph.getLocalKokkosRowViewNonConst (rowInfo);
4977 LocalOrdinal* beg = inds_view.data ();
4978 LocalOrdinal* end = inds_view.data () + rowInfo.numEntries;
4980 #ifdef HAVE_TPETRA_DEBUG
4981 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4982 (rowInfo.allocSize != static_cast<size_t> (inds_view.extent (0)) ||
4983 rowInfo.allocSize != static_cast<size_t> (rowValues.extent (0)),
4984 std::runtime_error,
"rowInfo.allocSize = " << rowInfo.allocSize
4985 <<
" != inds_view.extent(0) = " << inds_view.extent (0)
4986 <<
" || rowInfo.allocSize = " << rowInfo.allocSize
4987 <<
" != rowValues.extent(0) = " << rowValues.extent (0) <<
".");
4988 #endif // HAVE_TPETRA_DEBUG
4990 LocalOrdinal* newend = beg;
4992 LocalOrdinal* cur = beg + 1;
4993 value_type* vcur = rowValueIter + 1;
4994 value_type* vend = rowValueIter;
4996 while (cur != end) {
4997 if (*cur != *newend) {
5014 const size_t mergedEntries = newend - beg;
5016 const size_t numDups = rowInfo.numEntries - mergedEntries;
5020 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5025 using ::Tpetra::Details::ProfilingRegion;
5026 typedef LocalOrdinal LO;
5027 typedef typename Kokkos::View<LO*, device_type>::HostMirror::execution_space
5028 host_execution_space;
5029 typedef Kokkos::RangePolicy<host_execution_space, LO> range_type;
5031 const char tfecfFuncName[] =
"sortAndMergeIndicesAndValues: ";
5032 ProfilingRegion regionSAM (
"Tpetra::CrsMatrix::sortAndMergeIndicesAndValues");
5034 if (! sorted || ! merged) {
5035 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5036 (this->isStaticGraph (), std::runtime_error,
"Cannot sort or merge with "
5037 "\"static\" (const) graph, since the matrix does not own the graph.");
5038 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5039 (this->myGraph_.is_null (), std::logic_error,
"myGraph_ is null, but "
5040 "this matrix claims ! isStaticGraph(). "
5041 "Please report this bug to the Tpetra developers.");
5042 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5043 (this->isStorageOptimized (), std::logic_error,
"It is invalid to call "
5044 "this method if the graph's storage has already been optimized. "
5045 "Please report this bug to the Tpetra developers.");
5048 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5049 size_t totalNumDups = 0;
5051 Kokkos::parallel_reduce (range_type (0, lclNumRows),
5052 [
this, &graph, sorted, merged] (
const LO& lclRow,
size_t& numDups) {
5055 auto lclColInds = graph.getLocalKokkosRowViewNonConst (rowInfo);
5056 auto vals = this->getRowViewNonConst (rowInfo);
5059 sort2 (lclColInds.data (),
5060 lclColInds.data () + rowInfo.numEntries,
5064 numDups += this->mergeRowIndicesAndValues (graph, rowInfo);
5076 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5087 using Teuchos::rcp_const_cast;
5088 using Teuchos::rcpFromRef;
5089 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5090 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
5096 if (alpha == ZERO) {
5099 }
else if (beta != ONE) {
5113 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5114 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5120 const bool Y_is_overwritten = (beta ==
ZERO);
5123 const bool Y_is_replicated =
5124 (! Y_in.
isDistributed () && this->getComm ()->getSize () != 1);
5132 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5139 RCP<const MV> X_colMap;
5140 if (importer.is_null ()) {
5148 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in,
true);
5150 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
5155 X_colMap = rcpFromRef (X_in);
5159 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply: Import");
5165 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in);
5168 X_colMapNonConst->doImport (X_in, *importer,
INSERT);
5169 X_colMap = rcp_const_cast<
const MV> (X_colMapNonConst);
5176 RCP<MV> Y_rowMap = getRowMapMultiVector (Y_in);
5183 if (! exporter.is_null ()) {
5184 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, ZERO);
5186 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply: Export");
5192 if (Y_is_overwritten) {
5218 Y_rowMap = getRowMapMultiVector (Y_in,
true);
5225 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, beta);
5229 this->localApply (*X_colMap, Y_in, Teuchos::NO_TRANS, alpha, beta);
5237 if (Y_is_replicated) {
5238 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply: Reduce Y");
5243 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5248 const Teuchos::ETransp mode,
5253 using Teuchos::null;
5256 using Teuchos::rcp_const_cast;
5257 using Teuchos::rcpFromRef;
5258 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5261 if (alpha == ZERO) {
5284 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5285 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5291 const bool Y_is_overwritten = (beta ==
ZERO);
5292 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5298 X = rcp (
new MV (X_in, Teuchos::Copy));
5300 X = rcpFromRef (X_in);
5304 if (importer != Teuchos::null) {
5305 if (importMV_ != Teuchos::null && importMV_->getNumVectors() != numVectors) {
5308 if (importMV_ == null) {
5309 importMV_ = rcp (
new MV (this->getColMap (), numVectors));
5312 if (exporter != Teuchos::null) {
5313 if (exportMV_ != Teuchos::null && exportMV_->getNumVectors() != numVectors) {
5316 if (exportMV_ == null) {
5317 exportMV_ = rcp (
new MV (this->getRowMap (), numVectors));
5323 if (! exporter.is_null ()) {
5324 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply (transpose): Import");
5325 exportMV_->doImport (X_in, *exporter,
INSERT);
5332 if (importer != Teuchos::null) {
5333 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply (transpose): Export");
5340 importMV_->putScalar (ZERO);
5342 this->localApply (*X, *importMV_, mode, alpha, ZERO);
5343 if (Y_is_overwritten) {
5360 MV Y (Y_in, Teuchos::Copy);
5361 this->localApply (*X, Y, mode, alpha, beta);
5364 this->localApply (*X, Y_in, mode, alpha, beta);
5371 if (Y_is_replicated) {
5372 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply (transpose): Reduce Y");
5377 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5382 const Teuchos::ETransp mode,
5383 const Scalar& alpha,
5384 const Scalar& beta)
const
5387 using Teuchos::NO_TRANS;
5388 ProfilingRegion regionLocalApply (
"Tpetra::CrsMatrix::localApply");
5399 const char tfecfFuncName[] =
"localApply: ";
5400 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5401 (lclMatrix_.get () ==
nullptr, std::logic_error,
5402 "lclMatrix_ not created yet.");
5403 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5407 const bool transpose = (mode != Teuchos::NO_TRANS);
5408 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5410 getColMap ()->getNodeNumElements (), std::runtime_error,
5411 "NO_TRANS case: X has the wrong number of local rows. "
5413 "getColMap()->getNodeNumElements() = " <<
5414 getColMap ()->getNodeNumElements () <<
".");
5415 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5417 getRowMap ()->getNodeNumElements (), std::runtime_error,
5418 "NO_TRANS case: Y has the wrong number of local rows. "
5420 "getRowMap()->getNodeNumElements() = " <<
5421 getRowMap ()->getNodeNumElements () <<
".");
5422 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5424 getRowMap ()->getNodeNumElements (), std::runtime_error,
5425 "TRANS or CONJ_TRANS case: X has the wrong number of local "
5427 <<
" != getRowMap()->getNodeNumElements() = "
5428 << getRowMap ()->getNodeNumElements () <<
".");
5429 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5431 getColMap ()->getNodeNumElements (), std::runtime_error,
5432 "TRANS or CONJ_TRANS case: X has the wrong number of local "
5434 <<
" != getColMap()->getNodeNumElements() = "
5435 << getColMap ()->getNodeNumElements () <<
".");
5436 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5437 (! isFillComplete (), std::runtime_error,
"The matrix is not "
5438 "fill complete. You must call fillComplete() (possibly with "
5439 "domain and range Map arguments) without an intervening "
5440 "resumeFill() call before you may call this method.");
5441 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5443 std::runtime_error,
"X and Y must be constant stride.");
5446 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5447 (X_lcl.data () == Y_lcl.data () && X_lcl.data () !=
nullptr,
5448 std::runtime_error,
"X and Y may not alias one another.");
5451 LocalOrdinal nrows = getNodeNumRows();
5452 LocalOrdinal maxRowImbalance = 0;
5454 maxRowImbalance = getNodeMaxNumRowEntries() - (getNodeNumEntries() / nrows);
5456 lclMatrix_->applyImbalancedRows (X_lcl, Y_lcl, mode, alpha, beta);
5458 lclMatrix_->apply (X_lcl, Y_lcl, mode, alpha, beta);
5461 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5466 Teuchos::ETransp mode,
5471 const char fnName[] =
"Tpetra::CrsMatrix::apply";
5473 TEUCHOS_TEST_FOR_EXCEPTION
5474 (! isFillComplete (), std::runtime_error,
5475 fnName <<
": Cannot call apply() until fillComplete() "
5476 "has been called.");
5478 if (mode == Teuchos::NO_TRANS) {
5479 ProfilingRegion regionNonTranspose (fnName);
5480 this->applyNonTranspose (X, Y, alpha, beta);
5483 ProfilingRegion regionTranspose (
"Tpetra::CrsMatrix::apply (transpose)");
5490 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5494 this->applyTranspose (X, Y, mode, alpha, beta);
5498 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5504 const Scalar& dampingFactor,
5506 const int numSweeps)
const
5508 reorderedGaussSeidel (B, X, D, Teuchos::null, dampingFactor, direction, numSweeps);
5511 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5517 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
5518 const Scalar& dampingFactor,
5520 const int numSweeps)
const
5522 using Teuchos::null;
5525 using Teuchos::rcp_const_cast;
5526 using Teuchos::rcpFromRef;
5529 TEUCHOS_TEST_FOR_EXCEPTION(
5530 isFillComplete() ==
false, std::runtime_error,
5531 "Tpetra::CrsMatrix::gaussSeidel: cannot call this method until "
5532 "fillComplete() has been called.");
5533 TEUCHOS_TEST_FOR_EXCEPTION(
5535 std::invalid_argument,
5536 "Tpetra::CrsMatrix::gaussSeidel: The number of sweeps must be , "
5537 "nonnegative but you provided numSweeps = " << numSweeps <<
" < 0.");
5542 if (direction == Forward) {
5543 localDirection = Forward;
5545 else if (direction == Backward) {
5546 localDirection = Backward;
5548 else if (direction == Symmetric) {
5550 localDirection = Forward;
5553 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
5554 "Tpetra::CrsMatrix::gaussSeidel: The 'direction' enum does not have "
5555 "any of its valid values: Forward, Backward, or Symmetric.");
5558 if (numSweeps == 0) {
5565 RCP<const import_type> importer = this->getGraph()->getImporter();
5566 RCP<const export_type> exporter = this->getGraph()->getExporter();
5567 TEUCHOS_TEST_FOR_EXCEPTION(
5568 ! exporter.is_null (), std::runtime_error,
5569 "Tpetra's gaussSeidel implementation requires that the row, domain, "
5570 "and range Maps be the same. This cannot be the case, because the "
5571 "matrix has a nontrivial Export object.");
5573 RCP<const map_type> domainMap = this->getDomainMap ();
5574 RCP<const map_type> rangeMap = this->getRangeMap ();
5575 RCP<const map_type> rowMap = this->getGraph ()->getRowMap ();
5576 RCP<const map_type> colMap = this->getGraph ()->getColMap ();
5578 #ifdef HAVE_TEUCHOS_DEBUG
5583 TEUCHOS_TEST_FOR_EXCEPTION(
5584 ! X.
getMap ()->isSameAs (*domainMap),
5586 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5587 "multivector X be in the domain Map of the matrix.");
5588 TEUCHOS_TEST_FOR_EXCEPTION(
5589 ! B.
getMap ()->isSameAs (*rangeMap),
5591 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5592 "B be in the range Map of the matrix.");
5593 TEUCHOS_TEST_FOR_EXCEPTION(
5594 ! D.
getMap ()->isSameAs (*rowMap),
5596 "Tpetra::CrsMatrix::gaussSeidel requires that the input "
5597 "D be in the row Map of the matrix.");
5598 TEUCHOS_TEST_FOR_EXCEPTION(
5599 ! rowMap->isSameAs (*rangeMap),
5601 "Tpetra::CrsMatrix::gaussSeidel requires that the row Map and the "
5602 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
5603 TEUCHOS_TEST_FOR_EXCEPTION(
5604 ! domainMap->isSameAs (*rangeMap),
5606 "Tpetra::CrsMatrix::gaussSeidel requires that the domain Map and "
5607 "the range Map of the matrix be the same.");
5613 #endif // HAVE_TEUCHOS_DEBUG
5623 B_in = rcpFromRef (B);
5630 RCP<MV> B_in_nonconst = getRowMapMultiVector (B,
true);
5632 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
5637 "gaussSeidel: The current implementation of the Gauss-Seidel kernel "
5638 "requires that X and B both have constant stride. Since B does not "
5639 "have constant stride, we had to make a copy. This is a limitation of "
5640 "the current implementation and not your fault, but we still report it "
5641 "as an efficiency warning for your information.");
5650 RCP<MV> X_domainMap;
5652 bool copiedInput =
false;
5654 if (importer.is_null ()) {
5656 X_domainMap = rcpFromRef (X);
5657 X_colMap = X_domainMap;
5658 copiedInput =
false;
5664 X_colMap = getColumnMapMultiVector (X,
true);
5665 X_domainMap = X_colMap;
5670 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the "
5671 "Gauss-Seidel kernel requires that X and B both have constant "
5672 "stride. Since X does not have constant stride, we had to make a "
5673 "copy. This is a limitation of the current implementation and not "
5674 "your fault, but we still report it as an efficiency warning for "
5675 "your information.");
5680 X_domainMap = rcpFromRef (X);
5684 X_colMap = X_domainMap->offsetViewNonConst (colMap, 0);
5694 X_colMap->doImport (X, *importer,
INSERT);
5695 copiedInput =
false;
5702 X_colMap = getColumnMapMultiVector (X,
true);
5703 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
5704 X_colMap->doImport (X, *importer,
INSERT);
5708 "Tpetra::CrsMatrix::gaussSeidel: The current implementation of the "
5709 "Gauss-Seidel kernel requires that X and B both have constant stride. "
5710 "Since X does not have constant stride, we had to make a copy. "
5711 "This is a limitation of the current implementation and not your fault, "
5712 "but we still report it as an efficiency warning for your information.");
5716 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
5717 if (! importer.is_null () && sweep > 0) {
5719 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5723 if (direction != Symmetric) {
5724 if (rowIndices.is_null ()) {
5725 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5730 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5737 const bool doImportBetweenDirections =
false;
5738 if (rowIndices.is_null ()) {
5739 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5746 if (doImportBetweenDirections) {
5748 if (! importer.is_null ()) {
5749 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5752 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
5757 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5761 if (doImportBetweenDirections) {
5763 if (! importer.is_null ()) {
5764 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
5767 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
5780 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5786 const Scalar& dampingFactor,
5788 const int numSweeps,
5789 const bool zeroInitialGuess)
const
5791 reorderedGaussSeidelCopy (X, B, D, Teuchos::null, dampingFactor, direction,
5792 numSweeps, zeroInitialGuess);
5795 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5801 const Teuchos::ArrayView<LocalOrdinal>& rowIndices,
5802 const Scalar& dampingFactor,
5804 const int numSweeps,
5805 const bool zeroInitialGuess)
const
5807 using Teuchos::null;
5810 using Teuchos::rcpFromRef;
5811 using Teuchos::rcp_const_cast;
5813 const char prefix[] =
"Tpetra::CrsMatrix::(reordered)gaussSeidelCopy: ";
5814 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5816 TEUCHOS_TEST_FOR_EXCEPTION(
5817 ! isFillComplete (), std::runtime_error,
5818 prefix <<
"The matrix is not fill complete.");
5819 TEUCHOS_TEST_FOR_EXCEPTION(
5820 numSweeps < 0, std::invalid_argument,
5821 prefix <<
"The number of sweeps must be nonnegative, "
5822 "but you provided numSweeps = " << numSweeps <<
" < 0.");
5827 if (direction == Forward) {
5828 localDirection = Forward;
5830 else if (direction == Backward) {
5831 localDirection = Backward;
5833 else if (direction == Symmetric) {
5835 localDirection = Forward;
5838 TEUCHOS_TEST_FOR_EXCEPTION(
5839 true, std::invalid_argument,
5840 prefix <<
"The 'direction' enum does not have any of its valid "
5841 "values: Forward, Backward, or Symmetric.");
5844 if (numSweeps == 0) {
5848 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5849 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5850 TEUCHOS_TEST_FOR_EXCEPTION(
5851 ! exporter.is_null (), std::runtime_error,
5852 "This method's implementation currently requires that the matrix's row, "
5853 "domain, and range Maps be the same. This cannot be the case, because "
5854 "the matrix has a nontrivial Export object.");
5856 RCP<const map_type> domainMap = this->getDomainMap ();
5857 RCP<const map_type> rangeMap = this->getRangeMap ();
5858 RCP<const map_type> rowMap = this->getGraph ()->getRowMap ();
5859 RCP<const map_type> colMap = this->getGraph ()->getColMap ();
5861 #ifdef HAVE_TEUCHOS_DEBUG
5866 TEUCHOS_TEST_FOR_EXCEPTION(
5867 ! X.
getMap ()->isSameAs (*domainMap), std::runtime_error,
5868 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
5869 "multivector X be in the domain Map of the matrix.");
5870 TEUCHOS_TEST_FOR_EXCEPTION(
5871 ! B.
getMap ()->isSameAs (*rangeMap), std::runtime_error,
5872 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
5873 "B be in the range Map of the matrix.");
5874 TEUCHOS_TEST_FOR_EXCEPTION(
5875 ! D.
getMap ()->isSameAs (*rowMap), std::runtime_error,
5876 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the input "
5877 "D be in the row Map of the matrix.");
5878 TEUCHOS_TEST_FOR_EXCEPTION(
5879 ! rowMap->isSameAs (*rangeMap), std::runtime_error,
5880 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the row Map and the "
5881 "range Map be the same (in the sense of Tpetra::Map::isSameAs).");
5882 TEUCHOS_TEST_FOR_EXCEPTION(
5883 ! domainMap->isSameAs (*rangeMap), std::runtime_error,
5884 "Tpetra::CrsMatrix::gaussSeidelCopy requires that the domain Map and "
5885 "the range Map of the matrix be the same.");
5891 #endif // HAVE_TEUCHOS_DEBUG
5902 RCP<MV> X_domainMap;
5903 bool copyBackOutput =
false;
5904 if (importer.is_null ()) {
5906 X_colMap = rcpFromRef (X);
5907 X_domainMap = rcpFromRef (X);
5913 if (zeroInitialGuess) {
5914 X_colMap->putScalar (ZERO);
5922 X_colMap = getColumnMapMultiVector (X,
true);
5926 X_domainMap = X_colMap;
5927 if (! zeroInitialGuess) {
5930 }
catch (std::exception& e) {
5931 std::ostringstream os;
5932 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: "
5933 "deep_copy(*X_domainMap, X) threw an exception: "
5934 << e.what () <<
".";
5935 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
5938 copyBackOutput =
true;
5942 "gaussSeidelCopy: The current implementation of the Gauss-Seidel "
5943 "kernel requires that X and B both have constant stride. Since X "
5944 "does not have constant stride, we had to make a copy. This is a "
5945 "limitation of the current implementation and not your fault, but we "
5946 "still report it as an efficiency warning for your information.");
5950 X_colMap = getColumnMapMultiVector (X);
5951 X_domainMap = X_colMap->offsetViewNonConst (domainMap, 0);
5953 #ifdef HAVE_TPETRA_DEBUG
5954 auto X_colMap_host_view = X_colMap->getLocalViewHost ();
5955 auto X_domainMap_host_view = X_domainMap->getLocalViewHost ();
5957 if (X_colMap->getLocalLength () != 0 && X_domainMap->getLocalLength ()) {
5958 TEUCHOS_TEST_FOR_EXCEPTION
5959 (X_colMap_host_view.data () != X_domainMap_host_view.data (),
5960 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: Pointer to "
5961 "start of column Map view of X is not equal to pointer to start of "
5962 "(domain Map view of) X. This may mean that Tpetra::MultiVector::"
5963 "offsetViewNonConst is broken. "
5964 "Please report this bug to the Tpetra developers.");
5967 TEUCHOS_TEST_FOR_EXCEPTION(
5968 X_colMap_host_view.extent (0) < X_domainMap_host_view.extent (0) ||
5969 X_colMap->getLocalLength () < X_domainMap->getLocalLength (),
5970 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: "
5971 "X_colMap has fewer local rows than X_domainMap. "
5972 "X_colMap_host_view.extent(0) = " << X_colMap_host_view.extent (0)
5973 <<
", X_domainMap_host_view.extent(0) = "
5974 << X_domainMap_host_view.extent (0)
5975 <<
", X_colMap->getLocalLength() = " << X_colMap->getLocalLength ()
5976 <<
", and X_domainMap->getLocalLength() = "
5977 << X_domainMap->getLocalLength ()
5978 <<
". This means that Tpetra::MultiVector::offsetViewNonConst "
5979 "is broken. Please report this bug to the Tpetra developers.");
5981 TEUCHOS_TEST_FOR_EXCEPTION(
5982 X_colMap->getNumVectors () != X_domainMap->getNumVectors (),
5983 std::logic_error,
"Tpetra::CrsMatrix::gaussSeidelCopy: "
5984 "X_colMap has a different number of columns than X_domainMap. "
5985 "X_colMap->getNumVectors() = " << X_colMap->getNumVectors ()
5986 <<
" != X_domainMap->getNumVectors() = "
5987 << X_domainMap->getNumVectors ()
5988 <<
". This means that Tpetra::MultiVector::offsetViewNonConst "
5989 "is broken. Please report this bug to the Tpetra developers.");
5990 #endif // HAVE_TPETRA_DEBUG
5992 if (zeroInitialGuess) {
5994 X_colMap->putScalar (ZERO);
6004 X_colMap->doImport (X, *importer,
INSERT);
6006 copyBackOutput =
true;
6014 B_in = rcpFromRef (B);
6020 RCP<MV> B_in_nonconst = getRowMapMultiVector (B,
true);
6023 }
catch (std::exception& e) {
6024 std::ostringstream os;
6025 os <<
"Tpetra::CrsMatrix::reorderedGaussSeidelCopy: "
6026 "deep_copy(*B_in_nonconst, B) threw an exception: "
6027 << e.what () <<
".";
6028 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, e.what ());
6030 B_in = rcp_const_cast<
const MV> (B_in_nonconst);
6035 "gaussSeidelCopy: The current implementation requires that B have "
6036 "constant stride. Since B does not have constant stride, we had to "
6037 "copy it into a separate constant-stride multivector. This is a "
6038 "limitation of the current implementation and not your fault, but we "
6039 "still report it as an efficiency warning for your information.");
6042 for (
int sweep = 0; sweep < numSweeps; ++sweep) {
6043 if (! importer.is_null () && sweep > 0) {
6046 X_colMap->doImport (*X_domainMap, *importer,
INSERT);
6050 if (direction != Symmetric) {
6051 if (rowIndices.is_null ()) {
6052 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6057 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6064 if (rowIndices.is_null ()) {
6065 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6073 this->
template localGaussSeidel<ST, ST> (*B_in, *X_colMap, D,
6078 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6082 this->
template reorderedLocalGaussSeidel<ST, ST> (*B_in, *X_colMap,
6091 if (copyBackOutput) {
6094 }
catch (std::exception& e) {
6095 TEUCHOS_TEST_FOR_EXCEPTION(
6096 true, std::runtime_error, prefix <<
"deep_copy(X, *X_domainMap) "
6097 "threw an exception: " << e.what ());
6102 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6104 Teuchos::RCP<CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node> >
6110 const char tfecfFuncName[] =
"convert: ";
6112 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6113 (! this->isFillComplete (), std::runtime_error,
"This matrix (the source "
6114 "of the conversion) is not fill complete. You must first call "
6115 "fillComplete() (possibly with the domain and range Map) without an "
6116 "intervening call to resumeFill(), before you may call this method.");
6117 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6118 (! this->isStaticGraph (), std::logic_error,
"This matrix (the source "
6119 "of the conversion) claims to be fill complete, but does not have a "
6120 "static (i.e., constant) graph. Please report this bug to the Tpetra "
6123 RCP<output_matrix_type> newMatrix
6124 (
new output_matrix_type (this->getCrsGraph ()));
6128 copyConvert (newMatrix->lclMatrix_->getLocalMatrix ().values,
6129 this->lclMatrix_->getLocalMatrix ().values);
6133 newMatrix->fillComplete (this->getDomainMap (), this->getRangeMap ());
6139 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6146 const char tfecfFuncName[] =
"checkInternalState: ";
6147 const char err[] =
"Internal state is not consistent. "
6148 "Please report this bug to the Tpetra developers.";
6152 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6153 (staticGraph_.is_null (), std::logic_error, err);
6157 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6158 (! myGraph_.is_null () && myGraph_ != staticGraph_,
6159 std::logic_error, err);
6161 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6162 (isFillComplete () && ! staticGraph_->isFillComplete (),
6163 std::logic_error, err <<
" Specifically, the matrix is fill complete, "
6164 "but its graph is NOT fill complete.");
6167 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6168 (staticGraph_->indicesAreAllocated () &&
6169 staticGraph_->getNodeAllocationSize() > 0 &&
6170 staticGraph_->getNodeNumRows() > 0 &&
6171 k_values1D_.extent (0) == 0,
6172 std::logic_error, err);
6176 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6181 std::ostringstream os;
6183 os <<
"Tpetra::CrsMatrix (Kokkos refactor): {";
6184 if (this->getObjectLabel () !=
"") {
6185 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
6187 if (isFillComplete ()) {
6188 os <<
"isFillComplete: true"
6189 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
6190 << getGlobalNumCols () <<
"]"
6191 <<
", global number of entries: " << getGlobalNumEntries ()
6195 os <<
"isFillComplete: false"
6196 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
6197 << getGlobalNumCols () <<
"]}";
6202 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6206 const Teuchos::EVerbosityLevel verbLevel)
const
6210 using Teuchos::ArrayView;
6211 using Teuchos::Comm;
6213 using Teuchos::TypeNameTraits;
6214 using Teuchos::VERB_DEFAULT;
6215 using Teuchos::VERB_NONE;
6216 using Teuchos::VERB_LOW;
6217 using Teuchos::VERB_MEDIUM;
6218 using Teuchos::VERB_HIGH;
6219 using Teuchos::VERB_EXTREME;
6221 const Teuchos::EVerbosityLevel vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
6223 if (vl == VERB_NONE) {
6228 Teuchos::OSTab tab0 (out);
6230 RCP<const Comm<int> > comm = this->getComm();
6231 const int myRank = comm->getRank();
6232 const int numProcs = comm->getSize();
6234 for (
size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
6237 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
6247 out <<
"Tpetra::CrsMatrix (Kokkos refactor):" << endl;
6249 Teuchos::OSTab tab1 (out);
6252 if (this->getObjectLabel () !=
"") {
6253 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
6256 out <<
"Template parameters:" << endl;
6257 Teuchos::OSTab tab2 (out);
6258 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
6259 <<
"LocalOrdinal: " << TypeNameTraits<LocalOrdinal>::name () << endl
6260 <<
"GlobalOrdinal: " << TypeNameTraits<GlobalOrdinal>::name () << endl
6261 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
6263 if (isFillComplete()) {
6264 out <<
"isFillComplete: true" << endl
6265 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
6266 << getGlobalNumCols () <<
"]" << endl
6267 <<
"Global number of entries: " << getGlobalNumEntries () << endl
6268 << endl <<
"Global max number of entries in a row: "
6269 << getGlobalMaxNumRowEntries () << endl;
6272 out <<
"isFillComplete: false" << endl
6273 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
6274 << getGlobalNumCols () <<
"]" << endl;
6278 if (vl < VERB_MEDIUM) {
6284 out << endl <<
"Row Map:" << endl;
6286 if (getRowMap ().is_null ()) {
6288 out <<
"null" << endl;
6295 getRowMap ()->describe (out, vl);
6300 out <<
"Column Map: ";
6302 if (getColMap ().is_null ()) {
6304 out <<
"null" << endl;
6306 }
else if (getColMap () == getRowMap ()) {
6308 out <<
"same as row Map" << endl;
6314 getColMap ()->describe (out, vl);
6319 out <<
"Domain Map: ";
6321 if (getDomainMap ().is_null ()) {
6323 out <<
"null" << endl;
6325 }
else if (getDomainMap () == getRowMap ()) {
6327 out <<
"same as row Map" << endl;
6329 }
else if (getDomainMap () == getColMap ()) {
6331 out <<
"same as column Map" << endl;
6337 getDomainMap ()->describe (out, vl);
6342 out <<
"Range Map: ";
6344 if (getRangeMap ().is_null ()) {
6346 out <<
"null" << endl;
6348 }
else if (getRangeMap () == getDomainMap ()) {
6350 out <<
"same as domain Map" << endl;
6352 }
else if (getRangeMap () == getRowMap ()) {
6354 out <<
"same as row Map" << endl;
6360 getRangeMap ()->describe (out, vl);
6364 for (
int curRank = 0; curRank < numProcs; ++curRank) {
6365 if (myRank == curRank) {
6366 out <<
"Process rank: " << curRank << endl;
6367 Teuchos::OSTab tab2 (out);
6368 if (! staticGraph_->indicesAreAllocated ()) {
6369 out <<
"Graph indices not allocated" << endl;
6372 out <<
"Number of allocated entries: "
6373 << staticGraph_->getNodeAllocationSize () << endl;
6375 out <<
"Number of entries: " << getNodeNumEntries () << endl
6376 <<
"Max number of entries per row: " << getNodeMaxNumRowEntries ()
6385 if (vl < VERB_HIGH) {
6390 for (
int curRank = 0; curRank < numProcs; ++curRank) {
6391 if (myRank == curRank) {
6392 out << std::setw(width) <<
"Proc Rank"
6393 << std::setw(width) <<
"Global Row"
6394 << std::setw(width) <<
"Num Entries";
6395 if (vl == VERB_EXTREME) {
6396 out << std::setw(width) <<
"(Index,Value)";
6399 for (
size_t r = 0; r < getNodeNumRows (); ++r) {
6400 const size_t nE = getNumEntriesInLocalRow(r);
6401 GlobalOrdinal gid = getRowMap()->getGlobalElement(r);
6402 out << std::setw(width) << myRank
6403 << std::setw(width) << gid
6404 << std::setw(width) << nE;
6405 if (vl == VERB_EXTREME) {
6406 if (isGloballyIndexed()) {
6407 ArrayView<const GlobalOrdinal> rowinds;
6408 ArrayView<const Scalar> rowvals;
6409 getGlobalRowView (gid, rowinds, rowvals);
6410 for (
size_t j = 0; j < nE; ++j) {
6411 out <<
" (" << rowinds[j]
6412 <<
", " << rowvals[j]
6416 else if (isLocallyIndexed()) {
6417 ArrayView<const LocalOrdinal> rowinds;
6418 ArrayView<const Scalar> rowvals;
6419 getLocalRowView (r, rowinds, rowvals);
6420 for (
size_t j=0; j < nE; ++j) {
6421 out <<
" (" << getColMap()->getGlobalElement(rowinds[j])
6422 <<
", " << rowvals[j]
6438 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6451 const row_matrix_type* srcRowMat =
6452 dynamic_cast<const row_matrix_type*
> (&source);
6453 return (srcRowMat !=
nullptr);
6456 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6460 const typename crs_graph_type::padding_type& padding,
6466 using LO = local_ordinal_type;
6467 using execution_space =
typename device_type::execution_space;
6468 using row_ptrs_type =
6469 typename local_graph_type::row_map_type::non_const_type;
6470 using range_policy =
6471 Kokkos::RangePolicy<execution_space, Kokkos::IndexType<LO>>;
6472 const char tfecfFuncName[] =
"applyCrsPadding";
6473 const char suffix[] =
6474 ". Please report this bug to the Tpetra developers.";
6475 ProfilingRegion regionCAP(
"Tpetra::CrsMatrix::applyCrsPadding");
6477 std::unique_ptr<std::string> prefix;
6479 prefix = this->createPrefix(
"CrsMatrix", tfecfFuncName);
6480 std::ostringstream os;
6481 os << *prefix <<
"padding: ";
6484 std::cerr << os.str();
6486 const int myRank = ! verbose ? -1 : [&] () {
6487 auto map = this->getMap();
6488 if (map.is_null()) {
6491 auto comm = map->getComm();
6492 if (comm.is_null()) {
6495 return comm->getRank();
6499 if (! myGraph_->indicesAreAllocated()) {
6501 std::ostringstream os;
6502 os << *prefix <<
"Call allocateIndices" << endl;
6503 std::cerr << os.str();
6505 allocateValues(GlobalIndices, GraphNotYetAllocated, verbose);
6517 std::ostringstream os;
6518 os << *prefix <<
"Allocate row_ptrs_beg: "
6519 << myGraph_->k_rowPtrs_.extent(0) << endl;
6520 std::cerr << os.str();
6522 using Kokkos::view_alloc;
6523 using Kokkos::WithoutInitializing;
6524 row_ptrs_type row_ptr_beg(
6525 view_alloc(
"row_ptr_beg", WithoutInitializing),
6526 myGraph_->k_rowPtrs_.extent(0));
6529 const size_t N = row_ptr_beg.extent(0) == 0 ? size_t(0) :
6530 size_t(row_ptr_beg.extent(0) - 1);
6532 std::ostringstream os;
6533 os << *prefix <<
"Allocate row_ptrs_end: " << N << endl;
6534 std::cerr << os.str();
6536 row_ptrs_type row_ptr_end(
6537 view_alloc(
"row_ptr_end", WithoutInitializing), N);
6539 const bool refill_num_row_entries =
6540 myGraph_->k_numRowEntries_.extent(0) != 0;
6542 if (refill_num_row_entries) {
6545 auto num_row_entries = myGraph_->k_numRowEntries_;
6546 Kokkos::parallel_for
6547 (
"Fill end row pointers", range_policy(0, N),
6548 KOKKOS_LAMBDA (
const size_t i) {
6549 row_ptr_end(i) = row_ptr_beg(i) + num_row_entries(i);
6556 Kokkos::parallel_for
6557 (
"Fill end row pointers", range_policy(0, N),
6558 KOKKOS_LAMBDA (
const size_t i) {
6559 row_ptr_end(i) = row_ptr_beg(i+1);
6563 if (myGraph_->isGloballyIndexed()) {
6564 padCrsArrays(row_ptr_beg, row_ptr_end, myGraph_->k_gblInds1D_,
6565 k_values1D_, padding, myRank, verbose);
6566 const auto newValuesLen = k_values1D_.extent(0);
6567 const auto newColIndsLen = myGraph_->k_gblInds1D_.extent(0);
6568 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6569 (newValuesLen != newColIndsLen, std::logic_error,
6570 ": After padding, k_values1D_.extent(0)=" << newValuesLen
6571 <<
" != myGraph_->k_gblInds1D_.extent(0)=" << newColIndsLen
6575 padCrsArrays(row_ptr_beg, row_ptr_end, myGraph_->k_lclInds1D_,
6576 k_values1D_, padding, myRank, verbose);
6577 const auto newValuesLen = k_values1D_.extent(0);
6578 const auto newColIndsLen = myGraph_->k_lclInds1D_.extent(0);
6579 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6580 (newValuesLen != newColIndsLen, std::logic_error,
6581 ": After padding, k_values1D_.extent(0)=" << newValuesLen
6582 <<
" != myGraph_->k_lclInds1D_.extent(0)=" << newColIndsLen
6586 if (refill_num_row_entries) {
6587 auto num_row_entries = myGraph_->k_numRowEntries_;
6588 Kokkos::parallel_for
6589 (
"Fill num entries", range_policy(0, N),
6590 KOKKOS_LAMBDA (
const size_t i) {
6591 num_row_entries(i) = row_ptr_end(i) - row_ptr_beg(i);
6596 std::ostringstream os;
6597 os << *prefix <<
"Assign myGraph_->k_rowPtrs_; "
6598 <<
"old size: " << myGraph_->k_rowPtrs_.extent(0)
6599 <<
", new size: " << row_ptr_beg.extent(0) << endl;
6600 std::cerr << os.str();
6601 TEUCHOS_ASSERT( myGraph_->k_rowPtrs_.extent(0) ==
6602 row_ptr_beg.extent(0) );
6604 myGraph_->k_rowPtrs_ = row_ptr_beg;
6607 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6609 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6610 copyAndPermuteStaticGraph(
6611 const RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& srcMat,
6612 const size_t numSameIDs,
6613 const LocalOrdinal permuteToLIDs[],
6614 const LocalOrdinal permuteFromLIDs[],
6615 const size_t numPermutes)
6617 using Details::ProfilingRegion;
6618 using Teuchos::Array;
6619 using Teuchos::ArrayView;
6621 using LO = LocalOrdinal;
6622 using GO = GlobalOrdinal;
6623 const char tfecfFuncName[] =
"copyAndPermuteStaticGraph";
6624 const char suffix[] =
6625 " Please report this bug to the Tpetra developers.";
6626 ProfilingRegion regionCAP
6627 (
"Tpetra::CrsMatrix::copyAndPermuteStaticGraph");
6631 std::unique_ptr<std::string> prefix;
6633 prefix = this->
createPrefix(
"CrsGraph", tfecfFuncName);
6634 std::ostringstream os;
6635 os << *prefix <<
"Start" << endl;
6637 const char*
const prefix_raw =
6638 verbose ? prefix.get()->c_str() :
nullptr;
6640 const bool sourceIsLocallyIndexed = srcMat.isLocallyIndexed ();
6645 const map_type& srcRowMap = * (srcMat.getRowMap ());
6647 Array<Scalar> rowVals;
6648 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
6649 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
6653 const GO sourceGID = srcRowMap.getGlobalElement (sourceLID);
6654 const GO targetGID = sourceGID;
6656 ArrayView<const GO> rowIndsConstView;
6657 ArrayView<const Scalar> rowValsConstView;
6659 if (sourceIsLocallyIndexed) {
6660 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
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,
6675 rowValsView, checkRowLength);
6677 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6678 (rowLength != checkRowLength, std::logic_error,
"For "
6679 "global row index " << sourceGID <<
", the source "
6680 "matrix's getNumEntriesInGlobalRow returns a row length "
6681 "of " << rowLength <<
", but getGlobalRowCopy reports "
6682 "a row length of " << checkRowLength <<
"." << suffix);
6684 rowIndsConstView = rowIndsView.view (0, rowLength);
6685 rowValsConstView = rowValsView.view (0, rowLength);
6688 srcMat.getGlobalRowView(sourceGID, rowIndsConstView,
6694 combineGlobalValues(targetGID, rowIndsConstView,
6696 prefix_raw, debug, verbose);
6700 std::ostringstream os;
6701 os << *prefix <<
"Do permutes" << endl;
6704 const map_type& tgtRowMap = * (this->getRowMap ());
6705 for (
size_t p = 0; p < numPermutes; ++p) {
6706 const GO sourceGID = srcRowMap.getGlobalElement (permuteFromLIDs[p]);
6707 const GO targetGID = tgtRowMap.getGlobalElement (permuteToLIDs[p]);
6709 ArrayView<const GO> rowIndsConstView;
6710 ArrayView<const Scalar> rowValsConstView;
6712 if (sourceIsLocallyIndexed) {
6713 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6714 if (rowLength > static_cast<size_t> (rowInds.size ())) {
6715 rowInds.resize (rowLength);
6716 rowVals.resize (rowLength);
6720 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
6721 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
6726 size_t checkRowLength = 0;
6727 srcMat.getGlobalRowCopy(sourceGID, rowIndsView,
6728 rowValsView, checkRowLength);
6730 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6731 (rowLength != checkRowLength, std::logic_error,
"For "
6732 "source matrix global row index " << sourceGID <<
", "
6733 "getNumEntriesInGlobalRow returns a row length of " <<
6734 rowLength <<
", but getGlobalRowCopy a row length of "
6735 << checkRowLength <<
"." << suffix);
6737 rowIndsConstView = rowIndsView.view (0, rowLength);
6738 rowValsConstView = rowValsView.view (0, rowLength);
6741 srcMat.getGlobalRowView(sourceGID, rowIndsConstView,
6745 combineGlobalValues(targetGID, rowIndsConstView,
6747 prefix_raw, debug, verbose);
6751 std::ostringstream os;
6752 os << *prefix <<
"Done" << endl;
6756 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6758 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6759 copyAndPermuteNonStaticGraph(
6760 const RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& srcMat,
6761 const size_t numSameIDs,
6762 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs_dv,
6763 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs_dv,
6764 const size_t numPermutes)
6766 using Details::ProfilingRegion;
6767 using Teuchos::Array;
6768 using Teuchos::ArrayView;
6770 using LO = LocalOrdinal;
6771 using GO = GlobalOrdinal;
6772 const char tfecfFuncName[] =
"copyAndPermuteNonStaticGraph";
6773 const char suffix[] =
6774 " Please report this bug to the Tpetra developers.";
6775 ProfilingRegion regionCAP
6776 (
"Tpetra::CrsMatrix::copyAndPermuteNonStaticGraph");
6780 std::unique_ptr<std::string> prefix;
6782 prefix = this->
createPrefix(
"CrsGraph", tfecfFuncName);
6783 std::ostringstream os;
6784 os << *prefix <<
"Start" << endl;
6786 const char*
const prefix_raw =
6787 verbose ? prefix.get()->c_str() :
nullptr;
6790 using row_graph_type = RowGraph<LO, GO, Node>;
6791 const row_graph_type& srcGraph = *(srcMat.getGraph());
6793 myGraph_->computeCrsPadding(srcGraph, numSameIDs,
6794 permuteToLIDs_dv, permuteFromLIDs_dv, verbose);
6795 applyCrsPadding(*padding, verbose);
6797 const bool sourceIsLocallyIndexed = srcMat.isLocallyIndexed ();
6802 const map_type& srcRowMap = * (srcMat.getRowMap ());
6804 Array<Scalar> rowVals;
6805 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
6806 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
6810 const GO sourceGID = srcRowMap.getGlobalElement (sourceLID);
6811 const GO targetGID = sourceGID;
6813 ArrayView<const GO> rowIndsConstView;
6814 ArrayView<const Scalar> rowValsConstView;
6816 if (sourceIsLocallyIndexed) {
6817 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6818 if (rowLength > static_cast<size_t> (rowInds.size())) {
6819 rowInds.resize (rowLength);
6820 rowVals.resize (rowLength);
6824 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
6825 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
6830 size_t checkRowLength = 0;
6831 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView,
6834 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6835 (rowLength != checkRowLength, std::logic_error,
": For "
6836 "global row index " << sourceGID <<
", the source "
6837 "matrix's getNumEntriesInGlobalRow returns a row length "
6838 "of " << rowLength <<
", but getGlobalRowCopy reports "
6839 "a row length of " << checkRowLength <<
"." << suffix);
6841 rowIndsConstView = rowIndsView.view (0, rowLength);
6842 rowValsConstView = rowValsView.view (0, rowLength);
6845 srcMat.getGlobalRowView(sourceGID, rowIndsConstView,
6850 insertGlobalValuesFilteredChecked(targetGID, rowIndsConstView,
6851 rowValsConstView, prefix_raw, debug, verbose);
6855 std::ostringstream os;
6856 os << *prefix <<
"Do permutes" << endl;
6858 const LO*
const permuteFromLIDs = permuteFromLIDs_dv.view_host().data();
6859 const LO*
const permuteToLIDs = permuteToLIDs_dv.view_host().data();
6861 const map_type& tgtRowMap = * (this->getRowMap ());
6862 for (
size_t p = 0; p < numPermutes; ++p) {
6863 const GO sourceGID = srcRowMap.getGlobalElement (permuteFromLIDs[p]);
6864 const GO targetGID = tgtRowMap.getGlobalElement (permuteToLIDs[p]);
6866 ArrayView<const GO> rowIndsConstView;
6867 ArrayView<const Scalar> rowValsConstView;
6869 if (sourceIsLocallyIndexed) {
6870 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6871 if (rowLength > static_cast<size_t> (rowInds.size ())) {
6872 rowInds.resize (rowLength);
6873 rowVals.resize (rowLength);
6877 ArrayView<GO> rowIndsView = rowInds.view (0, rowLength);
6878 ArrayView<Scalar> rowValsView = rowVals.view (0, rowLength);
6883 size_t checkRowLength = 0;
6884 srcMat.getGlobalRowCopy(sourceGID, rowIndsView,
6885 rowValsView, checkRowLength);
6887 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6888 (rowLength != checkRowLength, std::logic_error,
"For "
6889 "source matrix global row index " << sourceGID <<
", "
6890 "getNumEntriesInGlobalRow returns a row length of " <<
6891 rowLength <<
", but getGlobalRowCopy a row length of "
6892 << checkRowLength <<
"." << suffix);
6894 rowIndsConstView = rowIndsView.view (0, rowLength);
6895 rowValsConstView = rowValsView.view (0, rowLength);
6898 srcMat.getGlobalRowView(sourceGID, rowIndsConstView,
6903 insertGlobalValuesFilteredChecked(targetGID, rowIndsConstView,
6904 rowValsConstView, prefix_raw, debug, verbose);
6908 std::ostringstream os;
6909 os << *prefix <<
"Done" << endl;
6913 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6915 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6917 const SrcDistObject& srcObj,
6918 const size_t numSameIDs,
6919 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs,
6920 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs)
6922 using Details::Behavior;
6924 using Details::ProfilingRegion;
6928 const char tfecfFuncName[] =
"copyAndPermute: ";
6929 ProfilingRegion regionCAP(
"Tpetra::CrsMatrix::copyAndPermute");
6931 const bool verbose = Behavior::verbose(
"CrsMatrix");
6932 std::unique_ptr<std::string> prefix;
6934 prefix = this->
createPrefix(
"CrsMatrix",
"copyAndPermute");
6935 std::ostringstream os;
6936 os << *prefix << endl
6937 << *prefix <<
" numSameIDs: " << numSameIDs << endl
6938 << *prefix <<
" numPermute: " << permuteToLIDs.extent(0)
6947 <<
"isStaticGraph: " << (isStaticGraph() ?
"true" :
"false")
6949 std::cerr << os.str ();
6952 const auto numPermute = permuteToLIDs.extent (0);
6953 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6954 (numPermute != permuteFromLIDs.extent (0),
6955 std::invalid_argument,
"permuteToLIDs.extent(0) = "
6956 << numPermute <<
"!= permuteFromLIDs.extent(0) = "
6957 << permuteFromLIDs.extent (0) <<
".");
6961 using RMT = RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
6962 const RMT& srcMat =
dynamic_cast<const RMT&
> (srcObj);
6963 if (isStaticGraph ()) {
6964 TEUCHOS_ASSERT( ! permuteToLIDs.need_sync_host () );
6965 auto permuteToLIDs_h = permuteToLIDs.view_host ();
6966 TEUCHOS_ASSERT( ! permuteFromLIDs.need_sync_host () );
6967 auto permuteFromLIDs_h = permuteFromLIDs.view_host ();
6969 copyAndPermuteStaticGraph(srcMat, numSameIDs,
6970 permuteToLIDs_h.data(),
6971 permuteFromLIDs_h.data(),
6975 copyAndPermuteNonStaticGraph(srcMat, numSameIDs, permuteToLIDs,
6976 permuteFromLIDs, numPermute);
6980 std::ostringstream os;
6981 os << *prefix <<
"Done" << endl;
6982 std::cerr << os.str();
6986 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6988 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6990 (
const SrcDistObject& source,
6991 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
6992 Kokkos::DualView<char*, buffer_device_type>& exports,
6993 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
6994 size_t& constantNumPackets,
6995 Distributor& distor)
6997 using Details::Behavior;
6999 using Details::ProfilingRegion;
7000 using Teuchos::outArg;
7001 using Teuchos::REDUCE_MAX;
7002 using Teuchos::reduceAll;
7004 typedef LocalOrdinal LO;
7005 typedef GlobalOrdinal GO;
7006 const char tfecfFuncName[] =
"packAndPrepare: ";
7007 ProfilingRegion regionPAP (
"Tpetra::CrsMatrix::packAndPrepare");
7009 const bool debug = Behavior::debug(
"CrsMatrix");
7010 const bool verbose = Behavior::verbose(
"CrsMatrix");
7013 Teuchos::RCP<const Teuchos::Comm<int> > pComm = this->getComm ();
7014 if (pComm.is_null ()) {
7017 const Teuchos::Comm<int>& comm = *pComm;
7018 const int myRank = comm.getSize ();
7020 std::unique_ptr<std::string> prefix;
7022 prefix = this->
createPrefix(
"CrsMatrix",
"packAndPrepare");
7023 std::ostringstream os;
7024 os << *prefix <<
"Start" << endl
7034 std::cerr << os.str ();
7057 std::ostringstream msg;
7060 using crs_matrix_type = CrsMatrix<Scalar, LO, GO, Node>;
7061 const crs_matrix_type* srcCrsMat =
7062 dynamic_cast<const crs_matrix_type*
> (&source);
7063 if (srcCrsMat !=
nullptr) {
7065 std::ostringstream os;
7066 os << *prefix <<
"Source matrix same (CrsMatrix) type as target; "
7067 "calling packNew" << endl;
7068 std::cerr << os.str ();
7071 srcCrsMat->packNew (exportLIDs, exports, numPacketsPerLID,
7072 constantNumPackets, distor);
7074 catch (std::exception& e) {
7076 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
7080 using Kokkos::HostSpace;
7081 using Kokkos::subview;
7082 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
7083 using range_type = Kokkos::pair<size_t, size_t>;
7086 std::ostringstream os;
7087 os << *prefix <<
"Source matrix NOT same (CrsMatrix) type as target"
7089 std::cerr << os.str ();
7092 using row_matrix_type = RowMatrix<Scalar, LO, GO, Node>;
7093 const row_matrix_type* srcRowMat =
7094 dynamic_cast<const row_matrix_type*
> (&source);
7095 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7096 (srcRowMat ==
nullptr, std::invalid_argument,
7097 "The source object of the Import or Export operation is neither a "
7098 "CrsMatrix (with the same template parameters as the target object), "
7099 "nor a RowMatrix (with the same first four template parameters as the "
7110 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
7111 auto exportLIDs_h = exportLIDs.view_host ();
7112 Teuchos::ArrayView<const LO> exportLIDs_av (exportLIDs_h.data (),
7113 exportLIDs_h.size ());
7117 Teuchos::Array<char> exports_a;
7123 numPacketsPerLID.clear_sync_state ();
7124 numPacketsPerLID.modify_host ();
7125 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
7126 Teuchos::ArrayView<size_t> numPacketsPerLID_av (numPacketsPerLID_h.data (),
7127 numPacketsPerLID_h.size ());
7132 srcRowMat->pack (exportLIDs_av, exports_a, numPacketsPerLID_av,
7133 constantNumPackets, distor);
7135 catch (std::exception& e) {
7137 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
7141 const size_t newAllocSize =
static_cast<size_t> (exports_a.size ());
7142 if (static_cast<size_t> (exports.extent (0)) < newAllocSize) {
7143 const std::string oldLabel = exports.d_view.label ();
7144 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
7145 exports = exports_type (newLabel, newAllocSize);
7150 exports.modify_host();
7152 auto exports_h = exports.view_host ();
7153 auto exports_h_sub = subview (exports_h, range_type (0, newAllocSize));
7157 typedef typename exports_type::t_host::execution_space HES;
7158 typedef Kokkos::Device<HES, HostSpace> host_device_type;
7159 Kokkos::View<const char*, host_device_type>
7160 exports_a_kv (exports_a.getRawPtr (), newAllocSize);
7166 reduceAll<int, int> (comm, REDUCE_MAX, lclBad, outArg (gblBad));
7169 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7170 (
true, std::logic_error,
"packNew() or pack() threw an exception on "
7171 "one or more participating processes.");
7175 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7176 (lclBad != 0, std::logic_error,
"packNew threw an exception on one "
7177 "or more participating processes. Here is this process' error "
7178 "message: " << msg.str ());
7182 std::ostringstream os;
7183 os << *prefix <<
"packAndPrepare: Done!" << endl
7193 std::cerr << os.str ();
7197 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7199 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7200 packRow (
char exports[],
7201 const size_t offset,
7202 const size_t numEnt,
7203 const GlobalOrdinal gidsIn[],
7204 const impl_scalar_type valsIn[],
7205 const size_t numBytesPerValue)
const
7208 using Kokkos::subview;
7210 typedef LocalOrdinal LO;
7211 typedef GlobalOrdinal GO;
7212 typedef impl_scalar_type ST;
7220 const LO numEntLO =
static_cast<size_t> (numEnt);
7222 const size_t numEntBeg = offset;
7224 const size_t gidsBeg = numEntBeg + numEntLen;
7225 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount (gid);
7226 const size_t valsBeg = gidsBeg + gidsLen;
7227 const size_t valsLen = numEnt * numBytesPerValue;
7229 char*
const numEntOut = exports + numEntBeg;
7230 char*
const gidsOut = exports + gidsBeg;
7231 char*
const valsOut = exports + valsBeg;
7233 size_t numBytesOut = 0;
7238 Kokkos::pair<int, size_t> p;
7239 p = PackTraits<GO>::packArray (gidsOut, gidsIn, numEnt);
7240 errorCode += p.first;
7241 numBytesOut += p.second;
7243 p = PackTraits<ST>::packArray (valsOut, valsIn, numEnt);
7244 errorCode += p.first;
7245 numBytesOut += p.second;
7248 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
7249 TEUCHOS_TEST_FOR_EXCEPTION
7250 (numBytesOut != expectedNumBytes, std::logic_error,
"packRow: "
7251 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
7252 << expectedNumBytes <<
".");
7253 TEUCHOS_TEST_FOR_EXCEPTION
7254 (errorCode != 0, std::runtime_error,
"packRow: "
7255 "PackTraits::packArray returned a nonzero error code");
7260 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7262 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7263 unpackRow (GlobalOrdinal gidsOut[],
7264 impl_scalar_type valsOut[],
7265 const char imports[],
7266 const size_t offset,
7267 const size_t numBytes,
7268 const size_t numEnt,
7269 const size_t numBytesPerValue)
7272 using Kokkos::subview;
7274 typedef LocalOrdinal LO;
7275 typedef GlobalOrdinal GO;
7276 typedef impl_scalar_type ST;
7278 Details::ProfilingRegion region_upack_row(
7279 "Tpetra::CrsMatrix::unpackRow",
7283 if (numBytes == 0) {
7286 const int myRank = this->getMap ()->getComm ()->getRank ();
7287 TEUCHOS_TEST_FOR_EXCEPTION
7288 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
7289 "unpackRow: The number of bytes to unpack numBytes=0, but the "
7290 "number of entries to unpack (as reported by numPacketsPerLID) "
7291 "for this row numEnt=" << numEnt <<
" != 0.");
7296 if (numEnt == 0 && numBytes != 0) {
7297 const int myRank = this->getMap ()->getComm ()->getRank ();
7298 TEUCHOS_TEST_FOR_EXCEPTION
7299 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
7300 "unpackRow: The number of entries to unpack (as reported by "
7301 "numPacketsPerLID) numEnt=0, but the number of bytes to unpack "
7302 "numBytes=" << numBytes <<
" != 0.");
7308 const size_t numEntBeg = offset;
7310 const size_t gidsBeg = numEntBeg + numEntLen;
7311 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount (gid);
7312 const size_t valsBeg = gidsBeg + gidsLen;
7313 const size_t valsLen = numEnt * numBytesPerValue;
7315 const char*
const numEntIn = imports + numEntBeg;
7316 const char*
const gidsIn = imports + gidsBeg;
7317 const char*
const valsIn = imports + valsBeg;
7319 size_t numBytesOut = 0;
7323 if (static_cast<size_t> (numEntOut) != numEnt ||
7324 numEntOut == static_cast<LO> (0)) {
7325 const int myRank = this->getMap ()->getComm ()->getRank ();
7326 std::ostringstream os;
7327 os <<
"(Proc " << myRank <<
") CrsMatrix::unpackRow: ";
7328 bool firstErrorCondition =
false;
7329 if (static_cast<size_t> (numEntOut) != numEnt) {
7330 os <<
"Number of entries from numPacketsPerLID numEnt=" << numEnt
7331 <<
" does not equal number of entries unpacked from imports "
7332 "buffer numEntOut=" << numEntOut <<
".";
7333 firstErrorCondition =
true;
7335 if (numEntOut == static_cast<LO> (0)) {
7336 if (firstErrorCondition) {
7339 os <<
"Number of entries unpacked from imports buffer numEntOut=0, "
7340 "but number of bytes to unpack for this row numBytes=" << numBytes
7341 <<
" != 0. This should never happen, since packRow should only "
7342 "ever pack rows with a nonzero number of entries. In this case, "
7343 "the number of entries from numPacketsPerLID is numEnt=" << numEnt
7346 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, os.str ());
7350 Kokkos::pair<int, size_t> p;
7351 p = PackTraits<GO>::unpackArray (gidsOut, gidsIn, numEnt);
7352 errorCode += p.first;
7353 numBytesOut += p.second;
7355 p = PackTraits<ST>::unpackArray (valsOut, valsIn, numEnt);
7356 errorCode += p.first;
7357 numBytesOut += p.second;
7360 TEUCHOS_TEST_FOR_EXCEPTION
7361 (numBytesOut != numBytes, std::logic_error,
"unpackRow: numBytesOut = "
7362 << numBytesOut <<
" != numBytes = " << numBytes <<
".");
7364 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
7365 TEUCHOS_TEST_FOR_EXCEPTION
7366 (numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: "
7367 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
7368 << expectedNumBytes <<
".");
7370 TEUCHOS_TEST_FOR_EXCEPTION
7371 (errorCode != 0, std::runtime_error,
"unpackRow: "
7372 "PackTraits::unpackArray returned a nonzero error code");
7377 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7379 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7380 allocatePackSpaceNew (Kokkos::DualView<char*, buffer_device_type>& exports,
7381 size_t& totalNumEntries,
7382 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs)
const
7384 using Details::Behavior;
7387 typedef impl_scalar_type IST;
7388 typedef LocalOrdinal LO;
7389 typedef GlobalOrdinal GO;
7395 const bool verbose = Behavior::verbose(
"CrsMatrix");
7396 std::unique_ptr<std::string> prefix;
7398 prefix = this->
createPrefix(
"CrsMatrix",
"allocatePackSpaceNew");
7399 std::ostringstream os;
7400 os << *prefix <<
"Before:"
7408 std::cerr << os.str ();
7413 const LO numExportLIDs =
static_cast<LO
> (exportLIDs.extent (0));
7415 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
7416 auto exportLIDs_h = exportLIDs.view_host ();
7419 totalNumEntries = 0;
7420 for (LO i = 0; i < numExportLIDs; ++i) {
7421 const LO lclRow = exportLIDs_h[i];
7422 size_t curNumEntries = this->getNumEntriesInLocalRow (lclRow);
7425 if (curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7428 totalNumEntries += curNumEntries;
7439 const size_t allocSize =
7440 static_cast<size_t> (numExportLIDs) *
sizeof (LO) +
7441 totalNumEntries * (
sizeof (IST) +
sizeof (GO));
7442 if (static_cast<size_t> (exports.extent (0)) < allocSize) {
7443 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
7445 const std::string oldLabel = exports.d_view.label ();
7446 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
7447 exports = exports_type (newLabel, allocSize);
7451 std::ostringstream os;
7452 os << *prefix <<
"After:"
7460 std::cerr << os.str ();
7464 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7467 packNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7468 Kokkos::DualView<char*, buffer_device_type>& exports,
7469 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7470 size_t& constantNumPackets,
7475 if (this->isStaticGraph ()) {
7478 constantNumPackets, dist);
7481 this->packNonStaticNew (exportLIDs, exports, numPacketsPerLID,
7482 constantNumPackets, dist);
7486 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7489 packNonStaticNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7490 Kokkos::DualView<char*, buffer_device_type>& exports,
7491 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7492 size_t& constantNumPackets,
7501 using LO = LocalOrdinal;
7502 using GO = GlobalOrdinal;
7503 using ST = impl_scalar_type;
7505 typename View<int*, device_type>::HostMirror::execution_space;
7506 const char tfecfFuncName[] =
"packNonStaticNew: ";
7508 const bool verbose = Behavior::verbose(
"CrsMatrix");
7509 std::unique_ptr<std::string> prefix;
7511 prefix = this->createPrefix(
"CrsMatrix",
"packNonStaticNew");
7512 std::ostringstream os;
7513 os << *prefix <<
"Start" << endl;
7514 std::cerr << os.str ();
7517 const size_t numExportLIDs =
static_cast<size_t> (exportLIDs.extent (0));
7518 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7519 (numExportLIDs != static_cast<size_t> (numPacketsPerLID.extent (0)),
7520 std::invalid_argument,
"exportLIDs.size() = " << numExportLIDs
7521 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.extent (0)
7527 constantNumPackets = 0;
7532 size_t totalNumEntries = 0;
7533 this->allocatePackSpaceNew (exports, totalNumEntries, exportLIDs);
7534 const size_t bufSize =
static_cast<size_t> (exports.extent (0));
7537 exports.clear_sync_state();
7538 exports.modify_host();
7539 auto exports_h = exports.view_host ();
7541 std::ostringstream os;
7542 os << *prefix <<
"After marking exports as modified on host, "
7544 std::cerr << os.str ();
7548 auto exportLIDs_h = exportLIDs.view_host ();
7551 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->clear_sync_state();
7552 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->modify_host();
7553 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
7559 for (
size_t i = 0; i < numExportLIDs; ++i) {
7560 const LO lclRow = exportLIDs_h[i];
7563 numEnt = this->getNumEntriesInLocalRow (lclRow);
7570 numPacketsPerLID_h[i] = 0;
7575 using Details::ScalarViewTraits;
7576 View<GO*, HES> gidsIn_k =
7577 ScalarViewTraits<GO, HES>::allocateArray (GO (0), numEnt,
"gids");
7579 Teuchos::ArrayView<const Scalar> valsIn;
7580 if (this->isLocallyIndexed ()) {
7584 Teuchos::ArrayView<const LO> lidsIn;
7585 this->getLocalRowView (lclRow, lidsIn, valsIn);
7586 const map_type& colMap = * (this->getColMap ());
7587 for (
size_t k = 0; k < numEnt; ++k) {
7588 gidsIn_k[k] = colMap.getGlobalElement (lidsIn[k]);
7591 else if (this->isGloballyIndexed ()) {
7597 Teuchos::ArrayView<const GO> gblIndView;;
7598 const map_type& rowMap = * (this->getRowMap ());
7599 const GO gblRow = rowMap.getGlobalElement (lclRow);
7600 this->getGlobalRowView (gblRow, gblIndView, valsIn);
7601 for (
size_t k = 0; k < numEnt; ++k) {
7602 gidsIn_k[k] = gblIndView[k];
7609 typename HES::device_type outputDevice;
7612 reinterpret_cast<const ST*> (valsIn.getRawPtr ()),
7615 const size_t numBytesPerValue =
7616 PackTraits<ST>::packValueCount (valsIn[0]);
7617 const size_t numBytes =
7618 this->packRow (exports_h.data (), offset, numEnt, gidsIn_k.data (),
7619 valsIn_k.data (), numBytesPerValue);
7620 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7621 (offset > bufSize || offset + numBytes > bufSize, std::logic_error,
7622 "First invalid offset into 'exports' pack buffer at index i = " << i
7623 <<
". exportLIDs_h[i]: " << exportLIDs_h[i] <<
", bufSize: " <<
7624 bufSize <<
", offset: " << offset <<
", numBytes: " << numBytes <<
7629 numPacketsPerLID_h[i] = numBytes;
7634 std::ostringstream os;
7635 os << *prefix <<
"Tpetra::CrsMatrix::packNonStaticNew: After:" << endl
7642 std::cerr << os.str ();
7646 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7648 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7649 combineGlobalValuesRaw(
const LocalOrdinal lclRow,
7650 const LocalOrdinal numEnt,
7651 const impl_scalar_type vals[],
7652 const GlobalOrdinal cols[],
7654 const char*
const prefix,
7658 using GO = GlobalOrdinal;
7662 const GO gblRow = myGraph_->rowMap_->getGlobalElement(lclRow);
7663 Teuchos::ArrayView<const GO> cols_av
7664 (numEnt == 0 ?
nullptr : cols, numEnt);
7665 Teuchos::ArrayView<const Scalar> vals_av
7666 (numEnt == 0 ?
nullptr : reinterpret_cast<const Scalar*> (vals), numEnt);
7671 combineGlobalValues(gblRow, cols_av, vals_av, combMode,
7672 prefix, debug, verbose);
7676 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7678 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7679 combineGlobalValues(
7680 const GlobalOrdinal globalRowIndex,
7681 const Teuchos::ArrayView<const GlobalOrdinal>& columnIndices,
7682 const Teuchos::ArrayView<const Scalar>& values,
7684 const char*
const prefix,
7688 const char tfecfFuncName[] =
"combineGlobalValues: ";
7690 if (isStaticGraph ()) {
7694 if (combineMode ==
ADD) {
7695 sumIntoGlobalValues (globalRowIndex, columnIndices, values);
7697 else if (combineMode ==
REPLACE) {
7698 replaceGlobalValues (globalRowIndex, columnIndices, values);
7700 else if (combineMode ==
ABSMAX) {
7701 using ::Tpetra::Details::AbsMax;
7703 this->
template transformGlobalValues<AbsMax<Scalar> > (globalRowIndex,
7707 else if (combineMode ==
INSERT) {
7708 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7709 (isStaticGraph() && combineMode ==
INSERT,
7710 std::invalid_argument,
"INSERT combine mode is forbidden "
7711 "if the matrix has a static (const) graph (i.e., was "
7712 "constructed with the CrsMatrix constructor that takes a "
7713 "const CrsGraph pointer).");
7716 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7717 (
true, std::logic_error,
"Invalid combine mode; should "
7719 "Please report this bug to the Tpetra developers.");
7723 if (combineMode ==
ADD || combineMode ==
INSERT) {
7730 insertGlobalValuesFilteredChecked(globalRowIndex,
7731 columnIndices, values, prefix, debug, verbose);
7742 else if (combineMode ==
ABSMAX) {
7743 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7744 ! isStaticGraph () && combineMode ==
ABSMAX, std::logic_error,
7745 "ABSMAX combine mode when the matrix has a dynamic graph is not yet "
7748 else if (combineMode ==
REPLACE) {
7749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7750 ! isStaticGraph () && combineMode ==
REPLACE, std::logic_error,
7751 "REPLACE combine mode when the matrix has a dynamic graph is not yet "
7755 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7756 true, std::logic_error,
"Should never get here! Please report this "
7757 "bug to the Tpetra developers.");
7762 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7766 (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& importLIDs,
7767 Kokkos::DualView<char*, buffer_device_type> imports,
7768 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7769 const size_t constantNumPackets,
7777 const char tfecfFuncName[] =
"unpackAndCombine: ";
7778 ProfilingRegion regionUAC (
"Tpetra::CrsMatrix::unpackAndCombine");
7780 const bool debug = Behavior::debug(
"CrsMatrix");
7781 const bool verbose = Behavior::verbose(
"CrsMatrix");
7782 constexpr
int numValidModes = 5;
7785 const char* validModeNames[numValidModes] =
7786 {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT",
"ZERO"};
7788 std::unique_ptr<std::string> prefix;
7790 prefix = this->createPrefix(
"CrsMatrix",
"unpackAndCombine");
7791 std::ostringstream os;
7792 os << *prefix <<
"Start:" << endl
7802 << *prefix <<
" constantNumPackets: " << constantNumPackets
7806 std::cerr << os.str ();
7810 if (std::find (validModes, validModes+numValidModes, combineMode) ==
7811 validModes+numValidModes) {
7812 std::ostringstream os;
7813 os <<
"Invalid combine mode. Valid modes are {";
7814 for (
int k = 0; k < numValidModes; ++k) {
7815 os << validModeNames[k];
7816 if (k < numValidModes - 1) {
7821 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7822 (
true, std::invalid_argument, os.str ());
7824 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7825 (importLIDs.extent(0) != numPacketsPerLID.extent(0),
7826 std::invalid_argument,
"importLIDs.extent(0)="
7827 << importLIDs.extent(0)
7828 <<
" != numPacketsPerLID.extent(0)="
7829 << numPacketsPerLID.extent(0) <<
".");
7832 if (combineMode ==
ZERO) {
7837 using Teuchos::reduceAll;
7838 std::unique_ptr<std::ostringstream> msg (
new std::ostringstream ());
7841 unpackAndCombineImpl(importLIDs, imports, numPacketsPerLID,
7842 constantNumPackets, distor, combineMode,
7844 }
catch (std::exception& e) {
7849 const Teuchos::Comm<int>& comm = * (this->getComm ());
7850 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
7851 lclBad, Teuchos::outArg (gblBad));
7857 std::ostringstream os;
7858 os <<
"Proc " << comm.getRank () <<
": " << msg->str () << endl;
7859 msg = std::unique_ptr<std::ostringstream> (
new std::ostringstream ());
7860 ::Tpetra::Details::gathervPrint (*msg, os.str (), comm);
7861 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7862 (
true, std::logic_error, std::endl <<
"unpackAndCombineImpl "
7863 "threw an exception on one or more participating processes: "
7864 << endl << msg->str ());
7868 unpackAndCombineImpl(importLIDs, imports, numPacketsPerLID,
7869 constantNumPackets, distor, combineMode,
7874 std::ostringstream os;
7875 os << *prefix <<
"Done!" << endl
7885 std::cerr << os.str ();
7889 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7893 const Kokkos::DualView<
const local_ordinal_type*,
7894 buffer_device_type>& importLIDs,
7895 Kokkos::DualView<char*, buffer_device_type> imports,
7896 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7897 const size_t constantNumPackets,
7903 "Tpetra::CrsMatrix::unpackAndCombineImpl",
7907 const char tfecfFuncName[] =
"unpackAndCombineImpl";
7908 std::unique_ptr<std::string> prefix;
7910 prefix = this->createPrefix(
"CrsMatrix", tfecfFuncName);
7911 std::ostringstream os;
7912 os << *prefix <<
"isStaticGraph(): "
7913 << (isStaticGraph() ?
"true" :
"false")
7914 <<
", importLIDs.extent(0): "
7915 << importLIDs.extent(0)
7916 <<
", imports.extent(0): "
7917 << imports.extent(0)
7918 <<
", numPacketsPerLID.extent(0): "
7919 << numPacketsPerLID.extent(0)
7921 std::cerr << os.str();
7924 if (isStaticGraph ()) {
7925 using Details::unpackCrsMatrixAndCombineNew;
7926 unpackCrsMatrixAndCombineNew(*
this, imports, numPacketsPerLID,
7927 importLIDs, constantNumPackets,
7928 distor, combineMode);
7932 using padding_type =
typename crs_graph_type::padding_type;
7933 std::unique_ptr<padding_type> padding;
7935 padding = myGraph_->computePaddingForCrsMatrixUnpack(
7936 importLIDs, imports, numPacketsPerLID, verbose);
7938 catch (std::exception& e) {
7939 const auto rowMap = getRowMap();
7940 const auto comm = rowMap.is_null() ? Teuchos::null :
7942 const int myRank = comm.is_null() ? -1 : comm->getRank();
7943 TEUCHOS_TEST_FOR_EXCEPTION
7944 (
true, std::runtime_error,
"Proc " << myRank <<
": "
7945 "Tpetra::CrsGraph::computePaddingForCrsMatrixUnpack "
7946 "threw an exception: " << e.what());
7949 std::ostringstream os;
7950 os << *prefix <<
"Call applyCrsPadding" << endl;
7951 std::cerr << os.str();
7953 applyCrsPadding(*padding, verbose);
7956 std::ostringstream os;
7957 os << *prefix <<
"Call unpackAndCombineImplNonStatic" << endl;
7958 std::cerr << os.str();
7960 unpackAndCombineImplNonStatic(importLIDs, imports,
7963 distor, combineMode);
7967 std::ostringstream os;
7968 os << *prefix <<
"Done" << endl;
7969 std::cerr << os.str();
7973 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7975 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7976 unpackAndCombineImplNonStatic(
7977 const Kokkos::DualView<
const local_ordinal_type*,
7978 buffer_device_type>& importLIDs,
7979 Kokkos::DualView<char*, buffer_device_type> imports,
7980 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7981 const size_t constantNumPackets,
7982 Distributor& distor,
7986 using Kokkos::subview;
7987 using Kokkos::MemoryUnmanaged;
7988 using Details::Behavior;
7991 using Details::PackTraits;
7992 using Details::ScalarViewTraits;
7994 using LO = LocalOrdinal;
7995 using GO = GlobalOrdinal;
7996 using ST = impl_scalar_type;
7997 using size_type =
typename Teuchos::ArrayView<LO>::size_type;
7999 typename View<int*, device_type>::HostMirror::execution_space;
8000 using pair_type = std::pair<typename View<int*, HES>::size_type,
8001 typename View<int*, HES>::size_type>;
8002 using gids_out_type = View<GO*, HES, MemoryUnmanaged>;
8003 using vals_out_type = View<ST*, HES, MemoryUnmanaged>;
8004 const char tfecfFuncName[] =
"unpackAndCombineImplNonStatic";
8006 const bool debug = Behavior::debug(
"CrsMatrix");
8007 const bool verbose = Behavior::verbose(
"CrsMatrix");
8008 std::unique_ptr<std::string> prefix;
8010 prefix = this->
createPrefix(
"CrsMatrix", tfecfFuncName);
8011 std::ostringstream os;
8012 os << *prefix << endl;
8013 std::cerr << os.str ();
8015 const char*
const prefix_raw =
8016 verbose ? prefix.get()->c_str() :
nullptr;
8018 const size_type numImportLIDs = importLIDs.extent (0);
8019 if (combineMode ==
ZERO || numImportLIDs == 0) {
8023 Details::ProfilingRegion region_unpack_and_combine_impl_non_static(
8024 "Tpetra::CrsMatrix::unpackAndCombineImplNonStatic",
8029 if (imports.need_sync_host()) {
8030 imports.sync_host ();
8032 auto imports_h = imports.view_host();
8035 if (numPacketsPerLID.need_sync_host()) {
8036 numPacketsPerLID.sync_host ();
8038 auto numPacketsPerLID_h = numPacketsPerLID.view_host();
8040 TEUCHOS_ASSERT( ! importLIDs.need_sync_host() );
8041 auto importLIDs_h = importLIDs.view_host();
8043 size_t numBytesPerValue;
8054 numBytesPerValue = PackTraits<ST>::packValueCount (val);
8059 size_t maxRowNumEnt = 0;
8060 for (size_type i = 0; i < numImportLIDs; ++i) {
8061 const size_t numBytes = numPacketsPerLID_h[i];
8062 if (numBytes == 0) {
8067 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8068 (offset + numBytes >
size_t(imports_h.extent (0)),
8069 std::logic_error,
": At local row index importLIDs_h[i="
8070 << i <<
"]=" << importLIDs_h[i] <<
", offset (=" << offset
8071 <<
") + numBytes (=" << numBytes <<
") > "
8072 "imports_h.extent(0)=" << imports_h.extent (0) <<
".");
8077 const size_t theNumBytes =
8079 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8080 (theNumBytes > numBytes, std::logic_error,
": theNumBytes="
8081 << theNumBytes <<
" > numBytes = " << numBytes <<
".");
8083 const char*
const inBuf = imports_h.data () + offset;
8084 const size_t actualNumBytes =
8088 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8089 (actualNumBytes > numBytes, std::logic_error,
": At i=" << i
8090 <<
", actualNumBytes=" << actualNumBytes
8091 <<
" > numBytes=" << numBytes <<
".");
8092 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8093 (numEntLO == 0, std::logic_error,
": At local row index "
8094 "importLIDs_h[i=" << i <<
"]=" << importLIDs_h[i] <<
", "
8095 "the number of entries read from the packed data is "
8096 "numEntLO=" << numEntLO <<
", but numBytes=" << numBytes
8100 maxRowNumEnt = std::max(
size_t(numEntLO), maxRowNumEnt);
8108 View<GO*, HES> gblColInds;
8109 View<LO*, HES> lclColInds;
8110 View<ST*, HES> vals;
8123 gblColInds = ScalarViewTraits<GO, HES>::allocateArray(
8124 gid, maxRowNumEnt,
"gids");
8125 lclColInds = ScalarViewTraits<LO, HES>::allocateArray(
8126 lid, maxRowNumEnt,
"lids");
8127 vals = ScalarViewTraits<ST, HES>::allocateArray(
8128 val, maxRowNumEnt,
"vals");
8132 for (size_type i = 0; i < numImportLIDs; ++i) {
8133 const size_t numBytes = numPacketsPerLID_h[i];
8134 if (numBytes == 0) {
8138 const char*
const inBuf = imports_h.data () + offset;
8141 const size_t numEnt =
static_cast<size_t>(numEntLO);;
8142 const LO lclRow = importLIDs_h[i];
8144 gids_out_type gidsOut = subview (gblColInds, pair_type (0, numEnt));
8145 vals_out_type valsOut = subview (vals, pair_type (0, numEnt));
8147 const size_t numBytesOut =
8148 unpackRow (gidsOut.data (), valsOut.data (), imports_h.data (),
8149 offset, numBytes, numEnt, numBytesPerValue);
8150 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
8151 (numBytes != numBytesOut, std::logic_error,
": At i=" << i
8152 <<
", numBytes=" << numBytes <<
" != numBytesOut="
8153 << numBytesOut <<
".");
8155 const ST*
const valsRaw =
const_cast<const ST*
> (valsOut.data ());
8156 const GO*
const gidsRaw =
const_cast<const GO*
> (gidsOut.data ());
8157 combineGlobalValuesRaw(lclRow, numEnt, valsRaw, gidsRaw,
8158 combineMode, prefix_raw, debug, verbose);
8164 std::ostringstream os;
8165 os << *prefix <<
"Done" << endl;
8166 std::cerr << os.str();
8170 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8171 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8174 const bool force)
const
8176 using Teuchos::null;
8180 TEUCHOS_TEST_FOR_EXCEPTION(
8181 ! this->hasColMap (), std::runtime_error,
"Tpetra::CrsMatrix::getColumn"
8182 "MapMultiVector: You may only call this method if the matrix has a "
8183 "column Map. If the matrix does not yet have a column Map, you should "
8184 "first call fillComplete (with domain and range Map if necessary).");
8188 TEUCHOS_TEST_FOR_EXCEPTION(
8189 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
8190 "CrsMatrix::getColumnMapMultiVector: You may only call this method if "
8191 "this matrix's graph is fill complete.");
8194 RCP<const import_type> importer = this->getGraph ()->getImporter ();
8195 RCP<const map_type> colMap = this->getColMap ();
8208 if (! importer.is_null () || force) {
8209 if (importMV_.is_null () || importMV_->getNumVectors () != numVecs) {
8210 X_colMap = rcp (
new MV (colMap, numVecs));
8213 importMV_ = X_colMap;
8216 X_colMap = importMV_;
8227 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8228 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8231 const bool force)
const
8233 using Teuchos::null;
8239 TEUCHOS_TEST_FOR_EXCEPTION(
8240 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
8241 "CrsMatrix::getRowMapMultiVector: You may only call this method if this "
8242 "matrix's graph is fill complete.");
8245 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
8249 RCP<const map_type> rowMap = this->getRowMap ();
8261 if (! exporter.is_null () || force) {
8262 if (exportMV_.is_null () || exportMV_->getNumVectors () != numVecs) {
8263 Y_rowMap = rcp (
new MV (rowMap, numVecs));
8264 exportMV_ = Y_rowMap;
8267 Y_rowMap = exportMV_;
8273 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8278 TEUCHOS_TEST_FOR_EXCEPTION(
8279 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::"
8280 "removeEmptyProcessesInPlace: This method does not work when the matrix "
8281 "was created with a constant graph (that is, when it was created using "
8282 "the version of its constructor that takes an RCP<const CrsGraph>). "
8283 "This is because the matrix is not allowed to modify the graph in that "
8284 "case, but removing empty processes requires modifying the graph.");
8285 myGraph_->removeEmptyProcessesInPlace (newMap);
8289 this->map_ = this->getRowMap ();
8293 staticGraph_ = Teuchos::rcp_const_cast<
const Graph> (myGraph_);
8296 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8297 Teuchos::RCP<RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
8302 const Teuchos::RCP<const map_type>& domainMap,
8303 const Teuchos::RCP<const map_type>& rangeMap,
8304 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
8306 using Teuchos::Array;
8307 using Teuchos::ArrayView;
8308 using Teuchos::ParameterList;
8311 using Teuchos::rcp_implicit_cast;
8312 using Teuchos::sublist;
8316 using row_matrix_type =
8318 using crs_matrix_type =
8320 const char errPfx[] =
"Tpetra::CrsMatrix::add: ";
8324 std::unique_ptr<std::string> prefix;
8326 prefix = this->createPrefix(
"CrsMatrix",
"add");
8327 std::ostringstream os;
8328 os << *prefix <<
"Start" << endl;
8329 std::cerr << os.str ();
8332 const crs_matrix_type& B = *
this;
8333 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero();
8334 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one();
8341 RCP<const map_type> A_rangeMap = A.
getRangeMap ();
8342 RCP<const map_type> B_domainMap = B.getDomainMap ();
8343 RCP<const map_type> B_rangeMap = B.getRangeMap ();
8345 RCP<const map_type> theDomainMap = domainMap;
8346 RCP<const map_type> theRangeMap = rangeMap;
8348 if (domainMap.is_null ()) {
8349 if (B_domainMap.is_null ()) {
8350 TEUCHOS_TEST_FOR_EXCEPTION(
8351 A_domainMap.is_null (), std::invalid_argument,
8352 "Tpetra::CrsMatrix::add: If neither A nor B have a domain Map, "
8353 "then you must supply a nonnull domain Map to this method.");
8354 theDomainMap = A_domainMap;
8356 theDomainMap = B_domainMap;
8359 if (rangeMap.is_null ()) {
8360 if (B_rangeMap.is_null ()) {
8361 TEUCHOS_TEST_FOR_EXCEPTION(
8362 A_rangeMap.is_null (), std::invalid_argument,
8363 "Tpetra::CrsMatrix::add: If neither A nor B have a range Map, "
8364 "then you must supply a nonnull range Map to this method.");
8365 theRangeMap = A_rangeMap;
8367 theRangeMap = B_rangeMap;
8375 if (! A_domainMap.is_null() && ! A_rangeMap.is_null()) {
8376 if (! B_domainMap.is_null() && ! B_rangeMap.is_null()) {
8377 TEUCHOS_TEST_FOR_EXCEPTION
8378 (! B_domainMap->isSameAs(*A_domainMap),
8379 std::invalid_argument,
8380 errPfx <<
"The input RowMatrix A must have a domain Map "
8381 "which is the same as (isSameAs) this RowMatrix's "
8383 TEUCHOS_TEST_FOR_EXCEPTION
8384 (! B_rangeMap->isSameAs(*A_rangeMap), std::invalid_argument,
8385 errPfx <<
"The input RowMatrix A must have a range Map "
8386 "which is the same as (isSameAs) this RowMatrix's range "
8388 TEUCHOS_TEST_FOR_EXCEPTION
8389 (! domainMap.is_null() &&
8390 ! domainMap->isSameAs(*B_domainMap),
8391 std::invalid_argument,
8392 errPfx <<
"The input domain Map must be the same as "
8393 "(isSameAs) this RowMatrix's domain Map.");
8394 TEUCHOS_TEST_FOR_EXCEPTION
8395 (! rangeMap.is_null() &&
8396 ! rangeMap->isSameAs(*B_rangeMap),
8397 std::invalid_argument,
8398 errPfx <<
"The input range Map must be the same as "
8399 "(isSameAs) this RowMatrix's range Map.");
8402 else if (! B_domainMap.is_null() && ! B_rangeMap.is_null()) {
8403 TEUCHOS_TEST_FOR_EXCEPTION
8404 (! domainMap.is_null() &&
8405 ! domainMap->isSameAs(*B_domainMap),
8406 std::invalid_argument,
8407 errPfx <<
"The input domain Map must be the same as "
8408 "(isSameAs) this RowMatrix's domain Map.");
8409 TEUCHOS_TEST_FOR_EXCEPTION
8410 (! rangeMap.is_null() && ! rangeMap->isSameAs(*B_rangeMap),
8411 std::invalid_argument,
8412 errPfx <<
"The input range Map must be the same as "
8413 "(isSameAs) this RowMatrix's range Map.");
8416 TEUCHOS_TEST_FOR_EXCEPTION
8417 (domainMap.is_null() || rangeMap.is_null(),
8418 std::invalid_argument, errPfx <<
"If neither A nor B "
8419 "have a domain and range Map, then you must supply a "
8420 "nonnull domain and range Map to this method.");
8427 bool callFillComplete =
true;
8428 RCP<ParameterList> constructorSublist;
8429 RCP<ParameterList> fillCompleteSublist;
8430 if (! params.is_null()) {
8432 params->get(
"Call fillComplete", callFillComplete);
8433 constructorSublist = sublist(params,
"Constructor parameters");
8434 fillCompleteSublist = sublist(params,
"fillComplete parameters");
8437 RCP<const map_type> A_rowMap = A.
getRowMap ();
8438 RCP<const map_type> B_rowMap = B.getRowMap ();
8439 RCP<const map_type> C_rowMap = B_rowMap;
8440 RCP<crs_matrix_type> C;
8447 if (A_rowMap->isSameAs (*B_rowMap)) {
8448 const LO localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8449 Array<size_t> C_maxNumEntriesPerRow (localNumRows, 0);
8452 if (alpha != ZERO) {
8453 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8455 C_maxNumEntriesPerRow[localRow] += A_numEntries;
8460 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8461 const size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8462 C_maxNumEntriesPerRow[localRow] += B_numEntries;
8466 if (constructorSublist.is_null ()) {
8467 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8470 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8471 StaticProfile, constructorSublist));
8482 TEUCHOS_TEST_FOR_EXCEPTION
8483 (
true, std::invalid_argument, errPfx <<
"The row maps must "
8484 "be the same for statically allocated matrices, to ensure "
8485 "that there is sufficient space to do the addition.");
8488 TEUCHOS_TEST_FOR_EXCEPTION
8489 (C.is_null (), std::logic_error,
8490 errPfx <<
"C should not be null at this point. "
8491 "Please report this bug to the Tpetra developers.");
8494 std::ostringstream os;
8495 os << *prefix <<
"Compute C = alpha*A + beta*B" << endl;
8496 std::cerr << os.str ();
8502 if (alpha != ZERO) {
8503 const LO A_localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8504 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
8506 const GO globalRow = A_rowMap->getGlobalElement (localRow);
8507 if (A_numEntries > static_cast<size_t> (ind.size ())) {
8508 ind.resize (A_numEntries);
8509 val.resize (A_numEntries);
8511 ArrayView<GO> indView = ind (0, A_numEntries);
8512 ArrayView<Scalar> valView = val (0, A_numEntries);
8516 for (
size_t k = 0; k < A_numEntries; ++k) {
8517 valView[k] *= alpha;
8520 C->insertGlobalValues (globalRow, indView, valView);
8525 const LO B_localNumRows =
static_cast<LO
> (B_rowMap->getNodeNumElements ());
8526 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
8527 size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8528 const GO globalRow = B_rowMap->getGlobalElement (localRow);
8529 if (B_numEntries > static_cast<size_t> (ind.size ())) {
8530 ind.resize (B_numEntries);
8531 val.resize (B_numEntries);
8533 ArrayView<GO> indView = ind (0, B_numEntries);
8534 ArrayView<Scalar> valView = val (0, B_numEntries);
8535 B.getGlobalRowCopy (globalRow, indView, valView, B_numEntries);
8538 for (
size_t k = 0; k < B_numEntries; ++k) {
8542 C->insertGlobalValues (globalRow, indView, valView);
8546 if (callFillComplete) {
8548 std::ostringstream os;
8549 os << *prefix <<
"Call fillComplete on C" << endl;
8550 std::cerr << os.str ();
8552 if (fillCompleteSublist.is_null ()) {
8553 C->fillComplete (theDomainMap, theRangeMap);
8555 C->fillComplete (theDomainMap, theRangeMap, fillCompleteSublist);
8559 std::ostringstream os;
8560 os << *prefix <<
"Do NOT call fillComplete on C" << endl;
8561 std::cerr << os.str ();
8565 std::ostringstream os;
8566 os << *prefix <<
"Done" << endl;
8567 std::cerr << os.str ();
8569 return rcp_implicit_cast<row_matrix_type> (C);
8574 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8578 const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node>& rowTransfer,
8579 const Teuchos::RCP<const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node> > & domainTransfer,
8580 const Teuchos::RCP<const map_type>& domainMap,
8581 const Teuchos::RCP<const map_type>& rangeMap,
8582 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
8589 using Teuchos::ArrayRCP;
8590 using Teuchos::ArrayView;
8591 using Teuchos::Comm;
8592 using Teuchos::ParameterList;
8595 typedef LocalOrdinal LO;
8596 typedef GlobalOrdinal GO;
8597 typedef node_type NT;
8602 const bool debug = Behavior::debug(
"CrsMatrix");
8603 const bool verbose = Behavior::verbose(
"CrsMatrix");
8604 int MyPID = getComm ()->getRank ();
8606 std::unique_ptr<std::string> verbosePrefix;
8609 this->createPrefix(
"CrsMatrix",
"transferAndFillComplete");
8610 std::ostringstream os;
8611 os <<
"Start" << endl;
8612 std::cerr << os.str();
8619 bool reverseMode =
false;
8620 bool restrictComm =
false;
8622 int mm_optimization_core_count =
8623 Behavior::TAFC_OptimizationCoreCount();
8624 RCP<ParameterList> matrixparams;
8625 bool overrideAllreduce =
false;
8626 if (! params.is_null ()) {
8627 matrixparams = sublist (params,
"CrsMatrix");
8628 reverseMode = params->get (
"Reverse Mode", reverseMode);
8629 restrictComm = params->get (
"Restrict Communicator", restrictComm);
8630 auto & slist = params->sublist(
"matrixmatrix: kernel params",
false);
8631 isMM = slist.get(
"isMatrixMatrix_TransferAndFillComplete",
false);
8632 mm_optimization_core_count = slist.get(
"MM_TAFC_OptimizationCoreCount",mm_optimization_core_count);
8634 overrideAllreduce = slist.get(
"MM_TAFC_OverrideAllreduceCheck",
false);
8635 if(getComm()->getSize() < mm_optimization_core_count && isMM) isMM =
false;
8636 if(reverseMode) isMM =
false;
8640 std::shared_ptr< ::Tpetra::Details::CommRequest> iallreduceRequest;
8642 int reduced_mismatch = 0;
8643 if (isMM && !overrideAllreduce) {
8646 const bool source_vals = ! getGraph ()->getImporter ().is_null();
8647 const bool target_vals = ! (rowTransfer.getExportLIDs ().size() == 0 ||
8648 rowTransfer.getRemoteLIDs ().size() == 0);
8649 mismatch = (source_vals != target_vals) ? 1 : 0;
8652 Teuchos::REDUCE_MAX, * (getComm ()));
8655 #ifdef HAVE_TPETRA_MMM_TIMINGS
8656 using Teuchos::TimeMonitor;
8658 if(!params.is_null())
8659 label = params->get(
"Timer Label",label);
8660 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
8663 std::ostringstream os;
8664 if(isMM) os<<
":MMOpt";
8665 else os<<
":MMLegacy";
8669 Teuchos::TimeMonitor MMall(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC All") +tlstr ));
8677 const import_type* xferAsImport =
dynamic_cast<const import_type*
> (&rowTransfer);
8678 const export_type* xferAsExport =
dynamic_cast<const export_type*
> (&rowTransfer);
8679 TEUCHOS_TEST_FOR_EXCEPTION(
8680 xferAsImport ==
nullptr && xferAsExport ==
nullptr, std::invalid_argument,
8681 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' input "
8682 "argument must be either an Import or an Export, and its template "
8683 "parameters must match the corresponding template parameters of the "
8691 Teuchos::RCP<const import_type> xferDomainAsImport = Teuchos::rcp_dynamic_cast<
const import_type> (domainTransfer);
8692 Teuchos::RCP<const export_type> xferDomainAsExport = Teuchos::rcp_dynamic_cast<
const export_type> (domainTransfer);
8694 if(! domainTransfer.is_null()) {
8695 TEUCHOS_TEST_FOR_EXCEPTION(
8696 (xferDomainAsImport.is_null() && xferDomainAsExport.is_null()), std::invalid_argument,
8697 "Tpetra::CrsMatrix::transferAndFillComplete: The 'domainTransfer' input "
8698 "argument must be either an Import or an Export, and its template "
8699 "parameters must match the corresponding template parameters of the "
8702 TEUCHOS_TEST_FOR_EXCEPTION(
8703 ( xferAsImport !=
nullptr || ! xferDomainAsImport.is_null() ) &&
8704 (( xferAsImport !=
nullptr && xferDomainAsImport.is_null() ) ||
8705 ( xferAsImport ==
nullptr && ! xferDomainAsImport.is_null() )), std::invalid_argument,
8706 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8707 "arguments must be of the same type (either Import or Export).");
8709 TEUCHOS_TEST_FOR_EXCEPTION(
8710 ( xferAsExport !=
nullptr || ! xferDomainAsExport.is_null() ) &&
8711 (( xferAsExport !=
nullptr && xferDomainAsExport.is_null() ) ||
8712 ( xferAsExport ==
nullptr && ! xferDomainAsExport.is_null() )), std::invalid_argument,
8713 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8714 "arguments must be of the same type (either Import or Export).");
8720 const bool communication_needed = rowTransfer.getSourceMap ()->isDistributed ();
8724 RCP<const map_type> MyRowMap = reverseMode ?
8725 rowTransfer.getSourceMap () : rowTransfer.getTargetMap ();
8726 RCP<const map_type> MyColMap;
8727 RCP<const map_type> MyDomainMap = ! domainMap.is_null () ?
8728 domainMap : getDomainMap ();
8729 RCP<const map_type> MyRangeMap = ! rangeMap.is_null () ?
8730 rangeMap : getRangeMap ();
8731 RCP<const map_type> BaseRowMap = MyRowMap;
8732 RCP<const map_type> BaseDomainMap = MyDomainMap;
8740 if (! destMat.is_null ()) {
8751 const bool NewFlag = ! destMat->getGraph ()->isLocallyIndexed () &&
8752 ! destMat->getGraph ()->isGloballyIndexed ();
8753 TEUCHOS_TEST_FOR_EXCEPTION(
8754 ! NewFlag, std::invalid_argument,
"Tpetra::CrsMatrix::"
8755 "transferAndFillComplete: The input argument 'destMat' is only allowed "
8756 "to be nonnull, if its graph is empty (neither locally nor globally "
8765 TEUCHOS_TEST_FOR_EXCEPTION(
8766 ! destMat->getRowMap ()->isSameAs (*MyRowMap), std::invalid_argument,
8767 "Tpetra::CrsMatrix::transferAndFillComplete: The (row) Map of the "
8768 "input argument 'destMat' is not the same as the (row) Map specified "
8769 "by the input argument 'rowTransfer'.");
8770 TEUCHOS_TEST_FOR_EXCEPTION(
8771 ! destMat->checkSizes (*
this), std::invalid_argument,
8772 "Tpetra::CrsMatrix::transferAndFillComplete: You provided a nonnull "
8773 "destination matrix, but checkSizes() indicates that it is not a legal "
8774 "legal target for redistribution from the source matrix (*this). This "
8775 "may mean that they do not have the same dimensions.");
8789 TEUCHOS_TEST_FOR_EXCEPTION(
8790 ! (reverseMode || getRowMap ()->isSameAs (*rowTransfer.getSourceMap ())),
8791 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8792 "rowTransfer->getSourceMap() must match this->getRowMap() in forward mode.");
8793 TEUCHOS_TEST_FOR_EXCEPTION(
8794 ! (! reverseMode || getRowMap ()->isSameAs (*rowTransfer.getTargetMap ())),
8795 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8796 "rowTransfer->getTargetMap() must match this->getRowMap() in reverse mode.");
8799 TEUCHOS_TEST_FOR_EXCEPTION(
8800 ! xferDomainAsImport.is_null() && ! xferDomainAsImport->getTargetMap()->isSameAs(*domainMap),
8801 std::invalid_argument,
8802 "Tpetra::CrsMatrix::transferAndFillComplete: The target map of the 'domainTransfer' input "
8803 "argument must be the same as the rebalanced domain map 'domainMap'");
8805 TEUCHOS_TEST_FOR_EXCEPTION(
8806 ! xferDomainAsExport.is_null() && ! xferDomainAsExport->getSourceMap()->isSameAs(*domainMap),
8807 std::invalid_argument,
8808 "Tpetra::CrsMatrix::transferAndFillComplete: The source map of the 'domainTransfer' input "
8809 "argument must be the same as the rebalanced domain map 'domainMap'");
8822 const size_t NumSameIDs = rowTransfer.getNumSameIDs();
8823 ArrayView<const LO> ExportLIDs = reverseMode ?
8824 rowTransfer.getRemoteLIDs () : rowTransfer.getExportLIDs ();
8825 ArrayView<const LO> RemoteLIDs = reverseMode ?
8826 rowTransfer.getExportLIDs () : rowTransfer.getRemoteLIDs ();
8827 ArrayView<const LO> PermuteToLIDs = reverseMode ?
8828 rowTransfer.getPermuteFromLIDs () : rowTransfer.getPermuteToLIDs ();
8829 ArrayView<const LO> PermuteFromLIDs = reverseMode ?
8830 rowTransfer.getPermuteToLIDs () : rowTransfer.getPermuteFromLIDs ();
8831 Distributor& Distor = rowTransfer.getDistributor ();
8834 Teuchos::Array<int> SourcePids;
8835 Teuchos::Array<int> TargetPids;
8838 RCP<const map_type> ReducedRowMap, ReducedColMap,
8839 ReducedDomainMap, ReducedRangeMap;
8840 RCP<const Comm<int> > ReducedComm;
8844 if (destMat.is_null ()) {
8845 destMat = rcp (
new this_type (MyRowMap, 0, StaticProfile, matrixparams));
8852 ReducedRowMap = MyRowMap->removeEmptyProcesses ();
8853 ReducedComm = ReducedRowMap.is_null () ?
8855 ReducedRowMap->getComm ();
8856 destMat->removeEmptyProcessesInPlace (ReducedRowMap);
8858 ReducedDomainMap = MyRowMap.getRawPtr () == MyDomainMap.getRawPtr () ?
8860 MyDomainMap->replaceCommWithSubset (ReducedComm);
8861 ReducedRangeMap = MyRowMap.getRawPtr () == MyRangeMap.getRawPtr () ?
8863 MyRangeMap->replaceCommWithSubset (ReducedComm);
8866 MyRowMap = ReducedRowMap;
8867 MyDomainMap = ReducedDomainMap;
8868 MyRangeMap = ReducedRangeMap;
8871 if (! ReducedComm.is_null ()) {
8872 MyPID = ReducedComm->getRank ();
8879 ReducedComm = MyRowMap->getComm ();
8888 RCP<const import_type> MyImporter = getGraph ()->getImporter ();
8891 bool bSameDomainMap = BaseDomainMap->isSameAs (*getDomainMap ());
8893 if (! restrictComm && ! MyImporter.is_null () && bSameDomainMap ) {
8900 Import_Util::getPids (*MyImporter, SourcePids,
false);
8902 else if (restrictComm && ! MyImporter.is_null () && bSameDomainMap) {
8905 IntVectorType SourceDomain_pids(getDomainMap (),
true);
8906 IntVectorType SourceCol_pids(getColMap());
8908 SourceDomain_pids.putScalar(MyPID);
8910 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8911 SourcePids.resize (getColMap ()->getNodeNumElements ());
8912 SourceCol_pids.get1dCopy (SourcePids ());
8914 else if (MyImporter.is_null () && bSameDomainMap) {
8916 SourcePids.resize (getColMap ()->getNodeNumElements ());
8917 SourcePids.assign (getColMap ()->getNodeNumElements (), MyPID);
8919 else if ( ! MyImporter.is_null () &&
8920 ! domainTransfer.is_null () ) {
8927 IntVectorType TargetDomain_pids (domainMap);
8928 TargetDomain_pids.putScalar (MyPID);
8931 IntVectorType SourceDomain_pids (getDomainMap ());
8934 IntVectorType SourceCol_pids (getColMap ());
8936 if (! reverseMode && ! xferDomainAsImport.is_null() ) {
8937 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8939 else if (reverseMode && ! xferDomainAsExport.is_null() ) {
8940 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8942 else if (! reverseMode && ! xferDomainAsExport.is_null() ) {
8943 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8945 else if (reverseMode && ! xferDomainAsImport.is_null() ) {
8946 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8949 TEUCHOS_TEST_FOR_EXCEPTION(
8950 true, std::logic_error,
"Tpetra::CrsMatrix::"
8951 "transferAndFillComplete: Should never get here! "
8952 "Please report this bug to a Tpetra developer.");
8954 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8955 SourcePids.resize (getColMap ()->getNodeNumElements ());
8956 SourceCol_pids.get1dCopy (SourcePids ());
8958 else if ( ! MyImporter.is_null () &&
8959 BaseDomainMap->isSameAs (*BaseRowMap) &&
8960 getDomainMap ()->isSameAs (*getRowMap ())) {
8963 IntVectorType TargetRow_pids (domainMap);
8964 IntVectorType SourceRow_pids (getRowMap ());
8965 IntVectorType SourceCol_pids (getColMap ());
8967 TargetRow_pids.putScalar (MyPID);
8968 if (! reverseMode && xferAsImport !=
nullptr) {
8969 SourceRow_pids.doExport (TargetRow_pids, *xferAsImport,
INSERT);
8971 else if (reverseMode && xferAsExport !=
nullptr) {
8972 SourceRow_pids.doExport (TargetRow_pids, *xferAsExport,
INSERT);
8974 else if (! reverseMode && xferAsExport !=
nullptr) {
8975 SourceRow_pids.doImport (TargetRow_pids, *xferAsExport,
INSERT);
8977 else if (reverseMode && xferAsImport !=
nullptr) {
8978 SourceRow_pids.doImport (TargetRow_pids, *xferAsImport,
INSERT);
8981 TEUCHOS_TEST_FOR_EXCEPTION(
8982 true, std::logic_error,
"Tpetra::CrsMatrix::"
8983 "transferAndFillComplete: Should never get here! "
8984 "Please report this bug to a Tpetra developer.");
8987 SourceCol_pids.doImport (SourceRow_pids, *MyImporter,
INSERT);
8988 SourcePids.resize (getColMap ()->getNodeNumElements ());
8989 SourceCol_pids.get1dCopy (SourcePids ());
8992 TEUCHOS_TEST_FOR_EXCEPTION(
8993 true, std::invalid_argument,
"Tpetra::CrsMatrix::"
8994 "transferAndFillComplete: This method only allows either domainMap == "
8995 "getDomainMap (), or (domainMap == rowTransfer.getTargetMap () and "
8996 "getDomainMap () == getRowMap ()).");
9000 size_t constantNumPackets = destMat->constantNumberOfPackets ();
9001 if (constantNumPackets == 0) {
9002 destMat->reallocArraysForNumPacketsPerLid (ExportLIDs.size (),
9003 RemoteLIDs.size ());
9010 const size_t rbufLen = RemoteLIDs.size() * constantNumPackets;
9011 destMat->reallocImportsIfNeeded (rbufLen,
false,
nullptr);
9016 using Teuchos::outArg;
9017 using Teuchos::REDUCE_MAX;
9018 using Teuchos::reduceAll;
9021 RCP<const Teuchos::Comm<int> > comm = this->getComm ();
9022 const int myRank = comm->getRank ();
9024 std::ostringstream errStrm;
9028 Teuchos::ArrayView<size_t> numExportPacketsPerLID;
9031 destMat->numExportPacketsPerLID_.modify_host ();
9032 numExportPacketsPerLID =
9035 catch (std::exception& e) {
9036 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw: "
9037 << e.what () << std::endl;
9041 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw "
9042 "an exception not a subclass of std::exception" << std::endl;
9046 if (! comm.is_null ()) {
9047 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
9050 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
9051 TEUCHOS_TEST_FOR_EXCEPTION(
9052 true, std::runtime_error,
"getArrayViewFromDualView threw an "
9053 "exception on at least one process.");
9057 std::ostringstream os;
9058 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
9060 std::cerr << os.str ();
9065 numExportPacketsPerLID,
9071 catch (std::exception& e) {
9072 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw: "
9073 << e.what () << std::endl;
9077 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw "
9078 "an exception not a subclass of std::exception" << std::endl;
9083 std::ostringstream os;
9084 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
9086 std::cerr << os.str ();
9089 if (! comm.is_null ()) {
9090 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
9093 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
9094 TEUCHOS_TEST_FOR_EXCEPTION(
9095 true, std::runtime_error,
"packCrsMatrixWithOwningPIDs threw an "
9096 "exception on at least one process.");
9101 destMat->numExportPacketsPerLID_.modify_host ();
9102 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
9105 std::ostringstream os;
9106 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
9108 std::cerr << os.str ();
9112 numExportPacketsPerLID,
9118 std::ostringstream os;
9119 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
9121 std::cerr << os.str ();
9126 if (! communication_needed) {
9128 std::ostringstream os;
9129 os << *verbosePrefix <<
"Communication not needed" << std::endl;
9130 std::cerr << os.str ();
9135 if (constantNumPackets == 0) {
9137 std::ostringstream os;
9138 os << *verbosePrefix <<
"Reverse mode, variable # packets / LID"
9140 std::cerr << os.str ();
9145 destMat->numExportPacketsPerLID_.sync_host ();
9146 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
9148 destMat->numImportPacketsPerLID_.sync_host ();
9149 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
9153 std::ostringstream os;
9154 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
9156 std::cerr << os.str ();
9158 Distor.doReversePostsAndWaits (numExportPacketsPerLID, 1,
9159 numImportPacketsPerLID);
9161 std::ostringstream os;
9162 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
9164 std::cerr << os.str ();
9167 size_t totalImportPackets = 0;
9168 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
9169 totalImportPackets += numImportPacketsPerLID[i];
9174 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
9175 verbosePrefix.get ());
9176 destMat->imports_.modify_host ();
9177 Teuchos::ArrayView<char> hostImports =
9181 destMat->exports_.sync_host ();
9182 Teuchos::ArrayView<const char> hostExports =
9185 std::ostringstream os;
9186 os << *verbosePrefix <<
"Calling 4-arg doReversePostsAndWaits"
9188 std::cerr << os.str ();
9190 Distor.doReversePostsAndWaits (hostExports,
9191 numExportPacketsPerLID,
9193 numImportPacketsPerLID);
9195 std::ostringstream os;
9196 os << *verbosePrefix <<
"Finished 4-arg doReversePostsAndWaits"
9198 std::cerr << os.str ();
9203 std::ostringstream os;
9204 os << *verbosePrefix <<
"Reverse mode, constant # packets / LID"
9206 std::cerr << os.str ();
9208 destMat->imports_.modify_host ();
9209 Teuchos::ArrayView<char> hostImports =
9213 destMat->exports_.sync_host ();
9214 Teuchos::ArrayView<const char> hostExports =
9217 std::ostringstream os;
9218 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
9220 std::cerr << os.str ();
9222 Distor.doReversePostsAndWaits (hostExports,
9226 std::ostringstream os;
9227 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
9229 std::cerr << os.str ();
9234 if (constantNumPackets == 0) {
9236 std::ostringstream os;
9237 os << *verbosePrefix <<
"Forward mode, variable # packets / LID"
9239 std::cerr << os.str ();
9244 destMat->numExportPacketsPerLID_.sync_host ();
9245 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
9247 destMat->numImportPacketsPerLID_.sync_host ();
9248 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
9251 std::ostringstream os;
9252 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
9254 std::cerr << os.str ();
9256 Distor.doPostsAndWaits (numExportPacketsPerLID, 1,
9257 numImportPacketsPerLID);
9259 std::ostringstream os;
9260 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
9262 std::cerr << os.str ();
9265 size_t totalImportPackets = 0;
9266 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
9267 totalImportPackets += numImportPacketsPerLID[i];
9272 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
9273 verbosePrefix.get ());
9274 destMat->imports_.modify_host ();
9275 Teuchos::ArrayView<char> hostImports =
9279 destMat->exports_.sync_host ();
9280 Teuchos::ArrayView<const char> hostExports =
9283 std::ostringstream os;
9284 os << *verbosePrefix <<
"Calling 4-arg doPostsAndWaits"
9286 std::cerr << os.str ();
9288 Distor.doPostsAndWaits (hostExports,
9289 numExportPacketsPerLID,
9291 numImportPacketsPerLID);
9293 std::ostringstream os;
9294 os << *verbosePrefix <<
"Finished 4-arg doPostsAndWaits"
9296 std::cerr << os.str ();
9301 std::ostringstream os;
9302 os << *verbosePrefix <<
"Forward mode, constant # packets / LID"
9304 std::cerr << os.str ();
9306 destMat->imports_.modify_host ();
9307 Teuchos::ArrayView<char> hostImports =
9311 destMat->exports_.sync_host ();
9312 Teuchos::ArrayView<const char> hostExports =
9315 std::ostringstream os;
9316 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
9318 std::cerr << os.str ();
9320 Distor.doPostsAndWaits (hostExports,
9324 std::ostringstream os;
9325 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
9327 std::cerr << os.str ();
9338 destMat->numImportPacketsPerLID_.sync_host ();
9339 Teuchos::ArrayView<const size_t> numImportPacketsPerLID =
9341 destMat->imports_.sync_host ();
9342 Teuchos::ArrayView<const char> hostImports =
9346 std::ostringstream os;
9347 os << *verbosePrefix <<
"Calling unpackAndCombineWithOwningPIDsCount"
9349 std::cerr << os.str ();
9355 numImportPacketsPerLID,
9363 std::ostringstream os;
9364 os << *verbosePrefix <<
"unpackAndCombineWithOwningPIDsCount returned "
9365 << mynnz << std::endl;
9366 std::cerr << os.str ();
9368 size_t N = BaseRowMap->getNodeNumElements ();
9371 ArrayRCP<size_t> CSR_rowptr(N+1);
9372 ArrayRCP<GO> CSR_colind_GID;
9373 ArrayRCP<LO> CSR_colind_LID;
9374 ArrayRCP<Scalar> CSR_vals;
9375 CSR_colind_GID.resize (mynnz);
9376 CSR_vals.resize (mynnz);
9380 if (
typeid (LO) ==
typeid (GO)) {
9381 CSR_colind_LID = Teuchos::arcp_reinterpret_cast<LO> (CSR_colind_GID);
9384 CSR_colind_LID.resize (mynnz);
9388 std::ostringstream os;
9389 os << *verbosePrefix <<
"Calling unpackAndCombineIntoCrsArrays"
9391 std::cerr << os.str ();
9401 numImportPacketsPerLID,
9413 Teuchos::av_reinterpret_cast<impl_scalar_type> (CSR_vals ()),
9423 Teuchos::Array<int> RemotePids;
9425 std::ostringstream os;
9426 os << *verbosePrefix <<
"Calling lowCommunicationMakeColMapAndReindex"
9428 std::cerr << os.str ();
9430 Import_Util::lowCommunicationMakeColMapAndReindex (CSR_rowptr (),
9439 std::ostringstream os;
9440 os << *verbosePrefix <<
"restrictComm="
9441 << (restrictComm ?
"true" :
"false") << std::endl;
9442 std::cerr << os.str ();
9449 ReducedColMap = (MyRowMap.getRawPtr () == MyColMap.getRawPtr ()) ?
9451 MyColMap->replaceCommWithSubset (ReducedComm);
9452 MyColMap = ReducedColMap;
9457 std::ostringstream os;
9458 os << *verbosePrefix <<
"Calling replaceColMap" << std::endl;
9459 std::cerr << os.str ();
9461 destMat->replaceColMap (MyColMap);
9468 if (ReducedComm.is_null ()) {
9470 std::ostringstream os;
9471 os << *verbosePrefix <<
"I am no longer in the communicator; "
9472 "returning" << std::endl;
9473 std::cerr << os.str ();
9481 if ((! reverseMode && xferAsImport !=
nullptr) ||
9482 (reverseMode && xferAsExport !=
nullptr)) {
9484 std::ostringstream os;
9485 os << *verbosePrefix <<
"Calling sortCrsEntries" << endl;
9486 std::cerr << os.str ();
9488 Import_Util::sortCrsEntries (CSR_rowptr (),
9492 else if ((! reverseMode && xferAsExport !=
nullptr) ||
9493 (reverseMode && xferAsImport !=
nullptr)) {
9495 std::ostringstream os;
9496 os << *verbosePrefix <<
"Calling sortAndMergeCrsEntries"
9498 std::cerr << os.str();
9500 Import_Util::sortAndMergeCrsEntries (CSR_rowptr (),
9503 if (CSR_rowptr[N] != mynnz) {
9504 CSR_colind_LID.resize (CSR_rowptr[N]);
9505 CSR_vals.resize (CSR_rowptr[N]);
9509 TEUCHOS_TEST_FOR_EXCEPTION(
9510 true, std::logic_error,
"Tpetra::CrsMatrix::"
9511 "transferAndFillComplete: Should never get here! "
9512 "Please report this bug to a Tpetra developer.");
9519 std::ostringstream os;
9520 os << *verbosePrefix <<
"Calling destMat->setAllValues" << endl;
9521 std::cerr << os.str ();
9529 destMat->setAllValues (CSR_rowptr, CSR_colind_LID, CSR_vals);
9535 Teuchos::ParameterList esfc_params;
9537 RCP<import_type> MyImport;
9540 if (iallreduceRequest.get () !=
nullptr) {
9542 std::ostringstream os;
9543 os << *verbosePrefix <<
"Calling iallreduceRequest->wait()"
9545 std::cerr << os.str ();
9547 iallreduceRequest->wait ();
9548 if (reduced_mismatch != 0) {
9554 #ifdef HAVE_TPETRA_MMM_TIMINGS
9555 Teuchos::TimeMonitor MMisMM (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM Block")));
9560 std::ostringstream os;
9561 os << *verbosePrefix <<
"Calling getAllValues" << endl;
9562 std::cerr << os.str ();
9565 Teuchos::ArrayRCP<LocalOrdinal> type3LIDs;
9566 Teuchos::ArrayRCP<int> type3PIDs;
9567 Teuchos::ArrayRCP<const size_t> rowptr;
9568 Teuchos::ArrayRCP<const LO> colind;
9569 Teuchos::ArrayRCP<const Scalar> vals;
9571 #ifdef HAVE_TPETRA_MMM_TIMINGS
9572 TimeMonitor tm_getAllValues (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMgetAllValues")));
9574 getAllValues(rowptr,colind,vals);
9578 std::ostringstream os;
9579 os << *verbosePrefix <<
"Calling reverseNeighborDiscovery" << std::endl;
9580 std::cerr << os.str ();
9584 #ifdef HAVE_TPETRA_MMM_TIMINGS
9585 TimeMonitor tm_rnd (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMrevNeighDis")));
9587 Import_Util::reverseNeighborDiscovery(*
this,
9599 std::ostringstream os;
9600 os << *verbosePrefix <<
"Done with reverseNeighborDiscovery" << std::endl;
9601 std::cerr << os.str ();
9604 Teuchos::ArrayView<const int> EPID1 = MyImporter.is_null() ? Teuchos::ArrayView<const int>() : MyImporter->getExportPIDs();
9605 Teuchos::ArrayView<const LO> ELID1 = MyImporter.is_null() ? Teuchos::ArrayView<const int>() : MyImporter->getExportLIDs();
9607 Teuchos::ArrayView<const int> TEPID2 = rowTransfer.getExportPIDs();
9608 Teuchos::ArrayView<const LO> TELID2 = rowTransfer.getExportLIDs();
9610 const int numCols = getGraph()->getColMap()->getNodeNumElements();
9612 std::vector<bool> IsOwned(numCols,
true);
9613 std::vector<int> SentTo(numCols,-1);
9614 if (! MyImporter.is_null ()) {
9615 for (
auto && rlid : MyImporter->getRemoteLIDs()) {
9616 IsOwned[rlid]=
false;
9620 std::vector<std::pair<int,GO> > usrtg;
9621 usrtg.reserve(TEPID2.size());
9624 const auto& colMap = * (this->getColMap ());
9626 const LO row = TELID2[i];
9627 const int pid = TEPID2[i];
9628 for (
auto j = rowptr[row]; j < rowptr[row+1]; ++j) {
9629 const int col = colind[j];
9630 if (IsOwned[col] && SentTo[col] != pid) {
9632 GO gid = colMap.getGlobalElement (col);
9633 usrtg.push_back (std::pair<int,GO> (pid, gid));
9640 std::sort(usrtg.begin(),usrtg.end());
9641 auto eopg = std ::unique(usrtg.begin(),usrtg.end());
9643 usrtg.erase(eopg,usrtg.end());
9646 Teuchos::ArrayRCP<int> EPID2=Teuchos::arcp(
new int[type2_us_size],0,type2_us_size,
true);
9647 Teuchos::ArrayRCP< LO> ELID2=Teuchos::arcp(
new LO[type2_us_size],0,type2_us_size,
true);
9650 for(
auto && p : usrtg) {
9651 EPID2[pos]= p.first;
9652 ELID2[pos]= this->getDomainMap()->getLocalElement(p.second);
9656 Teuchos::ArrayView<int> EPID3 = type3PIDs();
9657 Teuchos::ArrayView< LO> ELID3 = type3LIDs();
9658 GO InfGID = std::numeric_limits<GO>::max();
9659 int InfPID = INT_MAX;
9662 #endif // TPETRA_MIN3
9663 #define TPETRA_MIN3(x,y,z) ((x)<(y)?(std::min(x,z)):(std::min(y,z)))
9664 int i1=0, i2=0, i3=0;
9665 int Len1 = EPID1.size();
9666 int Len2 = EPID2.size();
9667 int Len3 = EPID3.size();
9669 int MyLen=Len1+Len2+Len3;
9670 Teuchos::ArrayRCP<LO> userExportLIDs = Teuchos::arcp(
new LO[MyLen],0,MyLen,
true);
9671 Teuchos::ArrayRCP<int> userExportPIDs = Teuchos::arcp(
new int[MyLen],0,MyLen,
true);
9674 while(i1 < Len1 || i2 < Len2 || i3 < Len3){
9675 int PID1 = (i1<Len1)?(EPID1[i1]):InfPID;
9676 int PID2 = (i2<Len2)?(EPID2[i2]):InfPID;
9677 int PID3 = (i3<Len3)?(EPID3[i3]):InfPID;
9679 GO GID1 = (i1<Len1)?getDomainMap()->getGlobalElement(ELID1[i1]):InfGID;
9680 GO GID2 = (i2<Len2)?getDomainMap()->getGlobalElement(ELID2[i2]):InfGID;
9681 GO GID3 = (i3<Len3)?getDomainMap()->getGlobalElement(ELID3[i3]):InfGID;
9683 int MIN_PID = TPETRA_MIN3(PID1,PID2,PID3);
9684 GO MIN_GID = TPETRA_MIN3( ((PID1==MIN_PID)?GID1:InfGID), ((PID2==MIN_PID)?GID2:InfGID), ((PID3==MIN_PID)?GID3:InfGID));
9687 #endif // TPETRA_MIN3
9688 bool added_entry=
false;
9690 if(PID1 == MIN_PID && GID1 == MIN_GID){
9691 userExportLIDs[iloc]=ELID1[i1];
9692 userExportPIDs[iloc]=EPID1[i1];
9697 if(PID2 == MIN_PID && GID2 == MIN_GID){
9699 userExportLIDs[iloc]=ELID2[i2];
9700 userExportPIDs[iloc]=EPID2[i2];
9706 if(PID3 == MIN_PID && GID3 == MIN_GID){
9708 userExportLIDs[iloc]=ELID3[i3];
9709 userExportPIDs[iloc]=EPID3[i3];
9717 std::ostringstream os;
9718 os << *verbosePrefix <<
"Create Import" << std::endl;
9719 std::cerr << os.str ();
9722 #ifdef HAVE_TPETRA_MMM_TIMINGS
9723 auto ismmIctor(*TimeMonitor::getNewTimer(prefix + std::string(
"isMMIportCtor")));
9725 Teuchos::RCP<Teuchos::ParameterList> plist = rcp(
new Teuchos::ParameterList());
9727 if ((MyDomainMap != MyColMap) && (!MyDomainMap->isSameAs(*MyColMap)))
9728 MyImport = rcp (
new import_type (MyDomainMap,
9731 userExportLIDs.view(0,iloc).getConst(),
9732 userExportPIDs.view(0,iloc).getConst(),
9737 std::ostringstream os;
9738 os << *verbosePrefix <<
"Call expertStaticFillComplete" << std::endl;
9739 std::cerr << os.str ();
9743 #ifdef HAVE_TPETRA_MMM_TIMINGS
9744 TimeMonitor esfc (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM::destMat->eSFC")));
9745 esfc_params.set(
"Timer Label",label+std::string(
"isMM eSFC"));
9747 if(!params.is_null())
9748 esfc_params.set(
"compute global constants",params->get(
"compute global constants",
true));
9749 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap, MyImport,Teuchos::null,rcp(
new Teuchos::ParameterList(esfc_params)));
9755 #ifdef HAVE_TPETRA_MMM_TIMINGS
9756 TimeMonitor MMnotMMblock (*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMblock")));
9759 std::ostringstream os;
9760 os << *verbosePrefix <<
"Create Import" << std::endl;
9761 std::cerr << os.str ();
9764 #ifdef HAVE_TPETRA_MMM_TIMINGS
9765 TimeMonitor notMMIcTor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMCreateImporter")));
9767 Teuchos::RCP<Teuchos::ParameterList> mypars = rcp(
new Teuchos::ParameterList);
9768 mypars->set(
"Timer Label",
"notMMFrom_tAFC");
9769 if ((MyDomainMap != MyColMap) && (!MyDomainMap->isSameAs(*MyColMap)))
9770 MyImport = rcp (
new import_type (MyDomainMap, MyColMap, RemotePids, mypars));
9773 std::ostringstream os;
9774 os << *verbosePrefix <<
"Call expertStaticFillComplete" << endl;
9775 std::cerr << os.str ();
9778 #ifdef HAVE_TPETRA_MMM_TIMINGS
9779 TimeMonitor esfcnotmm(*TimeMonitor::getNewTimer(prefix + std::string(
"notMMdestMat->expertStaticFillComplete")));
9780 esfc_params.set(
"Timer Label",prefix+std::string(
"notMM eSFC"));
9782 esfc_params.set(
"Timer Label",std::string(
"notMM eSFC"));
9785 if (!params.is_null ()) {
9786 esfc_params.set (
"compute global constants",
9787 params->get (
"compute global constants",
true));
9789 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap,
9790 MyImport, Teuchos::null,
9791 rcp (
new Teuchos::ParameterList (esfc_params)));
9795 std::ostringstream os;
9796 os << *verbosePrefix <<
"Done" << endl;
9797 std::cerr << os.str ();
9802 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9807 const Teuchos::RCP<const map_type>& domainMap,
9808 const Teuchos::RCP<const map_type>& rangeMap,
9809 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9811 transferAndFillComplete (destMatrix, importer, Teuchos::null, domainMap, rangeMap, params);
9814 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9820 const Teuchos::RCP<const map_type>& domainMap,
9821 const Teuchos::RCP<const map_type>& rangeMap,
9822 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9824 transferAndFillComplete (destMatrix, rowImporter, Teuchos::rcpFromRef(domainImporter), domainMap, rangeMap, params);
9827 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9832 const Teuchos::RCP<const map_type>& domainMap,
9833 const Teuchos::RCP<const map_type>& rangeMap,
9834 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9836 transferAndFillComplete (destMatrix, exporter, Teuchos::null, domainMap, rangeMap, params);
9839 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9845 const Teuchos::RCP<const map_type>& domainMap,
9846 const Teuchos::RCP<const map_type>& rangeMap,
9847 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9849 transferAndFillComplete (destMatrix, rowExporter, Teuchos::rcpFromRef(domainExporter), domainMap, rangeMap, params);
9861 #define TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR,LO,GO,NODE) \
9863 template class CrsMatrix< SCALAR , LO , GO , NODE >; \
9864 template Teuchos::RCP< CrsMatrix< SCALAR , LO , GO , NODE > > \
9865 CrsMatrix< SCALAR , LO , GO , NODE >::convert< SCALAR > () const;
9867 #define TPETRA_CRSMATRIX_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \
9869 template Teuchos::RCP< CrsMatrix< SO , LO , GO , NODE > > \
9870 CrsMatrix< SI , LO , GO , NODE >::convert< SO > () const;
9872 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9874 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9875 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9876 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9877 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9878 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& importer, \
9879 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9880 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9881 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9882 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9883 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9884 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9885 const Teuchos::RCP<Teuchos::ParameterList>& params);
9887 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9889 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9890 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9891 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9892 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9893 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowImporter, \
9894 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9895 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9896 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainImporter, \
9897 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9898 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9899 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9900 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9901 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9902 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9903 const Teuchos::RCP<Teuchos::ParameterList>& params);
9906 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9908 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9909 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9910 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9911 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9912 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& exporter, \
9913 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9914 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9915 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9916 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9917 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9918 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9919 const Teuchos::RCP<Teuchos::ParameterList>& params);
9921 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9923 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9924 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9925 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9926 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9927 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowExporter, \
9928 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9929 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9930 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainExporter, \
9931 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9932 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9933 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9934 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9935 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9936 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9937 const Teuchos::RCP<Teuchos::ParameterList>& params);
9940 #define TPETRA_CRSMATRIX_INSTANT(SCALAR, LO, GO ,NODE) \
9941 TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR, LO, GO, NODE) \
9942 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9943 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9944 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9945 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE)
9947 #endif // TPETRA_CRSMATRIX_DEF_HPP
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.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
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.
Abstract interface for local operators (e.g., matrices and preconditioners).
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.
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.
Kokkos::StaticCrsGraph< local_ordinal_type, Kokkos::LayoutLeft, device_type > local_graph_type
The type of the part of the sparse graph on each MPI process.
KokkosSparse::CrsMatrix< impl_scalar_type, local_ordinal_type, device_type, 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 merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2)
Merge values in place, additively, with the same index.
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().
static KOKKOS_INLINE_FUNCTION size_t unpackValue(LO &outVal, const char inBuf[])
Unpack the given value from the given output buffer.
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.
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.
size_t getLocalLength() const
Local number of rows on the calling process.
Declaration of a function that prints strings from each process.
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.
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.
GlobalOrdinal global_ordinal_type
The type of each global index in the matrix.
bool isDistributed() const
Whether this is a globally distributed object.
void unpackAndCombine(const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &importLIDs, Kokkos::DualView< char *, buffer_device_type > imports, Kokkos::DualView< size_t *, buffer_device_type > numPacketsPerLID, const size_t constantNumPackets, Distributor &distor, const CombineMode CM) override
Unpack the imported column indices and values, and combine into matrix.
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...
Scalar scalar_type
The type of each entry in the matrix.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
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...
void verbosePrintArray(std::ostream &out, const ArrayType &x, const char name[], const size_t maxNumToPrint)
Print min(x.size(), maxNumToPrint) entries of x.
bool isGloballyIndexed() const override
Whether the graph's column indices are stored as global indices.
void leftScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Left-scale a KokkosSparse::CrsMatrix.
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.
void packCrsMatrixNew(const CrsMatrix< ST, LO, GO, NT > &sourceMatrix, Kokkos::DualView< char *, typename DistObject< char, LO, GO, NT >::buffer_device_type > &exports, const Kokkos::DualView< size_t *, typename DistObject< char, LO, GO, NT >::buffer_device_type > &numPacketsPerLID, const Kokkos::DualView< const LO *, typename DistObject< char, LO, GO, NT >::buffer_device_type > &exportLIDs, size_t &constantNumPackets, Distributor &distor)
Pack specified entries of the given local sparse matrix for communication, for "new" DistObject inter...
std::shared_ptr< local_multiply_op_type > lclMatrix_
The local sparse matrix, wrapped in a multiply operator.
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().
Declare and define Tpetra::Details::copyConvert, an implementation detail of Tpetra (in particular...
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 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 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.
static KOKKOS_INLINE_FUNCTION size_t packValue(char outBuf[], const LO &inVal)
Pack the given value of type value_type into the given output buffer of bytes (char).
Insert new values that don't currently exist.
void padCrsArrays(const RowPtr &rowPtrBeg, const RowPtr &rowPtrEnd, Indices &indices, const Padding &padding, const int my_rank, const bool verbose)
Determine if the row pointers and indices arrays need to be resized to accommodate new entries...
local_matrix_type::values_type k_values1D_
Sparse matrix values, as part of compressed sparse row ("1-D") storage.
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.
local_ordinal_type replaceGlobalValues(const global_ordinal_type globalRow, const Kokkos::View< const global_ordinal_type *, Kokkos::AnonymousSpace > &inputInds, const Kokkos::View< const impl_scalar_type *, Kokkos::AnonymousSpace > &inputVals) const
Replace one or more entries' values, using global indices.
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.
global_ordinal_type getGlobalElement(local_ordinal_type localIndex) const
The global index corresponding to the given local index.
ESweepDirection
Sweep direction for Gauss-Seidel or Successive Over-Relaxation (SOR).
bool isNodeLocalElement(local_ordinal_type localIndex) const
Whether the given local index is valid for this Map on the calling process.
Functions for manipulating CRS arrays.
local_ordinal_type replaceLocalValues(const local_ordinal_type localRow, const Kokkos::View< const local_ordinal_type *, Kokkos::AnonymousSpace > &inputInds, const Kokkos::View< const impl_scalar_type *, Kokkos::AnonymousSpace > &inputVals) const
Replace one or more entries' values, using local row and column indices.
GlobalOrdinal getIndexBase() const override
The index base for global indices for this matrix.
Declare and define the functions Tpetra::Details::computeOffsetsFromCounts and Tpetra::computeOffsets...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
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...
bool isNodeGlobalElement(global_ordinal_type globalIndex) const
Whether the given global index is owned by this Map on the calling process.
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.
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.
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.
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.
void copyConvert(const OutputViewType &dst, const InputViewType &src)
Copy values from the 1-D Kokkos::View src, to the 1-D Kokkos::View dst, of the same length...
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.
local_ordinal_type sumIntoLocalValues(const local_ordinal_type localRow, const Kokkos::View< const local_ordinal_type *, Kokkos::AnonymousSpace > &inputInds, const Kokkos::View< const impl_scalar_type *, Kokkos::AnonymousSpace > &inputVals, const bool atomic=useAtomicUpdatesByDefault) const
Sum into one or more sparse matrix entries, using local row and column indices.
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.
static size_t rowImbalanceThreshold()
Threshold for deciding if a local matrix is "imbalanced" in the number of entries per row...
bool isLocallyComplete() const
Is this Export or Import locally complete?
local_matrix_type::values_type getLocalValuesView() const
Get the Kokkos local values.
Declaration and definition of Tpetra::Details::leftScaleLocalCrsMatrix.
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.
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.
static KOKKOS_INLINE_FUNCTION size_t packValueCount(const LO &)
Number of bytes required to pack or unpack the given value of type value_type.
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...
Details::EStorageStatus storageStatus_
Status of the matrix's storage, when not in a fill-complete state.
A read-only, row-oriented interface to a sparse matrix.
local_matrix_type getLocalMatrix() const
The local 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.
local_ordinal_type getLocalElement(global_ordinal_type globalIndex) const
The local index corresponding to the given global index.
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.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const ExecutionSpace &execSpace, const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
void allocateValues(ELocalGlobal lg, GraphAllocationStatus gas, const bool verbose)
Allocate values (and optionally indices) using the Node.
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...
static size_t verbosePrintCountThreshold()
Number of entries below which arrays, lists, etc. will be printed in debug mode.
size_t mergeRowIndicesAndValues(crs_graph_type &graph, const RowInfo &rowInfo)
Merge duplicate row indices in the given row, along with their corresponding values.
dual_view_type::t_dev getLocalViewDevice() const
A local Kokkos::View of device memory.
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::rightScaleLocalCrsMatrix.
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.
std::shared_ptr< local_multiply_op_type > getLocalMultiplyOperator() const
The local sparse matrix operator (a wrapper of getLocalMatrix() that supports local matrix-vector mul...
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.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes the distribution of rows over processes.
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.
void rightScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Right-scale a KokkosSparse::CrsMatrix.
bool isStorageOptimized() const
Returns true if storage has been optimized.
Description of Tpetra's behavior.
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.