47 #ifndef TPETRA_MAP_DEF_HPP
48 #define TPETRA_MAP_DEF_HPP
50 #include "Tpetra_Directory.hpp"
53 #include "Tpetra_Details_FixedHashTable.hpp"
54 #include "Tpetra_Details_gathervPrint.hpp"
58 #include "Teuchos_as.hpp"
59 #include "Teuchos_TypeNameTraits.hpp"
60 #include "Teuchos_CommHelpers.hpp"
61 #include "Tpetra_Details_mpiIsInitialized.hpp"
71 template<
class ExecutionSpace>
73 checkMapInputArray (
const char ctorName[],
74 const void* indexList,
75 const size_t indexListSize,
76 const ExecutionSpace& execSpace,
77 const Teuchos::Comm<int>*
const comm)
82 using Teuchos::outArg;
83 using Teuchos::REDUCE_MIN;
84 using Teuchos::reduceAll;
87 const int myRank = comm ==
nullptr ? 0 : comm->getRank ();
89 std::ostringstream lclErrStrm;
92 if (indexListSize != 0 && indexList ==
nullptr) {
95 lclErrStrm <<
"Proc " << myRank <<
": indexList is null, "
96 "but indexListSize=" << indexListSize <<
" != 0." << endl;
100 if (indexListSize != 0 && indexList !=
nullptr &&
104 using ::Tpetra::Details::memorySpaceName;
106 const std::string execSpaceName =
107 Teuchos::TypeNameTraits<ExecutionSpace>::name ();
108 lclErrStrm <<
"Proc " << myRank <<
": Input array is not "
109 "accessible from the required execution space " <<
110 execSpaceName <<
". As far as I can tell, array lives "
111 "in memory space " << memSpaceName <<
"." << endl;
116 reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
117 if (gblSuccess != 1) {
118 std::ostringstream gblErrStrm;
119 gblErrStrm <<
"Tpetra::Map constructor " << ctorName <<
120 " detected a problem with the input array "
121 "(raw array, Teuchos::ArrayView, or Kokkos::View) "
122 "of global indices." << endl;
124 using ::Tpetra::Details::gathervPrint;
127 TEUCHOS_TEST_FOR_EXCEPTION
128 (
true, std::invalid_argument, gblErrStrm.str ());
136 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
139 comm_ (new Teuchos::SerialComm<int> ()),
141 numGlobalElements_ (0),
142 numLocalElements_ (0),
143 minMyGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
144 maxMyGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
145 minAllGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
146 maxAllGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
147 firstContiguousGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
148 lastContiguousGID_ (
Tpetra::
Details::OrdinalTraits<GlobalOrdinal>::invalid ()),
151 distributed_ (false),
152 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
157 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
158 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
162 const global_ordinal_type indexBase,
163 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
165 const Teuchos::RCP<Node> &) :
166 Map<LocalOrdinal,GlobalOrdinal,Node>::
Map(numGlobalElements, indexBase,
169 #endif // TPETRA_ENABLE_DEPRECATED_CODE
171 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
179 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
182 using Teuchos::broadcast;
183 using Teuchos::outArg;
184 using Teuchos::reduceAll;
185 using Teuchos::REDUCE_MIN;
186 using Teuchos::REDUCE_MAX;
187 using Teuchos::typeName;
190 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
194 #ifdef HAVE_TPETRA_DEBUG
198 GST proc0NumGlobalElements = numGlobalElements;
199 broadcast<int, GST> (*comm_, 0, outArg (proc0NumGlobalElements));
200 GST minNumGlobalElements = numGlobalElements;
201 GST maxNumGlobalElements = numGlobalElements;
202 reduceAll<int, GST> (*comm, REDUCE_MIN, numGlobalElements, outArg (minNumGlobalElements));
203 reduceAll<int, GST> (*comm, REDUCE_MAX, numGlobalElements, outArg (maxNumGlobalElements));
204 TEUCHOS_TEST_FOR_EXCEPTION(
205 minNumGlobalElements != maxNumGlobalElements || numGlobalElements != minNumGlobalElements,
206 std::invalid_argument,
207 "Tpetra::Map constructor: All processes must provide the same number "
208 "of global elements. Process 0 set numGlobalElements = "
209 << proc0NumGlobalElements <<
". The calling process "
210 << comm->getRank () <<
" set numGlobalElements = " << numGlobalElements
211 <<
". The min and max values over all processes are "
212 << minNumGlobalElements <<
" resp. " << maxNumGlobalElements <<
".");
214 GO proc0IndexBase = indexBase;
215 broadcast<int, GO> (*comm_, 0, outArg (proc0IndexBase));
216 GO minIndexBase = indexBase;
217 GO maxIndexBase = indexBase;
218 reduceAll<int, GO> (*comm, REDUCE_MIN, indexBase, outArg (minIndexBase));
219 reduceAll<int, GO> (*comm, REDUCE_MAX, indexBase, outArg (maxIndexBase));
220 TEUCHOS_TEST_FOR_EXCEPTION(
221 minIndexBase != maxIndexBase || indexBase != minIndexBase,
222 std::invalid_argument,
223 "Tpetra::Map constructor: "
224 "All processes must provide the same indexBase argument. "
225 "Process 0 set indexBase = " << proc0IndexBase <<
". The calling "
226 "process " << comm->getRank () <<
" set indexBase = " << indexBase
227 <<
". The min and max values over all processes are "
228 << minIndexBase <<
" resp. " << maxIndexBase <<
".");
230 #endif // HAVE_TPETRA_DEBUG
249 TEUCHOS_TEST_FOR_EXCEPTION(
250 (numGlobalElements < 1 && numGlobalElements != 0),
251 std::invalid_argument,
252 "Tpetra::Map constructor: numGlobalElements (= "
253 << numGlobalElements <<
") must be nonnegative.");
255 TEUCHOS_TEST_FOR_EXCEPTION(
256 numGlobalElements == GSTI, std::invalid_argument,
257 "Tpetra::Map constructor: You provided numGlobalElements = Teuchos::"
258 "OrdinalTraits<Tpetra::global_size_t>::invalid(). This version of the "
259 "constructor requires a valid value of numGlobalElements. You "
260 "probably mistook this constructor for the \"contiguous nonuniform\" "
261 "constructor, which can compute the global number of elements for you "
262 "if you set numGlobalElements to that value.");
264 size_t numLocalElements = 0;
265 if (lOrG == GloballyDistributed) {
280 const GST numProcs =
static_cast<GST
> (comm_->getSize ());
281 const GST myRank =
static_cast<GST
> (comm_->getRank ());
282 const GST quotient = numGlobalElements / numProcs;
283 const GST remainder = numGlobalElements - quotient * numProcs;
286 if (myRank < remainder) {
287 numLocalElements =
static_cast<size_t> (1) +
static_cast<size_t> (quotient);
290 startIndex = as<GO> (myRank) * as<GO> (numLocalElements);
292 numLocalElements = as<size_t> (quotient);
293 startIndex = as<GO> (myRank) * as<GO> (numLocalElements) +
297 minMyGID_ = indexBase + startIndex;
298 maxMyGID_ = indexBase + startIndex + numLocalElements - 1;
299 minAllGID_ = indexBase;
300 maxAllGID_ = indexBase + numGlobalElements - 1;
301 distributed_ = (numProcs > 1);
304 numLocalElements = as<size_t> (numGlobalElements);
305 minMyGID_ = indexBase;
306 maxMyGID_ = indexBase + numGlobalElements - 1;
307 distributed_ =
false;
310 minAllGID_ = indexBase;
311 maxAllGID_ = indexBase + numGlobalElements - 1;
312 indexBase_ = indexBase;
313 numGlobalElements_ = numGlobalElements;
314 numLocalElements_ = numLocalElements;
315 firstContiguousGID_ = minMyGID_;
316 lastContiguousGID_ = maxMyGID_;
323 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
324 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
328 const size_t numLocalElements,
329 const global_ordinal_type indexBase,
330 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
331 const Teuchos::RCP<Node> &) :
332 Map<LocalOrdinal,GlobalOrdinal,Node>::
Map(numGlobalElements,
336 #endif // TPETRA_ENABLE_DEPRECATED_CODE
338 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
341 const size_t numLocalElements,
343 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm) :
346 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
349 using Teuchos::broadcast;
350 using Teuchos::outArg;
351 using Teuchos::reduceAll;
352 using Teuchos::REDUCE_MIN;
353 using Teuchos::REDUCE_MAX;
354 using Teuchos::REDUCE_SUM;
358 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
362 #ifdef HAVE_TPETRA_DEBUG
365 const GST debugGlobalSum =
366 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
368 #endif // HAVE_TPETRA_DEBUG
382 scan<int, GO> (*comm, REDUCE_SUM, numLocalElements, outArg (scanResult));
383 const GO myOffset = scanResult - numLocalElements;
385 if (numGlobalElements != GSTI) {
386 numGlobalElements_ = numGlobalElements;
392 const int numProcs = comm->getSize ();
393 GST globalSum = scanResult;
395 broadcast (*comm, numProcs - 1, outArg (globalSum));
397 numGlobalElements_ = globalSum;
399 #ifdef HAVE_TPETRA_DEBUG
401 TEUCHOS_TEST_FOR_EXCEPTION(
402 globalSum != debugGlobalSum, std::logic_error,
403 "Tpetra::Map constructor (contiguous nonuniform): "
404 "globalSum = " << globalSum <<
" != debugGlobalSum = " << debugGlobalSum
405 <<
". Please report this bug to the Tpetra developers.");
406 #endif // HAVE_TPETRA_DEBUG
408 numLocalElements_ = numLocalElements;
409 indexBase_ = indexBase;
410 minAllGID_ = (numGlobalElements_ == 0) ?
411 std::numeric_limits<GO>::max () :
413 maxAllGID_ = (numGlobalElements_ == 0) ?
414 std::numeric_limits<GO>::lowest () :
415 indexBase +
static_cast<GO
> (numGlobalElements_) -
static_cast<GO
> (1);
416 minMyGID_ = (numLocalElements_ == 0) ?
417 std::numeric_limits<GO>::max () :
418 indexBase +
static_cast<GO
> (myOffset);
419 maxMyGID_ = (numLocalElements_ == 0) ?
420 std::numeric_limits<GO>::lowest () :
421 indexBase + myOffset +
static_cast<GO
> (numLocalElements) -
static_cast<GO
> (1);
422 firstContiguousGID_ = minMyGID_;
423 lastContiguousGID_ = maxMyGID_;
425 distributed_ = checkIsDist ();
431 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
433 Map<LocalOrdinal,GlobalOrdinal,Node>::
434 initialNonuniformDebugCheck (
const global_size_t numGlobalElements,
435 const size_t numLocalElements,
436 const GlobalOrdinal indexBase,
437 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
const
439 #ifdef HAVE_TPETRA_DEBUG
440 using Teuchos::broadcast;
441 using Teuchos::outArg;
443 using Teuchos::REDUCE_MAX;
444 using Teuchos::REDUCE_MIN;
445 using Teuchos::REDUCE_SUM;
446 using Teuchos::reduceAll;
447 typedef GlobalOrdinal GO;
449 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
459 GST debugGlobalSum = 0;
460 reduceAll<int, GST> (*comm, REDUCE_SUM,
static_cast<GST
> (numLocalElements),
461 outArg (debugGlobalSum));
465 GST proc0NumGlobalElements = numGlobalElements;
466 broadcast<int, GST> (*comm_, 0, outArg (proc0NumGlobalElements));
467 GST minNumGlobalElements = numGlobalElements;
468 GST maxNumGlobalElements = numGlobalElements;
469 reduceAll<int, GST> (*comm, REDUCE_MIN, numGlobalElements,
470 outArg (minNumGlobalElements));
471 reduceAll<int, GST> (*comm, REDUCE_MAX, numGlobalElements,
472 outArg (maxNumGlobalElements));
473 TEUCHOS_TEST_FOR_EXCEPTION(
474 minNumGlobalElements != maxNumGlobalElements ||
475 numGlobalElements != minNumGlobalElements,
476 std::invalid_argument,
477 "Tpetra::Map constructor: All processes must provide the same number "
478 "of global elements. This is true even if that argument is Teuchos::"
479 "OrdinalTraits<global_size_t>::invalid() to signal that the Map should "
480 "compute the global number of elements. Process 0 set numGlobalElements"
481 " = " << proc0NumGlobalElements <<
". The calling process "
482 << comm->getRank () <<
" set numGlobalElements = " << numGlobalElements
483 <<
". The min and max values over all processes are "
484 << minNumGlobalElements <<
" resp. " << maxNumGlobalElements <<
".");
486 GO proc0IndexBase = indexBase;
487 broadcast<int, GO> (*comm_, 0, outArg (proc0IndexBase));
488 GO minIndexBase = indexBase;
489 GO maxIndexBase = indexBase;
490 reduceAll<int, GO> (*comm, REDUCE_MIN, indexBase, outArg (minIndexBase));
491 reduceAll<int, GO> (*comm, REDUCE_MAX, indexBase, outArg (maxIndexBase));
492 TEUCHOS_TEST_FOR_EXCEPTION(
493 minIndexBase != maxIndexBase || indexBase != minIndexBase,
494 std::invalid_argument,
495 "Tpetra::Map constructor: "
496 "All processes must provide the same indexBase argument. "
497 "Process 0 set indexBase = " << proc0IndexBase <<
". The calling "
498 "process " << comm->getRank () <<
" set indexBase = " << indexBase
499 <<
". The min and max values over all processes are "
500 << minIndexBase <<
" resp. " << maxIndexBase <<
".");
504 TEUCHOS_TEST_FOR_EXCEPTION
505 (numGlobalElements != GSTI && debugGlobalSum != numGlobalElements,
506 std::invalid_argument,
"Tpetra::Map constructor: The sum of each "
507 "process' number of indices over all processes, " << debugGlobalSum
508 <<
" != numGlobalElements = " << numGlobalElements <<
". If you "
509 "would like this constructor to compute numGlobalElements for you, "
510 "you may set numGlobalElements = "
511 "Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid() on input. "
512 "Please note that this is NOT necessarily -1.");
515 return debugGlobalSum;
517 (void)numGlobalElements;
518 (void)numLocalElements;
522 #endif // HAVE_TPETRA_DEBUG
525 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
527 Map<LocalOrdinal,GlobalOrdinal,Node>::
528 initWithNonownedHostIndexList (
const global_size_t numGlobalElements,
529 const Kokkos::View<
const GlobalOrdinal*,
532 Kokkos::MemoryUnmanaged>& entryList_host,
533 const GlobalOrdinal indexBase,
534 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
536 using Kokkos::LayoutLeft;
537 using Kokkos::subview;
539 using Kokkos::view_alloc;
540 using Kokkos::WithoutInitializing;
542 using Teuchos::broadcast;
543 using Teuchos::outArg;
545 using Teuchos::REDUCE_MAX;
546 using Teuchos::REDUCE_MIN;
547 using Teuchos::REDUCE_SUM;
548 using Teuchos::reduceAll;
549 using LO = LocalOrdinal;
550 using GO = GlobalOrdinal;
552 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
555 TEUCHOS_TEST_FOR_EXCEPTION
556 (! Kokkos::is_initialized (), std::runtime_error,
557 "Tpetra::Map constructor: The Kokkos execution space "
558 << Teuchos::TypeNameTraits<execution_space>::name ()
559 <<
" has not been initialized. "
560 "Please initialize it before creating a Map.")
573 const
size_t numLocalElements = static_cast<
size_t> (entryList_host.size ());
575 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
586 if (numGlobalElements != GSTI) {
587 numGlobalElements_ = numGlobalElements;
590 reduceAll<int, GST> (*comm, REDUCE_SUM,
591 static_cast<GST
> (numLocalElements),
592 outArg (numGlobalElements_));
618 numLocalElements_ = numLocalElements;
619 indexBase_ = indexBase;
621 minMyGID_ = indexBase_;
622 maxMyGID_ = indexBase_;
632 if (numLocalElements_ > 0) {
636 typename decltype (lgMap_)::non_const_type lgMap
637 (view_alloc (
"lgMap", WithoutInitializing), numLocalElements_);
639 Kokkos::create_mirror_view (Kokkos::HostSpace (), lgMap);
647 firstContiguousGID_ = entryList_host[0];
648 lastContiguousGID_ = firstContiguousGID_+1;
656 lgMap_host[0] = firstContiguousGID_;
658 for ( ; i < numLocalElements_; ++i) {
659 const GO curGid = entryList_host[i];
660 const LO curLid = as<LO> (i);
662 if (lastContiguousGID_ != curGid)
break;
668 lgMap_host[curLid] = curGid;
669 ++lastContiguousGID_;
671 --lastContiguousGID_;
676 minMyGID_ = firstContiguousGID_;
677 maxMyGID_ = lastContiguousGID_;
682 const std::pair<size_t, size_t> ncRange (i, entryList_host.extent (0));
683 auto nonContigGids_host = subview (entryList_host, ncRange);
684 TEUCHOS_TEST_FOR_EXCEPTION
685 (
static_cast<size_t> (nonContigGids_host.extent (0)) !=
686 static_cast<size_t> (entryList_host.extent (0) - i),
687 std::logic_error,
"Tpetra::Map noncontiguous constructor: "
688 "nonContigGids_host.extent(0) = "
689 << nonContigGids_host.extent (0)
690 <<
" != entryList_host.extent(0) - i = "
691 << (entryList_host.extent (0) - i) <<
" = "
692 << entryList_host.extent (0) <<
" - " << i
693 <<
". Please report this bug to the Tpetra developers.");
697 View<GO*, LayoutLeft, device_type>
698 nonContigGids (view_alloc (
"nonContigGids", WithoutInitializing),
699 nonContigGids_host.size ());
705 static_cast<LO
> (i));
713 for ( ; i < numLocalElements_; ++i) {
714 const GO curGid = entryList_host[i];
715 const LO curLid =
static_cast<LO
> (i);
716 lgMap_host[curLid] = curGid;
720 if (curGid < minMyGID_) {
723 if (curGid > maxMyGID_) {
734 lgMapHost_ = lgMap_host;
737 minMyGID_ = std::numeric_limits<GlobalOrdinal>::max();
738 maxMyGID_ = std::numeric_limits<GlobalOrdinal>::lowest();
742 firstContiguousGID_ = indexBase_+1;
743 lastContiguousGID_ = indexBase_;
768 if (std::numeric_limits<GO>::is_signed) {
771 (as<GST> (numLocalElements_) < numGlobalElements_) ? 1 : 0;
774 minMaxInput[0] = -minMyGID_;
775 minMaxInput[1] = maxMyGID_;
776 minMaxInput[2] = localDist;
782 reduceAll<int, GO> (*comm, REDUCE_MAX, 3, minMaxInput, minMaxOutput);
783 minAllGID_ = -minMaxOutput[0];
784 maxAllGID_ = minMaxOutput[1];
785 const GO globalDist = minMaxOutput[2];
786 distributed_ = (comm_->getSize () > 1 && globalDist == 1);
790 reduceAll<int, GO> (*comm_, REDUCE_MIN, minMyGID_, outArg (minAllGID_));
791 reduceAll<int, GO> (*comm_, REDUCE_MAX, maxMyGID_, outArg (maxAllGID_));
792 distributed_ = checkIsDist ();
797 TEUCHOS_TEST_FOR_EXCEPTION(
798 minAllGID_ < indexBase_,
799 std::invalid_argument,
800 "Tpetra::Map constructor (noncontiguous): "
801 "Minimum global ID = " << minAllGID_ <<
" over all process(es) is "
802 "less than the given indexBase = " << indexBase_ <<
".");
808 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
811 const GlobalOrdinal indexList[],
812 const LocalOrdinal indexListSize,
813 const GlobalOrdinal indexBase,
814 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) :
817 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
820 checkMapInputArray (
"(GST, const GO[], LO, GO, comm)",
821 indexList,
static_cast<size_t> (indexListSize),
822 Kokkos::DefaultHostExecutionSpace (),
827 const GlobalOrdinal*
const indsRaw = indexListSize == 0 ? NULL : indexList;
828 Kokkos::View<
const GlobalOrdinal*,
831 Kokkos::MemoryUnmanaged> inds (indsRaw, indexListSize);
832 initWithNonownedHostIndexList (numGlobalElements, inds, indexBase, comm);
835 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
836 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
839 const Teuchos::ArrayView<const GlobalOrdinal>& entryList,
840 const GlobalOrdinal indexBase,
841 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
842 const Teuchos::RCP<Node>& ) :
843 Map<LocalOrdinal,GlobalOrdinal,Node>::
Map(numGlobalElements, entryList,
846 #endif // TPETRA_ENABLE_DEPRECATED_CODE
848 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
851 const Teuchos::ArrayView<const GlobalOrdinal>& entryList,
852 const GlobalOrdinal indexBase,
853 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) :
856 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
859 const size_t numLclInds =
static_cast<size_t> (entryList.size ());
860 checkMapInputArray (
"(GST, ArrayView, GO, comm)",
861 entryList.getRawPtr (), numLclInds,
862 Kokkos::DefaultHostExecutionSpace (),
867 const GlobalOrdinal*
const indsRaw =
868 numLclInds == 0 ? NULL : entryList.getRawPtr ();
869 Kokkos::View<
const GlobalOrdinal*,
872 Kokkos::MemoryUnmanaged> inds (indsRaw, numLclInds);
873 initWithNonownedHostIndexList (numGlobalElements, inds, indexBase, comm);
876 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
879 const Kokkos::View<const GlobalOrdinal*, device_type>& entryList,
880 const GlobalOrdinal indexBase,
881 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) :
884 directory_ (new
Directory<LocalOrdinal, GlobalOrdinal, Node> ())
886 using Kokkos::LayoutLeft;
887 using Kokkos::subview;
889 using Kokkos::view_alloc;
890 using Kokkos::WithoutInitializing;
892 using Teuchos::ArrayView;
894 using Teuchos::broadcast;
895 using Teuchos::outArg;
897 using Teuchos::REDUCE_MAX;
898 using Teuchos::REDUCE_MIN;
899 using Teuchos::REDUCE_SUM;
900 using Teuchos::reduceAll;
901 using Teuchos::typeName;
902 typedef LocalOrdinal LO;
903 typedef GlobalOrdinal GO;
905 const GST GSTI = Tpetra::Details::OrdinalTraits<GST>::invalid ();
908 checkMapInputArray (
"(GST, Kokkos::View, GO, comm)",
910 static_cast<size_t> (entryList.extent (0)),
924 const size_t numLocalElements =
static_cast<size_t> (entryList.size ());
926 initialNonuniformDebugCheck (numGlobalElements, numLocalElements,
937 if (numGlobalElements != GSTI) {
938 numGlobalElements_ = numGlobalElements;
941 reduceAll<int, GST> (*comm, REDUCE_SUM,
942 static_cast<GST
> (numLocalElements),
943 outArg (numGlobalElements_));
969 numLocalElements_ = numLocalElements;
970 indexBase_ = indexBase;
972 minMyGID_ = indexBase_;
973 maxMyGID_ = indexBase_;
983 if (numLocalElements_ > 0) {
987 typename decltype (lgMap_)::non_const_type lgMap
988 (view_alloc (
"lgMap", WithoutInitializing), numLocalElements_);
990 Kokkos::create_mirror_view (Kokkos::HostSpace (), lgMap);
993 typename View<const GO*, device_type>::array_layout;
994 View<GO*, array_layout, Kokkos::HostSpace> entryList_host
995 (view_alloc (
"entryList_host", WithoutInitializing),
996 entryList.extent(0));
999 firstContiguousGID_ = entryList_host[0];
1000 lastContiguousGID_ = firstContiguousGID_+1;
1008 lgMap_host[0] = firstContiguousGID_;
1010 for ( ; i < numLocalElements_; ++i) {
1011 const GO curGid = entryList_host[i];
1012 const LO curLid = as<LO> (i);
1014 if (lastContiguousGID_ != curGid)
break;
1020 lgMap_host[curLid] = curGid;
1021 ++lastContiguousGID_;
1023 --lastContiguousGID_;
1028 minMyGID_ = firstContiguousGID_;
1029 maxMyGID_ = lastContiguousGID_;
1034 const std::pair<size_t, size_t> ncRange (i, entryList.extent (0));
1035 auto nonContigGids = subview (entryList, ncRange);
1036 TEUCHOS_TEST_FOR_EXCEPTION
1037 (
static_cast<size_t> (nonContigGids.extent (0)) !=
1038 static_cast<size_t> (entryList.extent (0) - i),
1039 std::logic_error,
"Tpetra::Map noncontiguous constructor: "
1040 "nonContigGids.extent(0) = "
1041 << nonContigGids.extent (0)
1042 <<
" != entryList.extent(0) - i = "
1043 << (entryList.extent (0) - i) <<
" = "
1044 << entryList.extent (0) <<
" - " << i
1045 <<
". Please report this bug to the Tpetra developers.");
1047 glMap_ = global_to_local_table_type (nonContigGids,
1048 firstContiguousGID_,
1050 static_cast<LO
> (i));
1058 for ( ; i < numLocalElements_; ++i) {
1059 const GO curGid = entryList_host[i];
1060 const LO curLid =
static_cast<LO
> (i);
1061 lgMap_host[curLid] = curGid;
1065 if (curGid < minMyGID_) {
1068 if (curGid > maxMyGID_) {
1079 lgMapHost_ = lgMap_host;
1082 minMyGID_ = std::numeric_limits<GlobalOrdinal>::max();
1083 maxMyGID_ = std::numeric_limits<GlobalOrdinal>::lowest();
1087 firstContiguousGID_ = indexBase_+1;
1088 lastContiguousGID_ = indexBase_;
1113 if (std::numeric_limits<GO>::is_signed) {
1115 const GO localDist =
1116 (as<GST> (numLocalElements_) < numGlobalElements_) ? 1 : 0;
1119 minMaxInput[0] = -minMyGID_;
1120 minMaxInput[1] = maxMyGID_;
1121 minMaxInput[2] = localDist;
1124 minMaxOutput[0] = 0;
1125 minMaxOutput[1] = 0;
1126 minMaxOutput[2] = 0;
1127 reduceAll<int, GO> (*comm, REDUCE_MAX, 3, minMaxInput, minMaxOutput);
1128 minAllGID_ = -minMaxOutput[0];
1129 maxAllGID_ = minMaxOutput[1];
1130 const GO globalDist = minMaxOutput[2];
1131 distributed_ = (comm_->getSize () > 1 && globalDist == 1);
1135 reduceAll<int, GO> (*comm_, REDUCE_MIN, minMyGID_, outArg (minAllGID_));
1136 reduceAll<int, GO> (*comm_, REDUCE_MAX, maxMyGID_, outArg (maxAllGID_));
1137 distributed_ = checkIsDist ();
1140 contiguous_ =
false;
1142 TEUCHOS_TEST_FOR_EXCEPTION(
1143 minAllGID_ < indexBase_,
1144 std::invalid_argument,
1145 "Tpetra::Map constructor (noncontiguous): "
1146 "Minimum global ID = " << minAllGID_ <<
" over all process(es) is "
1147 "less than the given indexBase = " << indexBase_ <<
".");
1154 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1157 if (! Kokkos::is_initialized ()) {
1158 std::ostringstream os;
1159 os <<
"WARNING: Tpetra::Map destructor (~Map()) is being called after "
1160 "Kokkos::finalize() has been called. This is user error! There are "
1161 "two likely causes: " << std::endl <<
1162 " 1. You have a static Tpetra::Map (or RCP or shared_ptr of a Map)"
1164 " 2. You declare and construct a Tpetra::Map (or RCP or shared_ptr "
1165 "of a Tpetra::Map) at the same scope in main() as Kokkos::finalize() "
1166 "or Tpetra::finalize()." << std::endl << std::endl <<
1167 "Don't do either of these! Please refer to GitHib Issue #2372."
1169 ::Tpetra::Details::printOnce (std::cerr, os.str (),
1170 this->getComm ().getRawPtr ());
1173 using ::Tpetra::Details::mpiIsInitialized;
1174 using ::Tpetra::Details::mpiIsFinalized;
1175 using ::Tpetra::Details::teuchosCommIsAnMpiComm;
1177 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getComm ();
1178 if (! comm.is_null () && teuchosCommIsAnMpiComm (*comm) &&
1179 mpiIsInitialized () && mpiIsFinalized ()) {
1185 std::ostringstream os;
1186 os <<
"WARNING: Tpetra::Map destructor (~Map()) is being called after "
1187 "MPI_Finalize() has been called. This is user error! There are "
1188 "two likely causes: " << std::endl <<
1189 " 1. You have a static Tpetra::Map (or RCP or shared_ptr of a Map)"
1191 " 2. You declare and construct a Tpetra::Map (or RCP or shared_ptr "
1192 "of a Tpetra::Map) at the same scope in main() as MPI_finalize() or "
1193 "Tpetra::finalize()." << std::endl << std::endl <<
1194 "Don't do either of these! Please refer to GitHib Issue #2372."
1196 ::Tpetra::Details::printOnce (std::cerr, os.str (), comm.getRawPtr ());
1205 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1209 TEUCHOS_TEST_FOR_EXCEPTION(
1210 getComm ().is_null (), std::logic_error,
"Tpetra::Map::isOneToOne: "
1211 "getComm() returns null. Please report this bug to the Tpetra "
1216 return directory_->isOneToOne (*
this);
1220 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1225 if (isContiguous ()) {
1226 if (globalIndex < getMinGlobalIndex () ||
1227 globalIndex > getMaxGlobalIndex ()) {
1228 return Tpetra::Details::OrdinalTraits<LocalOrdinal>::invalid ();
1230 return static_cast<LocalOrdinal
> (globalIndex - getMinGlobalIndex ());
1232 else if (globalIndex >= firstContiguousGID_ &&
1233 globalIndex <= lastContiguousGID_) {
1234 return static_cast<LocalOrdinal
> (globalIndex - firstContiguousGID_);
1239 return glMap_.get (globalIndex);
1243 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1248 if (localIndex < getMinLocalIndex () || localIndex > getMaxLocalIndex ()) {
1249 return Tpetra::Details::OrdinalTraits<GlobalOrdinal>::invalid ();
1251 if (isContiguous ()) {
1252 return getMinGlobalIndex () + localIndex;
1259 return lgMapHost_[localIndex];
1263 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1268 if (localIndex < getMinLocalIndex () || localIndex > getMaxLocalIndex ()) {
1275 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1279 return this->getLocalElement (globalIndex) !=
1280 Tpetra::Details::OrdinalTraits<LocalOrdinal>::invalid ();
1283 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1288 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1294 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1300 getMinGlobalIndex (), getMaxGlobalIndex (),
1301 firstContiguousGID_, lastContiguousGID_,
1302 getNodeNumElements (), isContiguous ());
1305 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1310 using Teuchos::outArg;
1311 using Teuchos::REDUCE_MIN;
1312 using Teuchos::reduceAll;
1322 else if (getComm ()->getSize () != map.
getComm ()->getSize ()) {
1333 else if (isContiguous () && isUniform () &&
1341 lgMap_.extent (0) != 0 && map.lgMap_.extent (0) != 0 &&
1342 lgMap_.data () == map.lgMap_.data ()) {
1356 TEUCHOS_TEST_FOR_EXCEPTION(
1358 "Tpetra::Map::isCompatible: There's a bug in this method. We've already "
1359 "checked that this condition is true above, but it's false here. "
1360 "Please report this bug to the Tpetra developers.");
1363 const int locallyCompat =
1366 int globallyCompat = 0;
1367 reduceAll<int, int> (*comm_, REDUCE_MIN, locallyCompat, outArg (globallyCompat));
1368 return (globallyCompat == 1);
1371 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1376 using Teuchos::ArrayView;
1377 typedef GlobalOrdinal GO;
1378 typedef typename ArrayView<const GO>::size_type size_type;
1401 if (isContiguous ()) {
1406 TEUCHOS_TEST_FOR_EXCEPTION(
1407 ! this->isContiguous () || map.
isContiguous (), std::logic_error,
1408 "Tpetra::Map::locallySameAs: BUG");
1410 const GO minLhsGid = this->getMinGlobalIndex ();
1411 const size_type numRhsElts = rhsElts.size ();
1412 for (size_type k = 0; k < numRhsElts; ++k) {
1413 const GO curLhsGid = minLhsGid +
static_cast<GO
> (k);
1414 if (curLhsGid != rhsElts[k]) {
1422 TEUCHOS_TEST_FOR_EXCEPTION(
1423 this->isContiguous () || ! map.
isContiguous (), std::logic_error,
1424 "Tpetra::Map::locallySameAs: BUG");
1425 ArrayView<const GO> lhsElts = this->getNodeElementList ();
1427 const size_type numLhsElts = lhsElts.size ();
1428 for (size_type k = 0; k < numLhsElts; ++k) {
1429 const GO curRhsGid = minRhsGid +
static_cast<GO
> (k);
1430 if (curRhsGid != lhsElts[k]) {
1436 else if (this->lgMap_.data () == map.lgMap_.data ()) {
1446 ArrayView<const GO> lhsElts = getNodeElementList ();
1452 return std::equal (lhsElts.begin (), lhsElts.end (), rhsElts.begin ());
1458 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1468 auto lmap2 = this->getLocalMap();
1470 auto numLocalElements1 = lmap1.getNodeNumElements();
1471 auto numLocalElements2 = lmap2.getNodeNumElements();
1473 if (numLocalElements1 > numLocalElements2) {
1478 if (lmap1.isContiguous () && lmap2.isContiguous ()) {
1480 return ((lmap1.getMinGlobalIndex () == lmap2.getMinGlobalIndex ()) &&
1481 (lmap1.getMaxGlobalIndex () <= lmap2.getMaxGlobalIndex ()));
1484 if (lmap1.getMinGlobalIndex () < lmap2.getMinGlobalIndex () ||
1485 lmap1.getMaxGlobalIndex () > lmap2.getMaxGlobalIndex ()) {
1491 typedef Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space> range_type;
1494 LocalOrdinal numDiff = 0;
1495 Kokkos::parallel_reduce(
"isLocallyFitted", range_type(0, numLocalElements1),
1496 KOKKOS_LAMBDA(
const LocalOrdinal i, LocalOrdinal& diff) {
1497 diff += (lmap1.getGlobalElement(i) != lmap2.getGlobalElement(i));
1500 return (numDiff == 0);
1503 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1508 using Teuchos::outArg;
1509 using Teuchos::REDUCE_MIN;
1510 using Teuchos::reduceAll;
1520 else if (getComm ()->getSize () != map.
getComm ()->getSize ()) {
1543 else if (isContiguous () && isUniform () &&
1564 const int isSame_lcl = locallySameAs (map) ? 1 : 0;
1568 reduceAll<int, int> (*comm_, REDUCE_MIN, isSame_lcl, outArg (isSame_gbl));
1569 return isSame_gbl == 1;
1573 template <
class LO,
class GO,
class DT>
1576 FillLgMap (
const Kokkos::View<GO*, DT>& lgMap,
1577 const GO startGid) :
1578 lgMap_ (lgMap), startGid_ (startGid)
1580 Kokkos::RangePolicy<LO, typename DT::execution_space>
1581 range (
static_cast<LO
> (0),
static_cast<LO
> (lgMap.size ()));
1582 Kokkos::parallel_for (range, *
this);
1585 KOKKOS_INLINE_FUNCTION
void operator () (
const LO& lid)
const {
1586 lgMap_(lid) = startGid_ +
static_cast<GO
> (lid);
1590 const Kokkos::View<GO*, DT> lgMap_;
1597 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1598 typename Map<LocalOrdinal,GlobalOrdinal,Node>::global_indices_array_type
1601 typedef LocalOrdinal LO;
1602 typedef GlobalOrdinal GO;
1605 typedef decltype (lgMap_) const_lg_view_type;
1606 typedef typename const_lg_view_type::non_const_type lg_view_type;
1611 const bool needToCreateLocalToGlobalMapping =
1612 lgMap_.extent (0) == 0 && numLocalElements_ > 0;
1614 if (needToCreateLocalToGlobalMapping) {
1615 #ifdef HAVE_TEUCHOS_DEBUG
1618 TEUCHOS_TEST_FOR_EXCEPTION( ! isContiguous(), std::logic_error,
1619 "Tpetra::Map::getNodeElementList: The local-to-global mapping (lgMap_) "
1620 "should have been set up already for a noncontiguous Map. Please report"
1621 " this bug to the Tpetra team.");
1622 #endif // HAVE_TEUCHOS_DEBUG
1624 const LO numElts =
static_cast<LO
> (getNodeNumElements ());
1626 using Kokkos::view_alloc;
1627 using Kokkos::WithoutInitializing;
1628 lg_view_type lgMap (
"lgMap", numElts);
1629 FillLgMap<LO, GO, DT> fillIt (lgMap, minMyGID_);
1632 Kokkos::create_mirror_view (Kokkos::HostSpace (), lgMap);
1637 lgMapHost_ = lgMapHost;
1648 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1649 Teuchos::ArrayView<const GlobalOrdinal>
1652 typedef GlobalOrdinal GO;
1657 (void) this->getMyGlobalIndices ();
1660 const GO* lgMapHostRawPtr = lgMapHost_.data ();
1664 return Teuchos::ArrayView<const GO> (lgMapHostRawPtr,
1665 lgMapHost_.extent (0),
1666 Teuchos::RCP_DISABLE_NODE_LOOKUP);
1669 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1671 return distributed_;
1674 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1676 using Teuchos::TypeNameTraits;
1677 std::ostringstream os;
1679 os <<
"Tpetra::Map: {"
1680 <<
"LocalOrdinalType: " << TypeNameTraits<LocalOrdinal>::name ()
1681 <<
", GlobalOrdinalType: " << TypeNameTraits<GlobalOrdinal>::name ()
1682 <<
", NodeType: " << TypeNameTraits<Node>::name ();
1683 if (this->getObjectLabel () !=
"") {
1684 os <<
", Label: \"" << this->getObjectLabel () <<
"\"";
1686 os <<
", Global number of entries: " << getGlobalNumElements ()
1687 <<
", Number of processes: " << getComm ()->getSize ()
1688 <<
", Uniform: " << (isUniform () ?
"true" :
"false")
1689 <<
", Contiguous: " << (isContiguous () ?
"true" :
"false")
1690 <<
", Distributed: " << (isDistributed () ?
"true" :
"false")
1699 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1704 typedef LocalOrdinal LO;
1708 if (vl < Teuchos::VERB_HIGH) {
1709 return std::string ();
1711 auto outStringP = Teuchos::rcp (
new std::ostringstream ());
1712 Teuchos::RCP<Teuchos::FancyOStream> outp =
1713 Teuchos::getFancyOStream (outStringP);
1714 Teuchos::FancyOStream& out = *outp;
1716 auto comm = this->getComm ();
1717 const int myRank = comm->getRank ();
1718 const int numProcs = comm->getSize ();
1719 out <<
"Process " << myRank <<
" of " << numProcs <<
":" << endl;
1720 Teuchos::OSTab tab1 (out);
1722 const LO numEnt =
static_cast<LO
> (this->getNodeNumElements ());
1723 out <<
"My number of entries: " << numEnt << endl
1724 <<
"My minimum global index: " << this->getMinGlobalIndex () << endl
1725 <<
"My maximum global index: " << this->getMaxGlobalIndex () << endl;
1727 if (vl == Teuchos::VERB_EXTREME) {
1728 out <<
"My global indices: [";
1729 const LO minLclInd = this->getMinLocalIndex ();
1730 for (LO k = 0; k < numEnt; ++k) {
1731 out << minLclInd + this->getGlobalElement (k);
1732 if (k + 1 < numEnt) {
1740 return outStringP->str ();
1743 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1746 describe (Teuchos::FancyOStream &out,
1747 const Teuchos::EVerbosityLevel verbLevel)
const
1749 using Teuchos::TypeNameTraits;
1750 using Teuchos::VERB_DEFAULT;
1751 using Teuchos::VERB_NONE;
1752 using Teuchos::VERB_LOW;
1753 using Teuchos::VERB_HIGH;
1755 typedef LocalOrdinal LO;
1756 typedef GlobalOrdinal GO;
1757 const Teuchos::EVerbosityLevel vl =
1758 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1760 if (vl == VERB_NONE) {
1767 auto comm = this->getComm ();
1768 if (comm.is_null ()) {
1771 const int myRank = comm->getRank ();
1772 const int numProcs = comm->getSize ();
1781 Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
1787 tab0 = Teuchos::rcp (
new Teuchos::OSTab (out));
1788 out <<
"\"Tpetra::Map\":" << endl;
1789 tab1 = Teuchos::rcp (
new Teuchos::OSTab (out));
1791 out <<
"Template parameters:" << endl;
1792 Teuchos::OSTab tab2 (out);
1793 out <<
"LocalOrdinal: " << TypeNameTraits<LO>::name () << endl
1794 <<
"GlobalOrdinal: " << TypeNameTraits<GO>::name () << endl
1795 <<
"Node: " << TypeNameTraits<Node>::name () << endl;
1797 const std::string label = this->getObjectLabel ();
1799 out <<
"Label: \"" << label <<
"\"" << endl;
1801 out <<
"Global number of entries: " << getGlobalNumElements () << endl
1802 <<
"Minimum global index: " << getMinAllGlobalIndex () << endl
1803 <<
"Maximum global index: " << getMaxAllGlobalIndex () << endl
1804 <<
"Index base: " << getIndexBase () << endl
1805 <<
"Number of processes: " << numProcs << endl
1806 <<
"Uniform: " << (isUniform () ?
"true" :
"false") << endl
1807 <<
"Contiguous: " << (isContiguous () ?
"true" :
"false") << endl
1808 <<
"Distributed: " << (isDistributed () ?
"true" :
"false") << endl;
1812 if (vl >= VERB_HIGH) {
1813 const std::string lclStr = this->localDescribeToString (vl);
1818 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1819 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
1826 typedef LocalOrdinal LO;
1827 typedef GlobalOrdinal GO;
1837 if (newComm.is_null () || newComm->getSize () < 1) {
1838 return Teuchos::null;
1840 else if (newComm->getSize () == 1) {
1845 RCP<map_type> newMap (
new map_type ());
1847 newMap->comm_ = newComm;
1851 newMap->indexBase_ = this->indexBase_;
1852 newMap->numGlobalElements_ = this->numLocalElements_;
1853 newMap->numLocalElements_ = this->numLocalElements_;
1854 newMap->minMyGID_ = this->minMyGID_;
1855 newMap->maxMyGID_ = this->maxMyGID_;
1856 newMap->minAllGID_ = this->minMyGID_;
1857 newMap->maxAllGID_ = this->maxMyGID_;
1858 newMap->firstContiguousGID_ = this->firstContiguousGID_;
1859 newMap->lastContiguousGID_ = this->lastContiguousGID_;
1862 newMap->uniform_ = this->uniform_;
1863 newMap->contiguous_ = this->contiguous_;
1866 newMap->distributed_ =
false;
1867 newMap->lgMap_ = this->lgMap_;
1868 newMap->lgMapHost_ = this->lgMapHost_;
1869 newMap->glMap_ = this->glMap_;
1890 const GST RECOMPUTE = Tpetra::Details::OrdinalTraits<GST>::invalid ();
1906 auto lgMap = this->getMyGlobalIndices ();
1907 typedef typename std::decay<decltype (lgMap.extent (0)) >::type size_type;
1908 const size_type lclNumInds =
1909 static_cast<size_type
> (this->getNodeNumElements ());
1910 using Teuchos::TypeNameTraits;
1911 TEUCHOS_TEST_FOR_EXCEPTION
1912 (lgMap.extent (0) != lclNumInds, std::logic_error,
1913 "Tpetra::Map::replaceCommWithSubset: Result of getMyGlobalIndices() "
1914 "has length " << lgMap.extent (0) <<
" (of type " <<
1915 TypeNameTraits<size_type>::name () <<
") != this->getNodeNumElements()"
1916 " = " << this->getNodeNumElements () <<
". The latter, upon being "
1917 "cast to size_type = " << TypeNameTraits<size_type>::name () <<
", "
1918 "becomes " << lclNumInds <<
". Please report this bug to the Tpetra "
1921 Teuchos::ArrayView<const GO> lgMap = this->getNodeElementList ();
1924 const GO indexBase = this->getIndexBase ();
1925 return rcp (
new map_type (RECOMPUTE, lgMap, indexBase, newComm));
1929 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1930 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >
1934 using Teuchos::Comm;
1935 using Teuchos::null;
1936 using Teuchos::outArg;
1939 using Teuchos::REDUCE_MIN;
1940 using Teuchos::reduceAll;
1947 const int color = (numLocalElements_ == 0) ? 0 : 1;
1952 RCP<const Comm<int> > newComm = comm_->split (color, 0);
1958 if (newComm.is_null ()) {
1963 RCP<Map> map = rcp (
new Map ());
1965 map->comm_ = newComm;
1966 map->indexBase_ = indexBase_;
1967 map->numGlobalElements_ = numGlobalElements_;
1968 map->numLocalElements_ = numLocalElements_;
1969 map->minMyGID_ = minMyGID_;
1970 map->maxMyGID_ = maxMyGID_;
1971 map->minAllGID_ = minAllGID_;
1972 map->maxAllGID_ = maxAllGID_;
1973 map->firstContiguousGID_= firstContiguousGID_;
1974 map->lastContiguousGID_ = lastContiguousGID_;
1978 map->uniform_ = uniform_;
1979 map->contiguous_ = contiguous_;
1994 if (! distributed_ || newComm->getSize () == 1) {
1995 map->distributed_ =
false;
1997 const int iOwnAllGids = (numLocalElements_ == numGlobalElements_) ? 1 : 0;
1998 int allProcsOwnAllGids = 0;
1999 reduceAll<int, int> (*newComm, REDUCE_MIN, iOwnAllGids, outArg (allProcsOwnAllGids));
2000 map->distributed_ = (allProcsOwnAllGids == 1) ?
false :
true;
2003 map->lgMap_ = lgMap_;
2004 map->lgMapHost_ = lgMapHost_;
2005 map->glMap_ = glMap_;
2022 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2026 TEUCHOS_TEST_FOR_EXCEPTION(
2027 directory_.is_null (), std::logic_error,
"Tpetra::Map::setupDirectory: "
2028 "The Directory is null. "
2029 "Please report this bug to the Tpetra developers.");
2033 if (! directory_->initialized ()) {
2034 directory_->initialize (*
this);
2038 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2042 const Teuchos::ArrayView<int>& PIDs,
2043 const Teuchos::ArrayView<LocalOrdinal>& LIDs)
const
2045 using Tpetra::Details::OrdinalTraits;
2046 typedef Teuchos::ArrayView<int>::size_type size_type;
2054 if (getGlobalNumElements () == 0) {
2055 if (GIDs.size () == 0) {
2058 for (size_type k = 0; k < PIDs.size (); ++k) {
2059 PIDs[k] = OrdinalTraits<int>::invalid ();
2061 for (size_type k = 0; k < LIDs.size (); ++k) {
2062 LIDs[k] = OrdinalTraits<LocalOrdinal>::invalid ();
2072 return directory_->getDirectoryEntries (*
this, GIDs, PIDs, LIDs);
2075 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2079 const Teuchos::ArrayView<int> & PIDs)
const
2081 if (getGlobalNumElements () == 0) {
2082 if (GIDs.size () == 0) {
2086 for (Teuchos::ArrayView<int>::size_type k = 0; k < PIDs.size (); ++k) {
2087 PIDs[k] = Tpetra::Details::OrdinalTraits<int>::invalid ();
2097 return directory_->getDirectoryEntries (*
this, GIDs, PIDs);
2100 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2101 Teuchos::RCP<const Teuchos::Comm<int> >
2106 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2107 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2113 return Teuchos::rcp (
new Node);
2115 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2117 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2118 bool Map<LocalOrdinal,GlobalOrdinal,Node>::checkIsDist()
const {
2120 using Teuchos::outArg;
2121 using Teuchos::REDUCE_MIN;
2122 using Teuchos::reduceAll;
2124 bool global =
false;
2125 if (comm_->getSize () > 1) {
2129 if (numGlobalElements_ == as<global_size_t> (numLocalElements_)) {
2142 reduceAll<int, int> (*comm_, REDUCE_MIN, localRep, outArg (allLocalRep));
2143 if (allLocalRep != 1) {
2156 template <
class LocalOrdinal,
class GlobalOrdinal>
2157 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2159 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2161 typedef LocalOrdinal LO;
2162 typedef GlobalOrdinal GO;
2163 typedef typename ::Tpetra::Map<LO, GO>::node_type NT;
2164 return createLocalMapWithNode<LO, GO, NT> (numElements, comm);
2167 template <
class LocalOrdinal,
class GlobalOrdinal>
2168 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2170 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2172 typedef LocalOrdinal LO;
2173 typedef GlobalOrdinal GO;
2174 typedef typename ::Tpetra::Map<LO, GO>::node_type NT;
2175 return createUniformContigMapWithNode<LO, GO, NT> (numElements, comm);
2178 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2179 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2181 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2183 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2184 const Teuchos::RCP<Node>&
2187 return Tpetra::createUniformContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>
2188 (numElements, comm);
2190 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2192 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2193 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2195 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm
2200 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2202 return rcp (
new map_type (numElements, indexBase, comm, GloballyDistributed));
2205 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2206 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2208 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2210 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2211 const Teuchos::RCP<Node>&
2214 return Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal,Node>
2215 (numElements, comm);
2217 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2219 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2220 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2222 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm
2228 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2231 return rcp (
new map_type (globalNumElts, indexBase, comm, LocallyReplicated));
2234 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2235 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2237 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2239 const size_t localNumElements,
2240 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2241 const Teuchos::RCP<Node>&
2244 return Tpetra::createContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>
2245 (numElements, localNumElements, comm);
2247 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2249 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2250 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2252 const size_t localNumElements,
2253 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm
2258 const GlobalOrdinal indexBase =
static_cast<GlobalOrdinal
> (0);
2260 return rcp (
new map_type (numElements, localNumElements, indexBase, comm));
2263 template <
class LocalOrdinal,
class GlobalOrdinal>
2264 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2266 const size_t localNumElements,
2267 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2269 typedef LocalOrdinal LO;
2270 typedef GlobalOrdinal GO;
2273 return Tpetra::createContigMapWithNode<LO, GO, NT> (numElements, localNumElements, comm);
2277 template <
class LocalOrdinal,
class GlobalOrdinal>
2278 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal> >
2280 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
2282 typedef LocalOrdinal LO;
2283 typedef GlobalOrdinal GO;
2286 return Tpetra::createNonContigMapWithNode<LO, GO, NT> (elementList, comm);
2290 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2291 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2293 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2295 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2296 const Teuchos::RCP<Node>&
2299 return Tpetra::createNonContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>
2300 (elementList, comm);
2302 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2304 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2305 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2307 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm
2313 const GST INV = Tpetra::Details::OrdinalTraits<GST>::invalid ();
2317 const GlobalOrdinal indexBase = 0;
2319 return rcp (
new map_type (INV, elementList, indexBase, comm));
2322 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2323 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2325 Teuchos::RCP< const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2326 Tpetra::createWeightedContigMapWithNode (
const int myWeight,
2328 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2329 const Teuchos::RCP<Node>&
2332 Teuchos::RCP< Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > map;
2333 int sumOfWeights, elemsLeft, localNumElements;
2334 const int numImages = comm->getSize();
2335 const int myImageID = comm->getRank();
2336 Teuchos::reduceAll<int>(*comm,Teuchos::REDUCE_SUM,myWeight,Teuchos::outArg(sumOfWeights));
2337 const double myShare = ((double)myWeight) / ((double)sumOfWeights);
2338 localNumElements = (int)std::floor( myShare * ((
double)numElements) );
2340 Teuchos::reduceAll<int>(*comm,Teuchos::REDUCE_SUM,localNumElements,Teuchos::outArg(elemsLeft));
2341 elemsLeft = numElements - elemsLeft;
2344 TEUCHOS_TEST_FOR_EXCEPT(elemsLeft < -numImages || numImages < elemsLeft);
2345 if (elemsLeft < 0) {
2347 if (myImageID >= numImages-elemsLeft) --localNumElements;
2349 else if (elemsLeft > 0) {
2351 if (myImageID < elemsLeft) ++localNumElements;
2354 return createContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>(numElements,localNumElements,comm);
2356 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2359 template<
class LO,
class GO,
class NT>
2360 Teuchos::RCP<const Tpetra::Map<LO, GO, NT> >
2363 using Teuchos::Array;
2364 using Teuchos::ArrayView;
2369 const GST GINV = Tpetra::Details::OrdinalTraits<GST>::invalid ();
2370 const int myRank = M->getComm ()->getRank ();
2376 if (! M->isDistributed ()) {
2383 const GST numGlobalEntries = M->getGlobalNumElements ();
2384 if (M->isContiguous ()) {
2385 const size_t numLocalEntries =
2386 (myRank == 0) ? as<size_t> (numGlobalEntries) :
static_cast<size_t> (0);
2387 return rcp (
new map_type (numGlobalEntries, numLocalEntries,
2388 M->getIndexBase (), M->getComm ()));
2391 ArrayView<const GO> myGids =
2392 (myRank == 0) ? M->getNodeElementList () : Teuchos::null;
2393 return rcp (
new map_type (GINV, myGids (), M->getIndexBase (),
2397 else if (M->isContiguous ()) {
2404 const size_t numMyElems = M->getNodeNumElements ();
2405 ArrayView<const GO> myElems = M->getNodeElementList ();
2406 Array<int> owner_procs_vec (numMyElems);
2410 Array<GO> myOwned_vec (numMyElems);
2411 size_t numMyOwnedElems = 0;
2412 for (
size_t i = 0; i < numMyElems; ++i) {
2413 const GO GID = myElems[i];
2414 const int owner = owner_procs_vec[i];
2416 if (myRank == owner) {
2417 myOwned_vec[numMyOwnedElems++] = GID;
2420 myOwned_vec.resize (numMyOwnedElems);
2422 return rcp (
new map_type (GINV, myOwned_vec (), M->getIndexBase (),
2427 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2428 Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >
2432 using ::Tpetra::Details::Behavior;
2433 using Teuchos::Array;
2434 using Teuchos::ArrayView;
2437 using Teuchos::toString;
2440 using LO = LocalOrdinal;
2441 using GO = GlobalOrdinal;
2443 const char funcPrefix[] =
"Tpetra::createOneToOne(Map,TieBreak): ";
2445 const bool verbose = Behavior::verbose (
"Map") ||
2446 Behavior::verbose (
"Directory");
2447 std::unique_ptr<std::string> procPrefix;
2449 std::ostringstream os;
2451 if (M.is_null () || M->getComm ().is_null ()) {
2455 os << M->getComm ()->getRank ();
2458 procPrefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
2459 os << funcPrefix <<
"Start" << endl;
2470 std::ostringstream os;
2471 os << *procPrefix <<
"Initialize Directory" << endl;
2476 std::ostringstream os;
2477 os << *procPrefix <<
"Done initializing Directory" << endl;
2480 size_t numMyElems = M->getNodeNumElements ();
2481 ArrayView<const GO> myElems = M->getNodeElementList ();
2482 Array<int> owner_procs_vec (numMyElems);
2484 std::ostringstream os;
2485 os << *procPrefix <<
"Call Directory::getDirectoryEntries with "
2486 "GIDs " << toString (myElems) << endl;
2491 std::ostringstream os;
2492 os << *procPrefix <<
"Directory::getDirectoryEntries PIDs "
2493 "result: " << toString (owner_procs_vec) << endl;
2497 const int myRank = M->getComm()->getRank();
2498 Array<GO> myOwned_vec (numMyElems);
2499 size_t numMyOwnedElems = 0;
2500 for (
size_t i = 0; i < numMyElems; ++i) {
2501 const GO GID = myElems[i];
2502 const int owner = owner_procs_vec[i];
2503 if (myRank == owner) {
2504 myOwned_vec[numMyOwnedElems++] = GID;
2507 myOwned_vec.resize (numMyOwnedElems);
2512 Tpetra::Details::OrdinalTraits<global_size_t>::invalid ();
2514 std::ostringstream os;
2515 os << *procPrefix <<
"Create Map with GIDs "
2516 << toString (myOwned_vec) << endl;
2519 RCP<const map_type> retMap
2520 (
new map_type (GINV, myOwned_vec (), M->getIndexBase (),
2523 std::ostringstream os;
2524 os << *procPrefix << funcPrefix <<
"Done!" << endl;
2537 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
2539 #define TPETRA_MAP_INSTANT(LO,GO,NODE) \
2541 template class Map< LO , GO , NODE >; \
2543 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2544 createLocalMapWithNode<LO,GO,NODE> (const size_t numElements, \
2545 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2547 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2548 createContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2549 const size_t localNumElements, \
2550 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2552 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2553 createNonContigMapWithNode(const Teuchos::ArrayView<const GO> &elementList, \
2554 const Teuchos::RCP<const Teuchos::Comm<int> > &comm); \
2556 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2557 createUniformContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2558 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2560 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2561 createLocalMapWithNode<LO,GO,NODE> (const size_t numElements, \
2562 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \
2563 const Teuchos::RCP< NODE >& node); \
2565 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2566 createContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2567 const size_t localNumElements, \
2568 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \
2569 const Teuchos::RCP< NODE > &node); \
2571 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2572 createNonContigMapWithNode(const Teuchos::ArrayView<const GO> &elementList, \
2573 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, \
2574 const Teuchos::RCP<NODE> &node); \
2576 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2577 createUniformContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2578 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \
2579 const Teuchos::RCP< NODE > &node); \
2581 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2582 createWeightedContigMapWithNode<LO,GO,NODE> (const int thisNodeWeight, \
2583 const global_size_t numElements, \
2584 const Teuchos::RCP< const Teuchos::Comm< int > >& comm, \
2585 const Teuchos::RCP< NODE >& node); \
2587 template Teuchos::RCP<const Map<LO,GO,NODE> > \
2588 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M); \
2590 template Teuchos::RCP<const Map<LO,GO,NODE> > \
2591 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M, \
2592 const Tpetra::Details::TieBreak<LO,GO>& tie_break); \
2594 #else // !TPETRA_ENABLE_DEPRECATED_CODE
2596 #define TPETRA_MAP_INSTANT(LO,GO,NODE) \
2598 template class Map< LO , GO , NODE >; \
2600 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2601 createLocalMapWithNode<LO,GO,NODE> (const size_t numElements, \
2602 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2604 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2605 createContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2606 const size_t localNumElements, \
2607 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2609 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2610 createNonContigMapWithNode(const Teuchos::ArrayView<const GO> &elementList, \
2611 const Teuchos::RCP<const Teuchos::Comm<int> > &comm); \
2613 template Teuchos::RCP< const Map<LO,GO,NODE> > \
2614 createUniformContigMapWithNode<LO,GO,NODE> (const global_size_t numElements, \
2615 const Teuchos::RCP< const Teuchos::Comm< int > >& comm); \
2617 template Teuchos::RCP<const Map<LO,GO,NODE> > \
2618 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M); \
2620 template Teuchos::RCP<const Map<LO,GO,NODE> > \
2621 createOneToOne (const Teuchos::RCP<const Map<LO,GO,NODE> >& M, \
2622 const Tpetra::Details::TieBreak<LO,GO>& tie_break); \
2624 #endif // TPETRA_ENABLE_DEPRECATED_CODE
2627 #define TPETRA_MAP_INSTANT_DEFAULTNODE(LO,GO) \
2628 template Teuchos::RCP< const Map<LO,GO> > \
2629 createLocalMap<LO,GO>( const size_t, const Teuchos::RCP< const Teuchos::Comm< int > > &); \
2631 template Teuchos::RCP< const Map<LO,GO> > \
2632 createContigMap<LO,GO>( global_size_t, size_t, \
2633 const Teuchos::RCP< const Teuchos::Comm< int > > &); \
2635 template Teuchos::RCP< const Map<LO,GO> > \
2636 createNonContigMap(const Teuchos::ArrayView<const GO> &, \
2637 const Teuchos::RCP<const Teuchos::Comm<int> > &); \
2639 template Teuchos::RCP< const Map<LO,GO> > \
2640 createUniformContigMap<LO,GO>( const global_size_t, \
2641 const Teuchos::RCP< const Teuchos::Comm< int > > &); \
2643 #endif // TPETRA_MAP_DEF_HPP