47 #ifndef TPETRA_MAP_DEF_HPP 48 #define TPETRA_MAP_DEF_HPP 50 #include "Tpetra_Directory.hpp" 51 #include "Tpetra_Details_FixedHashTable.hpp" 52 #include "Tpetra_Details_gathervPrint.hpp" 56 #include "Teuchos_as.hpp" 57 #include "Teuchos_TypeNameTraits.hpp" 58 #include "Teuchos_CommHelpers.hpp" 59 #include "Tpetra_Details_mpiIsInitialized.hpp" 68 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
71 comm_ (new
Teuchos::SerialComm<int> ()),
73 numGlobalElements_ (0),
74 numLocalElements_ (0),
75 minMyGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
76 maxMyGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
77 minAllGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
78 maxAllGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
79 firstContiguousGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
80 lastContiguousGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
84 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
89 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
92 GlobalOrdinal indexBase,
93 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
95 const Teuchos::RCP<Node> &node) :
98 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
101 using Teuchos::broadcast;
102 using Teuchos::outArg;
103 using Teuchos::reduceAll;
104 using Teuchos::REDUCE_MIN;
105 using Teuchos::REDUCE_MAX;
106 using Teuchos::typeName;
107 typedef GlobalOrdinal GO;
109 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
113 #ifdef HAVE_TPETRA_DEBUG 117 GST proc0NumGlobalElements = numGlobalElements;
118 broadcast<int, GST> (*comm_, 0, outArg (proc0NumGlobalElements));
119 GST minNumGlobalElements = numGlobalElements;
120 GST maxNumGlobalElements = numGlobalElements;
121 reduceAll<int, GST> (*comm, REDUCE_MIN, numGlobalElements, outArg (minNumGlobalElements));
122 reduceAll<int, GST> (*comm, REDUCE_MAX, numGlobalElements, outArg (maxNumGlobalElements));
123 TEUCHOS_TEST_FOR_EXCEPTION(
124 minNumGlobalElements != maxNumGlobalElements || numGlobalElements != minNumGlobalElements,
125 std::invalid_argument,
126 "Tpetra::Map constructor: All processes must provide the same number " 127 "of global elements. Process 0 set numGlobalElements = " 128 << proc0NumGlobalElements <<
". The calling process " 129 << comm->getRank () <<
" set numGlobalElements = " << numGlobalElements
130 <<
". The min and max values over all processes are " 131 << minNumGlobalElements <<
" resp. " << maxNumGlobalElements <<
".");
133 GO proc0IndexBase = indexBase;
134 broadcast<int, GO> (*comm_, 0, outArg (proc0IndexBase));
135 GO minIndexBase = indexBase;
136 GO maxIndexBase = indexBase;
137 reduceAll<int, GO> (*comm, REDUCE_MIN, indexBase, outArg (minIndexBase));
138 reduceAll<int, GO> (*comm, REDUCE_MAX, indexBase, outArg (maxIndexBase));
139 TEUCHOS_TEST_FOR_EXCEPTION(
140 minIndexBase != maxIndexBase || indexBase != minIndexBase,
141 std::invalid_argument,
142 "Tpetra::Map constructor: " 143 "All processes must provide the same indexBase argument. " 144 "Process 0 set indexBase = " << proc0IndexBase <<
". The calling " 145 "process " << comm->getRank () <<
" set indexBase = " << indexBase
146 <<
". The min and max values over all processes are " 147 << minIndexBase <<
" resp. " << maxIndexBase <<
".");
149 #endif // HAVE_TPETRA_DEBUG 168 TEUCHOS_TEST_FOR_EXCEPTION(
169 (numGlobalElements < 1 && numGlobalElements != 0),
170 std::invalid_argument,
171 "Tpetra::Map constructor: numGlobalElements (= " 172 << numGlobalElements <<
") must be nonnegative.");
174 TEUCHOS_TEST_FOR_EXCEPTION(
175 numGlobalElements == GSTI, std::invalid_argument,
176 "Tpetra::Map constructor: You provided numGlobalElements = Teuchos::" 177 "OrdinalTraits<Tpetra::global_size_t>::invalid(). This version of the " 178 "constructor requires a valid value of numGlobalElements. You " 179 "probably mistook this constructor for the \"contiguous nonuniform\" " 180 "constructor, which can compute the global number of elements for you " 181 "if you set numGlobalElements to that value.");
183 size_t numLocalElements = 0;
184 if (lOrG == GloballyDistributed) {
199 const GST numProcs =
static_cast<GST
> (comm_->getSize ());
200 const GST myRank =
static_cast<GST
> (comm_->getRank ());
201 const GST quotient = numGlobalElements / numProcs;
202 const GST remainder = numGlobalElements - quotient * numProcs;
205 if (myRank < remainder) {
206 numLocalElements =
static_cast<size_t> (1) + static_cast<size_t> (quotient);
209 startIndex = as<GO> (myRank) * as<GO> (numLocalElements);
211 numLocalElements = as<size_t> (quotient);
212 startIndex = as<GO> (myRank) * as<GO> (numLocalElements) +
216 minMyGID_ = indexBase + startIndex;
217 maxMyGID_ = indexBase + startIndex + numLocalElements - 1;
218 minAllGID_ = indexBase;
219 maxAllGID_ = indexBase + numGlobalElements - 1;
220 distributed_ = (numProcs > 1);
223 numLocalElements = as<size_t> (numGlobalElements);
224 minMyGID_ = indexBase;
225 maxMyGID_ = indexBase + numGlobalElements - 1;
226 distributed_ =
false;
229 minAllGID_ = indexBase;
230 maxAllGID_ = indexBase + numGlobalElements - 1;
231 indexBase_ = indexBase;
232 numGlobalElements_ = numGlobalElements;
233 numLocalElements_ = numLocalElements;
234 firstContiguousGID_ = minMyGID_;
235 lastContiguousGID_ = maxMyGID_;
242 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
245 size_t numLocalElements,
246 GlobalOrdinal indexBase,
247 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
248 const Teuchos::RCP<Node> &node) :
251 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
254 using Teuchos::broadcast;
255 using Teuchos::outArg;
256 using Teuchos::reduceAll;
257 using Teuchos::REDUCE_MIN;
258 using Teuchos::REDUCE_MAX;
259 using Teuchos::REDUCE_SUM;
261 typedef GlobalOrdinal GO;
263 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
267 #ifdef HAVE_TPETRA_DEBUG 270 const GST debugGlobalSum =
271 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
273 #endif // HAVE_TPETRA_DEBUG 287 scan<int, GO> (*comm, REDUCE_SUM, numLocalElements, outArg (scanResult));
288 const GO myOffset = scanResult - numLocalElements;
290 if (numGlobalElements != GSTI) {
291 numGlobalElements_ = numGlobalElements;
297 const int numProcs = comm->getSize ();
298 GST globalSum = scanResult;
300 broadcast (*comm, numProcs - 1, outArg (globalSum));
302 numGlobalElements_ = globalSum;
304 #ifdef HAVE_TPETRA_DEBUG 306 TEUCHOS_TEST_FOR_EXCEPTION(
307 globalSum != debugGlobalSum, std::logic_error,
308 "Tpetra::Map constructor (contiguous nonuniform): " 309 "globalSum = " << globalSum <<
" != debugGlobalSum = " << debugGlobalSum
310 <<
". Please report this bug to the Tpetra developers.");
311 #endif // HAVE_TPETRA_DEBUG 313 numLocalElements_ = numLocalElements;
314 indexBase_ = indexBase;
315 minAllGID_ = (numGlobalElements_ == 0) ?
316 std::numeric_limits<GO>::max () :
318 maxAllGID_ = (numGlobalElements_ == 0) ?
319 std::numeric_limits<GO>::lowest () :
320 indexBase +
static_cast<GO
> (numGlobalElements_) - static_cast<GO> (1);
321 minMyGID_ = (numLocalElements_ == 0) ?
322 std::numeric_limits<GO>::max () :
323 indexBase +
static_cast<GO
> (myOffset);
324 maxMyGID_ = (numLocalElements_ == 0) ?
325 std::numeric_limits<GO>::lowest () :
326 indexBase + myOffset +
static_cast<GO
> (numLocalElements) - static_cast<GO> (1);
327 firstContiguousGID_ = minMyGID_;
328 lastContiguousGID_ = maxMyGID_;
330 distributed_ = checkIsDist ();
336 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
340 const size_t numLocalElements,
341 const GlobalOrdinal indexBase,
342 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
const 344 #ifdef HAVE_TPETRA_DEBUG 345 using Teuchos::broadcast;
346 using Teuchos::outArg;
348 using Teuchos::REDUCE_MAX;
349 using Teuchos::REDUCE_MIN;
350 using Teuchos::REDUCE_SUM;
351 using Teuchos::reduceAll;
352 typedef GlobalOrdinal GO;
354 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
364 GST debugGlobalSum = 0;
365 reduceAll<int, GST> (*comm, REDUCE_SUM,
static_cast<GST
> (numLocalElements),
366 outArg (debugGlobalSum));
370 GST proc0NumGlobalElements = numGlobalElements;
371 broadcast<int, GST> (*comm_, 0, outArg (proc0NumGlobalElements));
372 GST minNumGlobalElements = numGlobalElements;
373 GST maxNumGlobalElements = numGlobalElements;
374 reduceAll<int, GST> (*comm, REDUCE_MIN, numGlobalElements,
375 outArg (minNumGlobalElements));
376 reduceAll<int, GST> (*comm, REDUCE_MAX, numGlobalElements,
377 outArg (maxNumGlobalElements));
378 TEUCHOS_TEST_FOR_EXCEPTION(
379 minNumGlobalElements != maxNumGlobalElements ||
380 numGlobalElements != minNumGlobalElements,
381 std::invalid_argument,
382 "Tpetra::Map constructor: All processes must provide the same number " 383 "of global elements. This is true even if that argument is Teuchos::" 384 "OrdinalTraits<global_size_t>::invalid() to signal that the Map should " 385 "compute the global number of elements. Process 0 set numGlobalElements" 386 " = " << proc0NumGlobalElements <<
". The calling process " 387 << comm->getRank () <<
" set numGlobalElements = " << numGlobalElements
388 <<
". The min and max values over all processes are " 389 << minNumGlobalElements <<
" resp. " << maxNumGlobalElements <<
".");
391 GO proc0IndexBase = indexBase;
392 broadcast<int, GO> (*comm_, 0, outArg (proc0IndexBase));
393 GO minIndexBase = indexBase;
394 GO maxIndexBase = indexBase;
395 reduceAll<int, GO> (*comm, REDUCE_MIN, indexBase, outArg (minIndexBase));
396 reduceAll<int, GO> (*comm, REDUCE_MAX, indexBase, outArg (maxIndexBase));
397 TEUCHOS_TEST_FOR_EXCEPTION(
398 minIndexBase != maxIndexBase || indexBase != minIndexBase,
399 std::invalid_argument,
400 "Tpetra::Map constructor: " 401 "All processes must provide the same indexBase argument. " 402 "Process 0 set indexBase = " << proc0IndexBase <<
". The calling " 403 "process " << comm->getRank () <<
" set indexBase = " << indexBase
404 <<
". The min and max values over all processes are " 405 << minIndexBase <<
" resp. " << maxIndexBase <<
".");
409 TEUCHOS_TEST_FOR_EXCEPTION
410 (numGlobalElements != GSTI && debugGlobalSum != numGlobalElements,
411 std::invalid_argument,
"Tpetra::Map constructor: The sum of each " 412 "process' number of indices over all processes, " << debugGlobalSum
413 <<
" != numGlobalElements = " << numGlobalElements <<
". If you " 414 "would like this constructor to compute numGlobalElements for you, " 415 "you may set numGlobalElements = " 416 "Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid() on input. " 417 "Please note that this is NOT necessarily -1.");
420 return debugGlobalSum;
423 #endif // HAVE_TPETRA_DEBUG 426 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
430 const Kokkos::View<
const GlobalOrdinal*,
433 Kokkos::MemoryUnmanaged>& entryList_host,
434 const GlobalOrdinal indexBase,
435 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
437 using Kokkos::LayoutLeft;
438 using Kokkos::subview;
441 using Teuchos::broadcast;
442 using Teuchos::outArg;
444 using Teuchos::REDUCE_MAX;
445 using Teuchos::REDUCE_MIN;
446 using Teuchos::REDUCE_SUM;
447 using Teuchos::reduceAll;
448 typedef LocalOrdinal LO;
449 typedef GlobalOrdinal GO;
451 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
454 TEUCHOS_TEST_FOR_EXCEPTION
455 (! Kokkos::is_initialized (), std::runtime_error,
456 "Tpetra::Map constructor: The Kokkos execution space " 457 << Teuchos::TypeNameTraits<execution_space>::name ()
458 <<
" has not been initialized. " 459 "Please initialize it before creating a Map.")
472 const size_t numLocalElements =
static_cast<size_t> (entryList_host.size ());
474 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
485 if (numGlobalElements != GSTI) {
486 numGlobalElements_ = numGlobalElements;
489 reduceAll<int, GST> (*comm, REDUCE_SUM,
490 static_cast<GST
> (numLocalElements),
491 outArg (numGlobalElements_));
517 numLocalElements_ = numLocalElements;
518 indexBase_ = indexBase;
520 minMyGID_ = indexBase_;
521 maxMyGID_ = indexBase_;
531 if (numLocalElements_ > 0) {
535 View<GO*, LayoutLeft, device_type> lgMap (
"lgMap", numLocalElements_);
536 auto lgMap_host = Kokkos::create_mirror_view (lgMap);
543 firstContiguousGID_ = entryList_host[0];
544 lastContiguousGID_ = firstContiguousGID_+1;
552 lgMap_host[0] = firstContiguousGID_;
554 for ( ; i < numLocalElements_; ++i) {
555 const GO curGid = entryList_host[i];
556 const LO curLid = as<LO> (i);
558 if (lastContiguousGID_ != curGid)
break;
564 lgMap_host[curLid] = curGid;
565 ++lastContiguousGID_;
567 --lastContiguousGID_;
572 minMyGID_ = firstContiguousGID_;
573 maxMyGID_ = lastContiguousGID_;
578 const std::pair<size_t, size_t> ncRange (i, entryList_host.extent (0));
579 auto nonContigGids_host = subview (entryList_host, ncRange);
580 TEUCHOS_TEST_FOR_EXCEPTION
581 (static_cast<size_t> (nonContigGids_host.extent (0)) !=
582 static_cast<size_t> (entryList_host.extent (0) - i),
583 std::logic_error,
"Tpetra::Map noncontiguous constructor: " 584 "nonContigGids_host.extent(0) = " 585 << nonContigGids_host.extent (0)
586 <<
" != entryList_host.extent(0) - i = " 587 << (entryList_host.extent (0) - i) <<
" = " 588 << entryList_host.extent (0) <<
" - " << i
589 <<
". Please report this bug to the Tpetra developers.");
593 View<GO*, LayoutLeft, device_type>
594 nonContigGids (
"nonContigGids", nonContigGids_host.size ());
600 static_cast<LO> (i));
608 for ( ; i < numLocalElements_; ++i) {
609 const GO curGid = entryList_host[i];
610 const LO curLid = as<LO> (i);
611 lgMap_host[curLid] = curGid;
615 if (curGid < minMyGID_) {
618 if (curGid > maxMyGID_) {
629 lgMapHost_ = lgMap_host;
632 minMyGID_ = std::numeric_limits<GlobalOrdinal>::max();
633 maxMyGID_ = std::numeric_limits<GlobalOrdinal>::lowest();
637 firstContiguousGID_ = indexBase_+1;
638 lastContiguousGID_ = indexBase_;
663 if (std::numeric_limits<GO>::is_signed) {
666 (as<GST> (numLocalElements_) < numGlobalElements_) ? 1 : 0;
669 minMaxInput[0] = -minMyGID_;
670 minMaxInput[1] = maxMyGID_;
671 minMaxInput[2] = localDist;
677 reduceAll<int, GO> (*comm, REDUCE_MAX, 3, minMaxInput, minMaxOutput);
678 minAllGID_ = -minMaxOutput[0];
679 maxAllGID_ = minMaxOutput[1];
680 const GO globalDist = minMaxOutput[2];
681 distributed_ = (comm_->getSize () > 1 && globalDist == 1);
685 reduceAll<int, GO> (*comm_, REDUCE_MIN, minMyGID_, outArg (minAllGID_));
686 reduceAll<int, GO> (*comm_, REDUCE_MAX, maxMyGID_, outArg (maxAllGID_));
687 distributed_ = checkIsDist ();
692 TEUCHOS_TEST_FOR_EXCEPTION(
693 minAllGID_ < indexBase_,
694 std::invalid_argument,
695 "Tpetra::Map constructor (noncontiguous): " 696 "Minimum global ID = " << minAllGID_ <<
" over all process(es) is " 697 "less than the given indexBase = " << indexBase_ <<
".");
703 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
706 const GlobalOrdinal indexList[],
707 const LocalOrdinal indexListSize,
708 const GlobalOrdinal indexBase,
709 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) :
712 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
719 const GlobalOrdinal*
const indsRaw = indexListSize == 0 ? NULL : indexList;
720 Kokkos::View<
const GlobalOrdinal*,
723 Kokkos::MemoryUnmanaged> inds (indsRaw, indexListSize);
724 initWithNonownedHostIndexList (numGlobalElements, inds, indexBase, comm);
727 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
730 const Teuchos::ArrayView<const GlobalOrdinal>& entryList,
731 const GlobalOrdinal indexBase,
732 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
733 const Teuchos::RCP<Node>& node) :
736 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
740 const size_t numLclInds =
static_cast<size_t> (entryList.size ());
745 const GlobalOrdinal*
const indsRaw =
746 numLclInds == 0 ? NULL : entryList.getRawPtr ();
747 Kokkos::View<
const GlobalOrdinal*,
750 Kokkos::MemoryUnmanaged> inds (indsRaw, numLclInds);
751 initWithNonownedHostIndexList (numGlobalElements, inds, indexBase, comm);
754 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
757 const Kokkos::View<const GlobalOrdinal*, device_type>& entryList,
758 const GlobalOrdinal indexBase,
759 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) :
762 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
764 using Kokkos::LayoutLeft;
765 using Kokkos::subview;
768 using Teuchos::ArrayView;
770 using Teuchos::broadcast;
771 using Teuchos::outArg;
773 using Teuchos::REDUCE_MAX;
774 using Teuchos::REDUCE_MIN;
775 using Teuchos::REDUCE_SUM;
776 using Teuchos::reduceAll;
777 using Teuchos::typeName;
778 typedef LocalOrdinal LO;
779 typedef GlobalOrdinal GO;
781 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
796 const size_t numLocalElements =
static_cast<size_t> (entryList.size ());
798 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
809 if (numGlobalElements != GSTI) {
810 numGlobalElements_ = numGlobalElements;
813 reduceAll<int, GST> (*comm, REDUCE_SUM,
814 static_cast<GST
> (numLocalElements),
815 outArg (numGlobalElements_));
841 numLocalElements_ = numLocalElements;
842 indexBase_ = indexBase;
844 minMyGID_ = indexBase_;
845 maxMyGID_ = indexBase_;
855 if (numLocalElements_ > 0) {
859 View<GO*, LayoutLeft, device_type> lgMap (
"lgMap", numLocalElements_);
860 auto lgMap_host = Kokkos::create_mirror_view (lgMap);
864 auto entryList_host = Kokkos::create_mirror_view (entryList);
867 firstContiguousGID_ = entryList_host[0];
868 lastContiguousGID_ = firstContiguousGID_+1;
876 lgMap_host[0] = firstContiguousGID_;
878 for ( ; i < numLocalElements_; ++i) {
879 const GO curGid = entryList_host[i];
880 const LO curLid = as<LO> (i);
882 if (lastContiguousGID_ != curGid)
break;
888 lgMap_host[curLid] = curGid;
889 ++lastContiguousGID_;
891 --lastContiguousGID_;
896 minMyGID_ = firstContiguousGID_;
897 maxMyGID_ = lastContiguousGID_;
902 const std::pair<size_t, size_t> ncRange (i, entryList.extent (0));
903 auto nonContigGids = subview (entryList, ncRange);
904 TEUCHOS_TEST_FOR_EXCEPTION
905 (static_cast<size_t> (nonContigGids.extent (0)) !=
906 static_cast<size_t> (entryList.extent (0) - i),
907 std::logic_error,
"Tpetra::Map noncontiguous constructor: " 908 "nonContigGids.extent(0) = " 909 << nonContigGids.extent (0)
910 <<
" != entryList.extent(0) - i = " 911 << (entryList.extent (0) - i) <<
" = " 912 << entryList.extent (0) <<
" - " << i
913 <<
". Please report this bug to the Tpetra developers.");
918 static_cast<LO> (i));
926 for ( ; i < numLocalElements_; ++i) {
927 const GO curGid = entryList_host[i];
928 const LO curLid =
static_cast<LO
> (i);
929 lgMap_host[curLid] = curGid;
933 if (curGid < minMyGID_) {
936 if (curGid > maxMyGID_) {
947 lgMapHost_ = lgMap_host;
950 minMyGID_ = std::numeric_limits<GlobalOrdinal>::max();
951 maxMyGID_ = std::numeric_limits<GlobalOrdinal>::lowest();
955 firstContiguousGID_ = indexBase_+1;
956 lastContiguousGID_ = indexBase_;
981 if (std::numeric_limits<GO>::is_signed) {
984 (as<GST> (numLocalElements_) < numGlobalElements_) ? 1 : 0;
987 minMaxInput[0] = -minMyGID_;
988 minMaxInput[1] = maxMyGID_;
989 minMaxInput[2] = localDist;
995 reduceAll<int, GO> (*comm, REDUCE_MAX, 3, minMaxInput, minMaxOutput);
996 minAllGID_ = -minMaxOutput[0];
997 maxAllGID_ = minMaxOutput[1];
998 const GO globalDist = minMaxOutput[2];
999 distributed_ = (comm_->getSize () > 1 && globalDist == 1);
1003 reduceAll<int, GO> (*comm_, REDUCE_MIN, minMyGID_, outArg (minAllGID_));
1004 reduceAll<int, GO> (*comm_, REDUCE_MAX, maxMyGID_, outArg (maxAllGID_));
1005 distributed_ = checkIsDist ();
1008 contiguous_ =
false;
1010 TEUCHOS_TEST_FOR_EXCEPTION(
1011 minAllGID_ < indexBase_,
1012 std::invalid_argument,
1013 "Tpetra::Map constructor (noncontiguous): " 1014 "Minimum global ID = " << minAllGID_ <<
" over all process(es) is " 1015 "less than the given indexBase = " << indexBase_ <<
".");
1022 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1025 if (! Kokkos::is_initialized ()) {
1026 std::ostringstream os;
1027 os <<
"WARNING: Tpetra::Map destructor (~Map()) is being called after " 1028 "Kokkos::finalize() has been called. This is user error! There are " 1029 "two likely causes: " << std::endl <<
1030 " 1. You have a static Tpetra::Map (or RCP or shared_ptr of a Map)" 1032 " 2. You declare and construct a Tpetra::Map (or RCP or shared_ptr " 1033 "of a Tpetra::Map) at the same scope in main() as Kokkos::finalize() " 1034 "or Tpetra::finalize()." << std::endl << std::endl <<
1035 "Don't do either of these! Please refer to GitHib Issue #2372." 1037 ::Tpetra::Details::printOnce (std::cerr, os.str (),
1038 this->getComm ().getRawPtr ());
1041 using ::Tpetra::Details::mpiIsInitialized;
1042 using ::Tpetra::Details::mpiIsFinalized;
1043 using ::Tpetra::Details::teuchosCommIsAnMpiComm;
1045 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getComm ();
1046 if (! comm.is_null () && teuchosCommIsAnMpiComm (*comm) &&
1047 mpiIsInitialized () && mpiIsFinalized ()) {
1053 std::ostringstream os;
1054 os <<
"WARNING: Tpetra::Map destructor (~Map()) is being called after " 1055 "MPI_Finalize() has been called. This is user error! There are " 1056 "two likely causes: " << std::endl <<
1057 " 1. You have a static Tpetra::Map (or RCP or shared_ptr of a Map)" 1059 " 2. You declare and construct a Tpetra::Map (or RCP or shared_ptr " 1060 "of a Tpetra::Map) at the same scope in main() as MPI_finalize() or " 1061 "Tpetra::finalize()." << std::endl << std::endl <<
1062 "Don't do either of these! Please refer to GitHib Issue #2372." 1064 ::Tpetra::Details::printOnce (std::cerr, os.str (), comm.getRawPtr ());
1073 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1077 TEUCHOS_TEST_FOR_EXCEPTION(
1078 getComm ().is_null (), std::logic_error,
"Tpetra::Map::isOneToOne: " 1079 "getComm() returns null. Please report this bug to the Tpetra " 1084 return directory_->isOneToOne (*
this);
1088 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1093 if (isContiguous ()) {
1094 if (globalIndex < getMinGlobalIndex () ||
1095 globalIndex > getMaxGlobalIndex ()) {
1096 return Tpetra::Details::OrdinalTraits<LocalOrdinal>::invalid ();
1098 return static_cast<LocalOrdinal
> (globalIndex - getMinGlobalIndex ());
1100 else if (globalIndex >= firstContiguousGID_ &&
1101 globalIndex <= lastContiguousGID_) {
1102 return static_cast<LocalOrdinal
> (globalIndex - firstContiguousGID_);
1107 return glMap_.get (globalIndex);
1111 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1116 if (localIndex < getMinLocalIndex () || localIndex > getMaxLocalIndex ()) {
1117 return Tpetra::Details::OrdinalTraits<GlobalOrdinal>::invalid ();
1119 if (isContiguous ()) {
1120 return getMinGlobalIndex () + localIndex;
1127 return lgMapHost_[localIndex];
1131 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1136 if (localIndex < getMinLocalIndex () || localIndex > getMaxLocalIndex ()) {
1143 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1147 return this->getLocalElement (globalIndex) !=
1148 Tpetra::Details::OrdinalTraits<LocalOrdinal>::invalid ();
1151 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1156 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1162 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1168 getMinGlobalIndex (), getMaxGlobalIndex (),
1169 firstContiguousGID_, lastContiguousGID_,
1170 getNodeNumElements (), isContiguous ());
1173 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1178 using Teuchos::outArg;
1179 using Teuchos::REDUCE_MIN;
1180 using Teuchos::reduceAll;
1190 else if (getComm ()->getSize () != map.
getComm ()->getSize ()) {
1201 else if (isContiguous () && isUniform () &&
1209 lgMap_.extent (0) != 0 && map.lgMap_.extent (0) != 0 &&
1210 lgMap_.data () == map.lgMap_.data ()) {
1224 TEUCHOS_TEST_FOR_EXCEPTION(
1226 "Tpetra::Map::isCompatible: There's a bug in this method. We've already " 1227 "checked that this condition is true above, but it's false here. " 1228 "Please report this bug to the Tpetra developers.");
1231 const int locallyCompat =
1234 int globallyCompat = 0;
1235 reduceAll<int, int> (*comm_, REDUCE_MIN, locallyCompat, outArg (globallyCompat));
1236 return (globallyCompat == 1);
1239 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1244 using Teuchos::ArrayView;
1245 typedef GlobalOrdinal GO;
1246 typedef typename ArrayView<const GO>::size_type size_type;
1269 if (isContiguous ()) {
1274 TEUCHOS_TEST_FOR_EXCEPTION(
1275 ! this->isContiguous () || map.
isContiguous (), std::logic_error,
1276 "Tpetra::Map::locallySameAs: BUG");
1278 const GO minLhsGid = this->getMinGlobalIndex ();
1279 const size_type numRhsElts = rhsElts.size ();
1280 for (size_type k = 0; k < numRhsElts; ++k) {
1281 const GO curLhsGid = minLhsGid +
static_cast<GO
> (k);
1282 if (curLhsGid != rhsElts[k]) {
1290 TEUCHOS_TEST_FOR_EXCEPTION(
1291 this->isContiguous () || ! map.
isContiguous (), std::logic_error,
1292 "Tpetra::Map::locallySameAs: BUG");
1293 ArrayView<const GO> lhsElts = this->getNodeElementList ();
1295 const size_type numLhsElts = lhsElts.size ();
1296 for (size_type k = 0; k < numLhsElts; ++k) {
1297 const GO curRhsGid = minRhsGid +
static_cast<GO
> (k);
1298 if (curRhsGid != lhsElts[k]) {
1304 else if (this->lgMap_.data () == map.lgMap_.data ()) {
1314 ArrayView<const GO> lhsElts = getNodeElementList ();
1320 return std::equal (lhsElts.begin (), lhsElts.end (), rhsElts.begin ());
1326 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1336 auto lmap2 = this->getLocalMap();
1338 auto numLocalElements1 = lmap1.getNodeNumElements();
1339 auto numLocalElements2 = lmap2.getNodeNumElements();
1341 if (numLocalElements1 > numLocalElements2) {
1346 if (lmap1.isContiguous () && lmap2.isContiguous ()) {
1348 return ((lmap1.getMinGlobalIndex () == lmap2.getMinGlobalIndex ()) &&
1349 (lmap1.getMaxGlobalIndex () <= lmap2.getMaxGlobalIndex ()));
1352 if (lmap1.getMinGlobalIndex () < lmap2.getMinGlobalIndex () ||
1353 lmap1.getMaxGlobalIndex () > lmap2.getMaxGlobalIndex ()) {
1359 typedef Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space> range_type;
1362 LocalOrdinal numDiff = 0;
1363 Kokkos::parallel_reduce(
"isLocallyFitted", range_type(0, numLocalElements1),
1364 KOKKOS_LAMBDA(
const LocalOrdinal i, LocalOrdinal& diff) {
1365 diff += (lmap1.getGlobalElement(i) != lmap2.getGlobalElement(i));
1368 return (numDiff == 0);
1371 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1376 using Teuchos::outArg;
1377 using Teuchos::REDUCE_MIN;
1378 using Teuchos::reduceAll;
1388 else if (getComm ()->getSize () != map.
getComm ()->getSize ()) {
1411 else if (isContiguous () && isUniform () &&
1432 const int isSame_lcl = locallySameAs (map) ? 1 : 0;
1436 reduceAll<int, int> (*comm_, REDUCE_MIN, isSame_lcl, outArg (isSame_gbl));
1437 return isSame_gbl == 1;
1441 template <
class LO,
class GO,
class DT>
1444 FillLgMap (
const Kokkos::View<GO*, DT>& lgMap,
1445 const GO startGid) :
1446 lgMap_ (lgMap), startGid_ (startGid)
1448 Kokkos::RangePolicy<LO, typename DT::execution_space>
1449 range (static_cast<LO> (0), static_cast<LO> (lgMap.size ()));
1450 Kokkos::parallel_for (range, *
this);
1453 KOKKOS_INLINE_FUNCTION
void operator () (
const LO& lid)
const {
1454 lgMap_(lid) = startGid_ +
static_cast<GO
> (lid);
1458 const Kokkos::View<GO*, DT> lgMap_;
1465 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1466 typename Map<LocalOrdinal,GlobalOrdinal,Node>::global_indices_array_type
1469 typedef LocalOrdinal LO;
1470 typedef GlobalOrdinal GO;
1473 typedef decltype (lgMap_) const_lg_view_type;
1474 typedef typename const_lg_view_type::non_const_type lg_view_type;
1479 const bool needToCreateLocalToGlobalMapping =
1480 lgMap_.extent (0) == 0 && numLocalElements_ > 0;
1482 if (needToCreateLocalToGlobalMapping) {
1483 #ifdef HAVE_TEUCHOS_DEBUG 1486 TEUCHOS_TEST_FOR_EXCEPTION( ! isContiguous(), std::logic_error,
1487 "Tpetra::Map::getNodeElementList: The local-to-global mapping (lgMap_) " 1488 "should have been set up already for a noncontiguous Map. Please report" 1489 " this bug to the Tpetra team.");
1490 #endif // HAVE_TEUCHOS_DEBUG 1492 const LO numElts =
static_cast<LO
> (getNodeNumElements ());
1494 lg_view_type lgMap (
"lgMap", numElts);
1495 FillLgMap<LO, GO, DT> fillIt (lgMap, minMyGID_);
1497 auto lgMapHost = Kokkos::create_mirror_view (lgMap);
1502 lgMapHost_ = lgMapHost;
1507 execution_space::fence ();
1513 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1514 Teuchos::ArrayView<const GlobalOrdinal>
1517 typedef GlobalOrdinal GO;
1522 (void) this->getMyGlobalIndices ();
1525 const GO* lgMapHostRawPtr = lgMapHost_.data ();
1529 return Teuchos::ArrayView<const GO> (lgMapHostRawPtr,
1530 lgMapHost_.extent (0),
1531 Teuchos::RCP_DISABLE_NODE_LOOKUP);
1534 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1536 return distributed_;
1539 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1541 using Teuchos::TypeNameTraits;
1542 std::ostringstream os;
1544 os <<
"Tpetra::Map: {" 1545 <<
"LocalOrdinalType: " << TypeNameTraits<LocalOrdinal>::name ()
1546 <<
", GlobalOrdinalType: " << TypeNameTraits<GlobalOrdinal>::name ()
1547 <<
", NodeType: " << TypeNameTraits<Node>::name ();
1548 if (this->getObjectLabel () !=
"") {
1549 os <<
", Label: \"" << this->getObjectLabel () <<
"\"";
1551 os <<
", Global number of entries: " << getGlobalNumElements ()
1552 <<
", Number of processes: " << getComm ()->getSize ()
1553 <<
", Uniform: " << (isUniform () ?
"true" :
"false")
1554 <<
", Contiguous: " << (isContiguous () ?
"true" :
"false")
1555 <<
", Distributed: " << (isDistributed () ?
"true" :
"false")
1564 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1569 typedef LocalOrdinal LO;
1573 if (vl < Teuchos::VERB_HIGH) {
1574 return std::string ();
1576 auto outStringP = Teuchos::rcp (
new std::ostringstream ());
1577 Teuchos::RCP<Teuchos::FancyOStream> outp =
1578 Teuchos::getFancyOStream (outStringP);
1579 Teuchos::FancyOStream& out = *outp;
1581 auto comm = this->getComm ();
1582 const int myRank = comm->getRank ();
1583 const int numProcs = comm->getSize ();
1584 out <<
"Process " << myRank <<
" of " << numProcs <<
":" << endl;
1585 Teuchos::OSTab tab1 (out);
1587 const LO numEnt =
static_cast<LO
> (this->getNodeNumElements ());
1588 out <<
"My number of entries: " << numEnt << endl
1589 <<
"My minimum global index: " << this->getMinGlobalIndex () << endl
1590 <<
"My maximum global index: " << this->getMaxGlobalIndex () << endl;
1592 if (vl == Teuchos::VERB_EXTREME) {
1593 out <<
"My global indices: [";
1594 const LO minLclInd = this->getMinLocalIndex ();
1595 for (LO k = 0; k < numEnt; ++k) {
1596 out << minLclInd + this->getGlobalElement (k);
1597 if (k + 1 < numEnt) {
1605 return outStringP->str ();
1608 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1612 const Teuchos::EVerbosityLevel verbLevel)
const 1614 using Teuchos::TypeNameTraits;
1615 using Teuchos::VERB_DEFAULT;
1616 using Teuchos::VERB_NONE;
1617 using Teuchos::VERB_LOW;
1618 using Teuchos::VERB_HIGH;
1620 typedef LocalOrdinal LO;
1621 typedef GlobalOrdinal GO;
1622 const Teuchos::EVerbosityLevel vl =
1623 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1625 if (vl == VERB_NONE) {
1632 auto comm = this->getComm ();
1633 if (comm.is_null ()) {
1636 const int myRank = comm->getRank ();
1637 const int numProcs = comm->getSize ();
1646 Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
1652 tab0 = Teuchos::rcp (
new Teuchos::OSTab (out));
1653 out <<
"\"Tpetra::Map\":" << endl;
1654 tab1 = Teuchos::rcp (
new Teuchos::OSTab (out));
1656 out <<
"Template parameters:" << endl;
1657 Teuchos::OSTab tab2 (out);
1658 out <<
"LocalOrdinal: " << TypeNameTraits<LO>::name () << endl
1659 <<
"GlobalOrdinal: " << TypeNameTraits<GO>::name () << endl
1660 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
1662 const std::string label = this->getObjectLabel ();
1664 out <<
"Label: \"" << label <<
"\"" << endl;
1666 out <<
"Global number of entries: " << getGlobalNumElements () << endl
1667 <<
"Minimum global index: " << getMinAllGlobalIndex () << endl
1668 <<
"Maximum global index: " << getMaxAllGlobalIndex () << endl
1669 <<
"Index base: " << getIndexBase () << endl
1670 <<
"Number of processes: " << numProcs << endl
1671 <<
"Uniform: " << (isUniform () ?
"true" :
"false") << endl
1672 <<
"Contiguous: " << (isContiguous () ?
"true" :
"false") << endl
1673 <<
"Distributed: " << (isDistributed () ?
"true" :
"false") << endl;
1677 if (vl >= VERB_HIGH) {
1678 const std::string lclStr = this->localDescribeToString (vl);
1683 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1684 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
1691 typedef LocalOrdinal LO;
1692 typedef GlobalOrdinal GO;
1702 if (newComm.is_null () || newComm->getSize () < 1) {
1703 return Teuchos::null;
1705 else if (newComm->getSize () == 1) {
1710 RCP<map_type> newMap (
new map_type ());
1712 newMap->comm_ = newComm;
1716 newMap->indexBase_ = this->indexBase_;
1717 newMap->numGlobalElements_ = this->numLocalElements_;
1718 newMap->numLocalElements_ = this->numLocalElements_;
1719 newMap->minMyGID_ = this->minMyGID_;
1720 newMap->maxMyGID_ = this->maxMyGID_;
1721 newMap->minAllGID_ = this->minMyGID_;
1722 newMap->maxAllGID_ = this->maxMyGID_;
1723 newMap->firstContiguousGID_ = this->firstContiguousGID_;
1724 newMap->lastContiguousGID_ = this->lastContiguousGID_;
1727 newMap->uniform_ = this->uniform_;
1728 newMap->contiguous_ = this->contiguous_;
1731 newMap->distributed_ =
false;
1732 newMap->lgMap_ = this->lgMap_;
1733 newMap->lgMapHost_ = this->lgMapHost_;
1734 newMap->glMap_ = this->glMap_;
1755 const GST RECOMPUTE = Tpetra::Details::OrdinalTraits<GST>::invalid ();
1771 auto lgMap = this->getMyGlobalIndices ();
1772 typedef typename std::decay<decltype (lgMap.extent (0)) >::type size_type;
1773 const size_type lclNumInds =
1774 static_cast<size_type
> (this->getNodeNumElements ());
1775 using Teuchos::TypeNameTraits;
1776 TEUCHOS_TEST_FOR_EXCEPTION
1777 (lgMap.extent (0) != lclNumInds, std::logic_error,
1778 "Tpetra::Map::replaceCommWithSubset: Result of getMyGlobalIndices() " 1779 "has length " << lgMap.extent (0) <<
" (of type " <<
1780 TypeNameTraits<size_type>::name () <<
") != this->getNodeNumElements()" 1781 " = " << this->getNodeNumElements () <<
". The latter, upon being " 1782 "cast to size_type = " << TypeNameTraits<size_type>::name () <<
", " 1783 "becomes " << lclNumInds <<
". Please report this bug to the Tpetra " 1786 Teuchos::ArrayView<const GO> lgMap = this->getNodeElementList ();
1789 const GO indexBase = this->getIndexBase ();
1790 return rcp (
new map_type (RECOMPUTE, lgMap, indexBase, newComm));
1794 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1795 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
1799 using Teuchos::Comm;
1800 using Teuchos::null;
1801 using Teuchos::outArg;
1804 using Teuchos::REDUCE_MIN;
1805 using Teuchos::reduceAll;
1812 const int color = (numLocalElements_ == 0) ? 0 : 1;
1817 RCP<const Comm<int> > newComm = comm_->split (color, 0);
1823 if (newComm.is_null ()) {
1828 RCP<Map> map = rcp (
new Map ());
1830 map->comm_ = newComm;
1831 map->indexBase_ = indexBase_;
1832 map->numGlobalElements_ = numGlobalElements_;
1833 map->numLocalElements_ = numLocalElements_;
1834 map->minMyGID_ = minMyGID_;
1835 map->maxMyGID_ = maxMyGID_;
1836 map->minAllGID_ = minAllGID_;
1837 map->maxAllGID_ = maxAllGID_;
1838 map->firstContiguousGID_= firstContiguousGID_;
1839 map->lastContiguousGID_ = lastContiguousGID_;
1843 map->uniform_ = uniform_;
1844 map->contiguous_ = contiguous_;
1859 if (! distributed_ || newComm->getSize () == 1) {
1860 map->distributed_ =
false;
1862 const int iOwnAllGids = (numLocalElements_ == numGlobalElements_) ? 1 : 0;
1863 int allProcsOwnAllGids = 0;
1864 reduceAll<int, int> (*newComm, REDUCE_MIN, iOwnAllGids, outArg (allProcsOwnAllGids));
1865 map->distributed_ = (allProcsOwnAllGids == 1) ?
false :
true;
1868 map->lgMap_ = lgMap_;
1869 map->lgMapHost_ = lgMapHost_;
1870 map->glMap_ = glMap_;
1887 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1891 TEUCHOS_TEST_FOR_EXCEPTION(
1892 directory_.is_null (), std::logic_error,
"Tpetra::Map::setupDirectory: " 1893 "The Directory is null. " 1894 "Please report this bug to the Tpetra developers.");
1898 if (! directory_->initialized ()) {
1899 directory_->initialize (*
this);
1903 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1907 const Teuchos::ArrayView<int>& PIDs,
1908 const Teuchos::ArrayView<LocalOrdinal>& LIDs)
const 1910 using Tpetra::Details::OrdinalTraits;
1911 typedef Teuchos::ArrayView<int>::size_type size_type;
1919 if (getGlobalNumElements () == 0) {
1920 if (GIDs.size () == 0) {
1923 for (size_type k = 0; k < PIDs.size (); ++k) {
1924 PIDs[k] = OrdinalTraits<int>::invalid ();
1926 for (size_type k = 0; k < LIDs.size (); ++k) {
1927 LIDs[k] = OrdinalTraits<LocalOrdinal>::invalid ();
1937 return directory_->getDirectoryEntries (*
this, GIDs, PIDs, LIDs);
1940 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1944 const Teuchos::ArrayView<int> & PIDs)
const 1946 if (getGlobalNumElements () == 0) {
1947 if (GIDs.size () == 0) {
1951 for (Teuchos::ArrayView<int>::size_type k = 0; k < PIDs.size (); ++k) {
1952 PIDs[k] = Tpetra::Details::OrdinalTraits<int>::invalid ();
1962 return directory_->getDirectoryEntries (*
this, GIDs, PIDs);
1965 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1966 Teuchos::RCP<const Teuchos::Comm<int> >
1971 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1976 return Teuchos::rcp (
new Node);
1979 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1982 using Teuchos::outArg;
1983 using Teuchos::REDUCE_MIN;
1984 using Teuchos::reduceAll;
1986 bool global =
false;
1987 if (comm_->getSize () > 1) {
1991 if (numGlobalElements_ == as<global_size_t> (numLocalElements_)) {
2004 reduceAll<int, int> (*comm_, REDUCE_MIN, localRep, outArg (allLocalRep));
2005 if (allLocalRep != 1) {
2019 template <
class LocalOrdinal,
class GlobalOrdinal>
2020 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2022 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2024 typedef LocalOrdinal LO;
2025 typedef GlobalOrdinal GO;
2026 typedef typename ::Tpetra::Map<LO, GO>::node_type NT;
2027 return createLocalMapWithNode<LO, GO, NT> (numElements, comm);
2030 template <
class LocalOrdinal,
class GlobalOrdinal>
2031 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2033 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2035 typedef LocalOrdinal LO;
2036 typedef GlobalOrdinal GO;
2037 typedef typename ::Tpetra::Map<LO, GO>::node_type NT;
2038 return createUniformContigMapWithNode<LO, GO, NT> (numElements, comm);
2041 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2042 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2044 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2045 const Teuchos::RCP<Node>& node)
2049 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2051 if (node.is_null ()) {
2052 return rcp (
new map_type (numElements, indexBase, comm, GloballyDistributed));
2055 return rcp (
new map_type (numElements, indexBase, comm, GloballyDistributed, node));
2059 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2060 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2062 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2063 const Teuchos::RCP<Node>& node)
2068 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2071 if (node.is_null ()) {
2072 return rcp (
new map_type (globalNumElts, indexBase, comm, LocallyReplicated));
2075 return rcp (
new map_type (globalNumElts, indexBase, comm, LocallyReplicated, node));
2079 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2080 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2082 const size_t localNumElements,
2083 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2084 const Teuchos::RCP<Node>& )
2088 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2090 return rcp (
new map_type (numElements, localNumElements, indexBase, comm));
2093 template <
class LocalOrdinal,
class GlobalOrdinal>
2094 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2096 const size_t localNumElements,
2097 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2099 typedef LocalOrdinal LO;
2100 typedef GlobalOrdinal GO;
2103 return Tpetra::createContigMapWithNode<LO, GO, NT> (numElements, localNumElements, comm);
2107 template <
class LocalOrdinal,
class GlobalOrdinal>
2108 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2110 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2112 typedef LocalOrdinal LO;
2113 typedef GlobalOrdinal GO;
2116 return Tpetra::createNonContigMapWithNode<LO, GO, NT> (elementList, comm);
2120 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2121 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2123 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2124 const Teuchos::RCP<Node>& )
2129 const GST INV = Tpetra::Details::OrdinalTraits<GST>::invalid ();
2133 const GlobalOrdinal indexBase = 0;
2135 return rcp (
new map_type (INV, elementList, indexBase, comm));
2138 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2139 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2142 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2143 const Teuchos::RCP<Node>& )
2145 Teuchos::RCP< Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > map;
2146 int sumOfWeights, elemsLeft, localNumElements;
2147 const int numImages = comm->getSize();
2148 const int myImageID = comm->getRank();
2149 Teuchos::reduceAll<int>(*comm,Teuchos::REDUCE_SUM,myWeight,Teuchos::outArg(sumOfWeights));
2150 const double myShare = ((double)myWeight) / ((double)sumOfWeights);
2151 localNumElements = (int)std::floor( myShare * ((
double)numElements) );
2153 Teuchos::reduceAll<int>(*comm,Teuchos::REDUCE_SUM,localNumElements,Teuchos::outArg(elemsLeft));
2154 elemsLeft = numElements - elemsLeft;
2157 TEUCHOS_TEST_FOR_EXCEPT(elemsLeft < -numImages || numImages < elemsLeft);
2158 if (elemsLeft < 0) {
2160 if (myImageID >= numImages-elemsLeft) --localNumElements;
2162 else if (elemsLeft > 0) {
2164 if (myImageID < elemsLeft) ++localNumElements;
2167 return createContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>(numElements,localNumElements,comm);
2171 template<
class LO,
class GO,
class NT>
2172 Teuchos::RCP<const Tpetra::Map<LO, GO, NT> >
2175 using Teuchos::Array;
2176 using Teuchos::ArrayView;
2181 const GST GINV = Tpetra::Details::OrdinalTraits<GST>::invalid ();
2182 const int myRank = M->getComm ()->getRank ();
2188 if (! M->isDistributed ()) {
2195 const GST numGlobalEntries = M->getGlobalNumElements ();
2196 if (M->isContiguous ()) {
2197 const size_t numLocalEntries =
2198 (myRank == 0) ? as<size_t> (numGlobalEntries) :
static_cast<size_t> (0);
2199 return rcp (
new map_type (numGlobalEntries, numLocalEntries,
2200 M->getIndexBase (), M->getComm ()));
2203 ArrayView<const GO> myGids =
2204 (myRank == 0) ? M->getNodeElementList () : Teuchos::null;
2205 return rcp (
new map_type (GINV, myGids (), M->getIndexBase (),
2209 else if (M->isContiguous ()) {
2216 const size_t numMyElems = M->getNodeNumElements ();
2217 ArrayView<const GO> myElems = M->getNodeElementList ();
2218 Array<int> owner_procs_vec (numMyElems);
2222 Array<GO> myOwned_vec (numMyElems);
2223 size_t numMyOwnedElems = 0;
2224 for (
size_t i = 0; i < numMyElems; ++i) {
2225 const GO GID = myElems[i];
2226 const int owner = owner_procs_vec[i];
2228 if (myRank == owner) {
2229 myOwned_vec[numMyOwnedElems++] = GID;
2232 myOwned_vec.resize (numMyOwnedElems);
2234 return rcp (
new map_type (GINV, myOwned_vec (), M->getIndexBase (),
2239 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2240 Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2244 using Teuchos::Array;
2245 using Teuchos::ArrayView;
2247 typedef LocalOrdinal LO;
2248 typedef GlobalOrdinal GO;
2250 int myID = M->
getComm()->getRank();
2259 size_t numMyElems = M->getNodeNumElements ();
2260 ArrayView<const GO> myElems = M->getNodeElementList ();
2261 Array<int> owner_procs_vec (numMyElems);
2265 Array<GO> myOwned_vec (numMyElems);
2266 size_t numMyOwnedElems = 0;
2267 for (
size_t i = 0; i < numMyElems; ++i) {
2268 GO GID = myElems[i];
2269 int owner = owner_procs_vec[i];
2271 if (myID == owner) {
2272 myOwned_vec[numMyOwnedElems++] = GID;
2275 myOwned_vec.resize (numMyOwnedElems);
2280 Tpetra::Details::OrdinalTraits<global_size_t>::invalid ();
2281 return rcp (
new map_type (GINV, myOwned_vec (), M->getIndexBase (),
2292 #define TPETRA_MAP_INSTANT(LO,GO,NODE) \ 2294 namespace Classes { template class Map< LO , GO , NODE >; } \ 2296 template Teuchos::RCP< const Map<LO,GO,NODE> > \ 2297 createLocalMapWithNode<LO,GO,NODE> (const size_t numElements, \ 2298 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \ 2299 const Teuchos::RCP< NODE >& node); \ 2301 template Teuchos::RCP< const Map<LO,GO,NODE> > \ 2302 createContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \ 2303 const size_t localNumElements, \ 2304 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \ 2305 const Teuchos::RCP< NODE > &node); \ 2307 template Teuchos::RCP< const Map<LO,GO,NODE> > \ 2308 createNonContigMapWithNode(const Teuchos::ArrayView<const GO> &elementList, \ 2309 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, \ 2310 const Teuchos::RCP<NODE> &node); \ 2312 template Teuchos::RCP< const Map<LO,GO,NODE> > \ 2313 createUniformContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \ 2314 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \ 2315 const Teuchos::RCP< NODE > &node); \ 2317 template Teuchos::RCP< const Map<LO,GO,NODE> > \ 2318 createWeightedContigMapWithNode<LO,GO,NODE> (const int thisNodeWeight, \ 2319 const global_size_t numElements, \ 2320 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \ 2321 const Teuchos::RCP< NODE >& node); \ 2323 template Teuchos::RCP<const Map<LO,GO,NODE> > \ 2324 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M); \ 2326 template Teuchos::RCP<const Map<LO,GO,NODE> > \ 2327 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M, \ 2328 const Tpetra::Details::TieBreak<LO,GO>& tie_break); \ 2332 #define TPETRA_MAP_INSTANT_DEFAULTNODE(LO,GO) \ 2333 template Teuchos::RCP< const Map<LO,GO> > \ 2334 createLocalMap<LO,GO>( const size_t, const Teuchos::RCP< const Teuchos::Comm< int > > &); \ 2336 template Teuchos::RCP< const Map<LO,GO> > \ 2337 createContigMap<LO,GO>( global_size_t, size_t, \ 2338 const Teuchos::RCP< const Teuchos::Comm< int > > &); \ 2340 template Teuchos::RCP< const Map<LO,GO> > \ 2341 createNonContigMap(const Teuchos::ArrayView<const GO> &, \ 2342 const Teuchos::RCP<const Teuchos::Comm<int> > &); \ 2344 template Teuchos::RCP< const Map<LO,GO> > \ 2345 createUniformContigMap<LO,GO>( const global_size_t, \ 2346 const Teuchos::RCP< const Teuchos::Comm< int > > &); \ 2348 #endif // TPETRA_MAP_DEF_HPP bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createUniformContigMapWithNode(const global_size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::null)
Non-member constructor for a uniformly distributed, contiguous Map with a user-specified Kokkos Node...
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
Declaration of Tpetra::Details::printOnce.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createOneToOne(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &M)
Creates a one-to-one version of the given Map where each GID lives on only one process.
local_map_type getLocalMap() const
Get the local Map for Kokkos kernels.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal > > createContigMap(const global_size_t numElements, const size_t localNumElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Non-member constructor for a (potentially) non-uniformly distributed, contiguous Map using the defaul...
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
Node node_type
The type of the Kokkos Node.
GlobalOrdinal getIndexBase() const
The index base for this Map.
Classes::Map< LocalOrdinal, GlobalOrdinal, Node > Map
Alias for Tpetra::Classes::Map.
void initialize(const map_type &map)
Initialize the Directory with its Map.
Implementation details of Tpetra.
Declaration of Tpetra::Details::initializeKokkos.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator, in rank order.
void initializeKokkos()
Initialize Kokkos, using command-line arguments (if any) given to Teuchos::GlobalMPISession.
size_t global_size_t
Global size_t object.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
LookupStatus getDirectoryEntries(const map_type &map, const Teuchos::ArrayView< const GlobalOrdinal > &globalIDs, const Teuchos::ArrayView< int > &nodeIDs) const
Given a global ID list, return the list of their owning process IDs.
Implement mapping from global ID to process ID and local ID.
Functions for initializing and finalizing Tpetra.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a NONOWNING view of the global indices owned by this process.
NT ::device_type device_type
The Kokkos device type over which to allocate Views and perform work.
GlobalOrdinal getMaxGlobalIndex() const
The maximum global index owned by the calling process.
"Local" part of Map suitable for Kokkos kernels.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
Map()
Default constructor (that does nothing).
Stand-alone utility functions and macros.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal > > createLocalMap(const size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Nonmember constructor for a locally replicated Map with the default Kokkos Node.
A parallel distribution of indices over processes.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createLocalMapWithNode(const size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::null)
Nonmember constructor for a locally replicated Map with a specified Kokkos Node.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createContigMapWithNode(const global_size_t numElements, const size_t localNumElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::null)
Nonmember constructor for a (potentially) nonuniformly distributed, contiguous Map for a user-specifi...
LocalGlobal
Enum for local versus global allocation of Map entries.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createWeightedContigMapWithNode(const int thisNodeWeight, const global_size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::null)
Nonmember constructor for a contiguous Map with user-defined weights and a user-specified, possibly nondefault Kokkos Node type.
Interface for breaking ties in ownership.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal > > createNonContigMap(const Teuchos::ArrayView< const GlobalOrdinal > &elementList, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Nonmember constructor for a non-contiguous Map using the default Kokkos::Device type.
bool isUniform() const
Whether the range of global indices is uniform.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal > > createUniformContigMap(const global_size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Non-member constructor for a uniformly distributed, contiguous Map with the default Kokkos Node...
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createNonContigMapWithNode(const Teuchos::ArrayView< const GlobalOrdinal > &elementList, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< Node > &node=Teuchos::null)
Nonmember constructor for a noncontiguous Map with a user-specified, possibly nondefault Kokkos Node ...