12#ifndef XPETRA_STRIDEDMAP_DEF_HPP
13#define XPETRA_STRIDEDMAP_DEF_HPP
15#include "Xpetra_StridedMap.hpp"
20#include "Xpetra_MapFactory.hpp"
24template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
28 GlobalOrdinal indexBase,
29 std::vector<size_t>& stridingInfo,
31 LocalOrdinal stridedBlockId,
34 : stridingInfo_(stridingInfo)
35 , stridedBlockId_(stridedBlockId)
37 , indexBase_(indexBase) {
44 "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
47 std::invalid_argument,
48 "StridedMap::StridedMap: numGlobalElements is invalid");
52 "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize "
53 "is not an integer multiple of numGlobalElements.");
55 if (stridedBlockId != -1) {
58 "StridedTpetraMap::StridedTpetraMap: "
59 "stridedBlockId > stridingInfo.size()");
63 if (blkSize != 1 ||
offset_ != 0) {
68 RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, indexBase, comm, lg);
72 size_t nStridedOffset = 0;
73 size_t nDofsPerNode = blkSize;
74 if (stridedBlockId > -1) {
75 for (
int j = 0; j < stridedBlockId; j++) {
80 numGlobalElements = numGlobalNodes * Teuchos::as<global_size_t>(nDofsPerNode);
82 size_t numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
84 std::vector<GlobalOrdinal> dofgids(numLocalElements);
85 for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
86 GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
88 for (
size_t j = 0; j < nDofsPerNode; j++) {
89 dofgids[i * nDofsPerNode + j] =
indexBase_ +
offset_ + (nodeGID -
indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
93 map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
95 if (stridedBlockId == -1) {
98 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
102 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
104 size_t nDofsInStridedBlock = stridingInfo[stridedBlockId];
107 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
111 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
114 map_ = MapFactory_t::Build(xlib, numGlobalElements, indexBase, comm, lg);
120template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
124 size_t numLocalElements,
125 GlobalOrdinal indexBase,
126 std::vector<size_t>& stridingInfo,
128 LocalOrdinal stridedBlockId,
129 GlobalOrdinal offset)
130 : stridingInfo_(stridingInfo)
131 , stridedBlockId_(stridedBlockId)
133 , indexBase_(indexBase) {
139 "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
143 "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
144 "multiple of numGlobalElements.");
145#ifdef HAVE_XPETRA_DEBUG
148 Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, Teuchos::as<global_size_t>(numLocalElements), Teuchos::outArg(sumLocalElements));
151 std::invalid_argument,
152 "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
153 "number of global elements.");
158 numLocalElements % blkSize != 0,
160 "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
162 if (stridedBlockId != -1) {
165 "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
169 if (blkSize != 1 ||
offset_ != 0) {
173 numGlobalNodes = numGlobalElements / blkSize;
178 RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, numLocalNodes, indexBase, comm);
181 size_t nStridedOffset = 0;
182 size_t nDofsPerNode = blkSize;
183 if (stridedBlockId > -1) {
184 for (
int j = 0; j < stridedBlockId; j++) {
189 numGlobalElements = nodeMap->getGlobalNumElements() * Teuchos::as<global_size_t>(nDofsPerNode);
191 numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
193 std::vector<GlobalOrdinal> dofgids(numLocalElements);
194 for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
195 GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
197 for (
size_t j = 0; j < nDofsPerNode; j++) {
198 dofgids[i * nDofsPerNode + j] =
indexBase_ +
offset_ + (nodeGID -
indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
202 map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
204 if (stridedBlockId == -1) {
207 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
211 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
213 int nDofsInStridedBlock = stridingInfo[stridedBlockId];
217 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
221 "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
224 map_ = MapFactory_t::Build(xlib, numGlobalElements, numLocalElements, indexBase, comm);
230template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
235 GlobalOrdinal indexBase,
236 std::vector<size_t>& stridingInfo,
238 LocalOrdinal stridedBlockId)
239 : stridingInfo_(stridingInfo)
240 , stridedBlockId_(stridedBlockId)
241 , indexBase_(indexBase) {
248 "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
249 if (stridedBlockId != -1)
252 "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
256 "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
257 "multiple of numGlobalElements.");
258#ifdef HAVE_XPETRA_DEBUG
261 Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numLocalElements, Teuchos::outArg(sumLocalElements));
263 std::invalid_argument,
264 "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
265 "number of global elements.");
269 if (stridedBlockId == -1) {
276 "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
277 "multiple of elementList.size().");
285 "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not "
286 "an integer multiple of elementList.size().");
289 map_ = MapFactory_t::Build(xlib, numGlobalElements, elementList, indexBase, comm);
295 for (Teuchos_Ordinal k = 0; k < elementList.
size(); k++)
297 if (elementList[k] < minGidOnCurProc) {
298 minGidOnCurProc = elementList[k];
302 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(
offset_));
305 size_t nStridedOffset = 0;
306 for (
int j = 0; j < stridedBlockId; j++) {
307 nStridedOffset += stridingInfo[j];
309 const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
317template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
320 std::vector<size_t>& stridingInfo,
322 LocalOrdinal stridedBlockId,
323 GlobalOrdinal offset)
324 : stridingInfo_(stridingInfo)
325 , stridedBlockId_(stridedBlockId)
327 , indexBase_(map->getIndexBase()) {
332 if (Teuchos::rcp_dynamic_cast<const StridedMap>(map) == Teuchos::null) {
335 map_ = map->getMap();
339template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
344template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
348 return stridingInfo_;
351template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
354 stridingInfo_ = stridingInfo;
357template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
362 for (std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it) {
368template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
372 return stridedBlockId_;
375template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
378 return stridingInfo_.size() > 1 ? true :
false;
381template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
384 return getFixedBlockSize() > 1 ? true :
false;
387template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
394template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
400template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
404 GlobalOrdinal tgid = gid - offset_ - indexBase_;
405 tgid = tgid % getFixedBlockSize();
407 size_t nStridedOffset = 0;
408 size_t stridedBlockId = 0;
409 for (
size_t j = 0; j < stridingInfo_.size(); j++) {
410 nStridedOffset += stridingInfo_[j];
411 if (Teuchos::as<size_t>(tgid) < nStridedOffset) {
416 return stridedBlockId;
419template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
426template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
429#ifndef HAVE_XPETRA_DEBUG
432 if (getStridedBlockId() == -1) {
434 if (getLocalNumElements() % getFixedBlockSize() != 0 ||
435 getGlobalNumElements() % getFixedBlockSize() != 0)
442 if (dofGids.
size() == 0)
447 if (dofGids.
size() % stridingInfo_[stridedBlockId_] != 0) {
452 size_t nStridedOffset = 0;
453 for (
int j = 0; j < stridedBlockId_; j++) {
454 nStridedOffset += stridingInfo_[j];
457 const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
458 const GlobalOrdinal goZeroOffset = (dofGids[0] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
460 GlobalOrdinal cnt = 0;
462 i < Teuchos::as<size_t>(dofGids.
size()) / stridingInfo_[stridedBlockId_];
463 i += stridingInfo_[stridedBlockId_]) {
464 const GlobalOrdinal first_gid = dofGids[i];
467 cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
470 for (
size_t j = 0; j < stridingInfo_[stridedBlockId_]; j++) {
471 const GlobalOrdinal gid = dofGids[i + j];
472 const GlobalOrdinal r = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt;
478 std::cout <<
"goZeroOffset : " << goZeroOffset << std::endl
479 <<
"dofGids[0] : " << dofGids[0] << std::endl
480 <<
"stridedOffset : " << nStridedOffset << std::endl
481 <<
"offset_ : " << offset_ << std::endl
482 <<
"goStridedOffset: " << goStridedOffset << std::endl
483 <<
"getFixedBlkSize: " << getFixedBlockSize() << std::endl
484 <<
"gid: " << gid <<
" GID: " << r << std::endl;
496template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
500 return map_->getGlobalNumElements();
503template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
507 return map_->getLocalNumElements();
510template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
514 return map_->getIndexBase();
517template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
521 return map_->getMinLocalIndex();
524template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
528 return map_->getMaxLocalIndex();
531template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
535 return map_->getMinGlobalIndex();
538template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
542 return map_->getMaxGlobalIndex();
545template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
549 return map_->getMinAllGlobalIndex();
552template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
556 return map_->getMaxAllGlobalIndex();
559template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
563 return map_->getLocalElement(globalIndex);
566template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
570 return map_->getGlobalElement(localIndex);
573template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
579 return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
582template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
587 return map_->getRemoteIndexList(GIDList, nodeIDList);
590template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
594 return map_->getLocalElementList();
597template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
601 return map_->getMyGlobalIndicesDevice();
604template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
607 return map_->isNodeLocalElement(localIndex);
610template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
613 return map_->isNodeGlobalElement(globalIndex);
616template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
619 return map_->isContiguous();
622template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
625 return map_->isDistributed();
628template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
631 return map_->isCompatible(map);
634template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
637 return map_->isSameAs(map);
640template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
644 return map_->getComm();
647template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
651 return map_->removeEmptyProcesses();
654template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
658 return map_->replaceCommWithSubset(newComm);
661template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
665 return map_->description();
668template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
671 map_->describe(out, verbLevel);
674template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
Exception throws to report errors in the internal logical of the program.
Create an Xpetra::Map instance.
Kokkos::View< const global_ordinal_type *, typename Node::device_type > global_indices_array_device_type
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
LocalOrdinal getMaxLocalIndex() const
Returns maximum local index.
std::vector< size_t > stridingInfo_
Vector with size of strided blocks (dofs)
GlobalOrdinal getMinAllGlobalIndex() const
Return the minimum global index over all nodes.
virtual ~StridedMap()
Destructor.
global_indices_array_device_type getMyGlobalIndicesDevice() const
Return a view of the global indices owned by this process on the Map's device.
bool isSameAs(const Map &map) const
Returns true if map is identical to this Map.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Returns true if the global index is found in this Map on this node; returns false if it isn't.
size_t GID2StridingBlockId(GlobalOrdinal gid) const
GlobalOrdinal indexBase_
Index base for the strided map (default = 0)
bool isNodeLocalElement(LocalOrdinal localIndex) const
Returns true if the local index is valid for this Map on this node; returns false if it isn't.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index.
UnderlyingLib lib() const
Get the library used by this object (Tpetra or Epetra?)
global_size_t getGlobalNumElements() const
Returns the number of elements in this Map.
bool isDistributed() const
Returns true if this Map is distributed across more than one node; returns false otherwise.
LocalOrdinal getStridedBlockId() const
void setStridingData(std::vector< size_t > stridingInfo)
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Returns the node IDs and corresponding local indices for a given list of global indices.
size_t getLocalNumElements() const
Returns the number of elements belonging to the calling node.
GlobalOrdinal getOffset() const
bool isContiguous() const
Returns true if this Map is distributed contiguously; returns false otherwise.
GlobalOrdinal getMaxAllGlobalIndex() const
Return the maximum global index over all nodes.
RCP< const Map > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const
Replace this Map's communicator with a subset communicator.
void setOffset(GlobalOrdinal offset)
GlobalOrdinal offset_
Offset for gids in map (default = 0)
GlobalOrdinal getMinGlobalIndex() const
Returns minimum global index owned by this node.
std::vector< size_t > getStridingData() const
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get the Comm object for this Map.
bool isCompatible(const Map &map) const
Returns true if map is compatible with this Map.
size_t getFixedBlockSize() const
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
Return the local index for a given global index.
bool isStrided() const
returns true, if this is a strided map (i.e. more than 1 strided blocks)
virtual bool CheckConsistency()
Teuchos::ArrayView< const GlobalOrdinal > getLocalElementList() const
Return a list of the global indices owned by this node.
std::string description() const
Return a simple one-line description of this object.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to a FancyOStream object.
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > map_
LocalOrdinal getMinLocalIndex() const
Returns minimum local index.
GlobalOrdinal getMaxGlobalIndex() const
Returns maximum global index owned by this node.
RCP< const Map > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
StridedMap(UnderlyingLib xlib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=GloballyDistributed)
Map constructor with contiguous uniform distribution.
GlobalOrdinal getIndexBase() const
Returns the index base for this Map.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_t global_size_t
Global size_t object.