00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef XPETRA_EPETRAMAP_HPP
00047 #define XPETRA_EPETRAMAP_HPP
00048
00049
00050
00051 #include "Xpetra_EpetraConfigDefs.hpp"
00052
00053 #include "Xpetra_Map.hpp"
00054
00055 #include <Epetra_Map.h>
00056 #include <Epetra_BlockMap.h>
00057
00058 #include "Xpetra_Utils.hpp"
00059 #include "Xpetra_EpetraUtils.hpp"
00060 #include "Xpetra_EpetraExceptions.hpp"
00061
00062 #include "Xpetra_ConfigDefs.hpp"
00063
00064 namespace Xpetra {
00065
00066
00067 template<class GlobalOrdinal>
00068 const Epetra_Map & toEpetra(const Map<int,GlobalOrdinal> &);
00069 template<class GlobalOrdinal>
00070 const Epetra_Map & toEpetra(const RCP< const Map<int, GlobalOrdinal> > &);
00071
00072
00073 template<class GlobalOrdinal>
00074 const RCP< const Map<int, GlobalOrdinal> > toXpetra(const Epetra_BlockMap &);
00075
00076
00077 template<class EpetraGlobalOrdinal>
00078 class EpetraMapT
00079 : public virtual Map<int, EpetraGlobalOrdinal>
00080 {
00081 typedef int LocalOrdinal;
00082 typedef EpetraGlobalOrdinal GlobalOrdinal;
00083 typedef typename Map<int, GlobalOrdinal>::node_type Node;
00084
00085 public:
00086 typedef int local_ordinal_type;
00087 typedef int global_ordinal_type;
00088 typedef Map<int, int>::node_type node_type;
00089
00090 static Teuchos::RCP<Node> defaultArgNode() {
00091
00092
00093
00094
00095
00096 return KokkosClassic::Details::getNode<Node>();
00097 }
00098
00100
00101
00103 EpetraMapT(global_size_t numGlobalElements,
00104 GlobalOrdinal indexBase,
00105 const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
00106 LocalGlobal lg=GloballyDistributed,
00107 const Teuchos::RCP< Node > &node = defaultArgNode());
00108
00110 EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=defaultArgNode());
00111
00113 EpetraMapT(global_size_t numGlobalElements,
00114 const Teuchos::ArrayView< const GlobalOrdinal > &elementList,
00115 GlobalOrdinal indexBase,
00116 const Teuchos::RCP< const Teuchos::Comm< int > > &comm,
00117 const Teuchos::RCP< Node > &node = defaultArgNode());
00118
00120
00122
00123
00125 global_size_t getGlobalNumElements() const { XPETRA_MONITOR("EpetraMapT::getGlobalNumElements"); return map_->NumGlobalElements64(); }
00126
00128 size_t getNodeNumElements() const { XPETRA_MONITOR("EpetraMapT::getNodeNumElements"); return map_->NumMyElements(); }
00129
00131 GlobalOrdinal getIndexBase() const { XPETRA_MONITOR("EpetraMapT::getIndexBase"); return (GlobalOrdinal) map_->IndexBase64(); }
00132
00134 LocalOrdinal getMinLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinLocalIndex"); return map_->MinLID(); }
00135
00137 LocalOrdinal getMaxLocalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxLocalIndex"); return map_->MaxLID(); }
00138
00140 GlobalOrdinal getMinGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinGlobalIndex"); return (GlobalOrdinal) map_->MinMyGID64(); }
00141
00143 GlobalOrdinal getMaxGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxGlobalIndex"); return (GlobalOrdinal) map_->MaxMyGID64(); }
00144
00146 GlobalOrdinal getMinAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMinAllGlobalIndex"); return (GlobalOrdinal) map_->MinAllGID64(); }
00147
00149 GlobalOrdinal getMaxAllGlobalIndex() const { XPETRA_MONITOR("EpetraMapT::getMaxAllGlobalIndex"); return (GlobalOrdinal) map_->MaxAllGID64(); }
00150
00152 LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::getLocalElement"); return map_->LID(globalIndex); }
00153
00155 LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const;
00156
00158 LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const;
00159
00161 Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const;
00162
00164
00166
00167
00169 bool isNodeLocalElement(LocalOrdinal localIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeLocalElement"); return map_->MyLID(localIndex); }
00170
00172 bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { XPETRA_MONITOR("EpetraMapT::isNodeGlobalElement"); return map_->MyGID(globalIndex); }
00173
00175 bool isContiguous() const { XPETRA_MONITOR("EpetraMapT::isContiguous"); return map_->LinearMap(); }
00176
00178 bool isDistributed() const { XPETRA_MONITOR("EpetraMapT::isDistributed"); return map_->DistributedGlobal(); }
00179
00181 bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isCompatible"); return map_->PointSameAs(toEpetra(map)); }
00182
00184 bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { XPETRA_MONITOR("EpetraMapT::isSameAs"); return map_->SameAs(toEpetra(map)); }
00185
00187
00189
00190
00192 Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { XPETRA_MONITOR("EpetraMapT::getComm"); return toXpetra(map_->Comm()); }
00193
00195 Teuchos::RCP< Node > getNode() const;
00196
00198
00200
00201
00203 std::string description() const;
00204
00206 void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const;
00207
00209
00211
00212
00214 RCP<const Map<int,GlobalOrdinal> > removeEmptyProcesses() const;
00215
00217 RCP<const Map<int,GlobalOrdinal> > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const;
00218
00220
00222 GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const {
00223 XPETRA_MONITOR("EpetraMapT::getGlobalElement");
00224
00225 GlobalOrdinal gid = (GlobalOrdinal) map_->GID64(localIndex);
00226 if (gid == map_->IndexBase64()-1) return (-1);
00227 else return (gid);
00228 }
00229
00231
00232
00234 virtual ~EpetraMapT() {}
00235
00237 EpetraMapT(const Teuchos::RCP<const Epetra_BlockMap> &map)
00238 : map_(map) {
00239 TEUCHOS_TEST_FOR_EXCEPTION(!map->GlobalIndicesIsType<GlobalOrdinal>(), std::runtime_error, "Xpetra::EpetraMapT: GlobalOrdinal mismatch.");
00240 }
00241
00243 UnderlyingLib lib() const { return Xpetra::UseEpetra; }
00244
00246
00247 const Epetra_BlockMap& getEpetra_BlockMap() const { return *map_; }
00248 const Epetra_Map& getEpetra_Map() const { return (Epetra_Map &)*map_; }
00249
00251
00252 protected:
00253
00254 RCP<const Epetra_BlockMap> map_;
00255
00256
00257
00258 };
00259
00260 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
00261 typedef EpetraMapT<int> EpetraMap;
00262 #endif
00263
00264 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
00265 typedef EpetraMapT<long long> EpetraMap64;
00266 #endif
00267
00268
00269
00270
00271
00272
00273 template<class EpetraGlobalOrdinal>
00274 EpetraMapT<EpetraGlobalOrdinal>::EpetraMapT(global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP<const Teuchos::Comm<int> > &comm,
00275 LocalGlobal lg, const Teuchos::RCP<Node> &node)
00276 {
00277
00278
00279 std::string errPrefix;
00280 errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,indexBase,comm,lOrG): ";
00281
00282 if (lg == GloballyDistributed) {
00283 const int myImageID = comm->getRank();
00284
00285
00286 global_size_t rootNGE = numGlobalElements;
00287 GlobalOrdinal rootIB = indexBase;
00288 Teuchos::broadcast<int,global_size_t>(*comm,0,&rootNGE);
00289 Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB);
00290 int localChecks[2], globalChecks[2];
00291 localChecks[0] = -1;
00292 localChecks[1] = 0;
00293 if (numGlobalElements != rootNGE) {
00294 localChecks[0] = myImageID;
00295 localChecks[1] = 1;
00296 }
00297 else if (indexBase != rootIB) {
00298 localChecks[0] = myImageID;
00299 localChecks[1] = 2;
00300 }
00301
00302
00303 Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
00304 if (globalChecks[0] != -1) {
00305 if (globalChecks[1] == 1) {
00306 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00307 errPrefix << "numGlobal must be the same on all nodes (examine node " << globalChecks[0] << ").");
00308 }
00309 else if (globalChecks[1] == 2) {
00310 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00311 errPrefix << "indexBase must be the same on all nodes (examine node " << globalChecks[0] << ").");
00312 }
00313 else {
00314
00315 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
00316 errPrefix << "logic error. Please contact the Tpetra team.");
00317 }
00318 }
00319 }
00320
00321
00322
00323 IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), 1, indexBase, *toEpetra(comm))))));
00324 }
00325
00326 template<class EpetraGlobalOrdinal>
00327 EpetraMapT<EpetraGlobalOrdinal>::EpetraMapT(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase,
00328 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, const Teuchos::RCP<Node> &node)
00329 {
00330
00331 using Teuchos::outArg;
00332
00333 const size_t L0 = Teuchos::OrdinalTraits<size_t>::zero();
00334 const size_t L1 = Teuchos::OrdinalTraits<size_t>::one();
00335 const global_size_t GST0 = Teuchos::OrdinalTraits<global_size_t>::zero();
00336 const global_size_t GST1 = Teuchos::OrdinalTraits<global_size_t>::one();
00337 const global_size_t GSTI = Teuchos::OrdinalTraits<global_size_t>::invalid();
00338
00339 std::string errPrefix;
00340 errPrefix = Teuchos::typeName(*this) + "::constructor(numGlobal,numLocal,indexBase,platform): ";
00341
00342
00343 const int myImageID = comm->getRank();
00344
00345 global_size_t global_sum;
00346 {
00347
00348 int localChecks[2], globalChecks[2];
00349
00350
00351
00352
00353
00354
00355
00356 Teuchos::reduceAll<int,global_size_t>(*comm,Teuchos::REDUCE_SUM,
00357 Teuchos::as<global_size_t>(numLocalElements),outArg(global_sum));
00358
00359
00360
00361
00362 localChecks[0] = -1;
00363 localChecks[1] = 0;
00364 if (numLocalElements < L1 && numLocalElements != L0) {
00365
00366 localChecks[0] = myImageID;
00367 localChecks[1] = 1;
00368 }
00369 else if (numGlobalElements < GST1 && numGlobalElements != GST0 && numGlobalElements != GSTI) {
00370
00371 localChecks[0] = myImageID;
00372 localChecks[1] = 2;
00373 }
00374 else if (numGlobalElements != GSTI && numGlobalElements != global_sum) {
00375
00376 localChecks[0] = myImageID;
00377 localChecks[1] = 3;
00378 }
00379
00380 GlobalOrdinal rootIB = indexBase;
00381 Teuchos::broadcast<int,GlobalOrdinal>(*comm,0,&rootIB);
00382 if (indexBase != rootIB) {
00383 localChecks[0] = myImageID;
00384 localChecks[1] = 4;
00385 }
00386
00387
00388 Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,2,localChecks,globalChecks);
00389 if (globalChecks[0] != -1) {
00390 if (globalChecks[1] == 1) {
00391 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00392 errPrefix << "numLocal is not valid on at least one node (possibly node "
00393 << globalChecks[0] << ").");
00394 }
00395 else if (globalChecks[1] == 2) {
00396 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00397 errPrefix << "numGlobal is not valid on at least one node (possibly node "
00398 << globalChecks[0] << ").");
00399 }
00400 else if (globalChecks[1] == 3) {
00401 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00402 errPrefix << "numGlobal doesn't match sum of numLocal (== "
00403 << global_sum << ") on at least one node (possibly node "
00404 << globalChecks[0] << ").");
00405 }
00406 else if (globalChecks[1] == 4) {
00407 TEUCHOS_TEST_FOR_EXCEPTION(true,std::invalid_argument,
00408 errPrefix << "indexBase is not the same on all nodes (examine node "
00409 << globalChecks[0] << ").");
00410 }
00411 else {
00412
00413 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
00414 errPrefix << "logic error. Please contact the Tpetra team.");
00415 }
00416 }
00417
00418 }
00419
00420
00421 if (numGlobalElements == GSTI) {
00422 numGlobalElements = global_sum;}
00423
00424 IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(static_cast<GlobalOrdinal>(numGlobalElements), numLocalElements, 1, indexBase, *toEpetra(comm))))));
00425 }
00426
00427
00428 template<class EpetraGlobalOrdinal>
00429 EpetraMapT<EpetraGlobalOrdinal>::EpetraMapT(global_size_t numGlobalElements, const Teuchos::ArrayView<const GlobalOrdinal> &elementList, GlobalOrdinal indexBase,
00430 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, const Teuchos::RCP<Node> &node)
00431 {
00432 if (numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid()) {
00433 IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(-1, elementList.size(), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
00434 } else {
00435 IF_EPETRA_EXCEPTION_THEN_THROW_GLOBAL_INVALID_ARG((map_ = (rcp(new Epetra_BlockMap(numGlobalElements, elementList.size(), elementList.getRawPtr(), 1, indexBase, *toEpetra(comm))))));
00436 }
00437 }
00438
00439
00440 template<class EpetraGlobalOrdinal>
00441 LookupStatus EpetraMapT<EpetraGlobalOrdinal>::getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< int > &LIDList) const { XPETRA_MONITOR("EpetraMapT::getRemoteIndexList"); return toXpetra(map_->RemoteIDList(GIDList.size(), GIDList.getRawPtr(), nodeIDList.getRawPtr(), LIDList.getRawPtr())); }
00442
00443 template<class EpetraGlobalOrdinal>
00444 LookupStatus EpetraMapT<EpetraGlobalOrdinal>::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)); }
00445
00446 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
00447 template<> inline
00448 Teuchos::ArrayView< const int > EpetraMapT<int>::getNodeElementList() const { XPETRA_MONITOR("EpetraMapT::getNodeElementList"); return ArrayView< const GlobalOrdinal >(map_->MyGlobalElements(), map_->NumMyElements()); }
00449 #endif
00450
00451 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
00452 template<> inline
00453 Teuchos::ArrayView< const long long > EpetraMapT<long long>::getNodeElementList() const { XPETRA_MONITOR("EpetraMapT::getNodeElementList"); return ArrayView< const GlobalOrdinal >(map_->MyGlobalElements64(), map_->NumMyElements()); }
00454 #endif
00455
00456 template<class EpetraGlobalOrdinal>
00457 Teuchos::RCP<typename EpetraMapT<EpetraGlobalOrdinal>::Node>
00458 EpetraMapT<EpetraGlobalOrdinal>::getNode () const
00459 {
00460 XPETRA_MONITOR("EpetraMapT<EpetraGlobalOrdinal>::getNode");
00461 return KokkosClassic::DefaultNode::getDefaultNode();
00462 }
00463
00464 template<class EpetraGlobalOrdinal>
00465 RCP<const Map<int,EpetraGlobalOrdinal> > EpetraMapT<EpetraGlobalOrdinal>::removeEmptyProcesses () const {
00466 const Epetra_BlockMap * NewMap = map_->RemoveEmptyProcesses();
00467 if (!NewMap) {
00468 return Teuchos::null;
00469 } else {
00470 const RCP< const Map<int, GlobalOrdinal> > NewMapX = toXpetra<GlobalOrdinal>(*NewMap);
00471 delete NewMap;
00472 return NewMapX;
00473 }
00474 }
00475
00476 template<class EpetraGlobalOrdinal>
00477 RCP<const Map<int,EpetraGlobalOrdinal> > EpetraMapT<EpetraGlobalOrdinal>::replaceCommWithSubset (const Teuchos::RCP<const Teuchos::Comm<int> >& newComm) const{
00478 throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented.");
00479 return Teuchos::null;
00480 }
00481
00482 template<class EpetraGlobalOrdinal>
00483 std::string EpetraMapT<EpetraGlobalOrdinal>::description() const {
00484 XPETRA_MONITOR("EpetraMapT::description");
00485
00486
00487 std::ostringstream oss;
00488 oss << Teuchos::Describable::description();
00489 oss << "{getGlobalNumElements() = " << getGlobalNumElements()
00490 << ", getNodeNumElements() = " << getNodeNumElements()
00491 << ", isContiguous() = " << isContiguous()
00492 << ", isDistributed() = " << isDistributed()
00493 << "}";
00494 return oss.str();
00495 }
00496
00497 template<class EpetraGlobalOrdinal>
00498 void EpetraMapT<EpetraGlobalOrdinal>::describe( Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const {
00499 XPETRA_MONITOR("EpetraMapT::describe");
00500
00501 const Teuchos::RCP<const Teuchos::Comm<int> > comm_ = getComm();
00502
00503
00504 using std::endl;
00505 using std::setw;
00506 using Teuchos::VERB_DEFAULT;
00507 using Teuchos::VERB_NONE;
00508 using Teuchos::VERB_LOW;
00509 using Teuchos::VERB_MEDIUM;
00510 using Teuchos::VERB_HIGH;
00511 using Teuchos::VERB_EXTREME;
00512
00513 const size_t nME = getNodeNumElements();
00514 Teuchos::ArrayView<const GlobalOrdinal> myEntries = getNodeElementList();
00515 int myImageID = comm_->getRank();
00516 int numImages = comm_->getSize();
00517
00518 Teuchos::EVerbosityLevel vl = verbLevel;
00519 if (vl == VERB_DEFAULT) vl = VERB_LOW;
00520
00521 size_t width = 1;
00522 for (size_t dec=10; dec<getGlobalNumElements(); dec *= 10) {
00523 ++width;
00524 }
00525 width = ::std::max<size_t>(width, (size_t) 12) + 2;
00526
00527 Teuchos::OSTab tab(out);
00528
00529 if (vl == VERB_NONE) {
00530
00531 }
00532 else if (vl == VERB_LOW) {
00533 out << this->description() << endl;
00534 }
00535 else {
00536 for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00537 if (myImageID == imageCtr) {
00538 if (myImageID == 0) {
00539 out << endl
00540 << "Number of Global Entries = " << getGlobalNumElements() << endl
00541 << "Maximum of all GIDs = " << getMaxAllGlobalIndex() << endl
00542 << "Minimum of all GIDs = " << getMinAllGlobalIndex() << endl
00543 << "Index Base = " << getIndexBase() << endl;
00544 }
00545 out << endl;
00546 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
00547 out << "Number of Local Elements = " << nME << endl
00548 << "Maximum of my GIDs = " << getMaxGlobalIndex() << endl
00549 << "Minimum of my GIDs = " << getMinGlobalIndex() << endl;
00550 out << endl;
00551 }
00552 if (vl == VERB_EXTREME) {
00553 out << std::setw(width) << "Node ID"
00554 << std::setw(width) << "Local Index"
00555 << std::setw(width) << "Global Index"
00556 << endl;
00557 for (size_t i=0; i < nME; i++) {
00558 out << std::setw(width) << myImageID
00559 << std::setw(width) << i
00560 << std::setw(width) << myEntries[i]
00561 << endl;
00562 }
00563 out << std::flush;
00564 }
00565 }
00566
00567 comm_->barrier();
00568 comm_->barrier();
00569 comm_->barrier();
00570 }
00571 }
00572 }
00573
00574
00575
00576
00577 }
00578
00579 #endif // XPETRA_EPETRAMAP_HPP