42 #ifndef TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP 43 #define TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP 45 #include "Tpetra_Experimental_BlockMultiVector_decl.hpp" 60 template<
class MultiVectorType>
61 struct RawPtrFromMultiVector {
62 typedef typename MultiVectorType::impl_scalar_type impl_scalar_type;
64 static impl_scalar_type* getRawPtr (MultiVectorType& X) {
65 typedef typename MultiVectorType::dual_view_type dual_view_type;
66 typedef typename dual_view_type::t_host::memory_space host_memory_space;
71 X.template modify<host_memory_space> ();
73 dual_view_type X_view = X.getDualView ();
74 impl_scalar_type* X_raw = X_view.h_view.ptr_on_device ();
91 template<
class S,
class LO,
class GO,
class N>
95 return RawPtrFromMultiVector<MV>::getRawPtr (X);
101 namespace Experimental {
103 template<
class Scalar,
class LO,
class GO,
class Node>
104 typename BlockMultiVector<Scalar, LO, GO, Node>::mv_type
105 BlockMultiVector<Scalar, LO, GO, Node>::
106 getMultiVectorView ()
109 mv_.setCopyOrView (Teuchos::View);
115 template<
class Scalar,
class LO,
class GO,
class Node>
116 Teuchos::RCP<const BlockMultiVector<Scalar, LO, GO, Node> >
121 const BMV* src_bmv =
dynamic_cast<const BMV*
> (&src);
122 TEUCHOS_TEST_FOR_EXCEPTION(
123 src_bmv == NULL, std::invalid_argument,
"Tpetra::Experimental::" 124 "BlockMultiVector: The source object of an Import or Export to a " 125 "BlockMultiVector, must also be a BlockMultiVector.");
126 return Teuchos::rcp (src_bmv,
false);
129 template<
class Scalar,
class LO,
class GO,
class Node>
136 pointMap_ (makePointMap (meshMap, blockSize)),
137 mv_ (
Teuchos::rcpFromRef (pointMap_), numVecs),
138 mvData_ (getRawPtrFromMultiVector (mv_)),
139 blockSize_ (blockSize)
145 template<
class Scalar,
class LO,
class GO,
class Node>
153 pointMap_ (pointMap),
154 mv_ (
Teuchos::rcpFromRef (pointMap_), numVecs),
155 mvData_ (getRawPtrFromMultiVector (
mv_)),
156 blockSize_ (blockSize)
162 template<
class Scalar,
class LO,
class GO,
class Node>
166 const LO blockSize) :
170 blockSize_ (blockSize)
186 RCP<const mv_type> X_view_const;
189 Teuchos::Array<size_t> cols (0);
190 X_view_const = X_mv.
subView (cols ());
192 X_view_const = X_mv.
subView (Teuchos::Range1D (0, numCols-1));
194 TEUCHOS_TEST_FOR_EXCEPTION(
195 X_view_const.is_null (), std::logic_error,
"Tpetra::Experimental::" 196 "BlockMultiVector constructor: X_mv.subView(...) returned null. This " 197 "should never happen. Please report this bug to the Tpetra developers.");
202 RCP<mv_type> X_view = Teuchos::rcp_const_cast<
mv_type> (X_view_const);
204 TEUCHOS_TEST_FOR_EXCEPTION(
205 X_view->getCopyOrView () != Teuchos::View, std::logic_error,
"Tpetra::" 206 "Experimental::BlockMultiVector constructor: We just set a MultiVector " 207 "to have view semantics, but it claims that it doesn't have view " 208 "semantics. This should never happen. " 209 "Please report this bug to the Tpetra developers.");
214 Teuchos::RCP<const map_type> pointMap =
mv_.
getMap ();
215 if (! pointMap.is_null ()) {
216 pointMap_ = *pointMap;
218 mvData_ = getRawPtrFromMultiVector (
mv_);
221 template<
class Scalar,
class LO,
class GO,
class Node>
232 template<
class Scalar,
class LO,
class GO,
class Node>
238 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
240 const GST gblNumMeshMapInds =
242 const size_t lclNumMeshMapIndices =
244 const GST gblNumPointMapInds =
245 gblNumMeshMapInds *
static_cast<GST
> (blockSize);
246 const size_t lclNumPointMapInds =
247 lclNumMeshMapIndices *
static_cast<size_t> (blockSize);
251 return map_type (gblNumPointMapInds, lclNumPointMapInds, indexBase,
259 const size_type lclNumMeshGblInds = lclMeshGblInds.size ();
260 Teuchos::Array<GO> lclPointGblInds (lclNumPointMapInds);
261 for (size_type g = 0; g < lclNumMeshGblInds; ++g) {
262 const GO meshGid = lclMeshGblInds[g];
263 const GO pointGidStart = indexBase +
264 (meshGid - indexBase) * static_cast<GO> (blockSize);
265 const size_type offset = g *
static_cast<size_type
> (blockSize);
266 for (LO k = 0; k < blockSize; ++k) {
267 const GO pointGid = pointGidStart +
static_cast<GO
> (k);
268 lclPointGblInds[offset +
static_cast<size_type
> (k)] = pointGid;
271 return map_type (gblNumPointMapInds, lclPointGblInds (), indexBase,
277 template<
class Scalar,
class LO,
class GO,
class Node>
282 const Scalar vals[])
const 285 const LO strideX = 1;
292 template<
class Scalar,
class LO,
class GO,
class Node>
297 const Scalar vals[])
const 302 replaceLocalValuesImpl (localRowIndex, colIndex, vals);
307 template<
class Scalar,
class LO,
class GO,
class Node>
312 const Scalar vals[])
const 315 if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
318 replaceLocalValuesImpl (localRowIndex, colIndex, vals);
323 template<
class Scalar,
class LO,
class GO,
class Node>
328 const Scalar vals[])
const 331 const LO strideX = 1;
334 X_dst.
update (STS::one (), X_src);
337 template<
class Scalar,
class LO,
class GO,
class Node>
342 const Scalar vals[])
const 347 sumIntoLocalValuesImpl (localRowIndex, colIndex, vals);
352 template<
class Scalar,
class LO,
class GO,
class Node>
357 const Scalar vals[])
const 360 if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
363 sumIntoLocalValuesImpl (localRowIndex, colIndex, vals);
368 template<
class Scalar,
class LO,
class GO,
class Node>
377 vals =
reinterpret_cast<Scalar*
> (X_ij.
getRawPtr ());
382 template<
class Scalar,
class LO,
class GO,
class Node>
388 if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
392 vals =
reinterpret_cast<Scalar*
> (X_ij.
getRawPtr ());
397 template<
class Scalar,
class LO,
class GO,
class Node>
401 const LO colIndex)
const 408 const size_t offset = colIndex * this->
getStrideY () +
409 localRowIndex * blockSize * strideX;
410 impl_scalar_type* blockRaw = this->
getRawPtr () + offset;
415 template<
class Scalar,
class LO,
class GO,
class Node>
416 Teuchos::RCP<const typename BlockMultiVector<Scalar, LO, GO, Node>::mv_type>
421 using Teuchos::rcpFromRef;
428 const this_type* srcBlkVec =
dynamic_cast<const this_type*
> (&src);
429 if (srcBlkVec == NULL) {
431 if (srcMultiVec == NULL) {
437 return rcp (srcMultiVec,
false);
440 return rcpFromRef (srcBlkVec->mv_);
444 template<
class Scalar,
class LO,
class GO,
class Node>
448 return ! getMultiVectorFromSrcDistObject (src).is_null ();
451 template<
class Scalar,
class LO,
class GO,
class Node>
455 const Teuchos::ArrayView<const LO>& permuteToLIDs,
456 const Teuchos::ArrayView<const LO>& permuteFromLIDs)
458 const char tfecfFuncName[] =
"copyAndPermute: ";
459 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
460 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
461 "permuteToLIDs and permuteFromLIDs must have the same size." 462 << std::endl <<
"permuteToLIDs.size() = " << permuteToLIDs.size ()
463 <<
" != permuteFromLIDs.size() = " << permuteFromLIDs.size () <<
".");
466 Teuchos::RCP<const BMV> srcAsBmvPtr = getBlockMultiVectorFromSrcDistObject (src);
467 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
468 srcAsBmvPtr.is_null (), std::invalid_argument,
469 "The source of an Import or Export to a BlockMultiVector " 470 "must also be a BlockMultiVector.");
471 const BMV& srcAsBmv = *srcAsBmvPtr;
477 const LO numSame =
static_cast<LO
> (numSameIDs);
478 for (LO j = 0; j < numVecs; ++j) {
479 for (LO lclRow = 0; lclRow < numSame; ++lclRow) {
487 const LO numPermuteLIDs =
static_cast<LO
> (permuteToLIDs.size ());
488 for (LO j = 0; j < numVecs; ++j) {
489 for (LO k = numSame; k < numPermuteLIDs; ++k) {
490 getLocalBlock (permuteToLIDs[k], j).
assign (srcAsBmv.getLocalBlock (permuteFromLIDs[k], j));
495 template<
class Scalar,
class LO,
class GO,
class Node>
498 const Teuchos::ArrayView<const LO>& exportLIDs,
499 Teuchos::Array<impl_scalar_type>& exports,
500 const Teuchos::ArrayView<size_t>& ,
501 size_t& constantNumPackets,
505 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
506 const char tfecfFuncName[] =
"packAndPrepare: ";
508 Teuchos::RCP<const BMV> srcAsBmvPtr = getBlockMultiVectorFromSrcDistObject (src);
509 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
510 srcAsBmvPtr.is_null (), std::invalid_argument,
511 "The source of an Import or Export to a BlockMultiVector " 512 "must also be a BlockMultiVector.");
513 const BMV& srcAsBmv = *srcAsBmvPtr;
522 static_cast<size_t> (blockSize) * static_cast<size_t> (numVecs);
523 const size_type numMeshLIDs = exportLIDs.size ();
525 const size_type requiredExportsSize = numMeshLIDs *
526 static_cast<size_type
> (blockSize) * static_cast<size_type> (numVecs);
527 exports.resize (requiredExportsSize);
530 size_type curExportPos = 0;
531 for (size_type meshLidIndex = 0; meshLidIndex < numMeshLIDs; ++meshLidIndex) {
532 for (LO j = 0; j < numVecs; ++j, curExportPos += blockSize) {
533 const LO meshLid = exportLIDs[meshLidIndex];
534 impl_scalar_type*
const curExportPtr = &exports[curExportPos];
541 }
catch (std::exception& e) {
542 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
543 true, std::logic_error,
"Oh no! packAndPrepare on Process " 544 << meshMap_.
getComm ()->getRank () <<
" raised the following exception: " 549 template<
class Scalar,
class LO,
class GO,
class Node>
552 const Teuchos::ArrayView<const impl_scalar_type>& imports,
553 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
554 size_t constantNumPackets,
558 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
559 const char tfecfFuncName[] =
"unpackAndCombine: ";
561 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
563 std::invalid_argument,
"Invalid CombineMode: " << CM <<
". Valid " 564 "CombineMode values are ADD, REPLACE, INSERT, ABSMAX, and ZERO.");
572 const size_type numMeshLIDs = importLIDs.size ();
576 const size_type requiredImportsSize = numMeshLIDs *
577 static_cast<size_type
> (blockSize) * static_cast<size_type> (numVecs);
578 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
579 imports.size () < requiredImportsSize, std::logic_error,
580 ": imports.size () = " << imports.size ()
581 <<
" < requiredImportsSize = " << requiredImportsSize <<
".");
583 size_type curImportPos = 0;
584 for (size_type meshLidIndex = 0; meshLidIndex < numMeshLIDs; ++meshLidIndex) {
585 for (LO j = 0; j < numVecs; ++j, curImportPos += blockSize) {
586 const LO meshLid = importLIDs[meshLidIndex];
587 const impl_scalar_type*
const curImportPtr = &imports[curImportPos];
594 }
else if (CM ==
ADD) {
595 X_dst.
update (STS::one (), X_src);
596 }
else if (CM ==
ABSMAX) {
603 template<
class Scalar,
class LO,
class GO,
class Node>
610 template<
class Scalar,
class LO,
class GO,
class Node>
625 #define TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_INSTANT(S,LO,GO,NODE) \ 626 template class Experimental::BlockMultiVector< S, LO, GO, NODE >; 628 #endif // TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
mv_type mv_
The Tpetra::MultiVector used to represent the data.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
void putScalar(const Scalar &val)
Fill all entries with the given value val.
mv_type getMultiVectorView()
Get a Tpetra::MultiVector that views this BlockMultiVector's data.
Tpetra::Map< LO, GO, Node > map_type
The specialization of Tpetra::Map that this class uses.
bool replaceGlobalValues(const GO globalRowIndex, const LO colIndex, const Scalar vals[]) const
Replace all values at the given mesh point, using a global index.
void setCopyOrView(const Teuchos::DataAccess copyOrView)
Set whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
One or more distributed dense vectors.
bool sumIntoGlobalValues(const GO globalRowIndex, const LO colIndex, const Scalar vals[]) const
Sum into all values at the given mesh point, using a global index.
MultiVector for multiple degrees of freedom per mesh point.
GlobalOrdinal getIndexBase() const
The index base for this Map.
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 Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
virtual void unpackAndCombine(const Teuchos::ArrayView< const LO > &importLIDs, const Teuchos::ArrayView< const impl_scalar_type > &imports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t constantNumPackets, Tpetra::Distributor &distor, Tpetra::CombineMode CM)
Perform any unpacking and combining after communication.
void assign(const LittleVectorType &X) const
*this := X.
void scale(const Scalar &val)
Multiply all entries in place by the given value val.
little_vec_type getLocalBlock(const LO localRowIndex, const LO colIndex) const
Get a view of the degrees of freedom at the given mesh point.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
LO getBlockSize() const
Get the number of degrees of freedom per mesh point.
size_t global_size_t
Global size_t object.
Insert new values that don't currently exist.
impl_scalar_type * getRawPtr() const
Raw pointer to the MultiVector's data.
Scalar * getRawPtr() const
Pointer to the block's entries.
Nonowning view of a set of degrees of freedom corresponding to a mesh point in a block vector or mult...
LO getNumVectors() const
Get the number of columns (vectors) in the BlockMultiVector.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
Teuchos::RCP< Node > getNode() const
Get this Map's Node object.
bool getLocalRowView(const LO localRowIndex, const LO colIndex, Scalar *&vals) const
Get a writeable view of the entries at the given mesh point, using a local index. ...
Replace old value with maximum of magnitudes of old and new values.
Abstract base class for objects that can be the source of an Import or Export operation.
bool isValidLocalMeshIndex(const LO meshLocalIndex) const
True if and only if meshLocalIndex is a valid local index in the mesh Map.
Replace existing values with new values.
Replace old values with zero.
Teuchos::DataAccess getCopyOrView() const
Get whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
virtual bool checkSizes(const Tpetra::SrcDistObject &source)
Compare the source and target (this) objects for compatibility.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
LittleVector< impl_scalar_type, LO > little_vec_type
"Block view" of all degrees of freedom at a mesh point, for a single column of the MultiVector...
size_t getStrideY() const
Stride between consecutive local entries in the same row.
BlockMultiVector()
Default constructor.
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.
void update(const Scalar &alpha, const LittleVectorType &X) const
*this := *this + alpha * X.
size_t getNumVectors() const
Number of columns in the multivector.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
void absmax(const LittleVectorType &X) const
(*this)(i,j) := max(abs((*this)(i,j)), abs(X(i,j))) for all (i,j).
bool replaceLocalValues(const LO localRowIndex, const LO colIndex, const Scalar vals[]) const
Replace all values at the given mesh point, using local row and column indices.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > subView(const Teuchos::Range1D &colRng) const
Return a const MultiVector with const views of selected columns.
size_t getStrideX() const
Stride between consecutive local entries in the same column.
virtual void packAndPrepare(const Tpetra::SrcDistObject &source, const Teuchos::ArrayView< const LO > &exportLIDs, Teuchos::Array< impl_scalar_type > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, Tpetra::Distributor &distor)
Perform any packing or preparation required for communication.
bool sumIntoLocalValues(const LO localRowIndex, const LO colIndex, const Scalar vals[]) const
Sum into all values at the given mesh point, using a local index.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
bool getGlobalRowView(const GO globalRowIndex, const LO colIndex, Scalar *&vals) const
Get a writeable view of the entries at the given mesh point, using a global index.