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"
78 #include "KokkosBlas.hpp"
86 using Teuchos::rcpFromRef;
92 template<
class T,
class BinaryFunction>
93 T atomic_binary_function_update (
volatile T*
const dest,
107 T newVal = f (assume, inputVal);
108 oldVal = Kokkos::atomic_compare_exchange (dest, assume, newVal);
109 }
while (assume != oldVal);
129 template<
class Scalar>
133 typedef Teuchos::ScalarTraits<Scalar> STS;
134 return std::max (STS::magnitude (x), STS::magnitude (y));
143 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
145 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
146 size_t maxNumEntriesPerRow,
148 const Teuchos::RCP<Teuchos::ParameterList>& params) :
151 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, size_t, "
152 "ProfileType[, RCP<ParameterList>]): ";
153 Teuchos::RCP<crs_graph_type> graph;
155 graph = Teuchos::rcp (
new crs_graph_type (rowMap, maxNumEntriesPerRow,
158 catch (std::exception& e) {
159 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
160 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
161 "size_t, ProfileType[, RCP<ParameterList>]) threw an exception: "
168 staticGraph_ = myGraph_;
173 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
176 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
178 const Teuchos::RCP<Teuchos::ParameterList>& params) :
181 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
182 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
183 Teuchos::RCP<crs_graph_type> graph;
189 catch (std::exception& e) {
190 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
191 (
true, std::runtime_error,
"CrsGraph constructor "
192 "(RCP<const Map>, ArrayView<const size_t>, "
193 "ProfileType[, RCP<ParameterList>]) threw an exception: "
200 staticGraph_ = graph;
206 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
208 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
209 const Teuchos::RCP<const map_type>& colMap,
210 const size_t maxNumEntPerRow,
212 const Teuchos::RCP<Teuchos::ParameterList>& params) :
215 const char tfecfFuncName[] =
"CrsMatrix(RCP<const Map>, "
216 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]): ";
217 const char suffix[] =
218 " Please report this bug to the Tpetra developers.";
221 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
222 (! staticGraph_.is_null (), std::logic_error,
223 "staticGraph_ is not null at the beginning of the constructor."
225 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
226 (! myGraph_.is_null (), std::logic_error,
227 "myGraph_ is not null at the beginning of the constructor."
229 Teuchos::RCP<crs_graph_type> graph;
235 catch (std::exception& e) {
236 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
237 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
238 "RCP<const Map>, size_t, ProfileType[, RCP<ParameterList>]) threw an "
239 "exception: " << e.what ());
245 staticGraph_ = myGraph_;
250 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
252 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
253 const Teuchos::RCP<const map_type>& colMap,
254 const Teuchos::ArrayView<const size_t>& numEntPerRowToAlloc,
256 const Teuchos::RCP<Teuchos::ParameterList>& params) :
259 const char tfecfFuncName[] =
260 "CrsMatrix(RCP<const Map>, RCP<const Map>, "
261 "ArrayView<const size_t>, ProfileType[, RCP<ParameterList>]): ";
262 Teuchos::RCP<crs_graph_type> graph;
268 catch (std::exception& e) {
269 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
270 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
271 "RCP<const Map>, ArrayView<const size_t>, ProfileType[, "
272 "RCP<ParameterList>]) threw an exception: " << e.what ());
278 staticGraph_ = graph;
284 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
286 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
287 const Teuchos::RCP<Teuchos::ParameterList>& ) :
289 staticGraph_ (graph),
290 storageStatus_ (
Details::STORAGE_1D_PACKED)
293 typedef typename local_matrix_device_type::values_type values_type;
294 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>[, "
295 "RCP<ParameterList>]): ";
298 std::unique_ptr<std::string> prefix;
300 prefix = this->createPrefix(
"CrsMatrix",
"CrsMatrix(graph,params)");
301 std::ostringstream os;
302 os << *prefix <<
"Start" << endl;
303 std::cerr << os.str ();
306 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
307 (graph.is_null (), std::runtime_error,
"Input graph is null.");
308 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
309 (! graph->isFillComplete (), std::runtime_error,
"Input graph "
310 "is not fill complete. You must call fillComplete on the "
311 "graph before using it to construct a CrsMatrix. Note that "
312 "calling resumeFill on the graph makes it not fill complete, "
313 "even if you had previously called fillComplete. In that "
314 "case, you must call fillComplete on the graph again.");
322 const size_t numEnt = graph->lclIndsPacked_wdv.extent (0);
324 std::ostringstream os;
325 os << *prefix <<
"Allocate values: " << numEnt << endl;
326 std::cerr << os.str ();
329 values_type val (
"Tpetra::CrsMatrix::values", numEnt);
330 valuesPacked_wdv = values_wdv_type(val);
331 valuesUnpacked_wdv = valuesPacked_wdv;
341 std::ostringstream os;
342 os << *prefix <<
"Done" << endl;
343 std::cerr << os.str ();
347 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
350 const Teuchos::RCP<const crs_graph_type>& graph,
351 const Teuchos::RCP<Teuchos::ParameterList>& params) :
353 staticGraph_ (graph),
354 storageStatus_ (matrix.storageStatus_)
356 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>, "
357 "local_matrix_device_type::values_type, "
358 "[,RCP<ParameterList>]): ";
359 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
360 (graph.is_null (), std::runtime_error,
"Input graph is null.");
361 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
362 (! graph->isFillComplete (), std::runtime_error,
"Input graph "
363 "is not fill complete. You must call fillComplete on the "
364 "graph before using it to construct a CrsMatrix. Note that "
365 "calling resumeFill on the graph makes it not fill complete, "
366 "even if you had previously called fillComplete. In that "
367 "case, you must call fillComplete on the graph again.");
369 size_t numValuesPacked = graph->lclIndsPacked_wdv.extent(0);
370 valuesPacked_wdv = values_wdv_type(matrix.valuesPacked_wdv, 0, numValuesPacked);
372 size_t numValuesUnpacked = graph->lclIndsUnpacked_wdv.extent(0);
373 valuesUnpacked_wdv = values_wdv_type(matrix.valuesUnpacked_wdv, 0, numValuesUnpacked);
379 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
381 CrsMatrix (
const Teuchos::RCP<const crs_graph_type>& graph,
382 const typename local_matrix_device_type::values_type& values,
383 const Teuchos::RCP<Teuchos::ParameterList>& ) :
385 staticGraph_ (graph),
386 storageStatus_ (
Details::STORAGE_1D_PACKED)
388 const char tfecfFuncName[] =
"CrsMatrix(RCP<const CrsGraph>, "
389 "local_matrix_device_type::values_type, "
390 "[,RCP<ParameterList>]): ";
391 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
392 (graph.is_null (), std::runtime_error,
"Input graph is null.");
393 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
394 (! graph->isFillComplete (), std::runtime_error,
"Input graph "
395 "is not fill complete. You must call fillComplete on the "
396 "graph before using it to construct a CrsMatrix. Note that "
397 "calling resumeFill on the graph makes it not fill complete, "
398 "even if you had previously called fillComplete. In that "
399 "case, you must call fillComplete on the graph again.");
407 valuesPacked_wdv = values_wdv_type(values);
408 valuesUnpacked_wdv = valuesPacked_wdv;
419 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
421 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
422 const Teuchos::RCP<const map_type>& colMap,
423 const typename local_graph_device_type::row_map_type& rowPointers,
424 const typename local_graph_device_type::entries_type::non_const_type& columnIndices,
425 const typename local_matrix_device_type::values_type& values,
426 const Teuchos::RCP<Teuchos::ParameterList>& params) :
428 storageStatus_ (
Details::STORAGE_1D_PACKED)
430 using Details::getEntryOnHost;
433 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
434 "RCP<const Map>, ptr, ind, val[, params]): ";
435 const char suffix[] =
436 ". Please report this bug to the Tpetra developers.";
440 std::unique_ptr<std::string> prefix;
442 prefix = this->createPrefix(
443 "CrsMatrix",
"CrsMatrix(rowMap,colMap,ptr,ind,val[,params])");
444 std::ostringstream os;
445 os << *prefix <<
"Start" << endl;
446 std::cerr << os.str ();
453 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
454 (values.extent(0) != columnIndices.extent(0),
455 std::invalid_argument,
"values.extent(0)=" << values.extent(0)
456 <<
" != columnIndices.extent(0) = " << columnIndices.extent(0)
458 if (debug && rowPointers.extent(0) != 0) {
459 const size_t numEnt =
460 getEntryOnHost(rowPointers, rowPointers.extent(0) - 1);
461 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
462 (numEnt !=
size_t(columnIndices.extent(0)) ||
463 numEnt !=
size_t(values.extent(0)),
464 std::invalid_argument,
"Last entry of rowPointers says that "
465 "the matrix has " << numEnt <<
" entr"
466 << (numEnt != 1 ?
"ies" :
"y") <<
", but the dimensions of "
467 "columnIndices and values don't match this. "
468 "columnIndices.extent(0)=" << columnIndices.extent (0)
469 <<
" and values.extent(0)=" << values.extent (0) <<
".");
472 RCP<crs_graph_type> graph;
474 graph = Teuchos::rcp (
new crs_graph_type (rowMap, colMap, rowPointers,
475 columnIndices, params));
477 catch (std::exception& e) {
478 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
479 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
480 "RCP<const Map>, ptr, ind[, params]) threw an exception: "
488 auto lclGraph = graph->getLocalGraphDevice ();
489 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
490 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
491 lclGraph.entries.extent (0) != columnIndices.extent (0),
492 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, "
493 "ind[, params]) did not set the local graph correctly." << suffix);
494 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
495 (lclGraph.entries.extent (0) != values.extent (0),
496 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, ptr, ind[, "
497 "params]) did not set the local graph correctly. "
498 "lclGraph.entries.extent(0) = " << lclGraph.entries.extent (0)
499 <<
" != values.extent(0) = " << values.extent (0) << suffix);
505 staticGraph_ = graph;
514 valuesPacked_wdv = values_wdv_type(values);
515 valuesUnpacked_wdv = valuesPacked_wdv;
524 std::ostringstream os;
525 os << *prefix <<
"Done" << endl;
526 std::cerr << os.str();
530 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
532 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
533 const Teuchos::RCP<const map_type>& colMap,
534 const Teuchos::ArrayRCP<size_t>& ptr,
535 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
536 const Teuchos::ArrayRCP<Scalar>& val,
537 const Teuchos::RCP<Teuchos::ParameterList>& params) :
539 storageStatus_ (
Details::STORAGE_1D_PACKED)
541 using Kokkos::Compat::getKokkosViewDeepCopy;
542 using Teuchos::av_reinterpret_cast;
544 using values_type =
typename local_matrix_device_type::values_type;
546 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
547 "RCP<const Map>, ptr, ind, val[, params]): ";
549 RCP<crs_graph_type> graph;
554 catch (std::exception& e) {
555 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
556 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
557 "RCP<const Map>, ArrayRCP<size_t>, ArrayRCP<LocalOrdinal>[, "
558 "RCP<ParameterList>]) threw an exception: " << e.what ());
564 staticGraph_ = graph;
577 auto lclGraph = staticGraph_->getLocalGraphDevice ();
578 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
579 (
size_t (lclGraph.row_map.extent (0)) != size_t (ptr.size ()) ||
580 size_t (lclGraph.entries.extent (0)) != size_t (ind.size ()),
581 std::logic_error,
"CrsGraph's constructor (rowMap, colMap, "
582 "ptr, ind[, params]) did not set the local graph correctly. "
583 "Please report this bug to the Tpetra developers.");
586 getKokkosViewDeepCopy<device_type> (av_reinterpret_cast<IST> (val ()));
587 valuesPacked_wdv = values_wdv_type(valIn);
588 valuesUnpacked_wdv = valuesPacked_wdv;
598 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
600 CrsMatrix (
const Teuchos::RCP<const map_type>& rowMap,
601 const Teuchos::RCP<const map_type>& colMap,
603 const Teuchos::RCP<Teuchos::ParameterList>& params) :
605 storageStatus_ (
Details::STORAGE_1D_PACKED),
608 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
609 "RCP<const Map>, local_matrix_device_type[, RCP<ParameterList>]): ";
610 const char suffix[] =
611 " Please report this bug to the Tpetra developers.";
613 Teuchos::RCP<crs_graph_type> graph;
616 lclMatrix.graph, params));
618 catch (std::exception& e) {
619 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
620 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
621 "RCP<const Map>, local_graph_device_type[, RCP<ParameterList>]) threw an "
622 "exception: " << e.what ());
624 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
625 (!graph->isFillComplete (), std::logic_error,
"CrsGraph constructor (RCP"
626 "<const Map>, RCP<const Map>, local_graph_device_type[, RCP<ParameterList>]) "
627 "did not produce a fill-complete graph. Please report this bug to the "
628 "Tpetra developers.");
633 staticGraph_ = graph;
635 valuesPacked_wdv = values_wdv_type(lclMatrix.values);
636 valuesUnpacked_wdv = valuesPacked_wdv;
640 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
641 params->get (
"compute global constants",
true);
642 if (callComputeGlobalConstants) {
646 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
648 "At the end of a CrsMatrix constructor that should produce "
649 "a fillComplete matrix, isFillActive() is true." << suffix);
650 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
652 "CrsMatrix constructor that should produce a fillComplete "
653 "matrix, isFillComplete() is false." << suffix);
657 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
660 const Teuchos::RCP<const map_type>& rowMap,
661 const Teuchos::RCP<const map_type>& colMap,
662 const Teuchos::RCP<const map_type>& domainMap,
663 const Teuchos::RCP<const map_type>& rangeMap,
664 const Teuchos::RCP<Teuchos::ParameterList>& params) :
666 storageStatus_ (
Details::STORAGE_1D_PACKED),
669 const char tfecfFuncName[] =
"Tpetra::CrsMatrix(RCP<const Map>, "
670 "RCP<const Map>, RCP<const Map>, RCP<const Map>, "
671 "local_matrix_device_type[, RCP<ParameterList>]): ";
672 const char suffix[] =
673 " Please report this bug to the Tpetra developers.";
675 Teuchos::RCP<crs_graph_type> graph;
677 graph = Teuchos::rcp (
new crs_graph_type (lclMatrix.graph, rowMap, colMap,
678 domainMap, rangeMap, params));
680 catch (std::exception& e) {
681 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
682 (
true, std::runtime_error,
"CrsGraph constructor (RCP<const Map>, "
683 "RCP<const Map>, RCP<const Map>, RCP<const Map>, local_graph_device_type[, "
684 "RCP<ParameterList>]) threw an exception: " << e.what ());
686 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
687 (! graph->isFillComplete (), std::logic_error,
"CrsGraph "
688 "constructor (RCP<const Map>, RCP<const Map>, RCP<const Map>, "
689 "RCP<const Map>, local_graph_device_type[, RCP<ParameterList>]) did "
690 "not produce a fillComplete graph." << suffix);
695 staticGraph_ = graph;
697 valuesPacked_wdv = values_wdv_type(lclMatrix.values);
698 valuesUnpacked_wdv = valuesPacked_wdv;
701 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
702 params->get (
"compute global constants",
true);
703 if (callComputeGlobalConstants) {
707 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
709 "At the end of a CrsMatrix constructor that should produce "
710 "a fillComplete matrix, isFillActive() is true." << suffix);
711 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
713 "CrsMatrix constructor that should produce a fillComplete "
714 "matrix, isFillComplete() is false." << suffix);
718 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
721 const Teuchos::RCP<const map_type>& rowMap,
722 const Teuchos::RCP<const map_type>& colMap,
723 const Teuchos::RCP<const map_type>& domainMap,
724 const Teuchos::RCP<const map_type>& rangeMap,
725 const Teuchos::RCP<const import_type>& importer,
726 const Teuchos::RCP<const export_type>& exporter,
727 const Teuchos::RCP<Teuchos::ParameterList>& params) :
729 storageStatus_ (
Details::STORAGE_1D_PACKED),
733 const char tfecfFuncName[] =
"Tpetra::CrsMatrix"
734 "(lclMat,Map,Map,Map,Map,Import,Export,params): ";
735 const char suffix[] =
736 " Please report this bug to the Tpetra developers.";
738 Teuchos::RCP<crs_graph_type> graph;
741 domainMap, rangeMap, importer,
744 catch (std::exception& e) {
745 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
746 (
true, std::runtime_error,
"CrsGraph constructor "
747 "(local_graph_device_type, Map, Map, Map, Map, Import, Export, "
748 "params) threw: " << e.what ());
750 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
751 (!graph->isFillComplete (), std::logic_error,
"CrsGraph "
752 "constructor (local_graph_device_type, Map, Map, Map, Map, Import, "
753 "Export, params) did not produce a fill-complete graph. "
754 "Please report this bug to the Tpetra developers.");
759 staticGraph_ = graph;
761 valuesPacked_wdv = values_wdv_type(lclMatrix.values);
762 valuesUnpacked_wdv = valuesPacked_wdv;
765 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
766 params->get (
"compute global constants",
true);
767 if (callComputeGlobalConstants) {
771 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
773 "At the end of a CrsMatrix constructor that should produce "
774 "a fillComplete matrix, isFillActive() is true." << suffix);
775 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
777 "CrsMatrix constructor that should produce a fillComplete "
778 "matrix, isFillComplete() is false." << suffix);
782 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
785 const Teuchos::DataAccess copyOrView)
786 :
CrsMatrix (source.getCrsGraph (), source.getLocalValuesView ())
788 const char tfecfFuncName[] =
"Tpetra::CrsMatrix("
789 "const CrsMatrix&, const Teuchos::DataAccess): ";
790 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
792 "Source graph must be fillComplete().");
794 if (copyOrView == Teuchos::Copy) {
795 using values_type =
typename local_matrix_device_type::values_type;
797 using Kokkos::view_alloc;
798 using Kokkos::WithoutInitializing;
799 values_type newvals (view_alloc (
"val", WithoutInitializing),
802 valuesPacked_wdv = values_wdv_type(newvals);
803 valuesUnpacked_wdv = valuesPacked_wdv;
809 else if (copyOrView == Teuchos::View) {
813 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
814 (
true, std::invalid_argument,
"Second argument 'copyOrView' "
815 "has an invalid value " << copyOrView <<
". Valid values "
816 "include Teuchos::Copy = " << Teuchos::Copy <<
" and "
817 "Teuchos::View = " << Teuchos::View <<
".");
821 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
826 std::swap(crs_matrix.
importMV_, this->importMV_);
827 std::swap(crs_matrix.
exportMV_, this->exportMV_);
828 std::swap(crs_matrix.staticGraph_, this->staticGraph_);
829 std::swap(crs_matrix.myGraph_, this->myGraph_);
830 std::swap(crs_matrix.valuesPacked_wdv, this->valuesPacked_wdv);
831 std::swap(crs_matrix.valuesUnpacked_wdv, this->valuesUnpacked_wdv);
834 std::swap(crs_matrix.
nonlocals_, this->nonlocals_);
835 std::swap(crs_matrix.
frobNorm_, this->frobNorm_);
838 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
839 Teuchos::RCP<const Teuchos::Comm<int> >
842 return getCrsGraphRef ().getComm ();
845 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
849 return this->getCrsGraphRef ().getProfileType ();
852 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
856 return fillComplete_;
859 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
863 return ! fillComplete_;
866 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
870 return this->getCrsGraphRef ().isStorageOptimized ();
873 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
877 return getCrsGraphRef ().isLocallyIndexed ();
880 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
884 return getCrsGraphRef ().isGloballyIndexed ();
887 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
891 return getCrsGraphRef ().hasColMap ();
894 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
898 return getCrsGraphRef ().getGlobalNumEntries ();
901 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
905 return getCrsGraphRef ().getNodeNumEntries ();
908 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
912 return getCrsGraphRef ().getGlobalNumRows ();
915 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
919 return getCrsGraphRef ().getGlobalNumCols ();
922 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
926 return getCrsGraphRef ().getNodeNumRows ();
929 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
933 return getCrsGraphRef ().getNodeNumCols ();
937 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
941 return getCrsGraphRef ().getNumEntriesInGlobalRow (globalRow);
944 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
948 return getCrsGraphRef ().getNumEntriesInLocalRow (localRow);
951 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
955 return getCrsGraphRef ().getGlobalMaxNumRowEntries ();
958 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
962 return getCrsGraphRef ().getNodeMaxNumRowEntries ();
965 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
969 return getRowMap ()->getIndexBase ();
972 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
973 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
976 return getCrsGraphRef ().getRowMap ();
979 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
980 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
983 return getCrsGraphRef ().getColMap ();
986 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
987 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
990 return getCrsGraphRef ().getDomainMap ();
993 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
994 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
997 return getCrsGraphRef ().getRangeMap ();
1000 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1001 Teuchos::RCP<const RowGraph<LocalOrdinal, GlobalOrdinal, Node> >
1004 if (staticGraph_ != Teuchos::null) {
1005 return staticGraph_;
1010 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1011 Teuchos::RCP<const CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
1014 if (staticGraph_ != Teuchos::null) {
1015 return staticGraph_;
1020 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1025 #ifdef HAVE_TPETRA_DEBUG
1026 constexpr
bool debug =
true;
1028 constexpr
bool debug =
false;
1031 if (! this->staticGraph_.is_null ()) {
1032 return * (this->staticGraph_);
1036 const char tfecfFuncName[] =
"getCrsGraphRef: ";
1037 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1038 (this->myGraph_.is_null (), std::logic_error,
1039 "Both staticGraph_ and myGraph_ are null. "
1040 "Please report this bug to the Tpetra developers.");
1042 return * (this->myGraph_);
1046 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
1047 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1049 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1050 getLocalMatrix ()
const
1052 return getLocalMatrixDevice();
1056 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1061 auto numCols = staticGraph_->getColMap()->getNodeNumElements();
1064 valuesPacked_wdv.getDeviceView(Access::ReadWrite),
1065 staticGraph_->getLocalGraphDevice());
1068 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1069 typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_matrix_host_type
1073 auto numCols = staticGraph_->
getColMap()->getNodeNumElements();
1074 return local_matrix_host_type(
"Tpetra::CrsMatrix::lclMatrixHost", numCols,
1075 valuesPacked_wdv.getHostView(Access::ReadWrite),
1076 staticGraph_->getLocalGraphHost());
1080 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1081 std::shared_ptr<typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_multiply_op_type>
1085 auto localMatrix = getLocalMatrixDevice();
1086 #ifdef HAVE_TPETRACORE_CUDA
1087 #ifdef KOKKOSKERNELS_ENABLE_TPL_CUSPARSE
1088 if(this->getNodeNumEntries() <=
size_t(Teuchos::OrdinalTraits<LocalOrdinal>::max()) &&
1089 std::is_same<Node, Kokkos::Compat::KokkosCudaWrapperNode>::value)
1091 if(this->ordinalRowptrs.data() ==
nullptr)
1093 auto originalRowptrs = localMatrix.graph.row_map;
1096 this->ordinalRowptrs = ordinal_rowptrs_type(
1097 Kokkos::ViewAllocateWithoutInitializing(
"CrsMatrix::ordinalRowptrs"), originalRowptrs.extent(0));
1098 auto ordinalRowptrs_ = this->ordinalRowptrs;
1099 Kokkos::parallel_for(
"CrsMatrix::getLocalMultiplyOperator::convertRowptrs",
1100 Kokkos::RangePolicy<execution_space>(0, originalRowptrs.extent(0)),
1101 KOKKOS_LAMBDA(LocalOrdinal i)
1103 ordinalRowptrs_(i) = originalRowptrs(i);
1107 return std::make_shared<local_multiply_op_type>(
1108 std::make_shared<local_matrix_device_type>(localMatrix), this->ordinalRowptrs);
1113 return std::make_shared<local_multiply_op_type>(
1114 std::make_shared<local_matrix_device_type>(
1115 getLocalMatrixDevice()));
1118 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1122 return myGraph_.is_null ();
1125 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1132 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1139 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1148 const char tfecfFuncName[] =
"allocateValues: ";
1149 const char suffix[] =
1150 " Please report this bug to the Tpetra developers.";
1151 ProfilingRegion region(
"Tpetra::CrsMatrix::allocateValues");
1153 std::unique_ptr<std::string> prefix;
1155 prefix = this->createPrefix(
"CrsMatrix",
"allocateValues");
1156 std::ostringstream os;
1157 os << *prefix <<
"lg: "
1158 << (lg == LocalIndices ?
"Local" :
"Global") <<
"Indices"
1160 << (gas == GraphAlreadyAllocated ?
"Already" :
"NotYet")
1161 <<
"Allocated" << endl;
1162 std::cerr << os.str();
1165 const bool debug = Behavior::debug(
"CrsMatrix");
1167 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1168 (this->staticGraph_.is_null (), std::logic_error,
1169 "staticGraph_ is null." << suffix);
1174 if ((gas == GraphAlreadyAllocated) !=
1175 staticGraph_->indicesAreAllocated ()) {
1176 const char err1[] =
"The caller has asserted that the graph "
1178 const char err2[] =
"already allocated, but the static graph "
1179 "says that its indices are ";
1180 const char err3[] =
"already allocated. ";
1181 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1182 (gas == GraphAlreadyAllocated &&
1183 ! staticGraph_->indicesAreAllocated (), std::logic_error,
1184 err1 << err2 <<
"not " << err3 << suffix);
1185 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1186 (gas != GraphAlreadyAllocated &&
1187 staticGraph_->indicesAreAllocated (), std::logic_error,
1188 err1 <<
"not " << err2 << err3 << suffix);
1196 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1197 (! this->staticGraph_->indicesAreAllocated () &&
1198 this->myGraph_.is_null (), std::logic_error,
1199 "The static graph says that its indices are not allocated, "
1200 "but the graph is not owned by the matrix." << suffix);
1203 if (gas == GraphNotYetAllocated) {
1205 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1206 (this->myGraph_.is_null (), std::logic_error,
1207 "gas = GraphNotYetAllocated, but myGraph_ is null." << suffix);
1210 this->myGraph_->allocateIndices (lg, verbose);
1212 catch (std::exception& e) {
1213 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1214 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1215 "threw an exception: " << e.what ());
1218 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1219 (
true, std::runtime_error,
"CrsGraph::allocateIndices "
1220 "threw an exception not a subclass of std::exception.");
1232 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1233 (this->staticGraph_.is_null (), std::logic_error,
1234 "this->getProfileType() == StaticProfile, but staticGraph_ "
1235 "is null." << suffix);
1238 const size_t lclNumRows = this->staticGraph_->getNodeNumRows ();
1239 typename Graph::local_graph_device_type::row_map_type k_ptrs =
1240 this->staticGraph_->rowPtrsUnpacked_dev_;
1241 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1242 (k_ptrs.extent (0) != lclNumRows+1, std::logic_error,
1243 "With StaticProfile, row offsets array has length "
1244 << k_ptrs.extent (0) <<
" != (lclNumRows+1) = "
1245 << (lclNumRows+1) <<
".");
1247 const size_t lclTotalNumEntries =
1248 this->staticGraph_->rowPtrsUnpacked_host_(lclNumRows);
1251 using values_type =
typename local_matrix_device_type::values_type;
1253 std::ostringstream os;
1254 os << *prefix <<
"Allocate values_wdv: Pre "
1255 << valuesUnpacked_wdv.extent(0) <<
", post "
1256 << lclTotalNumEntries << endl;
1257 std::cerr << os.str();
1260 valuesUnpacked_wdv = values_wdv_type(
1261 values_type(
"Tpetra::CrsMatrix::values",
1262 lclTotalNumEntries));
1265 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1267 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1268 getAllValues (Teuchos::ArrayRCP<const size_t>& rowPointers,
1269 Teuchos::ArrayRCP<const LocalOrdinal>& columnIndices,
1270 Teuchos::ArrayRCP<const Scalar>& values)
const
1273 const char tfecfFuncName[] =
"getAllValues: ";
1274 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1275 columnIndices.size () != values.size (), std::runtime_error,
1276 "Requires that columnIndices and values are the same size.");
1278 RCP<const crs_graph_type> relevantGraph = getCrsGraph ();
1279 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1280 relevantGraph.is_null (), std::runtime_error,
1281 "Requires that getCrsGraph() is not null.");
1283 rowPointers = relevantGraph->getNodeRowPtrs ();
1285 catch (std::exception &e) {
1286 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1287 true, std::runtime_error,
1288 "Caught exception while calling graph->getNodeRowPtrs(): "
1292 columnIndices = relevantGraph->getNodePackedIndices ();
1294 catch (std::exception &e) {
1295 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1296 true, std::runtime_error,
1297 "Caught exception while calling graph->getNodePackedIndices(): "
1300 Teuchos::ArrayRCP<const impl_scalar_type> vals =
1302 Kokkos::Compat::persistingView (valuesUnpacked_wdv.getHostView(Access::ReadOnly));
1303 values = Teuchos::arcp_reinterpret_cast<const Scalar> (vals);
1306 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1311 const char tfecfFuncName[] =
"getAllValues: ";
1312 RCP<const crs_graph_type> relevantGraph = getCrsGraph ();
1313 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1314 relevantGraph.is_null (), std::runtime_error,
1315 "Requires that getCrsGraph() is not null.");
1316 Teuchos::ArrayRCP<impl_scalar_type> vals =
1317 Kokkos::Compat::persistingView (k_values1D_);
1318 values = Teuchos::arcp_reinterpret_cast<Scalar> (vals);
1322 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1328 using ::Tpetra::Details::getEntryOnHost;
1329 using Teuchos::arcp_const_cast;
1330 using Teuchos::Array;
1331 using Teuchos::ArrayRCP;
1332 using Teuchos::null;
1336 using row_map_type =
typename local_graph_device_type::row_map_type;
1337 using lclinds_1d_type =
typename Graph::local_graph_device_type::entries_type::non_const_type;
1338 using values_type =
typename local_matrix_device_type::values_type;
1340 (
"Tpetra::CrsGraph::fillLocalGraphAndMatrix");
1342 const char tfecfFuncName[] =
"fillLocalGraphAndMatrix (called from "
1343 "fillComplete or expertStaticFillComplete): ";
1344 const char suffix[] =
1345 " Please report this bug to the Tpetra developers.";
1349 std::unique_ptr<std::string> prefix;
1351 prefix = this->createPrefix(
"CrsMatrix",
"fillLocalGraphAndMatrix");
1352 std::ostringstream os;
1353 os << *prefix << endl;
1354 std::cerr << os.str ();
1360 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1361 (myGraph_.is_null (), std::logic_error,
"The nonconst graph "
1362 "(myGraph_) is null. This means that the matrix has a "
1363 "const (a.k.a. \"static\") graph. fillComplete or "
1364 "expertStaticFillComplete should never call "
1365 "fillLocalGraphAndMatrix in that case." << suffix);
1368 const size_t lclNumRows = this->getNodeNumRows ();
1378 typedef decltype (myGraph_->k_numRowEntries_) row_entries_type;
1387 myGraph_->rowPtrsUnpacked_dev_;
1390 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1391 (curRowOffsets.extent (0) == 0, std::logic_error,
1392 "(StaticProfile branch) curRowOffsets.extent(0) == 0.");
1393 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1394 (curRowOffsets.extent (0) != lclNumRows + 1, std::logic_error,
1395 "(StaticProfile branch) curRowOffsets.extent(0) = "
1396 << curRowOffsets.extent (0) <<
" != lclNumRows + 1 = "
1397 << (lclNumRows + 1) <<
".");
1398 const size_t numOffsets = curRowOffsets.extent (0);
1399 const auto valToCheck = myGraph_->rowPtrsUnpacked_host_(numOffsets - 1);
1400 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1402 myGraph_->lclIndsUnpacked_wdv.extent (0) != valToCheck,
1403 std::logic_error,
"(StaticProfile branch) numOffsets = " <<
1404 numOffsets <<
" != 0 and myGraph_->lclIndsUnpacked_wdv.extent(0) = "
1405 << myGraph_->lclIndsUnpacked_wdv.extent (0) <<
" != curRowOffsets("
1406 << numOffsets <<
") = " << valToCheck <<
".");
1409 if (myGraph_->getNodeNumEntries() !=
1410 myGraph_->getNodeAllocationSize()) {
1414 typename row_map_type::non_const_type k_ptrs;
1415 row_map_type k_ptrs_const;
1416 lclinds_1d_type k_inds;
1420 std::ostringstream os;
1421 const auto numEnt = myGraph_->getNodeNumEntries();
1422 const auto allocSize = myGraph_->getNodeAllocationSize();
1423 os << *prefix <<
"Unpacked 1-D storage: numEnt=" << numEnt
1424 <<
", allocSize=" << allocSize << endl;
1425 std::cerr << os.str ();
1433 if (debug && curRowOffsets.extent (0) != 0) {
1434 const size_t numOffsets =
1435 static_cast<size_t> (curRowOffsets.extent (0));
1436 const auto valToCheck = myGraph_->rowPtrsUnpacked_host_(numOffsets - 1);
1437 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1438 (
static_cast<size_t> (valToCheck) !=
1439 static_cast<size_t> (valuesUnpacked_wdv.extent (0)),
1440 std::logic_error,
"(StaticProfile unpacked branch) Before "
1441 "allocating or packing, curRowOffsets(" << (numOffsets-1)
1442 <<
") = " << valToCheck <<
" != valuesUnpacked_wdv.extent(0)"
1443 " = " << valuesUnpacked_wdv.extent (0) <<
".");
1444 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1445 (
static_cast<size_t> (valToCheck) !=
1446 static_cast<size_t> (myGraph_->lclIndsUnpacked_wdv.extent (0)),
1447 std::logic_error,
"(StaticProfile unpacked branch) Before "
1448 "allocating or packing, curRowOffsets(" << (numOffsets-1)
1449 <<
") = " << valToCheck
1450 <<
" != myGraph_->lclIndsUnpacked_wdv.extent(0) = "
1451 << myGraph_->lclIndsUnpacked_wdv.extent (0) <<
".");
1459 size_t lclTotalNumEntries = 0;
1465 std::ostringstream os;
1466 os << *prefix <<
"Allocate packed row offsets: "
1467 << (lclNumRows+1) << endl;
1468 std::cerr << os.str ();
1470 typename row_map_type::non_const_type
1471 packedRowOffsets (
"Tpetra::CrsGraph::ptr", lclNumRows + 1);
1472 typename row_entries_type::const_type numRowEnt_h =
1473 myGraph_->k_numRowEntries_;
1476 lclTotalNumEntries =
1480 k_ptrs = packedRowOffsets;
1481 k_ptrs_const = k_ptrs;
1485 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1486 (
static_cast<size_t> (k_ptrs.extent (0)) != lclNumRows + 1,
1488 "(StaticProfile unpacked branch) After packing k_ptrs, "
1489 "k_ptrs.extent(0) = " << k_ptrs.extent (0) <<
" != "
1490 "lclNumRows+1 = " << (lclNumRows+1) <<
".");
1491 const auto valToCheck = getEntryOnHost (k_ptrs, lclNumRows);
1492 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1493 (valToCheck != lclTotalNumEntries, std::logic_error,
1494 "(StaticProfile unpacked branch) After filling k_ptrs, "
1495 "k_ptrs(lclNumRows=" << lclNumRows <<
") = " << valToCheck
1496 <<
" != total number of entries on the calling process = "
1497 << lclTotalNumEntries <<
".");
1502 std::ostringstream os;
1503 os << *prefix <<
"Allocate packed local column indices: "
1504 << lclTotalNumEntries << endl;
1505 std::cerr << os.str ();
1507 k_inds = lclinds_1d_type (
"Tpetra::CrsGraph::lclInds", lclTotalNumEntries);
1509 std::ostringstream os;
1510 os << *prefix <<
"Allocate packed values: "
1511 << lclTotalNumEntries << endl;
1512 std::cerr << os.str ();
1514 k_vals = values_type (
"Tpetra::CrsMatrix::values", lclTotalNumEntries);
1526 using inds_packer_type = pack_functor<
1527 typename Graph::local_graph_device_type::entries_type::non_const_type,
1528 typename Graph::local_inds_dualv_type::t_dev::const_type,
1529 typename Graph::local_graph_device_type::row_map_type::non_const_type,
1530 typename Graph::local_graph_device_type::row_map_type>;
1531 inds_packer_type indsPacker (
1533 myGraph_->lclIndsUnpacked_wdv.getDeviceView(Access::ReadOnly),
1534 k_ptrs, curRowOffsets);
1535 using exec_space =
typename decltype (k_inds)::execution_space;
1536 using range_type = Kokkos::RangePolicy<exec_space, LocalOrdinal>;
1537 Kokkos::parallel_for
1538 (
"Tpetra::CrsMatrix pack column indices",
1539 range_type (0, lclNumRows), indsPacker);
1543 using vals_packer_type = pack_functor<
1544 typename values_type::non_const_type,
1545 typename values_type::const_type,
1546 typename row_map_type::non_const_type,
1547 typename row_map_type::const_type>;
1548 vals_packer_type valsPacker (
1550 this->valuesUnpacked_wdv.getDeviceView(Access::ReadOnly),
1551 k_ptrs, curRowOffsets);
1552 Kokkos::parallel_for (
"Tpetra::CrsMatrix pack values",
1553 range_type (0, lclNumRows), valsPacker);
1556 const char myPrefix[] =
"(StaticProfile \"Optimize Storage\""
1557 "=true branch) After packing, ";
1558 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1559 (k_ptrs.extent (0) == 0, std::logic_error, myPrefix
1560 <<
"k_ptrs.extent(0) = 0. This probably means that "
1561 "rowPtrsUnpacked_ was never allocated.");
1562 if (k_ptrs.extent (0) != 0) {
1563 const size_t numOffsets (k_ptrs.extent (0));
1564 const auto valToCheck =
1565 getEntryOnHost (k_ptrs, numOffsets - 1);
1566 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1567 (
size_t (valToCheck) != k_vals.extent (0),
1568 std::logic_error, myPrefix <<
1569 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1570 " != k_vals.extent(0) = " << k_vals.extent (0) <<
".");
1571 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1572 (
size_t (valToCheck) != k_inds.extent (0),
1573 std::logic_error, myPrefix <<
1574 "k_ptrs(" << (numOffsets-1) <<
") = " << valToCheck <<
1575 " != k_inds.extent(0) = " << k_inds.extent (0) <<
".");
1579 myGraph_->setRowPtrsPacked(k_ptrs_const);
1580 myGraph_->lclIndsPacked_wdv =
1581 typename crs_graph_type::local_inds_wdv_type(k_inds);
1582 valuesPacked_wdv = values_wdv_type(k_vals);
1585 myGraph_->setRowPtrsPacked(myGraph_->rowPtrsUnpacked_dev_);
1586 myGraph_->lclIndsPacked_wdv = myGraph_->lclIndsUnpacked_wdv;
1587 valuesPacked_wdv = valuesUnpacked_wdv;
1590 std::ostringstream os;
1591 os << *prefix <<
"Storage already packed: rowPtrsUnpacked_: "
1592 << myGraph_->rowPtrsUnpacked_host_.extent(0) <<
", lclIndsUnpacked_wdv: "
1593 << myGraph_->lclIndsUnpacked_wdv.extent(0) <<
", valuesUnpacked_wdv: "
1594 << valuesUnpacked_wdv.extent(0) << endl;
1595 std::cerr << os.str();
1599 const char myPrefix[] =
1600 "(StaticProfile \"Optimize Storage\"=false branch) ";
1601 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1602 (myGraph_->rowPtrsUnpacked_dev_.extent (0) == 0, std::logic_error, myPrefix
1603 <<
"myGraph->rowPtrsUnpacked_dev_.extent(0) = 0. This probably means "
1604 "that rowPtrsUnpacked_ was never allocated.");
1605 if (myGraph_->rowPtrsUnpacked_dev_.extent (0) != 0) {
1606 const size_t numOffsets (myGraph_->rowPtrsUnpacked_host_.extent (0));
1607 const auto valToCheck = myGraph_->rowPtrsUnpacked_host_(numOffsets - 1);
1608 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1609 (
size_t (valToCheck) != valuesPacked_wdv.extent (0),
1610 std::logic_error, myPrefix <<
1611 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1612 <<
" != valuesPacked_wdv.extent(0) = "
1613 << valuesPacked_wdv.extent (0) <<
".");
1614 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1615 (
size_t (valToCheck) != myGraph_->lclIndsPacked_wdv.extent (0),
1616 std::logic_error, myPrefix <<
1617 "k_ptrs_const(" << (numOffsets-1) <<
") = " << valToCheck
1618 <<
" != myGraph_->lclIndsPacked.extent(0) = "
1619 << myGraph_->lclIndsPacked_wdv.extent (0) <<
".");
1625 const char myPrefix[] =
"After packing, ";
1626 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1627 (
size_t (myGraph_->rowPtrsUnpacked_host_.extent (0)) != size_t (lclNumRows + 1),
1628 std::logic_error, myPrefix <<
"myGraph_->rowPtrsUnpacked_host_.extent(0) = "
1629 << myGraph_->rowPtrsUnpacked_host_.extent (0) <<
" != lclNumRows+1 = " <<
1630 (lclNumRows+1) <<
".");
1631 if (myGraph_->rowPtrsUnpacked_host_.extent (0) != 0) {
1632 const size_t numOffsets (myGraph_->rowPtrsUnpacked_host_.extent (0));
1633 const size_t valToCheck = myGraph_->rowPtrsUnpacked_host_(numOffsets-1);
1634 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1635 (valToCheck !=
size_t (valuesPacked_wdv.extent (0)),
1636 std::logic_error, myPrefix <<
"k_ptrs_const(" <<
1637 (numOffsets-1) <<
") = " << valToCheck
1638 <<
" != valuesPacked_wdv.extent(0) = "
1639 << valuesPacked_wdv.extent (0) <<
".");
1640 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1641 (valToCheck !=
size_t (myGraph_->lclIndsPacked_wdv.extent (0)),
1642 std::logic_error, myPrefix <<
"k_ptrs_const(" <<
1643 (numOffsets-1) <<
") = " << valToCheck
1644 <<
" != myGraph_->lclIndsPacked_wdvk_inds.extent(0) = "
1645 << myGraph_->lclIndsPacked_wdv.extent (0) <<
".");
1653 const bool defaultOptStorage =
1654 ! isStaticGraph () || staticGraph_->isStorageOptimized ();
1655 const bool requestOptimizedStorage =
1656 (! params.is_null () &&
1657 params->get (
"Optimize Storage", defaultOptStorage)) ||
1658 (params.is_null () && defaultOptStorage);
1665 if (requestOptimizedStorage) {
1672 std::ostringstream os;
1673 os << *prefix <<
"Optimizing storage: free k_numRowEntries_: "
1674 << myGraph_->k_numRowEntries_.extent(0) << endl;
1675 std::cerr << os.str();
1678 myGraph_->k_numRowEntries_ = row_entries_type ();
1681 myGraph_->setRowPtrsUnpacked(myGraph_->rowPtrsPacked_dev_);
1682 myGraph_->lclIndsUnpacked_wdv = myGraph_->lclIndsPacked_wdv;
1683 valuesUnpacked_wdv = valuesPacked_wdv;
1686 myGraph_->storageStatus_ = Details::STORAGE_1D_PACKED;
1687 this->storageStatus_ = Details::STORAGE_1D_PACKED;
1691 std::ostringstream os;
1692 os << *prefix <<
"User requested NOT to optimize storage"
1694 std::cerr << os.str();
1699 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1704 using ::Tpetra::Details::ProfilingRegion;
1705 using Teuchos::ArrayRCP;
1706 using Teuchos::Array;
1707 using Teuchos::null;
1711 using row_map_type =
typename Graph::local_graph_device_type::row_map_type;
1712 using non_const_row_map_type =
typename row_map_type::non_const_type;
1713 using values_type =
typename local_matrix_device_type::values_type;
1714 ProfilingRegion regionFLM(
"Tpetra::CrsMatrix::fillLocalMatrix");
1715 const size_t lclNumRows = getNodeNumRows();
1718 std::unique_ptr<std::string> prefix;
1720 prefix = this->createPrefix(
"CrsMatrix",
"fillLocalMatrix");
1721 std::ostringstream os;
1722 os << *prefix <<
"lclNumRows: " << lclNumRows << endl;
1723 std::cerr << os.str ();
1735 size_t nodeNumEntries = staticGraph_->getNodeNumEntries ();
1736 size_t nodeNumAllocated = staticGraph_->getNodeAllocationSize ();
1737 row_map_type k_rowPtrs = staticGraph_->rowPtrsPacked_dev_;
1739 row_map_type k_ptrs;
1745 bool requestOptimizedStorage =
true;
1746 const bool default_OptimizeStorage =
1747 ! isStaticGraph() || staticGraph_->isStorageOptimized();
1748 if (! params.is_null() &&
1749 ! params->get(
"Optimize Storage", default_OptimizeStorage)) {
1750 requestOptimizedStorage =
false;
1757 if (! staticGraph_->isStorageOptimized () &&
1758 requestOptimizedStorage) {
1760 (
true, std::runtime_error,
"You requested optimized storage "
1761 "by setting the \"Optimize Storage\" flag to \"true\" in "
1762 "the ParameterList, or by virtue of default behavior. "
1763 "However, the associated CrsGraph was filled separately and "
1764 "requested not to optimize storage. Therefore, the "
1765 "CrsMatrix cannot optimize storage.");
1766 requestOptimizedStorage =
false;
1769 using row_entries_type = decltype (staticGraph_->k_numRowEntries_);
1788 if (nodeNumEntries != nodeNumAllocated) {
1790 std::ostringstream os;
1791 os << *prefix <<
"Unpacked 1-D storage: numEnt="
1792 << nodeNumEntries <<
", allocSize=" << nodeNumAllocated
1794 std::cerr << os.str();
1799 std::ostringstream os;
1800 os << *prefix <<
"Allocate packed row offsets: "
1801 << (lclNumRows+1) << endl;
1802 std::cerr << os.str();
1804 non_const_row_map_type tmpk_ptrs (
"Tpetra::CrsGraph::ptr",
1809 size_t lclTotalNumEntries = 0;
1812 typename row_entries_type::const_type numRowEnt_h =
1813 staticGraph_->k_numRowEntries_;
1815 lclTotalNumEntries =
1822 std::ostringstream os;
1823 os << *prefix <<
"Allocate packed values: "
1824 << lclTotalNumEntries << endl;
1825 std::cerr << os.str ();
1827 k_vals = values_type (
"Tpetra::CrsMatrix::val", lclTotalNumEntries);
1831 typename values_type::non_const_type,
1832 typename values_type::const_type,
1833 typename row_map_type::non_const_type,
1834 typename row_map_type::const_type> valsPacker
1835 (k_vals, valuesUnpacked_wdv.getDeviceView(Access::ReadOnly),
1836 tmpk_ptrs, k_rowPtrs);
1839 using range_type = Kokkos::RangePolicy<exec_space, LocalOrdinal>;
1840 Kokkos::parallel_for (
"Tpetra::CrsMatrix pack values",
1841 range_type (0, lclNumRows), valsPacker);
1842 valuesPacked_wdv = values_wdv_type(k_vals);
1845 valuesPacked_wdv = valuesUnpacked_wdv;
1847 std::ostringstream os;
1848 os << *prefix <<
"Storage already packed: "
1849 <<
"valuesUnpacked_wdv: " << valuesUnpacked_wdv.extent(0) << endl;
1850 std::cerr << os.str();
1855 if (requestOptimizedStorage) {
1858 valuesUnpacked_wdv = valuesPacked_wdv;
1860 this->storageStatus_ = Details::STORAGE_1D_PACKED;
1864 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1866 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1867 insertIndicesAndValues (crs_graph_type& graph,
1869 const typename crs_graph_type::SLocalGlobalViews& newInds,
1870 const Teuchos::ArrayView<impl_scalar_type>& oldRowVals,
1871 const Teuchos::ArrayView<const impl_scalar_type>& newRowVals,
1872 const ELocalGlobal lg,
1873 const ELocalGlobal I)
1875 const size_t oldNumEnt = rowInfo.numEntries;
1876 const size_t numInserted = graph.insertIndices (rowInfo, newInds, lg, I);
1882 if (numInserted > 0) {
1883 const size_t startOffset = oldNumEnt;
1884 memcpy (&oldRowVals[startOffset], &newRowVals[0],
1889 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1893 const Teuchos::ArrayView<const LocalOrdinal>& indices,
1894 const Teuchos::ArrayView<const Scalar>& values)
1897 const char tfecfFuncName[] =
"insertLocalValues: ";
1899 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1900 (! this->isFillActive (), std::runtime_error,
1901 "Fill is not active. After calling fillComplete, you must call "
1902 "resumeFill before you may insert entries into the matrix again.");
1903 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1904 (this->isStaticGraph (), std::runtime_error,
1905 "Cannot insert indices with static graph; use replaceLocalValues() "
1909 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1910 (graph.
colMap_.is_null (), std::runtime_error,
1911 "Cannot insert local indices without a column map.");
1912 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1914 std::runtime_error,
"Graph indices are global; use "
1915 "insertGlobalValues().");
1916 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1917 (values.size () != indices.size (), std::runtime_error,
1918 "values.size() = " << values.size ()
1919 <<
" != indices.size() = " << indices.size () <<
".");
1920 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1921 ! graph.
rowMap_->isNodeLocalElement (lclRow), std::runtime_error,
1922 "Local row index " << lclRow <<
" does not belong to this process.");
1924 if (! graph.indicesAreAllocated ()) {
1928 this->allocateValues (LocalIndices, GraphNotYetAllocated, verbose);
1931 #ifdef HAVE_TPETRA_DEBUG
1932 const size_t numEntriesToAdd =
static_cast<size_t> (indices.size ());
1937 using Teuchos::toString;
1939 const map_type& colMap = * (graph.
colMap_);
1940 Teuchos::Array<LocalOrdinal> badColInds;
1941 bool allInColMap =
true;
1942 for (
size_t k = 0; k < numEntriesToAdd; ++k) {
1943 if (! colMap.isNodeLocalElement (indices[k])) {
1944 allInColMap =
false;
1945 badColInds.push_back (indices[k]);
1948 if (! allInColMap) {
1949 std::ostringstream os;
1950 os <<
"You attempted to insert entries in owned row " << lclRow
1951 <<
", at the following column indices: " << toString (indices)
1953 os <<
"Of those, the following indices are not in the column Map on "
1954 "this process: " << toString (badColInds) <<
"." << endl <<
"Since "
1955 "the matrix has a column Map already, it is invalid to insert "
1956 "entries at those locations.";
1957 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1958 (
true, std::invalid_argument, os.str ());
1965 auto valsView = this->getValuesViewHostNonConst(rowInfo);
1966 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset) {
1967 valsView[offset] += values[k]; };
1968 std::function<void(
size_t const,
size_t const,
size_t const)> cb(std::ref(fun));
1969 graph.insertLocalIndicesImpl(lclRow, indices, cb);
1972 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1976 const LocalOrdinal numEnt,
1977 const Scalar vals[],
1978 const LocalOrdinal cols[])
1980 Teuchos::ArrayView<const LocalOrdinal> colsT (cols, numEnt);
1981 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
1982 this->insertLocalValues (localRow, colsT, valsT);
1985 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1990 const GlobalOrdinal gblColInds[],
1992 const size_t numInputEnt)
1994 #ifdef HAVE_TPETRA_DEBUG
1995 const char tfecfFuncName[] =
"insertGlobalValuesImpl: ";
1997 const size_t curNumEnt = rowInfo.numEntries;
2000 if (! graph.indicesAreAllocated ()) {
2003 using ::Tpetra::Details::Behavior;
2004 const bool verbose = Behavior::verbose(
"CrsMatrix");
2005 this->allocateValues (GlobalIndices, GraphNotYetAllocated, verbose);
2010 rowInfo = graph.
getRowInfo (rowInfo.localRow);
2013 auto valsView = this->getValuesViewHostNonConst(rowInfo);
2014 auto fun = [&](
size_t const k,
size_t const ,
size_t const offset){
2015 valsView[offset] += vals[k];
2017 std::function<void(
size_t const,
size_t const,
size_t const)> cb(std::ref(fun));
2018 #ifdef HAVE_TPETRA_DEBUG
2024 #ifdef HAVE_TPETRA_DEBUG
2025 size_t newNumEnt = curNumEnt + numInserted;
2026 const size_t chkNewNumEnt =
2028 if (chkNewNumEnt != newNumEnt) {
2029 std::ostringstream os;
2030 os << std::endl <<
"newNumEnt = " << newNumEnt
2031 <<
" != graph.getNumEntriesInLocalRow(" << rowInfo.localRow
2032 <<
") = " << chkNewNumEnt <<
"." << std::endl
2033 <<
"\torigNumEnt: " << origNumEnt << std::endl
2034 <<
"\tnumInputEnt: " << numInputEnt << std::endl
2035 <<
"\tgblColInds: [";
2036 for (
size_t k = 0; k < numInputEnt; ++k) {
2037 os << gblColInds[k];
2038 if (k +
size_t (1) < numInputEnt) {
2042 os <<
"]" << std::endl
2044 for (
size_t k = 0; k < numInputEnt; ++k) {
2046 if (k +
size_t (1) < numInputEnt) {
2050 os <<
"]" << std::endl;
2052 if (this->supportsRowViews ()) {
2053 values_host_view_type vals2;
2054 if (this->isGloballyIndexed ()) {
2055 global_inds_host_view_type gblColInds2;
2056 const GlobalOrdinal gblRow =
2057 graph.
rowMap_->getGlobalElement (rowInfo.localRow);
2059 Tpetra::Details::OrdinalTraits<GlobalOrdinal>::invalid ()) {
2060 os <<
"Local row index " << rowInfo.localRow <<
" is invalid!"
2064 bool getViewThrew =
false;
2066 this->getGlobalRowView (gblRow, gblColInds2, vals2);
2068 catch (std::exception& e) {
2069 getViewThrew =
true;
2070 os <<
"getGlobalRowView threw exception:" << std::endl
2071 << e.what () << std::endl;
2073 if (! getViewThrew) {
2074 os <<
"\tNew global column indices: ";
2075 for (
size_t jjj = 0; jjj < gblColInds2.extent(0); jjj++)
2076 os << gblColInds2[jjj] <<
" ";
2078 os <<
"\tNew values: ";
2079 for (
size_t jjj = 0; jjj < vals2.extent(0); jjj++)
2080 os << vals2[jjj] <<
" ";
2085 else if (this->isLocallyIndexed ()) {
2086 local_inds_host_view_type lclColInds2;
2087 this->getLocalRowView (rowInfo.localRow, lclColInds2, vals2);
2088 os <<
"\tNew local column indices: ";
2089 for (
size_t jjj = 0; jjj < lclColInds2.extent(0); jjj++)
2090 os << lclColInds2[jjj] <<
" ";
2092 os <<
"\tNew values: ";
2093 for (
size_t jjj = 0; jjj < vals2.extent(0); jjj++)
2094 os << vals2[jjj] <<
" ";
2099 os <<
"Please report this bug to the Tpetra developers.";
2100 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2101 (
true, std::logic_error, os.str ());
2106 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2110 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2111 const Teuchos::ArrayView<const Scalar>& values)
2113 using Teuchos::toString;
2116 typedef LocalOrdinal LO;
2117 typedef GlobalOrdinal GO;
2118 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2119 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
2120 const char tfecfFuncName[] =
"insertGlobalValues: ";
2122 #ifdef HAVE_TPETRA_DEBUG
2123 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2124 (values.size () != indices.size (), std::runtime_error,
2125 "values.size() = " << values.size () <<
" != indices.size() = "
2126 << indices.size () <<
".");
2131 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2134 if (lclRow == OTLO::invalid ()) {
2141 this->insertNonownedGlobalValues (gblRow, indices, values);
2144 if (this->isStaticGraph ()) {
2146 const int myRank = rowMap.
getComm ()->getRank ();
2147 const int numProcs = rowMap.
getComm ()->getSize ();
2148 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2149 (
true, std::runtime_error,
2150 "The matrix was constructed with a constant (\"static\") graph, "
2151 "yet the given global row index " << gblRow <<
" is in the row "
2152 "Map on the calling process (with rank " << myRank <<
", of " <<
2153 numProcs <<
" process(es)). In this case, you may not insert "
2154 "new entries into rows owned by the calling process.");
2157 crs_graph_type& graph = * (this->myGraph_);
2158 const IST*
const inputVals =
2159 reinterpret_cast<const IST*
> (values.getRawPtr ());
2160 const GO*
const inputGblColInds = indices.getRawPtr ();
2161 const size_t numInputEnt = indices.size ();
2162 RowInfo rowInfo = graph.getRowInfo (lclRow);
2170 if (! graph.colMap_.is_null ()) {
2171 const map_type& colMap = * (graph.colMap_);
2176 #ifdef HAVE_TPETRA_DEBUG
2177 Teuchos::Array<GO> badColInds;
2179 const size_type numEntriesToInsert = indices.size ();
2180 bool allInColMap =
true;
2181 for (size_type k = 0; k < numEntriesToInsert; ++k) {
2183 allInColMap =
false;
2184 #ifdef HAVE_TPETRA_DEBUG
2185 badColInds.push_back (indices[k]);
2191 if (! allInColMap) {
2192 std::ostringstream os;
2193 os <<
"You attempted to insert entries in owned row " << gblRow
2194 <<
", at the following column indices: " << toString (indices)
2196 #ifdef HAVE_TPETRA_DEBUG
2197 os <<
"Of those, the following indices are not in the column Map "
2198 "on this process: " << toString (badColInds) <<
"." << endl
2199 <<
"Since the matrix has a column Map already, it is invalid "
2200 "to insert entries at those locations.";
2202 os <<
"At least one of those indices is not in the column Map "
2203 "on this process." << endl <<
"It is invalid to insert into "
2204 "columns not in the column Map on the process that owns the "
2207 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2208 (
true, std::invalid_argument, os.str ());
2212 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2213 inputVals, numInputEnt);
2218 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2222 const LocalOrdinal numEnt,
2223 const Scalar vals[],
2224 const GlobalOrdinal inds[])
2226 Teuchos::ArrayView<const GlobalOrdinal> indsT (inds, numEnt);
2227 Teuchos::ArrayView<const Scalar> valsT (vals, numEnt);
2228 this->insertGlobalValues (globalRow, indsT, valsT);
2232 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2236 const GlobalOrdinal gblRow,
2237 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2238 const Teuchos::ArrayView<const Scalar>& values,
2242 typedef LocalOrdinal LO;
2243 typedef GlobalOrdinal GO;
2244 typedef Tpetra::Details::OrdinalTraits<LO> OTLO;
2245 const char tfecfFuncName[] =
"insertGlobalValuesFiltered: ";
2248 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2249 (values.size () != indices.size (), std::runtime_error,
2250 "values.size() = " << values.size () <<
" != indices.size() = "
2251 << indices.size () <<
".");
2256 const map_type& rowMap = * (this->getCrsGraphRef ().rowMap_);
2258 if (lclRow == OTLO::invalid ()) {
2265 this->insertNonownedGlobalValues (gblRow, indices, values);
2268 if (this->isStaticGraph ()) {
2270 const int myRank = rowMap.getComm ()->getRank ();
2271 const int numProcs = rowMap.getComm ()->getSize ();
2272 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2273 (
true, std::runtime_error,
2274 "The matrix was constructed with a constant (\"static\") graph, "
2275 "yet the given global row index " << gblRow <<
" is in the row "
2276 "Map on the calling process (with rank " << myRank <<
", of " <<
2277 numProcs <<
" process(es)). In this case, you may not insert "
2278 "new entries into rows owned by the calling process.");
2281 crs_graph_type& graph = * (this->myGraph_);
2282 const IST*
const inputVals =
2283 reinterpret_cast<const IST*
> (values.getRawPtr ());
2284 const GO*
const inputGblColInds = indices.getRawPtr ();
2285 const size_t numInputEnt = indices.size ();
2286 RowInfo rowInfo = graph.getRowInfo (lclRow);
2288 if (!graph.colMap_.is_null() && graph.isLocallyIndexed()) {
2295 const map_type& colMap = * (graph.colMap_);
2296 size_t curOffset = 0;
2297 while (curOffset < numInputEnt) {
2301 Teuchos::Array<LO> lclIndices;
2302 size_t endOffset = curOffset;
2303 for ( ; endOffset < numInputEnt; ++endOffset) {
2305 if (lclIndex != OTLO::invalid())
2306 lclIndices.push_back(lclIndex);
2313 const LO numIndInSeq = (endOffset - curOffset);
2314 if (numIndInSeq != 0) {
2315 this->insertLocalValues(lclRow, lclIndices(), values(curOffset, numIndInSeq));
2321 const bool invariant = endOffset == numInputEnt ||
2322 colMap.
getLocalElement (inputGblColInds[endOffset]) == OTLO::invalid ();
2323 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2324 (! invariant, std::logic_error, std::endl <<
"Invariant failed!");
2326 curOffset = endOffset + 1;
2329 else if (! graph.colMap_.is_null ()) {
2331 size_t curOffset = 0;
2332 while (curOffset < numInputEnt) {
2336 size_t endOffset = curOffset;
2337 for ( ; endOffset < numInputEnt &&
2338 colMap.
getLocalElement (inputGblColInds[endOffset]) != OTLO::invalid ();
2344 const LO numIndInSeq = (endOffset - curOffset);
2345 if (numIndInSeq != 0) {
2346 rowInfo = graph.getRowInfo(lclRow);
2347 this->insertGlobalValuesImpl (graph, rowInfo,
2348 inputGblColInds + curOffset,
2349 inputVals + curOffset,
2356 const bool invariant = endOffset == numInputEnt ||
2357 colMap.
getLocalElement (inputGblColInds[endOffset]) == OTLO::invalid ();
2358 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
2359 (! invariant, std::logic_error, std::endl <<
"Invariant failed!");
2361 curOffset = endOffset + 1;
2365 this->insertGlobalValuesImpl (graph, rowInfo, inputGblColInds,
2366 inputVals, numInputEnt);
2371 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2375 const GlobalOrdinal gblRow,
2376 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
2377 const Teuchos::ArrayView<const Scalar>& values,
2378 const char*
const prefix,
2386 insertGlobalValuesFiltered(gblRow, indices, values, debug);
2388 catch(std::exception& e) {
2389 std::ostringstream os;
2391 const size_t maxNumToPrint =
2393 os << *prefix <<
": insertGlobalValuesFiltered threw an "
2394 "exception: " << e.what() << endl
2395 <<
"Global row index: " << gblRow << endl;
2403 os <<
": insertGlobalValuesFiltered threw an exception: "
2406 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, os.str());
2410 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2416 const LocalOrdinal inds[],
2418 const LocalOrdinal numElts)
2420 typedef LocalOrdinal LO;
2421 typedef GlobalOrdinal GO;
2422 const bool sorted = graph.
isSorted ();
2432 for (LO j = 0; j < numElts; ++j) {
2433 const LO lclColInd = inds[j];
2434 const size_t offset =
2435 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2436 lclColInd, hint, sorted);
2437 if (offset != rowInfo.numEntries) {
2438 rowVals[offset] = newVals[j];
2445 if (graph.
colMap_.is_null ()) {
2446 return Teuchos::OrdinalTraits<LO>::invalid ();
2448 const map_type colMap = * (graph.
colMap_);
2454 for (LO j = 0; j < numElts; ++j) {
2455 const GO gblColInd = colMap.getGlobalElement (inds[j]);
2456 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
2457 const size_t offset =
2458 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2459 gblColInd, hint, sorted);
2460 if (offset != rowInfo.numEntries) {
2461 rowVals[offset] = newVals[j];
2480 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2484 const Teuchos::ArrayView<const LocalOrdinal>& lclCols,
2485 const Teuchos::ArrayView<const Scalar>& vals)
2487 typedef LocalOrdinal LO;
2489 const LO numInputEnt =
static_cast<LO
> (lclCols.size ());
2490 if (
static_cast<LO
> (vals.size ()) != numInputEnt) {
2491 return Teuchos::OrdinalTraits<LO>::invalid ();
2493 const LO*
const inputInds = lclCols.getRawPtr ();
2494 const Scalar*
const inputVals = vals.getRawPtr ();
2495 return this->replaceLocalValues (localRow, numInputEnt,
2496 inputVals, inputInds);
2499 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2505 const Kokkos::View<const local_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
2506 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals)
2509 const LO numInputEnt = inputInds.extent(0);
2510 if (numInputEnt !=
static_cast<LO
>(inputVals.extent(0))) {
2511 return Teuchos::OrdinalTraits<LO>::invalid();
2513 const Scalar*
const inVals =
2514 reinterpret_cast<const Scalar*
>(inputVals.data());
2515 return this->replaceLocalValues(localRow, numInputEnt,
2516 inVals, inputInds.data());
2519 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2523 const LocalOrdinal numEnt,
2524 const Scalar inputVals[],
2525 const LocalOrdinal inputCols[])
2528 typedef LocalOrdinal LO;
2530 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2532 return Teuchos::OrdinalTraits<LO>::invalid ();
2537 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2540 return static_cast<LO
> (0);
2542 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
2543 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2544 return this->replaceLocalValuesImpl (curRowVals.data (), graph, rowInfo,
2545 inputCols, inVals, numEnt);
2548 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2554 const GlobalOrdinal inds[],
2556 const LocalOrdinal numElts)
2558 Teuchos::ArrayView<const GlobalOrdinal> indsT(inds, numElts);
2560 [&](
size_t const k,
size_t const ,
size_t const offset) {
2561 rowVals[offset] = newVals[k];
2563 std::function<void(
size_t const,
size_t const,
size_t const)> cb(std::ref(fun));
2567 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2571 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2572 const Teuchos::ArrayView<const Scalar>& inputVals)
2574 typedef LocalOrdinal LO;
2576 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2577 if (
static_cast<LO
> (inputVals.size ()) != numInputEnt) {
2578 return Teuchos::OrdinalTraits<LO>::invalid ();
2580 return this->replaceGlobalValues (globalRow, numInputEnt,
2581 inputVals.getRawPtr (),
2582 inputGblColInds.getRawPtr ());
2585 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2589 const LocalOrdinal numEnt,
2590 const Scalar inputVals[],
2591 const GlobalOrdinal inputGblColInds[])
2594 typedef LocalOrdinal LO;
2596 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2598 return Teuchos::OrdinalTraits<LO>::invalid ();
2603 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2606 return static_cast<LO
> (0);
2609 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
2610 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2611 return this->replaceGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2612 inputGblColInds, inVals, numEnt);
2615 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2621 const Kokkos::View<const global_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
2622 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals)
2631 const LO numInputEnt =
static_cast<LO
>(inputInds.extent(0));
2632 if (
static_cast<LO
>(inputVals.extent(0)) != numInputEnt) {
2633 return Teuchos::OrdinalTraits<LO>::invalid();
2635 const Scalar*
const inVals =
2636 reinterpret_cast<const Scalar*
>(inputVals.data());
2637 return this->replaceGlobalValues(globalRow, numInputEnt, inVals,
2641 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2647 const GlobalOrdinal inds[],
2649 const LocalOrdinal numElts,
2652 typedef LocalOrdinal LO;
2653 typedef GlobalOrdinal GO;
2655 const bool sorted = graph.
isSorted ();
2664 if (graph.
colMap_.is_null ()) {
2675 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
2677 for (LO j = 0; j < numElts; ++j) {
2679 if (lclColInd != LINV) {
2680 const size_t offset =
2681 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2682 lclColInd, hint, sorted);
2683 if (offset != rowInfo.numEntries) {
2685 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2688 rowVals[offset] += newVals[j];
2701 for (LO j = 0; j < numElts; ++j) {
2702 const GO gblColInd = inds[j];
2703 const size_t offset =
2704 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2705 gblColInd, hint, sorted);
2706 if (offset != rowInfo.numEntries) {
2708 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
2711 rowVals[offset] += newVals[j];
2725 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2729 const Teuchos::ArrayView<const GlobalOrdinal>& inputGblColInds,
2730 const Teuchos::ArrayView<const Scalar>& inputVals,
2733 typedef LocalOrdinal LO;
2735 const LO numInputEnt =
static_cast<LO
> (inputGblColInds.size ());
2736 if (
static_cast<LO
> (inputVals.size ()) != numInputEnt) {
2737 return Teuchos::OrdinalTraits<LO>::invalid ();
2739 return this->sumIntoGlobalValues (gblRow, numInputEnt,
2740 inputVals.getRawPtr (),
2741 inputGblColInds.getRawPtr (),
2745 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2749 const LocalOrdinal numInputEnt,
2750 const Scalar inputVals[],
2751 const GlobalOrdinal inputGblColInds[],
2755 typedef LocalOrdinal LO;
2756 typedef GlobalOrdinal GO;
2758 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2760 return Teuchos::OrdinalTraits<LO>::invalid ();
2765 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2770 using Teuchos::ArrayView;
2771 ArrayView<const GO> inputGblColInds_av(
2772 numInputEnt == 0 ?
nullptr : inputGblColInds,
2774 ArrayView<const Scalar> inputVals_av(
2775 numInputEnt == 0 ?
nullptr :
2776 inputVals, numInputEnt);
2781 this->insertNonownedGlobalValues (gblRow, inputGblColInds_av,
2792 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
2793 const IST*
const inVals =
reinterpret_cast<const IST*
> (inputVals);
2794 return this->sumIntoGlobalValuesImpl (curRowVals.data (), graph, rowInfo,
2795 inputGblColInds, inVals,
2796 numInputEnt, atomic);
2800 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2802 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2803 transformLocalValues (
const LocalOrdinal lclRow,
2804 const LocalOrdinal numInputEnt,
2805 const impl_scalar_type inputVals[],
2806 const LocalOrdinal inputCols[],
2807 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2810 using Tpetra::Details::OrdinalTraits;
2811 typedef LocalOrdinal LO;
2813 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2815 return Teuchos::OrdinalTraits<LO>::invalid ();
2817 const crs_graph_type& graph = * (this->staticGraph_);
2818 const RowInfo rowInfo = graph.getRowInfo (lclRow);
2820 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2823 return static_cast<LO
> (0);
2825 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
2826 return this->transformLocalValues (curRowVals.data (), graph,
2827 rowInfo, inputCols, inputVals,
2828 numInputEnt, f, atomic);
2831 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2833 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2834 transformGlobalValues (
const GlobalOrdinal gblRow,
2835 const LocalOrdinal numInputEnt,
2836 const impl_scalar_type inputVals[],
2837 const GlobalOrdinal inputCols[],
2838 std::function<impl_scalar_type (
const impl_scalar_type&,
const impl_scalar_type&) > f,
2841 using Tpetra::Details::OrdinalTraits;
2842 typedef LocalOrdinal LO;
2844 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
2846 return OrdinalTraits<LO>::invalid ();
2851 if (rowInfo.localRow == OrdinalTraits<size_t>::invalid ()) {
2854 return static_cast<LO
> (0);
2856 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
2857 return this->transformGlobalValues (curRowVals.data (), graph,
2858 rowInfo, inputCols, inputVals,
2859 numInputEnt, f, atomic);
2862 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2868 const LocalOrdinal inds[],
2870 const LocalOrdinal numElts,
2875 typedef LocalOrdinal LO;
2876 typedef GlobalOrdinal GO;
2883 const bool sorted = graph.
isSorted ();
2893 for (LO j = 0; j < numElts; ++j) {
2894 const LO lclColInd = inds[j];
2895 const size_t offset =
2896 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2897 lclColInd, hint, sorted);
2898 if (offset != rowInfo.numEntries) {
2907 volatile ST*
const dest = &rowVals[offset];
2908 (void) atomic_binary_function_update (dest, newVals[j], f);
2912 rowVals[offset] = f (rowVals[offset], newVals[j]);
2923 if (graph.
colMap_.is_null ()) {
2930 const map_type& colMap = * (graph.
colMap_);
2935 const GO GINV = Teuchos::OrdinalTraits<GO>::invalid ();
2936 for (LO j = 0; j < numElts; ++j) {
2937 const GO gblColInd = colMap.getGlobalElement (inds[j]);
2938 if (gblColInd != GINV) {
2939 const size_t offset =
2940 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
2941 gblColInd, hint, sorted);
2942 if (offset != rowInfo.numEntries) {
2951 volatile ST*
const dest = &rowVals[offset];
2952 (void) atomic_binary_function_update (dest, newVals[j], f);
2956 rowVals[offset] = f (rowVals[offset], newVals[j]);
2971 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2973 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
2977 const GlobalOrdinal inds[],
2979 const LocalOrdinal numElts,
2984 typedef LocalOrdinal LO;
2985 typedef GlobalOrdinal GO;
2992 const bool sorted = graph.
isSorted ();
3002 for (LO j = 0; j < numElts; ++j) {
3003 const GO gblColInd = inds[j];
3004 const size_t offset =
3005 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3006 gblColInd, hint, sorted);
3007 if (offset != rowInfo.numEntries) {
3016 volatile ST*
const dest = &rowVals[offset];
3017 (void) atomic_binary_function_update (dest, newVals[j], f);
3021 rowVals[offset] = f (rowVals[offset], newVals[j]);
3032 if (graph.
colMap_.is_null ()) {
3038 const map_type& colMap = * (graph.
colMap_);
3043 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid ();
3044 for (LO j = 0; j < numElts; ++j) {
3045 const LO lclColInd = colMap.getLocalElement (inds[j]);
3046 if (lclColInd != LINV) {
3047 const size_t offset =
3048 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3049 lclColInd, hint, sorted);
3050 if (offset != rowInfo.numEntries) {
3059 volatile ST*
const dest = &rowVals[offset];
3060 (void) atomic_binary_function_update (dest, newVals[j], f);
3064 rowVals[offset] = f (rowVals[offset], newVals[j]);
3079 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3085 const LocalOrdinal inds[],
3087 const LocalOrdinal numElts,
3090 typedef LocalOrdinal LO;
3091 typedef GlobalOrdinal GO;
3093 const bool sorted = graph.
isSorted ();
3103 for (LO j = 0; j < numElts; ++j) {
3104 const LO lclColInd = inds[j];
3105 const size_t offset =
3106 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3107 lclColInd, hint, sorted);
3108 if (offset != rowInfo.numEntries) {
3110 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3113 rowVals[offset] += newVals[j];
3121 if (graph.
colMap_.is_null ()) {
3122 return Teuchos::OrdinalTraits<LO>::invalid ();
3130 for (LO j = 0; j < numElts; ++j) {
3132 if (gblColInd != Teuchos::OrdinalTraits<GO>::invalid ()) {
3133 const size_t offset =
3134 KokkosSparse::findRelOffset (colInds, rowInfo.numEntries,
3135 gblColInd, hint, sorted);
3136 if (offset != rowInfo.numEntries) {
3138 Kokkos::atomic_add (&rowVals[offset], newVals[j]);
3141 rowVals[offset] += newVals[j];
3161 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3165 const Teuchos::ArrayView<const LocalOrdinal>& indices,
3166 const Teuchos::ArrayView<const Scalar>& values,
3170 const LO numInputEnt =
static_cast<LO
>(indices.size());
3171 if (
static_cast<LO
>(values.size()) != numInputEnt) {
3172 return Teuchos::OrdinalTraits<LO>::invalid();
3174 const LO*
const inputInds = indices.getRawPtr();
3175 const scalar_type*
const inputVals = values.getRawPtr();
3176 return this->sumIntoLocalValues(localRow, numInputEnt,
3177 inputVals, inputInds, atomic);
3180 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3186 const Kokkos::View<const local_ordinal_type*, Kokkos::AnonymousSpace>& inputInds,
3187 const Kokkos::View<const impl_scalar_type*, Kokkos::AnonymousSpace>& inputVals,
3191 const LO numInputEnt =
static_cast<LO
>(inputInds.extent(0));
3192 if (
static_cast<LO
>(inputVals.extent(0)) != numInputEnt) {
3193 return Teuchos::OrdinalTraits<LO>::invalid();
3196 reinterpret_cast<const scalar_type*
>(inputVals.data());
3197 return this->sumIntoLocalValues(localRow, numInputEnt, inVals,
3198 inputInds.data(), atomic);
3201 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3205 const LocalOrdinal numEnt,
3206 const Scalar vals[],
3207 const LocalOrdinal cols[],
3211 typedef LocalOrdinal LO;
3213 if (! this->isFillActive () || this->staticGraph_.is_null ()) {
3215 return Teuchos::OrdinalTraits<LO>::invalid ();
3220 if (rowInfo.localRow == Teuchos::OrdinalTraits<size_t>::invalid ()) {
3223 return static_cast<LO
> (0);
3225 auto curRowVals = this->getValuesViewHostNonConst (rowInfo);
3226 const IST*
const inputVals =
reinterpret_cast<const IST*
> (vals);
3227 return this->sumIntoLocalValuesImpl (curRowVals.data (), graph, rowInfo,
3228 cols, inputVals, numEnt, atomic);
3231 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3233 values_dualv_type::t_host::const_type
3237 if (rowinfo.allocSize == 0 || valuesUnpacked_wdv.extent(0) == 0)
3238 return typename values_dualv_type::t_host::const_type ();
3240 return valuesUnpacked_wdv.getHostSubview(rowinfo.offset1D,
3245 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3247 values_dualv_type::t_host
3251 if (rowinfo.allocSize == 0 || valuesUnpacked_wdv.extent(0) == 0)
3252 return typename values_dualv_type::t_host ();
3254 return valuesUnpacked_wdv.getHostSubview(rowinfo.offset1D,
3259 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3261 values_dualv_type::t_dev::const_type
3265 if (rowinfo.allocSize == 0 || valuesUnpacked_wdv.extent(0) == 0)
3266 return typename values_dualv_type::t_dev::const_type ();
3268 return valuesUnpacked_wdv.getDeviceSubview(rowinfo.offset1D,
3273 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3275 values_dualv_type::t_dev
3279 if (rowinfo.allocSize == 0 || valuesUnpacked_wdv.extent(0) == 0)
3280 return typename values_dualv_type::t_dev ();
3282 return valuesUnpacked_wdv.getDeviceSubview(rowinfo.offset1D,
3287 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3288 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3289 Teuchos::ArrayView<const typename CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::impl_scalar_type>
3293 using Kokkos::MemoryUnmanaged;
3295 using Teuchos::ArrayView;
3296 using ST = impl_scalar_type;
3297 using range_type = std::pair<size_t, size_t>;
3299 if (valuesUnpacked_wdv.extent (0) != 0 && rowinfo.allocSize > 0) {
3301 #ifdef HAVE_TPETRA_DEBUG
3302 TEUCHOS_TEST_FOR_EXCEPTION(
3303 rowinfo.offset1D + rowinfo.allocSize > valuesUnpacked_wdv.extent (0),
3304 std::range_error,
"Tpetra::CrsMatrix::getView: Invalid access "
3305 "to 1-D storage of values." << std::endl <<
"rowinfo.offset1D (" <<
3306 rowinfo.offset1D <<
") + rowinfo.allocSize (" << rowinfo.allocSize <<
3307 ") > valuesUnpacked_wdv.extent(0) (" << valuesUnpacked_wdv.extent (0)
3311 range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize);
3319 auto sv = valuesUnpacked_wdv.getHostSubview(rowinfo.offset1D,
3322 const ST*
const sv_raw = (rowinfo.allocSize == 0) ?
nullptr : sv.data ();
3323 return ArrayView<const ST> (sv_raw, rowinfo.allocSize);
3326 return ArrayView<impl_scalar_type> ();
3332 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3336 nonconst_local_inds_host_view_type &indices,
3337 nonconst_values_host_view_type &values,
3338 size_t& numEntries)
const
3340 using Teuchos::ArrayView;
3341 using Teuchos::av_reinterpret_cast;
3342 const char tfecfFuncName[] =
"getLocalRowCopy: ";
3344 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3345 (! this->hasColMap (), std::runtime_error,
3346 "The matrix does not have a column Map yet. This means we don't have "
3347 "local indices for columns yet, so it doesn't make sense to call this "
3348 "method. If the matrix doesn't have a column Map yet, you should call "
3349 "fillComplete on it first.");
3351 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3352 const size_t theNumEntries = rowinfo.numEntries;
3353 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3354 (
static_cast<size_t> (indices.size ()) < theNumEntries ||
3355 static_cast<size_t> (values.size ()) < theNumEntries,
3356 std::runtime_error,
"Row with local index " << localRow <<
" has " <<
3357 theNumEntries <<
" entry/ies, but indices.size() = " <<
3358 indices.size () <<
" and values.size() = " << values.size () <<
".");
3359 numEntries = theNumEntries;
3361 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3362 if (staticGraph_->isLocallyIndexed ()) {
3363 auto curLclInds = staticGraph_->getLocalIndsViewHost(rowinfo);
3364 auto curVals = getValuesViewHost(rowinfo);
3366 for (
size_t j = 0; j < theNumEntries; ++j) {
3367 values[j] = curVals[j];
3368 indices[j] = curLclInds(j);
3371 else if (staticGraph_->isGloballyIndexed ()) {
3373 const map_type& colMap = * (staticGraph_->colMap_);
3374 auto curGblInds = staticGraph_->getGlobalIndsViewHost(rowinfo);
3375 auto curVals = getValuesViewHost(rowinfo);
3377 for (
size_t j = 0; j < theNumEntries; ++j) {
3378 values[j] = curVals[j];
3385 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3386 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3390 const Teuchos::ArrayView<LocalOrdinal>& indices,
3391 const Teuchos::ArrayView<Scalar>& values,
3392 size_t& numEntries)
const
3394 using Teuchos::ArrayView;
3395 using Teuchos::av_reinterpret_cast;
3396 const char tfecfFuncName[] =
"getLocalRowCopy: ";
3398 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3399 (! this->hasColMap (), std::runtime_error,
3400 "The matrix does not have a column Map yet. This means we don't have "
3401 "local indices for columns yet, so it doesn't make sense to call this "
3402 "method. If the matrix doesn't have a column Map yet, you should call "
3403 "fillComplete on it first.");
3405 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3406 const size_t theNumEntries = rowinfo.numEntries;
3407 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3408 (
static_cast<size_t> (indices.size ()) < theNumEntries ||
3409 static_cast<size_t> (values.size ()) < theNumEntries,
3410 std::runtime_error,
"Row with local index " << localRow <<
" has " <<
3411 theNumEntries <<
" entry/ies, but indices.size() = " <<
3412 indices.size () <<
" and values.size() = " << values.size () <<
".");
3413 numEntries = theNumEntries;
3415 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3416 if (staticGraph_->isLocallyIndexed ()) {
3417 auto curLclInds = staticGraph_->getLocalIndsViewHost(rowinfo);
3418 auto curVals = getValuesViewHost(rowinfo);
3420 for (
size_t j = 0; j < theNumEntries; ++j) {
3421 values[j] = curVals[j];
3422 indices[j] = curLclInds(j);
3425 else if (staticGraph_->isGloballyIndexed ()) {
3427 const map_type& colMap = * (staticGraph_->colMap_);
3428 auto curGblInds = staticGraph_->getGlobalIndsViewHost(rowinfo);
3429 auto curVals = getValuesViewHost(rowinfo);
3431 for (
size_t j = 0; j < theNumEntries; ++j) {
3432 values[j] = curVals[j];
3433 indices[j] = colMap.getLocalElement (curGblInds(j));
3440 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3444 nonconst_global_inds_host_view_type &indices,
3445 nonconst_values_host_view_type &values,
3446 size_t& numEntries)
const
3448 using Teuchos::ArrayView;
3449 using Teuchos::av_reinterpret_cast;
3450 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
3453 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3454 const size_t theNumEntries = rowinfo.numEntries;
3455 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3456 static_cast<size_t> (indices.size ()) < theNumEntries ||
3457 static_cast<size_t> (values.size ()) < theNumEntries,
3458 std::runtime_error,
"Row with global index " << globalRow <<
" has "
3459 << theNumEntries <<
" entry/ies, but indices.size() = " <<
3460 indices.size () <<
" and values.size() = " << values.size () <<
".");
3461 numEntries = theNumEntries;
3463 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3464 if (staticGraph_->isLocallyIndexed ()) {
3465 const map_type& colMap = * (staticGraph_->colMap_);
3466 auto curLclInds = staticGraph_->getLocalIndsViewHost(rowinfo);
3467 auto curVals = getValuesViewHost(rowinfo);
3469 for (
size_t j = 0; j < theNumEntries; ++j) {
3470 values[j] = curVals[j];
3474 else if (staticGraph_->isGloballyIndexed ()) {
3475 auto curGblInds = staticGraph_->getGlobalIndsViewHost(rowinfo);
3476 auto curVals = getValuesViewHost(rowinfo);
3478 for (
size_t j = 0; j < theNumEntries; ++j) {
3479 values[j] = curVals[j];
3480 indices[j] = curGblInds(j);
3486 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3487 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3491 const Teuchos::ArrayView<GlobalOrdinal>& indices,
3492 const Teuchos::ArrayView<Scalar>& values,
3493 size_t& numEntries)
const
3495 using Teuchos::ArrayView;
3496 using Teuchos::av_reinterpret_cast;
3497 const char tfecfFuncName[] =
"getGlobalRowCopy: ";
3500 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3501 const size_t theNumEntries = rowinfo.numEntries;
3502 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3503 static_cast<size_t> (indices.size ()) < theNumEntries ||
3504 static_cast<size_t> (values.size ()) < theNumEntries,
3505 std::runtime_error,
"Row with global index " << globalRow <<
" has "
3506 << theNumEntries <<
" entry/ies, but indices.size() = " <<
3507 indices.size () <<
" and values.size() = " << values.size () <<
".");
3508 numEntries = theNumEntries;
3510 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid ()) {
3511 if (staticGraph_->isLocallyIndexed ()) {
3512 const map_type& colMap = * (staticGraph_->colMap_);
3513 auto curLclInds = staticGraph_->getLocalIndsViewHost(rowinfo);
3514 auto curVals = getValuesViewHost(rowinfo);
3516 for (
size_t j = 0; j < theNumEntries; ++j) {
3517 values[j] = curVals[j];
3521 else if (staticGraph_->isGloballyIndexed ()) {
3522 auto curGblInds = staticGraph_->getGlobalIndsViewHost(rowinfo);
3523 auto curVals = getValuesViewHost(rowinfo);
3525 for (
size_t j = 0; j < theNumEntries; ++j) {
3526 values[j] = curVals[j];
3527 indices[j] = curGblInds(j);
3534 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3538 local_inds_host_view_type &indices,
3539 values_host_view_type &values)
const
3541 const char tfecfFuncName[] =
"getLocalRowView: ";
3543 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3544 isGloballyIndexed (), std::runtime_error,
"The matrix currently stores "
3545 "its indices as global indices, so you cannot get a view with local "
3546 "column indices. If the matrix has a column Map, you may call "
3547 "getLocalRowCopy() to get local column indices; otherwise, you may get "
3548 "a view with global column indices by calling getGlobalRowCopy().");
3550 const RowInfo rowInfo = staticGraph_->getRowInfo (localRow);
3551 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3552 rowInfo.numEntries > 0) {
3553 indices = staticGraph_->lclIndsUnpacked_wdv.getHostSubview(
3557 values = valuesUnpacked_wdv.getHostSubview(rowInfo.offset1D,
3564 indices = local_inds_host_view_type();
3565 values = values_host_view_type();
3568 #ifdef HAVE_TPETRA_DEBUG
3569 const char suffix[] =
". This should never happen. Please report this "
3570 "bug to the Tpetra developers.";
3571 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3572 (
static_cast<size_t> (indices.size ()) !=
3573 static_cast<size_t> (values.size ()), std::logic_error,
3574 "At the end of this method, for local row " << localRow <<
", "
3575 "indices.size() = " << indices.size () <<
" != values.size () = "
3576 << values.size () << suffix);
3577 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3578 (
static_cast<size_t> (indices.size ()) !=
3579 static_cast<size_t> (rowInfo.numEntries), std::logic_error,
3580 "At the end of this method, for local row " << localRow <<
", "
3581 "indices.size() = " << indices.size () <<
" != rowInfo.numEntries = "
3582 << rowInfo.numEntries << suffix);
3583 const size_t expectedNumEntries = getNumEntriesInLocalRow (localRow);
3584 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3585 (rowInfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3586 "of this method, for local row " << localRow <<
", rowInfo.numEntries = "
3587 << rowInfo.numEntries <<
" != getNumEntriesInLocalRow(localRow) = " <<
3588 expectedNumEntries << suffix);
3592 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3593 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3597 Teuchos::ArrayView<const LocalOrdinal>& indices,
3598 Teuchos::ArrayView<const Scalar>& values)
const
3600 using Teuchos::ArrayView;
3601 using Teuchos::av_reinterpret_cast;
3602 typedef LocalOrdinal LO;
3603 const char tfecfFuncName[] =
"getLocalRowView: ";
3605 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3606 isGloballyIndexed (), std::runtime_error,
"The matrix currently stores "
3607 "its indices as global indices, so you cannot get a view with local "
3608 "column indices. If the matrix has a column Map, you may call "
3609 "getLocalRowCopy() to get local column indices; otherwise, you may get "
3610 "a view with global column indices by calling getGlobalRowCopy().");
3611 indices = Teuchos::null;
3612 values = Teuchos::null;
3613 const RowInfo rowinfo = staticGraph_->getRowInfo (localRow);
3614 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3615 rowinfo.numEntries > 0) {
3616 ArrayView<const LO> indTmp = staticGraph_->getLocalView (rowinfo);
3617 ArrayView<const Scalar> valTmp =
3618 av_reinterpret_cast<const Scalar> (this->getView (rowinfo));
3619 indices = indTmp (0, rowinfo.numEntries);
3620 values = valTmp (0, rowinfo.numEntries);
3623 #ifdef HAVE_TPETRA_DEBUG
3624 const char suffix[] =
". This should never happen. Please report this "
3625 "bug to the Tpetra developers.";
3626 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3627 (
static_cast<size_t> (indices.size ()) !=
3628 static_cast<size_t> (values.size ()), std::logic_error,
3629 "At the end of this method, for local row " << localRow <<
", "
3630 "indices.size() = " << indices.size () <<
" != values.size () = "
3631 << values.size () << suffix);
3632 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3633 (
static_cast<size_t> (indices.size ()) !=
3634 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3635 "At the end of this method, for local row " << localRow <<
", "
3636 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3637 << rowinfo.numEntries << suffix);
3638 const size_t expectedNumEntries = getNumEntriesInLocalRow (localRow);
3639 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3640 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3641 "of this method, for local row " << localRow <<
", rowinfo.numEntries = "
3642 << rowinfo.numEntries <<
" != getNumEntriesInLocalRow(localRow) = " <<
3643 expectedNumEntries << suffix);
3648 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3649 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3653 LocalOrdinal& numEnt,
3654 const impl_scalar_type*& val,
3655 const LocalOrdinal*& ind)
const
3657 typedef LocalOrdinal LO;
3664 if (staticGraph_.is_null () || staticGraph_->isGloballyIndexed ()) {
3665 return Tpetra::Details::OrdinalTraits<LO>::invalid ();
3668 const RowInfo rowInfo = staticGraph_->getRowInfo (lclRow);
3669 if (rowInfo.localRow == Tpetra::Details::OrdinalTraits<size_t>::invalid ()) {
3674 return static_cast<LO
> (1);
3677 numEnt =
static_cast<LO
> (rowInfo.numEntries);
3678 auto lclColInds = staticGraph_->getLocalIndsViewHost (rowInfo);
3680 ind = lclColInds.data ();
3682 auto values = getValuesViewHost (rowInfo);
3684 val = values.data();
3685 return values.extent(0);
3691 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3692 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3694 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
3695 getLocalRowViewRaw (
const LocalOrdinal lclRow,
3696 LocalOrdinal& numEnt,
3697 const LocalOrdinal*& lclColInds,
3698 const Scalar*& vals)
const
3700 const impl_scalar_type* vals_ist =
nullptr;
3701 const LocalOrdinal errCode =
3702 this->getLocalRowView (lclRow, numEnt, vals_ist, lclColInds);
3703 vals =
reinterpret_cast<const Scalar*
> (vals_ist);
3708 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3712 global_inds_host_view_type &indices,
3713 values_host_view_type &values)
const
3715 const char tfecfFuncName[] =
"getGlobalRowView: ";
3717 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3718 isLocallyIndexed (), std::runtime_error,
3719 "The matrix is locally indexed, so we cannot return a view of the row "
3720 "with global column indices. Use getGlobalRowCopy() instead.");
3725 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3726 if (rowInfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3727 rowInfo.numEntries > 0) {
3728 indices = staticGraph_->gblInds_wdv.getHostSubview(rowInfo.offset1D,
3731 values = valuesUnpacked_wdv.getHostSubview(rowInfo.offset1D,
3736 indices = global_inds_host_view_type();
3737 values = values_host_view_type();
3740 #ifdef HAVE_TPETRA_DEBUG
3741 const char suffix[] =
". This should never happen. Please report this "
3742 "bug to the Tpetra developers.";
3743 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3744 (
static_cast<size_t> (indices.size ()) !=
3745 static_cast<size_t> (values.size ()), std::logic_error,
3746 "At the end of this method, for global row " << globalRow <<
", "
3747 "indices.size() = " << indices.size () <<
" != values.size () = "
3748 << values.size () << suffix);
3749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3750 (
static_cast<size_t> (indices.size ()) !=
3751 static_cast<size_t> (rowInfo.numEntries), std::logic_error,
3752 "At the end of this method, for global row " << globalRow <<
", "
3753 "indices.size() = " << indices.size () <<
" != rowInfo.numEntries = "
3754 << rowInfo.numEntries << suffix);
3755 const size_t expectedNumEntries = getNumEntriesInGlobalRow (globalRow);
3756 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3757 (rowInfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3758 "of this method, for global row " << globalRow <<
", rowInfo.numEntries "
3759 "= " << rowInfo.numEntries <<
" != getNumEntriesInGlobalRow(globalRow) ="
3760 " " << expectedNumEntries << suffix);
3764 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
3765 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3769 Teuchos::ArrayView<const GlobalOrdinal>& indices,
3770 Teuchos::ArrayView<const Scalar>& values)
const
3772 using Teuchos::ArrayView;
3773 using Teuchos::av_reinterpret_cast;
3774 typedef GlobalOrdinal GO;
3775 const char tfecfFuncName[] =
"getGlobalRowView: ";
3777 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3778 isLocallyIndexed (), std::runtime_error,
3779 "The matrix is locally indexed, so we cannot return a view of the row "
3780 "with global column indices. Use getGlobalRowCopy() instead.");
3781 indices = Teuchos::null;
3782 values = Teuchos::null;
3784 staticGraph_->getRowInfoFromGlobalRowIndex (globalRow);
3785 if (rowinfo.localRow != Teuchos::OrdinalTraits<size_t>::invalid () &&
3786 rowinfo.numEntries > 0) {
3787 ArrayView<const GO> indTmp = staticGraph_->getGlobalView (rowinfo);
3788 ArrayView<const Scalar> valTmp =
3789 av_reinterpret_cast<const Scalar> (this->getView (rowinfo));
3790 #ifdef HAVE_TPETRA_DEBUG
3791 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3792 (
static_cast<size_t> (indTmp.size ()) < rowinfo.numEntries ||
3793 static_cast<size_t> (valTmp.size ()) < rowinfo.numEntries,
3794 std::logic_error, std::endl <<
"rowinfo.numEntries not accurate. "
3795 << std::endl <<
"indTmp.size() = " << indTmp.size ()
3796 <<
", valTmp.size() = " << valTmp.size ()
3797 <<
", rowinfo.numEntries = " << rowinfo.numEntries <<
".");
3799 indices = indTmp (0, rowinfo.numEntries);
3800 values = valTmp (0, rowinfo.numEntries);
3803 #ifdef HAVE_TPETRA_DEBUG
3804 const char suffix[] =
". This should never happen. Please report this "
3805 "bug to the Tpetra developers.";
3806 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3807 (
static_cast<size_t> (indices.size ()) !=
3808 static_cast<size_t> (values.size ()), std::logic_error,
3809 "At the end of this method, for global row " << globalRow <<
", "
3810 "indices.size() = " << indices.size () <<
" != values.size () = "
3811 << values.size () << suffix);
3812 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3813 (
static_cast<size_t> (indices.size ()) !=
3814 static_cast<size_t> (rowinfo.numEntries), std::logic_error,
3815 "At the end of this method, for global row " << globalRow <<
", "
3816 "indices.size() = " << indices.size () <<
" != rowinfo.numEntries = "
3817 << rowinfo.numEntries << suffix);
3818 const size_t expectedNumEntries = getNumEntriesInGlobalRow (globalRow);
3819 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3820 (rowinfo.numEntries != expectedNumEntries, std::logic_error,
"At the end "
3821 "of this method, for global row " << globalRow <<
", rowinfo.numEntries "
3822 "= " << rowinfo.numEntries <<
" != getNumEntriesInGlobalRow(globalRow) ="
3823 " " << expectedNumEntries << suffix);
3828 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3831 scale (
const Scalar& alpha)
3833 const char tfecfFuncName[] =
"scale: ";
3836 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3837 ! isFillActive (), std::runtime_error,
3838 "Fill must be active before you may call this method. "
3839 "Please call resumeFill() to make fill active.");
3841 const size_t nlrs = staticGraph_->getNodeNumRows ();
3842 const size_t numEntries = staticGraph_->getNodeNumEntries ();
3843 if (! staticGraph_->indicesAreAllocated () ||
3844 nlrs == 0 || numEntries == 0) {
3849 auto vals = valuesPacked_wdv.getDeviceView(Access::ReadWrite);
3850 KokkosBlas::scal(vals, theAlpha, vals);
3855 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3860 const char tfecfFuncName[] =
"setAllToScalar: ";
3862 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3863 ! isFillActive (), std::runtime_error,
3864 "Fill must be active before you may call this method. "
3865 "Please call resumeFill() to make fill active.");
3871 const size_t numEntries = staticGraph_->getNodeNumEntries();
3872 if (! staticGraph_->indicesAreAllocated () || numEntries == 0) {
3881 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3884 setAllValues (
const typename local_graph_device_type::row_map_type& rowPointers,
3885 const typename local_graph_device_type::entries_type::non_const_type& columnIndices,
3886 const typename local_matrix_device_type::values_type& values)
3888 const char tfecfFuncName[] =
"setAllValues: ";
3889 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3890 (columnIndices.size () != values.size (), std::invalid_argument,
3891 "columnIndices.size() = " << columnIndices.size () <<
" != values.size()"
3892 " = " << values.size () <<
".");
3893 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3894 (myGraph_.is_null (), std::runtime_error,
"myGraph_ must not be null.");
3897 myGraph_->setAllIndices (rowPointers, columnIndices);
3899 catch (std::exception &e) {
3900 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3901 (
true, std::runtime_error,
"myGraph_->setAllIndices() threw an "
3902 "exception: " << e.what ());
3908 auto lclGraph = myGraph_->getLocalGraphDevice ();
3909 const size_t numEnt = lclGraph.entries.extent (0);
3910 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3911 (lclGraph.row_map.extent (0) != rowPointers.extent (0) ||
3912 numEnt !=
static_cast<size_t> (columnIndices.extent (0)),
3913 std::logic_error,
"myGraph_->setAllIndices() did not correctly create "
3914 "local graph. Please report this bug to the Tpetra developers.");
3916 valuesPacked_wdv = values_wdv_type(values);
3917 valuesUnpacked_wdv = valuesPacked_wdv;
3926 this->storageStatus_ = Details::STORAGE_1D_PACKED;
3928 checkInternalState ();
3931 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3935 const Teuchos::ArrayRCP<LocalOrdinal>& ind,
3936 const Teuchos::ArrayRCP<Scalar>& val)
3938 using Kokkos::Compat::getKokkosViewDeepCopy;
3939 using Teuchos::ArrayRCP;
3940 using Teuchos::av_reinterpret_cast;
3943 typedef typename local_graph_device_type::row_map_type row_map_type;
3945 const char tfecfFuncName[] =
"setAllValues(ArrayRCP<size_t>, ArrayRCP<LO>, ArrayRCP<Scalar>): ";
3951 typename row_map_type::non_const_type ptrNative (
"ptr", ptr.size ());
3952 Kokkos::View<
const size_t*,
3953 typename row_map_type::array_layout,
3955 Kokkos::MemoryUnmanaged> ptrSizeT (ptr.getRawPtr (), ptr.size ());
3958 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3959 (ptrNative.extent (0) != ptrSizeT.extent (0),
3960 std::logic_error,
"ptrNative.extent(0) = " <<
3961 ptrNative.extent (0) <<
" != ptrSizeT.extent(0) = "
3962 << ptrSizeT.extent (0) <<
". Please report this bug to the "
3963 "Tpetra developers.");
3965 auto indIn = getKokkosViewDeepCopy<DT> (ind ());
3966 auto valIn = getKokkosViewDeepCopy<DT> (av_reinterpret_cast<IST> (val ()));
3967 this->setAllValues (ptrNative, indIn, valIn);
3970 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3975 const char tfecfFuncName[] =
"getLocalDiagOffsets: ";
3976 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
3977 (staticGraph_.is_null (), std::runtime_error,
"The matrix has no graph.");
3984 const size_t lclNumRows = staticGraph_->getNodeNumRows ();
3985 if (
static_cast<size_t> (offsets.size ()) < lclNumRows) {
3986 offsets.resize (lclNumRows);
3992 typedef typename device_type::memory_space
memory_space;
3993 if (std::is_same<memory_space, Kokkos::HostSpace>::value) {
3998 Kokkos::MemoryUnmanaged> output_type;
3999 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
4000 staticGraph_->getLocalDiagOffsets (offsetsOut);
4003 Kokkos::View<size_t*, device_type> offsetsTmp (
"diagOffsets", lclNumRows);
4004 staticGraph_->getLocalDiagOffsets (offsetsTmp);
4005 typedef Kokkos::View<
size_t*, Kokkos::HostSpace,
4006 Kokkos::MemoryUnmanaged> output_type;
4007 output_type offsetsOut (offsets.getRawPtr (), lclNumRows);
4012 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4017 using Teuchos::ArrayRCP;
4018 using Teuchos::ArrayView;
4019 using Teuchos::av_reinterpret_cast;
4020 const char tfecfFuncName[] =
"getLocalDiagCopy (1-arg): ";
4024 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4025 staticGraph_.is_null (), std::runtime_error,
4026 "This method requires that the matrix have a graph.");
4027 auto rowMapPtr = this->getRowMap ();
4028 if (rowMapPtr.is_null () || rowMapPtr->getComm ().is_null ()) {
4034 auto colMapPtr = this->getColMap ();
4035 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4036 (! this->hasColMap () || colMapPtr.is_null (), std::runtime_error,
4037 "This method requires that the matrix have a column Map.");
4038 const map_type& rowMap = * rowMapPtr;
4040 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4042 #ifdef HAVE_TPETRA_DEBUG
4045 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4046 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4047 "The input Vector's Map must be compatible with the CrsMatrix's row "
4048 "Map. You may check this by using Map's isCompatible method: "
4049 "diag.getMap ()->isCompatible (A.getRowMap ());");
4052 if (this->isFillComplete ()) {
4055 const auto D_lcl_1d =
4056 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
4058 const auto lclRowMap = rowMap.getLocalMap ();
4063 getLocalMatrixDevice ());
4071 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4076 Kokkos::MemoryUnmanaged>& offsets)
const
4078 typedef LocalOrdinal LO;
4080 #ifdef HAVE_TPETRA_DEBUG
4081 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
4082 const map_type& rowMap = * (this->getRowMap ());
4085 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4086 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4087 "The input Vector's Map must be compatible with (in the sense of Map::"
4088 "isCompatible) the CrsMatrix's row Map.");
4099 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4102 Kokkos::subview (D_lcl, Kokkos::make_pair (LO (0), myNumRows), 0);
4104 KokkosSparse::getDiagCopy (D_lcl_1d, offsets,
4105 getLocalMatrixDevice ());
4108 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4112 const Teuchos::ArrayView<const size_t>& offsets)
const
4114 using LO = LocalOrdinal;
4115 using host_execution_space = Kokkos::DefaultHostExecutionSpace;
4118 #ifdef HAVE_TPETRA_DEBUG
4119 const char tfecfFuncName[] =
"getLocalDiagCopy: ";
4120 const map_type& rowMap = * (this->getRowMap ());
4123 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4124 ! diag.
getMap ()->isCompatible (rowMap), std::runtime_error,
4125 "The input Vector's Map must be compatible with (in the sense of Map::"
4126 "isCompatible) the CrsMatrix's row Map.");
4139 auto lclVecHost1d = Kokkos::subview (lclVecHost, Kokkos::ALL (), 0);
4141 using host_offsets_view_type =
4142 Kokkos::View<
const size_t*, Kokkos::HostSpace,
4143 Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
4144 host_offsets_view_type h_offsets (offsets.getRawPtr (), offsets.size ());
4146 using range_type = Kokkos::RangePolicy<host_execution_space, LO>;
4147 const LO myNumRows =
static_cast<LO
> (this->getNodeNumRows ());
4148 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
4150 auto rowPtrsPackedHost = staticGraph_->rowPtrsPacked_host_;
4151 auto valuesPackedHost = valuesPacked_wdv.getHostView(Access::ReadOnly);
4152 Kokkos::parallel_for
4153 (
"Tpetra::CrsMatrix::getLocalDiagCopy",
4154 range_type (0, myNumRows),
4155 [&, INV, h_offsets] (
const LO lclRow) {
4156 lclVecHost1d(lclRow) = STS::zero ();
4157 if (h_offsets[lclRow] != INV) {
4158 auto curRowOffset = rowPtrsPackedHost (lclRow);
4159 lclVecHost1d(lclRow) =
4160 static_cast<IST
> (valuesPackedHost(curRowOffset+h_offsets[lclRow]));
4167 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4172 using ::Tpetra::Details::ProfilingRegion;
4173 using Teuchos::ArrayRCP;
4174 using Teuchos::ArrayView;
4175 using Teuchos::null;
4178 using Teuchos::rcpFromRef;
4180 const char tfecfFuncName[] =
"leftScale: ";
4182 ProfilingRegion region (
"Tpetra::CrsMatrix::leftScale");
4184 RCP<const vec_type> xp;
4185 if (this->getRangeMap ()->isSameAs (* (x.
getMap ()))) {
4188 auto exporter = this->getCrsGraphRef ().getExporter ();
4189 if (exporter.get () !=
nullptr) {
4190 RCP<vec_type> tempVec (
new vec_type (this->getRowMap ()));
4191 tempVec->doImport (x, *exporter,
REPLACE);
4195 xp = rcpFromRef (x);
4198 else if (this->getRowMap ()->isSameAs (* (x.
getMap ()))) {
4199 xp = rcpFromRef (x);
4202 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4203 (
true, std::invalid_argument,
"x's Map must be the same as "
4204 "either the row Map or the range Map of the CrsMatrix.");
4207 if (this->isFillComplete()) {
4208 auto x_lcl = xp->getLocalViewDevice (Access::ReadOnly);
4209 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4212 x_lcl_1d,
false,
false);
4216 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4217 (
true, std::runtime_error,
"CrsMatrix::leftScale requires matrix to be"
4222 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4227 using ::Tpetra::Details::ProfilingRegion;
4228 using Teuchos::ArrayRCP;
4229 using Teuchos::ArrayView;
4230 using Teuchos::null;
4233 using Teuchos::rcpFromRef;
4235 const char tfecfFuncName[] =
"rightScale: ";
4237 ProfilingRegion region (
"Tpetra::CrsMatrix::rightScale");
4239 RCP<const vec_type> xp;
4240 if (this->getDomainMap ()->isSameAs (* (x.
getMap ()))) {
4243 auto importer = this->getCrsGraphRef ().getImporter ();
4244 if (importer.get () !=
nullptr) {
4245 RCP<vec_type> tempVec (
new vec_type (this->getColMap ()));
4246 tempVec->doImport (x, *importer,
REPLACE);
4250 xp = rcpFromRef (x);
4253 else if (this->getColMap ()->isSameAs (* (x.
getMap ()))) {
4254 xp = rcpFromRef (x);
4256 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4257 (
true, std::runtime_error,
"x's Map must be the same as "
4258 "either the domain Map or the column Map of the CrsMatrix.");
4261 if (this->isFillComplete()) {
4262 auto x_lcl = xp->getLocalViewDevice (Access::ReadOnly);
4263 auto x_lcl_1d = Kokkos::subview (x_lcl, Kokkos::ALL (), 0);
4266 x_lcl_1d,
false,
false);
4270 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4271 (
true, std::runtime_error,
"CrsMatrix::rightScale requires matrix to be"
4276 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4281 using Teuchos::ArrayView;
4282 using Teuchos::outArg;
4283 using Teuchos::REDUCE_SUM;
4284 using Teuchos::reduceAll;
4292 if (frobNorm == -STM::one ()) {
4294 if (getNodeNumEntries() > 0) {
4295 if (isStorageOptimized ()) {
4298 const size_t numEntries = getNodeNumEntries ();
4299 auto values = valuesPacked_wdv.getHostView(Access::ReadOnly);
4300 for (
size_t k = 0; k < numEntries; ++k) {
4301 auto val = values[k];
4305 const mag_type val_abs = STS::abs (val);
4306 mySum += val_abs * val_abs;
4310 const LocalOrdinal numRows =
4311 static_cast<LocalOrdinal
> (this->getNodeNumRows ());
4312 for (LocalOrdinal r = 0; r < numRows; ++r) {
4313 const RowInfo rowInfo = myGraph_->getRowInfo (r);
4314 const size_t numEntries = rowInfo.numEntries;
4315 auto A_r = this->getValuesViewHost(rowInfo);
4316 for (
size_t k = 0; k < numEntries; ++k) {
4318 const mag_type val_abs = STS::abs (val);
4319 mySum += val_abs * val_abs;
4325 reduceAll<int, mag_type> (* (getComm ()), REDUCE_SUM,
4326 mySum, outArg (totalSum));
4327 frobNorm = STM::sqrt (totalSum);
4329 if (isFillComplete ()) {
4333 frobNorm_ = frobNorm;
4338 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4341 replaceColMap (
const Teuchos::RCP<const map_type>& newColMap)
4343 const char tfecfFuncName[] =
"replaceColMap: ";
4347 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4348 myGraph_.is_null (), std::runtime_error,
4349 "This method does not work if the matrix has a const graph. The whole "
4350 "idea of a const graph is that you are not allowed to change it, but "
4351 "this method necessarily must modify the graph, since the graph owns "
4352 "the matrix's column Map.");
4353 myGraph_->replaceColMap (newColMap);
4356 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4360 const Teuchos::RCP<const map_type>& newColMap,
4361 const Teuchos::RCP<const import_type>& newImport,
4362 const bool sortEachRow)
4364 const char tfecfFuncName[] =
"reindexColumns: ";
4365 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4366 graph ==
nullptr && myGraph_.is_null (), std::invalid_argument,
4367 "The input graph is null, but the matrix does not own its graph.");
4369 crs_graph_type& theGraph = (graph ==
nullptr) ? *myGraph_ : *graph;
4370 const bool sortGraph =
false;
4375 const LocalOrdinal lclNumRows =
4378 for (LocalOrdinal row = 0; row < lclNumRows; ++row) {
4382 auto vals = this->getValuesViewHostNonConst (rowInfo);
4384 sort2 (lclColInds.data (),
4385 lclColInds.data () + rowInfo.numEntries,
4392 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4397 const char tfecfFuncName[] =
"replaceDomainMap: ";
4398 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4399 myGraph_.is_null (), std::runtime_error,
4400 "This method does not work if the matrix has a const graph. The whole "
4401 "idea of a const graph is that you are not allowed to change it, but this"
4402 " method necessarily must modify the graph, since the graph owns the "
4403 "matrix's domain Map and Import objects.");
4404 myGraph_->replaceDomainMap (newDomainMap);
4407 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4411 Teuchos::RCP<const import_type>& newImporter)
4413 const char tfecfFuncName[] =
"replaceDomainMapAndImporter: ";
4414 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4415 myGraph_.is_null (), std::runtime_error,
4416 "This method does not work if the matrix has a const graph. The whole "
4417 "idea of a const graph is that you are not allowed to change it, but this"
4418 " method necessarily must modify the graph, since the graph owns the "
4419 "matrix's domain Map and Import objects.");
4420 myGraph_->replaceDomainMapAndImporter (newDomainMap, newImporter);
4423 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4428 const char tfecfFuncName[] =
"replaceRangeMap: ";
4429 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4430 myGraph_.is_null (), std::runtime_error,
4431 "This method does not work if the matrix has a const graph. The whole "
4432 "idea of a const graph is that you are not allowed to change it, but this"
4433 " method necessarily must modify the graph, since the graph owns the "
4434 "matrix's domain Map and Import objects.");
4435 myGraph_->replaceRangeMap (newRangeMap);
4438 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4442 Teuchos::RCP<const export_type>& newExporter)
4444 const char tfecfFuncName[] =
"replaceRangeMapAndExporter: ";
4445 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
4446 myGraph_.is_null (), std::runtime_error,
4447 "This method does not work if the matrix has a const graph. The whole "
4448 "idea of a const graph is that you are not allowed to change it, but this"
4449 " method necessarily must modify the graph, since the graph owns the "
4450 "matrix's domain Map and Import objects.");
4451 myGraph_->replaceRangeMapAndExporter (newRangeMap, newExporter);
4454 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4458 const Teuchos::ArrayView<const GlobalOrdinal>& indices,
4459 const Teuchos::ArrayView<const Scalar>& values)
4461 using Teuchos::Array;
4462 typedef GlobalOrdinal GO;
4463 typedef typename Array<GO>::size_type size_type;
4465 const size_type numToInsert = indices.size ();
4468 std::pair<Array<GO>, Array<Scalar> >& curRow = nonlocals_[globalRow];
4469 Array<GO>& curRowInds = curRow.first;
4470 Array<Scalar>& curRowVals = curRow.second;
4471 const size_type newCapacity = curRowInds.size () + numToInsert;
4472 curRowInds.reserve (newCapacity);
4473 curRowVals.reserve (newCapacity);
4474 for (size_type k = 0; k < numToInsert; ++k) {
4475 curRowInds.push_back (indices[k]);
4476 curRowVals.push_back (values[k]);
4480 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4487 using Teuchos::Comm;
4488 using Teuchos::outArg;
4491 using Teuchos::REDUCE_MAX;
4492 using Teuchos::REDUCE_MIN;
4493 using Teuchos::reduceAll;
4497 typedef GlobalOrdinal GO;
4498 typedef typename Teuchos::Array<GO>::size_type size_type;
4499 const char tfecfFuncName[] =
"globalAssemble: ";
4500 ProfilingRegion regionGlobalAssemble (
"Tpetra::CrsMatrix::globalAssemble");
4502 const bool verbose = Behavior::verbose(
"CrsMatrix");
4503 std::unique_ptr<std::string> prefix;
4505 prefix = this->createPrefix(
"CrsMatrix",
"globalAssemble");
4506 std::ostringstream os;
4507 os << *prefix <<
"nonlocals_.size()=" << nonlocals_.size()
4509 std::cerr << os.str();
4511 RCP<const Comm<int> > comm = getComm ();
4513 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4514 (! isFillActive (), std::runtime_error,
"Fill must be active before "
4515 "you may call this method.");
4517 const size_t myNumNonlocalRows = nonlocals_.size ();
4524 const int iHaveNonlocalRows = (myNumNonlocalRows == 0) ? 0 : 1;
4525 int someoneHasNonlocalRows = 0;
4526 reduceAll<int, int> (*comm, REDUCE_MAX, iHaveNonlocalRows,
4527 outArg (someoneHasNonlocalRows));
4528 if (someoneHasNonlocalRows == 0) {
4542 RCP<const map_type> nonlocalRowMap;
4544 Teuchos::Array<size_t> numEntPerNonlocalRow (myNumNonlocalRows);
4546 Teuchos::Array<GO> myNonlocalGblRows (myNumNonlocalRows);
4547 size_type curPos = 0;
4548 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4549 ++mapIter, ++curPos) {
4550 myNonlocalGblRows[curPos] = mapIter->first;
4553 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4554 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4561 sort2 (gblCols.begin (), gblCols.end (), vals.begin ());
4562 typename Teuchos::Array<GO>::iterator gblCols_newEnd;
4563 typename Teuchos::Array<Scalar>::iterator vals_newEnd;
4564 merge2 (gblCols_newEnd, vals_newEnd,
4565 gblCols.begin (), gblCols.end (),
4566 vals.begin (), vals.end ());
4567 gblCols.erase (gblCols_newEnd, gblCols.end ());
4568 vals.erase (vals_newEnd, vals.end ());
4569 numEntPerNonlocalRow[curPos] = gblCols.size ();
4580 GO myMinNonlocalGblRow = std::numeric_limits<GO>::max ();
4582 auto iter = std::min_element (myNonlocalGblRows.begin (),
4583 myNonlocalGblRows.end ());
4584 if (iter != myNonlocalGblRows.end ()) {
4585 myMinNonlocalGblRow = *iter;
4588 GO gblMinNonlocalGblRow = 0;
4589 reduceAll<int, GO> (*comm, REDUCE_MIN, myMinNonlocalGblRow,
4590 outArg (gblMinNonlocalGblRow));
4591 const GO indexBase = gblMinNonlocalGblRow;
4592 const global_size_t INV = Teuchos::OrdinalTraits<global_size_t>::invalid ();
4593 nonlocalRowMap = rcp (
new map_type (INV, myNonlocalGblRows (), indexBase, comm));
4602 std::ostringstream os;
4603 os << *prefix <<
"Create nonlocal matrix" << endl;
4604 std::cerr << os.str();
4606 RCP<crs_matrix_type> nonlocalMatrix =
4607 rcp (
new crs_matrix_type (nonlocalRowMap, numEntPerNonlocalRow (),
4610 size_type curPos = 0;
4611 for (
auto mapIter = nonlocals_.begin (); mapIter != nonlocals_.end ();
4612 ++mapIter, ++curPos) {
4613 const GO gblRow = mapIter->first;
4615 Teuchos::Array<GO>& gblCols = (mapIter->second).first;
4616 Teuchos::Array<Scalar>& vals = (mapIter->second).second;
4618 nonlocalMatrix->insertGlobalValues (gblRow, gblCols (), vals ());
4630 auto origRowMap = this->getRowMap ();
4631 const bool origRowMapIsOneToOne = origRowMap->isOneToOne ();
4633 int isLocallyComplete = 1;
4635 if (origRowMapIsOneToOne) {
4637 std::ostringstream os;
4638 os << *prefix <<
"Original row Map is 1-to-1" << endl;
4639 std::cerr << os.str();
4641 export_type exportToOrig (nonlocalRowMap, origRowMap);
4643 isLocallyComplete = 0;
4646 std::ostringstream os;
4647 os << *prefix <<
"doExport from nonlocalMatrix" << endl;
4648 std::cerr << os.str();
4650 this->doExport (*nonlocalMatrix, exportToOrig,
Tpetra::ADD);
4655 std::ostringstream os;
4656 os << *prefix <<
"Original row Map is NOT 1-to-1" << endl;
4657 std::cerr << os.str();
4664 export_type exportToOneToOne (nonlocalRowMap, oneToOneRowMap);
4666 isLocallyComplete = 0;
4674 std::ostringstream os;
4675 os << *prefix <<
"Create & doExport into 1-to-1 matrix"
4677 std::cerr << os.str();
4679 crs_matrix_type oneToOneMatrix (oneToOneRowMap, 0);
4681 oneToOneMatrix.doExport(*nonlocalMatrix, exportToOneToOne,
4687 std::ostringstream os;
4688 os << *prefix <<
"Free nonlocalMatrix" << endl;
4689 std::cerr << os.str();
4691 nonlocalMatrix = Teuchos::null;
4695 std::ostringstream os;
4696 os << *prefix <<
"doImport from 1-to-1 matrix" << endl;
4697 std::cerr << os.str();
4699 import_type importToOrig (oneToOneRowMap, origRowMap);
4700 this->doImport (oneToOneMatrix, importToOrig,
Tpetra::ADD);
4708 std::ostringstream os;
4709 os << *prefix <<
"Free nonlocals_ (std::map)" << endl;
4710 std::cerr << os.str();
4712 decltype (nonlocals_) newNonlocals;
4713 std::swap (nonlocals_, newNonlocals);
4722 int isGloballyComplete = 0;
4723 reduceAll<int, int> (*comm, REDUCE_MIN, isLocallyComplete,
4724 outArg (isGloballyComplete));
4725 TEUCHOS_TEST_FOR_EXCEPTION
4726 (isGloballyComplete != 1, std::runtime_error,
"On at least one process, "
4727 "you called insertGlobalValues with a global row index which is not in "
4728 "the matrix's row Map on any process in its communicator.");
4731 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4734 resumeFill (
const Teuchos::RCP<Teuchos::ParameterList>& params)
4736 if (! isStaticGraph ()) {
4737 myGraph_->resumeFill (params);
4739 clearGlobalConstants ();
4740 fillComplete_ =
false;
4743 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4757 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4761 return getCrsGraphRef ().haveGlobalConstants ();
4764 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4776 frobNorm_ = -STM::one ();
4779 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4782 fillComplete (
const Teuchos::RCP<Teuchos::ParameterList>& params)
4784 const char tfecfFuncName[] =
"fillComplete(params): ";
4786 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4787 (this->getCrsGraph ().is_null (), std::logic_error,
4788 "getCrsGraph() returns null. This should not happen at this point. "
4789 "Please report this bug to the Tpetra developers.");
4799 Teuchos::RCP<const map_type> rangeMap = graph.
getRowMap ();
4800 Teuchos::RCP<const map_type> domainMap = rangeMap;
4801 this->fillComplete (domainMap, rangeMap, params);
4805 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4808 fillComplete (
const Teuchos::RCP<const map_type>& domainMap,
4809 const Teuchos::RCP<const map_type>& rangeMap,
4810 const Teuchos::RCP<Teuchos::ParameterList>& params)
4814 using Teuchos::ArrayRCP;
4818 const char tfecfFuncName[] =
"fillComplete: ";
4819 ProfilingRegion regionFillComplete
4820 (
"Tpetra::CrsMatrix::fillComplete");
4821 const bool verbose = Behavior::verbose(
"CrsMatrix");
4822 std::unique_ptr<std::string> prefix;
4824 prefix = this->createPrefix(
"CrsMatrix",
"fillComplete(dom,ran,p)");
4825 std::ostringstream os;
4826 os << *prefix << endl;
4827 std::cerr << os.str ();
4830 "Tpetra::CrsMatrix::fillCompete",
4833 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4834 (! this->isFillActive () || this->isFillComplete (), std::runtime_error,
4835 "Matrix fill state must be active (isFillActive() "
4836 "must be true) before you may call fillComplete().");
4837 const int numProcs = this->getComm ()->getSize ();
4847 bool assertNoNonlocalInserts =
false;
4850 bool sortGhosts =
true;
4852 if (! params.is_null ()) {
4853 assertNoNonlocalInserts = params->get (
"No Nonlocal Changes",
4854 assertNoNonlocalInserts);
4855 if (params->isParameter (
"sort column map ghost gids")) {
4856 sortGhosts = params->get (
"sort column map ghost gids", sortGhosts);
4858 else if (params->isParameter (
"Sort column Map ghost GIDs")) {
4859 sortGhosts = params->get (
"Sort column Map ghost GIDs", sortGhosts);
4864 const bool needGlobalAssemble = ! assertNoNonlocalInserts && numProcs > 1;
4866 if (! this->myGraph_.is_null ()) {
4867 this->myGraph_->sortGhostsAssociatedWithEachProcessor_ = sortGhosts;
4870 if (! this->getCrsGraphRef ().indicesAreAllocated ()) {
4871 if (this->hasColMap ()) {
4872 allocateValues(LocalIndices, GraphNotYetAllocated, verbose);
4875 allocateValues(GlobalIndices, GraphNotYetAllocated, verbose);
4880 if (needGlobalAssemble) {
4881 this->globalAssemble ();
4884 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4885 (numProcs == 1 && nonlocals_.size() > 0,
4886 std::runtime_error,
"Cannot have nonlocal entries on a serial run. "
4887 "An invalid entry (i.e., with row index not in the row Map) must have "
4888 "been submitted to the CrsMatrix.");
4891 if (this->isStaticGraph ()) {
4899 #ifdef HAVE_TPETRA_DEBUG
4917 const bool domainMapsMatch =
4918 this->staticGraph_->getDomainMap ()->isSameAs (*domainMap);
4919 const bool rangeMapsMatch =
4920 this->staticGraph_->getRangeMap ()->isSameAs (*rangeMap);
4922 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4923 (! domainMapsMatch, std::runtime_error,
4924 "The CrsMatrix's domain Map does not match the graph's domain Map. "
4925 "The graph cannot be changed because it was given to the CrsMatrix "
4926 "constructor as const. You can fix this by passing in the graph's "
4927 "domain Map and range Map to the matrix's fillComplete call.");
4929 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4930 (! rangeMapsMatch, std::runtime_error,
4931 "The CrsMatrix's range Map does not match the graph's range Map. "
4932 "The graph cannot be changed because it was given to the CrsMatrix "
4933 "constructor as const. You can fix this by passing in the graph's "
4934 "domain Map and range Map to the matrix's fillComplete call.");
4939 this->fillLocalMatrix (params);
4947 this->myGraph_->setDomainRangeMaps (domainMap, rangeMap);
4950 Teuchos::Array<int> remotePIDs (0);
4951 const bool mustBuildColMap = ! this->hasColMap ();
4952 if (mustBuildColMap) {
4953 this->myGraph_->makeColMap (remotePIDs);
4958 const std::pair<size_t, std::string> makeIndicesLocalResult =
4959 this->myGraph_->makeIndicesLocal(verbose);
4964 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
4965 (makeIndicesLocalResult.first != 0, std::runtime_error,
4966 makeIndicesLocalResult.second);
4968 const bool sorted = this->myGraph_->isSorted ();
4969 const bool merged = this->myGraph_->isMerged ();
4970 this->sortAndMergeIndicesAndValues (sorted, merged);
4975 this->myGraph_->makeImportExport (remotePIDs, mustBuildColMap);
4979 this->fillLocalGraphAndMatrix (params);
4981 const bool callGraphComputeGlobalConstants = params.get () ==
nullptr ||
4982 params->get (
"compute global constants",
true);
4983 if (callGraphComputeGlobalConstants) {
4984 this->myGraph_->computeGlobalConstants ();
4987 this->myGraph_->computeLocalConstants ();
4989 this->myGraph_->fillComplete_ =
true;
4990 this->myGraph_->checkInternalState ();
4995 "Tpetra::CrsMatrix::fillCompete",
"callComputeGlobalConstamnts"
4997 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
4998 params->get (
"compute global constants",
true);
4999 if (callComputeGlobalConstants) {
5000 this->computeGlobalConstants ();
5006 this->fillComplete_ =
true;
5009 "Tpetra::CrsMatrix::fillCompete",
"checkInternalState"
5011 this->checkInternalState ();
5015 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5019 const Teuchos::RCP<const map_type> & rangeMap,
5020 const Teuchos::RCP<const import_type>& importer,
5021 const Teuchos::RCP<const export_type>& exporter,
5022 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
5024 #ifdef HAVE_TPETRA_MMM_TIMINGS
5026 if(!params.is_null())
5027 label = params->get(
"Timer Label",label);
5028 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
5029 using Teuchos::TimeMonitor;
5031 Teuchos::TimeMonitor all(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-all")));
5034 const char tfecfFuncName[] =
"expertStaticFillComplete: ";
5035 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC( ! isFillActive() || isFillComplete(),
5036 std::runtime_error,
"Matrix fill state must be active (isFillActive() "
5037 "must be true) before calling fillComplete().");
5038 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
5039 myGraph_.is_null (), std::logic_error,
"myGraph_ is null. This is not allowed.");
5042 #ifdef HAVE_TPETRA_MMM_TIMINGS
5043 Teuchos::TimeMonitor graph(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-Graph")));
5046 myGraph_->expertStaticFillComplete (domainMap, rangeMap, importer, exporter,params);
5049 const bool callComputeGlobalConstants = params.get () ==
nullptr ||
5050 params->get (
"compute global constants",
true);
5051 if (callComputeGlobalConstants) {
5052 this->computeGlobalConstants ();
5056 #ifdef HAVE_TPETRA_MMM_TIMINGS
5057 TimeMonitor fLGAM(*TimeMonitor::getNewTimer(prefix + std::string(
"eSFC-M-fLGAM")));
5060 fillLocalGraphAndMatrix (params);
5065 fillComplete_ =
true;
5068 #ifdef HAVE_TPETRA_DEBUG
5069 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(isFillActive(), std::logic_error,
5070 ": We're at the end of fillComplete(), but isFillActive() is true. "
5071 "Please report this bug to the Tpetra developers.");
5072 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(! isFillComplete(), std::logic_error,
5073 ": We're at the end of fillComplete(), but isFillActive() is true. "
5074 "Please report this bug to the Tpetra developers.");
5077 #ifdef HAVE_TPETRA_MMM_TIMINGS
5078 Teuchos::TimeMonitor cIS(*TimeMonitor::getNewTimer(prefix + std::string(
"ESFC-M-cIS")));
5081 checkInternalState();
5085 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5091 LocalOrdinal* beg = cols;
5092 LocalOrdinal* end = cols + rowLen;
5093 LocalOrdinal* newend = beg;
5095 LocalOrdinal* cur = beg + 1;
5099 while (cur != end) {
5100 if (*cur != *newend) {
5117 return newend - beg;
5120 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5125 using ::Tpetra::Details::ProfilingRegion;
5126 typedef LocalOrdinal LO;
5127 typedef typename Kokkos::View<LO*, device_type>::HostMirror::execution_space
5128 host_execution_space;
5129 typedef Kokkos::RangePolicy<host_execution_space, LO> range_type;
5130 const char tfecfFuncName[] =
"sortAndMergeIndicesAndValues: ";
5131 ProfilingRegion regionSAM (
"Tpetra::CrsMatrix::sortAndMergeIndicesAndValues");
5133 if (! sorted || ! merged) {
5134 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5135 (this->isStaticGraph (), std::runtime_error,
"Cannot sort or merge with "
5136 "\"static\" (const) graph, since the matrix does not own the graph.");
5137 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5138 (this->myGraph_.is_null (), std::logic_error,
"myGraph_ is null, but "
5139 "this matrix claims ! isStaticGraph(). "
5140 "Please report this bug to the Tpetra developers.");
5141 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5142 (this->isStorageOptimized (), std::logic_error,
"It is invalid to call "
5143 "this method if the graph's storage has already been optimized. "
5144 "Please report this bug to the Tpetra developers.");
5147 const LO lclNumRows =
static_cast<LO
> (this->getNodeNumRows ());
5148 size_t totalNumDups = 0;
5151 auto rowBegins_ = graph.rowPtrsUnpacked_host_;
5153 auto vals_ = this->valuesUnpacked_wdv.getHostView(Access::ReadWrite);
5155 Kokkos::parallel_reduce (
"sortAndMergeIndicesAndValues", range_type (0, lclNumRows),
5156 [=] (
const LO lclRow,
size_t& numDups) {
5157 size_t rowBegin = rowBegins_(lclRow);
5158 size_t rowLen = rowLengths_(lclRow);
5159 LO* cols = cols_.data() + rowBegin;
5162 sort2 (cols, cols + rowLen, vals);
5165 size_t newRowLength = mergeRowIndicesAndValues (rowLen, cols, vals);
5166 rowLengths_(lclRow) = newRowLength;
5167 numDups += rowLen - newRowLength;
5180 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5191 using Teuchos::rcp_const_cast;
5192 using Teuchos::rcpFromRef;
5193 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5194 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one ();
5200 if (alpha ==
ZERO) {
5203 }
else if (beta != ONE) {
5217 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5218 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5224 const bool Y_is_overwritten = (beta ==
ZERO);
5227 const bool Y_is_replicated =
5228 (! Y_in.
isDistributed () && this->getComm ()->getSize () != 1);
5236 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5243 RCP<const MV> X_colMap;
5244 if (importer.is_null ()) {
5252 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in,
true);
5254 X_colMap = rcp_const_cast<const MV> (X_colMapNonConst);
5259 X_colMap = rcpFromRef (X_in);
5263 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply: Import");
5269 RCP<MV> X_colMapNonConst = getColumnMapMultiVector (X_in);
5272 X_colMapNonConst->doImport (X_in, *importer,
INSERT);
5273 X_colMap = rcp_const_cast<const MV> (X_colMapNonConst);
5280 RCP<MV> Y_rowMap = getRowMapMultiVector (Y_in);
5287 if (! exporter.is_null ()) {
5288 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha,
ZERO);
5290 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply: Export");
5296 if (Y_is_overwritten) {
5322 Y_rowMap = getRowMapMultiVector (Y_in,
true);
5329 this->localApply (*X_colMap, *Y_rowMap, Teuchos::NO_TRANS, alpha, beta);
5333 this->localApply (*X_colMap, Y_in, Teuchos::NO_TRANS, alpha, beta);
5341 if (Y_is_replicated) {
5342 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply: Reduce Y");
5347 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5352 const Teuchos::ETransp mode,
5357 using Teuchos::null;
5360 using Teuchos::rcp_const_cast;
5361 using Teuchos::rcpFromRef;
5362 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5365 if (alpha ==
ZERO) {
5388 RCP<const import_type> importer = this->getGraph ()->getImporter ();
5389 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
5395 const bool Y_is_overwritten = (beta ==
ZERO);
5396 if (Y_is_replicated && this->getComm ()->getRank () > 0) {
5402 X = rcp (
new MV (X_in, Teuchos::Copy));
5404 X = rcpFromRef (X_in);
5408 if (importer != Teuchos::null) {
5409 if (importMV_ != Teuchos::null && importMV_->getNumVectors() != numVectors) {
5412 if (importMV_ ==
null) {
5413 importMV_ = rcp (
new MV (this->getColMap (), numVectors));
5416 if (exporter != Teuchos::null) {
5417 if (exportMV_ != Teuchos::null && exportMV_->getNumVectors() != numVectors) {
5420 if (exportMV_ ==
null) {
5421 exportMV_ = rcp (
new MV (this->getRowMap (), numVectors));
5427 if (! exporter.is_null ()) {
5428 ProfilingRegion regionImport (
"Tpetra::CrsMatrix::apply (transpose): Import");
5429 exportMV_->doImport (X_in, *exporter,
INSERT);
5436 if (importer != Teuchos::null) {
5437 ProfilingRegion regionExport (
"Tpetra::CrsMatrix::apply (transpose): Export");
5444 importMV_->putScalar (
ZERO);
5446 this->localApply (*X, *importMV_, mode, alpha,
ZERO);
5448 if (Y_is_overwritten) {
5465 MV Y (Y_in, Teuchos::Copy);
5466 this->localApply (*X, Y, mode, alpha, beta);
5469 this->localApply (*X, Y_in, mode, alpha, beta);
5476 if (Y_is_replicated) {
5477 ProfilingRegion regionReduce (
"Tpetra::CrsMatrix::apply (transpose): Reduce Y");
5482 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5487 const Teuchos::ETransp mode,
5488 const Scalar& alpha,
5489 const Scalar& beta)
const
5492 using Teuchos::NO_TRANS;
5493 ProfilingRegion regionLocalApply (
"Tpetra::CrsMatrix::localApply");
5497 auto matrix_lcl = getLocalMultiplyOperator();
5501 const char tfecfFuncName[] =
"localApply: ";
5502 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5506 const bool transpose = (mode != Teuchos::NO_TRANS);
5507 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5509 getColMap ()->getNodeNumElements (), std::runtime_error,
5510 "NO_TRANS case: X has the wrong number of local rows. "
5512 "getColMap()->getNodeNumElements() = " <<
5513 getColMap ()->getNodeNumElements () <<
".");
5514 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5516 getRowMap ()->getNodeNumElements (), std::runtime_error,
5517 "NO_TRANS case: Y has the wrong number of local rows. "
5519 "getRowMap()->getNodeNumElements() = " <<
5520 getRowMap ()->getNodeNumElements () <<
".");
5521 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5523 getRowMap ()->getNodeNumElements (), std::runtime_error,
5524 "TRANS or CONJ_TRANS case: X has the wrong number of local "
5526 <<
" != getRowMap()->getNodeNumElements() = "
5527 << getRowMap ()->getNodeNumElements () <<
".");
5528 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5530 getColMap ()->getNodeNumElements (), std::runtime_error,
5531 "TRANS or CONJ_TRANS case: X has the wrong number of local "
5533 <<
" != getColMap()->getNodeNumElements() = "
5534 << getColMap ()->getNodeNumElements () <<
".");
5535 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5536 (! isFillComplete (), std::runtime_error,
"The matrix is not "
5537 "fill complete. You must call fillComplete() (possibly with "
5538 "domain and range Map arguments) without an intervening "
5539 "resumeFill() call before you may call this method.");
5540 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5542 std::runtime_error,
"X and Y must be constant stride.");
5545 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5546 (X_lcl.data () == Y_lcl.data () && X_lcl.data () !=
nullptr,
5547 std::runtime_error,
"X and Y may not alias one another.");
5550 LocalOrdinal nrows = getNodeNumRows();
5551 LocalOrdinal maxRowImbalance = 0;
5553 maxRowImbalance = getNodeMaxNumRowEntries() - (getNodeNumEntries() / nrows);
5556 matrix_lcl->applyImbalancedRows (X_lcl, Y_lcl, mode, alpha, beta);
5558 matrix_lcl->apply (X_lcl, Y_lcl, mode, alpha, beta);
5561 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5566 Teuchos::ETransp mode,
5571 const char fnName[] =
"Tpetra::CrsMatrix::apply";
5573 TEUCHOS_TEST_FOR_EXCEPTION
5574 (! isFillComplete (), std::runtime_error,
5575 fnName <<
": Cannot call apply() until fillComplete() "
5576 "has been called.");
5578 if (mode == Teuchos::NO_TRANS) {
5579 ProfilingRegion regionNonTranspose (fnName);
5580 this->applyNonTranspose (X, Y, alpha, beta);
5583 ProfilingRegion regionTranspose (
"Tpetra::CrsMatrix::apply (transpose)");
5590 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
5594 this->applyTranspose (X, Y, mode, alpha, beta);
5599 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5601 Teuchos::RCP<CrsMatrix<T, LocalOrdinal, GlobalOrdinal, Node> >
5607 const char tfecfFuncName[] =
"convert: ";
5609 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5610 (! this->isFillComplete (), std::runtime_error,
"This matrix (the source "
5611 "of the conversion) is not fill complete. You must first call "
5612 "fillComplete() (possibly with the domain and range Map) without an "
5613 "intervening call to resumeFill(), before you may call this method.");
5615 RCP<output_matrix_type> newMatrix
5616 (
new output_matrix_type (this->getCrsGraph ()));
5620 copyConvert (newMatrix->getLocalMatrixDevice ().values,
5621 this->getLocalMatrixDevice ().values);
5625 newMatrix->fillComplete (this->getDomainMap (), this->getRangeMap ());
5631 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5638 const char tfecfFuncName[] =
"checkInternalState: ";
5639 const char err[] =
"Internal state is not consistent. "
5640 "Please report this bug to the Tpetra developers.";
5644 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5645 (staticGraph_.is_null (), std::logic_error, err);
5649 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5650 (! myGraph_.is_null () && myGraph_ != staticGraph_,
5651 std::logic_error, err);
5653 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5654 (isFillComplete () && ! staticGraph_->isFillComplete (),
5655 std::logic_error, err <<
" Specifically, the matrix is fill complete, "
5656 "but its graph is NOT fill complete.");
5659 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
5660 (staticGraph_->indicesAreAllocated () &&
5661 staticGraph_->getNodeAllocationSize() > 0 &&
5662 staticGraph_->getNodeNumRows() > 0 &&
5663 valuesUnpacked_wdv.extent (0) == 0,
5664 std::logic_error, err);
5668 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5673 std::ostringstream os;
5675 os <<
"Tpetra::CrsMatrix (Kokkos refactor): {";
5676 if (this->getObjectLabel () !=
"") {
5677 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5679 if (isFillComplete ()) {
5680 os <<
"isFillComplete: true"
5681 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
5682 << getGlobalNumCols () <<
"]"
5683 <<
", global number of entries: " << getGlobalNumEntries ()
5687 os <<
"isFillComplete: false"
5688 <<
", global dimensions: [" << getGlobalNumRows () <<
", "
5689 << getGlobalNumCols () <<
"]}";
5694 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5697 describe (Teuchos::FancyOStream &out,
5698 const Teuchos::EVerbosityLevel verbLevel)
const
5702 using Teuchos::ArrayView;
5703 using Teuchos::Comm;
5705 using Teuchos::TypeNameTraits;
5706 using Teuchos::VERB_DEFAULT;
5707 using Teuchos::VERB_NONE;
5708 using Teuchos::VERB_LOW;
5709 using Teuchos::VERB_MEDIUM;
5710 using Teuchos::VERB_HIGH;
5711 using Teuchos::VERB_EXTREME;
5713 const Teuchos::EVerbosityLevel vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
5715 if (vl == VERB_NONE) {
5720 Teuchos::OSTab tab0 (out);
5722 RCP<const Comm<int> > comm = this->getComm();
5723 const int myRank = comm->getRank();
5724 const int numProcs = comm->getSize();
5726 for (
size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
5729 width = std::max<size_t> (width,
static_cast<size_t> (11)) + 2;
5739 out <<
"Tpetra::CrsMatrix (Kokkos refactor):" << endl;
5741 Teuchos::OSTab tab1 (out);
5744 if (this->getObjectLabel () !=
"") {
5745 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
5748 out <<
"Template parameters:" << endl;
5749 Teuchos::OSTab tab2 (out);
5750 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
5751 <<
"LocalOrdinal: " << TypeNameTraits<LocalOrdinal>::name () << endl
5752 <<
"GlobalOrdinal: " << TypeNameTraits<GlobalOrdinal>::name () << endl
5753 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
5755 if (isFillComplete()) {
5756 out <<
"isFillComplete: true" << endl
5757 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
5758 << getGlobalNumCols () <<
"]" << endl
5759 <<
"Global number of entries: " << getGlobalNumEntries () << endl
5760 << endl <<
"Global max number of entries in a row: "
5761 << getGlobalMaxNumRowEntries () << endl;
5764 out <<
"isFillComplete: false" << endl
5765 <<
"Global dimensions: [" << getGlobalNumRows () <<
", "
5766 << getGlobalNumCols () <<
"]" << endl;
5770 if (vl < VERB_MEDIUM) {
5776 out << endl <<
"Row Map:" << endl;
5778 if (getRowMap ().is_null ()) {
5780 out <<
"null" << endl;
5787 getRowMap ()->describe (out, vl);
5792 out <<
"Column Map: ";
5794 if (getColMap ().is_null ()) {
5796 out <<
"null" << endl;
5798 }
else if (getColMap () == getRowMap ()) {
5800 out <<
"same as row Map" << endl;
5806 getColMap ()->describe (out, vl);
5811 out <<
"Domain Map: ";
5813 if (getDomainMap ().is_null ()) {
5815 out <<
"null" << endl;
5817 }
else if (getDomainMap () == getRowMap ()) {
5819 out <<
"same as row Map" << endl;
5821 }
else if (getDomainMap () == getColMap ()) {
5823 out <<
"same as column Map" << endl;
5829 getDomainMap ()->describe (out, vl);
5834 out <<
"Range Map: ";
5836 if (getRangeMap ().is_null ()) {
5838 out <<
"null" << endl;
5840 }
else if (getRangeMap () == getDomainMap ()) {
5842 out <<
"same as domain Map" << endl;
5844 }
else if (getRangeMap () == getRowMap ()) {
5846 out <<
"same as row Map" << endl;
5852 getRangeMap ()->describe (out, vl);
5856 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5857 if (myRank == curRank) {
5858 out <<
"Process rank: " << curRank << endl;
5859 Teuchos::OSTab tab2 (out);
5860 if (! staticGraph_->indicesAreAllocated ()) {
5861 out <<
"Graph indices not allocated" << endl;
5864 out <<
"Number of allocated entries: "
5865 << staticGraph_->getNodeAllocationSize () << endl;
5867 out <<
"Number of entries: " << getNodeNumEntries () << endl
5868 <<
"Max number of entries per row: " << getNodeMaxNumRowEntries ()
5877 if (vl < VERB_HIGH) {
5882 for (
int curRank = 0; curRank < numProcs; ++curRank) {
5883 if (myRank == curRank) {
5884 out << std::setw(width) <<
"Proc Rank"
5885 << std::setw(width) <<
"Global Row"
5886 << std::setw(width) <<
"Num Entries";
5887 if (vl == VERB_EXTREME) {
5888 out << std::setw(width) <<
"(Index,Value)";
5891 for (
size_t r = 0; r < getNodeNumRows (); ++r) {
5892 const size_t nE = getNumEntriesInLocalRow(r);
5893 GlobalOrdinal gid = getRowMap()->getGlobalElement(r);
5894 out << std::setw(width) << myRank
5895 << std::setw(width) << gid
5896 << std::setw(width) << nE;
5897 if (vl == VERB_EXTREME) {
5898 if (isGloballyIndexed()) {
5899 global_inds_host_view_type rowinds;
5900 values_host_view_type rowvals;
5901 getGlobalRowView (gid, rowinds, rowvals);
5902 for (
size_t j = 0; j < nE; ++j) {
5903 out <<
" (" << rowinds[j]
5904 <<
", " << rowvals[j]
5908 else if (isLocallyIndexed()) {
5909 local_inds_host_view_type rowinds;
5910 values_host_view_type rowvals;
5911 getLocalRowView (r, rowinds, rowvals);
5912 for (
size_t j=0; j < nE; ++j) {
5913 out <<
" (" << getColMap()->getGlobalElement(rowinds[j])
5914 <<
", " << rowvals[j]
5930 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5944 return (srcRowMat !=
nullptr);
5947 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5951 const typename crs_graph_type::padding_type& padding,
5957 using LO = local_ordinal_type;
5958 using row_ptrs_type =
5959 typename local_graph_device_type::row_map_type::non_const_type;
5960 using range_policy =
5961 Kokkos::RangePolicy<execution_space, Kokkos::IndexType<LO>>;
5962 const char tfecfFuncName[] =
"applyCrsPadding";
5963 const char suffix[] =
5964 ". Please report this bug to the Tpetra developers.";
5965 ProfilingRegion regionCAP(
"Tpetra::CrsMatrix::applyCrsPadding");
5967 std::unique_ptr<std::string> prefix;
5969 prefix = this->createPrefix(
"CrsMatrix", tfecfFuncName);
5970 std::ostringstream os;
5971 os << *prefix <<
"padding: ";
5974 std::cerr << os.str();
5976 const int myRank = ! verbose ? -1 : [&] () {
5977 auto map = this->getMap();
5978 if (map.is_null()) {
5981 auto comm = map->getComm();
5982 if (comm.is_null()) {
5985 return comm->getRank();
5989 if (! myGraph_->indicesAreAllocated()) {
5991 std::ostringstream os;
5992 os << *prefix <<
"Call allocateIndices" << endl;
5993 std::cerr << os.str();
5995 allocateValues(GlobalIndices, GraphNotYetAllocated, verbose);
6007 std::ostringstream os;
6008 os << *prefix <<
"Allocate row_ptrs_beg: "
6009 << myGraph_->rowPtrsUnpacked_host_.extent(0) << endl;
6010 std::cerr << os.str();
6012 using Kokkos::view_alloc;
6013 using Kokkos::WithoutInitializing;
6014 row_ptrs_type row_ptr_beg(
6015 view_alloc(
"row_ptr_beg", WithoutInitializing),
6016 myGraph_->rowPtrsUnpacked_dev_.extent(0));
6019 const size_t N = row_ptr_beg.extent(0) == 0 ? size_t(0) :
6020 size_t(row_ptr_beg.extent(0) - 1);
6022 std::ostringstream os;
6023 os << *prefix <<
"Allocate row_ptrs_end: " << N << endl;
6024 std::cerr << os.str();
6026 row_ptrs_type row_ptr_end(
6027 view_alloc(
"row_ptr_end", WithoutInitializing), N);
6029 row_ptrs_type num_row_entries_d;
6031 const bool refill_num_row_entries =
6032 myGraph_->k_numRowEntries_.extent(0) != 0;
6034 if (refill_num_row_entries) {
6037 num_row_entries_d = create_mirror_view_and_copy(memory_space(),
6038 myGraph_->k_numRowEntries_);
6039 Kokkos::parallel_for
6040 (
"Fill end row pointers", range_policy(0, N),
6041 KOKKOS_LAMBDA (
const size_t i) {
6042 row_ptr_end(i) = row_ptr_beg(i) + num_row_entries_d(i);
6049 Kokkos::parallel_for
6050 (
"Fill end row pointers", range_policy(0, N),
6051 KOKKOS_LAMBDA (
const size_t i) {
6052 row_ptr_end(i) = row_ptr_beg(i+1);
6056 if (myGraph_->isGloballyIndexed()) {
6058 myGraph_->gblInds_wdv,
6059 valuesUnpacked_wdv, padding, myRank, verbose);
6060 const auto newValuesLen = valuesUnpacked_wdv.extent(0);
6061 const auto newColIndsLen = myGraph_->gblInds_wdv.extent(0);
6062 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6063 (newValuesLen != newColIndsLen, std::logic_error,
6064 ": After padding, valuesUnpacked_wdv.extent(0)=" << newValuesLen
6065 <<
" != myGraph_->gblInds_wdv.extent(0)=" << newColIndsLen
6070 myGraph_->lclIndsUnpacked_wdv,
6071 valuesUnpacked_wdv, padding, myRank, verbose);
6072 const auto newValuesLen = valuesUnpacked_wdv.extent(0);
6073 const auto newColIndsLen = myGraph_->lclIndsUnpacked_wdv.extent(0);
6074 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6075 (newValuesLen != newColIndsLen, std::logic_error,
6076 ": After padding, valuesUnpacked_wdv.extent(0)=" << newValuesLen
6077 <<
" != myGraph_->lclIndsUnpacked_wdv.extent(0)=" << newColIndsLen
6081 if (refill_num_row_entries) {
6082 Kokkos::parallel_for
6083 (
"Fill num entries", range_policy(0, N),
6084 KOKKOS_LAMBDA (
const size_t i) {
6085 num_row_entries_d(i) = row_ptr_end(i) - row_ptr_beg(i);
6091 std::ostringstream os;
6092 os << *prefix <<
"Assign myGraph_->rowPtrsUnpacked_; "
6093 <<
"old size: " << myGraph_->rowPtrsUnpacked_host_.extent(0)
6094 <<
", new size: " << row_ptr_beg.extent(0) << endl;
6095 std::cerr << os.str();
6096 TEUCHOS_ASSERT( myGraph_->rowPtrsUnpacked_host_.extent(0) ==
6097 row_ptr_beg.extent(0) );
6099 myGraph_->setRowPtrsUnpacked(row_ptr_beg);
6102 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6104 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6105 copyAndPermuteStaticGraph(
6106 const RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& srcMat,
6107 const size_t numSameIDs,
6108 const LocalOrdinal permuteToLIDs[],
6109 const LocalOrdinal permuteFromLIDs[],
6110 const size_t numPermutes)
6112 using Details::ProfilingRegion;
6113 using Teuchos::Array;
6114 using Teuchos::ArrayView;
6116 using LO = LocalOrdinal;
6117 using GO = GlobalOrdinal;
6118 const char tfecfFuncName[] =
"copyAndPermuteStaticGraph";
6119 const char suffix[] =
6120 " Please report this bug to the Tpetra developers.";
6121 ProfilingRegion regionCAP
6122 (
"Tpetra::CrsMatrix::copyAndPermuteStaticGraph");
6126 std::unique_ptr<std::string> prefix;
6128 prefix = this->
createPrefix(
"CrsGraph", tfecfFuncName);
6129 std::ostringstream os;
6130 os << *prefix <<
"Start" << endl;
6132 const char*
const prefix_raw =
6133 verbose ? prefix.get()->c_str() :
nullptr;
6135 const bool sourceIsLocallyIndexed = srcMat.isLocallyIndexed ();
6140 const map_type& srcRowMap = * (srcMat.getRowMap ());
6141 nonconst_global_inds_host_view_type rowInds;
6142 nonconst_values_host_view_type rowVals;
6143 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
6144 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
6148 const GO sourceGID = srcRowMap.getGlobalElement (sourceLID);
6149 const GO targetGID = sourceGID;
6151 ArrayView<const GO>rowIndsConstView;
6152 ArrayView<const Scalar> rowValsConstView;
6154 if (sourceIsLocallyIndexed) {
6155 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6156 if (rowLength >
static_cast<size_t> (rowInds.size())) {
6157 Kokkos::resize(rowInds,rowLength);
6158 Kokkos::resize(rowVals,rowLength);
6162 nonconst_global_inds_host_view_type rowIndsView = Kokkos::subview(rowInds,std::make_pair((
size_t)0, rowLength));
6163 nonconst_values_host_view_type rowValsView = Kokkos::subview(rowVals,std::make_pair((
size_t)0, rowLength));
6168 size_t checkRowLength = 0;
6169 srcMat.getGlobalRowCopy (sourceGID, rowIndsView,
6170 rowValsView, checkRowLength);
6172 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6173 (rowLength != checkRowLength, std::logic_error,
"For "
6174 "global row index " << sourceGID <<
", the source "
6175 "matrix's getNumEntriesInGlobalRow returns a row length "
6176 "of " << rowLength <<
", but getGlobalRowCopy reports "
6177 "a row length of " << checkRowLength <<
"." << suffix);
6184 rowIndsConstView = Teuchos::ArrayView<const GO> (
6185 rowIndsView.data(), rowIndsView.extent(0),
6186 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6187 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6188 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6189 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6194 global_inds_host_view_type rowIndsView;
6195 values_host_view_type rowValsView;
6196 srcMat.getGlobalRowView(sourceGID, rowIndsView, rowValsView);
6201 rowIndsConstView = Teuchos::ArrayView<const GO> (
6202 rowIndsView.data(), rowIndsView.extent(0),
6203 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6204 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6205 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6206 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6214 combineGlobalValues(targetGID, rowIndsConstView,
6216 prefix_raw, debug, verbose);
6220 std::ostringstream os;
6221 os << *prefix <<
"Do permutes" << endl;
6224 const map_type& tgtRowMap = * (this->getRowMap ());
6225 for (
size_t p = 0; p < numPermutes; ++p) {
6226 const GO sourceGID = srcRowMap.getGlobalElement (permuteFromLIDs[p]);
6227 const GO targetGID = tgtRowMap.getGlobalElement (permuteToLIDs[p]);
6229 ArrayView<const GO> rowIndsConstView;
6230 ArrayView<const Scalar> rowValsConstView;
6232 if (sourceIsLocallyIndexed) {
6233 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6234 if (rowLength >
static_cast<size_t> (rowInds.size ())) {
6235 Kokkos::resize(rowInds,rowLength);
6236 Kokkos::resize(rowVals,rowLength);
6240 nonconst_global_inds_host_view_type rowIndsView = Kokkos::subview(rowInds,std::make_pair((
size_t)0, rowLength));
6241 nonconst_values_host_view_type rowValsView = Kokkos::subview(rowVals,std::make_pair((
size_t)0, rowLength));
6246 size_t checkRowLength = 0;
6247 srcMat.getGlobalRowCopy(sourceGID, rowIndsView,
6248 rowValsView, checkRowLength);
6250 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6251 (rowLength != checkRowLength, std::logic_error,
"For "
6252 "source matrix global row index " << sourceGID <<
", "
6253 "getNumEntriesInGlobalRow returns a row length of " <<
6254 rowLength <<
", but getGlobalRowCopy a row length of "
6255 << checkRowLength <<
"." << suffix);
6262 rowIndsConstView = Teuchos::ArrayView<const GO> (
6263 rowIndsView.data(), rowIndsView.extent(0),
6264 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6265 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6266 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6267 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6272 global_inds_host_view_type rowIndsView;
6273 values_host_view_type rowValsView;
6274 srcMat.getGlobalRowView(sourceGID, rowIndsView, rowValsView);
6279 rowIndsConstView = Teuchos::ArrayView<const GO> (
6280 rowIndsView.data(), rowIndsView.extent(0),
6281 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6282 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6283 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6284 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6289 combineGlobalValues(targetGID, rowIndsConstView,
6291 prefix_raw, debug, verbose);
6295 std::ostringstream os;
6296 os << *prefix <<
"Done" << endl;
6300 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6302 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6303 copyAndPermuteNonStaticGraph(
6304 const RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& srcMat,
6305 const size_t numSameIDs,
6306 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs_dv,
6307 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs_dv,
6308 const size_t numPermutes)
6310 using Details::ProfilingRegion;
6311 using Teuchos::Array;
6312 using Teuchos::ArrayView;
6314 using LO = LocalOrdinal;
6315 using GO = GlobalOrdinal;
6316 const char tfecfFuncName[] =
"copyAndPermuteNonStaticGraph";
6317 const char suffix[] =
6318 " Please report this bug to the Tpetra developers.";
6319 ProfilingRegion regionCAP
6320 (
"Tpetra::CrsMatrix::copyAndPermuteNonStaticGraph");
6324 std::unique_ptr<std::string> prefix;
6326 prefix = this->
createPrefix(
"CrsGraph", tfecfFuncName);
6327 std::ostringstream os;
6328 os << *prefix <<
"Start" << endl;
6330 const char*
const prefix_raw =
6331 verbose ? prefix.get()->c_str() :
nullptr;
6334 using row_graph_type = RowGraph<LO, GO, Node>;
6335 const row_graph_type& srcGraph = *(srcMat.getGraph());
6337 myGraph_->computeCrsPadding(srcGraph, numSameIDs,
6338 permuteToLIDs_dv, permuteFromLIDs_dv, verbose);
6339 applyCrsPadding(*padding, verbose);
6341 const bool sourceIsLocallyIndexed = srcMat.isLocallyIndexed ();
6346 const map_type& srcRowMap = * (srcMat.getRowMap ());
6347 const LO numSameIDs_as_LID =
static_cast<LO
> (numSameIDs);
6348 using gids_type = nonconst_global_inds_host_view_type;
6349 using vals_type = nonconst_values_host_view_type;
6352 for (LO sourceLID = 0; sourceLID < numSameIDs_as_LID; ++sourceLID) {
6356 const GO sourceGID = srcRowMap.getGlobalElement (sourceLID);
6357 const GO targetGID = sourceGID;
6359 ArrayView<const GO> rowIndsConstView;
6360 ArrayView<const Scalar> rowValsConstView;
6362 if (sourceIsLocallyIndexed) {
6364 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6365 if (rowLength >
static_cast<size_t> (rowInds.extent(0))) {
6366 Kokkos::resize(rowInds,rowLength);
6367 Kokkos::resize(rowVals,rowLength);
6371 gids_type rowIndsView = Kokkos::subview(rowInds,std::make_pair((
size_t)0, rowLength));
6372 vals_type rowValsView = Kokkos::subview(rowVals,std::make_pair((
size_t)0, rowLength));
6377 size_t checkRowLength = 0;
6378 srcMat.getGlobalRowCopy (sourceGID, rowIndsView, rowValsView,
6381 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6382 (rowLength != checkRowLength, std::logic_error,
": For "
6383 "global row index " << sourceGID <<
", the source "
6384 "matrix's getNumEntriesInGlobalRow returns a row length "
6385 "of " << rowLength <<
", but getGlobalRowCopy reports "
6386 "a row length of " << checkRowLength <<
"." << suffix);
6388 rowIndsConstView = Teuchos::ArrayView<const GO>(rowIndsView.data(), rowLength);
6389 rowValsConstView = Teuchos::ArrayView<const Scalar>(
reinterpret_cast<Scalar *
>(rowValsView.data()), rowLength);
6392 global_inds_host_view_type rowIndsView;
6393 values_host_view_type rowValsView;
6394 srcMat.getGlobalRowView(sourceGID, rowIndsView, rowValsView);
6400 rowIndsConstView = Teuchos::ArrayView<const GO> (
6401 rowIndsView.data(), rowIndsView.extent(0),
6402 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6403 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6404 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6405 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6411 insertGlobalValuesFilteredChecked(targetGID, rowIndsConstView,
6412 rowValsConstView, prefix_raw, debug, verbose);
6416 std::ostringstream os;
6417 os << *prefix <<
"Do permutes" << endl;
6419 const LO*
const permuteFromLIDs = permuteFromLIDs_dv.view_host().data();
6420 const LO*
const permuteToLIDs = permuteToLIDs_dv.view_host().data();
6422 const map_type& tgtRowMap = * (this->getRowMap ());
6423 for (
size_t p = 0; p < numPermutes; ++p) {
6424 const GO sourceGID = srcRowMap.getGlobalElement (permuteFromLIDs[p]);
6425 const GO targetGID = tgtRowMap.getGlobalElement (permuteToLIDs[p]);
6427 ArrayView<const GO> rowIndsConstView;
6428 ArrayView<const Scalar> rowValsConstView;
6430 if (sourceIsLocallyIndexed) {
6431 const size_t rowLength = srcMat.getNumEntriesInGlobalRow (sourceGID);
6432 if (rowLength >
static_cast<size_t> (rowInds.extent(0))) {
6433 Kokkos::resize(rowInds,rowLength);
6434 Kokkos::resize(rowVals,rowLength);
6438 gids_type rowIndsView = Kokkos::subview(rowInds,std::make_pair((
size_t)0, rowLength));
6439 vals_type rowValsView = Kokkos::subview(rowVals,std::make_pair((
size_t)0, rowLength));
6444 size_t checkRowLength = 0;
6445 srcMat.getGlobalRowCopy(sourceGID, rowIndsView,
6446 rowValsView, checkRowLength);
6448 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6449 (rowLength != checkRowLength, std::logic_error,
"For "
6450 "source matrix global row index " << sourceGID <<
", "
6451 "getNumEntriesInGlobalRow returns a row length of " <<
6452 rowLength <<
", but getGlobalRowCopy a row length of "
6453 << checkRowLength <<
"." << suffix);
6455 rowIndsConstView = Teuchos::ArrayView<const GO>(rowIndsView.data(), rowLength);
6456 rowValsConstView = Teuchos::ArrayView<const Scalar>(
reinterpret_cast<Scalar *
>(rowValsView.data()), rowLength);
6459 global_inds_host_view_type rowIndsView;
6460 values_host_view_type rowValsView;
6461 srcMat.getGlobalRowView(sourceGID, rowIndsView, rowValsView);
6467 rowIndsConstView = Teuchos::ArrayView<const GO> (
6468 rowIndsView.data(), rowIndsView.extent(0),
6469 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6470 rowValsConstView = Teuchos::ArrayView<const Scalar> (
6471 reinterpret_cast<const Scalar*
>(rowValsView.data()), rowValsView.extent(0),
6472 Teuchos::RCP_DISABLE_NODE_LOOKUP);
6478 insertGlobalValuesFilteredChecked(targetGID, rowIndsConstView,
6479 rowValsConstView, prefix_raw, debug, verbose);
6483 std::ostringstream os;
6484 os << *prefix <<
"Done" << endl;
6488 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6490 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6492 const SrcDistObject& srcObj,
6493 const size_t numSameIDs,
6494 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs,
6495 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs,
6498 using Details::Behavior;
6500 using Details::ProfilingRegion;
6504 const char tfecfFuncName[] =
"copyAndPermute: ";
6505 ProfilingRegion regionCAP(
"Tpetra::CrsMatrix::copyAndPermute");
6507 const bool verbose = Behavior::verbose(
"CrsMatrix");
6508 std::unique_ptr<std::string> prefix;
6510 prefix = this->
createPrefix(
"CrsMatrix",
"copyAndPermute");
6511 std::ostringstream os;
6512 os << *prefix << endl
6513 << *prefix <<
" numSameIDs: " << numSameIDs << endl
6514 << *prefix <<
" numPermute: " << permuteToLIDs.extent(0)
6523 <<
"isStaticGraph: " << (isStaticGraph() ?
"true" :
"false")
6525 std::cerr << os.str ();
6528 const auto numPermute = permuteToLIDs.extent (0);
6529 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6530 (numPermute != permuteFromLIDs.extent (0),
6531 std::invalid_argument,
"permuteToLIDs.extent(0) = "
6532 << numPermute <<
"!= permuteFromLIDs.extent(0) = "
6533 << permuteFromLIDs.extent (0) <<
".");
6537 using RMT = RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
6538 const RMT& srcMat =
dynamic_cast<const RMT&
> (srcObj);
6539 if (isStaticGraph ()) {
6540 TEUCHOS_ASSERT( ! permuteToLIDs.need_sync_host () );
6541 auto permuteToLIDs_h = permuteToLIDs.view_host ();
6542 TEUCHOS_ASSERT( ! permuteFromLIDs.need_sync_host () );
6543 auto permuteFromLIDs_h = permuteFromLIDs.view_host ();
6545 copyAndPermuteStaticGraph(srcMat, numSameIDs,
6546 permuteToLIDs_h.data(),
6547 permuteFromLIDs_h.data(),
6551 copyAndPermuteNonStaticGraph(srcMat, numSameIDs, permuteToLIDs,
6552 permuteFromLIDs, numPermute);
6556 std::ostringstream os;
6557 os << *prefix <<
"Done" << endl;
6558 std::cerr << os.str();
6562 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6564 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6566 (
const SrcDistObject& source,
6567 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
6568 Kokkos::DualView<char*, buffer_device_type>& exports,
6569 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
6570 size_t& constantNumPackets)
6572 using Details::Behavior;
6574 using Details::ProfilingRegion;
6575 using Teuchos::outArg;
6576 using Teuchos::REDUCE_MAX;
6577 using Teuchos::reduceAll;
6579 typedef LocalOrdinal LO;
6580 typedef GlobalOrdinal GO;
6581 const char tfecfFuncName[] =
"packAndPrepare: ";
6582 ProfilingRegion regionPAP (
"Tpetra::CrsMatrix::packAndPrepare");
6584 const bool debug = Behavior::debug(
"CrsMatrix");
6585 const bool verbose = Behavior::verbose(
"CrsMatrix");
6588 Teuchos::RCP<const Teuchos::Comm<int> > pComm = this->getComm ();
6589 if (pComm.is_null ()) {
6592 const Teuchos::Comm<int>& comm = *pComm;
6593 const int myRank = comm.getSize ();
6595 std::unique_ptr<std::string> prefix;
6597 prefix = this->
createPrefix(
"CrsMatrix",
"packAndPrepare");
6598 std::ostringstream os;
6599 os << *prefix <<
"Start" << endl
6609 std::cerr << os.str ();
6632 std::ostringstream msg;
6635 using crs_matrix_type = CrsMatrix<Scalar, LO, GO, Node>;
6636 const crs_matrix_type* srcCrsMat =
6637 dynamic_cast<const crs_matrix_type*
> (&source);
6638 if (srcCrsMat !=
nullptr) {
6640 std::ostringstream os;
6641 os << *prefix <<
"Source matrix same (CrsMatrix) type as target; "
6642 "calling packNew" << endl;
6643 std::cerr << os.str ();
6646 srcCrsMat->packNew (exportLIDs, exports, numPacketsPerLID,
6647 constantNumPackets);
6649 catch (std::exception& e) {
6651 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
6655 using Kokkos::HostSpace;
6656 using Kokkos::subview;
6657 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
6658 using range_type = Kokkos::pair<size_t, size_t>;
6661 std::ostringstream os;
6662 os << *prefix <<
"Source matrix NOT same (CrsMatrix) type as target"
6664 std::cerr << os.str ();
6667 const row_matrix_type* srcRowMat =
6668 dynamic_cast<const row_matrix_type*
> (&source);
6669 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6670 (srcRowMat ==
nullptr, std::invalid_argument,
6671 "The source object of the Import or Export operation is neither a "
6672 "CrsMatrix (with the same template parameters as the target object), "
6673 "nor a RowMatrix (with the same first four template parameters as the "
6684 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
6685 auto exportLIDs_h = exportLIDs.view_host ();
6686 Teuchos::ArrayView<const LO> exportLIDs_av (exportLIDs_h.data (),
6687 exportLIDs_h.size ());
6691 Teuchos::Array<char> exports_a;
6697 numPacketsPerLID.clear_sync_state ();
6698 numPacketsPerLID.modify_host ();
6699 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
6700 Teuchos::ArrayView<size_t> numPacketsPerLID_av (numPacketsPerLID_h.data (),
6701 numPacketsPerLID_h.size ());
6706 srcRowMat->pack (exportLIDs_av, exports_a, numPacketsPerLID_av,
6707 constantNumPackets);
6709 catch (std::exception& e) {
6711 msg <<
"Proc " << myRank <<
": " << e.what () << std::endl;
6715 const size_t newAllocSize =
static_cast<size_t> (exports_a.size ());
6716 if (
static_cast<size_t> (exports.extent (0)) < newAllocSize) {
6717 const std::string oldLabel = exports.d_view.label ();
6718 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
6719 exports = exports_type (newLabel, newAllocSize);
6724 exports.modify_host();
6726 auto exports_h = exports.view_host ();
6727 auto exports_h_sub = subview (exports_h, range_type (0, newAllocSize));
6731 typedef typename exports_type::t_host::execution_space HES;
6732 typedef Kokkos::Device<HES, HostSpace> host_device_type;
6733 Kokkos::View<const char*, host_device_type>
6734 exports_a_kv (exports_a.getRawPtr (), newAllocSize);
6740 reduceAll<int, int> (comm, REDUCE_MAX, lclBad, outArg (gblBad));
6743 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6744 (
true, std::logic_error,
"packNew() or pack() threw an exception on "
6745 "one or more participating processes.");
6749 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
6750 (lclBad != 0, std::logic_error,
"packNew threw an exception on one "
6751 "or more participating processes. Here is this process' error "
6752 "message: " << msg.str ());
6756 std::ostringstream os;
6757 os << *prefix <<
"packAndPrepare: Done!" << endl
6767 std::cerr << os.str ();
6771 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6773 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6774 packRow (
char exports[],
6775 const size_t offset,
6776 const size_t numEnt,
6777 const GlobalOrdinal gidsIn[],
6778 const impl_scalar_type valsIn[],
6779 const size_t numBytesPerValue)
const
6782 using Kokkos::subview;
6784 typedef LocalOrdinal LO;
6785 typedef GlobalOrdinal GO;
6786 typedef impl_scalar_type ST;
6794 const LO numEntLO =
static_cast<size_t> (numEnt);
6796 const size_t numEntBeg = offset;
6798 const size_t gidsBeg = numEntBeg + numEntLen;
6799 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount (gid);
6800 const size_t valsBeg = gidsBeg + gidsLen;
6801 const size_t valsLen = numEnt * numBytesPerValue;
6803 char*
const numEntOut = exports + numEntBeg;
6804 char*
const gidsOut = exports + gidsBeg;
6805 char*
const valsOut = exports + valsBeg;
6807 size_t numBytesOut = 0;
6812 Kokkos::pair<int, size_t> p;
6813 p = PackTraits<GO>::packArray (gidsOut, gidsIn, numEnt);
6814 errorCode += p.first;
6815 numBytesOut += p.second;
6817 p = PackTraits<ST>::packArray (valsOut, valsIn, numEnt);
6818 errorCode += p.first;
6819 numBytesOut += p.second;
6822 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
6823 TEUCHOS_TEST_FOR_EXCEPTION
6824 (numBytesOut != expectedNumBytes, std::logic_error,
"packRow: "
6825 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
6826 << expectedNumBytes <<
".");
6827 TEUCHOS_TEST_FOR_EXCEPTION
6828 (errorCode != 0, std::runtime_error,
"packRow: "
6829 "PackTraits::packArray returned a nonzero error code");
6834 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6836 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6837 unpackRow (GlobalOrdinal gidsOut[],
6838 impl_scalar_type valsOut[],
6839 const char imports[],
6840 const size_t offset,
6841 const size_t numBytes,
6842 const size_t numEnt,
6843 const size_t numBytesPerValue)
6846 using Kokkos::subview;
6848 typedef LocalOrdinal LO;
6849 typedef GlobalOrdinal GO;
6850 typedef impl_scalar_type ST;
6852 Details::ProfilingRegion region_upack_row(
6853 "Tpetra::CrsMatrix::unpackRow",
6857 if (numBytes == 0) {
6860 const int myRank = this->getMap ()->getComm ()->getRank ();
6861 TEUCHOS_TEST_FOR_EXCEPTION
6862 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
6863 "unpackRow: The number of bytes to unpack numBytes=0, but the "
6864 "number of entries to unpack (as reported by numPacketsPerLID) "
6865 "for this row numEnt=" << numEnt <<
" != 0.");
6870 if (numEnt == 0 && numBytes != 0) {
6871 const int myRank = this->getMap ()->getComm ()->getRank ();
6872 TEUCHOS_TEST_FOR_EXCEPTION
6873 (
true, std::logic_error,
"(Proc " << myRank <<
") CrsMatrix::"
6874 "unpackRow: The number of entries to unpack (as reported by "
6875 "numPacketsPerLID) numEnt=0, but the number of bytes to unpack "
6876 "numBytes=" << numBytes <<
" != 0.");
6882 const size_t numEntBeg = offset;
6884 const size_t gidsBeg = numEntBeg + numEntLen;
6885 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount (gid);
6886 const size_t valsBeg = gidsBeg + gidsLen;
6887 const size_t valsLen = numEnt * numBytesPerValue;
6889 const char*
const numEntIn = imports + numEntBeg;
6890 const char*
const gidsIn = imports + gidsBeg;
6891 const char*
const valsIn = imports + valsBeg;
6893 size_t numBytesOut = 0;
6897 if (
static_cast<size_t> (numEntOut) != numEnt ||
6898 numEntOut ==
static_cast<LO
> (0)) {
6899 const int myRank = this->getMap ()->getComm ()->getRank ();
6900 std::ostringstream os;
6901 os <<
"(Proc " << myRank <<
") CrsMatrix::unpackRow: ";
6902 bool firstErrorCondition =
false;
6903 if (
static_cast<size_t> (numEntOut) != numEnt) {
6904 os <<
"Number of entries from numPacketsPerLID numEnt=" << numEnt
6905 <<
" does not equal number of entries unpacked from imports "
6906 "buffer numEntOut=" << numEntOut <<
".";
6907 firstErrorCondition =
true;
6909 if (numEntOut ==
static_cast<LO
> (0)) {
6910 if (firstErrorCondition) {
6913 os <<
"Number of entries unpacked from imports buffer numEntOut=0, "
6914 "but number of bytes to unpack for this row numBytes=" << numBytes
6915 <<
" != 0. This should never happen, since packRow should only "
6916 "ever pack rows with a nonzero number of entries. In this case, "
6917 "the number of entries from numPacketsPerLID is numEnt=" << numEnt
6920 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, os.str ());
6924 Kokkos::pair<int, size_t> p;
6925 p = PackTraits<GO>::unpackArray (gidsOut, gidsIn, numEnt);
6926 errorCode += p.first;
6927 numBytesOut += p.second;
6929 p = PackTraits<ST>::unpackArray (valsOut, valsIn, numEnt);
6930 errorCode += p.first;
6931 numBytesOut += p.second;
6934 TEUCHOS_TEST_FOR_EXCEPTION
6935 (numBytesOut != numBytes, std::logic_error,
"unpackRow: numBytesOut = "
6936 << numBytesOut <<
" != numBytes = " << numBytes <<
".");
6938 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
6939 TEUCHOS_TEST_FOR_EXCEPTION
6940 (numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: "
6941 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = "
6942 << expectedNumBytes <<
".");
6944 TEUCHOS_TEST_FOR_EXCEPTION
6945 (errorCode != 0, std::runtime_error,
"unpackRow: "
6946 "PackTraits::unpackArray returned a nonzero error code");
6951 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6953 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
6954 allocatePackSpaceNew (Kokkos::DualView<char*, buffer_device_type>& exports,
6955 size_t& totalNumEntries,
6956 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs)
const
6958 using Details::Behavior;
6961 typedef impl_scalar_type IST;
6962 typedef LocalOrdinal LO;
6963 typedef GlobalOrdinal GO;
6969 const bool verbose = Behavior::verbose(
"CrsMatrix");
6970 std::unique_ptr<std::string> prefix;
6972 prefix = this->
createPrefix(
"CrsMatrix",
"allocatePackSpaceNew");
6973 std::ostringstream os;
6974 os << *prefix <<
"Before:"
6982 std::cerr << os.str ();
6987 const LO numExportLIDs =
static_cast<LO
> (exportLIDs.extent (0));
6989 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
6990 auto exportLIDs_h = exportLIDs.view_host ();
6993 totalNumEntries = 0;
6994 for (LO i = 0; i < numExportLIDs; ++i) {
6995 const LO lclRow = exportLIDs_h[i];
6996 size_t curNumEntries = this->getNumEntriesInLocalRow (lclRow);
6999 if (curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7002 totalNumEntries += curNumEntries;
7013 const size_t allocSize =
7014 static_cast<size_t> (numExportLIDs) *
sizeof (LO) +
7015 totalNumEntries * (
sizeof (IST) +
sizeof (GO));
7016 if (
static_cast<size_t> (exports.extent (0)) < allocSize) {
7017 using exports_type = Kokkos::DualView<char*, buffer_device_type>;
7019 const std::string oldLabel = exports.d_view.label ();
7020 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
7021 exports = exports_type (newLabel, allocSize);
7025 std::ostringstream os;
7026 os << *prefix <<
"After:"
7034 std::cerr << os.str ();
7038 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7041 packNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7042 Kokkos::DualView<char*, buffer_device_type>& exports,
7043 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7044 size_t& constantNumPackets)
const
7048 if (this->isStaticGraph ()) {
7051 constantNumPackets);
7054 this->packNonStaticNew (exportLIDs, exports, numPacketsPerLID,
7055 constantNumPackets);
7059 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7062 packNonStaticNew (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
7063 Kokkos::DualView<char*, buffer_device_type>& exports,
7064 const Kokkos::DualView<size_t*, buffer_device_type>& numPacketsPerLID,
7065 size_t& constantNumPackets)
const
7073 using LO = LocalOrdinal;
7074 using GO = GlobalOrdinal;
7075 using ST = impl_scalar_type;
7076 const char tfecfFuncName[] =
"packNonStaticNew: ";
7078 const bool verbose = Behavior::verbose(
"CrsMatrix");
7079 std::unique_ptr<std::string> prefix;
7081 prefix = this->createPrefix(
"CrsMatrix",
"packNonStaticNew");
7082 std::ostringstream os;
7083 os << *prefix <<
"Start" << endl;
7084 std::cerr << os.str ();
7087 const size_t numExportLIDs =
static_cast<size_t> (exportLIDs.extent (0));
7088 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7089 (numExportLIDs !=
static_cast<size_t> (numPacketsPerLID.extent (0)),
7090 std::invalid_argument,
"exportLIDs.size() = " << numExportLIDs
7091 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.extent (0)
7097 constantNumPackets = 0;
7102 size_t totalNumEntries = 0;
7103 this->allocatePackSpaceNew (exports, totalNumEntries, exportLIDs);
7104 const size_t bufSize =
static_cast<size_t> (exports.extent (0));
7107 exports.clear_sync_state();
7108 exports.modify_host();
7109 auto exports_h = exports.view_host ();
7111 std::ostringstream os;
7112 os << *prefix <<
"After marking exports as modified on host, "
7114 std::cerr << os.str ();
7118 auto exportLIDs_h = exportLIDs.view_host ();
7121 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->clear_sync_state();
7122 const_cast<Kokkos::DualView<size_t*, buffer_device_type>*
>(&numPacketsPerLID)->modify_host();
7123 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
7128 auto maxRowNumEnt = this->getNodeMaxNumRowEntries();
7132 typename global_inds_host_view_type::non_const_type gidsIn_k;
7133 if (this->isLocallyIndexed()) {
7135 typename global_inds_host_view_type::non_const_type(
"packGids",
7140 for (
size_t i = 0; i < numExportLIDs; ++i) {
7141 const LO lclRow = exportLIDs_h[i];
7145 numEnt = this->getNumEntriesInLocalRow (lclRow);
7152 numPacketsPerLID_h[i] = 0;
7156 if (this->isLocallyIndexed ()) {
7157 typename global_inds_host_view_type::non_const_type gidsIn;
7158 values_host_view_type valsIn;
7162 local_inds_host_view_type lidsIn;
7163 this->getLocalRowView (lclRow, lidsIn, valsIn);
7164 const map_type& colMap = * (this->getColMap ());
7165 for (
size_t k = 0; k < numEnt; ++k) {
7168 gidsIn = Kokkos::subview(gidsIn_k, Kokkos::make_pair(GO(0),GO(numEnt)));
7170 const size_t numBytesPerValue =
7171 PackTraits<ST>::packValueCount (valsIn[0]);
7172 numBytes = this->
packRow (exports_h.data (), offset, numEnt,
7173 gidsIn.data (), valsIn.data (),
7176 else if (this->isGloballyIndexed ()) {
7177 global_inds_host_view_type gidsIn;
7178 values_host_view_type valsIn;
7184 const map_type& rowMap = * (this->getRowMap ());
7185 const GO gblRow = rowMap.getGlobalElement (lclRow);
7186 this->getGlobalRowView (gblRow, gidsIn, valsIn);
7188 const size_t numBytesPerValue =
7189 PackTraits<ST>::packValueCount (valsIn[0]);
7190 numBytes = this->
packRow (exports_h.data (), offset, numEnt,
7191 gidsIn.data (), valsIn.data (),
7198 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7199 (offset > bufSize || offset + numBytes > bufSize, std::logic_error,
7200 "First invalid offset into 'exports' pack buffer at index i = " << i
7201 <<
". exportLIDs_h[i]: " << exportLIDs_h[i] <<
", bufSize: " <<
7202 bufSize <<
", offset: " << offset <<
", numBytes: " << numBytes <<
7207 numPacketsPerLID_h[i] = numBytes;
7212 std::ostringstream os;
7213 os << *prefix <<
"Tpetra::CrsMatrix::packNonStaticNew: After:" << endl
7220 std::cerr << os.str ();
7224 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7226 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7227 combineGlobalValuesRaw(
const LocalOrdinal lclRow,
7228 const LocalOrdinal numEnt,
7229 const impl_scalar_type vals[],
7230 const GlobalOrdinal cols[],
7232 const char*
const prefix,
7236 using GO = GlobalOrdinal;
7240 const GO gblRow = myGraph_->rowMap_->getGlobalElement(lclRow);
7241 Teuchos::ArrayView<const GO> cols_av
7242 (numEnt == 0 ?
nullptr : cols, numEnt);
7243 Teuchos::ArrayView<const Scalar> vals_av
7244 (numEnt == 0 ?
nullptr :
reinterpret_cast<const Scalar*
> (vals), numEnt);
7249 combineGlobalValues(gblRow, cols_av, vals_av, combMode,
7250 prefix, debug, verbose);
7254 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7256 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7257 combineGlobalValues(
7258 const GlobalOrdinal globalRowIndex,
7259 const Teuchos::ArrayView<const GlobalOrdinal>& columnIndices,
7260 const Teuchos::ArrayView<const Scalar>& values,
7262 const char*
const prefix,
7266 const char tfecfFuncName[] =
"combineGlobalValues: ";
7268 if (isStaticGraph ()) {
7272 if (combineMode ==
ADD) {
7273 sumIntoGlobalValues (globalRowIndex, columnIndices, values);
7275 else if (combineMode ==
REPLACE) {
7276 replaceGlobalValues (globalRowIndex, columnIndices, values);
7278 else if (combineMode ==
ABSMAX) {
7279 using ::Tpetra::Details::AbsMax;
7281 this->
template transformGlobalValues<AbsMax<Scalar> > (globalRowIndex,
7285 else if (combineMode ==
INSERT) {
7286 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7287 (isStaticGraph() && combineMode ==
INSERT,
7288 std::invalid_argument,
"INSERT combine mode is forbidden "
7289 "if the matrix has a static (const) graph (i.e., was "
7290 "constructed with the CrsMatrix constructor that takes a "
7291 "const CrsGraph pointer).");
7294 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7295 (
true, std::logic_error,
"Invalid combine mode; should "
7297 "Please report this bug to the Tpetra developers.");
7301 if (combineMode ==
ADD || combineMode ==
INSERT) {
7308 insertGlobalValuesFilteredChecked(globalRowIndex,
7309 columnIndices, values, prefix, debug, verbose);
7320 else if (combineMode ==
ABSMAX) {
7321 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7322 ! isStaticGraph () && combineMode ==
ABSMAX, std::logic_error,
7323 "ABSMAX combine mode when the matrix has a dynamic graph is not yet "
7326 else if (combineMode ==
REPLACE) {
7327 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7328 ! isStaticGraph () && combineMode ==
REPLACE, std::logic_error,
7329 "REPLACE combine mode when the matrix has a dynamic graph is not yet "
7333 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
7334 true, std::logic_error,
"Should never get here! Please report this "
7335 "bug to the Tpetra developers.");
7340 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7344 (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& importLIDs,
7345 Kokkos::DualView<char*, buffer_device_type> imports,
7346 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7347 const size_t constantNumPackets,
7354 const char tfecfFuncName[] =
"unpackAndCombine: ";
7355 ProfilingRegion regionUAC (
"Tpetra::CrsMatrix::unpackAndCombine");
7357 const bool debug = Behavior::debug(
"CrsMatrix");
7358 const bool verbose = Behavior::verbose(
"CrsMatrix");
7359 constexpr
int numValidModes = 5;
7362 const char* validModeNames[numValidModes] =
7363 {
"ADD",
"REPLACE",
"ABSMAX",
"INSERT",
"ZERO"};
7365 std::unique_ptr<std::string> prefix;
7367 prefix = this->createPrefix(
"CrsMatrix",
"unpackAndCombine");
7368 std::ostringstream os;
7369 os << *prefix <<
"Start:" << endl
7379 << *prefix <<
" constantNumPackets: " << constantNumPackets
7383 std::cerr << os.str ();
7387 if (std::find (validModes, validModes+numValidModes, combineMode) ==
7388 validModes+numValidModes) {
7389 std::ostringstream os;
7390 os <<
"Invalid combine mode. Valid modes are {";
7391 for (
int k = 0; k < numValidModes; ++k) {
7392 os << validModeNames[k];
7393 if (k < numValidModes - 1) {
7398 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7399 (
true, std::invalid_argument, os.str ());
7401 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7402 (importLIDs.extent(0) != numPacketsPerLID.extent(0),
7403 std::invalid_argument,
"importLIDs.extent(0)="
7404 << importLIDs.extent(0)
7405 <<
" != numPacketsPerLID.extent(0)="
7406 << numPacketsPerLID.extent(0) <<
".");
7409 if (combineMode ==
ZERO) {
7414 using Teuchos::reduceAll;
7415 std::unique_ptr<std::ostringstream> msg (
new std::ostringstream ());
7418 unpackAndCombineImpl(importLIDs, imports, numPacketsPerLID,
7419 constantNumPackets, combineMode,
7421 }
catch (std::exception& e) {
7426 const Teuchos::Comm<int>& comm = * (this->getComm ());
7427 reduceAll<int, int> (comm, Teuchos::REDUCE_MAX,
7428 lclBad, Teuchos::outArg (gblBad));
7434 std::ostringstream os;
7435 os <<
"Proc " << comm.getRank () <<
": " << msg->str () << endl;
7436 msg = std::unique_ptr<std::ostringstream> (
new std::ostringstream ());
7437 ::Tpetra::Details::gathervPrint (*msg, os.str (), comm);
7438 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7439 (
true, std::logic_error, std::endl <<
"unpackAndCombineImpl "
7440 "threw an exception on one or more participating processes: "
7441 << endl << msg->str ());
7445 unpackAndCombineImpl(importLIDs, imports, numPacketsPerLID,
7446 constantNumPackets, combineMode,
7451 std::ostringstream os;
7452 os << *prefix <<
"Done!" << endl
7462 std::cerr << os.str ();
7466 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7470 const Kokkos::DualView<
const local_ordinal_type*,
7471 buffer_device_type>& importLIDs,
7472 Kokkos::DualView<char*, buffer_device_type> imports,
7473 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7474 const size_t constantNumPackets,
7479 "Tpetra::CrsMatrix::unpackAndCombineImpl",
7483 const char tfecfFuncName[] =
"unpackAndCombineImpl";
7484 std::unique_ptr<std::string> prefix;
7486 prefix = this->createPrefix(
"CrsMatrix", tfecfFuncName);
7487 std::ostringstream os;
7488 os << *prefix <<
"isStaticGraph(): "
7489 << (isStaticGraph() ?
"true" :
"false")
7490 <<
", importLIDs.extent(0): "
7491 << importLIDs.extent(0)
7492 <<
", imports.extent(0): "
7493 << imports.extent(0)
7494 <<
", numPacketsPerLID.extent(0): "
7495 << numPacketsPerLID.extent(0)
7497 std::cerr << os.str();
7500 if (isStaticGraph ()) {
7501 using Details::unpackCrsMatrixAndCombineNew;
7502 unpackCrsMatrixAndCombineNew(*
this, imports, numPacketsPerLID,
7503 importLIDs, constantNumPackets,
7508 using padding_type =
typename crs_graph_type::padding_type;
7509 std::unique_ptr<padding_type> padding;
7511 padding = myGraph_->computePaddingForCrsMatrixUnpack(
7512 importLIDs, imports, numPacketsPerLID, verbose);
7514 catch (std::exception& e) {
7515 const auto rowMap = getRowMap();
7516 const auto comm = rowMap.is_null() ? Teuchos::null :
7518 const int myRank = comm.is_null() ? -1 : comm->getRank();
7519 TEUCHOS_TEST_FOR_EXCEPTION
7520 (
true, std::runtime_error,
"Proc " << myRank <<
": "
7521 "Tpetra::CrsGraph::computePaddingForCrsMatrixUnpack "
7522 "threw an exception: " << e.what());
7525 std::ostringstream os;
7526 os << *prefix <<
"Call applyCrsPadding" << endl;
7527 std::cerr << os.str();
7529 applyCrsPadding(*padding, verbose);
7532 std::ostringstream os;
7533 os << *prefix <<
"Call unpackAndCombineImplNonStatic" << endl;
7534 std::cerr << os.str();
7536 unpackAndCombineImplNonStatic(importLIDs, imports,
7543 std::ostringstream os;
7544 os << *prefix <<
"Done" << endl;
7545 std::cerr << os.str();
7549 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7551 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
7552 unpackAndCombineImplNonStatic(
7553 const Kokkos::DualView<
const local_ordinal_type*,
7554 buffer_device_type>& importLIDs,
7555 Kokkos::DualView<char*, buffer_device_type> imports,
7556 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
7557 const size_t constantNumPackets,
7561 using Kokkos::subview;
7562 using Kokkos::MemoryUnmanaged;
7563 using Details::Behavior;
7566 using Details::PackTraits;
7567 using Details::ScalarViewTraits;
7569 using LO = LocalOrdinal;
7570 using GO = GlobalOrdinal;
7571 using ST = impl_scalar_type;
7572 using size_type =
typename Teuchos::ArrayView<LO>::size_type;
7574 typename View<int*, device_type>::HostMirror::execution_space;
7575 using pair_type = std::pair<typename View<int*, HES>::size_type,
7576 typename View<int*, HES>::size_type>;
7577 using gids_out_type = View<GO*, HES, MemoryUnmanaged>;
7578 using vals_out_type = View<ST*, HES, MemoryUnmanaged>;
7579 const char tfecfFuncName[] =
"unpackAndCombineImplNonStatic";
7581 const bool debug = Behavior::debug(
"CrsMatrix");
7582 const bool verbose = Behavior::verbose(
"CrsMatrix");
7583 std::unique_ptr<std::string> prefix;
7585 prefix = this->
createPrefix(
"CrsMatrix", tfecfFuncName);
7586 std::ostringstream os;
7587 os << *prefix << endl;
7588 std::cerr << os.str ();
7590 const char*
const prefix_raw =
7591 verbose ? prefix.get()->c_str() :
nullptr;
7593 const size_type numImportLIDs = importLIDs.extent (0);
7594 if (combineMode ==
ZERO || numImportLIDs == 0) {
7598 Details::ProfilingRegion region_unpack_and_combine_impl_non_static(
7599 "Tpetra::CrsMatrix::unpackAndCombineImplNonStatic",
7604 if (imports.need_sync_host()) {
7605 imports.sync_host ();
7607 auto imports_h = imports.view_host();
7610 if (numPacketsPerLID.need_sync_host()) {
7611 numPacketsPerLID.sync_host ();
7613 auto numPacketsPerLID_h = numPacketsPerLID.view_host();
7615 TEUCHOS_ASSERT( ! importLIDs.need_sync_host() );
7616 auto importLIDs_h = importLIDs.view_host();
7618 size_t numBytesPerValue;
7629 numBytesPerValue = PackTraits<ST>::packValueCount (val);
7634 size_t maxRowNumEnt = 0;
7635 for (size_type i = 0; i < numImportLIDs; ++i) {
7636 const size_t numBytes = numPacketsPerLID_h[i];
7637 if (numBytes == 0) {
7642 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7643 (offset + numBytes >
size_t(imports_h.extent (0)),
7644 std::logic_error,
": At local row index importLIDs_h[i="
7645 << i <<
"]=" << importLIDs_h[i] <<
", offset (=" << offset
7646 <<
") + numBytes (=" << numBytes <<
") > "
7647 "imports_h.extent(0)=" << imports_h.extent (0) <<
".");
7652 const size_t theNumBytes =
7654 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7655 (theNumBytes > numBytes, std::logic_error,
": theNumBytes="
7656 << theNumBytes <<
" > numBytes = " << numBytes <<
".");
7658 const char*
const inBuf = imports_h.data () + offset;
7659 const size_t actualNumBytes =
7663 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7664 (actualNumBytes > numBytes, std::logic_error,
": At i=" << i
7665 <<
", actualNumBytes=" << actualNumBytes
7666 <<
" > numBytes=" << numBytes <<
".");
7667 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7668 (numEntLO == 0, std::logic_error,
": At local row index "
7669 "importLIDs_h[i=" << i <<
"]=" << importLIDs_h[i] <<
", "
7670 "the number of entries read from the packed data is "
7671 "numEntLO=" << numEntLO <<
", but numBytes=" << numBytes
7675 maxRowNumEnt = std::max(
size_t(numEntLO), maxRowNumEnt);
7683 View<GO*, HES> gblColInds;
7684 View<LO*, HES> lclColInds;
7685 View<ST*, HES> vals;
7698 gblColInds = ScalarViewTraits<GO, HES>::allocateArray(
7699 gid, maxRowNumEnt,
"gids");
7700 lclColInds = ScalarViewTraits<LO, HES>::allocateArray(
7701 lid, maxRowNumEnt,
"lids");
7702 vals = ScalarViewTraits<ST, HES>::allocateArray(
7703 val, maxRowNumEnt,
"vals");
7707 for (size_type i = 0; i < numImportLIDs; ++i) {
7708 const size_t numBytes = numPacketsPerLID_h[i];
7709 if (numBytes == 0) {
7713 const char*
const inBuf = imports_h.data () + offset;
7716 const size_t numEnt =
static_cast<size_t>(numEntLO);;
7717 const LO lclRow = importLIDs_h[i];
7719 gids_out_type gidsOut = subview (gblColInds, pair_type (0, numEnt));
7720 vals_out_type valsOut = subview (vals, pair_type (0, numEnt));
7722 const size_t numBytesOut =
7723 unpackRow (gidsOut.data (), valsOut.data (), imports_h.data (),
7724 offset, numBytes, numEnt, numBytesPerValue);
7725 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
7726 (numBytes != numBytesOut, std::logic_error,
": At i=" << i
7727 <<
", numBytes=" << numBytes <<
" != numBytesOut="
7728 << numBytesOut <<
".");
7730 const ST*
const valsRaw =
const_cast<const ST*
> (valsOut.data ());
7731 const GO*
const gidsRaw =
const_cast<const GO*
> (gidsOut.data ());
7732 combineGlobalValuesRaw(lclRow, numEnt, valsRaw, gidsRaw,
7733 combineMode, prefix_raw, debug, verbose);
7739 std::ostringstream os;
7740 os << *prefix <<
"Done" << endl;
7741 std::cerr << os.str();
7745 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7746 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
7749 const bool force)
const
7751 using Teuchos::null;
7755 TEUCHOS_TEST_FOR_EXCEPTION(
7756 ! this->hasColMap (), std::runtime_error,
"Tpetra::CrsMatrix::getColumn"
7757 "MapMultiVector: You may only call this method if the matrix has a "
7758 "column Map. If the matrix does not yet have a column Map, you should "
7759 "first call fillComplete (with domain and range Map if necessary).");
7763 TEUCHOS_TEST_FOR_EXCEPTION(
7764 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
7765 "CrsMatrix::getColumnMapMultiVector: You may only call this method if "
7766 "this matrix's graph is fill complete.");
7769 RCP<const import_type> importer = this->getGraph ()->getImporter ();
7770 RCP<const map_type> colMap = this->getColMap ();
7783 if (! importer.is_null () || force) {
7784 if (importMV_.is_null () || importMV_->getNumVectors () != numVecs) {
7785 X_colMap = rcp (
new MV (colMap, numVecs));
7788 importMV_ = X_colMap;
7791 X_colMap = importMV_;
7802 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7803 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
7806 const bool force)
const
7808 using Teuchos::null;
7814 TEUCHOS_TEST_FOR_EXCEPTION(
7815 ! this->getGraph ()->isFillComplete (), std::runtime_error,
"Tpetra::"
7816 "CrsMatrix::getRowMapMultiVector: You may only call this method if this "
7817 "matrix's graph is fill complete.");
7820 RCP<const export_type> exporter = this->getGraph ()->getExporter ();
7824 RCP<const map_type> rowMap = this->getRowMap ();
7836 if (! exporter.is_null () || force) {
7837 if (exportMV_.is_null () || exportMV_->getNumVectors () != numVecs) {
7838 Y_rowMap = rcp (
new MV (rowMap, numVecs));
7839 exportMV_ = Y_rowMap;
7842 Y_rowMap = exportMV_;
7848 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7853 TEUCHOS_TEST_FOR_EXCEPTION(
7854 myGraph_.is_null (), std::logic_error,
"Tpetra::CrsMatrix::"
7855 "removeEmptyProcessesInPlace: This method does not work when the matrix "
7856 "was created with a constant graph (that is, when it was created using "
7857 "the version of its constructor that takes an RCP<const CrsGraph>). "
7858 "This is because the matrix is not allowed to modify the graph in that "
7859 "case, but removing empty processes requires modifying the graph.");
7860 myGraph_->removeEmptyProcessesInPlace (newMap);
7864 this->map_ = this->getRowMap ();
7868 staticGraph_ = Teuchos::rcp_const_cast<const Graph> (myGraph_);
7871 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7872 Teuchos::RCP<RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
7874 add (
const Scalar& alpha,
7877 const Teuchos::RCP<const map_type>& domainMap,
7878 const Teuchos::RCP<const map_type>& rangeMap,
7879 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
7881 using Teuchos::Array;
7882 using Teuchos::ArrayView;
7883 using Teuchos::ParameterList;
7886 using Teuchos::rcp_implicit_cast;
7887 using Teuchos::sublist;
7891 using crs_matrix_type =
7893 const char errPfx[] =
"Tpetra::CrsMatrix::add: ";
7897 std::unique_ptr<std::string> prefix;
7899 prefix = this->createPrefix(
"CrsMatrix",
"add");
7900 std::ostringstream os;
7901 os << *prefix <<
"Start" << endl;
7902 std::cerr << os.str ();
7905 const crs_matrix_type& B = *
this;
7906 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero();
7907 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one();
7914 RCP<const map_type> A_rangeMap = A.
getRangeMap ();
7915 RCP<const map_type> B_domainMap = B.getDomainMap ();
7916 RCP<const map_type> B_rangeMap = B.getRangeMap ();
7918 RCP<const map_type> theDomainMap = domainMap;
7919 RCP<const map_type> theRangeMap = rangeMap;
7921 if (domainMap.is_null ()) {
7922 if (B_domainMap.is_null ()) {
7923 TEUCHOS_TEST_FOR_EXCEPTION(
7924 A_domainMap.is_null (), std::invalid_argument,
7925 "Tpetra::CrsMatrix::add: If neither A nor B have a domain Map, "
7926 "then you must supply a nonnull domain Map to this method.");
7927 theDomainMap = A_domainMap;
7929 theDomainMap = B_domainMap;
7932 if (rangeMap.is_null ()) {
7933 if (B_rangeMap.is_null ()) {
7934 TEUCHOS_TEST_FOR_EXCEPTION(
7935 A_rangeMap.is_null (), std::invalid_argument,
7936 "Tpetra::CrsMatrix::add: If neither A nor B have a range Map, "
7937 "then you must supply a nonnull range Map to this method.");
7938 theRangeMap = A_rangeMap;
7940 theRangeMap = B_rangeMap;
7948 if (! A_domainMap.is_null() && ! A_rangeMap.is_null()) {
7949 if (! B_domainMap.is_null() && ! B_rangeMap.is_null()) {
7950 TEUCHOS_TEST_FOR_EXCEPTION
7951 (! B_domainMap->isSameAs(*A_domainMap),
7952 std::invalid_argument,
7953 errPfx <<
"The input RowMatrix A must have a domain Map "
7954 "which is the same as (isSameAs) this RowMatrix's "
7956 TEUCHOS_TEST_FOR_EXCEPTION
7957 (! B_rangeMap->isSameAs(*A_rangeMap), std::invalid_argument,
7958 errPfx <<
"The input RowMatrix A must have a range Map "
7959 "which is the same as (isSameAs) this RowMatrix's range "
7961 TEUCHOS_TEST_FOR_EXCEPTION
7962 (! domainMap.is_null() &&
7963 ! domainMap->isSameAs(*B_domainMap),
7964 std::invalid_argument,
7965 errPfx <<
"The input domain Map must be the same as "
7966 "(isSameAs) this RowMatrix's domain Map.");
7967 TEUCHOS_TEST_FOR_EXCEPTION
7968 (! rangeMap.is_null() &&
7969 ! rangeMap->isSameAs(*B_rangeMap),
7970 std::invalid_argument,
7971 errPfx <<
"The input range Map must be the same as "
7972 "(isSameAs) this RowMatrix's range Map.");
7975 else if (! B_domainMap.is_null() && ! B_rangeMap.is_null()) {
7976 TEUCHOS_TEST_FOR_EXCEPTION
7977 (! domainMap.is_null() &&
7978 ! domainMap->isSameAs(*B_domainMap),
7979 std::invalid_argument,
7980 errPfx <<
"The input domain Map must be the same as "
7981 "(isSameAs) this RowMatrix's domain Map.");
7982 TEUCHOS_TEST_FOR_EXCEPTION
7983 (! rangeMap.is_null() && ! rangeMap->isSameAs(*B_rangeMap),
7984 std::invalid_argument,
7985 errPfx <<
"The input range Map must be the same as "
7986 "(isSameAs) this RowMatrix's range Map.");
7989 TEUCHOS_TEST_FOR_EXCEPTION
7990 (domainMap.is_null() || rangeMap.is_null(),
7991 std::invalid_argument, errPfx <<
"If neither A nor B "
7992 "have a domain and range Map, then you must supply a "
7993 "nonnull domain and range Map to this method.");
8000 bool callFillComplete =
true;
8001 RCP<ParameterList> constructorSublist;
8002 RCP<ParameterList> fillCompleteSublist;
8003 if (! params.is_null()) {
8005 params->get(
"Call fillComplete", callFillComplete);
8006 constructorSublist = sublist(params,
"Constructor parameters");
8007 fillCompleteSublist = sublist(params,
"fillComplete parameters");
8010 RCP<const map_type> A_rowMap = A.
getRowMap ();
8011 RCP<const map_type> B_rowMap = B.getRowMap ();
8012 RCP<const map_type> C_rowMap = B_rowMap;
8013 RCP<crs_matrix_type> C;
8020 if (A_rowMap->isSameAs (*B_rowMap)) {
8021 const LO localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8022 Array<size_t> C_maxNumEntriesPerRow (localNumRows, 0);
8025 if (alpha !=
ZERO) {
8026 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8028 C_maxNumEntriesPerRow[localRow] += A_numEntries;
8033 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
8034 const size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8035 C_maxNumEntriesPerRow[localRow] += B_numEntries;
8039 if (constructorSublist.is_null ()) {
8040 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8043 C = rcp (
new crs_matrix_type (C_rowMap, C_maxNumEntriesPerRow (),
8044 StaticProfile, constructorSublist));
8055 TEUCHOS_TEST_FOR_EXCEPTION
8056 (
true, std::invalid_argument, errPfx <<
"The row maps must "
8057 "be the same for statically allocated matrices, to ensure "
8058 "that there is sufficient space to do the addition.");
8061 TEUCHOS_TEST_FOR_EXCEPTION
8062 (C.is_null (), std::logic_error,
8063 errPfx <<
"C should not be null at this point. "
8064 "Please report this bug to the Tpetra developers.");
8067 std::ostringstream os;
8068 os << *prefix <<
"Compute C = alpha*A + beta*B" << endl;
8069 std::cerr << os.str ();
8071 using gids_type = nonconst_global_inds_host_view_type;
8072 using vals_type = nonconst_values_host_view_type;
8076 if (alpha !=
ZERO) {
8077 const LO A_localNumRows =
static_cast<LO
> (A_rowMap->getNodeNumElements ());
8078 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
8080 const GO globalRow = A_rowMap->getGlobalElement (localRow);
8081 if (A_numEntries >
static_cast<size_t> (ind.size ())) {
8082 Kokkos::resize(ind,A_numEntries);
8083 Kokkos::resize(val,A_numEntries);
8085 gids_type indView = Kokkos::subview(ind,std::make_pair((
size_t)0, A_numEntries));
8086 vals_type valView = Kokkos::subview(val,std::make_pair((
size_t)0, A_numEntries));
8090 for (
size_t k = 0; k < A_numEntries; ++k) {
8091 valView[k] *= alpha;
8094 C->insertGlobalValues (globalRow, A_numEntries,
8095 reinterpret_cast<Scalar *
>(valView.data()),
8101 const LO B_localNumRows =
static_cast<LO
> (B_rowMap->getNodeNumElements ());
8102 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
8103 size_t B_numEntries = B.getNumEntriesInLocalRow (localRow);
8104 const GO globalRow = B_rowMap->getGlobalElement (localRow);
8105 if (B_numEntries >
static_cast<size_t> (ind.size ())) {
8106 Kokkos::resize(ind,B_numEntries);
8107 Kokkos::resize(val,B_numEntries);
8109 gids_type indView = Kokkos::subview(ind,std::make_pair((
size_t)0, B_numEntries));
8110 vals_type valView = Kokkos::subview(val,std::make_pair((
size_t)0, B_numEntries));
8111 B.getGlobalRowCopy (globalRow, indView, valView, B_numEntries);
8114 for (
size_t k = 0; k < B_numEntries; ++k) {
8118 C->insertGlobalValues (globalRow, B_numEntries,
8119 reinterpret_cast<Scalar *
>(valView.data()),
8124 if (callFillComplete) {
8126 std::ostringstream os;
8127 os << *prefix <<
"Call fillComplete on C" << endl;
8128 std::cerr << os.str ();
8130 if (fillCompleteSublist.is_null ()) {
8131 C->fillComplete (theDomainMap, theRangeMap);
8133 C->fillComplete (theDomainMap, theRangeMap, fillCompleteSublist);
8137 std::ostringstream os;
8138 os << *prefix <<
"Do NOT call fillComplete on C" << endl;
8139 std::cerr << os.str ();
8143 std::ostringstream os;
8144 os << *prefix <<
"Done" << endl;
8145 std::cerr << os.str ();
8147 return rcp_implicit_cast<row_matrix_type> (C);
8152 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
8156 const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node>& rowTransfer,
8157 const Teuchos::RCP<const ::Tpetra::Details::Transfer<LocalOrdinal, GlobalOrdinal, Node> > & domainTransfer,
8158 const Teuchos::RCP<const map_type>& domainMap,
8159 const Teuchos::RCP<const map_type>& rangeMap,
8160 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
8167 using Teuchos::ArrayRCP;
8168 using Teuchos::ArrayView;
8169 using Teuchos::Comm;
8170 using Teuchos::ParameterList;
8173 typedef LocalOrdinal LO;
8174 typedef GlobalOrdinal GO;
8175 typedef node_type NT;
8180 const bool debug = Behavior::debug(
"CrsMatrix");
8181 const bool verbose = Behavior::verbose(
"CrsMatrix");
8182 int MyPID = getComm ()->getRank ();
8184 std::unique_ptr<std::string> verbosePrefix;
8187 this->createPrefix(
"CrsMatrix",
"transferAndFillComplete");
8188 std::ostringstream os;
8189 os <<
"Start" << endl;
8190 std::cerr << os.str();
8197 bool reverseMode =
false;
8198 bool restrictComm =
false;
8200 int mm_optimization_core_count =
8201 Behavior::TAFC_OptimizationCoreCount();
8202 RCP<ParameterList> matrixparams;
8203 bool overrideAllreduce =
false;
8204 if (! params.is_null ()) {
8205 matrixparams = sublist (params,
"CrsMatrix");
8206 reverseMode = params->get (
"Reverse Mode", reverseMode);
8207 restrictComm = params->get (
"Restrict Communicator", restrictComm);
8208 auto & slist = params->sublist(
"matrixmatrix: kernel params",
false);
8209 isMM = slist.get(
"isMatrixMatrix_TransferAndFillComplete",
false);
8210 mm_optimization_core_count = slist.get(
"MM_TAFC_OptimizationCoreCount",mm_optimization_core_count);
8212 overrideAllreduce = slist.get(
"MM_TAFC_OverrideAllreduceCheck",
false);
8213 if(getComm()->getSize() < mm_optimization_core_count && isMM) isMM =
false;
8214 if(reverseMode) isMM =
false;
8218 std::shared_ptr< ::Tpetra::Details::CommRequest> iallreduceRequest;
8220 int reduced_mismatch = 0;
8221 if (isMM && !overrideAllreduce) {
8224 const bool source_vals = ! getGraph ()->getImporter ().is_null();
8225 const bool target_vals = ! (rowTransfer.getExportLIDs ().size() == 0 ||
8226 rowTransfer.getRemoteLIDs ().size() == 0);
8227 mismatch = (source_vals != target_vals) ? 1 : 0;
8230 Teuchos::REDUCE_MAX, * (getComm ()));
8233 #ifdef HAVE_TPETRA_MMM_TIMINGS
8234 using Teuchos::TimeMonitor;
8236 if(!params.is_null())
8237 label = params->get(
"Timer Label",label);
8238 std::string prefix = std::string(
"Tpetra ")+ label + std::string(
": ");
8241 std::ostringstream os;
8242 if(isMM) os<<
":MMOpt";
8243 else os<<
":MMLegacy";
8247 Teuchos::TimeMonitor MMall(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC All") +tlstr ));
8255 const import_type* xferAsImport =
dynamic_cast<const import_type*
> (&rowTransfer);
8256 const export_type* xferAsExport =
dynamic_cast<const export_type*
> (&rowTransfer);
8257 TEUCHOS_TEST_FOR_EXCEPTION(
8258 xferAsImport ==
nullptr && xferAsExport ==
nullptr, std::invalid_argument,
8259 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' input "
8260 "argument must be either an Import or an Export, and its template "
8261 "parameters must match the corresponding template parameters of the "
8269 Teuchos::RCP<const import_type> xferDomainAsImport = Teuchos::rcp_dynamic_cast<const import_type> (domainTransfer);
8270 Teuchos::RCP<const export_type> xferDomainAsExport = Teuchos::rcp_dynamic_cast<const export_type> (domainTransfer);
8272 if(! domainTransfer.is_null()) {
8273 TEUCHOS_TEST_FOR_EXCEPTION(
8274 (xferDomainAsImport.is_null() && xferDomainAsExport.is_null()), std::invalid_argument,
8275 "Tpetra::CrsMatrix::transferAndFillComplete: The 'domainTransfer' input "
8276 "argument must be either an Import or an Export, and its template "
8277 "parameters must match the corresponding template parameters of the "
8280 TEUCHOS_TEST_FOR_EXCEPTION(
8281 ( xferAsImport !=
nullptr || ! xferDomainAsImport.is_null() ) &&
8282 (( xferAsImport !=
nullptr && xferDomainAsImport.is_null() ) ||
8283 ( xferAsImport ==
nullptr && ! xferDomainAsImport.is_null() )), std::invalid_argument,
8284 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8285 "arguments must be of the same type (either Import or Export).");
8287 TEUCHOS_TEST_FOR_EXCEPTION(
8288 ( xferAsExport !=
nullptr || ! xferDomainAsExport.is_null() ) &&
8289 (( xferAsExport !=
nullptr && xferDomainAsExport.is_null() ) ||
8290 ( xferAsExport ==
nullptr && ! xferDomainAsExport.is_null() )), std::invalid_argument,
8291 "Tpetra::CrsMatrix::transferAndFillComplete: The 'rowTransfer' and 'domainTransfer' input "
8292 "arguments must be of the same type (either Import or Export).");
8298 const bool communication_needed = rowTransfer.getSourceMap ()->isDistributed ();
8302 RCP<const map_type> MyRowMap = reverseMode ?
8303 rowTransfer.getSourceMap () : rowTransfer.getTargetMap ();
8304 RCP<const map_type> MyColMap;
8305 RCP<const map_type> MyDomainMap = ! domainMap.is_null () ?
8306 domainMap : getDomainMap ();
8307 RCP<const map_type> MyRangeMap = ! rangeMap.is_null () ?
8308 rangeMap : getRangeMap ();
8309 RCP<const map_type> BaseRowMap = MyRowMap;
8310 RCP<const map_type> BaseDomainMap = MyDomainMap;
8318 if (! destMat.is_null ()) {
8329 const bool NewFlag = ! destMat->getGraph ()->isLocallyIndexed () &&
8330 ! destMat->getGraph ()->isGloballyIndexed ();
8331 TEUCHOS_TEST_FOR_EXCEPTION(
8332 ! NewFlag, std::invalid_argument,
"Tpetra::CrsMatrix::"
8333 "transferAndFillComplete: The input argument 'destMat' is only allowed "
8334 "to be nonnull, if its graph is empty (neither locally nor globally "
8343 TEUCHOS_TEST_FOR_EXCEPTION(
8344 ! destMat->getRowMap ()->isSameAs (*MyRowMap), std::invalid_argument,
8345 "Tpetra::CrsMatrix::transferAndFillComplete: The (row) Map of the "
8346 "input argument 'destMat' is not the same as the (row) Map specified "
8347 "by the input argument 'rowTransfer'.");
8348 TEUCHOS_TEST_FOR_EXCEPTION(
8349 ! destMat->checkSizes (*
this), std::invalid_argument,
8350 "Tpetra::CrsMatrix::transferAndFillComplete: You provided a nonnull "
8351 "destination matrix, but checkSizes() indicates that it is not a legal "
8352 "legal target for redistribution from the source matrix (*this). This "
8353 "may mean that they do not have the same dimensions.");
8367 TEUCHOS_TEST_FOR_EXCEPTION(
8368 ! (reverseMode || getRowMap ()->isSameAs (*rowTransfer.getSourceMap ())),
8369 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8370 "rowTransfer->getSourceMap() must match this->getRowMap() in forward mode.");
8371 TEUCHOS_TEST_FOR_EXCEPTION(
8372 ! (! reverseMode || getRowMap ()->isSameAs (*rowTransfer.getTargetMap ())),
8373 std::invalid_argument,
"Tpetra::CrsMatrix::transferAndFillComplete: "
8374 "rowTransfer->getTargetMap() must match this->getRowMap() in reverse mode.");
8377 TEUCHOS_TEST_FOR_EXCEPTION(
8378 ! xferDomainAsImport.is_null() && ! xferDomainAsImport->getTargetMap()->isSameAs(*domainMap),
8379 std::invalid_argument,
8380 "Tpetra::CrsMatrix::transferAndFillComplete: The target map of the 'domainTransfer' input "
8381 "argument must be the same as the rebalanced domain map 'domainMap'");
8383 TEUCHOS_TEST_FOR_EXCEPTION(
8384 ! xferDomainAsExport.is_null() && ! xferDomainAsExport->getSourceMap()->isSameAs(*domainMap),
8385 std::invalid_argument,
8386 "Tpetra::CrsMatrix::transferAndFillComplete: The source map of the 'domainTransfer' input "
8387 "argument must be the same as the rebalanced domain map 'domainMap'");
8400 const size_t NumSameIDs = rowTransfer.getNumSameIDs();
8401 ArrayView<const LO> ExportLIDs = reverseMode ?
8402 rowTransfer.getRemoteLIDs () : rowTransfer.getExportLIDs ();
8403 ArrayView<const LO> RemoteLIDs = reverseMode ?
8404 rowTransfer.getExportLIDs () : rowTransfer.getRemoteLIDs ();
8405 ArrayView<const LO> PermuteToLIDs = reverseMode ?
8406 rowTransfer.getPermuteFromLIDs () : rowTransfer.getPermuteToLIDs ();
8407 ArrayView<const LO> PermuteFromLIDs = reverseMode ?
8408 rowTransfer.getPermuteToLIDs () : rowTransfer.getPermuteFromLIDs ();
8409 Distributor& Distor = rowTransfer.getDistributor ();
8412 Teuchos::Array<int> SourcePids;
8413 Teuchos::Array<int> TargetPids;
8416 RCP<const map_type> ReducedRowMap, ReducedColMap,
8417 ReducedDomainMap, ReducedRangeMap;
8418 RCP<const Comm<int> > ReducedComm;
8422 if (destMat.is_null ()) {
8423 destMat = rcp (
new this_type (MyRowMap, 0, StaticProfile, matrixparams));
8430 ReducedRowMap = MyRowMap->removeEmptyProcesses ();
8431 ReducedComm = ReducedRowMap.is_null () ?
8433 ReducedRowMap->getComm ();
8434 destMat->removeEmptyProcessesInPlace (ReducedRowMap);
8436 ReducedDomainMap = MyRowMap.getRawPtr () == MyDomainMap.getRawPtr () ?
8438 MyDomainMap->replaceCommWithSubset (ReducedComm);
8439 ReducedRangeMap = MyRowMap.getRawPtr () == MyRangeMap.getRawPtr () ?
8441 MyRangeMap->replaceCommWithSubset (ReducedComm);
8444 MyRowMap = ReducedRowMap;
8445 MyDomainMap = ReducedDomainMap;
8446 MyRangeMap = ReducedRangeMap;
8449 if (! ReducedComm.is_null ()) {
8450 MyPID = ReducedComm->getRank ();
8457 ReducedComm = MyRowMap->getComm ();
8466 RCP<const import_type> MyImporter = getGraph ()->getImporter ();
8469 bool bSameDomainMap = BaseDomainMap->isSameAs (*getDomainMap ());
8471 if (! restrictComm && ! MyImporter.is_null () && bSameDomainMap ) {
8478 Import_Util::getPids (*MyImporter, SourcePids,
false);
8480 else if (restrictComm && ! MyImporter.is_null () && bSameDomainMap) {
8483 IntVectorType SourceDomain_pids(getDomainMap (),
true);
8484 IntVectorType SourceCol_pids(getColMap());
8486 SourceDomain_pids.putScalar(MyPID);
8488 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8489 SourcePids.resize (getColMap ()->getNodeNumElements ());
8490 SourceCol_pids.get1dCopy (SourcePids ());
8492 else if (MyImporter.is_null ()) {
8494 SourcePids.resize (getColMap ()->getNodeNumElements ());
8495 SourcePids.assign (getColMap ()->getNodeNumElements (), MyPID);
8497 else if ( ! MyImporter.is_null () &&
8498 ! domainTransfer.is_null () ) {
8505 IntVectorType TargetDomain_pids (domainMap);
8506 TargetDomain_pids.putScalar (MyPID);
8509 IntVectorType SourceDomain_pids (getDomainMap ());
8512 IntVectorType SourceCol_pids (getColMap ());
8514 if (! reverseMode && ! xferDomainAsImport.is_null() ) {
8515 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8517 else if (reverseMode && ! xferDomainAsExport.is_null() ) {
8518 SourceDomain_pids.doExport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8520 else if (! reverseMode && ! xferDomainAsExport.is_null() ) {
8521 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsExport,
INSERT);
8523 else if (reverseMode && ! xferDomainAsImport.is_null() ) {
8524 SourceDomain_pids.doImport (TargetDomain_pids, *xferDomainAsImport,
INSERT);
8527 TEUCHOS_TEST_FOR_EXCEPTION(
8528 true, std::logic_error,
"Tpetra::CrsMatrix::"
8529 "transferAndFillComplete: Should never get here! "
8530 "Please report this bug to a Tpetra developer.");
8532 SourceCol_pids.doImport (SourceDomain_pids, *MyImporter,
INSERT);
8533 SourcePids.resize (getColMap ()->getNodeNumElements ());
8534 SourceCol_pids.get1dCopy (SourcePids ());
8536 else if ( ! MyImporter.is_null () &&
8537 BaseDomainMap->isSameAs (*BaseRowMap) &&
8538 getDomainMap ()->isSameAs (*getRowMap ())) {
8541 IntVectorType TargetRow_pids (domainMap);
8542 IntVectorType SourceRow_pids (getRowMap ());
8543 IntVectorType SourceCol_pids (getColMap ());
8545 TargetRow_pids.putScalar (MyPID);
8546 if (! reverseMode && xferAsImport !=
nullptr) {
8547 SourceRow_pids.doExport (TargetRow_pids, *xferAsImport,
INSERT);
8549 else if (reverseMode && xferAsExport !=
nullptr) {
8550 SourceRow_pids.doExport (TargetRow_pids, *xferAsExport,
INSERT);
8552 else if (! reverseMode && xferAsExport !=
nullptr) {
8553 SourceRow_pids.doImport (TargetRow_pids, *xferAsExport,
INSERT);
8555 else if (reverseMode && xferAsImport !=
nullptr) {
8556 SourceRow_pids.doImport (TargetRow_pids, *xferAsImport,
INSERT);
8559 TEUCHOS_TEST_FOR_EXCEPTION(
8560 true, std::logic_error,
"Tpetra::CrsMatrix::"
8561 "transferAndFillComplete: Should never get here! "
8562 "Please report this bug to a Tpetra developer.");
8565 SourceCol_pids.doImport (SourceRow_pids, *MyImporter,
INSERT);
8566 SourcePids.resize (getColMap ()->getNodeNumElements ());
8567 SourceCol_pids.get1dCopy (SourcePids ());
8570 TEUCHOS_TEST_FOR_EXCEPTION(
8571 true, std::invalid_argument,
"Tpetra::CrsMatrix::"
8572 "transferAndFillComplete: This method only allows either domainMap == "
8573 "getDomainMap (), or (domainMap == rowTransfer.getTargetMap () and "
8574 "getDomainMap () == getRowMap ()).");
8578 size_t constantNumPackets = destMat->constantNumberOfPackets ();
8579 if (constantNumPackets == 0) {
8580 destMat->reallocArraysForNumPacketsPerLid (ExportLIDs.size (),
8581 RemoteLIDs.size ());
8588 const size_t rbufLen = RemoteLIDs.size() * constantNumPackets;
8589 destMat->reallocImportsIfNeeded (rbufLen,
false,
nullptr);
8594 using Teuchos::outArg;
8595 using Teuchos::REDUCE_MAX;
8596 using Teuchos::reduceAll;
8599 RCP<const Teuchos::Comm<int> > comm = this->getComm ();
8600 const int myRank = comm->getRank ();
8602 std::ostringstream errStrm;
8606 Teuchos::ArrayView<size_t> numExportPacketsPerLID;
8609 destMat->numExportPacketsPerLID_.modify_host ();
8610 numExportPacketsPerLID =
8613 catch (std::exception& e) {
8614 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw: "
8615 << e.what () << std::endl;
8619 errStrm <<
"Proc " << myRank <<
": getArrayViewFromDualView threw "
8620 "an exception not a subclass of std::exception" << std::endl;
8624 if (! comm.is_null ()) {
8625 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
8628 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
8629 TEUCHOS_TEST_FOR_EXCEPTION(
8630 true, std::runtime_error,
"getArrayViewFromDualView threw an "
8631 "exception on at least one process.");
8635 std::ostringstream os;
8636 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
8638 std::cerr << os.str ();
8643 numExportPacketsPerLID,
8646 constantNumPackets);
8648 catch (std::exception& e) {
8649 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw: "
8650 << e.what () << std::endl;
8654 errStrm <<
"Proc " << myRank <<
": packCrsMatrixWithOwningPIDs threw "
8655 "an exception not a subclass of std::exception" << std::endl;
8660 std::ostringstream os;
8661 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
8663 std::cerr << os.str ();
8666 if (! comm.is_null ()) {
8667 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
8670 ::Tpetra::Details::gathervPrint (cerr, errStrm.str (), *comm);
8671 TEUCHOS_TEST_FOR_EXCEPTION(
8672 true, std::runtime_error,
"packCrsMatrixWithOwningPIDs threw an "
8673 "exception on at least one process.");
8678 destMat->numExportPacketsPerLID_.modify_host ();
8679 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
8682 std::ostringstream os;
8683 os << *verbosePrefix <<
"Calling packCrsMatrixWithOwningPIDs"
8685 std::cerr << os.str ();
8689 numExportPacketsPerLID,
8692 constantNumPackets);
8694 std::ostringstream os;
8695 os << *verbosePrefix <<
"Done with packCrsMatrixWithOwningPIDs"
8697 std::cerr << os.str ();
8702 if (! communication_needed) {
8704 std::ostringstream os;
8705 os << *verbosePrefix <<
"Communication not needed" << std::endl;
8706 std::cerr << os.str ();
8711 if (constantNumPackets == 0) {
8713 std::ostringstream os;
8714 os << *verbosePrefix <<
"Reverse mode, variable # packets / LID"
8716 std::cerr << os.str ();
8721 destMat->numExportPacketsPerLID_.sync_host ();
8722 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
8724 destMat->numImportPacketsPerLID_.sync_host ();
8725 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
8729 std::ostringstream os;
8730 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
8732 std::cerr << os.str ();
8734 Distor.doReversePostsAndWaits (numExportPacketsPerLID, 1,
8735 numImportPacketsPerLID);
8737 std::ostringstream os;
8738 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
8740 std::cerr << os.str ();
8743 size_t totalImportPackets = 0;
8744 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
8745 totalImportPackets += numImportPacketsPerLID[i];
8750 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
8751 verbosePrefix.get ());
8752 destMat->imports_.modify_host ();
8753 Teuchos::ArrayView<char> hostImports =
8757 destMat->exports_.sync_host ();
8758 Teuchos::ArrayView<const char> hostExports =
8761 std::ostringstream os;
8762 os << *verbosePrefix <<
"Calling 4-arg doReversePostsAndWaits"
8764 std::cerr << os.str ();
8766 Distor.doReversePostsAndWaits (hostExports,
8767 numExportPacketsPerLID,
8769 numImportPacketsPerLID);
8771 std::ostringstream os;
8772 os << *verbosePrefix <<
"Finished 4-arg doReversePostsAndWaits"
8774 std::cerr << os.str ();
8779 std::ostringstream os;
8780 os << *verbosePrefix <<
"Reverse mode, constant # packets / LID"
8782 std::cerr << os.str ();
8784 destMat->imports_.modify_host ();
8785 Teuchos::ArrayView<char> hostImports =
8789 destMat->exports_.sync_host ();
8790 Teuchos::ArrayView<const char> hostExports =
8793 std::ostringstream os;
8794 os << *verbosePrefix <<
"Calling 3-arg doReversePostsAndWaits"
8796 std::cerr << os.str ();
8798 Distor.doReversePostsAndWaits (hostExports,
8802 std::ostringstream os;
8803 os << *verbosePrefix <<
"Finished 3-arg doReversePostsAndWaits"
8805 std::cerr << os.str ();
8810 if (constantNumPackets == 0) {
8812 std::ostringstream os;
8813 os << *verbosePrefix <<
"Forward mode, variable # packets / LID"
8815 std::cerr << os.str ();
8820 destMat->numExportPacketsPerLID_.sync_host ();
8821 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
8823 destMat->numImportPacketsPerLID_.sync_host ();
8824 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
8827 std::ostringstream os;
8828 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
8830 std::cerr << os.str ();
8832 Distor.doPostsAndWaits (numExportPacketsPerLID, 1,
8833 numImportPacketsPerLID);
8835 std::ostringstream os;
8836 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
8838 std::cerr << os.str ();
8841 size_t totalImportPackets = 0;
8842 for (
Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
8843 totalImportPackets += numImportPacketsPerLID[i];
8848 destMat->reallocImportsIfNeeded (totalImportPackets, verbose,
8849 verbosePrefix.get ());
8850 destMat->imports_.modify_host ();
8851 Teuchos::ArrayView<char> hostImports =
8855 destMat->exports_.sync_host ();
8856 Teuchos::ArrayView<const char> hostExports =
8859 std::ostringstream os;
8860 os << *verbosePrefix <<
"Calling 4-arg doPostsAndWaits"
8862 std::cerr << os.str ();
8864 Distor.doPostsAndWaits (hostExports,
8865 numExportPacketsPerLID,
8867 numImportPacketsPerLID);
8869 std::ostringstream os;
8870 os << *verbosePrefix <<
"Finished 4-arg doPostsAndWaits"
8872 std::cerr << os.str ();
8877 std::ostringstream os;
8878 os << *verbosePrefix <<
"Forward mode, constant # packets / LID"
8880 std::cerr << os.str ();
8882 destMat->imports_.modify_host ();
8883 Teuchos::ArrayView<char> hostImports =
8887 destMat->exports_.sync_host ();
8888 Teuchos::ArrayView<const char> hostExports =
8891 std::ostringstream os;
8892 os << *verbosePrefix <<
"Calling 3-arg doPostsAndWaits"
8894 std::cerr << os.str ();
8896 Distor.doPostsAndWaits (hostExports,
8900 std::ostringstream os;
8901 os << *verbosePrefix <<
"Finished 3-arg doPostsAndWaits"
8903 std::cerr << os.str ();
8914 destMat->numImportPacketsPerLID_.sync_host ();
8915 Teuchos::ArrayView<const size_t> numImportPacketsPerLID =
8917 destMat->imports_.sync_host ();
8918 Teuchos::ArrayView<const char> hostImports =
8922 std::ostringstream os;
8923 os << *verbosePrefix <<
"Calling unpackAndCombineWithOwningPIDsCount"
8925 std::cerr << os.str ();
8931 numImportPacketsPerLID,
8938 std::ostringstream os;
8939 os << *verbosePrefix <<
"unpackAndCombineWithOwningPIDsCount returned "
8940 << mynnz << std::endl;
8941 std::cerr << os.str ();
8943 size_t N = BaseRowMap->getNodeNumElements ();
8946 ArrayRCP<size_t> CSR_rowptr(N+1);
8947 ArrayRCP<GO> CSR_colind_GID;
8948 ArrayRCP<LO> CSR_colind_LID;
8949 ArrayRCP<Scalar> CSR_vals;
8950 CSR_colind_GID.resize (mynnz);
8951 CSR_vals.resize (mynnz);
8955 if (
typeid (LO) ==
typeid (GO)) {
8956 CSR_colind_LID = Teuchos::arcp_reinterpret_cast<LO> (CSR_colind_GID);
8959 CSR_colind_LID.resize (mynnz);
8963 std::ostringstream os;
8964 os << *verbosePrefix <<
"Calling unpackAndCombineIntoCrsArrays"
8966 std::cerr << os.str ();
8976 numImportPacketsPerLID,
8987 Teuchos::av_reinterpret_cast<impl_scalar_type> (CSR_vals ()),
8997 Teuchos::Array<int> RemotePids;
8999 std::ostringstream os;
9000 os << *verbosePrefix <<
"Calling lowCommunicationMakeColMapAndReindex"
9002 std::cerr << os.str ();
9004 Import_Util::lowCommunicationMakeColMapAndReindex (CSR_rowptr (),
9013 std::ostringstream os;
9014 os << *verbosePrefix <<
"restrictComm="
9015 << (restrictComm ?
"true" :
"false") << std::endl;
9016 std::cerr << os.str ();
9023 ReducedColMap = (MyRowMap.getRawPtr () == MyColMap.getRawPtr ()) ?
9025 MyColMap->replaceCommWithSubset (ReducedComm);
9026 MyColMap = ReducedColMap;
9031 std::ostringstream os;
9032 os << *verbosePrefix <<
"Calling replaceColMap" << std::endl;
9033 std::cerr << os.str ();
9035 destMat->replaceColMap (MyColMap);
9042 if (ReducedComm.is_null ()) {
9044 std::ostringstream os;
9045 os << *verbosePrefix <<
"I am no longer in the communicator; "
9046 "returning" << std::endl;
9047 std::cerr << os.str ();
9055 if ((! reverseMode && xferAsImport !=
nullptr) ||
9056 (reverseMode && xferAsExport !=
nullptr)) {
9058 std::ostringstream os;
9059 os << *verbosePrefix <<
"Calling sortCrsEntries" << endl;
9060 std::cerr << os.str ();
9062 Import_Util::sortCrsEntries (CSR_rowptr (),
9066 else if ((! reverseMode && xferAsExport !=
nullptr) ||
9067 (reverseMode && xferAsImport !=
nullptr)) {
9069 std::ostringstream os;
9070 os << *verbosePrefix <<
"Calling sortAndMergeCrsEntries"
9072 std::cerr << os.str();
9074 Import_Util::sortAndMergeCrsEntries (CSR_rowptr (),
9077 if (CSR_rowptr[N] != mynnz) {
9078 CSR_colind_LID.resize (CSR_rowptr[N]);
9079 CSR_vals.resize (CSR_rowptr[N]);
9083 TEUCHOS_TEST_FOR_EXCEPTION(
9084 true, std::logic_error,
"Tpetra::CrsMatrix::"
9085 "transferAndFillComplete: Should never get here! "
9086 "Please report this bug to a Tpetra developer.");
9093 std::ostringstream os;
9094 os << *verbosePrefix <<
"Calling destMat->setAllValues" << endl;
9095 std::cerr << os.str ();
9103 destMat->setAllValues (CSR_rowptr, CSR_colind_LID, CSR_vals);
9109 Teuchos::ParameterList esfc_params;
9111 RCP<import_type> MyImport;
9114 if (iallreduceRequest.get () !=
nullptr) {
9116 std::ostringstream os;
9117 os << *verbosePrefix <<
"Calling iallreduceRequest->wait()"
9119 std::cerr << os.str ();
9121 iallreduceRequest->wait ();
9122 if (reduced_mismatch != 0) {
9128 #ifdef HAVE_TPETRA_MMM_TIMINGS
9129 Teuchos::TimeMonitor MMisMM (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM Block")));
9134 std::ostringstream os;
9135 os << *verbosePrefix <<
"Calling getAllValues" << endl;
9136 std::cerr << os.str ();
9139 Teuchos::ArrayRCP<LocalOrdinal> type3LIDs;
9140 Teuchos::ArrayRCP<int> type3PIDs;
9141 Teuchos::ArrayRCP<const size_t> rowptr;
9142 Teuchos::ArrayRCP<const LO> colind;
9143 Teuchos::ArrayRCP<const Scalar> vals;
9145 #ifdef HAVE_TPETRA_MMM_TIMINGS
9146 TimeMonitor tm_getAllValues (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMgetAllValues")));
9148 getAllValues(rowptr,colind,vals);
9152 std::ostringstream os;
9153 os << *verbosePrefix <<
"Calling reverseNeighborDiscovery" << std::endl;
9154 std::cerr << os.str ();
9158 #ifdef HAVE_TPETRA_MMM_TIMINGS
9159 TimeMonitor tm_rnd (*TimeMonitor::getNewTimer(prefix + std::string(
"isMMrevNeighDis")));
9161 Import_Util::reverseNeighborDiscovery(*
this,
9173 std::ostringstream os;
9174 os << *verbosePrefix <<
"Done with reverseNeighborDiscovery" << std::endl;
9175 std::cerr << os.str ();
9178 Teuchos::ArrayView<const int> EPID1 = MyImporter.is_null() ? Teuchos::ArrayView<const int>() : MyImporter->getExportPIDs();
9179 Teuchos::ArrayView<const LO> ELID1 = MyImporter.is_null() ? Teuchos::ArrayView<const LO>() : MyImporter->getExportLIDs();
9181 Teuchos::ArrayView<const int> TEPID2 = rowTransfer.getExportPIDs();
9182 Teuchos::ArrayView<const LO> TELID2 = rowTransfer.getExportLIDs();
9184 const int numCols = getGraph()->getColMap()->getNodeNumElements();
9186 std::vector<bool> IsOwned(numCols,
true);
9187 std::vector<int> SentTo(numCols,-1);
9188 if (! MyImporter.is_null ()) {
9189 for (
auto && rlid : MyImporter->getRemoteLIDs()) {
9190 IsOwned[rlid]=
false;
9194 std::vector<std::pair<int,GO> > usrtg;
9195 usrtg.reserve(TEPID2.size());
9198 const auto& colMap = * (this->getColMap ());
9200 const LO row = TELID2[i];
9201 const int pid = TEPID2[i];
9202 for (
auto j = rowptr[row]; j < rowptr[row+1]; ++j) {
9203 const int col = colind[j];
9204 if (IsOwned[col] && SentTo[col] != pid) {
9206 GO gid = colMap.getGlobalElement (col);
9207 usrtg.push_back (std::pair<int,GO> (pid, gid));
9215 auto eopg = std ::unique(usrtg.begin(),usrtg.end());
9217 usrtg.erase(eopg,usrtg.end());
9220 Teuchos::ArrayRCP<int> EPID2=Teuchos::arcp(
new int[type2_us_size],0,type2_us_size,
true);
9221 Teuchos::ArrayRCP< LO> ELID2=Teuchos::arcp(
new LO[type2_us_size],0,type2_us_size,
true);
9224 for(
auto && p : usrtg) {
9225 EPID2[pos]= p.first;
9226 ELID2[pos]= this->getDomainMap()->getLocalElement(p.second);
9230 Teuchos::ArrayView<int> EPID3 = type3PIDs();
9231 Teuchos::ArrayView< LO> ELID3 = type3LIDs();
9232 GO InfGID = std::numeric_limits<GO>::max();
9233 int InfPID = INT_MAX;
9237 #define TPETRA_MIN3(x,y,z) ((x)<(y)?(std::min(x,z)):(std::min(y,z)))
9238 int i1=0, i2=0, i3=0;
9239 int Len1 = EPID1.size();
9240 int Len2 = EPID2.size();
9241 int Len3 = EPID3.size();
9243 int MyLen=Len1+Len2+Len3;
9244 Teuchos::ArrayRCP<LO> userExportLIDs = Teuchos::arcp(
new LO[MyLen],0,MyLen,
true);
9245 Teuchos::ArrayRCP<int> userExportPIDs = Teuchos::arcp(
new int[MyLen],0,MyLen,
true);
9248 while(i1 < Len1 || i2 < Len2 || i3 < Len3){
9249 int PID1 = (i1<Len1)?(EPID1[i1]):InfPID;
9250 int PID2 = (i2<Len2)?(EPID2[i2]):InfPID;
9251 int PID3 = (i3<Len3)?(EPID3[i3]):InfPID;
9253 GO GID1 = (i1<Len1)?getDomainMap()->getGlobalElement(ELID1[i1]):InfGID;
9254 GO GID2 = (i2<Len2)?getDomainMap()->getGlobalElement(ELID2[i2]):InfGID;
9255 GO GID3 = (i3<Len3)?getDomainMap()->getGlobalElement(ELID3[i3]):InfGID;
9257 int MIN_PID = TPETRA_MIN3(PID1,PID2,PID3);
9258 GO MIN_GID = TPETRA_MIN3( ((PID1==MIN_PID)?GID1:InfGID), ((PID2==MIN_PID)?GID2:InfGID), ((PID3==MIN_PID)?GID3:InfGID));
9262 bool added_entry=
false;
9264 if(PID1 == MIN_PID && GID1 == MIN_GID){
9265 userExportLIDs[iloc]=ELID1[i1];
9266 userExportPIDs[iloc]=EPID1[i1];
9271 if(PID2 == MIN_PID && GID2 == MIN_GID){
9273 userExportLIDs[iloc]=ELID2[i2];
9274 userExportPIDs[iloc]=EPID2[i2];
9280 if(PID3 == MIN_PID && GID3 == MIN_GID){
9282 userExportLIDs[iloc]=ELID3[i3];
9283 userExportPIDs[iloc]=EPID3[i3];
9291 std::ostringstream os;
9292 os << *verbosePrefix <<
"Create Import" << std::endl;
9293 std::cerr << os.str ();
9296 #ifdef HAVE_TPETRA_MMM_TIMINGS
9297 auto ismmIctor(*TimeMonitor::getNewTimer(prefix + std::string(
"isMMIportCtor")));
9299 Teuchos::RCP<Teuchos::ParameterList> plist = rcp(
new Teuchos::ParameterList());
9301 if ((MyDomainMap != MyColMap) && (!MyDomainMap->isSameAs(*MyColMap)))
9302 MyImport = rcp (
new import_type (MyDomainMap,
9305 userExportLIDs.view(0,iloc).getConst(),
9306 userExportPIDs.view(0,iloc).getConst(),
9311 std::ostringstream os;
9312 os << *verbosePrefix <<
"Call expertStaticFillComplete" << std::endl;
9313 std::cerr << os.str ();
9317 #ifdef HAVE_TPETRA_MMM_TIMINGS
9318 TimeMonitor esfc (*TimeMonitor::getNewTimer(prefix + std::string(
"isMM::destMat->eSFC")));
9319 esfc_params.set(
"Timer Label",label+std::string(
"isMM eSFC"));
9321 if(!params.is_null())
9322 esfc_params.set(
"compute global constants",params->get(
"compute global constants",
true));
9323 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap, MyImport,Teuchos::null,rcp(
new Teuchos::ParameterList(esfc_params)));
9329 #ifdef HAVE_TPETRA_MMM_TIMINGS
9330 TimeMonitor MMnotMMblock (*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMblock")));
9333 std::ostringstream os;
9334 os << *verbosePrefix <<
"Create Import" << std::endl;
9335 std::cerr << os.str ();
9338 #ifdef HAVE_TPETRA_MMM_TIMINGS
9339 TimeMonitor notMMIcTor(*TimeMonitor::getNewTimer(prefix + std::string(
"TAFC notMMCreateImporter")));
9341 Teuchos::RCP<Teuchos::ParameterList> mypars = rcp(
new Teuchos::ParameterList);
9342 mypars->set(
"Timer Label",
"notMMFrom_tAFC");
9343 if ((MyDomainMap != MyColMap) && (!MyDomainMap->isSameAs(*MyColMap)))
9344 MyImport = rcp (
new import_type (MyDomainMap, MyColMap, RemotePids, mypars));
9347 std::ostringstream os;
9348 os << *verbosePrefix <<
"Call expertStaticFillComplete" << endl;
9349 std::cerr << os.str ();
9352 #ifdef HAVE_TPETRA_MMM_TIMINGS
9353 TimeMonitor esfcnotmm(*TimeMonitor::getNewTimer(prefix + std::string(
"notMMdestMat->expertStaticFillComplete")));
9354 esfc_params.set(
"Timer Label",prefix+std::string(
"notMM eSFC"));
9356 esfc_params.set(
"Timer Label",std::string(
"notMM eSFC"));
9359 if (!params.is_null ()) {
9360 esfc_params.set (
"compute global constants",
9361 params->get (
"compute global constants",
true));
9363 destMat->expertStaticFillComplete (MyDomainMap, MyRangeMap,
9364 MyImport, Teuchos::null,
9365 rcp (
new Teuchos::ParameterList (esfc_params)));
9369 std::ostringstream os;
9370 os << *verbosePrefix <<
"Done" << endl;
9371 std::cerr << os.str ();
9376 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9381 const Teuchos::RCP<const map_type>& domainMap,
9382 const Teuchos::RCP<const map_type>& rangeMap,
9383 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9385 transferAndFillComplete (destMatrix, importer, Teuchos::null, domainMap, rangeMap, params);
9388 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9394 const Teuchos::RCP<const map_type>& domainMap,
9395 const Teuchos::RCP<const map_type>& rangeMap,
9396 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9398 transferAndFillComplete (destMatrix, rowImporter, Teuchos::rcpFromRef(domainImporter), domainMap, rangeMap, params);
9401 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9406 const Teuchos::RCP<const map_type>& domainMap,
9407 const Teuchos::RCP<const map_type>& rangeMap,
9408 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9410 transferAndFillComplete (destMatrix, exporter, Teuchos::null, domainMap, rangeMap, params);
9413 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
9419 const Teuchos::RCP<const map_type>& domainMap,
9420 const Teuchos::RCP<const map_type>& rangeMap,
9421 const Teuchos::RCP<Teuchos::ParameterList>& params)
const
9423 transferAndFillComplete (destMatrix, rowExporter, Teuchos::rcpFromRef(domainExporter), domainMap, rangeMap, params);
9435 #define TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR,LO,GO,NODE) \
9437 template class CrsMatrix< SCALAR , LO , GO , NODE >; \
9438 template Teuchos::RCP< CrsMatrix< SCALAR , LO , GO , NODE > > \
9439 CrsMatrix< SCALAR , LO , GO , NODE >::convert< SCALAR > () const;
9441 #define TPETRA_CRSMATRIX_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \
9443 template Teuchos::RCP< CrsMatrix< SO , LO , GO , NODE > > \
9444 CrsMatrix< SI , LO , GO , NODE >::convert< SO > () const;
9446 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9448 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9449 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9450 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9451 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9452 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& importer, \
9453 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9454 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9455 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9456 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9457 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9458 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9459 const Teuchos::RCP<Teuchos::ParameterList>& params);
9461 #define TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9463 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9464 importAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9465 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9466 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9467 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowImporter, \
9468 const Import<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9469 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9470 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainImporter, \
9471 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9472 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9473 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9474 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9475 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9476 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9477 const Teuchos::RCP<Teuchos::ParameterList>& params);
9480 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9482 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9483 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9484 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9485 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9486 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& exporter, \
9487 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9488 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9489 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9490 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9491 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9492 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9493 const Teuchos::RCP<Teuchos::ParameterList>& params);
9495 #define TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9497 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > \
9498 exportAndFillCompleteCrsMatrix (const Teuchos::RCP<const CrsMatrix<SCALAR, LO, GO, NODE> >& sourceMatrix, \
9499 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9500 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9501 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& rowExporter, \
9502 const Export<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9503 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9504 CrsMatrix<SCALAR, LO, GO, NODE>::node_type>& domainExporter, \
9505 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9506 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9507 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& domainMap, \
9508 const Teuchos::RCP<const Map<CrsMatrix<SCALAR, LO, GO, NODE>::local_ordinal_type, \
9509 CrsMatrix<SCALAR, LO, GO, NODE>::global_ordinal_type, \
9510 CrsMatrix<SCALAR, LO, GO, NODE>::node_type> >& rangeMap, \
9511 const Teuchos::RCP<Teuchos::ParameterList>& params);
9514 #define TPETRA_CRSMATRIX_INSTANT(SCALAR, LO, GO ,NODE) \
9515 TPETRA_CRSMATRIX_MATRIX_INSTANT(SCALAR, LO, GO, NODE) \
9516 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9517 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT(SCALAR, LO, GO, NODE) \
9518 TPETRA_CRSMATRIX_IMPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE) \
9519 TPETRA_CRSMATRIX_EXPORT_AND_FILL_COMPLETE_INSTANT_TWO(SCALAR, LO, GO, NODE)
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
Declaration and definition of Tpetra::Details::castAwayConstDualView, an implementation detail of Tpe...
Declare and define the functions Tpetra::Details::computeOffsetsFromCounts and Tpetra::computeOffsets...
Declare and define Tpetra::Details::copyConvert, an implementation detail of Tpetra (in particular,...
Declare and define Tpetra::Details::copyOffsets, an implementation detail of Tpetra (in particular,...
Functions that wrap Kokkos::create_mirror_view, in order to avoid deep copies when not necessary,...
Functions for manipulating CRS arrays.
Declaration of a function that prints strings from each process.
Declaration and definition of Tpetra::Details::getEntryOnHost.
Declaration of Tpetra::Details::iallreduce.
Declaration and definition of Tpetra::Details::leftScaleLocalCrsMatrix.
KOKKOS_FUNCTION size_t packRow(const LocalMapType &col_map, const Kokkos::View< Packet *, BufferDeviceType > &exports, const InputLidsType &lids_in, const InputPidsType &pids_in, const size_t offset, const size_t num_ent, const bool pack_pids)
Packs a single row of the CrsGraph.
Declaration and definition of Tpetra::Details::rightScaleLocalCrsMatrix.
KOKKOS_FUNCTION int unpackRow(const Kokkos::View< GO *, Device, Kokkos::MemoryUnmanaged > &gids_out, const Kokkos::View< int *, Device, Kokkos::MemoryUnmanaged > &pids_out, const Kokkos::View< const Packet *, BufferDevice > &imports, const size_t offset, const size_t num_ent)
Unpack a single row of a CrsGraph.
Utility functions for packing and unpacking sparse matrix entries.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects.
#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...
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
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...
global_inds_dualv_type::t_host::const_type getGlobalIndsViewHost(const RowInfo &rowinfo) const
Get a const, globally indexed view of the locally owned row myRow, such that rowinfo = getRowInfo(myR...
size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const override
Get the number of entries in the given row (local index).
local_inds_wdv_type lclIndsUnpacked_wdv
Local ordinals of colum indices for all rows KDDKDD UVM Removal: Device view takes place of k_lclInds...
RowInfo getRowInfoFromGlobalRowIndex(const global_ordinal_type gblRow) const
Get information about the locally owned row with global index gblRow.
size_t findGlobalIndices(const RowInfo &rowInfo, const Teuchos::ArrayView< const global_ordinal_type > &indices, std::function< void(const size_t, const size_t, const size_t)> fun) const
Finds indices in the given row.
num_row_entries_type k_numRowEntries_
The number of local entries in each locally owned row.
Teuchos::RCP< const map_type > getDomainMap() const override
Returns the Map associated with the domain of this graph.
RowInfo getRowInfo(const local_ordinal_type myRow) const
Get information about the locally owned row with local index myRow.
Teuchos::RCP< const map_type > colMap_
The Map describing the distribution of columns of the graph.
bool noRedundancies_
Whether the graph's indices are non-redundant (merged) in each row, on this process.
bool isSorted() const
Whether graph indices in all rows are known to be sorted.
bool isFillComplete() const override
Whether fillComplete() has been called and the graph is in compute mode.
Teuchos::RCP< const map_type > getRangeMap() const override
Returns the Map associated with the domain of this graph.
local_inds_dualv_type::t_host::const_type getLocalIndsViewHost(const RowInfo &rowinfo) const
Get a const, locally indexed view of the locally owned row myRow, such that rowinfo = getRowInfo(myRo...
Teuchos::RCP< const map_type > getRowMap() const override
Returns the Map that describes the row distribution in this graph.
size_t insertGlobalIndicesImpl(const local_ordinal_type lclRow, const global_ordinal_type inputGblColInds[], const size_t numInputInds)
Insert global indices, using an input local row index.
bool indicesAreSorted_
Whether the graph's indices are sorted in each row, on this process.
size_t getNodeNumRows() const override
Returns the number of graph rows owned on the calling node.
local_inds_dualv_type::t_host getLocalIndsViewHostNonConst(const RowInfo &rowinfo)
Get a ReadWrite locally indexed view of the locally owned row myRow, such that rowinfo = getRowInfo(m...
Teuchos::RCP< const map_type > rowMap_
The Map describing the distribution of rows of the graph.
bool isGloballyIndexed() const override
Whether the graph's column indices are stored as global indices.
bool isLocallyIndexed() const override
Whether the graph's column indices are stored as local indices.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries.
virtual void insertGlobalValuesImpl(crs_graph_type &graph, RowInfo &rowInfo, const GlobalOrdinal gblColInds[], const impl_scalar_type vals[], const size_t numInputEnt)
Common implementation detail of insertGlobalValues and insertGlobalValuesFiltered.
bool isGloballyIndexed() const override
Whether the matrix is globally indexed on the calling process.
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.
size_t getNodeNumRows() const override
The number of matrix rows owned by the calling process.
std::map< GlobalOrdinal, std::pair< Teuchos::Array< GlobalOrdinal >, Teuchos::Array< Scalar > > > nonlocals_
Nonlocal data added using insertGlobalValues().
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.
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, const CombineMode CM) override
Unpack the imported column indices and values, and combine into matrix.
void replaceRangeMap(const Teuchos::RCP< const map_type > &newRangeMap)
Replace the current range Map with the given objects.
Details::EStorageStatus storageStatus_
Status of the matrix's storage, when not in a fill-complete state.
typename device_type::execution_space execution_space
The Kokkos execution space.
void applyNonTranspose(const MV &X_in, MV &Y_in, Scalar alpha, Scalar beta) const
Special case of apply() for mode == Teuchos::NO_TRANS.
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.
CrsGraph< LocalOrdinal, GlobalOrdinal, Node > crs_graph_type
The CrsGraph specialization suitable for this CrsMatrix specialization.
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)
Replace one or more entries' values, using global indices.
bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
size_t getGlobalMaxNumRowEntries() const override
Maximum number of entries in any row of the matrix, over all processes in the matrix's communicator.
void getGlobalRowCopy(GlobalOrdinal GlobalRow, nonconst_global_inds_host_view_type &Indices, nonconst_values_host_view_type &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,...
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const override
Number of entries in the sparse matrix in the given global row, on the calling (MPI) process.
void scale(const Scalar &alpha)
Scale the matrix's values: this := alpha*this.
GlobalOrdinal global_ordinal_type
The type of each global index in the matrix.
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...
size_t getNodeNumCols() const override
The number of columns connected to the locally owned rows of this matrix.
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) const
Pack this object's data for an Import or Export.
Teuchos::RCP< const map_type > getDomainMap() const override
The domain Map of this matrix.
bool hasColMap() const override
Whether the matrix has a well-defined column Map.
Teuchos::RCP< CrsMatrix< T, LocalOrdinal, GlobalOrdinal, Node > > convert() const
Return another CrsMatrix with the same entries, but converted to a different Scalar type T.
values_dualv_type::t_dev getValuesViewDeviceNonConst(const RowInfo &rowinfo)
Get a non-const Device view of the locally owned values row myRow, such that rowinfo = getRowInfo(myR...
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.
std::shared_ptr< local_multiply_op_type > getLocalMultiplyOperator() const
The local sparse matrix operator (a wrapper of getLocalMatrixDevice() that supports local matrix-vect...
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)
Sum into one or more sparse matrix entries, using local row and column indices.
void computeGlobalConstants()
Compute matrix properties that require collectives.
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.
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.
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.
Teuchos::RCP< MV > exportMV_
Row Map MultiVector used in apply().
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
The communicator over which the matrix is distributed.
bool isFillActive() const
Whether the matrix is not fill complete.
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.
LocalOrdinal sumIntoGlobalValues(const GlobalOrdinal globalRow, const Teuchos::ArrayView< const GlobalOrdinal > &cols, const Teuchos::ArrayView< const Scalar > &vals, const bool atomic=useAtomicUpdatesByDefault)
Sum into one or more sparse matrix entries, using global indices.
void 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.
mag_type getFrobeniusNorm() const override
Compute and return the Frobenius norm of the matrix.
global_size_t getGlobalNumCols() const override
The number of global columns in the matrix.
Teuchos::RCP< const map_type > getRangeMap() const override
The range Map of this matrix.
Teuchos::RCP< MV > importMV_
Column Map MultiVector used in apply().
void allocateValues(ELocalGlobal lg, GraphAllocationStatus gas, const bool verbose)
Allocate values (and optionally indices) using the Node.
typename Node::device_type device_type
The Kokkos device type.
bool fillComplete_
Whether the matrix is fill complete.
virtual LocalOrdinal sumIntoGlobalValuesImpl(impl_scalar_type rowVals[], const crs_graph_type &graph, const RowInfo &rowInfo, const GlobalOrdinal inds[], const impl_scalar_type newVals[], const LocalOrdinal numElts, const bool atomic=useAtomicUpdatesByDefault)
Implementation detail of sumIntoGlobalValues.
void replaceDomainMap(const Teuchos::RCP< const map_type > &newDomainMap)
Replace the current domain Map with the given objects.
std::string description() const override
A one-line description of this object.
void reindexColumns(crs_graph_type *const graph, const Teuchos::RCP< const map_type > &newColMap, const Teuchos::RCP< const import_type > &newImport=Teuchos::null, const bool sortEachRow=true)
Reindex the column indices in place, and replace the column Map. Optionally, replace the Import objec...
Teuchos::RCP< MV > getColumnMapMultiVector(const MV &X_domainMap, const bool force=false) const
Create a (or fetch a cached) column Map MultiVector.
KokkosSparse::CrsMatrix< impl_scalar_type, local_ordinal_type, device_type, void, typename local_graph_device_type::size_type > local_matrix_device_type
The specialization of Kokkos::CrsMatrix that represents the part of the sparse matrix on each MPI pro...
void replaceRangeMapAndExporter(const Teuchos::RCP< const map_type > &newRangeMap, Teuchos::RCP< const export_type > &newExporter)
Replace the current Range Map and Export with the given objects.
void replaceColMap(const Teuchos::RCP< const map_type > &newColMap)
Replace the matrix's column Map with the given Map.
global_size_t getGlobalNumRows() const override
Number of global elements in the row map of this matrix.
void globalAssemble()
Communicate nonlocal contributions to other processes.
void checkInternalState() const
Check that this object's state is sane; throw if it's not.
bool hasTransposeApply() const override
Whether apply() allows applying the transpose or conjugate transpose.
GlobalOrdinal getIndexBase() const override
The index base for global indices for this matrix.
local_matrix_device_type::values_type getLocalValuesView() const
Get the Kokkos local values.
Scalar scalar_type
The type of each entry in the matrix.
LocalOrdinal local_ordinal_type
The type of each local index in the matrix.
void getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &diag) const override
Get a constant, nonpersisting view of a row of this matrix, using local row and column indices,...
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
void fillLocalGraphAndMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local graph and matrix.
local_matrix_device_type getLocalMatrixDevice() const
The local sparse matrix.
void getLocalRowView(LocalOrdinal LocalRow, local_inds_host_view_type &indices, values_host_view_type &values) const override
Get a constant view of a row of this matrix, using local row and column indices.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
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.
typename Kokkos::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
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...
typename crs_graph_type::local_graph_device_type local_graph_device_type
The part of the sparse matrix's graph on each MPI process.
void getGlobalRowView(GlobalOrdinal GlobalRow, global_inds_host_view_type &indices, values_host_view_type &values) const override
Get a constant, nonpersisting view of a row of this matrix, using global row and column indices.
void setAllValues(const typename local_graph_device_type::row_map_type &ptr, const typename local_graph_device_type::entries_type::non_const_type &ind, const typename local_matrix_device_type::values_type &val)
Set the local matrix using three (compressed sparse row) arrays.
Teuchos::RCP< const RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const override
This matrix's graph, as a RowGraph.
void clearGlobalConstants()
Clear matrix properties that require collectives.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap) override
Remove processes owning zero rows from the Maps and their communicator.
size_t getNodeMaxNumRowEntries() const override
Maximum number of entries in any row of the matrix, on this process.
virtual LocalOrdinal sumIntoLocalValuesImpl(impl_scalar_type rowVals[], const crs_graph_type &graph, const RowInfo &rowInfo, const LocalOrdinal inds[], const impl_scalar_type newVals[], const LocalOrdinal numElts, const bool atomic=useAtomicUpdatesByDefault)
Implementation detail of sumIntoLocalValues.
void swap(CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &matrix)
Swaps the data from *this with the data and maps from crsMatrix.
bool isStaticGraph() const
Indicates that the graph is static, so that new entries cannot be added to this matrix.
global_size_t getGlobalNumEntries() const override
The global number of entries in this matrix.
virtual LocalOrdinal replaceLocalValuesImpl(impl_scalar_type rowVals[], const crs_graph_type &graph, const RowInfo &rowInfo, const LocalOrdinal inds[], const impl_scalar_type newVals[], const LocalOrdinal numElts)
Implementation detail of replaceLocalValues.
mag_type frobNorm_
Cached Frobenius norm of the (global) matrix.
bool isFillComplete() const override
Whether the matrix is fill complete.
virtual bool checkSizes(const SrcDistObject &source) override
Compare the source and target (this) objects for compatibility.
Teuchos::RCP< const map_type > getRowMap() const override
The Map that describes the row distribution in this matrix.
typename device_type::memory_space memory_space
The Kokkos memory space.
ProfileType getProfileType() const
Returns true if the matrix was allocated with static data structures.
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)
Replace one or more entries' values, using local row and column indices.
size_t getNodeNumEntries() const override
The local number of entries in this matrix.
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.
values_dualv_type::t_host::const_type getValuesViewHost(const RowInfo &rowinfo) const
Get a const Host view of the locally owned values row myRow, such that rowinfo = getRowInfo(myRow).
bool isLocallyIndexed() const override
Whether the matrix is locally indexed on the calling process.
typename row_matrix_type::impl_scalar_type impl_scalar_type
The type used internally in place of Scalar.
Teuchos::RCP< MV > getRowMapMultiVector(const MV &Y_rangeMap, const bool force=false) const
Create a (or fetch a cached) row Map MultiVector.
virtual LocalOrdinal replaceGlobalValuesImpl(impl_scalar_type rowVals[], const crs_graph_type &graph, const RowInfo &rowInfo, const GlobalOrdinal inds[], const impl_scalar_type newVals[], const LocalOrdinal numElts)
Implementation detail of replaceGlobalValues.
values_dualv_type::t_host getValuesViewHostNonConst(const RowInfo &rowinfo)
Get a non-const Host view of the locally owned values row myRow, such that rowinfo = getRowInfo(myRow...
void resumeFill(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Resume operations that may change the values or structure of the matrix.
void getLocalDiagOffsets(Teuchos::ArrayRCP< size_t > &offsets) const
Get offsets of the diagonal entries in the matrix.
void fillLocalMatrix(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Fill data into the local matrix.
void rightScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x) override
Scale the matrix on the right with the given Vector.
bool isStorageOptimized() const
Returns true if storage has been optimized.
void getLocalRowCopy(LocalOrdinal LocalRow, nonconst_local_inds_host_view_type &Indices, nonconst_values_host_view_type &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,...
values_dualv_type::t_dev::const_type getValuesViewDevice(const RowInfo &rowinfo) const
Get a const Device view of the locally owned values row myRow, such that rowinfo = getRowInfo(myRow).
void leftScale(const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x) override
Scale the matrix on the left with the given Vector.
virtual bool supportsRowViews() const override
Return true if getLocalRowView() and getGlobalRowView() are valid for this object.
static size_t mergeRowIndicesAndValues(size_t rowLen, local_ordinal_type *cols, impl_scalar_type *vals)
Merge duplicate row indices in the given row, along with their corresponding values.
Teuchos::RCP< const crs_graph_type > getCrsGraph() const
This matrix's graph, as a CrsGraph.
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.
Description of Tpetra's behavior.
static bool debug()
Whether Tpetra is in debug mode.
static bool verbose()
Whether Tpetra is in verbose mode.
static size_t verbosePrintCountThreshold()
Number of entries below which arrays, lists, etc. will be printed in debug mode.
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?
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").
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
bool isDistributed() const
Whether this is a globally distributed object.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
A parallel distribution of indices over processes.
global_ordinal_type getGlobalElement(local_ordinal_type localIndex) const
The global index corresponding to the given local index.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
local_ordinal_type getLocalElement(global_ordinal_type globalIndex) const
The local index corresponding to the given global index.
bool isNodeGlobalElement(global_ordinal_type globalIndex) const
Whether the given global index is owned by this Map on the calling process.
local_map_type getLocalMap() const
Get the local Map for Kokkos kernels.
One or more distributed dense vectors.
void reduce()
Sum values of a locally replicated multivector across all processes.
void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
size_t getLocalLength() const
Local number of rows on the calling process.
size_t getNumVectors() const
Number of columns in the multivector.
dual_view_type::t_dev::const_type getLocalViewDevice(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on device. This requires that th...
dual_view_type::t_host::const_type getLocalViewHost(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on host. This requires that ther...
bool isConstantStride() const
Whether this multivector has constant stride between columns.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
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....
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....
A read-only, row-oriented interface to a sparse matrix.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes the distribution of rows over processes.
virtual void getGlobalRowCopy(GlobalOrdinal GlobalRow, nonconst_global_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const =0
Get a copy of the given global row's entries.
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0
The current number of entries on the calling process in the specified local row.
Abstract base class for objects that can be the source of an Import or Export operation.
A distributed dense vector.
Implementation details of Tpetra.
void padCrsArrays(const RowPtr &rowPtrBeg, const RowPtr &rowPtrEnd, Indices &indices_wdv, 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....
void verbosePrintArray(std::ostream &out, const ArrayType &x, const char name[], const size_t maxNumToPrint)
Print min(x.size(), maxNumToPrint) entries of x.
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.
void leftScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Left-scale a KokkosSparse::CrsMatrix.
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...
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, 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
Kokkos::DualView< ValueType *, DeviceType > castAwayConstDualView(const Kokkos::DualView< const ValueType *, DeviceType > &input_dv)
Cast away const-ness of a 1-D Kokkos::DualView.
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, 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 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....
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.
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)
Pack specified entries of the given local sparse matrix for communication.
void rightScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Right-scale a KokkosSparse::CrsMatrix.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
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.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const ExecutionSpace &execSpace, const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
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,...
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)
Pack specified entries of the given local sparse matrix for communication, for "new" DistObject inter...
Teuchos::ArrayView< typename DualViewType::t_dev::value_type > getArrayViewFromDualView(const DualViewType &x)
Get a Teuchos::ArrayView which views the host Kokkos::View of the input 1-D Kokkos::DualView.
void 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,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void sort(View &view, const size_t &size)
Convenience wrapper for std::sort for host-accessible views.
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.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
Teuchos_Ordinal Array_size_type
Size type for Teuchos Array objects.
size_t global_size_t
Global size_t object.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
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,...
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2)
Merge values in place, additively, with the same index.
CombineMode
Rule for combining data in an Import or Export.
@ REPLACE
Replace existing values with new values.
@ ABSMAX
Replace old value with maximum of magnitudes of old and new values.
@ ADD_ASSIGN
Accumulate new values into existing values (may not be supported in all classes)
@ INSERT
Insert new values that don't currently exist.
@ ZERO
Replace old values with zero.
Functor for the the ABSMAX CombineMode of Import and Export operations.
Scalar operator()(const Scalar &x, const Scalar &y)
Return the maximum of the magnitudes (absolute values) of x and y.
Traits class for packing / unpacking data of type T.
static KOKKOS_INLINE_FUNCTION size_t unpackValue(LO &outVal, const char inBuf[])
Unpack the given value from the given output buffer.
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).
static KOKKOS_INLINE_FUNCTION size_t packValueCount(const LO &)
Number of bytes required to pack or unpack the given value of type value_type.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.