10#ifndef TPETRA_BLOCKCRSMATRIX_DEF_HPP
11#define TPETRA_BLOCKCRSMATRIX_DEF_HPP
19#include "Tpetra_BlockMultiVector.hpp"
22#include "Teuchos_TimeMonitor.hpp"
23#ifdef HAVE_TPETRA_DEBUG
27#include "KokkosSparse_spmv.hpp"
34struct BlockCrsRowStruct {
35 T totalNumEntries, totalNumBytes, maxRowLength;
36 KOKKOS_DEFAULTED_FUNCTION BlockCrsRowStruct() =
default;
37 KOKKOS_DEFAULTED_FUNCTION BlockCrsRowStruct(
const BlockCrsRowStruct& b) =
default;
38 KOKKOS_INLINE_FUNCTION BlockCrsRowStruct(
const T& numEnt,
const T& numBytes,
const T& rowLength)
39 : totalNumEntries(numEnt)
40 , totalNumBytes(numBytes)
41 , maxRowLength(rowLength) {}
45static KOKKOS_INLINE_FUNCTION
void operator+=(BlockCrsRowStruct<T>& a,
const BlockCrsRowStruct<T>& b) {
46 a.totalNumEntries += b.totalNumEntries;
47 a.totalNumBytes += b.totalNumBytes;
48 a.maxRowLength = a.maxRowLength > b.maxRowLength ? a.maxRowLength : b.maxRowLength;
51template <
typename T,
typename ExecSpace>
52struct BlockCrsReducer {
53 typedef BlockCrsReducer reducer;
55 typedef Kokkos::View<value_type, ExecSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> > result_view_type;
58 KOKKOS_INLINE_FUNCTION
59 BlockCrsReducer(value_type& val)
62 KOKKOS_INLINE_FUNCTION
void join(value_type& dst, value_type& src)
const { dst += src; }
63 KOKKOS_INLINE_FUNCTION
void join(value_type& dst,
const value_type& src)
const { dst += src; }
64 KOKKOS_INLINE_FUNCTION
void init(value_type& val)
const { val = value_type(); }
65 KOKKOS_INLINE_FUNCTION value_type& reference() {
return *value; }
66 KOKKOS_INLINE_FUNCTION result_view_type view()
const {
return result_view_type(value); }
75template <
class Scalar,
class LO,
class GO,
class Node>
76class GetLocalDiagCopy {
78 typedef typename Node::device_type device_type;
79 typedef size_t diag_offset_type;
80 typedef Kokkos::View<
const size_t*, device_type,
81 Kokkos::MemoryUnmanaged>
83 typedef typename ::Tpetra::CrsGraph<LO, GO, Node> global_graph_type;
85 typedef typename local_graph_device_type::row_map_type row_offsets_type;
86 typedef typename ::Tpetra::BlockMultiVector<Scalar, LO, GO, Node>::impl_scalar_type IST;
87 typedef Kokkos::View<IST***, device_type, Kokkos::MemoryUnmanaged> diag_type;
88 typedef Kokkos::View<const IST*, device_type, Kokkos::MemoryUnmanaged> values_type;
91 GetLocalDiagCopy(
const diag_type& diag,
92 const values_type& val,
93 const diag_offsets_type& diagOffsets,
94 const row_offsets_type& ptr,
97 , diagOffsets_(diagOffsets)
99 , blockSize_(blockSize)
100 , offsetPerBlock_(blockSize_ * blockSize_)
103 KOKKOS_INLINE_FUNCTION
void
104 operator()(
const LO& lclRowInd)
const {
108 const size_t absOffset = ptr_[lclRowInd];
111 const size_t relOffset = diagOffsets_[lclRowInd];
114 const size_t pointOffset = (absOffset + relOffset) * offsetPerBlock_;
119 device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
120 const_little_block_type;
121 const_little_block_type D_in(val_.data() + pointOffset,
122 blockSize_, blockSize_);
123 auto D_out = Kokkos::subview(diag_, lclRowInd, ALL(), ALL());
129 diag_offsets_type diagOffsets_;
130 row_offsets_type ptr_;
137template <
class Scalar,
class LO,
class GO,
class Node>
141 *(this->localError_) =
true;
142 if ((*errs_).is_null()) {
143 *errs_ = Teuchos::rcp(
new std::ostringstream());
148template <
class Scalar,
class LO,
class GO,
class Node>
151 : dist_object_type(Teuchos::rcp(new
map_type()))
153 graph_(Teuchos::rcp(new
map_type()), 0)
155 blockSize_(static_cast<LO>(0))
156 , X_colMap_(new Teuchos::RCP<BMV>())
158 Y_rowMap_(new Teuchos::RCP<BMV>())
162 , localError_(new bool(false))
163 , errs_(new Teuchos::RCP<std::ostringstream>())
167template <
class Scalar,
class LO,
class GO,
class Node>
171 : dist_object_type(graph.
getMap())
174 , blockSize_(blockSize)
175 , X_colMap_(new Teuchos::RCP<BMV>())
177 Y_rowMap_(new Teuchos::RCP<BMV>())
181 , localError_(new bool(false))
182 , errs_(new Teuchos::RCP<std::ostringstream>())
185 TEUCHOS_TEST_FOR_EXCEPTION(
186 !graph_.isSorted(), std::invalid_argument,
188 "BlockCrsMatrix constructor: The input CrsGraph does not have sorted "
189 "rows (isSorted() is false). This class assumes sorted rows.");
191 graphRCP_ = Teuchos::rcpFromRef(graph_);
197 const bool blockSizeIsNonpositive = (blockSize + 1 <= 1);
198 TEUCHOS_TEST_FOR_EXCEPTION(
199 blockSizeIsNonpositive, std::invalid_argument,
201 "BlockCrsMatrix constructor: The input blockSize = "
202 << blockSize <<
" <= 0. The block size must be positive.");
204 const size_t blockSizeProd =
static_cast<size_t>(blockSize) *
static_cast<size_t>(blockSize);
205 TEUCHOS_TEST_FOR_EXCEPTION(
206 blockSizeProd >
static_cast<size_t>(std::numeric_limits<LO>::max()),
208 "Tpetra::BlockCrsMatrix constructor: blockSize * blockSize overflows LO");
209 offsetPerBlock_ =
static_cast<LO
>(blockSizeProd);
221 auto local_graph_h = graph.getLocalGraphHost();
222 auto ptr_h = local_graph_h.row_map;
223 ptrHost_ =
decltype(ptrHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph row offset"), ptr_h.extent(0));
224 Kokkos::deep_copy(ptrHost_, ptr_h);
226 auto ind_h = local_graph_h.entries;
227 indHost_ =
decltype(indHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph column indices"), ind_h.extent(0));
229 Kokkos::deep_copy(indHost_, ind_h);
231 const auto numValEnt = ind_h.extent(0) * offsetPerBlock();
232 val_ =
decltype(val_)(impl_scalar_type_dualview(
"val", numValEnt));
236template <
class Scalar,
class LO,
class GO,
class Node>
239 const typename local_matrix_device_type::values_type& values,
241 : dist_object_type(graph.
getMap())
244 , blockSize_(blockSize)
245 , X_colMap_(new Teuchos::RCP<BMV>())
247 Y_rowMap_(new Teuchos::RCP<BMV>())
251 , localError_(new bool(false))
252 , errs_(new Teuchos::RCP<std::ostringstream>())
255 TEUCHOS_TEST_FOR_EXCEPTION(
256 !graph_.isSorted(), std::invalid_argument,
258 "BlockCrsMatrix constructor: The input CrsGraph does not have sorted "
259 "rows (isSorted() is false). This class assumes sorted rows.");
261 graphRCP_ = Teuchos::rcpFromRef(graph_);
267 const bool blockSizeIsNonpositive = (blockSize + 1 <= 1);
268 TEUCHOS_TEST_FOR_EXCEPTION(
269 blockSizeIsNonpositive, std::invalid_argument,
271 "BlockCrsMatrix constructor: The input blockSize = "
272 << blockSize <<
" <= 0. The block size must be positive.");
274 const size_t blockSizeProd =
static_cast<size_t>(blockSize) *
static_cast<size_t>(blockSize);
275 TEUCHOS_TEST_FOR_EXCEPTION(
276 blockSizeProd >
static_cast<size_t>(std::numeric_limits<LO>::max()),
278 "Tpetra::BlockCrsMatrix constructor: blockSize * blockSize overflows LO");
279 offsetPerBlock_ =
static_cast<LO
>(blockSizeProd);
291 auto local_graph_h = graph.getLocalGraphHost();
292 auto ptr_h = local_graph_h.row_map;
293 ptrHost_ =
decltype(ptrHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph row offset"), ptr_h.extent(0));
294 Kokkos::deep_copy(ptrHost_, ptr_h);
296 auto ind_h = local_graph_h.entries;
297 indHost_ =
decltype(indHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph column indices"), ind_h.extent(0));
298 Kokkos::deep_copy(indHost_, ind_h);
300 const auto numValEnt = ind_h.extent(0) * offsetPerBlock();
301 TEUCHOS_ASSERT_EQUALITY(numValEnt, values.size());
302 val_ =
decltype(val_)(values);
306template <
class Scalar,
class LO,
class GO,
class Node>
312 : dist_object_type(graph.
getMap())
315 , domainPointMap_(domainPointMap)
316 , rangePointMap_(rangePointMap)
317 , blockSize_(blockSize)
318 , X_colMap_(new Teuchos::RCP<BMV>())
320 Y_rowMap_(new Teuchos::RCP<BMV>())
324 , localError_(new bool(false))
325 , errs_(new Teuchos::RCP<std::ostringstream>())
327 const size_t blockSizeProd =
static_cast<size_t>(blockSize) *
static_cast<size_t>(blockSize);
328 TEUCHOS_TEST_FOR_EXCEPTION(
329 blockSizeProd >
static_cast<size_t>(std::numeric_limits<LO>::max()),
331 "Tpetra::BlockCrsMatrix constructor: blockSize * blockSize overflows LO");
332 offsetPerBlock_ =
static_cast<LO
>(blockSizeProd);
334 TEUCHOS_TEST_FOR_EXCEPTION(
335 !graph_.isSorted(), std::invalid_argument,
337 "BlockCrsMatrix constructor: The input CrsGraph does not have sorted "
338 "rows (isSorted() is false). This class assumes sorted rows.");
340 graphRCP_ = Teuchos::rcpFromRef(graph_);
346 const bool blockSizeIsNonpositive = (blockSize + 1 <= 1);
347 TEUCHOS_TEST_FOR_EXCEPTION(
348 blockSizeIsNonpositive, std::invalid_argument,
350 "BlockCrsMatrix constructor: The input blockSize = "
351 << blockSize <<
" <= 0. The block size must be positive.");
359 auto local_graph_h = graph.getLocalGraphHost();
360 auto ptr_h = local_graph_h.row_map;
361 ptrHost_ =
decltype(ptrHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph row offset"), ptr_h.extent(0));
363 Kokkos::deep_copy(ptrHost_, ptr_h);
365 auto ind_h = local_graph_h.entries;
366 indHost_ =
decltype(indHost_)(Kokkos::ViewAllocateWithoutInitializing(
"graph column indices"), ind_h.extent(0));
368 Kokkos::deep_copy(indHost_, ind_h);
370 const auto numValEnt = ind_h.extent(0) * offsetPerBlock();
371 val_ =
decltype(val_)(impl_scalar_type_dualview(
"val", numValEnt));
375template <
class Scalar,
class LO,
class GO,
class Node>
376Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
380 return Teuchos::rcp(
new map_type(domainPointMap_));
383template <
class Scalar,
class LO,
class GO,
class Node>
384Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
388 return Teuchos::rcp(
new map_type(rangePointMap_));
391template <
class Scalar,
class LO,
class GO,
class Node>
392Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
395 return graph_.getRowMap();
398template <
class Scalar,
class LO,
class GO,
class Node>
399Teuchos::RCP<const typename BlockCrsMatrix<Scalar, LO, GO, Node>::map_type>
402 return graph_.getColMap();
405template <
class Scalar,
class LO,
class GO,
class Node>
409 return graph_.getGlobalNumRows();
412template <
class Scalar,
class LO,
class GO,
class Node>
416 return graph_.getLocalNumRows();
419template <
class Scalar,
class LO,
class GO,
class Node>
423 return graph_.getLocalMaxNumRowEntries();
426template <
class Scalar,
class LO,
class GO,
class Node>
430 Teuchos::ETransp mode,
434 TEUCHOS_TEST_FOR_EXCEPTION(
435 mode != Teuchos::NO_TRANS && mode != Teuchos::TRANS && mode != Teuchos::CONJ_TRANS,
436 std::invalid_argument,
437 "Tpetra::BlockCrsMatrix::apply: "
438 "Invalid 'mode' argument. Valid values are Teuchos::NO_TRANS, "
439 "Teuchos::TRANS, and Teuchos::CONJ_TRANS.");
441 TEUCHOS_TEST_FOR_EXCEPTION(
443 std::invalid_argument,
444 "Tpetra::BlockCrsMatrix::apply: "
445 "X and Y must both be constant stride");
451 X_view = BMV(X, *(graph_.getDomainMap()), blockSize);
452 Y_view = BMV(Y, *(graph_.getRangeMap()), blockSize);
453 }
catch (std::invalid_argument& e) {
454 TEUCHOS_TEST_FOR_EXCEPTION(
455 true, std::invalid_argument,
456 "Tpetra::BlockCrsMatrix::"
457 "apply: Either the input MultiVector X or the output MultiVector Y "
458 "cannot be viewed as a BlockMultiVector, given this BlockCrsMatrix's "
459 "graph. BlockMultiVector's constructor threw the following exception: "
468 const_cast<this_BCRS_type&
>(*this).applyBlock(X_view, Y_view, mode, alpha, beta);
469 }
catch (std::invalid_argument& e) {
470 TEUCHOS_TEST_FOR_EXCEPTION(
471 true, std::invalid_argument,
472 "Tpetra::BlockCrsMatrix::"
473 "apply: The implementation method applyBlock complained about having "
474 "an invalid argument. It reported the following: "
476 }
catch (std::logic_error& e) {
477 TEUCHOS_TEST_FOR_EXCEPTION(
478 true, std::invalid_argument,
479 "Tpetra::BlockCrsMatrix::"
480 "apply: The implementation method applyBlock complained about a "
481 "possible bug in its implementation. It reported the following: "
483 }
catch (std::exception& e) {
484 TEUCHOS_TEST_FOR_EXCEPTION(
485 true, std::invalid_argument,
486 "Tpetra::BlockCrsMatrix::"
487 "apply: The implementation method applyBlock threw an exception which "
488 "is neither std::invalid_argument nor std::logic_error, but is a "
489 "subclass of std::exception. It reported the following: "
492 TEUCHOS_TEST_FOR_EXCEPTION(
493 true, std::logic_error,
494 "Tpetra::BlockCrsMatrix::"
495 "apply: The implementation method applyBlock threw an exception which "
496 "is not an instance of a subclass of std::exception. This probably "
497 "indicates a bug. Please report this to the Tpetra developers.");
501template <
class Scalar,
class LO,
class GO,
class Node>
505 Teuchos::ETransp mode,
508 TEUCHOS_TEST_FOR_EXCEPTION(
510 "Tpetra::BlockCrsMatrix::applyBlock: "
511 "X and Y have different block sizes. X.getBlockSize() = "
515 if (mode == Teuchos::NO_TRANS) {
516 applyBlockNoTrans(X, Y, alpha, beta);
517 }
else if (mode == Teuchos::TRANS || mode == Teuchos::CONJ_TRANS) {
518 applyBlockTrans(X, Y, mode, alpha, beta);
520 TEUCHOS_TEST_FOR_EXCEPTION(
521 true, std::invalid_argument,
522 "Tpetra::BlockCrsMatrix::"
523 "applyBlock: Invalid 'mode' argument. Valid values are "
524 "Teuchos::NO_TRANS, Teuchos::TRANS, and Teuchos::CONJ_TRANS.");
528template <
class Scalar,
class LO,
class GO,
class Node>
537 TEUCHOS_TEST_FOR_EXCEPTION(!destMatrix.is_null(), std::invalid_argument,
538 "destMatrix is required to be null.");
542 RCP<crs_graph_type> srcGraph = rcp(
new crs_graph_type(this->getCrsGraph()));
544 srcGraph->getDomainMap(),
545 srcGraph->getRangeMap());
548 destMatrix = rcp(
new this_BCRS_type(*destGraph,
getBlockSize()));
552template <
class Scalar,
class LO,
class GO,
class Node>
561 TEUCHOS_TEST_FOR_EXCEPTION(!destMatrix.is_null(), std::invalid_argument,
562 "destMatrix is required to be null.");
566 RCP<crs_graph_type> srcGraph = rcp(
new crs_graph_type(this->getCrsGraph()));
568 srcGraph->getDomainMap(),
569 srcGraph->getRangeMap());
572 destMatrix = rcp(
new this_BCRS_type(*destGraph,
getBlockSize()));
576template <
class Scalar,
class LO,
class GO,
class Node>
579 auto val_d = val_.getDeviceView(Access::OverwriteAll);
580 Kokkos::deep_copy(val_d, alpha);
583template <
class Scalar,
class LO,
class GO,
class Node>
588 const LO numColInds)
const {
589 std::vector<ptrdiff_t> offsets(numColInds);
590 const LO numOffsets = this->
getLocalRowOffsets(localRowInd, offsets.data(), colInds, numColInds);
595template <
class Scalar,
class LO,
class GO,
class Node>
598 Kokkos::MemoryUnmanaged>& offsets)
const {
599 graph_.getLocalDiagOffsets(offsets);
602template <
class Scalar,
class LO,
class GO,
class Node>
605 Kokkos::MemoryUnmanaged>& diag,
607 Kokkos::MemoryUnmanaged>& offsets)
const {
608 using Kokkos::parallel_for;
609 const char prefix[] =
"Tpetra::BlockCrsMatrix::getLocalDiagCopy (2-arg): ";
611 const LO lclNumMeshRows =
static_cast<LO
>(rowMeshMap_.getLocalNumElements());
613 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<LO
>(diag.extent(0)) < lclNumMeshRows ||
614 static_cast<LO
>(diag.extent(1)) < blockSize ||
615 static_cast<LO
>(diag.extent(2)) < blockSize,
616 std::invalid_argument, prefix <<
"The input Kokkos::View is not big enough to hold all the data.");
617 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<LO
>(offsets.size()) < lclNumMeshRows, std::invalid_argument,
618 prefix <<
"offsets.size() = " << offsets.size() <<
" < local number of "
620 << lclNumMeshRows <<
".");
622 typedef Kokkos::RangePolicy<execution_space, LO> policy_type;
623 typedef GetLocalDiagCopy<Scalar, LO, GO, Node> functor_type;
629 auto val_d = val_.getDeviceView(Access::ReadOnly);
630 parallel_for(policy_type(0, lclNumMeshRows),
631 functor_type(diag, val_d, offsets,
632 graph_.getLocalGraphDevice().row_map, blockSize_));
635template <
class Scalar,
class LO,
class GO,
class Node>
640 const LO numColInds)
const {
641 std::vector<ptrdiff_t> offsets(numColInds);
642 const LO numOffsets = this->
getLocalRowOffsets(localRowInd, offsets.data(), colInds, numColInds);
643 const LO validCount = this->absMaxLocalValuesByOffsets(localRowInd, offsets.data(), vals, numOffsets);
647template <
class Scalar,
class LO,
class GO,
class Node>
652 const LO numColInds)
const {
653 std::vector<ptrdiff_t> offsets(numColInds);
654 const LO numOffsets = this->
getLocalRowOffsets(localRowInd, offsets.data(), colInds, numColInds);
658template <
class Scalar,
class LO,
class GO,
class Node>
661 nonconst_local_inds_host_view_type& Indices,
662 nonconst_values_host_view_type& Values,
663 size_t& NumEntries)
const {
664 auto vals = getValuesHost(LocalRow);
665 const LO numInds = ptrHost_(LocalRow + 1) - ptrHost_(LocalRow);
666 if (numInds > (LO)Indices.extent(0) || numInds * blockSize_ * blockSize_ > (LO)Values.extent(0)) {
667 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
668 "Tpetra::BlockCrsMatrix::getLocalRowCopy : Column and/or values array is not large enough to hold "
669 << numInds <<
" row entries");
671 const LO* colInds = indHost_.data() + ptrHost_(LocalRow);
672 for (LO i = 0; i < numInds; ++i) {
673 Indices[i] = colInds[i];
675 for (LO i = 0; i < numInds * blockSize_ * blockSize_; ++i) {
678 NumEntries = numInds;
681template <
class Scalar,
class LO,
class GO,
class Node>
686 const LO numColInds)
const {
687 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
692 return static_cast<LO
>(0);
695 const LO LINV = Teuchos::OrdinalTraits<LO>::invalid();
699 for (LO k = 0; k < numColInds; ++k) {
700 const LO relBlockOffset =
701 this->findRelOffsetOfColumnIndex(localRowInd, colInds[k], hint);
702 if (relBlockOffset != LINV) {
703 offsets[k] =
static_cast<ptrdiff_t
>(relBlockOffset);
704 hint = relBlockOffset + 1;
711template <
class Scalar,
class LO,
class GO,
class Node>
714 const ptrdiff_t offsets[],
716 const LO numOffsets)
const {
717 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
722 return static_cast<LO
>(0);
726 auto val_out =
const_cast<this_BCRS_type&
>(*this).getValuesHostNonConst(localRowInd);
729 const size_t perBlockSize = offsetPerBlock();
730 const ptrdiff_t STINV = Teuchos::OrdinalTraits<ptrdiff_t>::invalid();
731 size_t pointOffset = 0;
734 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
735 const size_t blockOffset = offsets[k] * perBlockSize;
736 if (offsets[k] != STINV) {
746template <
class Scalar,
class LO,
class GO,
class Node>
749 const ptrdiff_t offsets[],
751 const LO numOffsets)
const {
752 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
757 return static_cast<LO
>(0);
759 const impl_scalar_type*
const vIn =
reinterpret_cast<const impl_scalar_type*
>(vals);
760 auto val_out = getValuesHost(localRowInd);
761 impl_scalar_type* vOut =
const_cast<impl_scalar_type*
>(val_out.data());
763 const size_t perBlockSize = offsetPerBlock();
764 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid();
765 size_t pointOffset = 0;
768 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
769 const size_t blockOffset = offsets[k] * perBlockSize;
770 if (blockOffset != STINV) {
771 little_block_type A_old = getNonConstLocalBlockFromInput(vOut, blockOffset);
772 const_little_block_type A_new = getConstLocalBlockFromInput(vIn, pointOffset);
780template <
class Scalar,
class LO,
class GO,
class Node>
783 const ptrdiff_t offsets[],
785 const LO numOffsets)
const {
786 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
791 return static_cast<LO
>(0);
796 auto val_out =
const_cast<this_BCRS_type&
>(*this).getValuesHostNonConst(localRowInd);
799 const size_t perBlockSize = offsetPerBlock();
800 const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid();
801 size_t pointOffset = 0;
804 for (LO k = 0; k < numOffsets; ++k, pointOffset += perBlockSize) {
805 const size_t blockOffset = offsets[k] * perBlockSize;
806 if (blockOffset != STINV) {
809 AXPY(ONE, A_new, A_old);
816template <
class Scalar,
class LO,
class GO,
class Node>
818 impl_scalar_type_dualview::t_host::const_type
821 return val_.getHostView(Access::ReadOnly);
824template <
class Scalar,
class LO,
class GO,
class Node>
825typename BlockCrsMatrix<Scalar, LO, GO, Node>::
826 impl_scalar_type_dualview::t_dev::const_type
827 BlockCrsMatrix<Scalar, LO, GO, Node>::
828 getValuesDevice()
const {
829 return val_.getDeviceView(Access::ReadOnly);
832template <
class Scalar,
class LO,
class GO,
class Node>
834 impl_scalar_type_dualview::t_host
837 return val_.getHostView(Access::ReadWrite);
840template <
class Scalar,
class LO,
class GO,
class Node>
842 impl_scalar_type_dualview::t_dev
845 return val_.getDeviceView(Access::ReadWrite);
848template <
class Scalar,
class LO,
class GO,
class Node>
849typename BlockCrsMatrix<Scalar, LO, GO, Node>::
850 impl_scalar_type_dualview::t_host::const_type
853 const size_t perBlockSize = offsetPerBlock();
854 auto val = val_.getHostView(Access::ReadOnly);
855 auto r_val = Kokkos::subview(val, Kokkos::pair<size_t, size_t>(ptrHost_(lclRow) * perBlockSize, ptrHost_(lclRow + 1) * perBlockSize));
859template <
class Scalar,
class LO,
class GO,
class Node>
861 impl_scalar_type_dualview::t_dev::const_type
864 const size_t perBlockSize = offsetPerBlock();
865 auto val = val_.getDeviceView(Access::ReadOnly);
866 auto r_val = Kokkos::subview(val, Kokkos::pair<size_t, size_t>(ptrHost_(lclRow) * perBlockSize, ptrHost_(lclRow + 1) * perBlockSize));
870template <
class Scalar,
class LO,
class GO,
class Node>
874 const size_t perBlockSize = offsetPerBlock();
875 auto val = val_.getHostView(Access::ReadWrite);
876 auto r_val = Kokkos::subview(val, Kokkos::pair<size_t, size_t>(ptrHost_(lclRow) * perBlockSize, ptrHost_(lclRow + 1) * perBlockSize));
880template <
class Scalar,
class LO,
class GO,
class Node>
884 const size_t perBlockSize = offsetPerBlock();
885 auto val = val_.getDeviceView(Access::ReadWrite);
886 auto r_val = Kokkos::subview(val, Kokkos::pair<size_t, size_t>(ptrHost_(lclRow) * perBlockSize, ptrHost_(lclRow + 1) * perBlockSize));
890template <
class Scalar,
class LO,
class GO,
class Node>
894 const size_t numEntInGraph = graph_.getNumEntriesInLocalRow(localRowInd);
895 if (numEntInGraph == Teuchos::OrdinalTraits<size_t>::invalid()) {
898 return numEntInGraph;
902template <
class Scalar,
class LO,
class GO,
class Node>
903typename BlockCrsMatrix<Scalar, LO, GO, Node>::local_matrix_device_type
906 auto numCols = this->graph_.
getColMap()->getLocalNumElements();
907 auto val = val_.getDeviceView(Access::ReadWrite);
909 const auto graph = this->graph_.getLocalGraphDevice();
911 return local_matrix_device_type(
"Tpetra::BlockCrsMatrix::lclMatrixDevice",
918template <
class Scalar,
class LO,
class GO,
class Node>
922 const Teuchos::ETransp mode,
931 TEUCHOS_TEST_FOR_EXCEPTION(
932 true, std::logic_error,
933 "Tpetra::BlockCrsMatrix::apply: "
934 "transpose and conjugate transpose modes are not yet implemented.");
937template <
class Scalar,
class LO,
class GO,
class Node>
938void BlockCrsMatrix<Scalar, LO, GO, Node>::
939 applyBlockNoTrans(
const BlockMultiVector<Scalar, LO, GO, Node>& X,
940 BlockMultiVector<Scalar, LO, GO, Node>& Y,
945 typedef ::Tpetra::Import<LO, GO, Node> import_type;
946 typedef ::Tpetra::Export<LO, GO, Node> export_type;
947 const Scalar zero = STS::zero();
948 const Scalar one = STS::one();
949 RCP<const import_type>
import = graph_.getImporter();
951 RCP<const export_type> theExport = graph_.getExporter();
952 const char prefix[] =
"Tpetra::BlockCrsMatrix::applyBlockNoTrans: ";
957 }
else if (beta != one) {
961 const BMV* X_colMap = NULL;
962 if (
import.is_null()) {
965 }
catch (std::exception& e) {
966 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, prefix <<
"Tpetra::MultiVector::"
967 "operator= threw an exception: "
978 if ((*X_colMap_).is_null() ||
979 (**X_colMap_).getNumVectors() != X.getNumVectors() ||
980 (**X_colMap_).getBlockSize() != X.getBlockSize()) {
981 *X_colMap_ = rcp(
new BMV(*(graph_.getColMap()), getBlockSize(),
982 static_cast<LO
>(X.getNumVectors())));
984 (*X_colMap_)->getMultiVectorView().doImport(X.getMultiVectorView(), **pointImporter_,
::Tpetra::REPLACE);
986 X_colMap = &(**X_colMap_);
987 }
catch (std::exception& e) {
988 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, prefix <<
"Tpetra::MultiVector::"
989 "operator= threw an exception: "
995 BMV* Y_rowMap = NULL;
996 if (theExport.is_null()) {
998 }
else if ((*Y_rowMap_).is_null() ||
999 (**Y_rowMap_).getNumVectors() != Y.getNumVectors() ||
1000 (**Y_rowMap_).getBlockSize() != Y.getBlockSize()) {
1001 *Y_rowMap_ = rcp(
new BMV(*(graph_.getRowMap()), getBlockSize(),
1002 static_cast<LO
>(X.getNumVectors())));
1004 Y_rowMap = &(**Y_rowMap_);
1005 }
catch (std::exception& e) {
1006 TEUCHOS_TEST_FOR_EXCEPTION(
1007 true, std::logic_error, prefix <<
"Tpetra::MultiVector::"
1008 "operator= threw an exception: "
1015 localApplyBlockNoTrans(*X_colMap, *Y_rowMap, alpha, beta);
1016 }
catch (std::exception& e) {
1017 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, prefix <<
"localApplyBlockNoTrans threw "
1021 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, prefix <<
"localApplyBlockNoTrans threw "
1022 "an exception not a subclass of std::exception.");
1025 if (!theExport.is_null()) {
1031template <
class Scalar,
class LO,
class GO,
class Node>
1032void BlockCrsMatrix<Scalar, LO, GO, Node>::localApplyBlockNoTrans(
1035 const Scalar beta) {
1036 ::Tpetra::Details::ProfilingRegion profile_region(
1037 "Tpetra::BlockCrsMatrix::localApplyBlockNoTrans");
1039 const auto graph = this->graph_.getLocalGraphDevice();
1042 mv_type Y_mv = Y.getMultiVectorView();
1044 auto Y_lcl = Y_mv.getLocalViewDevice(Access::ReadWrite);
1046 auto A_lcl = getLocalMatrixDevice();
1047 if (!applyHelper.get()) {
1049 applyHelper = std::make_shared<ApplyHelper>(A_lcl.nnz(), A_lcl.graph.row_map);
1051 if (applyHelper->shouldUseIntRowptrs()) {
1052 auto A_lcl_int_rowptrs = applyHelper->getIntRowptrMatrix(A_lcl);
1054 &applyHelper->handle_int, KokkosSparse::NoTranspose,
1055 alpha_impl, A_lcl_int_rowptrs, X_lcl, beta, Y_lcl);
1058 &applyHelper->handle, KokkosSparse::NoTranspose,
1059 alpha_impl, A_lcl, X_lcl, beta, Y_lcl);
1063template <
class Scalar,
class LO,
class GO,
class Node>
1066 const LO colIndexToFind,
1067 const LO hint)
const {
1068 const size_t absStartOffset = ptrHost_[localRowIndex];
1069 const size_t absEndOffset = ptrHost_[localRowIndex + 1];
1070 const LO numEntriesInRow =
static_cast<LO
>(absEndOffset - absStartOffset);
1072 const LO*
const curInd = indHost_.data() + absStartOffset;
1075 if (hint < numEntriesInRow && curInd[hint] == colIndexToFind) {
1082 LO relOffset = Teuchos::OrdinalTraits<LO>::invalid();
1087 const LO maxNumEntriesForLinearSearch = 32;
1088 if (numEntriesInRow > maxNumEntriesForLinearSearch) {
1093 const LO* beg = curInd;
1094 const LO* end = curInd + numEntriesInRow;
1095 std::pair<const LO*, const LO*> p =
1096 std::equal_range(beg, end, colIndexToFind);
1097 if (p.first != p.second) {
1099 relOffset =
static_cast<LO
>(p.first - beg);
1102 for (LO k = 0; k < numEntriesInRow; ++k) {
1103 if (colIndexToFind == curInd[k]) {
1113template <
class Scalar,
class LO,
class GO,
class Node>
1116 return offsetPerBlock_;
1119template <
class Scalar,
class LO,
class GO,
class Node>
1123 const size_t pointOffset)
const {
1125 const LO rowStride = blockSize_;
1126 return const_little_block_type(val + pointOffset, blockSize_, rowStride);
1129template <
class Scalar,
class LO,
class GO,
class Node>
1133 const size_t pointOffset)
const {
1135 const LO rowStride = blockSize_;
1136 return little_block_type(val + pointOffset, blockSize_, rowStride);
1139template <
class Scalar,
class LO,
class GO,
class Node>
1140typename BlockCrsMatrix<Scalar, LO, GO, Node>::little_block_host_type
1143 const size_t pointOffset)
const {
1145 const LO rowStride = blockSize_;
1146 const size_t bs2 = blockSize_ * blockSize_;
1147 return little_block_host_type(val + bs2 * pointOffset, blockSize_, rowStride);
1150template <
class Scalar,
class LO,
class GO,
class Node>
1156 const size_t absRowBlockOffset = ptrHost_[localRowInd];
1157 const LO relBlockOffset = this->findRelOffsetOfColumnIndex(localRowInd, localColInd);
1158 if (relBlockOffset != Teuchos::OrdinalTraits<LO>::invalid()) {
1159 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
1160 auto vals =
const_cast<this_BCRS_type&
>(*this).getValuesDeviceNonConst();
1161 auto r_val = getNonConstLocalBlockFromInput(vals.data(), absBlockOffset);
1164 return little_block_type();
1168template <
class Scalar,
class LO,
class GO,
class Node>
1169typename BlockCrsMatrix<Scalar, LO, GO, Node>::little_block_host_type
1174 const size_t absRowBlockOffset = ptrHost_[localRowInd];
1175 const LO relBlockOffset = this->findRelOffsetOfColumnIndex(localRowInd, localColInd);
1176 if (relBlockOffset != Teuchos::OrdinalTraits<LO>::invalid()) {
1177 const size_t absBlockOffset = absRowBlockOffset + relBlockOffset;
1178 auto vals =
const_cast<this_BCRS_type&
>(*this).getValuesHostNonConst();
1179 auto r_val = getNonConstLocalBlockFromInputHost(vals.data(), absBlockOffset);
1182 return little_block_host_type();
1186template <
class Scalar,
class LO,
class GO,
class Node>
1188 checkSizes(const ::Tpetra::SrcDistObject& source) {
1191 const this_BCRS_type* src =
dynamic_cast<const this_BCRS_type*
>(&source);
1194 std::ostream& err = markLocalErrorAndGetStream();
1195 err <<
"checkSizes: The source object of the Import or Export "
1196 "must be a BlockCrsMatrix with the same template parameters as the "
1202 if (src->getBlockSize() != this->getBlockSize()) {
1203 std::ostream& err = markLocalErrorAndGetStream();
1204 err <<
"checkSizes: The source and target objects of the Import or "
1205 <<
"Export must have the same block sizes. The source's block "
1206 <<
"size = " << src->getBlockSize() <<
" != the target's block "
1207 <<
"size = " << this->getBlockSize() <<
"." << endl;
1209 if (!src->graph_.isFillComplete()) {
1210 std::ostream& err = markLocalErrorAndGetStream();
1211 err <<
"checkSizes: The source object of the Import or Export is "
1212 "not fill complete. Both source and target objects must be fill "
1216 if (!this->graph_.isFillComplete()) {
1217 std::ostream& err = markLocalErrorAndGetStream();
1218 err <<
"checkSizes: The target object of the Import or Export is "
1219 "not fill complete. Both source and target objects must be fill "
1223 if (src->graph_.getColMap().is_null()) {
1224 std::ostream& err = markLocalErrorAndGetStream();
1225 err <<
"checkSizes: The source object of the Import or Export does "
1226 "not have a column Map. Both source and target objects must have "
1230 if (this->graph_.getColMap().is_null()) {
1231 std::ostream& err = markLocalErrorAndGetStream();
1232 err <<
"checkSizes: The target object of the Import or Export does "
1233 "not have a column Map. Both source and target objects must have "
1239 return !(*(this->localError_));
1242template <
class Scalar,
class LO,
class GO,
class Node>
1245 const size_t numSameIDs,
1257 ProfilingRegion profile_region(
"Tpetra::BlockCrsMatrix::copyAndPermute");
1258 const bool debug = Behavior::debug();
1259 const bool verbose = Behavior::verbose();
1264 std::ostringstream os;
1265 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1266 os <<
"Proc " << myRank <<
": BlockCrsMatrix::copyAndPermute : " << endl;
1271 if (*(this->localError_)) {
1272 std::ostream& err = this->markLocalErrorAndGetStream();
1274 <<
"The target object of the Import or Export is already in an error state."
1283 std::ostringstream os;
1284 os << prefix << endl
1285 << prefix <<
" " << dualViewStatusToString(permuteToLIDs,
"permuteToLIDs") << endl
1286 << prefix <<
" " << dualViewStatusToString(permuteFromLIDs,
"permuteFromLIDs") << endl;
1287 std::cerr << os.str();
1293 if (permuteToLIDs.extent(0) != permuteFromLIDs.extent(0)) {
1294 std::ostream& err = this->markLocalErrorAndGetStream();
1296 <<
"permuteToLIDs.extent(0) = " << permuteToLIDs.extent(0)
1297 <<
" != permuteFromLIDs.extent(0) = " << permuteFromLIDs.extent(0)
1301 if (permuteToLIDs.need_sync_host() || permuteFromLIDs.need_sync_host()) {
1302 std::ostream& err = this->markLocalErrorAndGetStream();
1304 <<
"Both permuteToLIDs and permuteFromLIDs must be sync'd to host."
1309 const this_BCRS_type* src =
dynamic_cast<const this_BCRS_type*
>(&source);
1311 std::ostream& err = this->markLocalErrorAndGetStream();
1313 <<
"The source (input) object of the Import or "
1314 "Export is either not a BlockCrsMatrix, or does not have the right "
1315 "template parameters. checkSizes() should have caught this. "
1316 "Please report this bug to the Tpetra developers."
1321 bool lclErr =
false;
1322#ifdef HAVE_TPETRA_DEBUG
1323 std::set<LO> invalidSrcCopyRows;
1324 std::set<LO> invalidDstCopyRows;
1325 std::set<LO> invalidDstCopyCols;
1326 std::set<LO> invalidDstPermuteCols;
1327 std::set<LO> invalidPermuteFromRows;
1337#ifdef HAVE_TPETRA_DEBUG
1338 const map_type& srcRowMap = *(src->graph_.getRowMap());
1340 const map_type& dstRowMap = *(this->graph_.getRowMap());
1341 const map_type& srcColMap = *(src->graph_.getColMap());
1342 const map_type& dstColMap = *(this->graph_.getColMap());
1343 const bool canUseLocalColumnIndices = srcColMap.
locallySameAs(dstColMap);
1345 const size_t numPermute =
static_cast<size_t>(permuteFromLIDs.extent(0));
1347 std::ostringstream os;
1349 <<
"canUseLocalColumnIndices: "
1350 << (canUseLocalColumnIndices ?
"true" :
"false")
1351 <<
", numPermute: " << numPermute
1353 std::cerr << os.str();
1356 const auto permuteToLIDsHost = permuteToLIDs.view_host();
1357 const auto permuteFromLIDsHost = permuteFromLIDs.view_host();
1359 if (canUseLocalColumnIndices) {
1361 for (LO localRow = 0; localRow < static_cast<LO>(numSameIDs); ++localRow) {
1362#ifdef HAVE_TPETRA_DEBUG
1365 invalidSrcCopyRows.insert(localRow);
1370 local_inds_host_view_type lclSrcCols;
1371 values_host_view_type vals;
1375 src->getLocalRowView(localRow, lclSrcCols, vals);
1376 numEntries = lclSrcCols.extent(0);
1377 if (numEntries > 0) {
1379 if (err != numEntries) {
1382#ifdef HAVE_TPETRA_DEBUG
1383 invalidDstCopyRows.insert(localRow);
1391 for (LO k = 0; k < numEntries; ++k) {
1394#ifdef HAVE_TPETRA_DEBUG
1395 (void)invalidDstCopyCols.insert(lclSrcCols[k]);
1405 for (
size_t k = 0; k < numPermute; ++k) {
1406 const LO srcLclRow =
static_cast<LO
>(permuteFromLIDsHost(k));
1407 const LO dstLclRow =
static_cast<LO
>(permuteToLIDsHost(k));
1409 local_inds_host_view_type lclSrcCols;
1410 values_host_view_type vals;
1412 src->getLocalRowView(srcLclRow, lclSrcCols, vals);
1413 numEntries = lclSrcCols.extent(0);
1414 if (numEntries > 0) {
1416 if (err != numEntries) {
1418#ifdef HAVE_TPETRA_DEBUG
1419 for (LO c = 0; c < numEntries; ++c) {
1421 invalidDstPermuteCols.insert(lclSrcCols[c]);
1430 const size_t maxNumEnt = src->graph_.getLocalMaxNumRowEntries();
1431 Teuchos::Array<LO> lclDstCols(maxNumEnt);
1434 for (LO localRow = 0; localRow < static_cast<LO>(numSameIDs); ++localRow) {
1435 local_inds_host_view_type lclSrcCols;
1436 values_host_view_type vals;
1442 src->getLocalRowView(localRow, lclSrcCols, vals);
1443 numEntries = lclSrcCols.extent(0);
1444 }
catch (std::exception& e) {
1446 std::ostringstream os;
1447 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1448 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow "
1449 << localRow <<
", src->getLocalRowView() threw an exception: "
1451 std::cerr << os.str();
1456 if (numEntries > 0) {
1457 if (
static_cast<size_t>(numEntries) >
static_cast<size_t>(lclDstCols.size())) {
1460 std::ostringstream os;
1461 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1462 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow "
1463 << localRow <<
", numEntries = " << numEntries <<
" > maxNumEnt = "
1464 << maxNumEnt << endl;
1465 std::cerr << os.str();
1470 Teuchos::ArrayView<LO> lclDstColsView = lclDstCols.view(0, numEntries);
1471 for (LO j = 0; j < numEntries; ++j) {
1473 if (lclDstColsView[j] == Teuchos::OrdinalTraits<LO>::invalid()) {
1475#ifdef HAVE_TPETRA_DEBUG
1476 invalidDstCopyCols.insert(lclDstColsView[j]);
1483 }
catch (std::exception& e) {
1485 std::ostringstream os;
1486 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1487 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" localRow "
1488 << localRow <<
", this->replaceLocalValues() threw an exception: "
1490 std::cerr << os.str();
1494 if (err != numEntries) {
1497 std::ostringstream os;
1498 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1499 os <<
"Proc " << myRank <<
": copyAndPermute: At \"same\" "
1501 << localRow <<
", this->replaceLocalValues "
1503 << err <<
" instead of numEntries = "
1504 << numEntries << endl;
1505 std::cerr << os.str();
1513 for (
size_t k = 0; k < numPermute; ++k) {
1514 const LO srcLclRow =
static_cast<LO
>(permuteFromLIDsHost(k));
1515 const LO dstLclRow =
static_cast<LO
>(permuteToLIDsHost(k));
1517 local_inds_host_view_type lclSrcCols;
1518 values_host_view_type vals;
1522 src->getLocalRowView(srcLclRow, lclSrcCols, vals);
1523 numEntries = lclSrcCols.extent(0);
1524 }
catch (std::exception& e) {
1526 std::ostringstream os;
1527 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1528 os <<
"Proc " << myRank <<
": copyAndPermute: At \"permute\" "
1530 << srcLclRow <<
" and dstLclRow " << dstLclRow
1531 <<
", src->getLocalRowView() threw an exception: " << e.what();
1532 std::cerr << os.str();
1537 if (numEntries > 0) {
1538 if (
static_cast<size_t>(numEntries) >
static_cast<size_t>(lclDstCols.size())) {
1543 Teuchos::ArrayView<LO> lclDstColsView = lclDstCols.view(0, numEntries);
1544 for (LO j = 0; j < numEntries; ++j) {
1546 if (lclDstColsView[j] == Teuchos::OrdinalTraits<LO>::invalid()) {
1548#ifdef HAVE_TPETRA_DEBUG
1549 invalidDstPermuteCols.insert(lclDstColsView[j]);
1554 if (err != numEntries) {
1563 std::ostream& err = this->markLocalErrorAndGetStream();
1564#ifdef HAVE_TPETRA_DEBUG
1565 err <<
"copyAndPermute: The graph structure of the source of the "
1566 "Import or Export must be a subset of the graph structure of the "
1568 err <<
"invalidSrcCopyRows = [";
1569 for (
typename std::set<LO>::const_iterator it = invalidSrcCopyRows.begin();
1570 it != invalidSrcCopyRows.end(); ++it) {
1572 typename std::set<LO>::const_iterator itp1 = it;
1574 if (itp1 != invalidSrcCopyRows.end()) {
1578 err <<
"], invalidDstCopyRows = [";
1579 for (
typename std::set<LO>::const_iterator it = invalidDstCopyRows.begin();
1580 it != invalidDstCopyRows.end(); ++it) {
1582 typename std::set<LO>::const_iterator itp1 = it;
1584 if (itp1 != invalidDstCopyRows.end()) {
1588 err <<
"], invalidDstCopyCols = [";
1589 for (
typename std::set<LO>::const_iterator it = invalidDstCopyCols.begin();
1590 it != invalidDstCopyCols.end(); ++it) {
1592 typename std::set<LO>::const_iterator itp1 = it;
1594 if (itp1 != invalidDstCopyCols.end()) {
1598 err <<
"], invalidDstPermuteCols = [";
1599 for (
typename std::set<LO>::const_iterator it = invalidDstPermuteCols.begin();
1600 it != invalidDstPermuteCols.end(); ++it) {
1602 typename std::set<LO>::const_iterator itp1 = it;
1604 if (itp1 != invalidDstPermuteCols.end()) {
1608 err <<
"], invalidPermuteFromRows = [";
1609 for (
typename std::set<LO>::const_iterator it = invalidPermuteFromRows.begin();
1610 it != invalidPermuteFromRows.end(); ++it) {
1612 typename std::set<LO>::const_iterator itp1 = it;
1614 if (itp1 != invalidPermuteFromRows.end()) {
1620 err <<
"copyAndPermute: The graph structure of the source of the "
1621 "Import or Export must be a subset of the graph structure of the "
1628 std::ostringstream os;
1629 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1630 const bool lclSuccess = !(*(this->localError_));
1631 os <<
"*** Proc " << myRank <<
": copyAndPermute "
1632 << (lclSuccess ?
"succeeded" :
"FAILED");
1638 std::cerr << os.str();
1662template <
class LO,
class GO>
1664packRowCount(
const size_t numEnt,
1665 const size_t numBytesPerValue,
1666 const size_t blkSize) {
1676 const size_t numEntLen = PackTraits<LO>::packValueCount(numEntLO);
1677 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount(gid);
1678 const size_t valsLen = numEnt * numBytesPerValue * blkSize * blkSize;
1679 return numEntLen + gidsLen + valsLen;
1693template <
class ST,
class LO,
class GO>
1695unpackRowCount(
const typename ::Tpetra::Details::PackTraits<LO>::input_buffer_type& imports,
1696 const size_t offset,
1697 const size_t numBytes,
1699 using Kokkos::subview;
1700 using ::Tpetra::Details::PackTraits;
1702 if (numBytes == 0) {
1704 return static_cast<size_t>(0);
1707 const size_t theNumBytes = PackTraits<LO>::packValueCount(numEntLO);
1708 TEUCHOS_TEST_FOR_EXCEPTION(theNumBytes > numBytes, std::logic_error,
1711 << theNumBytes <<
" < numBytes = " << numBytes
1713 const char*
const inBuf = imports.data() + offset;
1714 const size_t actualNumBytes = PackTraits<LO>::unpackValue(numEntLO, inBuf);
1715 TEUCHOS_TEST_FOR_EXCEPTION(actualNumBytes > numBytes, std::logic_error,
1718 << actualNumBytes <<
" < numBytes = " << numBytes
1720 return static_cast<size_t>(numEntLO);
1727template <
class ST,
class LO,
class GO>
1729packRowForBlockCrs(
const typename ::Tpetra::Details::PackTraits<LO>::output_buffer_type exports,
1730 const size_t offset,
1731 const size_t numEnt,
1732 const typename ::Tpetra::Details::PackTraits<GO>::input_array_type& gidsIn,
1733 const typename ::Tpetra::Details::PackTraits<ST>::input_array_type& valsIn,
1734 const size_t numBytesPerValue,
1735 const size_t blockSize) {
1736 using Kokkos::subview;
1737 using ::Tpetra::Details::PackTraits;
1743 const size_t numScalarEnt = numEnt * blockSize * blockSize;
1746 const LO numEntLO =
static_cast<size_t>(numEnt);
1748 const size_t numEntBeg = offset;
1749 const size_t numEntLen = PackTraits<LO>::packValueCount(numEntLO);
1750 const size_t gidsBeg = numEntBeg + numEntLen;
1751 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount(gid);
1752 const size_t valsBeg = gidsBeg + gidsLen;
1753 const size_t valsLen = numScalarEnt * numBytesPerValue;
1755 char*
const numEntOut = exports.data() + numEntBeg;
1756 char*
const gidsOut = exports.data() + gidsBeg;
1757 char*
const valsOut = exports.data() + valsBeg;
1759 size_t numBytesOut = 0;
1761 numBytesOut += PackTraits<LO>::packValue(numEntOut, numEntLO);
1764 Kokkos::pair<int, size_t> p;
1765 p = PackTraits<GO>::packArray(gidsOut, gidsIn.data(), numEnt);
1766 errorCode += p.first;
1767 numBytesOut += p.second;
1769 p = PackTraits<ST>::packArray(valsOut, valsIn.data(), numScalarEnt);
1770 errorCode += p.first;
1771 numBytesOut += p.second;
1774 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
1775 TEUCHOS_TEST_FOR_EXCEPTION(numBytesOut != expectedNumBytes, std::logic_error,
1776 "packRowForBlockCrs: numBytesOut = " << numBytesOut
1777 <<
" != expectedNumBytes = " << expectedNumBytes <<
".");
1779 TEUCHOS_TEST_FOR_EXCEPTION(errorCode != 0, std::runtime_error,
1780 "packRowForBlockCrs: "
1781 "PackTraits::packArray returned a nonzero error code");
1787template <
class ST,
class LO,
class GO>
1789unpackRowForBlockCrs(
const typename ::Tpetra::Details::PackTraits<GO>::output_array_type& gidsOut,
1790 const typename ::Tpetra::Details::PackTraits<ST>::output_array_type& valsOut,
1791 const typename ::Tpetra::Details::PackTraits<int>::input_buffer_type& imports,
1792 const size_t offset,
1793 const size_t numBytes,
1794 const size_t numEnt,
1795 const size_t numBytesPerValue,
1796 const size_t blockSize) {
1797 using ::Tpetra::Details::PackTraits;
1799 if (numBytes == 0) {
1803 const size_t numScalarEnt = numEnt * blockSize * blockSize;
1804 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<size_t>(imports.extent(0)) <= offset,
1805 std::logic_error,
"unpackRowForBlockCrs: imports.extent(0) = " << imports.extent(0) <<
" <= offset = " << offset <<
".");
1806 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<size_t>(imports.extent(0)) < offset + numBytes,
1807 std::logic_error,
"unpackRowForBlockCrs: imports.extent(0) = " << imports.extent(0) <<
" < offset + numBytes = " << (offset + numBytes) <<
".");
1812 const size_t numEntBeg = offset;
1813 const size_t numEntLen = PackTraits<LO>::packValueCount(lid);
1814 const size_t gidsBeg = numEntBeg + numEntLen;
1815 const size_t gidsLen = numEnt * PackTraits<GO>::packValueCount(gid);
1816 const size_t valsBeg = gidsBeg + gidsLen;
1817 const size_t valsLen = numScalarEnt * numBytesPerValue;
1819 const char*
const numEntIn = imports.data() + numEntBeg;
1820 const char*
const gidsIn = imports.data() + gidsBeg;
1821 const char*
const valsIn = imports.data() + valsBeg;
1823 size_t numBytesOut = 0;
1826 numBytesOut += PackTraits<LO>::unpackValue(numEntOut, numEntIn);
1827 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<size_t>(numEntOut) != numEnt, std::logic_error,
1828 "unpackRowForBlockCrs: Expected number of entries " << numEnt
1829 <<
" != actual number of entries " << numEntOut <<
".");
1832 Kokkos::pair<int, size_t> p;
1833 p = PackTraits<GO>::unpackArray(gidsOut.data(), gidsIn, numEnt);
1834 errorCode += p.first;
1835 numBytesOut += p.second;
1837 p = PackTraits<ST>::unpackArray(valsOut.data(), valsIn, numScalarEnt);
1838 errorCode += p.first;
1839 numBytesOut += p.second;
1842 TEUCHOS_TEST_FOR_EXCEPTION(numBytesOut != numBytes, std::logic_error,
1843 "unpackRowForBlockCrs: numBytesOut = " << numBytesOut
1844 <<
" != numBytes = " << numBytes <<
".");
1846 const size_t expectedNumBytes = numEntLen + gidsLen + valsLen;
1847 TEUCHOS_TEST_FOR_EXCEPTION(numBytesOut != expectedNumBytes, std::logic_error,
1848 "unpackRowForBlockCrs: numBytesOut = " << numBytesOut
1849 <<
" != expectedNumBytes = " << expectedNumBytes <<
".");
1851 TEUCHOS_TEST_FOR_EXCEPTION(errorCode != 0, std::runtime_error,
1852 "unpackRowForBlockCrs: "
1853 "PackTraits::unpackArray returned a nonzero error code");
1859template <
class Scalar,
class LO,
class GO,
class Node>
1866 Kokkos::DualView<
size_t*,
1869 size_t& constantNumPackets) {
1875 typedef typename Kokkos::View<int*, device_type>::host_mirror_type::execution_space host_exec;
1879 ProfilingRegion profile_region(
"Tpetra::BlockCrsMatrix::packAndPrepare");
1881 const bool debug = Behavior::debug();
1882 const bool verbose = Behavior::verbose();
1887 std::ostringstream os;
1888 const int myRank = this->graph_.getRowMap()->getComm()->getRank();
1889 os <<
"Proc " << myRank <<
": BlockCrsMatrix::packAndPrepare: " << std::endl;
1894 if (*(this->localError_)) {
1895 std::ostream& err = this->markLocalErrorAndGetStream();
1897 <<
"The target object of the Import or Export is already in an error state."
1906 std::ostringstream os;
1907 os << prefix << std::endl
1908 << prefix <<
" " << dualViewStatusToString(exportLIDs,
"exportLIDs") << std::endl
1909 << prefix <<
" " << dualViewStatusToString(exports,
"exports") << std::endl
1910 << prefix <<
" " << dualViewStatusToString(numPacketsPerLID,
"numPacketsPerLID") << std::endl;
1911 std::cerr << os.str();
1917 if (exportLIDs.extent(0) != numPacketsPerLID.extent(0)) {
1918 std::ostream& err = this->markLocalErrorAndGetStream();
1920 <<
"exportLIDs.extent(0) = " << exportLIDs.extent(0)
1921 <<
" != numPacketsPerLID.extent(0) = " << numPacketsPerLID.extent(0)
1922 <<
"." << std::endl;
1925 if (exportLIDs.need_sync_host()) {
1926 std::ostream& err = this->markLocalErrorAndGetStream();
1927 err << prefix <<
"exportLIDs be sync'd to host." << std::endl;
1931 const this_BCRS_type* src =
dynamic_cast<const this_BCRS_type*
>(&source);
1933 std::ostream& err = this->markLocalErrorAndGetStream();
1935 <<
"The source (input) object of the Import or "
1936 "Export is either not a BlockCrsMatrix, or does not have the right "
1937 "template parameters. checkSizes() should have caught this. "
1938 "Please report this bug to the Tpetra developers."
1951 constantNumPackets = 0;
1955 const size_t blockSize =
static_cast<size_t>(src->getBlockSize());
1956 const size_t numExportLIDs = exportLIDs.extent(0);
1957 size_t numBytesPerValue(0);
1959 auto val_host = val_.getHostView(Access::ReadOnly);
1961 PackTraits<impl_scalar_type>::packValueCount(val_host.extent(0) ? val_host(0) :
impl_scalar_type());
1968 Impl::BlockCrsRowStruct<size_t> rowReducerStruct;
1971 auto exportLIDsHost = exportLIDs.view_host();
1972 auto numPacketsPerLIDHost = numPacketsPerLID.view_host();
1973 numPacketsPerLID.modify_host();
1975 rowReducerStruct = Impl::BlockCrsRowStruct<size_t>();
1976 for (
size_t i = 0; i < numExportLIDs; ++i) {
1977 const LO lclRow = exportLIDsHost(i);
1979 numEnt = (numEnt == Teuchos::OrdinalTraits<size_t>::invalid() ? 0 : numEnt);
1981 const size_t numBytes =
1982 packRowCount<LO, GO>(numEnt, numBytesPerValue, blockSize);
1983 numPacketsPerLIDHost(i) = numBytes;
1984 rowReducerStruct += Impl::BlockCrsRowStruct<size_t>(numEnt, numBytes, numEnt);
1991 const size_t totalNumBytes = rowReducerStruct.totalNumBytes;
1992 const size_t totalNumEntries = rowReducerStruct.totalNumEntries;
1993 const size_t maxRowLength = rowReducerStruct.maxRowLength;
1996 std::ostringstream os;
1998 <<
"totalNumBytes = " << totalNumBytes <<
", totalNumEntries = " << totalNumEntries
2000 std::cerr << os.str();
2006 if (exports.extent(0) != totalNumBytes) {
2007 const std::string oldLabel = exports.view_device().label();
2008 const std::string newLabel = (oldLabel ==
"") ?
"exports" : oldLabel;
2009 exports = Kokkos::DualView<packet_type*, buffer_device_type>(newLabel, totalNumBytes);
2011 if (totalNumEntries > 0) {
2013 Kokkos::View<size_t*, host_exec> offset(
"offset", numExportLIDs + 1);
2015 const auto policy = Kokkos::RangePolicy<host_exec>(
size_t(0), numExportLIDs + 1);
2016 Kokkos::parallel_scan(policy,
2017 [=](
const size_t& i,
size_t& update,
const bool&
final) {
2018 if (
final) offset(i) = update;
2019 update += (i == numExportLIDs ? 0 : numPacketsPerLIDHost(i));
2022 if (offset(numExportLIDs) != totalNumBytes) {
2023 std::ostream& err = this->markLocalErrorAndGetStream();
2025 <<
"At end of method, the final offset (in bytes) "
2026 << offset(numExportLIDs) <<
" does not equal the total number of bytes packed "
2027 << totalNumBytes <<
". "
2028 <<
"Please report this bug to the Tpetra developers." << std::endl;
2042 exports.modify_host();
2044 typedef Kokkos::TeamPolicy<host_exec> policy_type;
2046 policy_type(numExportLIDs, 1, 1)
2047 .set_scratch_size(0, Kokkos::PerTeam(
sizeof(GO) * maxRowLength));
2052 Kokkos::parallel_for(policy,
2053 [=](
const typename policy_type::member_type& member) {
2054 const size_t i = member.league_rank();
2055 Kokkos::View<GO*, typename host_exec::scratch_memory_space>
2056 gblColInds(member.team_scratch(0), maxRowLength);
2058 const LO lclRowInd = exportLIDsHost(i);
2059 local_inds_host_view_type lclColInds;
2060 values_host_view_type vals;
2065 src->getLocalRowView(lclRowInd, lclColInds, vals);
2066 const size_t numEnt = lclColInds.extent(0);
2069 for (
size_t j = 0; j < numEnt; ++j)
2076 const size_t numBytes =
2077 packRowForBlockCrs<impl_scalar_type, LO, GO>(exports.view_host(),
2080 Kokkos::View<const GO*, host_exec>(gblColInds.data(), maxRowLength),
2087 const size_t offsetDiff = offset(i + 1) - offset(i);
2088 if (numBytes != offsetDiff) {
2089 std::ostringstream os;
2091 <<
"numBytes computed from packRowForBlockCrs is different from "
2092 <<
"precomputed offset values, LID = " << i << std::endl;
2093 std::cerr << os.str();
2102 std::ostringstream os;
2103 const bool lclSuccess = !(*(this->localError_));
2105 << (lclSuccess ?
"succeeded" :
"FAILED")
2107 std::cerr << os.str();
2111template <
class Scalar,
class LO,
class GO,
class Node>
2118 Kokkos::DualView<
size_t*,
2129 typename Kokkos::View<int*, device_type>::host_mirror_type::execution_space;
2131 ProfilingRegion profile_region(
"Tpetra::BlockCrsMatrix::unpackAndCombine");
2132 const bool verbose = Behavior::verbose();
2137 std::ostringstream os;
2138 auto map = this->graph_.getRowMap();
2139 auto comm = map.is_null() ? Teuchos::null : map->getComm();
2140 const int myRank = comm.is_null() ? -1 : comm->getRank();
2141 os <<
"Proc " << myRank <<
": Tpetra::BlockCrsMatrix::unpackAndCombine: ";
2144 os <<
"Start" << endl;
2145 std::cerr << os.str();
2150 if (*(this->localError_)) {
2151 std::ostream& err = this->markLocalErrorAndGetStream();
2152 std::ostringstream os;
2153 os << prefix <<
"{Im/Ex}port target is already in error." << endl;
2155 std::cerr << os.str();
2164 if (importLIDs.extent(0) != numPacketsPerLID.extent(0)) {
2165 std::ostream& err = this->markLocalErrorAndGetStream();
2166 std::ostringstream os;
2167 os << prefix <<
"importLIDs.extent(0) = " << importLIDs.extent(0)
2168 <<
" != numPacketsPerLID.extent(0) = " << numPacketsPerLID.extent(0)
2171 std::cerr << os.str();
2177 if (combineMode !=
ADD && combineMode !=
INSERT &&
2179 combineMode !=
ZERO) {
2180 std::ostream& err = this->markLocalErrorAndGetStream();
2181 std::ostringstream os;
2183 <<
"Invalid CombineMode value " << combineMode <<
". Valid "
2184 <<
"values include ADD, INSERT, REPLACE, ABSMAX, and ZERO."
2187 std::cerr << os.str();
2193 if (this->graph_.getColMap().is_null()) {
2194 std::ostream& err = this->markLocalErrorAndGetStream();
2195 std::ostringstream os;
2196 os << prefix <<
"Target matrix's column Map is null." << endl;
2198 std::cerr << os.str();
2207 const map_type& tgtColMap = *(this->graph_.getColMap());
2211 const size_t numImportLIDs = importLIDs.extent(0);
2218 size_t numBytesPerValue(0);
2220 auto val_host = val_.getHostView(Access::ReadOnly);
2222 PackTraits<impl_scalar_type>::packValueCount(val_host.extent(0) ? val_host(0) :
impl_scalar_type());
2224 const size_t maxRowNumEnt = graph_.getLocalMaxNumRowEntries();
2225 const size_t maxRowNumScalarEnt = maxRowNumEnt * blockSize * blockSize;
2228 std::ostringstream os;
2229 os << prefix <<
"combineMode: "
2231 <<
", blockSize: " << blockSize
2232 <<
", numImportLIDs: " << numImportLIDs
2233 <<
", numBytesPerValue: " << numBytesPerValue
2234 <<
", maxRowNumEnt: " << maxRowNumEnt
2235 <<
", maxRowNumScalarEnt: " << maxRowNumScalarEnt << endl;
2236 std::cerr << os.str();
2239 if (combineMode ==
ZERO || numImportLIDs == 0) {
2241 std::ostringstream os;
2242 os << prefix <<
"Nothing to unpack. Done!" << std::endl;
2243 std::cerr << os.str();
2250 if (imports.need_sync_host()) {
2251 imports.sync_host();
2261 if (imports.need_sync_host() || numPacketsPerLID.need_sync_host() ||
2262 importLIDs.need_sync_host()) {
2263 std::ostream& err = this->markLocalErrorAndGetStream();
2264 std::ostringstream os;
2265 os << prefix <<
"All input DualViews must be sync'd to host by now. "
2266 <<
"imports_nc.need_sync_host()="
2267 << (imports.need_sync_host() ?
"true" :
"false")
2268 <<
", numPacketsPerLID.need_sync_host()="
2269 << (numPacketsPerLID.need_sync_host() ?
"true" :
"false")
2270 <<
", importLIDs.need_sync_host()="
2271 << (importLIDs.need_sync_host() ?
"true" :
"false")
2274 std::cerr << os.str();
2280 const auto importLIDsHost = importLIDs.view_host();
2281 const auto numPacketsPerLIDHost = numPacketsPerLID.view_host();
2287 Kokkos::View<size_t*, host_exec> offset(
"offset", numImportLIDs + 1);
2289 const auto policy = Kokkos::RangePolicy<host_exec>(
size_t(0), numImportLIDs + 1);
2290 Kokkos::parallel_scan(
"Tpetra::BlockCrsMatrix::unpackAndCombine: offsets", policy,
2291 [=](
const size_t& i,
size_t& update,
const bool&
final) {
2292 if (
final) offset(i) = update;
2293 update += (i == numImportLIDs ? 0 : numPacketsPerLIDHost(i));
2303 Kokkos::View<int, host_exec, Kokkos::MemoryTraits<Kokkos::Atomic> >
2304 errorDuringUnpack(
"errorDuringUnpack");
2305 errorDuringUnpack() = 0;
2307 using policy_type = Kokkos::TeamPolicy<host_exec>;
2308 size_t scratch_per_row =
sizeof(GO) * maxRowNumEnt +
sizeof(LO) * maxRowNumEnt + numBytesPerValue * maxRowNumScalarEnt + 2 *
sizeof(GO);
2310 const auto policy = policy_type(numImportLIDs, 1, 1)
2311 .set_scratch_size(0, Kokkos::PerTeam(scratch_per_row));
2312 using host_scratch_space =
typename host_exec::scratch_memory_space;
2314 using pair_type = Kokkos::pair<size_t, size_t>;
2319 Kokkos::parallel_for(
"Tpetra::BlockCrsMatrix::unpackAndCombine: unpack", policy,
2320 [=, *
this](
const typename policy_type::member_type& member) {
2321 const size_t i = member.league_rank();
2322 Kokkos::View<GO*, host_scratch_space> gblColInds(member.team_scratch(0), maxRowNumEnt);
2323 Kokkos::View<LO*, host_scratch_space> lclColInds(member.team_scratch(0), maxRowNumEnt);
2324 Kokkos::View<impl_scalar_type*, host_scratch_space> vals(member.team_scratch(0), maxRowNumScalarEnt);
2326 const size_t offval = offset(i);
2327 const LO lclRow = importLIDsHost(i);
2328 const size_t numBytes = numPacketsPerLIDHost(i);
2329 const size_t numEnt =
2330 unpackRowCount<impl_scalar_type, LO, GO>(imports.view_host(), offval, numBytes, numBytesPerValue);
2333 if (numEnt > maxRowNumEnt) {
2334 errorDuringUnpack() = 1;
2336 std::ostringstream os;
2338 <<
"At i = " << i <<
", numEnt = " << numEnt
2339 <<
" > maxRowNumEnt = " << maxRowNumEnt
2341 std::cerr << os.str();
2346 const size_t numScalarEnt = numEnt * blockSize * blockSize;
2347 auto gidsOut = Kokkos::subview(gblColInds, pair_type(0, numEnt));
2348 auto lidsOut = Kokkos::subview(lclColInds, pair_type(0, numEnt));
2349 auto valsOut = Kokkos::subview(vals, pair_type(0, numScalarEnt));
2354 size_t numBytesOut = 0;
2357 unpackRowForBlockCrs<impl_scalar_type, LO, GO>(Kokkos::View<GO*, host_exec>(gidsOut.data(), numEnt),
2358 Kokkos::View<impl_scalar_type*, host_exec>(valsOut.data(), numScalarEnt),
2359 imports.view_host(),
2360 offval, numBytes, numEnt,
2361 numBytesPerValue, blockSize);
2362 }
catch (std::exception& e) {
2363 errorDuringUnpack() = 1;
2365 std::ostringstream os;
2366 os << prefix <<
"At i = " << i <<
", unpackRowForBlockCrs threw: "
2367 << e.what() << endl;
2368 std::cerr << os.str();
2373 if (numBytes != numBytesOut) {
2374 errorDuringUnpack() = 1;
2376 std::ostringstream os;
2378 <<
"At i = " << i <<
", numBytes = " << numBytes
2379 <<
" != numBytesOut = " << numBytesOut <<
"."
2381 std::cerr << os.str();
2387 for (
size_t k = 0; k < numEnt; ++k) {
2389 if (lidsOut(k) == Teuchos::OrdinalTraits<LO>::invalid()) {
2391 std::ostringstream os;
2393 <<
"At i = " << i <<
", GID " << gidsOut(k)
2394 <<
" is not owned by the calling process."
2396 std::cerr << os.str();
2404 const LO*
const lidsRaw =
const_cast<const LO*
>(lidsOut.data());
2405 const Scalar*
const valsRaw =
reinterpret_cast<const Scalar*
>(
const_cast<const impl_scalar_type*
>(valsOut.data()));
2406 if (combineMode ==
ADD) {
2408 }
else if (combineMode ==
INSERT || combineMode ==
REPLACE) {
2410 }
else if (combineMode ==
ABSMAX) {
2414 if (
static_cast<LO
>(numEnt) != numCombd) {
2415 errorDuringUnpack() = 1;
2417 std::ostringstream os;
2418 os << prefix <<
"At i = " << i <<
", numEnt = " << numEnt
2419 <<
" != numCombd = " << numCombd <<
"."
2421 std::cerr << os.str();
2429 if (errorDuringUnpack() != 0) {
2430 std::ostream& err = this->markLocalErrorAndGetStream();
2431 err << prefix <<
"Unpacking failed.";
2433 err <<
" Please run again with the environment variable setting "
2434 "TPETRA_VERBOSE=1 to get more verbose diagnostic output.";
2440 std::ostringstream os;
2441 const bool lclSuccess = !(*(this->localError_));
2443 << (lclSuccess ?
"succeeded" :
"FAILED")
2445 std::cerr << os.str();
2449template <
class Scalar,
class LO,
class GO,
class Node>
2452 using Teuchos::TypeNameTraits;
2453 std::ostringstream os;
2454 os <<
"\"Tpetra::BlockCrsMatrix\": { "
2455 <<
"Template parameters: { "
2456 <<
"Scalar: " << TypeNameTraits<Scalar>::name()
2457 <<
"LO: " << TypeNameTraits<LO>::name()
2458 <<
"GO: " << TypeNameTraits<GO>::name()
2459 <<
"Node: " << TypeNameTraits<Node>::name()
2461 <<
", Label: \"" << this->getObjectLabel() <<
"\""
2462 <<
", Global dimensions: ["
2463 << graph_.getDomainMap()->getGlobalNumElements() <<
", "
2464 << graph_.getRangeMap()->getGlobalNumElements() <<
"]"
2470template <
class Scalar,
class LO,
class GO,
class Node>
2472 describe(Teuchos::FancyOStream& out,
2473 const Teuchos::EVerbosityLevel verbLevel)
const {
2474 using Teuchos::ArrayRCP;
2475 using Teuchos::CommRequest;
2476 using Teuchos::FancyOStream;
2477 using Teuchos::getFancyOStream;
2478 using Teuchos::ireceive;
2479 using Teuchos::isend;
2480 using Teuchos::outArg;
2481 using Teuchos::TypeNameTraits;
2482 using Teuchos::VERB_DEFAULT;
2483 using Teuchos::VERB_LOW;
2484 using Teuchos::VERB_MEDIUM;
2485 using Teuchos::VERB_NONE;
2489 using Teuchos::VERB_EXTREME;
2490 using Teuchos::wait;
2493 const Teuchos::EVerbosityLevel vl =
2494 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
2496 if (vl == VERB_NONE) {
2501 Teuchos::OSTab tab0(out);
2503 out <<
"\"Tpetra::BlockCrsMatrix\":" << endl;
2504 Teuchos::OSTab tab1(out);
2506 out <<
"Template parameters:" << endl;
2508 Teuchos::OSTab tab2(out);
2509 out <<
"Scalar: " << TypeNameTraits<Scalar>::name() << endl
2510 <<
"LO: " << TypeNameTraits<LO>::name() << endl
2511 <<
"GO: " << TypeNameTraits<GO>::name() << endl
2512 <<
"Node: " << TypeNameTraits<Node>::name() << endl;
2514 out <<
"Label: \"" << this->getObjectLabel() <<
"\"" << endl
2515 <<
"Global dimensions: ["
2516 << graph_.getDomainMap()->getGlobalNumElements() <<
", "
2517 << graph_.getRangeMap()->getGlobalNumElements() <<
"]" << endl;
2520 out <<
"Block size: " << blockSize << endl;
2523 if (vl >= VERB_MEDIUM) {
2524 const Teuchos::Comm<int>& comm = *(graph_.getMap()->
getComm());
2525 const int myRank = comm.getRank();
2527 out <<
"Row Map:" << endl;
2534 out <<
"Column Map: same as row Map" << endl;
2538 out <<
"Column Map:" << endl;
2546 out <<
"Domain Map: same as row Map" << endl;
2550 out <<
"Domain Map: same as column Map" << endl;
2554 out <<
"Domain Map:" << endl;
2562 out <<
"Range Map: same as domain Map" << endl;
2566 out <<
"Range Map: same as row Map" << endl;
2570 out <<
"Range Map: " << endl;
2577 if (vl >= VERB_EXTREME) {
2578 const Teuchos::Comm<int>& comm = *(graph_.getMap()->
getComm());
2579 const int myRank = comm.getRank();
2580 const int numProcs = comm.getSize();
2583 RCP<std::ostringstream> lclOutStrPtr(
new std::ostringstream());
2584 RCP<FancyOStream> osPtr = getFancyOStream(lclOutStrPtr);
2585 FancyOStream& os = *osPtr;
2586 os <<
"Process " << myRank <<
":" << endl;
2587 Teuchos::OSTab tab2(os);
2589 const map_type& meshRowMap = *(graph_.getRowMap());
2590 const map_type& meshColMap = *(graph_.getColMap());
2595 os <<
"Row " << meshGblRow <<
": {";
2597 local_inds_host_view_type lclColInds;
2598 values_host_view_type vals;
2601 numInds = lclColInds.extent(0);
2603 for (LO k = 0; k < numInds; ++k) {
2606 os <<
"Col " << gblCol <<
": [";
2607 for (LO i = 0; i < blockSize; ++i) {
2608 for (LO j = 0; j < blockSize; ++j) {
2609 os << vals[blockSize * blockSize * k + i * blockSize + j];
2610 if (j + 1 < blockSize) {
2614 if (i + 1 < blockSize) {
2619 if (k + 1 < numInds) {
2629 out << lclOutStrPtr->str();
2630 lclOutStrPtr = Teuchos::null;
2633 const int sizeTag = 1337;
2634 const int dataTag = 1338;
2636 ArrayRCP<char> recvDataBuf;
2640 for (
int p = 1; p < numProcs; ++p) {
2643 ArrayRCP<size_t> recvSize(1);
2645 RCP<CommRequest<int> > recvSizeReq =
2646 ireceive<int, size_t>(recvSize, p, sizeTag, comm);
2647 wait<int>(comm, outArg(recvSizeReq));
2648 const size_t numCharsToRecv = recvSize[0];
2655 if (
static_cast<size_t>(recvDataBuf.size()) < numCharsToRecv + 1) {
2656 recvDataBuf.resize(numCharsToRecv + 1);
2658 ArrayRCP<char> recvData = recvDataBuf.persistingView(0, numCharsToRecv);
2660 RCP<CommRequest<int> > recvDataReq =
2661 ireceive<int, char>(recvData, p, dataTag, comm);
2662 wait<int>(comm, outArg(recvDataReq));
2667 recvDataBuf[numCharsToRecv] =
'\0';
2668 out << recvDataBuf.getRawPtr();
2669 }
else if (myRank == p) {
2673 const std::string stringToSend = lclOutStrPtr->str();
2674 lclOutStrPtr = Teuchos::null;
2677 const size_t numCharsToSend = stringToSend.size();
2678 ArrayRCP<size_t> sendSize(1);
2679 sendSize[0] = numCharsToSend;
2680 RCP<CommRequest<int> > sendSizeReq =
2681 isend<int, size_t>(sendSize, 0, sizeTag, comm);
2682 wait<int>(comm, outArg(sendSizeReq));
2690 ArrayRCP<const char> sendData(&stringToSend[0], 0, numCharsToSend,
false);
2691 RCP<CommRequest<int> > sendDataReq =
2692 isend<int, char>(sendData, 0, dataTag, comm);
2693 wait<int>(comm, outArg(sendDataReq));
2699template <
class Scalar,
class LO,
class GO,
class Node>
2700Teuchos::RCP<const Teuchos::Comm<int> >
2703 return graph_.getComm();
2706template <
class Scalar,
class LO,
class GO,
class Node>
2710 return graph_.getGlobalNumCols();
2713template <
class Scalar,
class LO,
class GO,
class Node>
2717 return graph_.getLocalNumCols();
2720template <
class Scalar,
class LO,
class GO,
class Node>
2723 return graph_.getIndexBase();
2726template <
class Scalar,
class LO,
class GO,
class Node>
2730 return graph_.getGlobalNumEntries();
2733template <
class Scalar,
class LO,
class GO,
class Node>
2737 return graph_.getLocalNumEntries();
2740template <
class Scalar,
class LO,
class GO,
class Node>
2744 return graph_.getNumEntriesInGlobalRow(globalRow);
2747template <
class Scalar,
class LO,
class GO,
class Node>
2751 return graph_.getGlobalMaxNumRowEntries();
2754template <
class Scalar,
class LO,
class GO,
class Node>
2757 return graph_.hasColMap();
2760template <
class Scalar,
class LO,
class GO,
class Node>
2763 return graph_.isLocallyIndexed();
2766template <
class Scalar,
class LO,
class GO,
class Node>
2769 return graph_.isGloballyIndexed();
2772template <
class Scalar,
class LO,
class GO,
class Node>
2775 return graph_.isFillComplete();
2778template <
class Scalar,
class LO,
class GO,
class Node>
2784template <
class Scalar,
class LO,
class GO,
class Node>
2787 nonconst_global_inds_host_view_type& ,
2788 nonconst_values_host_view_type& ,
2790 TEUCHOS_TEST_FOR_EXCEPTION(
2791 true, std::logic_error,
2792 "Tpetra::BlockCrsMatrix::getGlobalRowCopy: "
2793 "This class doesn't support global matrix indexing.");
2796template <
class Scalar,
class LO,
class GO,
class Node>
2799 global_inds_host_view_type& ,
2800 values_host_view_type& )
const {
2801 TEUCHOS_TEST_FOR_EXCEPTION(
2802 true, std::logic_error,
2803 "Tpetra::BlockCrsMatrix::getGlobalRowView: "
2804 "This class doesn't support global matrix indexing.");
2807template <
class Scalar,
class LO,
class GO,
class Node>
2810 local_inds_host_view_type& colInds,
2811 values_host_view_type& vals)
const {
2812 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
2813 colInds = local_inds_host_view_type();
2814 vals = values_host_view_type();
2816 const size_t absBlockOffsetStart = ptrHost_[localRowInd];
2817 const size_t numInds = ptrHost_[localRowInd + 1] - absBlockOffsetStart;
2818 colInds = local_inds_host_view_type(indHost_.data() + absBlockOffsetStart, numInds);
2820 vals = getValuesHost(localRowInd);
2824template <
class Scalar,
class LO,
class GO,
class Node>
2827 local_inds_host_view_type& colInds,
2828 nonconst_values_host_view_type& vals)
const {
2829 if (!rowMeshMap_.isNodeLocalElement(localRowInd)) {
2830 colInds = nonconst_local_inds_host_view_type();
2831 vals = nonconst_values_host_view_type();
2833 const size_t absBlockOffsetStart = ptrHost_[localRowInd];
2834 const size_t numInds = ptrHost_[localRowInd + 1] - absBlockOffsetStart;
2835 colInds = local_inds_host_view_type(indHost_.data() + absBlockOffsetStart, numInds);
2838 vals =
const_cast<this_BCRS_type&
>(*this).getValuesHostNonConst(localRowInd);
2842template <
class Scalar,
class LO,
class GO,
class Node>
2845 const size_t lclNumMeshRows = graph_.getLocalNumRows();
2847 Kokkos::View<size_t*, device_type> diagOffsets(
"diagOffsets", lclNumMeshRows);
2848 graph_.getLocalDiagOffsets(diagOffsets);
2851 auto diagOffsetsHost = Kokkos::create_mirror_view(diagOffsets);
2855 auto vals_host_out = val_.getHostView(Access::ReadOnly);
2859 size_t rowOffset = 0;
2865 offset = rowOffset + diagOffsetsHost(r) * bs * bs;
2866 for (
int b = 0; b < bs; b++) {
2876template <
class Scalar,
class LO,
class GO,
class Node>
2878 leftScale(const ::Tpetra::Vector<Scalar, LO, GO, Node>& ) {
2879 TEUCHOS_TEST_FOR_EXCEPTION(
2880 true, std::logic_error,
2881 "Tpetra::BlockCrsMatrix::leftScale: "
2882 "not implemented.");
2885template <
class Scalar,
class LO,
class GO,
class Node>
2887 rightScale(const ::Tpetra::Vector<Scalar, LO, GO, Node>& ) {
2888 TEUCHOS_TEST_FOR_EXCEPTION(
2889 true, std::logic_error,
2890 "Tpetra::BlockCrsMatrix::rightScale: "
2891 "not implemented.");
2894template <
class Scalar,
class LO,
class GO,
class Node>
2895Teuchos::RCP<const ::Tpetra::RowGraph<LO, GO, Node> >
2901template <
class Scalar,
class LO,
class GO,
class Node>
2902typename ::Tpetra::RowMatrix<Scalar, LO, GO, Node>::mag_type
2905 TEUCHOS_TEST_FOR_EXCEPTION(
2906 true, std::logic_error,
2907 "Tpetra::BlockCrsMatrix::getFrobeniusNorm: "
2908 "not implemented.");
2918#define TPETRA_BLOCKCRSMATRIX_INSTANT(S, LO, GO, NODE) \
2919 template class BlockCrsMatrix<S, LO, GO, NODE>;
Linear algebra kernels for small dense matrices and vectors.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
Sparse matrix whose entries are small dense square blocks, all of the same dimensions.
LO sumIntoLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Sum into values at the given (mesh, i.e., block) column indices, in the given (mesh,...
virtual LO getBlockSize() const override
The number of degrees of freedom per mesh point.
void exportAndFillComplete(Teuchos::RCP< BlockCrsMatrix< Scalar, LO, GO, Node > > &destMatrix, const Export< LO, GO, Node > &exporter) const
Import from this to the given destination matrix, and make the result fill complete.
virtual bool isLocallyIndexed() const override
Whether matrix indices are locally indexed.
virtual bool isFillComplete() const override
Whether fillComplete() has been called.
virtual size_t getGlobalMaxNumRowEntries() const override
The maximum number of entries in any row over all processes in the matrix's communicator.
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.
LO replaceLocalValuesByOffsets(const LO localRowInd, const ptrdiff_t offsets[], const Scalar vals[], const LO numOffsets) const
Like replaceLocalValues, but avoids computing row offsets.
virtual void getLocalRowCopy(LO LocalRow, nonconst_local_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const override
Not implemented.
std::string errorMessages() const
The current stream of error messages.
LO absMaxLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Variant of getLocalDiagCopy() that uses precomputed offsets and puts diagonal blocks in a 3-D Kokkos:...
Scalar scalar_type
The type of entries in the matrix (that is, of each entry in each block).
virtual void getGlobalRowView(GO GlobalRow, global_inds_host_view_type &indices, values_host_view_type &values) const override
Get a constant, nonpersisting, globally indexed view of the given row of the matrix.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Print a description of this object to the given output stream.
size_t getLocalMaxNumRowEntries() const override
Maximum number of entries in any row of the matrix, on this process.
LO local_ordinal_type
The type of local indices.
virtual void getGlobalRowCopy(GO GlobalRow, nonconst_global_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const override
Get a copy of the given global row's entries.
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.
virtual size_t getLocalNumCols() const override
The number of columns needed to apply the forward operator on this node.
virtual void copyAndPermute(const SrcDistObject &sourceObj, const size_t numSameIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteToLIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteFromLIDs, const CombineMode CM) override
::Tpetra::MultiVector< Scalar, LO, GO, node_type > mv_type
The implementation of MultiVector that this class uses.
Teuchos::RCP< const map_type > getRangeMap() const override
Get the (point) range Map of this matrix.
LO sumIntoLocalValuesByOffsets(const LO localRowInd, const ptrdiff_t offsets[], const Scalar vals[], const LO numOffsets) const
Like sumIntoLocalValues, but avoids computing row offsets.
virtual bool hasColMap() const override
Whether this matrix has a well-defined column Map.
device_type::execution_space execution_space
The Kokkos execution space that this class uses.
size_t getLocalNumRows() const override
get the local number of block rows
virtual size_t getLocalNumEntries() const override
The local number of stored (structurally nonzero) entries.
impl_scalar_type_dualview::t_host getValuesHostNonConst() const
Get the host or device View of the matrix's values (val_).
Kokkos::View< impl_scalar_type **, Impl::BlockCrsMatrixLittleBlockArrayLayout, device_type, Kokkos::MemoryTraits< Kokkos::Unmanaged > > little_block_type
The type used to access nonconst matrix blocks.
Teuchos::RCP< const map_type > getColMap() const override
get the (mesh) map for the columns of this block matrix.
virtual typename::Tpetra::RowMatrix< Scalar, LO, GO, Node >::mag_type getFrobeniusNorm() const override
The Frobenius norm of the matrix.
virtual void unpackAndCombine(const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &importLIDs, Kokkos::DualView< packet_type *, buffer_device_type > imports, Kokkos::DualView< size_t *, buffer_device_type > numPacketsPerLID, const size_t constantNumPackets, const CombineMode combineMode) override
local_matrix_device_type getLocalMatrixDevice() const
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 override
For this matrix A, compute Y := beta * Y + alpha * Op(A) * X.
virtual global_size_t getGlobalNumCols() const override
The global number of columns of this matrix.
void getLocalDiagOffsets(const Kokkos::View< size_t *, device_type, Kokkos::MemoryUnmanaged > &offsets) const
Get offsets of the diagonal entries in the matrix.
Teuchos::RCP< const map_type > getRowMap() const override
get the (mesh) map for the rows of this block matrix.
std::string description() const override
One-line description of this object.
void importAndFillComplete(Teuchos::RCP< BlockCrsMatrix< Scalar, LO, GO, Node > > &destMatrix, const Import< LO, GO, Node > &importer) const
Import from this to the given destination matrix, and make the result fill complete.
void getLocalRowView(LO LocalRow, local_inds_host_view_type &indices, values_host_view_type &values) const override
Get a view of the (mesh, i.e., block) row, using local (mesh, i.e., block) indices.
void getLocalDiagCopy(const Kokkos::View< impl_scalar_type ***, device_type, Kokkos::MemoryUnmanaged > &diag, const Kokkos::View< const size_t *, device_type, Kokkos::MemoryUnmanaged > &offsets) const
Variant of getLocalDiagCopy() that uses precomputed offsets and puts diagonal blocks in a 3-D Kokkos:...
size_t getNumEntriesInLocalRow(const LO localRowInd) const override
Return the number of entries in the given row on the calling process.
virtual bool supportsRowViews() const override
Whether this object implements getLocalRowView() and getGlobalRowView().
virtual Teuchos::RCP< const ::Tpetra::RowGraph< LO, GO, Node > > getGraph() const override
Get the (mesh) graph.
LO replaceLocalValues(const LO localRowInd, const LO colInds[], const Scalar vals[], const LO numColInds) const
Replace values at the given (mesh, i.e., block) column indices, in the given (mesh,...
virtual size_t getNumEntriesInGlobalRow(GO globalRow) const override
The current number of entries on the calling process in the specified global row.
typename DistObject< Scalar, LO, GO, Node >::buffer_device_type buffer_device_type
Kokkos::Device specialization for communication buffers.
Node::device_type device_type
The Kokkos::Device specialization that this class uses.
void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to alpha.
Kokkos::View< const impl_scalar_type **, Impl::BlockCrsMatrixLittleBlockArrayLayout, device_type, Kokkos::MemoryTraits< Kokkos::Unmanaged > > const_little_block_type
The type used to access const matrix blocks.
void getLocalRowViewNonConst(LO LocalRow, local_inds_host_view_type &indices, nonconst_values_host_view_type &values) const
char packet_type
Implementation detail; tells.
virtual void packAndPrepare(const SrcDistObject &sourceObj, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &exportLIDs, Kokkos::DualView< packet_type *, buffer_device_type > &exports, Kokkos::DualView< size_t *, buffer_device_type > numPacketsPerLID, size_t &constantNumPackets) override
::Tpetra::Map< LO, GO, node_type > map_type
The implementation of Map that this class uses.
virtual void rightScale(const ::Tpetra::Vector< Scalar, LO, GO, Node > &x) override
Scale the RowMatrix on the right with the given Vector x.
virtual GO getIndexBase() const override
The index base for global indices in this matrix.
virtual global_size_t getGlobalNumEntries() const override
The global number of stored (structurally nonzero) entries.
typename BMV::impl_scalar_type impl_scalar_type
The implementation type of entries in the matrix.
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
The communicator over which this matrix is distributed.
::Tpetra::CrsGraph< LO, GO, node_type > crs_graph_type
The implementation of CrsGraph that this class uses.
global_size_t getGlobalNumRows() const override
get the global number of block rows
virtual void leftScale(const ::Tpetra::Vector< Scalar, LO, GO, Node > &x) override
Scale the RowMatrix on the left with the given Vector x.
Teuchos::RCP< const map_type > getDomainMap() const override
Get the (point) domain Map of this matrix.
virtual bool isGloballyIndexed() const override
Whether matrix indices are globally indexed.
BlockCrsMatrix()
Default constructor: Makes an empty block matrix.
MultiVector for multiple degrees of freedom per mesh point.
const mv_type & getMultiVectorView() const
Get a Tpetra::MultiVector that views this BlockMultiVector's data.
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.
Tpetra::Map< LO, GO, Node > map_type
The specialization of Tpetra::Map that this class uses.
LO getBlockSize() const
Get the number of degrees of freedom per mesh point.
size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const override
Get the number of entries in the given row (local index).
Teuchos::RCP< const map_type > getColMap() const override
Returns the Map that describes the column distribution in this graph.
::Tpetra::Import< LO, GO, node_type > import_type
KokkosSparse::StaticCrsGraph< local_ordinal_type, Kokkos::LayoutLeft, device_type, void, size_t > local_graph_device_type
Teuchos::RCP< const map_type > getDomainMap() const override
Returns the Map associated with the domain of this graph.
Teuchos::RCP< const map_type > getRangeMap() const override
Returns the Map associated with the domain of this graph.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
Description of Tpetra's behavior.
virtual Teuchos::RCP< const map_type > getMap() const
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...
global_ordinal_type getGlobalElement(local_ordinal_type localIndex) const
The global index corresponding to the given local index.
bool isNodeLocalElement(local_ordinal_type localIndex) const
Whether the given local index is valid for this Map on the calling process.
bool locallySameAs(const Map< local_ordinal_type, global_ordinal_type, node_type > &map) const
Is this Map locally the same as the input Map?
local_ordinal_type getLocalElement(global_ordinal_type globalIndex) const
The local index corresponding to the given global index.
local_ordinal_type getMinLocalIndex() const
The minimum local index.
local_ordinal_type getMaxLocalIndex() const
The maximum local index on the calling process.
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...
bool isConstantStride() const
Whether this multivector has constant stride between columns.
A distributed dense vector.
void replaceLocalValue(const LocalOrdinal myRow, const Scalar &value)
Replace current value at the specified location with specified values.
void disableWDVTracking()
Disable WrappedDualView reference-count tracking and syncing. Call this before entering a host-parall...
void enableWDVTracking()
Enable WrappedDualView reference-count tracking and syncing. Call this after exiting a host-parallel ...
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
Namespace for new Tpetra features that are not ready for public release, but are ready for evaluation...
Kokkos::LayoutRight BlockCrsMatrixLittleBlockArrayLayout
give an option to use layoutleft
KOKKOS_INLINE_FUNCTION void absMax(const ViewType2 &Y, const ViewType1 &X)
Implementation of Tpetra's ABSMAX CombineMode for the small dense blocks in BlockCrsMatrix,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::RCP< CrsGraphType > exportAndFillCompleteCrsGraph(const Teuchos::RCP< const CrsGraphType > &sourceGraph, const Export< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > &exporter, const Teuchos::RCP< const Map< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > > &domainMap=Teuchos::null, const Teuchos::RCP< const Map< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > > &rangeMap=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Nonmember CrsGraph constructor that fuses Export and fillComplete().
KOKKOS_INLINE_FUNCTION void AXPY(const CoefficientType &alpha, const ViewType1 &x, const ViewType2 &y)
y := y + alpha * x (dense vector or matrix update)
Teuchos::RCP< CrsGraphType > importAndFillCompleteCrsGraph(const Teuchos::RCP< const CrsGraphType > &sourceGraph, const Import< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > &importer, const Teuchos::RCP< const Map< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > > &domainMap=Teuchos::null, const Teuchos::RCP< const Map< typename CrsGraphType::local_ordinal_type, typename CrsGraphType::global_ordinal_type, typename CrsGraphType::node_type > > &rangeMap=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Nonmember CrsGraph constructor that fuses Import and fillComplete().
size_t global_size_t
Global size_t object.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
KOKKOS_INLINE_FUNCTION void COPY(const ViewType1 &x, const ViewType2 &y)
Deep copy x into y, where x and y are either rank 1 (vectors) or rank 2 (matrices) with the same dime...
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.
@ INSERT
Insert new values that don't currently exist.
@ ZERO
Replace old values with zero.
Traits class for packing / unpacking data of type T.