Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tpetra_BlockMap_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_BLOCKMAP_DEF_HPP
43 #define TPETRA_BLOCKMAP_DEF_HPP
44 
45 #include <Tpetra_ConfigDefs.hpp>
46 #include "Tpetra_Distributor.hpp"
47 #include "Tpetra_BlockMap_decl.hpp"
48 
49 namespace Tpetra {
50 
51 template<class LocalOrdinal,class GlobalOrdinal,class Node>
53  global_size_t numGlobalBlocks,
54  LocalOrdinal blockSize,
55  GlobalOrdinal indexBase,
56  const Teuchos::RCP<const Teuchos::Comm<int> > &comm,
57  const Teuchos::RCP<Node> &node)
58  : pointMap_(),
59  globalNumBlocks_(numGlobalBlocks),
60  myGlobalBlockIDs_(),
61  pbuf_firstPointInBlock_(),
62  view_firstPointInBlock_(),
63  blockIDsAreContiguous_(true),
64  constantBlockSize_(blockSize)
65 {
66  TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error,
67  "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0.");
68 
69  global_size_t numGlobalPoints = numGlobalBlocks*blockSize;
70 
71  //we compute numLocalPoints to make sure that Tpetra::Map doesn't split
72  //numGlobalPoints in a way that would separate the points within a block
73  //onto different mpi processors.
74 
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;
80 
81  //now create the point-map specifying both numGlobalPoints and numLocalPoints:
82  pointMap_ = Teuchos::rcp(new Map<LocalOrdinal,GlobalOrdinal,Node>(numGlobalPoints, numLocalPoints, indexBase, comm, node));
83 
84  size_t numLocalBlocks = pointMap_->getNodeNumElements()/blockSize;
85  size_t checkLocalBlocks = numLocalPoints/blockSize;
86  //can there be an inconsistency here???
87  TEUCHOS_TEST_FOR_EXCEPTION(numLocalBlocks != checkLocalBlocks, std::runtime_error,
88  "Tpetra::BlockMap::BlockMap ERROR: internal failure, numLocalBlocks not consistent with point-map.");
89 
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_);
93 
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;
100  }
101  v_firstPoints[numLocalBlocks] = firstPoint;
102  v_firstPoints = Teuchos::null;
103  view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_);
104 }
105 
106 template<class LocalOrdinal,class GlobalOrdinal,class Node>
108  global_size_t numGlobalBlocks,
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)
114  : pointMap_(),
115  globalNumBlocks_(numGlobalBlocks),
116  myGlobalBlockIDs_(),
117  pbuf_firstPointInBlock_(),
118  view_firstPointInBlock_(),
119  blockIDsAreContiguous_(true),
120  constantBlockSize_(blockSize)
121 {
122  using KokkosClassic::WriteOnly;
123  using Teuchos::rcp;
124  using Teuchos::REDUCE_SUM;
125  using Teuchos::reduceAll;
126  typedef LocalOrdinal LO;
127  typedef global_size_t GST;
128 
129  TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error,
130  "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0.");
131 
132  const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
133  GST numGlobalPoints = numGlobalBlocks*blockSize;
134  if (numGlobalBlocks == INVALID) {
135  numGlobalPoints = INVALID;
136  }
137 
138  size_t numLocalPoints = numLocalBlocks*blockSize;
139 
140  //now create the point-map specifying both numGlobalPoints and numLocalPoints:
141  pointMap_ = rcp (new point_map_type (numGlobalPoints, numLocalPoints,
142  indexBase, comm, node));
143 
144  if (numGlobalBlocks == INVALID) {
145  reduceAll<int, GST> (*comm, REDUCE_SUM, 1, &numLocalBlocks, &globalNumBlocks_);
146  }
147 
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_);
153 
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;
160  }
161  v_firstPoints[numLocalBlocks] = firstPoint;
162  v_firstPoints = Teuchos::null;
163  view_firstPointInBlock_ =
164  node->template viewBuffer<LO> (numLocalBlocks + 1, pbuf_firstPointInBlock_);
165 }
166 
167 template<class LocalOrdinal,class GlobalOrdinal,class Node>
169 BlockMap (const global_size_t numGlobalBlocks,
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)
176  : pointMap_ (),
177  globalNumBlocks_ (numGlobalBlocks),
178  myGlobalBlockIDs_ (myGlobalBlockIDs),
179  pbuf_firstPointInBlock_ (),
180  view_firstPointInBlock_ (),
181  blockIDsAreContiguous_ (false),
182  constantBlockSize_ (0)
183 {
184  using Teuchos::outArg;
185  using Teuchos::rcp;
186  using Teuchos::REDUCE_SUM;
187  using Teuchos::reduceAll;
188  typedef LocalOrdinal LO;
189  typedef global_size_t GST;
190 
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.");
195 
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();
200  size_t i = 0;
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);
207  }
208  }
209 
210  const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
211  pointMap_ = rcp (new point_map_type (INVALID, myGlobalPoints (),
212  indexBase, comm, node));
213 
214  global_size_t global_sum;
215  reduceAll<int, GST> (*comm, REDUCE_SUM, static_cast<GST> (myGlobalBlockIDs.size ()), outArg (global_sum));
216  globalNumBlocks_ = global_sum;
217 
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,
225  numLocalBlocks + 1,
226  pbuf_firstPointInBlock_);
227 
228  bool blockSizesAreConstant = true;
229  i=0;
230  for(; iter!=iend; ++iter, ++i) {
231  v_firstPoints[i] = firstPoint;
232  firstPoint += *iter;
233  if (*iter != firstBlockSize) {
234  blockSizesAreConstant = false;
235  }
236  }
237  v_firstPoints[i] = firstPoint;
238  v_firstPoints = Teuchos::null;
239  if (blockSizesAreConstant) {
240  constantBlockSize_ = firstBlockSize;
241  }
242 
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().");
248 
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;
257  break;
258  }
259  ++id;
260  }
261  if (blockIDsAreContiguous_ == false) {
262  setup_noncontig_mapping();
263  }
264 
265  view_firstPointInBlock_ =
266  node->template viewBuffer<LO> (numLocalBlocks+1, pbuf_firstPointInBlock_);
267 }
268 
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)
281 {
282  Teuchos::RCP<Node> node =
283  pointMap.is_null () ? defaultArgNode<Node> () : pointMap->getNode ();
284  initWithPointMap (pointMap, myGlobalBlockIDs, blockSizes, node);
285 }
286 
287 template<class LocalOrdinal,class GlobalOrdinal,class Node>
288 TPETRA_DEPRECATED
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)
301 {
302  initWithPointMap (pointMap, myGlobalBlockIDs, blockSizes, node);
303 }
304 
305 template<class LocalOrdinal,class GlobalOrdinal,class Node>
306 void
308 initWithPointMap (const Teuchos::RCP<const point_map_type>& pointMap,
309  const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs,
310  const Teuchos::ArrayView<const LocalOrdinal>& blockSizes,
311  const Teuchos::RCP<Node>& node)
312 {
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;
319  typedef global_size_t GST;
320 
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.");
325 
326  const global_size_t numLocalBlocks = myGlobalBlockIDs.size ();
327  reduceAll<int, GST> (* (pointMap->getComm ()), REDUCE_SUM, 1,
328  &numLocalBlocks, &globalNumBlocks_);
329 
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_);
335 
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;
342  size_t i = 0;
343  for (; iter!=iend; ++iter, ++i) {
344  sum_blockSizes += *iter;
345  v_firstPoints[i] = firstPoint;
346  firstPoint += *iter;
347  if (*iter != firstBlockSize) {
348  blockSizesAreConstant = false;
349  }
350  }
351  v_firstPoints[i] = firstPoint;
352  v_firstPoints = Teuchos::null;
353  if (blockSizesAreConstant) {
354  constantBlockSize_ = firstBlockSize;
355  }
356 
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().");
362 
363  typename Teuchos::Array<GO>::const_iterator
364  b_iter = myGlobalBlockIDs_.begin(), b_end = myGlobalBlockIDs_.end();
365  GlobalOrdinal id = *b_iter;
366  ++b_iter;
367  blockIDsAreContiguous_ = true;
368  for (; b_iter != b_end; ++b_iter) {
369  if (*b_iter != id+1) {
370  blockIDsAreContiguous_ = false;
371  break;
372  }
373  ++id;
374  }
375  if (! blockIDsAreContiguous_) {
376  setup_noncontig_mapping ();
377  }
378 
379  view_firstPointInBlock_ =
380  node->template viewBuffer<LO> (numLocalBlocks+1, pbuf_firstPointInBlock_);
381 }
382 
383 
384 template<class LocalOrdinal,class GlobalOrdinal,class Node>
385 void
387  const Teuchos::ArrayView<const GlobalOrdinal>& GBIDs,
388  const Teuchos::ArrayView<GlobalOrdinal>& firstGlobalPointInBlocks,
389  const Teuchos::ArrayView<LocalOrdinal>& blockSizes) const
390 {
391  Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > pbmap =
392  convertBlockMapToPointMap(*this);
393 
394  Teuchos::Array<int> remoteProcs(GBIDs.size());
395  pbmap->getRemoteIndexList(GBIDs(), remoteProcs());
396 
397  Tpetra::Distributor distor(pbmap->getComm());
398 
399  Tpetra::Array<GlobalOrdinal> exportGBIDs;
400  Tpetra::Array<int> exportProcs;
401 
402  distor.createFromRecvs(GBIDs(), remoteProcs(), exportGBIDs, exportProcs);
403 
404  Tpetra::Array<GlobalOrdinal> exportFirstPointInBlocks(exportGBIDs.size());
405  Tpetra::Array<LocalOrdinal> exportSizes(exportGBIDs.size());
406 
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);
415  }
416 
417  size_t numPackets = 1;
418  distor.doPostsAndWaits(exportFirstPointInBlocks().getConst(),
419  numPackets, firstGlobalPointInBlocks);
420 
421  distor.doPostsAndWaits(exportSizes().getConst(), numPackets, blockSizes);
422 }
423 
424 template<class LocalOrdinal,class GlobalOrdinal,class Node>
425 void
427 {
428  typedef typename Teuchos::Array<GlobalOrdinal>::size_type Tsize_t;
429  for(Tsize_t i=0; i<myGlobalBlockIDs_.size(); ++i) {
430  LocalOrdinal li = i;
431  // TODO: Use Tpetra::Details::HashTable here instead of std::map.
432  map_global_to_local_.insert(std::make_pair(myGlobalBlockIDs_[i],li));
433  }
434 }
435 
436 template<class LocalOrdinal,class GlobalOrdinal,class Node>
439 {
440  return globalNumBlocks_;
441 }
442 
443 template<class LocalOrdinal,class GlobalOrdinal,class Node>
444 size_t
446 {
447  return myGlobalBlockIDs_.size();
448 }
449 
450 template<class LocalOrdinal,class GlobalOrdinal,class Node>
451 Teuchos::ArrayView<const GlobalOrdinal>
453 {
454  return myGlobalBlockIDs_();
455 }
456 
457 template<class LocalOrdinal,class GlobalOrdinal,class Node>
458 bool
460 { return constantBlockSize_ != 0; }
461 
462 template<class LocalOrdinal,class GlobalOrdinal,class Node>
463 Teuchos::ArrayRCP<const LocalOrdinal>
465 {
466  return view_firstPointInBlock_;
467 }
468 
469 template<class LocalOrdinal,class GlobalOrdinal,class Node>
470 Teuchos::ArrayRCP<const LocalOrdinal>
472 {
473  return pbuf_firstPointInBlock_;
474 }
475 
476 template<class LocalOrdinal,class GlobalOrdinal,class Node>
477 GlobalOrdinal
479 {
480  LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid();
481  if (localBlockID < 0 || localBlockID >= myGlobalBlockIDs_.size()) {
482  return invalid;
483  }
484 
485  return myGlobalBlockIDs_[localBlockID];
486 }
487 
488 template<class LocalOrdinal,class GlobalOrdinal,class Node>
489 LocalOrdinal
491 {
492  LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid();
493  if (myGlobalBlockIDs_.size() == 0) {
494  return invalid;
495  }
496 
497  if (blockIDsAreContiguous_ == false) {
498  // TODO: Use Tpetra::Details::HashTable instead of std::map.
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;
502  return iter->second;
503  }
504 
505  LocalOrdinal localBlockID = globalBlockID - myGlobalBlockIDs_[0];
506  LocalOrdinal numLocalBlocks = myGlobalBlockIDs_.size();
507 
508  if (localBlockID < 0 || localBlockID >= numLocalBlocks) {
509  return invalid;
510  }
511 
512  return localBlockID;
513 }
514 
515 template<class LocalOrdinal,class GlobalOrdinal,class Node>
516 LocalOrdinal
518 {
519  if (constantBlockSize_ != 0) {
520  return constantBlockSize_;
521  }
522 
523  //should this be a debug-mode-only range check?
524  if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
525  throw std::runtime_error("Tpetra::BlockMap::getLocalBlockSize ERROR: localBlockID out of range.");
526  }
527 
528  return view_firstPointInBlock_[localBlockID+1]-view_firstPointInBlock_[localBlockID];
529 }
530 
531 template<class LocalOrdinal,class GlobalOrdinal,class Node>
532 LocalOrdinal
534 {
535  //should this be a debug-mode-only range check?
536  if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
537  throw std::runtime_error("Tpetra::BlockMap::getFirstLocalPointInLocalBlock ERROR: localBlockID out of range.");
538  }
539 
540  return view_firstPointInBlock_[localBlockID];
541 }
542 
543 template<class LocalOrdinal,class GlobalOrdinal,class Node>
544 GlobalOrdinal
546 {
547  //should this be a debug-mode-only range check?
548  if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) {
549  throw std::runtime_error("Tpetra::BlockMap::getFirstGlobalPointInLocalBlock ERROR: localBlockID out of range.");
550  }
551 
552  return pointMap_->getGlobalElement(view_firstPointInBlock_[localBlockID]);
553 }
554 
555 } // namespace Tpetra
556 
557 //
558 // Explicit instantiation macro
559 //
560 // Must be expanded from within the Tpetra namespace!
561 //
562 
563 #define TPETRA_BLOCKMAP_INSTANT(LO,GO,NODE) \
564  \
565  template class BlockMap< LO , GO , NODE >;
566 
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.