42 #ifndef TPETRA_BLOCKMAP_DEF_HPP
43 #define TPETRA_BLOCKMAP_DEF_HPP
45 #include <Tpetra_ConfigDefs.hpp>
46 #include "Tpetra_Distributor.hpp"
51 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
54 LocalOrdinal blockSize,
55 GlobalOrdinal indexBase,
56 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
57 const Teuchos::RCP<Node> &node)
59 globalNumBlocks_(numGlobalBlocks),
61 pbuf_firstPointInBlock_(),
62 view_firstPointInBlock_(),
63 blockIDsAreContiguous_(true),
64 constantBlockSize_(blockSize)
66 TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error,
67 "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0.");
75 size_t numLocalPoints = numGlobalBlocks/comm->getSize();
76 int remainder = numGlobalBlocks%comm->getSize();
77 int localProc = comm->getRank();
78 if (localProc < remainder) ++numLocalPoints;
79 numLocalPoints *= blockSize;
84 size_t numLocalBlocks = pointMap_->getNodeNumElements()/blockSize;
85 size_t checkLocalBlocks = numLocalPoints/blockSize;
87 TEUCHOS_TEST_FOR_EXCEPTION(numLocalBlocks != checkLocalBlocks, std::runtime_error,
88 "Tpetra::BlockMap::BlockMap ERROR: internal failure, numLocalBlocks not consistent with point-map.");
90 myGlobalBlockIDs_.resize(numLocalBlocks);
91 pbuf_firstPointInBlock_ = node->template allocBuffer<LocalOrdinal>(numLocalBlocks+1);
92 Teuchos::ArrayRCP<LocalOrdinal> v_firstPoints = node->template viewBufferNonConst<LocalOrdinal>(KokkosClassic::WriteOnly, numLocalBlocks+1, pbuf_firstPointInBlock_);
94 LocalOrdinal firstPoint = pointMap_->getMinLocalIndex();
95 GlobalOrdinal blockID = pointMap_->getMinGlobalIndex()/blockSize;
96 for(
size_t i=0; i<numLocalBlocks; ++i) {
97 myGlobalBlockIDs_[i] = blockID++;
98 v_firstPoints[i] = firstPoint;
99 firstPoint += blockSize;
101 v_firstPoints[numLocalBlocks] = firstPoint;
102 v_firstPoints = Teuchos::null;
103 view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_);
106 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
109 size_t numLocalBlocks,
110 LocalOrdinal blockSize,
111 GlobalOrdinal indexBase,
112 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
113 const Teuchos::RCP<Node> &node)
115 globalNumBlocks_(numGlobalBlocks),
117 pbuf_firstPointInBlock_(),
118 view_firstPointInBlock_(),
119 blockIDsAreContiguous_(true),
120 constantBlockSize_(blockSize)
122 using KokkosClassic::WriteOnly;
124 using Teuchos::REDUCE_SUM;
125 using Teuchos::reduceAll;
126 typedef LocalOrdinal LO;
129 TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error,
130 "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0.");
132 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
133 GST numGlobalPoints = numGlobalBlocks*blockSize;
134 if (numGlobalBlocks == INVALID) {
135 numGlobalPoints = INVALID;
138 size_t numLocalPoints = numLocalBlocks*blockSize;
141 pointMap_ = rcp (
new point_map_type (numGlobalPoints, numLocalPoints,
142 indexBase, comm, node));
144 if (numGlobalBlocks == INVALID) {
145 reduceAll<int, GST> (*comm, REDUCE_SUM, 1, &numLocalBlocks, &globalNumBlocks_);
148 myGlobalBlockIDs_.resize(numLocalBlocks);
149 pbuf_firstPointInBlock_ = node->template allocBuffer<LO> (numLocalBlocks + 1);
150 Teuchos::ArrayRCP<LO> v_firstPoints =
151 node->template viewBufferNonConst<LO> (WriteOnly, numLocalBlocks + 1,
152 pbuf_firstPointInBlock_);
154 LO firstPoint = pointMap_->getMinLocalIndex ();
155 GlobalOrdinal blockID = pointMap_->getMinGlobalIndex () / blockSize;
156 for (
size_t i=0; i < numLocalBlocks; ++i) {
157 myGlobalBlockIDs_[i] = blockID++;
158 v_firstPoints[i] = firstPoint;
159 firstPoint += blockSize;
161 v_firstPoints[numLocalBlocks] = firstPoint;
162 v_firstPoints = Teuchos::null;
163 view_firstPointInBlock_ =
164 node->template viewBuffer<LO> (numLocalBlocks + 1, pbuf_firstPointInBlock_);
167 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
170 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs,
171 const Teuchos::ArrayView<const GlobalOrdinal>& myFirstGlobalPointInBlocks,
172 const Teuchos::ArrayView<const LocalOrdinal>& blockSizes,
173 const GlobalOrdinal indexBase,
174 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
175 const Teuchos::RCP<Node>& node)
177 globalNumBlocks_ (numGlobalBlocks),
178 myGlobalBlockIDs_ (myGlobalBlockIDs),
179 pbuf_firstPointInBlock_ (),
180 view_firstPointInBlock_ (),
181 blockIDsAreContiguous_ (false),
182 constantBlockSize_ (0)
184 using Teuchos::outArg;
186 using Teuchos::REDUCE_SUM;
187 using Teuchos::reduceAll;
188 typedef LocalOrdinal LO;
191 TEUCHOS_TEST_FOR_EXCEPTION(
192 myGlobalBlockIDs_.size () != blockSizes.size (), std::runtime_error,
193 "Tpetra::BlockMap::BlockMap: input myGlobalBlockIDs and blockSizes arrays "
194 "must have the same length.");
196 size_t sum_blockSizes = 0;
197 Teuchos::Array<GlobalOrdinal> myGlobalPoints;
198 typename Teuchos::ArrayView<const LocalOrdinal>::const_iterator
199 iter = blockSizes.begin(), iend = blockSizes.end();
201 for (; iter!=iend; ++iter) {
202 LocalOrdinal bsize = *iter;
203 sum_blockSizes += bsize;
204 GlobalOrdinal firstPoint = myFirstGlobalPointInBlocks[i++];
205 for(LocalOrdinal j=0; j<bsize; ++j) {
206 myGlobalPoints.push_back(firstPoint+j);
210 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
212 indexBase, comm, node));
215 reduceAll<int, GST> (*comm, REDUCE_SUM,
static_cast<GST
> (myGlobalBlockIDs.size ()), outArg (global_sum));
216 globalNumBlocks_ = global_sum;
218 iter = blockSizes.begin();
219 LO firstBlockSize = (iter == iend) ? 0 : *iter;
220 LO firstPoint = pointMap_->getMinLocalIndex ();
221 LO numLocalBlocks = myGlobalBlockIDs.size ();
222 pbuf_firstPointInBlock_ = node->template allocBuffer<LO> (numLocalBlocks + 1);
223 Teuchos::ArrayRCP<LO> v_firstPoints =
224 node->template viewBufferNonConst<LO> (KokkosClassic::WriteOnly,
226 pbuf_firstPointInBlock_);
228 bool blockSizesAreConstant =
true;
230 for(; iter!=iend; ++iter, ++i) {
231 v_firstPoints[i] = firstPoint;
233 if (*iter != firstBlockSize) {
234 blockSizesAreConstant =
false;
237 v_firstPoints[i] = firstPoint;
238 v_firstPoints = Teuchos::null;
239 if (blockSizesAreConstant) {
240 constantBlockSize_ = firstBlockSize;
243 size_t num_points = pointMap_->getNodeNumElements ();
244 TEUCHOS_TEST_FOR_EXCEPTION(
245 sum_blockSizes != num_points, std::runtime_error,
246 "Tpetra::BlockMap::BlockMap: internal failure, sum of block sizes must "
247 "equal pointMap->getNodeNumElements().");
249 typename Teuchos::Array<GlobalOrdinal>::const_iterator
250 b_iter = myGlobalBlockIDs_.begin(), b_end = myGlobalBlockIDs_.end();
251 GlobalOrdinal
id = b_iter==b_end ? 0 : *b_iter;
252 if (b_iter != b_end) ++b_iter;
253 blockIDsAreContiguous_ =
true;
254 for(; b_iter != b_end; ++b_iter) {
255 if (*b_iter !=
id+1) {
256 blockIDsAreContiguous_ =
false;
261 if (blockIDsAreContiguous_ ==
false) {
262 setup_noncontig_mapping();
265 view_firstPointInBlock_ =
266 node->template viewBuffer<LO> (numLocalBlocks+1, pbuf_firstPointInBlock_);
269 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
271 BlockMap (
const Teuchos::RCP<const point_map_type>& pointMap,
272 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs,
273 const Teuchos::ArrayView<const LocalOrdinal>& blockSizes) :
274 pointMap_ (pointMap),
275 globalNumBlocks_ (Teuchos::OrdinalTraits<
global_size_t>::invalid ()),
276 myGlobalBlockIDs_(myGlobalBlockIDs),
277 pbuf_firstPointInBlock_ (),
278 view_firstPointInBlock_ (),
279 blockIDsAreContiguous_ (false),
280 constantBlockSize_ (0)
282 Teuchos::RCP<Node> node =
283 pointMap.is_null () ? defaultArgNode<Node> () : pointMap->getNode ();
284 initWithPointMap (pointMap, myGlobalBlockIDs, blockSizes, node);
287 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
290 BlockMap (
const Teuchos::RCP<const point_map_type>& pointMap,
291 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs,
292 const Teuchos::ArrayView<const LocalOrdinal>& blockSizes,
293 const Teuchos::RCP<Node>& node) :
294 pointMap_ (pointMap),
295 globalNumBlocks_ (Teuchos::OrdinalTraits<
global_size_t>::invalid ()),
296 myGlobalBlockIDs_(myGlobalBlockIDs),
297 pbuf_firstPointInBlock_ (),
298 view_firstPointInBlock_ (),
299 blockIDsAreContiguous_ (false),
300 constantBlockSize_ (0)
302 initWithPointMap (pointMap, myGlobalBlockIDs, blockSizes, node);
305 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
309 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs,
310 const Teuchos::ArrayView<const LocalOrdinal>& blockSizes,
311 const Teuchos::RCP<Node>& node)
313 using KokkosClassic::WriteOnly;
314 using Teuchos::ArrayRCP;
315 using Teuchos::REDUCE_SUM;
316 using Teuchos::reduceAll;
317 typedef GlobalOrdinal GO;
318 typedef LocalOrdinal LO;
321 TEUCHOS_TEST_FOR_EXCEPTION(
322 myGlobalBlockIDs_.size () != blockSizes.size (), std::runtime_error,
323 "Tpetra::BlockMap::BlockMap: input myGlobalBlockIDs and blockSizes arrays "
324 "must have the same length.");
326 const global_size_t numLocalBlocks = myGlobalBlockIDs.size ();
327 reduceAll<int, GST> (* (pointMap->getComm ()), REDUCE_SUM, 1,
328 &numLocalBlocks, &globalNumBlocks_);
330 pbuf_firstPointInBlock_ =
331 node->template allocBuffer<LO> (myGlobalBlockIDs.size () + 1);
332 ArrayRCP<LO> v_firstPoints =
333 node->template viewBufferNonConst<LO> (WriteOnly, numLocalBlocks + 1,
334 pbuf_firstPointInBlock_);
336 LO firstPoint = pointMap->getMinLocalIndex ();
337 size_t sum_blockSizes = 0;
338 typename Teuchos::ArrayView<const LO>::const_iterator
339 iter = blockSizes.begin(), iend = blockSizes.end();
340 LocalOrdinal firstBlockSize = *iter;
341 bool blockSizesAreConstant =
true;
343 for (; iter!=iend; ++iter, ++i) {
344 sum_blockSizes += *iter;
345 v_firstPoints[i] = firstPoint;
347 if (*iter != firstBlockSize) {
348 blockSizesAreConstant =
false;
351 v_firstPoints[i] = firstPoint;
352 v_firstPoints = Teuchos::null;
353 if (blockSizesAreConstant) {
354 constantBlockSize_ = firstBlockSize;
357 const size_t num_points = pointMap->getNodeNumElements ();
358 TEUCHOS_TEST_FOR_EXCEPTION(
359 sum_blockSizes != num_points, std::runtime_error,
360 "Tpetra::BlockMap::BlockMap: Sum of block sizes must equal "
361 "pointMap->getNodeNumElements().");
363 typename Teuchos::Array<GO>::const_iterator
364 b_iter = myGlobalBlockIDs_.begin(), b_end = myGlobalBlockIDs_.end();
365 GlobalOrdinal
id = *b_iter;
367 blockIDsAreContiguous_ =
true;
368 for (; b_iter != b_end; ++b_iter) {
369 if (*b_iter !=
id+1) {
370 blockIDsAreContiguous_ =
false;
375 if (! blockIDsAreContiguous_) {
376 setup_noncontig_mapping ();
379 view_firstPointInBlock_ =
380 node->template viewBuffer<LO> (numLocalBlocks+1, pbuf_firstPointInBlock_);
384 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
387 const Teuchos::ArrayView<const GlobalOrdinal>& GBIDs,
388 const Teuchos::ArrayView<GlobalOrdinal>& firstGlobalPointInBlocks,
389 const Teuchos::ArrayView<LocalOrdinal>& blockSizes)
const
391 Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > pbmap =
392 convertBlockMapToPointMap(*
this);
394 Teuchos::Array<int> remoteProcs(GBIDs.size());
395 pbmap->getRemoteIndexList(GBIDs(), remoteProcs());
399 Tpetra::Array<GlobalOrdinal> exportGBIDs;
400 Tpetra::Array<int> exportProcs;
402 distor.
createFromRecvs(GBIDs(), remoteProcs(), exportGBIDs, exportProcs);
404 Tpetra::Array<GlobalOrdinal> exportFirstPointInBlocks(exportGBIDs.size());
405 Tpetra::Array<LocalOrdinal> exportSizes(exportGBIDs.size());
407 typename Teuchos::Array<GlobalOrdinal>::const_iterator
408 iter = exportGBIDs.begin(),
409 iter_end = exportGBIDs.end();
410 for(
int i=0; iter!=iter_end; ++iter, ++i) {
411 GlobalOrdinal gbid = *iter;
412 LocalOrdinal lbid = getLocalBlockID(gbid);
413 exportFirstPointInBlocks[i] = getFirstGlobalPointInLocalBlock(lbid);
414 exportSizes[i] = getLocalBlockSize(lbid);
417 size_t numPackets = 1;
418 distor.doPostsAndWaits(exportFirstPointInBlocks().getConst(),
419 numPackets, firstGlobalPointInBlocks);
421 distor.doPostsAndWaits(exportSizes().getConst(), numPackets, blockSizes);
424 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
428 typedef typename Teuchos::Array<GlobalOrdinal>::size_type Tsize_t;
429 for(Tsize_t i=0; i<myGlobalBlockIDs_.size(); ++i) {
432 map_global_to_local_.insert(std::make_pair(myGlobalBlockIDs_[i],li));
436 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
440 return globalNumBlocks_;
443 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
447 return myGlobalBlockIDs_.size();
450 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
451 Teuchos::ArrayView<const GlobalOrdinal>
454 return myGlobalBlockIDs_();
457 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
460 {
return constantBlockSize_ != 0; }
462 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
463 Teuchos::ArrayRCP<const LocalOrdinal>
466 return view_firstPointInBlock_;
469 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
470 Teuchos::ArrayRCP<const LocalOrdinal>
473 return pbuf_firstPointInBlock_;
476 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
480 LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid();
481 if (localBlockID < 0 || localBlockID >= myGlobalBlockIDs_.size()) {
485 return myGlobalBlockIDs_[localBlockID];
488 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
492 LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid();
493 if (myGlobalBlockIDs_.size() == 0) {
497 if (blockIDsAreContiguous_ ==
false) {
499 typename std::map<GlobalOrdinal,LocalOrdinal>::const_iterator iter =
500 map_global_to_local_.find(globalBlockID);
501 if (iter == map_global_to_local_.end())
return invalid;
505 LocalOrdinal localBlockID = globalBlockID - myGlobalBlockIDs_[0];
506 LocalOrdinal numLocalBlocks = myGlobalBlockIDs_.size();
508 if (localBlockID < 0 || localBlockID >= numLocalBlocks) {
515 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
519 if (constantBlockSize_ != 0) {
520 return constantBlockSize_;
524 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
525 throw std::runtime_error(
"Tpetra::BlockMap::getLocalBlockSize ERROR: localBlockID out of range.");
528 return view_firstPointInBlock_[localBlockID+1]-view_firstPointInBlock_[localBlockID];
531 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
536 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
537 throw std::runtime_error(
"Tpetra::BlockMap::getFirstLocalPointInLocalBlock ERROR: localBlockID out of range.");
540 return view_firstPointInBlock_[localBlockID];
543 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
548 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
549 throw std::runtime_error(
"Tpetra::BlockMap::getFirstGlobalPointInLocalBlock ERROR: localBlockID out of range.");
552 return pointMap_->getGlobalElement(view_firstPointInBlock_[localBlockID]);
563 #define TPETRA_BLOCKMAP_INSTANT(LO,GO,NODE) \
565 template class BlockMap< LO , GO , NODE >;
567 #endif // ! TPETRA_BLOCKMAP_DEF_HPP
Block-entry counterpart to Tpetra::Map.
LocalOrdinal getLocalBlockID(GlobalOrdinal globalBlockID) const
Return the localBlockID corresponding to the given globalBlockID.
global_size_t getGlobalNumBlocks() const
Return global number of blocks.
Teuchos::ArrayRCP< const LocalOrdinal > getNodeFirstPointInBlocks() const
Return ArrayRCP of first-local-point in local blocks.
bool isBlockSizeConstant() const
Return true if all blocks have the same size.
GlobalOrdinal getGlobalBlockID(LocalOrdinal localBlockID) const
Return the globalBlockID corresponding to the given localBlockID.
size_t global_size_t
Global size_t object.
LocalOrdinal getLocalBlockSize(LocalOrdinal localBlockID) const
Return the block-size for localBlockID.
Declarations for the class Tpetra::BlockMap.
Sets up and executes a communication plan for a Tpetra DistObject.
void getRemoteBlockInfo(const Teuchos::ArrayView< const GlobalOrdinal > &GBIDs, const Teuchos::ArrayView< GlobalOrdinal > &firstGlobalPointInBlocks, const Teuchos::ArrayView< LocalOrdinal > &blockSizes) const
Return the first-global-point-in-block and block-sizes for a list of block-IDs on remote processors...
size_t getNodeNumBlocks() const
Return number of blocks on the local processor.
Describes a parallel distribution of objects over processes.
Teuchos::ArrayView< const GlobalOrdinal > getNodeBlockIDs() const
Return array-view of block-ids for this local processor.
BlockMap(global_size_t numGlobalBlocks, LocalOrdinal blockSize, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=defaultArgNode< node_type >())
BlockMap constructor specifying numGlobalBlocks and constant blockSize.
GlobalOrdinal getFirstGlobalPointInLocalBlock(LocalOrdinal localBlockID) const
Return the first global point-index corresponding to localBlockID.
LocalOrdinal getFirstLocalPointInLocalBlock(LocalOrdinal localBlockID) const
Return the first local point-index corresponding to localBlockID.
void createFromRecvs(const ArrayView< const Ordinal > &remoteIDs, const ArrayView< const int > &remoteNodeIDs, Array< Ordinal > &exportIDs, Array< int > &exportNodeIDs)
Set up Distributor using list of process ranks from which to receive.
Teuchos::ArrayRCP< const LocalOrdinal > getNodeFirstPointInBlocks_Device() const
Return device-resident ArrayRCP of first-local-point in local blocks.