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;
422 return static_cast<global_size_t> (0);
423 #endif // HAVE_TPETRA_DEBUG
426 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
428 Map<LocalOrdinal,GlobalOrdinal,Node>::
429 initWithNonownedHostIndexList (
const global_size_t numGlobalElements,
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;
450 typedef global_size_t GST;
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 ());
597 glMap_ = global_to_local_table_type (nonContigGids,
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>
1610 Map<LocalOrdinal,GlobalOrdinal,Node>::
1611 describe (Teuchos::FancyOStream &out,
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>
1905 Map<LocalOrdinal,GlobalOrdinal,Node>::
1906 getRemoteIndexList (
const Teuchos::ArrayView<const GlobalOrdinal>& GIDs,
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);
2069 const global_size_t globalNumElts = static_cast<global_size_t> (numElements);
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