Xpetra_EpetraMap.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Xpetra: A linear algebra interface package
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef XPETRA_EPETRAMAP_HPP
47 #define XPETRA_EPETRAMAP_HPP
48 
49 
51 
52 #include "Xpetra_Map.hpp"
53 
54 #include <Epetra_Map.h>
55 #include <Epetra_BlockMap.h>
56 
57 #include "Xpetra_Utils.hpp"
58 #include "Xpetra_EpetraUtils.hpp"
60 
61 #include "Xpetra_ConfigDefs.hpp"
62 
63 namespace Xpetra {
64 
65  // TODO: move that elsewhere
66  template<class GlobalOrdinal, class Node>
67  const Epetra_Map & toEpetra(const Map<int,GlobalOrdinal, Node> &);
68  template<class GlobalOrdinal, class Node>
69  const Epetra_Map & toEpetra(const RCP< const Map<int, GlobalOrdinal, Node> > &);
70  //template<class GlobalOrdinal>
71  //const RCP< const Map<int, GlobalOrdinal> > toXpetra(const RCP< const Epetra_Map > &);
72  template<class GlobalOrdinal, class Node>
73  const RCP< const Map<int, GlobalOrdinal, Node> > toXpetra(const Epetra_BlockMap &);
74 
75  // stub implementation for EpetraMapT
76  template<class GlobalOrdinal, class Node>
77  class EpetraMapT
78  : public virtual Map<int, GlobalOrdinal, Node>
79  {
80  typedef int LocalOrdinal;
81 
82  public:
83  typedef int local_ordinal_type;
84  typedef GlobalOrdinal global_ordinal_type;
85  typedef Node node_type;
86 
88 
89 
91  EpetraMapT(global_size_t numGlobalElements,
92  GlobalOrdinal indexBase,
93  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
95  const Teuchos::RCP< Node > &node = Teuchos::rcp (new Node))
96  {
98  "Xpetra::EpetraMap only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)");
99  }
100 
102  EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node)) {
104  "Xpetra::EpetraMap only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)");
105  }
106 
108  EpetraMapT(global_size_t numGlobalElements,
110  GlobalOrdinal indexBase,
111  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
112  const Teuchos::RCP< Node > &node = Teuchos::rcp(new Node)) {
114  "Xpetra::EpetraMap only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)");
115  }
116 
118 
120 
121 
123  global_size_t getGlobalNumElements() const { return 0; }
124 
126  size_t getNodeNumElements() const { return 0; }
127 
129  GlobalOrdinal getIndexBase() const { return 0; }
130 
132  LocalOrdinal getMinLocalIndex() const { return 0; }
133 
135  LocalOrdinal getMaxLocalIndex() const { return 0; }
136 
138  GlobalOrdinal getMinGlobalIndex() const { return 0; }
139 
141  GlobalOrdinal getMaxGlobalIndex() const { return 0; }
142 
144  GlobalOrdinal getMinAllGlobalIndex() const { return 0; }
145 
147  GlobalOrdinal getMaxAllGlobalIndex() const { return 0; }
148 
150  LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { return 0; }
151 
154 
157 
159  //Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const;
160 
163 
165 
166 
168  bool isNodeLocalElement(LocalOrdinal localIndex) const { return false; }
169 
171  bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { return false; }
172 
174  bool isContiguous() const { return false; }
175 
177  bool isDistributed() const { return false; }
178 
180  bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { return false; }
181 
183  bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { return false; }
184 
186 
188 
189 
191  Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { return Teuchos::null; }
192 
195  XPETRA_MONITOR("EpetraMapT<GlobalOrdinal>::getNode");
196  return Teuchos::rcp (new Node);
197  }
198 
200 
202 
203 
205  std::string description() const { return std::string(""); }
206 
209 
211 
213 
214 
217 
219  RCP<const Map<int,GlobalOrdinal,Node> > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const { return Teuchos::null; }
220 
222 
224  GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const { return -1; }
225 
227 
228 
230  virtual ~EpetraMapT() {}
231 
234  : map_(map) {
236  "Xpetra::EpetraMap only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)");
237  }
238 
240  UnderlyingLib lib() const { return Xpetra::UseEpetra; }
241 
243  //const RCP< const Epetra_Map > & getEpetra_Map() const { return map_; }
244  const Epetra_BlockMap& getEpetra_BlockMap() const { return *map_; }
245  const Epetra_Map& getEpetra_Map() const { return (Epetra_Map &)*map_; } // Ugly, but the same is done in Epetra_CrsMatrix.h to get the map.
246 
247 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
248 #ifdef HAVE_XPETRA_TPETRA
249  using local_map_type = typename Map<LocalOrdinal, GlobalOrdinal, Node>::local_map_type;
251  local_map_type getLocalMap () const {
253  "Xpetra::EpetraMap only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)");
254  TEUCHOS_UNREACHABLE_RETURN(local_map_type());
255  }
256 #else
257 #ifdef __GNUC__
258 #warning "Xpetra Kokkos interface for CrsMatrix is enabled (HAVE_XPETRA_KOKKOS_REFACTOR) but Tpetra is disabled. The Kokkos interface needs Tpetra to be enabled, too."
259 #endif
260 #endif
261 #endif
262 
264 
265  protected:
266 
268  }; // EpetraMapT class
269 
270  // specialization on GO=int and EpetraNode
271 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
272  template<>
273  class EpetraMapT<int, EpetraNode>
274  : public virtual Map<int, int, EpetraNode>
275  {
276  typedef int LocalOrdinal;
277  typedef int GlobalOrdinal;
278  typedef EpetraNode Node;
279 
280  public:
281  typedef LocalOrdinal local_ordinal_type;
282  typedef GlobalOrdinal global_ordinal_type;
283  typedef Node node_type;
284 
286 
287 
289  EpetraMapT(global_size_t numGlobalElements,
290  GlobalOrdinal indexBase,
291  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
293  const Teuchos::RCP< Node > &node = Teuchos::rcp(new Node))
294  {
295  // This test come from Tpetra (Epetra doesn't check if numGlobalElements,indexBase are equivalent across images).
296  // In addition, for the test TEST_THROW(M map((myImageID == 0 ? GSTI : 0),0,comm), std::invalid_argument), only one node throw an exception and there is a dead lock.
297  std::string errPrefix;
298  errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,indexBase,comm,lOrG): ";
299 
300  if (lg == GloballyDistributed) {
301  const int myImageID = comm->getRank();
302 
303  // check that numGlobalElements,indexBase is equivalent across images
304  global_size_t rootNGE = numGlobalElements;
305  GlobalOrdinal rootIB = indexBase;
306  Teuchos::broadcast<int,global_size_t>(*comm,0,&rootNGE);
307  Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB);
308  int localChecks[2], globalChecks[2];
309  localChecks[0] = -1; // fail or pass
310  localChecks[1] = 0; // fail reason
311  if (numGlobalElements != rootNGE) {
312  localChecks[0] = myImageID;
313  localChecks[1] = 1;
314  }
315  else if (indexBase != rootIB) {
316  localChecks[0] = myImageID;
317  localChecks[1] = 2;
318  }
319  // REDUCE_MAX will give us the image ID of the highest rank proc that DID NOT pass, as well as the reason
320  // these will be -1 and 0 if all procs passed
321  Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
322  if (globalChecks[0] != -1) {
323  if (globalChecks[1] == 1) {
324  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
325  errPrefix << "numGlobal must be the same on all nodes (examine node " << globalChecks[0] << ").");
326  }
327  else if (globalChecks[1] == 2) {
328  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
329  errPrefix << "indexBase must be the same on all nodes (examine node " << globalChecks[0] << ").");
330  }
331  else {
332  // logic error on our part
333  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
334  errPrefix << "logic error. Please contact the Tpetra team.");
335  }
336  }
337  }
338 
339  // Note: validity of numGlobalElements checked by Epetra.
340 
341  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), 1, indexBase, *toEpetra(comm))))));
342  }
343 
345  EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
346  {
347  // This test come from Tpetra
348  using Teuchos::outArg;
349 
350  const size_t L0 = Teuchos::OrdinalTraits<size_t>::zero();
351  const size_t L1 = Teuchos::OrdinalTraits<size_t>::one();
355 
356  std::string errPrefix;
357  errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,numLocal,indexBase,platform): ";
358 
359  // get a internodal communicator from the Platform
360  const int myImageID = comm->getRank();
361 
362  global_size_t global_sum;
363  { // begin scoping block
364  // for communicating failures
365  int localChecks[2], globalChecks[2];
366  /* compute the global size
367  we are computing the number of global elements because exactly ONE of the following is true:
368  - the user didn't specify it, and we need it
369  - the user did specify it, but we need to
370  + validate it against the sum of the local sizes, and
371  + ensure that it is the same on all nodes
372  */
373  Teuchos::reduceAll<int,global_size_t>(*comm,Teuchos::REDUCE_SUM,
374  Teuchos::as<global_size_t>(numLocalElements),outArg(global_sum));
375  /* there are three errors we should be detecting:
376  - numGlobalElements != invalid() and it is incorrect/invalid
377  - numLocalElements invalid (<0)
378  */
379  localChecks[0] = -1;
380  localChecks[1] = 0;
381  if (numLocalElements < L1 && numLocalElements != L0) {
382  // invalid
383  localChecks[0] = myImageID;
384  localChecks[1] = 1;
385  }
386  else if (numGlobalElements < GST1 && numGlobalElements != GST0 && numGlobalElements != GSTI) {
387  // invalid
388  localChecks[0] = myImageID;
389  localChecks[1] = 2;
390  }
391  else if (numGlobalElements != GSTI && numGlobalElements != global_sum) {
392  // incorrect
393  localChecks[0] = myImageID;
394  localChecks[1] = 3;
395  }
396  // now check that indexBase is equivalent across images
397  GlobalOrdinal rootIB = indexBase;
398  Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB); // broadcast one ordinal from node 0
399  if (indexBase != rootIB) {
400  localChecks[0] = myImageID;
401  localChecks[1] = 4;
402  }
403  // REDUCE_MAX will give us the image ID of the highest rank proc that DID NOT pass
404  // this will be -1 if all procs passed
405  Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
406  if (globalChecks[0] != -1) {
407  if (globalChecks[1] == 1) {
408  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
409  errPrefix << "numLocal is not valid on at least one node (possibly node "
410  << globalChecks[0] << ").");
411  }
412  else if (globalChecks[1] == 2) {
413  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
414  errPrefix << "numGlobal is not valid on at least one node (possibly node "
415  << globalChecks[0] << ").");
416  }
417  else if (globalChecks[1] == 3) {
418  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
419  errPrefix << "numGlobal doesn't match sum of numLocal (== "
420  << global_sum << ") on at least one node (possibly node "
421  << globalChecks[0] << ").");
422  }
423  else if (globalChecks[1] == 4) {
424  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
425  errPrefix << "indexBase is not the same on all nodes (examine node "
426  << globalChecks[0] << ").");
427  }
428  else {
429  // logic error on my part
430  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
431  errPrefix << "logic error. Please contact the Tpetra team.");
432  }
433  }
434 
435  }
436 
437  // set numGlobalElements
438  if (numGlobalElements == GSTI) {
439  numGlobalElements = global_sum;}
440 
441  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), static_cast<int>(numLocalElements), 1, indexBase, *toEpetra(comm))))));
442  }
443 
445  EpetraMapT(global_size_t numGlobalElements,
447  GlobalOrdinal indexBase,
448  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
449  const Teuchos::RCP< Node > &node = Teuchos::rcp(new Node))
450  {
451  if (numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid()) {
452  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(-1, static_cast<int>(elementList.size()), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
453  } else {
454  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<int>(numGlobalElements), static_cast<int>(elementList.size()), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
455  }
456  }
457 
459 
461 
462 
464  global_size_t getGlobalNumElements() const { XPETRA_MONITOR("EpetraMapT::getGlobalNumElements"); return map_->NumGlobalElements64(); }
465 
467  size_t getNodeNumElements() const { XPETRA_MONITOR("EpetraMapT::getNodeNumElements"); return map_->NumMyElements(); }
468 
470  GlobalOrdinal getIndexBase() const { XPETRA_MONITOR("EpetraMapT::getIndexBase"); return (GlobalOrdinal) map_->IndexBase64(); }
471 
473  LocalOrdinal getMinLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinLocalIndex"); return map_->MinLID(); }
474 
476  LocalOrdinal getMaxLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxLocalIndex"); return map_->MaxLID(); }
477 
479  GlobalOrdinal getMinGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinGlobalIndex"); return (GlobalOrdinal) map_->MinMyGID64(); }
480 
482  GlobalOrdinal getMaxGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxGlobalIndex"); return (GlobalOrdinal) map_->MaxMyGID64(); }
483 
485  GlobalOrdinal getMinAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinAllGlobalIndex"); return (GlobalOrdinal) map_->MinAllGID64(); }
486 
488  GlobalOrdinal getMaxAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxAllGlobalIndex"); return (GlobalOrdinal) map_->MaxAllGID64(); }
489 
491  LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::getLocalElement"); return map_->LID(globalIndex); }
492 
494  LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const { XPETRA_MONITOR("EpetraMapT::getRemoteIndexList"); return toXpetra(map_->RemoteIDList(static_cast<int>(GIDList.size()), GIDList.getRawPtr(), nodeIDList.getRawPtr(), LIDList.getRawPtr())); }
495 
497  LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const { XPETRA_MONITOR("EpetraMapT::getRemoteIndexList"); return toXpetra(map_->RemoteIDList(static_cast<int>(GIDList.size()), GIDList.getRawPtr(), nodeIDList.getRawPtr(), 0)); }
498 
502 
504 
505 
507  bool isNodeLocalElement(LocalOrdinal localIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeLocalElement"); return map_->MyLID(localIndex); }
508 
510  bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeGlobalElement"); return map_->MyGID(globalIndex); }
511 
513  bool isContiguous() const { XPETRA_MONITOR("EpetraMapT::isContiguous"); return map_->LinearMap(); }
514 
516  bool isDistributed() const { XPETRA_MONITOR("EpetraMapT::isDistributed"); return map_->DistributedGlobal(); }
517 
519  bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isCompatible"); return map_->PointSameAs(toEpetra<GlobalOrdinal,Node>(map)); }
520 
522  bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isSameAs"); return map_->SameAs(toEpetra<GlobalOrdinal,Node>(map)); }
523 
525 
527 
528 
530  Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { XPETRA_MONITOR("EpetraMapT::getComm"); return toXpetra(map_->Comm()); }
531 
534  XPETRA_MONITOR("EpetraMapT<GlobalOrdinal>::getNode");
535  return Teuchos::rcp (new Node);
536  }
537 
539 
541 
542 
544  std::string description() const {
545  XPETRA_MONITOR("EpetraMapT::description");
546 
547  // This implementation come from Tpetra_Map_def.hpp (without modification)
548  std::ostringstream oss;
550  oss << "{getGlobalNumElements() = " << getGlobalNumElements()
551  << ", getNodeNumElements() = " << getNodeNumElements()
552  << ", isContiguous() = " << isContiguous()
553  << ", isDistributed() = " << isDistributed()
554  << "}";
555  return oss.str();
556  }
557 
560  XPETRA_MONITOR("EpetraMapT::describe");
561 
563 
564  // This implementation come from Tpetra_Map_def.hpp (without modification)
565  using std::endl;
566  using std::setw;
567  using Teuchos::VERB_DEFAULT;
568  using Teuchos::VERB_NONE;
569  using Teuchos::VERB_LOW;
570  using Teuchos::VERB_MEDIUM;
571  using Teuchos::VERB_HIGH;
572  using Teuchos::VERB_EXTREME;
573 
574  const size_t nME = getNodeNumElements();
576  int myImageID = comm_->getRank();
577  int numImages = comm_->getSize();
578 
579  Teuchos::EVerbosityLevel vl = verbLevel;
580  if (vl == VERB_DEFAULT) vl = VERB_LOW;
581 
582  size_t width = 1;
583  for (size_t dec=10; dec<getGlobalNumElements(); dec *= 10) {
584  ++width;
585  }
586  width = ::std::max<size_t>(width, (size_t) 12) + 2; // casting to size_t to avoid ambiguity error when compiling Sacado.
587 
588  Teuchos::OSTab tab(out);
589 
590  if (vl == VERB_NONE) {
591  // do nothing
592  }
593  else if (vl == VERB_LOW) {
594  out << this->description() << endl;
595  }
596  else { // MEDIUM, HIGH or EXTREME
597  for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
598  if (myImageID == imageCtr) {
599  if (myImageID == 0) { // this is the root node (only output this info once)
600  out << endl
601  << "Number of Global Entries = " << getGlobalNumElements() << endl
602  << "Maximum of all GIDs = " << getMaxAllGlobalIndex() << endl
603  << "Minimum of all GIDs = " << getMinAllGlobalIndex() << endl
604  << "Index Base = " << getIndexBase() << endl;
605  }
606  out << endl;
607  if (vl == VERB_HIGH || vl == VERB_EXTREME) {
608  out << "Number of Local Elements = " << nME << endl
609  << "Maximum of my GIDs = " << getMaxGlobalIndex() << endl
610  << "Minimum of my GIDs = " << getMinGlobalIndex() << endl;
611  out << endl;
612  }
613  if (vl == VERB_EXTREME) {
614  out << std::setw(width) << "Node ID"
615  << std::setw(width) << "Local Index"
616  << std::setw(width) << "Global Index"
617  << endl;
618  for (size_t i=0; i < nME; i++) {
619  out << std::setw(width) << myImageID
620  << std::setw(width) << i
621  << std::setw(width) << myEntries[i]
622  << endl;
623  }
624  out << std::flush;
625  }
626  }
627  // Do a few global ops to give I/O a chance to complete
628  comm_->barrier();
629  comm_->barrier();
630  comm_->barrier();
631  }
632  }
633  }
634 
636 
638 
639 
642  const Epetra_BlockMap * NewMap = map_->RemoveEmptyProcesses();
643  if (!NewMap) {
644  return Teuchos::null;
645  } else {
646  const RCP< const Map<int, GlobalOrdinal, Node> > NewMapX = toXpetra<GlobalOrdinal, Node>(*NewMap);
647  delete NewMap; // NOTE: toXpetra *copys* the epetra map rather than wrapping it, so we have to delete NewMap to avoid a memory leak.
648  return NewMapX;
649  }
650  }
651 
654  throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented.");
655  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
656  }
657 
659 
661  GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const {
662  XPETRA_MONITOR("EpetraMapT::getGlobalElement");
663 
664  GlobalOrdinal gid = (GlobalOrdinal) map_->GID64(localIndex);
665  if (gid == map_->IndexBase64()-1) return (-1);
666  else return (gid);
667  }
668 
670 
671 
673  virtual ~EpetraMapT() {}
674 
677  : map_(map) {
678  TEUCHOS_TEST_FOR_EXCEPTION(!map->GlobalIndicesIsType<GlobalOrdinal>(), std::runtime_error, "Xpetra::EpetraMapT: GlobalOrdinal mismatch.");
679  }
680 
682  UnderlyingLib lib() const { return Xpetra::UseEpetra; }
683 
685  //const RCP< const Epetra_Map > & getEpetra_Map() const { return map_; }
686  const Epetra_BlockMap& getEpetra_BlockMap() const { return *map_; }
687  const Epetra_Map& getEpetra_Map() const { return (Epetra_Map &)*map_; } // Ugly, but the same is done in Epetra_CrsMatrix.h to get the map.
688 
690 
691 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
692 #ifdef HAVE_XPETRA_TPETRA
693  using local_map_type = typename Map<LocalOrdinal, GlobalOrdinal, Node>::local_map_type;
695  local_map_type getLocalMap () const {
696  if (isInitializedLocalMap_)
697  return localMap_;
698 
699  typedef GlobalOrdinal GO;
700  typedef LocalOrdinal LO;
701 
702  typedef typename Node::device_type DeviceType;
703 
704  typedef Tpetra::Details::FixedHashTable<GO, LO, DeviceType> glMapType;
705  typedef ::Kokkos::View<GO*, ::Kokkos::LayoutLeft, DeviceType> lgMapType;
706 
707  GO indexBase = getIndexBase();
708  GO myMinGID = getMinGlobalIndex();
709  GO myMaxGID = getMaxGlobalIndex();
710  bool contiguous = isContiguous();
711 
712  size_t numLocalElements = map_->NumMyElements();
713 
714  GO firstContiguousGID, lastContiguousGID;
715  glMapType glMap;
716  lgMapType lgMap;
717  if (numLocalElements) {
718  if (contiguous) {
719  // Don't need to initialize glMap and lgMap
720  firstContiguousGID = myMinGID;
721  lastContiguousGID = myMaxGID+1;
722 
723  } else {
724 
725  auto GIDs = getNodeElementList();
726 
727  lgMap = lgMapType("lgMap", numLocalElements);
728 
729  firstContiguousGID = GIDs[0];
730  lastContiguousGID = firstContiguousGID+1;
731 
732  size_t i = 1;
733  lgMap(0) = firstContiguousGID;
734  for ( ; i < numLocalElements; ++i) {
735  const GO curGID = GIDs[i];
736  const LO curLid = Teuchos::as<LO> (i);
737 
738  if (lastContiguousGID != curGID)
739  break;
740 
741  // Add the entry to the LID->GID table only after we know that
742  // the current GID is in the initial contiguous sequence, so
743  // that we don't repeat adding it in the first iteration of
744  // the loop below over the remaining noncontiguous GIDs.
745  lgMap(curLid) = curGID;
746  ++lastContiguousGID;
747  }
748  --lastContiguousGID;
749 
750  ::Kokkos::View<GO*, ::Kokkos::LayoutLeft, DeviceType>
751  nonContigGIDs ("nonContigGIDs", numLocalElements-i);
752  // FIXME_KOKKOS: relies on UVM
753  for (size_t idx = 0; idx < numLocalElements - i; idx++)
754  nonContigGIDs(idx) = GIDs[i+idx];
755 
756  glMap = glMapType (nonContigGIDs,
757  firstContiguousGID,
758  lastContiguousGID,
759  static_cast<LO> (i));
760 
761  for ( ; i < numLocalElements; ++i) {
762  const GO curGID = GIDs[i];
763  const LO curLid = Teuchos::as<LO> (i);
764 
765  lgMap(curLid) = curGID;
766  }
767  }
768 
769  } else {
770  // No elements
771  firstContiguousGID = indexBase+1;
772  lastContiguousGID = indexBase;
773  }
774  localMap_ = local_map_type(glMap, lgMap, indexBase, myMinGID, myMaxGID, firstContiguousGID, lastContiguousGID, numLocalElements, contiguous);
775 
776  isInitializedLocalMap_ = true;
777 
778  return localMap_;
779  }
780 
781  private:
782  mutable local_map_type localMap_;
783  mutable bool isInitializedLocalMap_ = false; // It's OK to use C++11 when Tpetra is enabled
784 #else
785 #ifdef __GNUC__
786 #warning "Xpetra Kokkos interface for CrsMatrix is enabled (HAVE_XPETRA_KOKKOS_REFACTOR) but Tpetra is disabled. The Kokkos interface needs Tpetra to be enabled, too."
787 #endif
788 #endif
789 #endif
790 
791  protected:
792 
794 }; // EpetraMapT class
795 #endif // #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
796 
797 // specialization on GO=long long and EpetraNode
798 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
799  template<>
800  class EpetraMapT<long long, EpetraNode>
801  : public virtual Map<int, long long, EpetraNode>
802  {
803  typedef int LocalOrdinal;
804  typedef long long GlobalOrdinal;
805  typedef EpetraNode Node;
806 
807  public:
808  typedef LocalOrdinal local_ordinal_type;
809  typedef GlobalOrdinal global_ordinal_type;
810  typedef Node node_type;
811 
813 
814 
816  EpetraMapT(global_size_t numGlobalElements,
817  GlobalOrdinal indexBase,
818  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
820  const Teuchos::RCP< Node > &node = Teuchos::rcp(new Node)) {
821  // This test come from Tpetra (Epetra doesn't check if numGlobalElements,indexBase are equivalent across images).
822  // In addition, for the test TEST_THROW(M map((myImageID == 0 ? GSTI : 0),0,comm), std::invalid_argument), only one node throw an exception and there is a dead lock.
823  std::string errPrefix;
824  errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,indexBase,comm,lOrG): ";
825 
826  if (lg == GloballyDistributed) {
827  const int myImageID = comm->getRank();
828 
829  // check that numGlobalElements,indexBase is equivalent across images
830  global_size_t rootNGE = numGlobalElements;
831  GlobalOrdinal rootIB = indexBase;
832  Teuchos::broadcast<int,global_size_t>(*comm,0,&rootNGE);
833  Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB);
834  int localChecks[2], globalChecks[2];
835  localChecks[0] = -1; // fail or pass
836  localChecks[1] = 0; // fail reason
837  if (numGlobalElements != rootNGE) {
838  localChecks[0] = myImageID;
839  localChecks[1] = 1;
840  }
841  else if (indexBase != rootIB) {
842  localChecks[0] = myImageID;
843  localChecks[1] = 2;
844  }
845  // REDUCE_MAX will give us the image ID of the highest rank proc that DID NOT pass, as well as the reason
846  // these will be -1 and 0 if all procs passed
847  Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
848  if (globalChecks[0] != -1) {
849  if (globalChecks[1] == 1) {
850  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
851  errPrefix << "numGlobal must be the same on all nodes (examine node " << globalChecks[0] << ").");
852  }
853  else if (globalChecks[1] == 2) {
854  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
855  errPrefix << "indexBase must be the same on all nodes (examine node " << globalChecks[0] << ").");
856  }
857  else {
858  // logic error on our part
859  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
860  errPrefix << "logic error. Please contact the Tpetra team.");
861  }
862  }
863  }
864 
865  // Note: validity of numGlobalElements checked by Epetra.
866 
867  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), 1, indexBase, *toEpetra(comm))))));
868  }
869 
871  EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node)) {
872  // This test come from Tpetra
873  using Teuchos::outArg;
874 
875  const size_t L0 = Teuchos::OrdinalTraits<size_t>::zero();
876  const size_t L1 = Teuchos::OrdinalTraits<size_t>::one();
880 
881  std::string errPrefix;
882  errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,numLocal,indexBase,platform): ";
883 
884  // get a internodal communicator from the Platform
885  const int myImageID = comm->getRank();
886 
887  global_size_t global_sum;
888  { // begin scoping block
889  // for communicating failures
890  int localChecks[2], globalChecks[2];
891  /* compute the global size
892  we are computing the number of global elements because exactly ONE of the following is true:
893  - the user didn't specify it, and we need it
894  - the user did specify it, but we need to
895  + validate it against the sum of the local sizes, and
896  + ensure that it is the same on all nodes
897  */
898  Teuchos::reduceAll<int,global_size_t>(*comm,Teuchos::REDUCE_SUM,
899  Teuchos::as<global_size_t>(numLocalElements),outArg(global_sum));
900  /* there are three errors we should be detecting:
901  - numGlobalElements != invalid() and it is incorrect/invalid
902  - numLocalElements invalid (<0)
903  */
904  localChecks[0] = -1;
905  localChecks[1] = 0;
906  if (numLocalElements < L1 && numLocalElements != L0) {
907  // invalid
908  localChecks[0] = myImageID;
909  localChecks[1] = 1;
910  }
911  else if (numGlobalElements < GST1 && numGlobalElements != GST0 && numGlobalElements != GSTI) {
912  // invalid
913  localChecks[0] = myImageID;
914  localChecks[1] = 2;
915  }
916  else if (numGlobalElements != GSTI && numGlobalElements != global_sum) {
917  // incorrect
918  localChecks[0] = myImageID;
919  localChecks[1] = 3;
920  }
921  // now check that indexBase is equivalent across images
922  GlobalOrdinal rootIB = indexBase;
923  Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB); // broadcast one ordinal from node 0
924  if (indexBase != rootIB) {
925  localChecks[0] = myImageID;
926  localChecks[1] = 4;
927  }
928  // REDUCE_MAX will give us the image ID of the highest rank proc that DID NOT pass
929  // this will be -1 if all procs passed
930  Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
931  if (globalChecks[0] != -1) {
932  if (globalChecks[1] == 1) {
933  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
934  errPrefix << "numLocal is not valid on at least one node (possibly node "
935  << globalChecks[0] << ").");
936  }
937  else if (globalChecks[1] == 2) {
938  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
939  errPrefix << "numGlobal is not valid on at least one node (possibly node "
940  << globalChecks[0] << ").");
941  }
942  else if (globalChecks[1] == 3) {
943  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
944  errPrefix << "numGlobal doesn't match sum of numLocal (== "
945  << global_sum << ") on at least one node (possibly node "
946  << globalChecks[0] << ").");
947  }
948  else if (globalChecks[1] == 4) {
949  TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
950  errPrefix << "indexBase is not the same on all nodes (examine node "
951  << globalChecks[0] << ").");
952  }
953  else {
954  // logic error on my part
955  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
956  errPrefix << "logic error. Please contact the Tpetra team.");
957  }
958  }
959 
960  }
961 
962  // set numGlobalElements
963  if (numGlobalElements == GSTI) {
964  numGlobalElements = global_sum;}
965 
966  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), numLocalElements, 1, indexBase, *toEpetra(comm))))));
967  }
968 
970  EpetraMapT(global_size_t numGlobalElements,
972  GlobalOrdinal indexBase,
973  const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
974  const Teuchos::RCP< Node > &node = Teuchos::rcp(new Node)) {
975  if (numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid()) {
976  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(-1, elementList.size(), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
977  } else {
978  IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(numGlobalElements, elementList.size(), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
979  }
980  }
981 
983 
985 
986 
988  global_size_t getGlobalNumElements() const { XPETRA_MONITOR("EpetraMapT::getGlobalNumElements"); return map_->NumGlobalElements64(); }
989 
991  size_t getNodeNumElements() const { XPETRA_MONITOR("EpetraMapT::getNodeNumElements"); return map_->NumMyElements(); }
992 
994  GlobalOrdinal getIndexBase() const { XPETRA_MONITOR("EpetraMapT::getIndexBase"); return (GlobalOrdinal) map_->IndexBase64(); }
995 
997  LocalOrdinal getMinLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinLocalIndex"); return map_->MinLID(); }
998 
1000  LocalOrdinal getMaxLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxLocalIndex"); return map_->MaxLID(); }
1001 
1003  GlobalOrdinal getMinGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinGlobalIndex"); return (GlobalOrdinal) map_->MinMyGID64(); }
1004 
1006  GlobalOrdinal getMaxGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxGlobalIndex"); return (GlobalOrdinal) map_->MaxMyGID64(); }
1007 
1009  GlobalOrdinal getMinAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinAllGlobalIndex"); return (GlobalOrdinal) map_->MinAllGID64(); }
1010 
1012  GlobalOrdinal getMaxAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxAllGlobalIndex"); return (GlobalOrdinal) map_->MaxAllGID64(); }
1013 
1015  LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::getLocalElement"); return map_->LID(globalIndex); }
1016 
1018  LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const { XPETRA_MONITOR("EpetraMapT::getRemoteIndexList"); return toXpetra(map_->RemoteIDList(GIDList.size(), GIDList.getRawPtr(), nodeIDList.getRawPtr(), LIDList.getRawPtr())); }
1019 
1021  LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const { XPETRA_MONITOR("EpetraMapT::getRemoteIndexList"); return toXpetra(map_->RemoteIDList(GIDList.size(), GIDList.getRawPtr(), nodeIDList.getRawPtr(), 0)); }
1022 
1024  Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const { XPETRA_MONITOR("EpetraMapT::getNodeElementList"); return ArrayView< const long long >(map_->MyGlobalElements64(), map_->NumMyElements()); }
1026 
1028 
1029 
1031  bool isNodeLocalElement(LocalOrdinal localIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeLocalElement"); return map_->MyLID(localIndex); }
1032 
1034  bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeGlobalElement"); return map_->MyGID(globalIndex); }
1035 
1037  bool isContiguous() const { XPETRA_MONITOR("EpetraMapT::isContiguous"); return map_->LinearMap(); }
1038 
1040  bool isDistributed() const { XPETRA_MONITOR("EpetraMapT::isDistributed"); return map_->DistributedGlobal(); }
1041 
1043  bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isCompatible"); return map_->PointSameAs(toEpetra<GlobalOrdinal,Node>(map)); }
1044 
1046  bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isSameAs"); return map_->SameAs(toEpetra<GlobalOrdinal,Node>(map)); }
1047 
1049 
1051 
1052 
1054  Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { XPETRA_MONITOR("EpetraMapT::getComm"); return toXpetra(map_->Comm()); }
1055 
1058  XPETRA_MONITOR("EpetraMapT<GlobalOrdinal>::getNode");
1059  return Teuchos::rcp (new Node);
1060  }
1061 
1063 
1065 
1066 
1068  std::string description() const {
1069  XPETRA_MONITOR("EpetraMapT::description");
1070 
1071  // This implementation come from Tpetra_Map_def.hpp (without modification)
1072  std::ostringstream oss;
1074  oss << "{getGlobalNumElements() = " << getGlobalNumElements()
1075  << ", getNodeNumElements() = " << getNodeNumElements()
1076  << ", isContiguous() = " << isContiguous()
1077  << ", isDistributed() = " << isDistributed()
1078  << "}";
1079  return oss.str();
1080  }
1081 
1084  XPETRA_MONITOR("EpetraMapT::describe");
1085 
1087 
1088  // This implementation come from Tpetra_Map_def.hpp (without modification)
1089  using std::endl;
1090  using std::setw;
1091  using Teuchos::VERB_DEFAULT;
1092  using Teuchos::VERB_NONE;
1093  using Teuchos::VERB_LOW;
1094  using Teuchos::VERB_MEDIUM;
1095  using Teuchos::VERB_HIGH;
1096  using Teuchos::VERB_EXTREME;
1097 
1098  const size_t nME = getNodeNumElements();
1100  int myImageID = comm_->getRank();
1101  int numImages = comm_->getSize();
1102 
1103  Teuchos::EVerbosityLevel vl = verbLevel;
1104  if (vl == VERB_DEFAULT) vl = VERB_LOW;
1105 
1106  size_t width = 1;
1107  for (size_t dec=10; dec<getGlobalNumElements(); dec *= 10) {
1108  ++width;
1109  }
1110  width = ::std::max<size_t>(width, (size_t) 12) + 2; // casting to size_t to avoid ambiguity error when compiling Sacado.
1111 
1112  Teuchos::OSTab tab(out);
1113 
1114  if (vl == VERB_NONE) {
1115  // do nothing
1116  }
1117  else if (vl == VERB_LOW) {
1118  out << this->description() << endl;
1119  }
1120  else { // MEDIUM, HIGH or EXTREME
1121  for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
1122  if (myImageID == imageCtr) {
1123  if (myImageID == 0) { // this is the root node (only output this info once)
1124  out << endl
1125  << "Number of Global Entries = " << getGlobalNumElements() << endl
1126  << "Maximum of all GIDs = " << getMaxAllGlobalIndex() << endl
1127  << "Minimum of all GIDs = " << getMinAllGlobalIndex() << endl
1128  << "Index Base = " << getIndexBase() << endl;
1129  }
1130  out << endl;
1131  if (vl == VERB_HIGH || vl == VERB_EXTREME) {
1132  out << "Number of Local Elements = " << nME << endl
1133  << "Maximum of my GIDs = " << getMaxGlobalIndex() << endl
1134  << "Minimum of my GIDs = " << getMinGlobalIndex() << endl;
1135  out << endl;
1136  }
1137  if (vl == VERB_EXTREME) {
1138  out << std::setw(width) << "Node ID"
1139  << std::setw(width) << "Local Index"
1140  << std::setw(width) << "Global Index"
1141  << endl;
1142  for (size_t i=0; i < nME; i++) {
1143  out << std::setw(width) << myImageID
1144  << std::setw(width) << i
1145  << std::setw(width) << myEntries[i]
1146  << endl;
1147  }
1148  out << std::flush;
1149  }
1150  }
1151  // Do a few global ops to give I/O a chance to complete
1152  comm_->barrier();
1153  comm_->barrier();
1154  comm_->barrier();
1155  }
1156  }
1157  }
1158 
1160 
1162 
1163 
1166  const Epetra_BlockMap * NewMap = map_->RemoveEmptyProcesses();
1167  if (!NewMap) {
1168  return Teuchos::null;
1169  } else {
1170  const RCP< const Map<int, GlobalOrdinal, Node> > NewMapX = toXpetra<GlobalOrdinal, Node>(*NewMap);
1171  delete NewMap; // NOTE: toXpetra *copys* the epetra map rather than wrapping it, so we have to delete NewMap to avoid a memory leak.
1172  return NewMapX;
1173  }
1174  }
1175 
1178  throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented.");
1179  // return Teuchos::null; // unreachable
1180  }
1181 
1183 
1185  GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const {
1186  XPETRA_MONITOR("EpetraMapT::getGlobalElement");
1187 
1188  GlobalOrdinal gid = (GlobalOrdinal) map_->GID64(localIndex);
1189  if (gid == map_->IndexBase64()-1) return (-1);
1190  else return (gid);
1191  }
1192 
1194 
1195 
1197  virtual ~EpetraMapT() {}
1198 
1201  : map_(map) {
1202  TEUCHOS_TEST_FOR_EXCEPTION(!map->GlobalIndicesIsType<GlobalOrdinal>(), std::runtime_error, "Xpetra::EpetraMapT: GlobalOrdinal mismatch.");
1203  }
1204 
1207 
1209  //const RCP< const Epetra_Map > & getEpetra_Map() const { return map_; }
1210  const Epetra_BlockMap& getEpetra_BlockMap() const { return *map_; }
1211  const Epetra_Map& getEpetra_Map() const { return (Epetra_Map &)*map_; } // Ugly, but the same is done in Epetra_CrsMatrix.h to get the map.
1212 
1213 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
1214 #ifdef HAVE_XPETRA_TPETRA
1215  using local_map_type = typename Map<LocalOrdinal, GlobalOrdinal, Node>::local_map_type;
1217  local_map_type getLocalMap () const {
1218  if (isInitializedLocalMap_)
1219  return localMap_;
1220 
1221  typedef GlobalOrdinal GO;
1222  typedef LocalOrdinal LO;
1223 
1224  typedef typename Node::device_type DeviceType;
1225 
1226  typedef Tpetra::Details::FixedHashTable<GO, LO, DeviceType> glMapType;
1227  typedef ::Kokkos::View<GO*, ::Kokkos::LayoutLeft, DeviceType> lgMapType;
1228 
1229  GO indexBase = getIndexBase();
1230  GO myMinGID = getMinGlobalIndex();
1231  GO myMaxGID = getMaxGlobalIndex();
1232  bool contiguous = isContiguous();
1233 
1234  size_t numLocalElements = map_->NumMyElements();
1235 
1236  GO firstContiguousGID, lastContiguousGID;
1237  glMapType glMap;
1238  lgMapType lgMap;
1239  if (numLocalElements) {
1240  if (contiguous) {
1241  // Don't need to initialize glMap and lgMap
1242  firstContiguousGID = myMinGID;
1243  lastContiguousGID = myMaxGID+1;
1244 
1245  } else {
1246 
1247  auto GIDs = getNodeElementList();
1248 
1249  lgMap = lgMapType("lgMap", numLocalElements);
1250 
1251  firstContiguousGID = GIDs[0];
1252  lastContiguousGID = firstContiguousGID+1;
1253 
1254  size_t i = 1;
1255  lgMap(0) = firstContiguousGID;
1256  for ( ; i < numLocalElements; ++i) {
1257  const GO curGID = GIDs[i];
1258  const LO curLid = Teuchos::as<LO> (i);
1259 
1260  if (lastContiguousGID != curGID)
1261  break;
1262 
1263  // Add the entry to the LID->GID table only after we know that
1264  // the current GID is in the initial contiguous sequence, so
1265  // that we don't repeat adding it in the first iteration of
1266  // the loop below over the remaining noncontiguous GIDs.
1267  lgMap(curLid) = curGID;
1268  ++lastContiguousGID;
1269  }
1270  --lastContiguousGID;
1271 
1272  ::Kokkos::View<GO*, ::Kokkos::LayoutLeft, DeviceType>
1273  nonContigGIDs ("nonContigGIDs", numLocalElements-i);
1274  // FIXME_KOKKOS: relies on UVM
1275  for (size_t idx = 0; idx < numLocalElements - i; idx++)
1276  nonContigGIDs(idx) = GIDs[i+idx];
1277 
1278  glMap = glMapType (nonContigGIDs,
1279  firstContiguousGID,
1280  lastContiguousGID,
1281  static_cast<LO> (i));
1282 
1283  for ( ; i < numLocalElements; ++i) {
1284  const GO curGID = GIDs[i];
1285  const LO curLid = Teuchos::as<LO> (i);
1286 
1287  lgMap(curLid) = curGID;
1288  }
1289  }
1290 
1291  } else {
1292  // No elements
1293  firstContiguousGID = indexBase+1;
1294  lastContiguousGID = indexBase;
1295  }
1296  localMap_ = local_map_type(glMap, lgMap, indexBase, myMinGID, myMaxGID, firstContiguousGID, lastContiguousGID, numLocalElements, contiguous);
1297 
1298  isInitializedLocalMap_ = true;
1299 
1300  return localMap_;
1301  }
1302 
1303  private:
1304  mutable local_map_type localMap_;
1305  mutable bool isInitializedLocalMap_ = false; // It's OK to use C++11 when Tpetra is enabled
1306 #else
1307 #ifdef __GNUC__
1308 #warning "Xpetra Kokkos interface for CrsMatrix is enabled (HAVE_XPETRA_KOKKOS_REFACTOR) but Tpetra is disabled. The Kokkos interface needs Tpetra to be enabled, too."
1309 #endif
1310 #endif
1311 #endif
1312 
1314 
1315  protected:
1316 
1318 }; // EpetraMapT class
1319 #endif // #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
1320 
1321 } // Xpetra namespace
1322 
1323 #endif // XPETRA_EPETRAMAP_HPP
int MinLID() const
GlobalOrdinal global_ordinal_type
Teuchos::RCP< Node > getNode() const
Get this Map&#39;s Node object.
int MyGlobalElements(int *MyGlobalElementList) const
bool MyLID(int lid) const
LocalOrdinal getMaxLocalIndex() const
The maximum local index on the calling process.
UnderlyingLib lib() const
Get the library used by this object (Epetra or Epetra?)
global_size_t getGlobalNumElements() const
The number of elements in this Map.
UnderlyingLib lib() const
Get the library used by this object (Epetra or Epetra?)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print this object with the given verbosity level to the given Teuchos::FancyOStream.
const Epetra_BlockMap & getEpetra_BlockMap() const
Get the underlying Epetra map.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print this object with the given verbosity level to the given Teuchos::FancyOStream.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
bool DistributedGlobal() const
std::string description() const
Return a simple one-line description of this object.
RCP< const Map< int, GlobalOrdinal, Node > > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get this Map&#39;s Comm object.
GlobalOrdinal GO
bool SameAs(const Epetra_BlockMap &Map) const
EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with a user-defined contiguous distribution.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on this process.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is valid for this Map on this process.
EpetraMapT(const Teuchos::RCP< const Epetra_BlockMap > &map)
EpetraMapT constructor to wrap a Epetra_Map object.
EpetraMapT(global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=GloballyDistributed, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with Tpetra-defined contiguous uniform distribution.
EpetraMapT(global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=GloballyDistributed, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with Tpetra-defined contiguous uniform distribution.
RCP< const Map< int, GlobalOrdinal, Node > > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const
Replace this Map&#39;s communicator with a subset communicator.
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Epetra_BlockMap * RemoveEmptyProcesses() const
Xpetra namespace
LocalOrdinal getMinLocalIndex() const
The minimum local index.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on this process.
Exception throws to report errors in the internal logical of the program.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get this Map&#39;s Comm object.
LocalOrdinal LO
const Epetra_CrsGraph & toEpetra(const RCP< const CrsGraph< int, GlobalOrdinal, Node > > &graph)
size_type size() const
RCP< const Map< int, GlobalOrdinal, Node > > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with a user-defined contiguous distribution.
EpetraMapT(const Teuchos::RCP< const Epetra_BlockMap > &map)
EpetraMapT constructor to wrap a Epetra_Map object.
const Epetra_BlockMap & getEpetra_BlockMap() const
Get the underlying Epetra map.
virtual std::string description() const
GlobalOrdinal getMaxGlobalIndex() const
The maximum global index owned by the calling process.
UnderlyingLib lib() const
Get the library used by this object (Epetra or Epetra?)
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
LocalOrdinal getMaxLocalIndex() const
The maximum local index on the calling process.
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
GlobalOrdinal getIndexBase() const
The index base for this Map.
bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is compatible with this Map.
const Epetra_Map & getEpetra_Map() const
GlobalOrdinal getIndexBase() const
The index base for this Map.
EpetraMapT(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with user-defined arbitrary (possibly noncontiguous) distribution.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on this process.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index. Note that this returns -1 if not found on this proce...
bool isContiguous() const
True if this Map is distributed contiguously, else false.
bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is identical to this Map.
bool MyGID(int GID_in) const
RCP< const Map< int, GlobalOrdinal, Node > > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const
Replace this Map&#39;s communicator with a subset communicator.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is valid for this Map on this process.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< const Map< int, GlobalOrdinal, Node > > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const
Replace this Map&#39;s communicator with a subset communicator.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is compatible with this Map.
GlobalOrdinal getIndexBase() const
The index base for this Map.
std::string description() const
Return a simple one-line description of this object.
int MaxLID() const
EpetraMapT(global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=GloballyDistributed, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with Tpetra-defined contiguous uniform distribution.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
int NumMyElements() const
bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is identical to this Map.
RCP< const Epetra_BlockMap > map_
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is valid for this Map on this process.
#define IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG(sourceCode)
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is compatible with this Map.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
const Epetra_Comm & Comm() const
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
int RemoteIDList(int NumIDs, const int *GIDList, int *PIDList, int *LIDList) const
LocalOrdinal getMinLocalIndex() const
The minimum local index.
RCP< const Epetra_BlockMap > map_
size_t global_size_t
Global size_t object.
EpetraMapT(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with user-defined arbitrary (possibly noncontiguous) distribution.
Teuchos::RCP< Node > getNode() const
Get this Map&#39;s Node object.
int LID(int GID) const
static const EVerbosityLevel verbLevel_default
global_size_t getGlobalNumElements() const
The number of elements in this Map.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print this object with the given verbosity level to the given Teuchos::FancyOStream.
EpetraMapT(const Teuchos::RCP< const Epetra_BlockMap > &map)
EpetraMapT constructor to wrap a Epetra_Map object.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
T * getRawPtr() const
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const
Return the process ranks for the given global indices.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
LocalOrdinal getMaxLocalIndex() const
The maximum local index on the calling process.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
virtual ~EpetraMapT()
Destructor.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const
Return the process ranks for the given global indices.
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
RCP< const Map< int, GlobalOrdinal, Node > > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const
Return the process ranks for the given global indices.
#define XPETRA_MONITOR(funcName)
Teuchos::RCP< Node > getNode() const
Get this Map&#39;s Node object.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with a user-defined contiguous distribution.
bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is identical to this Map.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index. Note that this returns -1 if not found on this proce...
bool LinearMap() const
const Epetra_BlockMap & getEpetra_BlockMap() const
Get the underlying Epetra map.
GlobalOrdinal getMaxGlobalIndex() const
The maximum global index owned by the calling process.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index. Note that this returns -1 if not found on this proce...
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get this Map&#39;s Comm object.
const Epetra_Map & getEpetra_Map() const
EpetraMapT(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::rcp(new Node))
Constructor with user-defined arbitrary (possibly noncontiguous) distribution.
LocalOrdinal getMinLocalIndex() const
The minimum local index.
std::string description() const
Return a simple one-line description of this object.
bool PointSameAs(const Epetra_BlockMap &Map) const
GlobalOrdinal getMaxGlobalIndex() const
The maximum global index owned by the calling process.
std::string typeName(const T &t)