42 #ifndef TPETRA_EXPERIMENTAL_BLOCKCRSMATRIX_DEF_HPP 43 #define TPETRA_EXPERIMENTAL_BLOCKCRSMATRIX_DEF_HPP 52 namespace Experimental {
54 template<
class Scalar,
class LO,
class GO,
class Node>
56 BlockCrsMatrix<Scalar, LO, GO, Node>::
57 markLocalErrorAndGetStream ()
59 * (this->localError_) =
true;
60 if ((*errs_).is_null ()) {
61 *errs_ = Teuchos::rcp (
new std::ostringstream ());
66 template<
class Scalar,
class LO,
class GO,
class Node>
71 blockSize_ (static_cast<LO> (0)),
77 localError_ (new bool (false)),
78 errs_ (new
Teuchos::RCP<std::ostringstream> ()),
79 computedDiagonalGraph_(false)
83 template<
class Scalar,
class LO,
class GO,
class Node>
90 blockSize_ (blockSize),
97 localError_ (new bool (false)),
98 errs_ (new
Teuchos::RCP<std::ostringstream> ()),
99 computedDiagonalGraph_(false)
101 TEUCHOS_TEST_FOR_EXCEPTION(
102 ! graph_.
isSorted (), std::invalid_argument,
"Tpetra::Experimental::" 103 "BlockCrsMatrix constructor: The input CrsGraph does not have sorted " 104 "rows (isSorted() is false). This class assumes sorted rows.");
106 graphRCP_ = Teuchos::rcpFromRef(graph_);
112 const bool blockSizeIsNonpositive = (blockSize + 1 <= 1);
113 TEUCHOS_TEST_FOR_EXCEPTION(
114 blockSizeIsNonpositive, std::invalid_argument,
"Tpetra::Experimental::" 115 "BlockCrsMatrix constructor: The input blockSize = " << blockSize <<
116 " <= 0. The block size must be positive.");
122 typedef typename crs_graph_type::local_graph_type::row_map_type row_map_type;
123 typedef typename row_map_type::HostMirror::non_const_type nc_host_row_map_type;
128 nc_host_row_map_type ptr_h_nc = Kokkos::create_mirror_view (ptr_d);
134 val_ = valView_.getRawPtr ();
137 template<
class Scalar,
class LO,
class GO,
class Node>
142 const LO blockSize) :
146 domainPointMap_ (domainPointMap),
147 rangePointMap_ (rangePointMap),
148 blockSize_ (blockSize),
154 localError_ (new bool (false)),
155 errs_ (new
Teuchos::RCP<std::ostringstream> ()),
156 computedDiagonalGraph_(false)
158 TEUCHOS_TEST_FOR_EXCEPTION(
159 ! graph_.
isSorted (), std::invalid_argument,
"Tpetra::Experimental::" 160 "BlockCrsMatrix constructor: The input CrsGraph does not have sorted " 161 "rows (isSorted() is false). This class assumes sorted rows.");
163 graphRCP_ = Teuchos::rcpFromRef(graph_);
169 const bool blockSizeIsNonpositive = (blockSize + 1 <= 1);
170 TEUCHOS_TEST_FOR_EXCEPTION(
171 blockSizeIsNonpositive, std::invalid_argument,
"Tpetra::Experimental::" 172 "BlockCrsMatrix constructor: The input blockSize = " << blockSize <<
173 " <= 0. The block size must be positive.");
176 typedef typename crs_graph_type::local_graph_type::row_map_type row_map_type;
177 typedef typename row_map_type::HostMirror::non_const_type nc_host_row_map_type;
182 nc_host_row_map_type ptr_h_nc = Kokkos::create_mirror_view (ptr_d);
188 val_ = valView_.getRawPtr ();
191 template<
class Scalar,
class LO,
class GO,
class Node>
192 Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
197 return Teuchos::rcp (
new map_type (domainPointMap_));
200 template<
class Scalar,
class LO,
class GO,
class Node>
201 Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
206 return Teuchos::rcp (
new map_type (rangePointMap_));
209 template<
class Scalar,
class LO,
class GO,
class Node>
210 Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
217 template<
class Scalar,
class LO,
class GO,
class Node>
218 Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
225 template<
class Scalar,
class LO,
class GO,
class Node>
233 template<
class Scalar,
class LO,
class GO,
class Node>
241 template<
class Scalar,
class LO,
class GO,
class Node>
249 template<
class Scalar,
class LO,
class GO,
class Node>
254 Teuchos::ETransp mode,
259 TEUCHOS_TEST_FOR_EXCEPTION(
260 mode != Teuchos::NO_TRANS && mode != Teuchos::TRANS && mode != Teuchos::CONJ_TRANS,
261 std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::apply: " 262 "Invalid 'mode' argument. Valid values are Teuchos::NO_TRANS, " 263 "Teuchos::TRANS, and Teuchos::CONJ_TRANS.");
272 catch (std::invalid_argument& e) {
273 TEUCHOS_TEST_FOR_EXCEPTION(
274 true, std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::" 275 "apply: Either the input MultiVector X or the output MultiVector Y " 276 "cannot be viewed as a BlockMultiVector, given this BlockCrsMatrix's " 277 "graph. BlockMultiVector's constructor threw the following exception: " 286 const_cast<this_type*
> (
this)->
applyBlock (X_view, Y_view, mode, alpha, beta);
287 }
catch (std::invalid_argument& e) {
288 TEUCHOS_TEST_FOR_EXCEPTION(
289 true, std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::" 290 "apply: The implementation method applyBlock complained about having " 291 "an invalid argument. It reported the following: " << e.what ());
292 }
catch (std::logic_error& e) {
293 TEUCHOS_TEST_FOR_EXCEPTION(
294 true, std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::" 295 "apply: The implementation method applyBlock complained about a " 296 "possible bug in its implementation. It reported the following: " 298 }
catch (std::exception& e) {
299 TEUCHOS_TEST_FOR_EXCEPTION(
300 true, std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::" 301 "apply: The implementation method applyBlock threw an exception which " 302 "is neither std::invalid_argument nor std::logic_error, but is a " 303 "subclass of std::exception. It reported the following: " 306 TEUCHOS_TEST_FOR_EXCEPTION(
307 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 308 "apply: The implementation method applyBlock threw an exception which " 309 "is not an instance of a subclass of std::exception. This probably " 310 "indicates a bug. Please report this to the Tpetra developers.");
314 template<
class Scalar,
class LO,
class GO,
class Node>
319 Teuchos::ETransp mode,
323 TEUCHOS_TEST_FOR_EXCEPTION(
325 "Tpetra::Experimental::BlockCrsMatrix::applyBlock: " 326 "X and Y have different block sizes. X.getBlockSize() = " 330 if (mode == Teuchos::NO_TRANS) {
331 applyBlockNoTrans (X, Y, alpha, beta);
332 }
else if (mode == Teuchos::TRANS || mode == Teuchos::CONJ_TRANS) {
333 applyBlockTrans (X, Y, mode, alpha, beta);
335 TEUCHOS_TEST_FOR_EXCEPTION(
336 true, std::invalid_argument,
"Tpetra::Experimental::BlockCrsMatrix::" 337 "applyBlock: Invalid 'mode' argument. Valid values are " 338 "Teuchos::NO_TRANS, Teuchos::TRANS, and Teuchos::CONJ_TRANS.");
342 template<
class Scalar,
class LO,
class GO,
class Node>
348 for (LO lclRow = 0; lclRow < numLocalMeshRows; ++lclRow) {
349 const size_t meshBeg = ptr_[lclRow];
350 const size_t meshEnd = ptr_[lclRow+1];
351 for (
size_t absBlkOff = meshBeg; absBlkOff < meshEnd; ++absBlkOff) {
353 A_cur.
fill (static_cast<impl_scalar_type> (alpha));
358 template<
class Scalar,
class LO,
class GO,
class Node>
364 const LO numColInds)
const 371 return static_cast<LO
> (0);
375 const size_t absRowBlockOffset = ptr_[localRowInd];
376 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
377 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
379 size_t pointOffset = 0;
382 for (LO k = 0; k < numColInds; ++k, pointOffset += perBlockSize) {
383 const size_t relBlockOffset =
384 findRelOffsetOfColumnIndex (localRowInd, colInds[k], hint);
385 if (relBlockOffset != STINV) {
386 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
388 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
390 getConstLocalBlockFromInput (vIn, pointOffset);
392 hint = relBlockOffset + 1;
399 template <
class Scalar,
class LO,
class GO,
class Node>
409 if (static_cast<size_t> (offsets.size ()) != myNumRows) {
410 offsets.resize (static_cast<size_t> (myNumRows));
413 #ifdef HAVE_TPETRA_DEBUG 414 bool allRowMapDiagEntriesInColMap =
true;
415 bool allDiagEntriesFound =
true;
416 #endif // HAVE_TPETRA_DEBUG 418 for (
size_t r = 0; r < myNumRows; ++r) {
422 #ifdef HAVE_TPETRA_DEBUG 423 if (rlid == Teuchos::OrdinalTraits<LO>::invalid ()) {
424 allRowMapDiagEntriesInColMap =
false;
426 #endif // HAVE_TPETRA_DEBUG 428 if (rlid != Teuchos::OrdinalTraits<LO>::invalid ()) {
430 if (rowinfo.numEntries > 0) {
434 offsets[r] = Teuchos::OrdinalTraits<size_t>::invalid ();
435 #ifdef HAVE_TPETRA_DEBUG 436 allDiagEntriesFound =
false;
437 #endif // HAVE_TPETRA_DEBUG 442 #ifdef HAVE_TPETRA_DEBUG 443 using Teuchos::reduceAll;
445 const char tfecfFuncName[] =
"getLocalDiagOffsets";
447 const bool localSuccess =
448 allRowMapDiagEntriesInColMap && allDiagEntriesFound;
450 localResults[0] = allRowMapDiagEntriesInColMap ? 1 : 0;
451 localResults[1] = allDiagEntriesFound ? 1 : 0;
456 int globalResults[3];
457 globalResults[0] = 0;
458 globalResults[1] = 0;
459 globalResults[2] = 0;
460 reduceAll<int, int> (* (
getComm ()), Teuchos::REDUCE_MIN,
461 3, localResults, globalResults);
462 if (globalResults[0] == 0 || globalResults[1] == 0) {
463 std::ostringstream os;
465 globalResults[0] == 0 && globalResults[1] == 0;
466 os <<
": At least one process (including Process " << globalResults[2]
467 <<
") had the following issue" << (both ?
"s" :
"") <<
":" << endl;
468 if (globalResults[0] == 0) {
469 os <<
" - The column Map does not contain at least one diagonal entry " 470 "of the matrix." << endl;
472 if (globalResults[1] == 0) {
473 os <<
" - There is a row on that / those process(es) that does not " 474 "contain a diagonal entry." << endl;
476 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::runtime_error, os.str());
478 #endif // HAVE_TPETRA_DEBUG 481 template <
class Scalar,
class LO,
class GO,
class Node>
488 if (computedDiagonalGraph_) {
498 const size_t maxDiagEntPerRow = 1;
508 Teuchos::Array<GO> diagGblColInds (maxDiagEntPerRow);
513 diagGblColInds[0] = gblRowInd;
514 diagonalGraph_->insertGlobalIndices (gblRowInd, diagGblColInds ());
518 computedDiagonalGraph_ =
true;
521 template <
class Scalar,
class LO,
class GO,
class Node>
522 Teuchos::RCP<CrsGraph<LO, GO, Node> >
526 TEUCHOS_TEST_FOR_EXCEPTION(
527 ! computedDiagonalGraph_, std::runtime_error,
"Tpetra::Experimental::" 528 "BlockCrsMatrix::getDiagonalGraph: You must call computeDiagonalGraph() " 529 "before calling this method.");
530 return diagonalGraph_;
533 template <
class Scalar,
class LO,
class GO,
class Node>
539 const int * factorizationPivots,
543 const LO numLocalMeshRows =
552 Teuchos::Array<impl_scalar_type> localMem (blockSize);
553 Teuchos::Array<impl_scalar_type> localMat (blockSize*blockSize);
556 const LO * columnIndices;
561 LO rowBegin = 0, rowEnd = 0, rowStride = 0;
562 if (direction == Forward) {
564 rowEnd = numLocalMeshRows+1;
567 else if (direction == Backward) {
568 rowBegin = numLocalMeshRows;
572 else if (direction == Symmetric) {
573 this->
localGaussSeidel (B, X, factorizedDiagonal, factorizationPivots, omega, Forward);
574 this->
localGaussSeidel (B, X, factorizedDiagonal, factorizationPivots, omega, Backward);
578 const Scalar one_minus_omega = Teuchos::ScalarTraits<Scalar>::one()-omega;
579 const Scalar minus_omega = -omega;
582 for (LO lclRow = rowBegin; lclRow != rowEnd; lclRow += rowStride) {
583 const LO actlRow = lclRow - 1;
589 const size_t meshBeg = ptr_[actlRow];
590 const size_t meshEnd = ptr_[actlRow+1];
591 for (
size_t absBlkOff = meshBeg; absBlkOff < meshEnd; ++absBlkOff) {
592 const LO meshCol = ind_[absBlkOff];
594 getConstLocalBlockFromAbsOffset (absBlkOff);
599 const Scalar alpha = meshCol == actlRow ? one_minus_omega : minus_omega;
606 getNonConstLocalBlockFromInput (reinterpret_cast<impl_scalar_type*> (Dmat), 0);
608 D_lcl.solve (X_lcl, &factorizationPivots[actlRow*blockSize_]);
614 for (LO lclRow = rowBegin; lclRow != rowEnd; lclRow += rowStride) {
615 for (LO j = 0; j < numVecs; ++j) {
616 LO actlRow = lclRow-1;
622 const size_t meshBeg = ptr_[actlRow];
623 const size_t meshEnd = ptr_[actlRow+1];
624 for (
size_t absBlkOff = meshBeg; absBlkOff < meshEnd; ++absBlkOff) {
625 const LO meshCol = ind_[absBlkOff];
627 getConstLocalBlockFromAbsOffset (absBlkOff);
632 const Scalar alpha = meshCol == actlRow ? one_minus_omega : minus_omega;
639 getNonConstLocalBlockFromInput (reinterpret_cast<impl_scalar_type*> (Dmat), 0);
641 D_lcl.solve (X_lcl, &factorizationPivots[actlRow*blockSize_]);
650 template <
class Scalar,
class LO,
class GO,
class Node>
656 const Scalar& dampingFactor,
659 const bool zeroInitialGuess)
const 663 TEUCHOS_TEST_FOR_EXCEPTION(
664 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 665 "gaussSeidelCopy: Not implemented.");
668 template <
class Scalar,
class LO,
class GO,
class Node>
674 const ArrayView<LO>& rowIndices,
675 const Scalar& dampingFactor,
678 const bool zeroInitialGuess)
const 682 TEUCHOS_TEST_FOR_EXCEPTION(
683 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 684 "reorderedGaussSeidelCopy: Not implemented.");
687 template <
class Scalar,
class LO,
class GO,
class Node>
691 const Teuchos::ArrayView<const size_t>& offsets)
const 693 using Teuchos::ArrayRCP;
694 using Teuchos::ArrayView;
695 const Scalar
ZERO = Teuchos::ScalarTraits<Scalar>::zero ();
698 const LO* columnIndices;
701 Teuchos::Array<LO> cols(1);
704 Teuchos::Array<Scalar> zeroMat (blockSize_*blockSize_, ZERO);
705 for (
size_t i = 0; i < myNumRows; ++i) {
707 if (offsets[i] == Teuchos::OrdinalTraits<size_t>::invalid ()) {
712 diag.
replaceLocalValues (i, cols.getRawPtr(), &vals[offsets[i]*blockSize_*blockSize_], 1);
718 template<
class Scalar,
class LO,
class GO,
class Node>
724 const LO numColInds)
const 731 return static_cast<LO
> (0);
735 const size_t absRowBlockOffset = ptr_[localRowInd];
736 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
737 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
739 size_t pointOffset = 0;
742 for (LO k = 0; k < numColInds; ++k, pointOffset += perBlockSize) {
743 const size_t relBlockOffset =
744 findRelOffsetOfColumnIndex (localRowInd, colInds[k], hint);
745 if (relBlockOffset != STINV) {
746 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
748 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
750 getConstLocalBlockFromInput (vIn, pointOffset);
752 hint = relBlockOffset + 1;
760 template<
class Scalar,
class LO,
class GO,
class Node>
766 const LO numColInds)
const 773 return static_cast<LO
> (0);
777 const size_t absRowBlockOffset = ptr_[localRowInd];
778 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
779 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
781 size_t pointOffset = 0;
784 for (LO k = 0; k < numColInds; ++k, pointOffset += perBlockSize) {
785 const size_t relBlockOffset =
786 findRelOffsetOfColumnIndex (localRowInd, colInds[k], hint);
787 if (relBlockOffset != STINV) {
788 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
790 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
792 getConstLocalBlockFromInput (vIn, pointOffset);
793 A_old.
update (static_cast<impl_scalar_type> (STS::one ()), A_new);
794 hint = relBlockOffset + 1;
801 template<
class Scalar,
class LO,
class GO,
class Node>
813 return Teuchos::OrdinalTraits<LO>::invalid ();
816 const size_t absBlockOffsetStart = ptr_[localRowInd];
817 colInds = ind_ + absBlockOffsetStart;
819 impl_scalar_type*
const vOut = val_ + absBlockOffsetStart * offsetPerBlock ();
820 vals =
reinterpret_cast<Scalar*
> (vOut);
822 numInds = ptr_[localRowInd + 1] - absBlockOffsetStart;
827 template<
class Scalar,
class LO,
class GO,
class Node>
831 const Teuchos::ArrayView<LO>& Indices,
832 const Teuchos::ArrayView<Scalar>& Values,
833 size_t &NumEntries)
const 839 if (numInds > Indices.size() || numInds > Values.size()) {
840 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
841 "Tpetra::BlockCrsMatrix::getLocalRowCopy : Column and/or values array is not large enough to hold " 842 << numInds <<
" row entries");
844 for (LO i=0; i<numInds; ++i) {
845 Indices[i] = colInds[i];
848 NumEntries = numInds;
851 template<
class Scalar,
class LO,
class GO,
class Node>
857 const LO numColInds)
const 864 return static_cast<LO
> (0);
867 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
871 for (LO k = 0; k < numColInds; ++k) {
872 const size_t relBlockOffset =
873 findRelOffsetOfColumnIndex (localRowInd, colInds[k], hint);
874 if (relBlockOffset != STINV) {
875 offsets[k] = relBlockOffset;
876 hint = relBlockOffset + 1;
884 template<
class Scalar,
class LO,
class GO,
class Node>
888 const ptrdiff_t offsets[],
890 const LO numOffsets)
const 897 return static_cast<LO
> (0);
901 const size_t absRowBlockOffset = ptr_[localRowInd];
902 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
903 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
904 size_t pointOffset = 0;
907 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
908 const size_t relBlockOffset = offsets[k];
909 if (relBlockOffset != STINV) {
910 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
912 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
914 getConstLocalBlockFromInput (vIn, pointOffset);
923 template<
class Scalar,
class LO,
class GO,
class Node>
927 const ptrdiff_t offsets[],
929 const LO numOffsets)
const 936 return static_cast<LO
> (0);
940 const size_t absRowBlockOffset = ptr_[localRowInd];
941 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
942 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
943 size_t pointOffset = 0;
946 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
947 const size_t relBlockOffset = offsets[k];
948 if (relBlockOffset != STINV) {
949 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
951 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
953 getConstLocalBlockFromInput (vIn, pointOffset);
962 template<
class Scalar,
class LO,
class GO,
class Node>
966 const ptrdiff_t offsets[],
968 const LO numOffsets)
const 975 return static_cast<LO
> (0);
979 const size_t absRowBlockOffset = ptr_[localRowInd];
980 const size_t perBlockSize =
static_cast<LO
> (offsetPerBlock ());
981 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
982 size_t pointOffset = 0;
985 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
986 const size_t relBlockOffset = offsets[k];
987 if (relBlockOffset != STINV) {
988 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
990 getNonConstLocalBlockFromAbsOffset (absBlockOffset);
992 getConstLocalBlockFromInput (vIn, pointOffset);
993 A_old.
update (static_cast<impl_scalar_type> (STS::one ()), A_new);
1001 template<
class Scalar,
class LO,
class GO,
class Node>
1007 if (numEntInGraph == Teuchos::OrdinalTraits<size_t>::invalid ()) {
1008 return static_cast<LO
> (0);
1010 return static_cast<LO
> (numEntInGraph);
1014 template<
class Scalar,
class LO,
class GO,
class Node>
1019 const Teuchos::ETransp mode,
1029 TEUCHOS_TEST_FOR_EXCEPTION(
1030 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::apply: " 1031 "transpose and conjugate transpose modes are not yet implemented.");
1034 template<
class Scalar,
class LO,
class GO,
class Node>
1046 const Scalar zero = STS::zero ();
1047 const Scalar one = STS::one ();
1048 RCP<const import_type>
import = graph_.
getImporter ();
1050 RCP<const export_type> theExport = graph_.
getExporter ();
1054 TEUCHOS_TEST_FOR_EXCEPTION(
1056 "Tpetra::Experimental::BlockCrsMatrix::applyBlockNoTrans: " 1057 "The input BlockMultiVector X has deep copy semantics, " 1058 "not view semantics (as it should).");
1059 TEUCHOS_TEST_FOR_EXCEPTION(
1061 "Tpetra::Experimental::BlockCrsMatrix::applyBlockNoTrans: " 1062 "The output BlockMultiVector Y has deep copy semantics, " 1063 "not view semantics (as it should).");
1065 if (alpha == zero) {
1068 }
else if (beta != one) {
1072 const BMV* X_colMap = NULL;
1073 if (
import.is_null ()) {
1076 }
catch (std::exception& e) {
1077 TEUCHOS_TEST_FOR_EXCEPTION(
1078 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 1079 "applyBlockNoTrans:" << std::endl <<
"Tpetra::MultiVector::" 1080 "operator= threw an exception: " << std::endl << e.what ());
1089 if ((*X_colMap_).is_null () ||
1097 X_colMap = &(**X_colMap_);
1098 }
catch (std::exception& e) {
1099 TEUCHOS_TEST_FOR_EXCEPTION(
1100 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 1101 "applyBlockNoTrans:" << std::endl <<
"Tpetra::MultiVector::" 1102 "operator= threw an exception: " << std::endl << e.what ());
1106 BMV* Y_rowMap = NULL;
1107 if (theExport.is_null ()) {
1109 }
else if ((*Y_rowMap_).is_null () ||
1115 Y_rowMap = &(**Y_rowMap_);
1116 }
catch (std::exception& e) {
1117 TEUCHOS_TEST_FOR_EXCEPTION(
1118 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::" 1119 "applyBlockNoTrans:" << std::endl <<
"Tpetra::MultiVector::" 1120 "operator= threw an exception: " << std::endl << e.what ());
1124 localApplyBlockNoTrans (*X_colMap, *Y_rowMap, alpha, beta);
1126 if (! theExport.is_null ()) {
1132 template<
class Scalar,
class LO,
class GO,
class Node>
1142 const Scalar zero = STS::zero ();
1143 const Scalar one = STS::one ();
1144 const LO numLocalMeshRows =
1153 Teuchos::Array<impl_scalar_type> localMem (blockSize);
1157 for (LO lclRow = 0; lclRow < numLocalMeshRows; ++lclRow) {
1162 }
else if (beta == one) {
1163 Y_lcl.assign (Y_cur);
1165 Y_lcl.assign (Y_cur);
1169 const size_t meshBeg = ptr_[lclRow];
1170 const size_t meshEnd = ptr_[lclRow+1];
1171 for (
size_t absBlkOff = meshBeg; absBlkOff < meshEnd; ++absBlkOff) {
1172 const LO meshCol = ind_[absBlkOff];
1174 getConstLocalBlockFromAbsOffset (absBlkOff);
1184 for (LO lclRow = 0; lclRow < numLocalMeshRows; ++lclRow) {
1185 for (LO j = 0; j < numVecs; ++j) {
1190 }
else if (beta == one) {
1191 Y_lcl.assign (Y_cur);
1193 Y_lcl.assign (Y_cur);
1197 const size_t meshBeg = ptr_[lclRow];
1198 const size_t meshEnd = ptr_[lclRow+1];
1199 for (
size_t absBlkOff = meshBeg; absBlkOff < meshEnd; ++absBlkOff) {
1200 const LO meshCol = ind_[absBlkOff];
1202 getConstLocalBlockFromAbsOffset (absBlkOff);
1214 template<
class Scalar,
class LO,
class GO,
class Node>
1218 const LO colIndexToFind,
1219 const size_t hint)
const 1221 const size_t absStartOffset = ptr_[localRowIndex];
1222 const size_t absEndOffset = ptr_[localRowIndex+1];
1223 const size_t numEntriesInRow = absEndOffset - absStartOffset;
1226 if (hint < numEntriesInRow && ind_[absStartOffset+hint] == colIndexToFind) {
1233 size_t relOffset = Teuchos::OrdinalTraits<size_t>::invalid ();
1238 const size_t maxNumEntriesForLinearSearch = 32;
1239 if (numEntriesInRow > maxNumEntriesForLinearSearch) {
1244 const LO* beg = ind_ + absStartOffset;
1245 const LO* end = ind_ + absEndOffset;
1246 std::pair<const LO*, const LO*> p =
1247 std::equal_range (beg, end, colIndexToFind);
1248 if (p.first != p.second) {
1250 relOffset =
static_cast<size_t> (p.first - beg);
1254 for (
size_t k = 0; k < numEntriesInRow; ++k) {
1255 if (colIndexToFind == ind_[absStartOffset + k]) {
1265 template<
class Scalar,
class LO,
class GO,
class Node>
1270 const LO numRows = blockSize_;
1272 LO numCols = blockSize_;
1273 if (columnPadding_ > 0) {
1274 const LO numColsRoundedDown = (blockSize_ / columnPadding_) * columnPadding_;
1275 numCols = (numColsRoundedDown < numCols) ?
1276 (numColsRoundedDown + columnPadding_) :
1279 return numRows * numCols;
1282 template<
class Scalar,
class LO,
class GO,
class Node>
1286 const size_t pointOffset)
const 1289 const size_t rowStride = (columnPadding_ == 0) ?
1290 static_cast<size_t> (blockSize_) :
static_cast<size_t> (columnPadding_);
1297 template<
class Scalar,
class LO,
class GO,
class Node>
1301 const size_t pointOffset)
const 1304 const size_t rowStride = (columnPadding_ == 0) ?
1305 static_cast<size_t> (blockSize_) :
static_cast<size_t> (columnPadding_);
1312 template<
class Scalar,
class LO,
class GO,
class Node>
1323 const size_t absPointOffset = absBlockOffset * offsetPerBlock ();
1324 return getConstLocalBlockFromInput (val_, absPointOffset);
1328 template<
class Scalar,
class LO,
class GO,
class Node>
1339 const size_t absPointOffset = absBlockOffset * offsetPerBlock ();
1340 return getNonConstLocalBlockFromInput (const_cast<impl_scalar_type*> (val_),
1345 template<
class Scalar,
class LO,
class GO,
class Node>
1348 getLocalBlock (
const LO localRowInd,
const LO localColInd)
const 1350 const size_t absRowBlockOffset = ptr_[localRowInd];
1353 const size_t relBlockOffset =
1354 findRelOffsetOfColumnIndex (localRowInd, localColInd, hint);
1356 if (relBlockOffset != Teuchos::OrdinalTraits<size_t>::invalid ()) {
1357 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
1358 return getNonConstLocalBlockFromAbsOffset (absBlockOffset);
1375 template<
class Scalar,
class LO,
class GO,
class Node>
1382 const this_type* src =
dynamic_cast<const this_type*
> (&source);
1385 std::ostream& err = markLocalErrorAndGetStream ();
1386 err <<
"checkSizes: The source object of the Import or Export " 1387 "must be a BlockCrsMatrix with the same template parameters as the " 1388 "target object." << endl;
1394 std::ostream& err = markLocalErrorAndGetStream ();
1395 err <<
"checkSizes: The source and target objects of the Import or " 1396 <<
"Export must have the same block sizes. The source's block " 1397 <<
"size = " << src->getBlockSize () <<
" != the target's block " 1400 if (! src->graph_.isFillComplete ()) {
1401 std::ostream& err = markLocalErrorAndGetStream ();
1402 err <<
"checkSizes: The source object of the Import or Export is " 1403 "not fill complete. Both source and target objects must be fill " 1404 "complete." << endl;
1407 std::ostream& err = markLocalErrorAndGetStream ();
1408 err <<
"checkSizes: The target object of the Import or Export is " 1409 "not fill complete. Both source and target objects must be fill " 1410 "complete." << endl;
1412 if (src->graph_.getColMap ().is_null ()) {
1413 std::ostream& err = markLocalErrorAndGetStream ();
1414 err <<
"checkSizes: The source object of the Import or Export does " 1415 "not have a column Map. Both source and target objects must have " 1416 "column Maps." << endl;
1418 if (this->graph_.
getColMap ().is_null ()) {
1419 std::ostream& err = markLocalErrorAndGetStream ();
1420 err <<
"checkSizes: The target object of the Import or Export does " 1421 "not have a column Map. Both source and target objects must have " 1422 "column Maps." << endl;
1426 return ! (* (this->localError_));
1429 template<
class Scalar,
class LO,
class GO,
class Node>
1434 const Teuchos::ArrayView<const LO>& permuteToLIDs,
1435 const Teuchos::ArrayView<const LO>& permuteFromLIDs)
1439 const bool debug =
false;
1442 std::ostringstream os;
1443 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1444 os <<
"Proc " << myRank <<
": copyAndPermute: " 1445 <<
"numSameIDs: " << numSameIDs
1446 <<
", permuteToLIDs.size(): " << permuteToLIDs.size ()
1447 <<
", permuteFromLIDs.size(): " << permuteFromLIDs.size ()
1449 std::cerr << os.str ();
1455 if (* (this->localError_)) {
1456 std::ostream& err = this->markLocalErrorAndGetStream ();
1457 err <<
"copyAndPermute: The target object of the Import or Export is " 1458 "already in an error state." << endl;
1461 if (permuteToLIDs.size () != permuteFromLIDs.size ()) {
1462 std::ostream& err = this->markLocalErrorAndGetStream ();
1463 err <<
"copyAndPermute: permuteToLIDs.size() = " << permuteToLIDs.size ()
1464 <<
" != permuteFromLIDs.size() = " << permuteFromLIDs.size () <<
"." 1469 const this_type* src =
dynamic_cast<const this_type*
> (&source);
1471 std::ostream& err = this->markLocalErrorAndGetStream ();
1472 err <<
"copyAndPermute: The source object of the Import or Export is " 1473 "either not a BlockCrsMatrix, or does not have the right template " 1474 "parameters. checkSizes() should have caught this. " 1475 "Please report this bug to the Tpetra developers." << endl;
1478 if (* (src->localError_)) {
1479 std::ostream& err = this->markLocalErrorAndGetStream ();
1480 err <<
"copyAndPermute: The source object of the Import or Export is " 1481 "already in an error state." << endl;
1485 bool lclErr =
false;
1486 #ifdef HAVE_TPETRA_DEBUG 1487 std::set<LO> invalidSrcCopyRows;
1488 std::set<LO> invalidDstCopyRows;
1489 std::set<LO> invalidDstCopyCols;
1490 std::set<LO> invalidDstPermuteCols;
1491 std::set<LO> invalidPermuteFromRows;
1492 #endif // HAVE_TPETRA_DEBUG 1501 #ifdef HAVE_TPETRA_DEBUG 1502 const map_type& srcRowMap = * (src->graph_.getRowMap ());
1503 #endif // HAVE_TPETRA_DEBUG 1505 const map_type& srcColMap = * (src->graph_.getColMap ());
1507 const bool canUseLocalColumnIndices = srcColMap.
locallySameAs (dstColMap);
1508 const size_t numPermute =
static_cast<size_t> (permuteFromLIDs.size ());
1511 std::ostringstream os;
1512 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1513 os <<
"Proc " << myRank <<
": copyAndPermute: " 1514 <<
"canUseLocalColumnIndices: " 1515 << (canUseLocalColumnIndices ?
"true" :
"false")
1516 <<
", numPermute: " << numPermute
1518 std::cerr << os.str ();
1521 if (canUseLocalColumnIndices) {
1523 for (LO localRow = 0; localRow < static_cast<LO> (numSameIDs); ++localRow) {
1524 #ifdef HAVE_TPETRA_DEBUG 1527 invalidSrcCopyRows.insert (localRow);
1530 #endif // HAVE_TPETRA_DEBUG 1532 const LO* lclSrcCols;
1537 LO err = src->getLocalRowView (localRow, lclSrcCols, vals, numEntries);
1540 #ifdef HAVE_TPETRA_DEBUG 1541 (void) invalidSrcCopyRows.insert (localRow);
1542 #endif // HAVE_TPETRA_DEBUG 1546 if (err != numEntries) {
1549 #ifdef HAVE_TPETRA_DEBUG 1550 invalidDstCopyRows.insert (localRow);
1551 #endif // HAVE_TPETRA_DEBUG 1559 for (LO k = 0; k < numEntries; ++k) {
1562 #ifdef HAVE_TPETRA_DEBUG 1563 (void) invalidDstCopyCols.insert (lclSrcCols[k]);
1564 #endif // HAVE_TPETRA_DEBUG 1573 for (
size_t k = 0; k < numPermute; ++k) {
1574 const LO srcLclRow =
static_cast<LO
> (permuteFromLIDs[k]);
1575 const LO dstLclRow =
static_cast<LO
> (permuteToLIDs[k]);
1577 const LO* lclSrcCols;
1580 LO err = src->getLocalRowView (srcLclRow, lclSrcCols, vals, numEntries);
1583 #ifdef HAVE_TPETRA_DEBUG 1584 invalidPermuteFromRows.insert (srcLclRow);
1585 #endif // HAVE_TPETRA_DEBUG 1589 if (err != numEntries) {
1591 #ifdef HAVE_TPETRA_DEBUG 1592 for (LO c = 0; c < numEntries; ++c) {
1594 invalidDstPermuteCols.insert (lclSrcCols[c]);
1597 #endif // HAVE_TPETRA_DEBUG 1604 const size_t maxNumEnt = src->graph_.getNodeMaxNumRowEntries ();
1605 Teuchos::Array<LO> lclDstCols (maxNumEnt);
1608 for (LO localRow = 0; localRow < static_cast<LO> (numSameIDs); ++localRow) {
1609 const LO* lclSrcCols;
1616 err = src->getLocalRowView (localRow, lclSrcCols, vals, numEntries);
1617 }
catch (std::exception& e) {
1619 std::ostringstream os;
1620 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1621 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow " 1622 << localRow <<
", src->getLocalRowView() threw an exception: " 1624 std::cerr << os.str ();
1631 #ifdef HAVE_TPETRA_DEBUG 1632 invalidSrcCopyRows.insert (localRow);
1633 #endif // HAVE_TPETRA_DEBUG 1636 if (static_cast<size_t> (numEntries) > static_cast<size_t> (lclDstCols.size ())) {
1639 std::ostringstream os;
1640 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1641 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow " 1642 << localRow <<
", numEntries = " << numEntries <<
" > maxNumEnt = " 1643 << maxNumEnt << endl;
1644 std::cerr << os.str ();
1650 Teuchos::ArrayView<LO> lclDstColsView = lclDstCols.view (0, numEntries);
1651 for (LO j = 0; j < numEntries; ++j) {
1653 if (lclDstColsView[j] == Teuchos::OrdinalTraits<LO>::invalid ()) {
1655 #ifdef HAVE_TPETRA_DEBUG 1656 invalidDstCopyCols.insert (lclDstColsView[j]);
1657 #endif // HAVE_TPETRA_DEBUG 1661 err = this->
replaceLocalValues (localRow, lclDstColsView.getRawPtr (), vals, numEntries);
1662 }
catch (std::exception& e) {
1664 std::ostringstream os;
1665 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1666 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow " 1667 << localRow <<
", this->replaceLocalValues() threw an exception: " 1669 std::cerr << os.str ();
1673 if (err != numEntries) {
1676 std::ostringstream os;
1677 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1678 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" " 1679 "localRow " << localRow <<
", this->replaceLocalValues " 1680 "returned " << err <<
" instead of numEntries = " 1681 << numEntries << endl;
1682 std::cerr << os.str ();
1690 for (
size_t k = 0; k < numPermute; ++k) {
1691 const LO srcLclRow =
static_cast<LO
> (permuteFromLIDs[k]);
1692 const LO dstLclRow =
static_cast<LO
> (permuteToLIDs[k]);
1694 const LO* lclSrcCols;
1699 err = src->getLocalRowView (srcLclRow, lclSrcCols, vals, numEntries);
1700 }
catch (std::exception& e) {
1702 std::ostringstream os;
1703 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1704 os <<
"Proc " << myRank <<
": copyAndPermute: At \"permute\" " 1705 "srcLclRow " << srcLclRow <<
" and dstLclRow " << dstLclRow
1706 <<
", src->getLocalRowView() threw an exception: " << e.what ();
1707 std::cerr << os.str ();
1714 #ifdef HAVE_TPETRA_DEBUG 1715 invalidPermuteFromRows.insert (srcLclRow);
1716 #endif // HAVE_TPETRA_DEBUG 1719 if (static_cast<size_t> (numEntries) > static_cast<size_t> (lclDstCols.size ())) {
1725 Teuchos::ArrayView<LO> lclDstColsView = lclDstCols.view (0, numEntries);
1726 for (LO j = 0; j < numEntries; ++j) {
1728 if (lclDstColsView[j] == Teuchos::OrdinalTraits<LO>::invalid ()) {
1730 #ifdef HAVE_TPETRA_DEBUG 1731 invalidDstPermuteCols.insert (lclDstColsView[j]);
1732 #endif // HAVE_TPETRA_DEBUG 1735 err = this->
replaceLocalValues (dstLclRow, lclDstColsView.getRawPtr (), vals, numEntries);
1736 if (err != numEntries) {
1745 std::ostream& err = this->markLocalErrorAndGetStream ();
1746 #ifdef HAVE_TPETRA_DEBUG 1747 err <<
"copyAndPermute: The graph structure of the source of the " 1748 "Import or Export must be a subset of the graph structure of the " 1750 err <<
"invalidSrcCopyRows = [";
1751 for (
typename std::set<LO>::const_iterator it = invalidSrcCopyRows.begin ();
1752 it != invalidSrcCopyRows.end (); ++it) {
1754 typename std::set<LO>::const_iterator itp1 = it;
1756 if (itp1 != invalidSrcCopyRows.end ()) {
1760 err <<
"], invalidDstCopyRows = [";
1761 for (
typename std::set<LO>::const_iterator it = invalidDstCopyRows.begin ();
1762 it != invalidDstCopyRows.end (); ++it) {
1764 typename std::set<LO>::const_iterator itp1 = it;
1766 if (itp1 != invalidDstCopyRows.end ()) {
1770 err <<
"], invalidDstCopyCols = [";
1771 for (
typename std::set<LO>::const_iterator it = invalidDstCopyCols.begin ();
1772 it != invalidDstCopyCols.end (); ++it) {
1774 typename std::set<LO>::const_iterator itp1 = it;
1776 if (itp1 != invalidDstCopyCols.end ()) {
1780 err <<
"], invalidDstPermuteCols = [";
1781 for (
typename std::set<LO>::const_iterator it = invalidDstPermuteCols.begin ();
1782 it != invalidDstPermuteCols.end (); ++it) {
1784 typename std::set<LO>::const_iterator itp1 = it;
1786 if (itp1 != invalidDstPermuteCols.end ()) {
1790 err <<
"], invalidPermuteFromRows = [";
1791 for (
typename std::set<LO>::const_iterator it = invalidPermuteFromRows.begin ();
1792 it != invalidPermuteFromRows.end (); ++it) {
1794 typename std::set<LO>::const_iterator itp1 = it;
1796 if (itp1 != invalidPermuteFromRows.end ()) {
1800 err <<
"]" << std::endl;
1802 err <<
"copyAndPermute: The graph structure of the source of the " 1803 "Import or Export must be a subset of the graph structure of the " 1804 "target." << std::endl;
1805 #endif // HAVE_TPETRA_DEBUG 1809 std::ostringstream os;
1810 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
1811 const bool lclSuccess = ! (* (this->localError_));
1812 os <<
"*** Proc " << myRank <<
": copyAndPermute " 1813 << (lclSuccess ?
"succeeded" :
"FAILED");
1819 std::cerr << os.str ();
1843 template<
class LO,
class GO,
class D>
1845 packRowCount (
const size_t numEnt,
1846 const size_t numBytesPerValue,
1847 const size_t blkSize)
1859 const size_t numEntLen = PackTraits<LO, D>::packValueCount (numEntLO);
1860 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
1861 const size_t valsLen = numEnt * numBytesPerValue * blkSize * blkSize;
1862 return numEntLen + gidsLen + valsLen;
1876 template<
class ST,
class LO,
class GO,
class D>
1879 const size_t offset,
1880 const size_t numBytes,
1881 const size_t numBytesPerValue)
1883 using Kokkos::subview;
1885 typedef typename PackTraits<LO, D>::input_buffer_type input_buffer_type;
1886 typedef typename input_buffer_type::size_type size_type;
1888 if (numBytes == 0) {
1890 return static_cast<size_t> (0);
1894 const size_t theNumBytes = PackTraits<LO, D>::packValueCount (numEntLO);
1895 #ifdef HAVE_TPETRA_DEBUG 1896 TEUCHOS_TEST_FOR_EXCEPTION(
1897 theNumBytes > numBytes, std::logic_error,
"unpackRowCount: " 1898 "theNumBytes = " << theNumBytes <<
" < numBytes = " << numBytes
1900 #endif // HAVE_TPETRA_DEBUG 1901 const std::pair<size_type, size_type> rng (offset, offset + theNumBytes);
1902 input_buffer_type inBuf = subview (imports, rng);
1903 const size_t actualNumBytes = PackTraits<LO, D>::unpackValue (numEntLO, inBuf);
1904 #ifdef HAVE_TPETRA_DEBUG 1905 TEUCHOS_TEST_FOR_EXCEPTION(
1906 theNumBytes > numBytes, std::logic_error,
"unpackRowCount: " 1907 "actualNumBytes = " << actualNumBytes <<
" < numBytes = " << numBytes
1910 (void) actualNumBytes;
1911 #endif // HAVE_TPETRA_DEBUG 1912 return static_cast<size_t> (numEntLO);
1923 template<
class ST,
class LO,
class GO,
class D>
1926 const size_t offset,
1927 const size_t numEnt,
1930 const size_t numBytesPerValue,
1931 const size_t blockSize)
1933 using Kokkos::subview;
1940 typedef typename PackTraits<LO, D>::output_buffer_type output_buffer_type;
1941 typedef typename output_buffer_type::size_type size_type;
1942 typedef typename std::pair<size_type, size_type> pair_type;
1948 const size_t numScalarEnt = numEnt * blockSize * blockSize;
1951 const LO numEntLO =
static_cast<size_t> (numEnt);
1953 const size_t numEntBeg = offset;
1954 const size_t numEntLen = PackTraits<LO, D>::packValueCount (numEntLO);
1955 const size_t gidsBeg = numEntBeg + numEntLen;
1956 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
1957 const size_t valsBeg = gidsBeg + gidsLen;
1958 const size_t valsLen = numScalarEnt * numBytesPerValue;
1960 output_buffer_type numEntOut =
1961 subview (exports, pair_type (numEntBeg, numEntBeg + numEntLen));
1962 output_buffer_type gidsOut =
1963 subview (exports, pair_type (gidsBeg, gidsBeg + gidsLen));
1964 output_buffer_type valsOut =
1965 subview (exports, pair_type (valsBeg, valsBeg + valsLen));
1967 size_t numBytesOut = 0;
1968 numBytesOut += PackTraits<LO, D>::packValue (numEntOut, numEntLO);
1969 numBytesOut += PackTraits<GO, D>::packArray (gidsOut, gidsIn, numEnt);
1970 numBytesOut += PackTraits<ST, D>::packArray (valsOut, valsIn, numScalarEnt);
1972 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
1973 TEUCHOS_TEST_FOR_EXCEPTION(
1974 numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: " 1975 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = " 1976 << expectedNumBytes <<
".");
1981 template<
class ST,
class LO,
class GO,
class D>
1986 const size_t offset,
1987 const size_t numBytes,
1988 const size_t numEnt,
1989 const size_t numBytesPerValue,
1990 const size_t blockSize)
1992 using Kokkos::subview;
1999 typedef typename PackTraits<LO, D>::input_buffer_type input_buffer_type;
2000 typedef typename input_buffer_type::size_type size_type;
2001 typedef typename std::pair<size_type, size_type> pair_type;
2003 if (numBytes == 0) {
2007 const size_t numScalarEnt = numEnt * blockSize * blockSize;
2008 TEUCHOS_TEST_FOR_EXCEPTION(
2009 static_cast<size_t> (imports.dimension_0 ()) <= offset,
2010 std::logic_error,
"unpackRow: imports.dimension_0() = " 2011 << imports.dimension_0 () <<
" <= offset = " << offset <<
".");
2012 TEUCHOS_TEST_FOR_EXCEPTION(
2013 static_cast<size_t> (imports.dimension_0 ()) < offset + numBytes,
2014 std::logic_error,
"unpackRow: imports.dimension_0() = " 2015 << imports.dimension_0 () <<
" < offset + numBytes = " 2016 << (offset + numBytes) <<
".");
2021 const size_t numEntBeg = offset;
2022 const size_t numEntLen = PackTraits<LO, D>::packValueCount (lid);
2023 const size_t gidsBeg = numEntBeg + numEntLen;
2024 const size_t gidsLen = numEnt * PackTraits<GO, D>::packValueCount (gid);
2025 const size_t valsBeg = gidsBeg + gidsLen;
2026 const size_t valsLen = numScalarEnt * numBytesPerValue;
2028 input_buffer_type numEntIn =
2029 subview (imports, pair_type (numEntBeg, numEntBeg + numEntLen));
2030 input_buffer_type gidsIn =
2031 subview (imports, pair_type (gidsBeg, gidsBeg + gidsLen));
2032 input_buffer_type valsIn =
2033 subview (imports, pair_type (valsBeg, valsBeg + valsLen));
2035 size_t numBytesOut = 0;
2037 numBytesOut += PackTraits<LO, D>::unpackValue (numEntOut, numEntIn);
2038 TEUCHOS_TEST_FOR_EXCEPTION(
2039 static_cast<size_t> (numEntOut) != numEnt, std::logic_error,
2040 "unpackRow: Expected number of entries " << numEnt
2041 <<
" != actual number of entries " << numEntOut <<
".");
2043 numBytesOut += PackTraits<GO, D>::unpackArray (gidsOut, gidsIn, numEnt);
2044 numBytesOut += PackTraits<ST, D>::unpackArray (valsOut, valsIn, numScalarEnt);
2046 TEUCHOS_TEST_FOR_EXCEPTION(
2047 numBytesOut != numBytes, std::logic_error,
"unpackRow: numBytesOut = " 2048 << numBytesOut <<
" != numBytes = " << numBytes <<
".");
2049 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
2050 TEUCHOS_TEST_FOR_EXCEPTION(
2051 numBytesOut != expectedNumBytes, std::logic_error,
"unpackRow: " 2052 "numBytesOut = " << numBytesOut <<
" != expectedNumBytes = " 2053 << expectedNumBytes <<
".");
2058 template<
class Scalar,
class LO,
class GO,
class Node>
2062 const Teuchos::ArrayView<const LO>& exportLIDs,
2063 Teuchos::Array<packet_type>& exports,
2064 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
2065 size_t& constantNumPackets,
2070 using Kokkos::MemoryUnmanaged;
2071 using Kokkos::subview;
2075 typedef typename View<int*, execution_space>::HostMirror::execution_space HES;
2077 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
2078 const bool debug =
false;
2081 std::ostringstream os;
2082 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2083 os <<
"Proc " << myRank <<
": packAndPrepare: exportLIDs.size() = " 2084 << exportLIDs.size () <<
", numPacketsPerLID.size() = " 2085 << numPacketsPerLID.size () << endl;
2086 std::cerr << os.str ();
2089 if (* (this->localError_)) {
2090 std::ostream& err = this->markLocalErrorAndGetStream ();
2091 err <<
"packAndPrepare: The target object of the Import or Export is " 2092 "already in an error state." << endl;
2096 const this_type* src =
dynamic_cast<const this_type*
> (&source);
2099 std::ostream& err = this->markLocalErrorAndGetStream ();
2100 err <<
"packAndPrepare: The source (input) object of the Import or " 2101 "Export is either not a BlockCrsMatrix, or does not have the right " 2102 "template parameters. checkSizes() should have caught this. " 2103 "Please report this bug to the Tpetra developers." << endl;
2108 const size_t blockSize =
static_cast<size_t> (src->getBlockSize ());
2109 const size_type numExportLIDs = exportLIDs.size ();
2111 if (numExportLIDs != numPacketsPerLID.size ()) {
2112 std::ostream& err = this->markLocalErrorAndGetStream ();
2113 err <<
"packAndPrepare: exportLIDs.size() = " << numExportLIDs
2114 <<
" != numPacketsPerLID.size() = " << numPacketsPerLID.size ()
2127 constantNumPackets = 0;
2132 size_t totalNumBytes = 0;
2133 size_t totalNumEntries = 0;
2134 size_t maxRowLength = 0;
2135 for (size_type i = 0; i < numExportLIDs; ++i) {
2136 const LO lclRow = exportLIDs[i];
2144 if (numEnt == Teuchos::OrdinalTraits<size_t>::invalid ()) {
2147 const size_t numScalarEnt = numEnt * blockSize * blockSize;
2151 size_t numBytesPerValue = 0;
2157 Scalar* valsRaw = NULL;
2158 const LO* lidsRaw = NULL;
2159 LO actualNumEnt = 0;
2161 src->getLocalRowView (lclRow, lidsRaw, valsRaw, actualNumEnt);
2163 if (numEnt != static_cast<size_t> (actualNumEnt)) {
2164 std::ostream& err = this->markLocalErrorAndGetStream ();
2165 err <<
"packAndPrepare: Local row " << i <<
" claims to have " <<
2166 numEnt <<
"entry/ies, but the View returned by getLocalRowView() " 2167 "has " << actualNumEnt <<
" entry/ies. This should never happen. " 2168 "Please report this bug to the Tpetra developers." << endl;
2171 if (errCode == Teuchos::OrdinalTraits<LO>::invalid ()) {
2172 std::ostream& err = this->markLocalErrorAndGetStream ();
2173 err <<
"packAndPrepare: Local row " << i <<
" is not in the row Map " 2174 "of the source object on the calling process." << endl;
2178 const ST* valsRawST =
const_cast<const ST*
> (
reinterpret_cast<ST*
> (valsRaw));
2179 View<const ST*, HES, MemoryUnmanaged> vals (valsRawST, numScalarEnt);
2184 numBytesPerValue = PackTraits<ST, HES>::packValueCount (vals(0));
2187 const size_t numBytes =
2188 packRowCount<LO, GO, HES> (numEnt, numBytesPerValue, blockSize);
2189 numPacketsPerLID[i] = numBytes;
2190 totalNumBytes += numBytes;
2191 totalNumEntries += numEnt;
2192 maxRowLength = std::max (maxRowLength, numEnt);
2196 const int myRank = graph_.
getComm ()->getRank ();
2197 std::ostringstream os;
2198 os <<
"Proc " << myRank <<
": packAndPrepare: totalNumBytes = " 2199 << totalNumBytes << endl;
2200 std::cerr << os.str ();
2206 exports.resize (totalNumBytes);
2207 if (totalNumEntries > 0) {
2208 View<char*, HES, MemoryUnmanaged> exportsK (exports.getRawPtr (),
2223 View<GO*, HES> gblColInds;
2226 gblColInds = PackTraits<GO, HES>::allocateArray (gid, maxRowLength,
"gids");
2230 for (size_type i = 0; i < numExportLIDs; ++i) {
2231 const LO lclRowInd = exportLIDs[i];
2232 const LO* lclColIndsRaw;
2238 (void) src->getLocalRowView (lclRowInd, lclColIndsRaw, valsRaw, numEntLO);
2239 const size_t numEnt =
static_cast<size_t> (numEntLO);
2240 const size_t numScalarEnt = numEnt * blockSize * blockSize;
2241 View<const LO*, HES, MemoryUnmanaged> lclColInds (lclColIndsRaw, numEnt);
2242 const ST* valsRawST =
const_cast<const ST*
> (
reinterpret_cast<ST*
> (valsRaw));
2243 View<const ST*, HES, MemoryUnmanaged> vals (valsRawST, numScalarEnt);
2248 const size_t numBytesPerValue = numEnt == 0 ?
2249 static_cast<size_t> (0) :
2250 PackTraits<ST, HES>::packValueCount (vals(0));
2253 for (
size_t j = 0; j < numEnt; ++j) {
2258 const size_t numBytes =
2259 packRowForBlockCrs<ST, LO, GO, HES> (exportsK, offset, numEnt, gblColInds,
2260 vals, numBytesPerValue, blockSize);
2265 if (offset != totalNumBytes) {
2266 std::ostream& err = this->markLocalErrorAndGetStream ();
2267 err <<
"packAndPreapre: At end of method, the final offset (in bytes) " 2268 << offset <<
" does not equal the total number of bytes packed " 2269 << totalNumBytes <<
". " 2270 <<
"Please report this bug to the Tpetra developers." << endl;
2276 std::ostringstream os;
2277 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2278 const bool lclSuccess = ! (* (this->localError_));
2279 os <<
"*** Proc " << myRank <<
": packAndPrepare " 2280 << (lclSuccess ?
"succeeded" :
"FAILED")
2281 <<
" (totalNumEntries = " << totalNumEntries <<
") ***" << endl;
2282 std::cerr << os.str ();
2287 template<
class Scalar,
class LO,
class GO,
class Node>
2291 const Teuchos::ArrayView<const packet_type>& imports,
2292 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
2299 using Kokkos::MemoryUnmanaged;
2300 using Kokkos::subview;
2303 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
2305 typedef typename View<int*, execution_space>::HostMirror::execution_space HES;
2306 typedef std::pair<typename View<int*, HES>::size_type,
2307 typename View<int*, HES>::size_type> pair_type;
2308 typedef View<GO*, HES, MemoryUnmanaged> gids_out_type;
2309 typedef View<LO*, HES, MemoryUnmanaged> lids_out_type;
2310 typedef View<ST*, HES, MemoryUnmanaged> vals_out_type;
2311 typedef typename PackTraits<GO, HES>::input_buffer_type input_buffer_type;
2312 const char prefix[] =
"Tpetra::Experimental::BlockCrsMatrix::unpackAndCombine: ";
2313 const bool debug =
false;
2316 std::ostringstream os;
2317 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2318 os <<
"Proc " << myRank <<
": unpackAndCombine" << endl;
2319 std::cerr << os.str ();
2325 if (* (this->localError_)) {
2326 std::ostream& err = this->markLocalErrorAndGetStream ();
2327 err << prefix <<
"The target object of the Import or Export is " 2328 "already in an error state." << endl;
2331 if (importLIDs.size () != numPacketsPerLID.size ()) {
2332 std::ostream& err = this->markLocalErrorAndGetStream ();
2333 err << prefix <<
"importLIDs.size() = " << importLIDs.size () <<
" != " 2334 "numPacketsPerLID.size() = " << numPacketsPerLID.size () <<
"." << endl;
2338 std::ostream& err = this->markLocalErrorAndGetStream ();
2339 err << prefix <<
"Invalid CombineMode value " << CM <<
". Valid " 2340 <<
"values include ADD, INSERT, REPLACE, ABSMAX, and ZERO." 2350 const size_type numImportLIDs = importLIDs.size ();
2351 if (CM ==
ZERO || numImportLIDs == 0) {
2353 std::ostringstream os;
2354 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2355 os <<
"Proc " << myRank <<
": unpackAndCombine: Nothing to do" << endl;
2356 std::cerr << os.str ();
2362 std::ostringstream os;
2363 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2364 os <<
"Proc " << myRank <<
": unpackAndCombine: Getting ready" << endl;
2365 std::cerr << os.str ();
2368 input_buffer_type importsK (imports.getRawPtr (), imports.size ());
2371 const size_t maxRowNumScalarEnt = maxRowNumEnt * blockSize * blockSize;
2373 size_t numBytesPerValue;
2385 numBytesPerValue = PackTraits<ST, HES>::packValueCount (val);
2392 View<GO*, HES> gblColInds;
2393 View<LO*, HES> lclColInds;
2394 View<ST*, HES> vals;
2408 gblColInds = PackTraits<GO, HES>::allocateArray (gid, maxRowNumEnt,
"gids");
2409 lclColInds = PackTraits<LO, HES>::allocateArray (lid, maxRowNumEnt,
"lids");
2410 vals = PackTraits<ST, HES>::allocateArray (val, maxRowNumScalarEnt,
"vals");
2414 for (size_type i = 0; i < numImportLIDs; ++i) {
2415 const size_t numBytes = numPacketsPerLID[i];
2416 if (numBytes == 0) {
2420 const size_t numEnt =
2421 unpackRowCount<ST, LO, GO, HES> (importsK, offset, numBytes, numBytesPerValue);
2422 if (numEnt > maxRowNumEnt) {
2423 std::ostream& err = this->markLocalErrorAndGetStream ();
2424 err << prefix <<
"At i = " << i <<
", numEnt = " << numEnt
2425 <<
" > maxRowNumEnt = " << maxRowNumEnt << endl;
2429 const size_t numScalarEnt = numEnt * blockSize * blockSize;
2430 const LO lclRow = importLIDs[i];
2432 gids_out_type gidsOut = subview (gblColInds, pair_type (0, numEnt));
2433 vals_out_type valsOut = subview (vals, pair_type (0, numScalarEnt));
2435 const size_t numBytesOut =
2436 unpackRowForBlockCrs<ST, LO, GO, HES> (gidsOut, valsOut, importsK, offset, numBytes,
2437 numEnt, numBytesPerValue, blockSize);
2438 if (numBytes != numBytesOut) {
2439 std::ostream& err = this->markLocalErrorAndGetStream ();
2440 err << prefix <<
"At i = " << i <<
", numBytes = " << numBytes
2441 <<
" != numBytesOut = " << numBytesOut <<
".";
2446 lids_out_type lidsOut = subview (lclColInds, pair_type (0, numEnt));
2447 for (
size_t k = 0; k < numEnt; ++k) {
2449 #ifdef HAVE_TPETRA_DEBUG 2450 if (lidsOut(k) == Teuchos::OrdinalTraits<LO>::invalid ()) {
2451 std::ostream& err = this->markLocalErrorAndGetStream ();
2452 err << prefix <<
"At i = " << i <<
", GID " << gidsOut(k)
2453 <<
" is not owned by the calling process.";
2456 #endif // HAVE_TPETRA_DEBUG 2461 const LO*
const lidsRaw =
const_cast<const LO*
> (lidsOut.ptr_on_device ());
2462 const Scalar*
const valsRaw =
2463 reinterpret_cast<const Scalar*
> (
const_cast<const ST*
> (valsOut.ptr_on_device ()));
2468 }
else if (CM ==
ABSMAX) {
2471 #ifdef HAVE_TPETRA_DEBUG 2472 if (static_cast<LO> (numEnt) != numCombd) {
2473 std::ostream& err = this->markLocalErrorAndGetStream ();
2474 err << prefix <<
"At i = " << i <<
", numEnt = " << numEnt
2475 <<
" != numCombd = " << numCombd <<
".";
2480 #endif // HAVE_TPETRA_DEBUG 2487 std::ostringstream os;
2488 const int myRank = this->graph_.
getRowMap ()->getComm ()->getRank ();
2489 const bool lclSuccess = ! (* (this->localError_));
2490 os <<
"*** Proc " << myRank <<
": unpackAndCombine " 2491 << (lclSuccess ?
"succeeded" :
"FAILED")
2493 std::cerr << os.str ();
2498 template<
class Scalar,
class LO,
class GO,
class Node>
2502 using Teuchos::TypeNameTraits;
2503 std::ostringstream os;
2504 os <<
"\"Tpetra::BlockCrsMatrix\": { " 2505 <<
"Template parameters: { " 2506 <<
"Scalar: " << TypeNameTraits<Scalar>::name ()
2507 <<
"LO: " << TypeNameTraits<LO>::name ()
2508 <<
"GO: " << TypeNameTraits<GO>::name ()
2509 <<
"Node: " << TypeNameTraits<Node>::name ()
2511 <<
", Label: \"" << this->getObjectLabel () <<
"\"" 2512 <<
", Global dimensions: [" 2513 << graph_.
getDomainMap ()->getGlobalNumElements () <<
", " 2514 << graph_.
getRangeMap ()->getGlobalNumElements () <<
"]" 2521 template<
class Scalar,
class LO,
class GO,
class Node>
2525 const Teuchos::EVerbosityLevel verbLevel)
const 2527 using Teuchos::ArrayRCP;
2528 using Teuchos::CommRequest;
2529 using Teuchos::FancyOStream;
2530 using Teuchos::getFancyOStream;
2531 using Teuchos::ireceive;
2532 using Teuchos::isend;
2533 using Teuchos::outArg;
2534 using Teuchos::TypeNameTraits;
2535 using Teuchos::VERB_DEFAULT;
2536 using Teuchos::VERB_NONE;
2537 using Teuchos::VERB_LOW;
2538 using Teuchos::VERB_MEDIUM;
2540 using Teuchos::VERB_EXTREME;
2542 using Teuchos::wait;
2546 const Teuchos::EVerbosityLevel vl =
2547 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
2549 if (vl == VERB_NONE) {
2554 Teuchos::OSTab tab0 (out);
2556 out <<
"\"Tpetra::BlockCrsMatrix\":" << endl;
2557 Teuchos::OSTab tab1 (out);
2559 out <<
"Template parameters:" << endl;
2561 Teuchos::OSTab tab2 (out);
2562 out <<
"Scalar: " << TypeNameTraits<Scalar>::name () << endl
2563 <<
"LO: " << TypeNameTraits<LO>::name () << endl
2564 <<
"GO: " << TypeNameTraits<GO>::name () << endl
2565 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
2567 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl
2568 <<
"Global dimensions: [" 2569 << graph_.
getDomainMap ()->getGlobalNumElements () <<
", " 2570 << graph_.
getRangeMap ()->getGlobalNumElements () <<
"]" << endl;
2573 out <<
"Block size: " << blockSize << endl;
2576 if (vl >= VERB_MEDIUM) {
2577 const Teuchos::Comm<int>& comm = * (graph_.
getMap ()->getComm ());
2578 const int myRank = comm.getRank ();
2580 out <<
"Row Map:" << endl;
2587 out <<
"Column Map: same as row Map" << endl;
2592 out <<
"Column Map:" << endl;
2600 out <<
"Domain Map: same as row Map" << endl;
2605 out <<
"Domain Map: same as column Map" << endl;
2610 out <<
"Domain Map:" << endl;
2618 out <<
"Range Map: same as domain Map" << endl;
2623 out <<
"Range Map: same as row Map" << endl;
2628 out <<
"Range Map: " << endl;
2635 if (vl >= VERB_EXTREME) {
2636 const Teuchos::Comm<int>& comm = * (graph_.
getMap ()->getComm ());
2637 const int myRank = comm.getRank ();
2638 const int numProcs = comm.getSize ();
2641 RCP<std::ostringstream> lclOutStrPtr (
new std::ostringstream ());
2642 RCP<FancyOStream> osPtr = getFancyOStream (lclOutStrPtr);
2643 FancyOStream& os = *osPtr;
2644 os <<
"Process " << myRank <<
":" << endl;
2645 Teuchos::OSTab tab2 (os);
2653 os <<
"Row " << meshGblRow <<
": {";
2655 const LO* lclColInds = NULL;
2656 Scalar* vals = NULL;
2660 for (LO k = 0; k < numInds; ++k) {
2663 os <<
"Col " << gblCol <<
": [";
2664 for (LO i = 0; i < blockSize; ++i) {
2665 for (LO j = 0; j < blockSize; ++j) {
2666 os << vals[blockSize*blockSize*k + i*blockSize + j];
2667 if (j + 1 < blockSize) {
2671 if (i + 1 < blockSize) {
2676 if (k + 1 < numInds) {
2686 out << lclOutStrPtr->str ();
2687 lclOutStrPtr = Teuchos::null;
2690 const int sizeTag = 1337;
2691 const int dataTag = 1338;
2693 ArrayRCP<char> recvDataBuf;
2697 for (
int p = 1; p < numProcs; ++p) {
2700 ArrayRCP<size_t> recvSize (1);
2702 RCP<CommRequest<int> > recvSizeReq =
2703 ireceive<int, size_t> (recvSize, p, sizeTag, comm);
2704 wait<int> (comm, outArg (recvSizeReq));
2705 const size_t numCharsToRecv = recvSize[0];
2712 if (static_cast<size_t>(recvDataBuf.size()) < numCharsToRecv + 1) {
2713 recvDataBuf.resize (numCharsToRecv + 1);
2715 ArrayRCP<char> recvData = recvDataBuf.persistingView (0, numCharsToRecv);
2717 RCP<CommRequest<int> > recvDataReq =
2718 ireceive<int, char> (recvData, p, dataTag, comm);
2719 wait<int> (comm, outArg (recvDataReq));
2724 recvDataBuf[numCharsToRecv] =
'\0';
2725 out << recvDataBuf.getRawPtr ();
2727 else if (myRank == p) {
2731 const std::string stringToSend = lclOutStrPtr->str ();
2732 lclOutStrPtr = Teuchos::null;
2735 const size_t numCharsToSend = stringToSend.size ();
2736 ArrayRCP<size_t> sendSize (1);
2737 sendSize[0] = numCharsToSend;
2738 RCP<CommRequest<int> > sendSizeReq =
2739 isend<int, size_t> (sendSize, 0, sizeTag, comm);
2740 wait<int> (comm, outArg (sendSizeReq));
2748 ArrayRCP<const char> sendData (&stringToSend[0], 0, numCharsToSend,
false);
2749 RCP<CommRequest<int> > sendDataReq =
2750 isend<int, char> (sendData, 0, dataTag, comm);
2751 wait<int> (comm, outArg (sendDataReq));
2757 template<
class Scalar,
class LO,
class GO,
class Node>
2758 Teuchos::RCP<const Teuchos::Comm<int> >
2765 template<
class Scalar,
class LO,
class GO,
class Node>
2774 template<
class Scalar,
class LO,
class GO,
class Node>
2782 template<
class Scalar,
class LO,
class GO,
class Node>
2790 template<
class Scalar,
class LO,
class GO,
class Node>
2798 template<
class Scalar,
class LO,
class GO,
class Node>
2806 template<
class Scalar,
class LO,
class GO,
class Node>
2814 template<
class Scalar,
class LO,
class GO,
class Node>
2822 template<
class Scalar,
class LO,
class GO,
class Node>
2830 template<
class Scalar,
class LO,
class GO,
class Node>
2838 template<
class Scalar,
class LO,
class GO,
class Node>
2846 template<
class Scalar,
class LO,
class GO,
class Node>
2854 template<
class Scalar,
class LO,
class GO,
class Node>
2862 template<
class Scalar,
class LO,
class GO,
class Node>
2870 template<
class Scalar,
class LO,
class GO,
class Node>
2878 template<
class Scalar,
class LO,
class GO,
class Node>
2886 template<
class Scalar,
class LO,
class GO,
class Node>
2894 template<
class Scalar,
class LO,
class GO,
class Node>
2903 template<
class Scalar,
class LO,
class GO,
class Node>
2907 const Teuchos::ArrayView<GO> &Indices,
2908 const Teuchos::ArrayView<Scalar> &Values,
2909 size_t &NumEntries)
const 2911 TEUCHOS_TEST_FOR_EXCEPTION(
2912 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::getGlobalRowCopy: " 2913 "This class doesn't support global matrix indexing.");
2917 template<
class Scalar,
class LO,
class GO,
class Node>
2921 ArrayView<const GO> &indices,
2922 ArrayView<const Scalar> &values)
const 2924 TEUCHOS_TEST_FOR_EXCEPTION(
2925 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::getGlobalRowView: " 2926 "This class doesn't support global matrix indexing.");
2930 template<
class Scalar,
class LO,
class GO,
class Node>
2934 ArrayView<const LO> &indices,
2935 ArrayView<const Scalar> &values)
const 2937 TEUCHOS_TEST_FOR_EXCEPTION(
2938 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::getGlobalRowView: " 2939 "This class doesn't support global matrix indexing.");
2944 template<
class Scalar,
class LO,
class GO,
class Node>
2949 TEUCHOS_TEST_FOR_EXCEPTION(
2950 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::getLocalDiagCopy: " 2951 "not implemented.");
2955 template<
class Scalar,
class LO,
class GO,
class Node>
2960 TEUCHOS_TEST_FOR_EXCEPTION(
2961 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::leftScale: " 2962 "not implemented.");
2966 template<
class Scalar,
class LO,
class GO,
class Node>
2971 TEUCHOS_TEST_FOR_EXCEPTION(
2972 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::rightScale: " 2973 "not implemented.");
2977 template<
class Scalar,
class LO,
class GO,
class Node>
2978 Teuchos::RCP<const Tpetra::RowGraph<LO, GO, Node> >
2985 template<
class Scalar,
class LO,
class GO,
class Node>
2990 TEUCHOS_TEST_FOR_EXCEPTION(
2991 true, std::logic_error,
"Tpetra::Experimental::BlockCrsMatrix::getFrobeniusNorm: " 2992 "not implemented.");
3003 #define TPETRA_EXPERIMENTAL_BLOCKCRSMATRIX_INSTANT(S,LO,GO,NODE) \ 3004 template class Experimental::BlockCrsMatrix< S, LO, GO, NODE >; 3006 #endif // TPETRA_EXPERIMENTAL_BLOCKCRSMATRIX_DEF_HPP Teuchos::ArrayRCP< const LocalOrdinal > getNodePackedIndices() const
Get an Teuchos::ArrayRCP of the packed column-indices.
LO absMaxLocalValuesByOffsets(const LO localRowInd, const ptrdiff_t offsets[], const Scalar vals[], const LO numOffsets) const
Like sumIntoLocalValuesByOffsets, but for the ABSMAX combine mode.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
bool isGloballyIndexed() const
If graph indices are in the global range, this function returns true. Otherwise, this function return...
Teuchos::RCP< const Comm< int > > getComm() const
Returns the communicator.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
virtual bool supportsRowViews() const
Whether this object implements getLocalRowView() and getGlobalRowView().
virtual void copyAndPermute(const Tpetra::SrcDistObject &source, size_t numSameIDs, const Teuchos::ArrayView< const LO > &permuteToLIDs, const Teuchos::ArrayView< const LO > &permuteFromLIDs)
Perform copies and permutations that are local to this process.
virtual bool isLowerTriangular() const
Whether this matrix is lower triangular.
device_type::execution_space execution_space
The Kokkos execution space.
Teuchos::RCP< const map_type > getRowMap() const
Returns the Map that describes the row distribution in this graph.
Teuchos::RCP< const map_type > getColMap() const
get the (mesh) map for the columns of this block matrix.
LO getBlockSize() const
The number of degrees of freedom per mesh point.
void fill(const Scalar &alpha) const
(*this)(i,j) := alpha for all (i,j).
Teuchos::RCP< const map_type > getRowMap() const
get the (mesh) map for the rows of this block matrix.
Teuchos::RCP< const map_type > getRangeMap() const
Returns the Map associated with the domain of this graph.
mv_type mv_
The Tpetra::MultiVector used to represent the data.
LO replaceLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Replace values at the given column indices, in the given row.
size_t getNodeNumCols() const
Returns the number of columns connected to the locally owned rows of this graph.
local_graph_type getLocalGraph() const
Get the local graph.
LO replaceLocalValuesByOffsets(const LO localRowInd, const ptrdiff_t offsets[], const Scalar vals[], const LO numOffsets) const
Like replaceLocalValues, but avoids computing row offsets.
bool hasColMap() const
Whether the graph has a column Map.
void putScalar(const Scalar &val)
Fill all entries with the given value val.
void matvecUpdate(const Scalar &alpha, const LittleBlockType &A, const LittleVectorType &X) const
(*this) := (*this) + alpha * A * X (matrix-vector multiply).
size_t getGlobalMaxNumRowEntries() const
Maximum number of entries in all rows over all processes.
global_size_t getGlobalNumRows() const
Returns the number of global rows in the graph.
size_t getNodeNumRows() const
get the local number of block rows
bool isSorted() const
Whether graph indices in all rows are known to be sorted.
void getLocalDiagOffsets(Teuchos::ArrayRCP< size_t > &offsets) const
Get offsets of the diagonal entries in the matrix.
void applyBlock(const BlockMultiVector< Scalar, LO, GO, Node > &X, BlockMultiVector< Scalar, LO, GO, Node > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, const Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), const Scalar beta=Teuchos::ScalarTraits< Scalar >::zero())
Version of apply() that takes BlockMultiVector input and output.
Traits class for packing / unpacking data of type T, using Kokkos data structures that live in the gi...
One or more distributed dense vectors.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Print a description of this object to the given output stream.
MultiVector for multiple degrees of freedom per mesh point.
LO getLocalRowOffsets(const LO localRowInd, ptrdiff_t offsets[], const LO colInds[], const LO numColInds) const
Get relative offsets corresponding to the given rows, given by local row index.
global_size_t getGlobalNumRows() const
get the global number of block rows
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
static map_type makePointMap(const map_type &meshMap, const LO blockSize)
Create and return the point Map corresponding to the given mesh Map and block size.
Teuchos::RCP< const import_type > getImporter() const
Returns the importer associated with this graph.
void absmax(const LittleBlockType &X) const
(*this)(i,j) := max(abs((*this)(i,j)), abs(X(i,j))) for all (i,j).
Nonowning view of a square dense block in a block matrix.
LocalOrdinal getMinLocalIndex() const
The minimum local index.
LO absMaxLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Like sumIntoLocalValues, but for the ABSMAX combine mode.
Teuchos::RCP< const map_type > getRangeMap() const
Get the (point) range Map of this matrix.
virtual bool isUpperTriangular() const
Whether this matrix is upper triangular.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
bool locallySameAs(const Map< LocalOrdinal, GlobalOrdinal, node_type > &map) const
Is the given Map locally the same as the input Map?
size_t getNodeMaxNumRowEntries() const
Maximum number of entries in all rows owned by the calling process.
void assign(const LittleVectorType &X) const
*this := X.
void scale(const Scalar &val)
Multiply all entries in place by the given value val.
virtual bool checkSizes(const Tpetra::SrcDistObject &source)
Compare the source and target (this) objects for compatibility.
little_vec_type getLocalBlock(const LO localRowIndex, const LO colIndex) const
Get a view of the degrees of freedom at the given mesh point.
Kokkos::View< char *, D, Kokkos::MemoryUnmanaged > output_buffer_type
The type of an output buffer of bytes.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
virtual bool hasColMap() const
Whether this matrix has a well-defined column map.
bool isFillComplete() const
Returns true if fillComplete() has been called and the graph is in compute mode.
Teuchos::RCP< const map_type > getDomainMap() const
Get the (point) domain Map of this matrix.
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
virtual size_t getNodeNumDiags() const
The number of local diagonal entries, based on global row/column index comparisons.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in the graph.
LO getBlockSize() const
Get the number of degrees of freedom per mesh point.
virtual GO getIndexBase() const
The index base for global indices in this matrix.
virtual bool isGloballyIndexed() const
Whether matrix indices are globally indexed.
size_t global_size_t
Global size_t object.
Insert new values that don't currently exist.
bool isLocallyIndexed() const
If graph indices are in the local range, this function returns true. Otherwise, this function returns...
std::string description() const
One-line description of this object.
BlockCrsMatrix()
Default constructor: Makes an empty block matrix.
Teuchos::RCP< const map_type > getDomainMap() const
Returns the Map associated with the domain of this graph.
Teuchos::RCP< node_type > getNode() const
Returns the underlying node.
GlobalOrdinal getIndexBase() const
Returns the index base for global indices for this graph.
virtual global_size_t getGlobalNumCols() const
The global number of columns of this matrix.
ESweepDirection
Sweep direction for Gauss-Seidel or Successive Over-Relaxation (SOR).
virtual bool isFillComplete() const
Whether fillComplete() has been called.
void update(const Scalar &alpha, const LittleBlockType &X) const
*this := *this + alpha * X.
Nonowning view of a set of degrees of freedom corresponding to a mesh point in a block vector or mult...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
LO getNumVectors() const
Get the number of columns (vectors) in the BlockMultiVector.
bool isUpperTriangular() const
Whether the graph is locally upper triangular.
Sets up and executes a communication plan for a Tpetra DistObject.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
void reorderedGaussSeidelCopy(MultiVector< Scalar, LO, GO, Node > &X, const MultiVector< Scalar, LO, GO, Node > &B, const MultiVector< Scalar, LO, GO, Node > &D, const ArrayView< LO > &rowIndices, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps, const bool zeroInitialGuess) const
Version of reorderedGaussSeidel(), with fewer requirements on X.
Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >::mag_type mag_type
Type of a norm result.
Kokkos::View< const value_type *, D, Kokkos::MemoryUnmanaged > input_array_type
The type of an input array of value_type.
virtual size_t getNodeNumCols() const
The number of columns needed to apply the forward operator on this node.
virtual size_t getNodeNumEntries() const
The local number of stored (structurally nonzero) entries.
virtual void leftScale(const Vector< Scalar, LO, GO, Node > &x)
Scale the RowMatrix on the left with the given Vector x.
void getLocalDiagCopy(BlockCrsMatrix< Scalar, LO, GO, Node > &diag, const Teuchos::ArrayView< const size_t > &offsets) const
Variant of getLocalDiagCopy() that uses precomputed offsets.
virtual global_size_t getGlobalNumEntries() const
The global number of stored (structurally nonzero) entries.
virtual void getGlobalRowCopy(GO GlobalRow, const Teuchos::ArrayView< GO > &Indices, const Teuchos::ArrayView< Scalar > &Values, size_t &NumEntries) const
Get a copy of the given global row's entries.
void localGaussSeidel(const BlockMultiVector< Scalar, LO, GO, Node > &Residual, BlockMultiVector< Scalar, LO, GO, Node > &Solution, BlockCrsMatrix< Scalar, LO, GO, Node > &factorizedDiagonal, const int *factorizationPivots, const Scalar omega, const ESweepDirection direction) const
Local Gauss-Seidel solve given a factorized diagonal.
void getLocalRowCopy(LO LocalRow, const Teuchos::ArrayView< LO > &Indices, const Teuchos::ArrayView< Scalar > &Values, size_t &NumEntries) const
Not implemented.
Kokkos::View< const char *, D, Kokkos::MemoryUnmanaged > input_buffer_type
The type of an input buffer of bytes.
Replace old value with maximum of magnitudes of old and new values.
global_size_t getGlobalNumCols() const
Returns the number of global columns in the graph.
Abstract base class for objects that can be the source of an Import or Export operation.
LO getLocalRowView(const LO localRowInd, const LO *&colInds, Scalar *&vals, LO &numInds) const
Get a view of the row, using local indices.
void gaussSeidelCopy(MultiVector< Scalar, LO, GO, Node > &X, const MultiVector< Scalar, LO, GO, Node > &B, const MultiVector< Scalar, LO, GO, Node > &D, const Scalar &dampingFactor, const ESweepDirection direction, const int numSweeps, const bool zeroInitialGuess) const
Version of gaussSeidel(), with fewer requirements on X.
Replace existing values with new values.
Teuchos::RCP< const map_type > getColMap() const
Returns the Map that describes the column distribution in this graph.
Replace old values with zero.
std::string errorMessages() const
The current stream of error messages.
Teuchos::DataAccess getCopyOrView() const
Get whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
LO sumIntoLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Sum into values at the given column indices, in the given row.
virtual size_t getGlobalMaxNumRowEntries() const
The maximum number of entries across all rows/columns on all nodes.
void fill(const Scalar &alpha) const
(*this)(i,j) := alpha for all (i,j).
size_t getNodeNumEntries() const
Returns the local number of entries in the graph.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
size_t findLocalIndex(RowInfo rowinfo, LocalOrdinal ind, size_t hint=0) const
Find the column offset corresponding to the given (local) column index.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
virtual void rightScale(const Vector< Scalar, LO, GO, Node > &x)
Scale the RowMatrix on the right with the given Vector x.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
virtual Tpetra::RowMatrix< Scalar, LO, GO, Node >::mag_type getFrobeniusNorm() const
The Frobenius norm of the matrix.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
Kokkos::View< value_type *, D, Kokkos::MemoryUnmanaged > output_array_type
The type of an output array of value_type.
LO sumIntoLocalValuesByOffsets(const LO localRowInd, const ptrdiff_t offsets[], const Scalar vals[], const LO numOffsets) const
Like sumIntoLocalValues, but avoids computing row offsets.
A distributed dense vector.
Constant block CRS matrix class.
void apply(const mv_type &X, mv_type &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
For this matrix A, compute Y := beta * Y + alpha * Op(A) * X.
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which this matrix is distributed.
size_t getNodeNumRows() const
Returns the number of graph rows owned on the calling node.
void assign(const LittleBlockType &X) const
*this := X.
void doExport(const SrcDistObject &source, const Export< LO, GO, Node > &exporter, CombineMode CM)
Export data into this object using an Export object ("forward mode").
virtual global_size_t getGlobalNumDiags() const
The number of global diagonal entries, based on global row/column index comparisons.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
BlockMultiVector< Scalar, LO, GO, Node >::impl_scalar_type impl_scalar_type
The implementation type of entries in the matrix.
virtual Teuchos::RCP< Node > getNode() const
The Kokkos Node instance.
Declaration of Tpetra::Experimental::BlockCrsMatrix.
size_t getNodeMaxNumRowEntries() const
The maximum number of entries across all rows/columns on this node.
void computeDiagonalGraph()
Computes the DiagonalGraph.
bool isLowerTriangular() const
Whether the graph is locally lower triangular.
LocalOrdinal getMaxLocalIndex() const
The maximum local index on the calling process.
virtual size_t getNumEntriesInGlobalRow(GO globalRow) const
The current number of entries on the calling process in the specified global row. ...
virtual Teuchos::RCP< const Tpetra::RowGraph< LO, GO, Node > > getGraph() const
Get the (mesh) graph.
size_t getNumEntriesInLocalRow(const LO localRowInd) const
Return the number of entries in the given row on the calling process.
Teuchos::RCP< const export_type > getExporter() const
Returns the exporter associated with this graph.
virtual void getGlobalRowView(GO GlobalRow, Teuchos::ArrayView< const GO > &indices, Teuchos::ArrayView< const Scalar > &values) const
Get a constant, nonpersisting, globally indexed view of the given row of the matrix.
virtual bool isLocallyIndexed() const
Whether matrix indices are locally indexed.
RowInfo getRowInfo(const size_t myRow) const
Get information about the locally owned row with local index myRow.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.