42 #ifndef TPETRA_IMPORT_DEF_HPP 43 #define TPETRA_IMPORT_DEF_HPP 45 #include <Tpetra_Import_decl.hpp> 46 #include <Tpetra_Distributor.hpp> 47 #include <Tpetra_Map.hpp> 48 #include <Tpetra_ImportExportData.hpp> 51 #include <Tpetra_Export.hpp> 53 #include <Tpetra_Details_gathervPrint.hpp> 54 #include <Teuchos_as.hpp> 55 #ifdef HAVE_TPETRA_MMM_TIMINGS 56 #include <Teuchos_TimeMonitor.hpp> 64 const bool tpetraImportDebugDefault =
false;
67 getBoolParameter (Teuchos::ParameterList* plist,
68 const char paramName[],
69 const bool defaultValue)
71 if (plist ==
nullptr) {
74 else if (plist->isType<
bool> (paramName)) {
75 return plist->get<
bool> (paramName);
77 else if (plist->isType<
int> (paramName)) {
78 const int val_int = plist->get<
int> (paramName);
89 std::string toString (
const std::vector<T>& x)
91 std::ostringstream os;
93 const std::size_t N = x.size ();
94 for (std::size_t k = 0; k < N; ++k) {
96 if (k + std::size_t (1) < N) {
108 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
110 Import<LocalOrdinal,GlobalOrdinal,Node>::
111 setParameterList (
const Teuchos::RCP<Teuchos::ParameterList>& plist)
113 bool debug = tpetraImportDebugDefault;
114 if (! plist.is_null ()) {
116 debug = plist->get<
bool> (
"Debug");
117 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
120 ImportData_->distributor_.setParameterList (plist);
123 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
126 init (
const Teuchos::RCP<const map_type>& source,
127 const Teuchos::RCP<const map_type>& target,
129 Teuchos::Array<int> & remotePIDs,
130 const Teuchos::RCP<Teuchos::ParameterList>& plist)
132 using Teuchos::Array;
139 this->debug_ = getBoolParameter (plist.getRawPtr (),
"Debug",
140 tpetraImportDebugDefault);
141 if (! out_.is_null ()) {
145 std::ostringstream os;
146 const int myRank = source->getComm ()->getRank ();
147 os << myRank <<
": Import ctor" << endl;
150 ImportData_ = rcp (
new data_type (source, target, out_, plist));
152 Array<GlobalOrdinal> remoteGIDs;
153 setupSamePermuteRemote (remoteGIDs);
155 std::ostringstream os;
156 const int myRank = source->getComm ()->getRank ();
157 os << myRank <<
": Import ctor: " 158 <<
"setupSamePermuteRemote done" << endl;
161 if (source->isDistributed ()) {
162 setupExport (remoteGIDs,useRemotePIDs,remotePIDs);
165 std::ostringstream os;
166 const int myRank = source->getComm ()->getRank ();
167 os << myRank <<
": Import ctor: done" << endl;
170 if (! out_.is_null ()) {
175 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
177 Import (
const Teuchos::RCP<const map_type >& source,
178 const Teuchos::RCP<const map_type >& target) :
179 out_ (
Teuchos::getFancyOStream (
Teuchos::rcpFromRef (std::cerr))),
180 debug_ (tpetraImportDebugDefault)
182 Teuchos::Array<int> dummy;
183 init (source, target,
false, dummy, Teuchos::null);
186 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
188 Import (
const Teuchos::RCP<const map_type >& source,
189 const Teuchos::RCP<const map_type >& target,
190 const Teuchos::RCP<Teuchos::FancyOStream>& out) :
192 debug_ (tpetraImportDebugDefault)
194 Teuchos::Array<int> dummy;
195 init (source, target,
false, dummy, Teuchos::null);
198 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
200 Import (
const Teuchos::RCP<const map_type >& source,
201 const Teuchos::RCP<const map_type >& target,
202 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
203 out_ (
Teuchos::getFancyOStream (
Teuchos::rcpFromRef (std::cerr))),
204 debug_ (tpetraImportDebugDefault)
206 Teuchos::Array<int> dummy;
207 init (source, target,
false, dummy, plist);
210 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
212 Import (
const Teuchos::RCP<const map_type >& source,
213 const Teuchos::RCP<const map_type >& target,
214 const Teuchos::RCP<Teuchos::FancyOStream>& out,
215 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
217 debug_ (tpetraImportDebugDefault)
219 Teuchos::Array<int> dummy;
220 init (source, target,
false, dummy, plist);
223 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
225 Import (
const Teuchos::RCP<const map_type >& source,
226 const Teuchos::RCP<const map_type >& target,
227 Teuchos::Array<int> & remotePIDs) :
228 debug_ (tpetraImportDebugDefault)
230 init (source, target,
true, remotePIDs, Teuchos::null);
234 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
237 : ImportData_ (rhs.ImportData_)
239 , debug_ (rhs.debug_)
242 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
245 : out_ (exporter.out_)
246 , debug_ (exporter.debug_)
248 if (! exporter.ExportData_.is_null ()) {
249 ImportData_ = exporter.ExportData_->reverseClone ();
255 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
259 Teuchos::Array<int>& userRemotePIDs,
260 Teuchos::Array<GlobalOrdinal>& remoteGIDs,
261 const Teuchos::ArrayView<const LocalOrdinal> & userExportLIDs,
262 const Teuchos::ArrayView<const int> & userExportPIDs,
263 const bool useRemotePIDGID,
264 const Teuchos::RCP<Teuchos::ParameterList>& plist,
265 const Teuchos::RCP<Teuchos::FancyOStream>& out) :
266 out_ (out.is_null () ?
270 using Teuchos::Array;
271 using Teuchos::ArrayRCP;
272 using Teuchos::ArrayView;
276 typedef LocalOrdinal LO;
277 typedef GlobalOrdinal GO;
278 typedef Teuchos::Array<int>::size_type size_type;
283 ArrayView<const GO> sourceGIDs = source->getNodeElementList ();
284 ArrayView<const GO> targetGIDs = target->getNodeElementList ();
285 const size_type numSrcGids = sourceGIDs.size ();
286 const size_type numTgtGids = targetGIDs.size ();
287 const size_type numGids = std::min (numSrcGids, numTgtGids);
289 size_type numSameGids = 0;
290 for ( ; numSameGids < numGids && sourceGIDs[numSameGids] == targetGIDs[numSameGids]; ++numSameGids)
294 bool debug = tpetraImportDebugDefault;
295 if (! plist.is_null ()) {
297 debug = plist->get<
bool> (
"Debug");
298 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
302 if (debug_ && ! out_.is_null ()) {
303 std::ostringstream os;
304 const int myRank = source->getComm ()->getRank ();
305 os << myRank <<
": constructExpert " << std::endl;
308 ImportData_ = rcp (
new data_type (source, target, out_, plist));
309 ImportData_->numSameIDs_ = numSameGids;
311 Array<LO>& permuteToLIDs = ImportData_->permuteToLIDs_;
312 Array<LO>& permuteFromLIDs = ImportData_->permuteFromLIDs_;
313 Array<LO>& remoteLIDs = ImportData_->remoteLIDs_;
314 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
315 const LO numTgtLids = as<LO> (numTgtGids);
317 if(!useRemotePIDGID) {
322 for (LO tgtLid = numSameGids; tgtLid < numTgtLids; ++tgtLid) {
323 const GO curTargetGid = targetGIDs[tgtLid];
325 const LO srcLid = source->getLocalElement (curTargetGid);
326 if (srcLid != LINVALID) {
327 permuteToLIDs.push_back (tgtLid);
328 permuteFromLIDs.push_back (srcLid);
330 if(!useRemotePIDGID) {
331 remoteGIDs.push_back (curTargetGid);
332 remoteLIDs.push_back (tgtLid);
340 "::constructExpert(): Target has remote LIDs but Source is not " 341 "distributed globally." << std::endl
342 <<
"Importing to a submap of the target map.");
344 Array<int> remotePIDs;
345 remotePIDs.resize (remoteGIDs.size (),0);
348 ArrayView<GO> remoteGIDsView = remoteGIDs ();
349 lookup = source->getRemoteIndexList (remoteGIDsView, remotePIDs ());
350 remoteGIDsView = remoteGIDs ();
352 Array<int>& remoteProcIDs = (useRemotePIDGID) ? userRemotePIDs : remotePIDs;
354 TEUCHOS_TEST_FOR_EXCEPTION( lookup ==
IDNotPresent, std::runtime_error,
355 "Import::Import createExpert: the source Map wasn't able to figure out which process " 356 "owns one or more of the GIDs in the list of remote GIDs. This probably " 357 "means that there is at least one GID owned by some process in the target" 358 " Map which is not owned by any process in the source Map. (That is, the" 359 " source and target Maps do not contain the same set of GIDs globally.)");
366 TEUCHOS_TEST_FOR_EXCEPTION( !(remoteProcIDs.size() == remoteGIDsView.size() &&remoteGIDsView.size() == remoteLIDs.size()), std::runtime_error,
367 "Import::Import createExpert version: Size miss match on RemoteProcIDs, remoteGIDsView and remoteLIDs Array's to sort3. This will produce produce an error, aborting ");
369 sort3 (remoteProcIDs.begin (),
370 remoteProcIDs.end (),
371 remoteGIDsView.begin (),
372 remoteLIDs.begin ());
374 ImportData_->remoteLIDs_ = remoteLIDs;
375 ImportData_->distributor_ =
Distributor (source->getComm(),this->out_);
376 ImportData_->exportPIDs_ = Teuchos::Array<int>(userExportPIDs.size(),0);
377 ImportData_->exportLIDs_ = Teuchos::Array<int>(userExportPIDs.size(),0);
379 bool locallyComplete =
true;
380 for(size_type i=0; i<userExportPIDs.size(); i++) {
381 if (userExportPIDs[i] == -1) {
382 locallyComplete =
false;
384 ImportData_->exportPIDs_[i] = userExportPIDs[i];
385 ImportData_->exportLIDs_[i] = userExportLIDs[i];
387 ImportData_->isLocallyComplete_ = locallyComplete;
389 ImportData_->distributor_.createFromSendsAndRecvs(ImportData_->exportPIDs_,remoteProcIDs);
394 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
396 Import (
const Teuchos::RCP<const map_type>& source,
397 const Teuchos::RCP<const map_type>& target,
398 const size_t numSameIDs,
399 Teuchos::Array<LocalOrdinal>& permuteToLIDs,
400 Teuchos::Array<LocalOrdinal>& permuteFromLIDs,
401 Teuchos::Array<LocalOrdinal>& remoteLIDs,
402 Teuchos::Array<LocalOrdinal>& exportLIDs,
403 Teuchos::Array<int>& exportPIDs,
405 const Teuchos::RCP<Teuchos::FancyOStream>& out,
406 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
407 out_ (out.is_null () ? Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr)) : out),
408 debug_ (tpetraImportDebugDefault)
418 bool debug = tpetraImportDebugDefault;
419 if (! plist.is_null ()) {
421 debug = plist->get<
bool> (
"Debug");
422 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
426 if (! out_.is_null ()) {
429 if (debug_ && ! out_.is_null ()) {
430 std::ostringstream os;
431 const int myRank = source->getComm ()->getRank ();
432 os << myRank <<
": Import expert ctor" << endl;
435 ImportData_ = rcp (
new data_type (source, target, out_, plist));
437 bool locallyComplete =
true;
438 for (Teuchos::Array<int>::size_type i = 0; i < exportPIDs.size (); ++i) {
439 if (exportPIDs[i] == -1) {
440 locallyComplete =
false;
443 ImportData_->isLocallyComplete_ = locallyComplete;
445 ImportData_->numSameIDs_ = numSameIDs;
446 ImportData_->permuteToLIDs_.swap (permuteToLIDs);
447 ImportData_->permuteFromLIDs_.swap (permuteFromLIDs);
448 ImportData_->remoteLIDs_.swap (remoteLIDs);
449 ImportData_->distributor_.swap (distributor);
450 ImportData_->exportLIDs_.swap (exportLIDs);
451 ImportData_->exportPIDs_.swap (exportPIDs);
456 template <
class LO,
class GO,
class NT>
457 struct ImportLocalSetupResult
459 Teuchos::RCP<const ::Tpetra::Map<LO, GO, NT> > targetMap;
463 std::vector<GO> remoteGIDs;
464 std::vector<LO> remoteLIDs;
465 std::vector<int> remotePIDs;
470 void printArray (std::ostream& out,
const T x[],
const std::size_t N)
473 for (std::size_t k = 0; k < N; ++k) {
482 template<
class LO,
class GO,
class NT>
483 ImportLocalSetupResult<LO, GO, NT>
484 setupSamePermuteRemoteFromUserGlobalIndexList (const ::Tpetra::Map<LO, GO, NT>& sourceMap,
485 const GO targetMapRemoteOrPermuteGlobalIndices[],
486 const int targetMapRemoteOrPermuteProcessRanks[],
487 const LO numTargetMapRemoteOrPermuteGlobalIndices,
488 const bool mayReorderTargetMapIndicesLocally,
489 Teuchos::FancyOStream* out,
490 const std::string* verboseHeader,
495 const int myRank = sourceMap.getComm ()->getRank ();
496 ImportLocalSetupResult<LO, GO, NT> result;
499 std::ostringstream os;
500 os << *verboseHeader <<
"- Import::setupSPR w/ remote GIDs & PIDs: " << endl
501 << *verboseHeader <<
" Input GIDs: ";
502 printArray (os, targetMapRemoteOrPermuteGlobalIndices, numTargetMapRemoteOrPermuteGlobalIndices);
503 os << endl <<
" Input PIDs: ";
504 printArray (os, targetMapRemoteOrPermuteProcessRanks, numTargetMapRemoteOrPermuteGlobalIndices);
514 std::vector<GO> badGIDs;
515 std::vector<int> badPIDs;
516 const Teuchos::Comm<int>& comm = * (sourceMap.getComm ());
517 const int numProcs = comm.getSize ();
519 for (LO k = 0; k < numTargetMapRemoteOrPermuteGlobalIndices; ++k) {
520 const GO tgtGID = targetMapRemoteOrPermuteGlobalIndices[k];
521 if (sourceMap.isNodeGlobalElement (tgtGID)) {
522 badGIDs.push_back (tgtGID);
524 const int tgtPID = targetMapRemoteOrPermuteProcessRanks[k];
525 if (tgtPID < 0 || tgtPID >= numProcs) {
526 badPIDs.push_back (tgtPID);
530 std::array<int, 2> lclStatus {{
531 badGIDs.size () == 0 ? 1 : 0,
532 badPIDs.size () == 0 ? 1 : 0
534 std::array<int, 2> gblStatus {{0, 0}};
535 Teuchos::reduceAll<int, int> (comm, Teuchos::REDUCE_MIN, 2,
536 lclStatus.data (), gblStatus.data ());
537 const bool good = gblStatus[0] == 1 && gblStatus[1] == 1;
540 if (verbose && gblStatus[0] != 1) {
541 std::ostringstream os;
542 os << *verboseHeader <<
"- Some input GIDs are already in the source Map: ";
543 printArray (os, badGIDs.data (), badGIDs.size ());
545 ::Tpetra::Details::gathervPrint (*out, os.str (), comm);
547 if (verbose && gblStatus[0] != 1) {
548 std::ostringstream os;
549 os << *verboseHeader <<
"- Some input PIDs are invalid: ";
550 printArray (os, badPIDs.data (), badPIDs.size ());
552 ::Tpetra::Details::gathervPrint (*out, os.str (), comm);
556 std::ostringstream os;
557 os <<
"Tpetra::Import constructor that takes remote GIDs and PIDs: ";
558 if (gblStatus[0] != 1) {
559 os <<
"Some input GIDs (global indices) are already in the source Map! ";
561 if (gblStatus[1] != 1) {
562 os <<
"Some input PIDs (process ranks) are invalid! ";
564 os <<
"Rerun with the environment variable TPETRA_VERBOSE=Tpetra::Import " 565 "to see what GIDs and/or PIDs are bad.";
566 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str ());
573 const LO numLclSrcIDs =
static_cast<LO
> (sourceMap.getNodeNumElements ());
574 const LO numLclTgtIDs = numLclSrcIDs + numTargetMapRemoteOrPermuteGlobalIndices;
576 std::ostringstream os;
577 os << *verboseHeader <<
"- Copy source Map GIDs into target Map GID list: " 578 "numLclSrcIDs=" << numLclSrcIDs
579 <<
", numTargetMapRemoteOrPermuteGlobalIndices=" 580 << numTargetMapRemoteOrPermuteGlobalIndices << endl;
583 std::vector<GO> tgtGIDs (numLclTgtIDs);
584 if (sourceMap.isContiguous ()) {
585 GO curTgtGID = sourceMap.getMinGlobalIndex ();
586 for (LO k = 0; k < numLclSrcIDs; ++k, ++curTgtGID) {
587 tgtGIDs[k] = curTgtGID;
591 auto srcGIDs = sourceMap.getNodeElementList ();
592 for (LO k = 0; k < numLclSrcIDs; ++k) {
593 tgtGIDs[k] = srcGIDs[k];
596 std::copy (targetMapRemoteOrPermuteGlobalIndices,
597 targetMapRemoteOrPermuteGlobalIndices + numTargetMapRemoteOrPermuteGlobalIndices,
598 tgtGIDs.begin () + numLclSrcIDs);
611 std::ostringstream os;
612 os << *verboseHeader <<
"- Sort by PID? " 613 << (mayReorderTargetMapIndicesLocally ?
"true" :
"false") << endl;
616 std::vector<int> tgtPIDs (targetMapRemoteOrPermuteProcessRanks,
617 targetMapRemoteOrPermuteProcessRanks + numTargetMapRemoteOrPermuteGlobalIndices);
618 result.numPermutes = 0;
619 if (mayReorderTargetMapIndicesLocally) {
620 Tpetra::sort2 (tgtPIDs.begin (), tgtPIDs.end (), tgtGIDs.begin () + numLclSrcIDs);
621 auto range = std::equal_range (tgtPIDs.begin (), tgtPIDs.end (), myRank);
622 if (range.second > range.first) {
623 result.numPermutes =
static_cast<LO
> (range.second - range.first);
627 result.numPermutes =
static_cast<LO
> (std::count (tgtPIDs.begin (), tgtPIDs.end (), myRank));
630 const LO numRemotes = numTargetMapRemoteOrPermuteGlobalIndices - result.numPermutes;
631 result.numSameIDs =
static_cast<LO
> (sourceMap.getNodeNumElements ());
634 std::ostringstream os;
635 os << *verboseHeader <<
"- numSame=" << result.numSameIDs
636 <<
", numPermutes=" << result.numPermutes
637 <<
", numRemotes=" << numRemotes << endl;
641 if (result.numPermutes == 0) {
643 std::ostringstream os;
644 os << *verboseHeader <<
"- No permutes" << endl;
647 result.remoteGIDs = std::vector<GO> (tgtGIDs.begin () + numLclSrcIDs, tgtGIDs.end ());
648 result.remotePIDs.swap (tgtPIDs);
649 result.remoteLIDs.resize (numRemotes);
650 for (LO k = 0; k < numRemotes; ++k) {
651 const LO tgtLid = result.numSameIDs + k;
652 result.remoteLIDs[k] = tgtLid;
655 std::ostringstream os;
656 os << *verboseHeader <<
"- Remote GIDs: " << Teuchos::toString (result.remoteGIDs) << endl;
657 os << *verboseHeader <<
"- Remote PIDs: " << Teuchos::toString (result.remotePIDs) << endl;
658 os << *verboseHeader <<
"- Remote LIDs: " << Teuchos::toString (result.remoteLIDs) << endl;
666 result.remoteGIDs.reserve (numRemotes);
667 result.remoteLIDs.reserve (numRemotes);
668 result.remotePIDs.reserve (numRemotes);
669 for (LO k = 0; k < numTargetMapRemoteOrPermuteGlobalIndices; ++k) {
670 const LO tgtLid = result.numSameIDs + k;
671 const GO tgtGid = tgtGIDs[numLclSrcIDs + k];
672 const int tgtPid = tgtPIDs[k];
674 if (tgtPid != myRank) {
675 result.remoteGIDs.push_back (tgtGid);
676 result.remoteLIDs.push_back (tgtLid);
677 result.remotePIDs.push_back (tgtPid);
681 std::ostringstream os;
682 os << *verboseHeader <<
"- Some permutes" << endl;
687 if (sourceMap.isDistributed ()) {
689 std::ostringstream os;
690 os << *verboseHeader <<
"- Sort remotes by PID, as Import always does" << endl
691 << *verboseHeader <<
"-- remotePIDs before: " 692 << Teuchos::toString (result.remotePIDs) << endl
693 << *verboseHeader <<
"-- remoteGIDs before: " 694 << Teuchos::toString (result.remoteGIDs) << endl
695 << *verboseHeader <<
"-- remoteLIDs before: " 696 << Teuchos::toString (result.remoteLIDs) << endl;
697 std::cerr << os.str ();
700 sort3 (result.remotePIDs.begin (),
701 result.remotePIDs.end (),
702 result.remoteGIDs.begin (),
703 result.remoteLIDs.begin ());
705 std::ostringstream os;
706 os << *verboseHeader <<
"-- remotePIDs after: " 707 << Teuchos::toString (result.remotePIDs) << endl
708 << *verboseHeader <<
"-- remoteGIDs after: " 709 << Teuchos::toString (result.remoteGIDs) << endl
710 << *verboseHeader <<
"-- remoteLIDs after: " 711 << Teuchos::toString (result.remoteLIDs) << endl;
712 std::cerr << os.str ();
717 std::ostringstream os;
718 os << *verboseHeader <<
"- Make target Map" << endl;
721 using ::Teuchos::rcp;
722 typedef ::Tpetra::Map<LO, GO, NT>
map_type;
723 typedef ::Tpetra::global_size_t GST;
724 const GST MAP_COMPUTES_GLOBAL_COUNT = ::Teuchos::OrdinalTraits<GST>::invalid ();
725 result.targetMap = rcp (
new map_type (MAP_COMPUTES_GLOBAL_COUNT,
728 sourceMap.getIndexBase (),
729 sourceMap.getComm ()));
731 std::ostringstream os;
732 os << *verboseHeader <<
"- Done with sameSPR..." << endl;
733 std::cerr << os.str ();
739 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
742 const GlobalOrdinal targetMapRemoteOrPermuteGlobalIndices[],
743 const int targetMapRemoteOrPermuteProcessRanks[],
744 const LocalOrdinal numTargetMapRemoteOrPermuteGlobalIndices,
745 const bool mayReorderTargetMapIndicesLocally,
746 const Teuchos::RCP<Teuchos::ParameterList>& plist,
747 const Teuchos::RCP<Teuchos::FancyOStream>& debugOutput) :
749 debug_ (getBoolParameter (plist.getRawPtr (),
"Debug", tpetraImportDebugDefault))
751 using Teuchos::FancyOStream;
755 typedef LocalOrdinal LO;
756 typedef GlobalOrdinal GO;
763 RCP<FancyOStream> outPtr = debugOutput.is_null () ?
764 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr)) : debugOutput;
765 TEUCHOS_TEST_FOR_EXCEPTION
766 (outPtr.is_null (), std::logic_error,
767 "outPtr is null; this should never happen!");
768 FancyOStream& out = *outPtr;
769 Teuchos::OSTab tab1 (out);
771 std::unique_ptr<std::string> verboseHeader;
773 std::ostringstream os;
774 const int myRank = sourceMap->getComm ()->getRank ();
775 os <<
"Proc " << myRank <<
": ";
776 verboseHeader = std::unique_ptr<std::string> (
new std::string (os.str ()));
779 std::ostringstream os;
780 os << *verboseHeader <<
"Import ctor (source Map + target indices, " 781 "mayReorder=" << (mayReorderTargetMapIndicesLocally ?
"true" :
"false")
786 ImportLocalSetupResult<LO, GO, NT> localSetupResult =
787 setupSamePermuteRemoteFromUserGlobalIndexList<LO, GO, NT> (*sourceMap,
788 targetMapRemoteOrPermuteGlobalIndices,
789 targetMapRemoteOrPermuteProcessRanks,
790 numTargetMapRemoteOrPermuteGlobalIndices,
791 mayReorderTargetMapIndicesLocally,
793 verboseHeader.get (),
797 localSetupResult.targetMap,
800 this->ImportData_->numSameIDs_ = localSetupResult.numSameIDs;
803 this->ImportData_->remoteLIDs_ =
804 Teuchos::Array<LO> (localSetupResult.remoteLIDs.begin (),
805 localSetupResult.remoteLIDs.end ());
813 this->ImportData_->isLocallyComplete_ =
true;
815 Teuchos::Array<GO> exportGIDs;
816 if (sourceMap->isDistributed ()) {
818 std::ostringstream os;
819 os << *verboseHeader <<
"Make Distributor (createFromRecvs)" << endl;
820 std::cerr << os.str ();
822 Teuchos::ArrayView<const GO> remoteGIDs (localSetupResult.remoteGIDs.data (),
823 localSetupResult.remoteGIDs.size ());
824 Teuchos::ArrayView<const int> remotePIDs (localSetupResult.remotePIDs.data (),
825 localSetupResult.remotePIDs.size ());
830 this->ImportData_->distributor_.createFromRecvs (remoteGIDs,
833 this->ImportData_->exportPIDs_);
843 std::ostringstream os;
844 os << *verboseHeader <<
"Compute exportLIDs" << endl;
845 std::cerr << os.str ();
847 typedef typename Teuchos::Array<GO>::size_type size_type;
848 const size_type numExportIDs = exportGIDs.size ();
849 this->ImportData_->exportLIDs_.resize (numExportIDs);
850 Teuchos::ArrayView<LO> exportLIDs = this->ImportData_->exportLIDs_ ();
851 for (size_type k = 0; k < numExportIDs; ++k) {
852 exportLIDs[k] = sourceMap->getLocalElement (exportGIDs[k]);
857 std::ostringstream os;
858 os << *verboseHeader <<
"ImportExportData::remoteLIDs_: " 859 << Teuchos::toString (this->ImportData_->remoteLIDs_) << endl;
860 std::cerr << os.str ();
863 std::ostringstream os;
864 const int myRank = sourceMap->getComm ()->getRank ();
865 os << myRank <<
": Import ctor: done" << endl;
870 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
874 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
876 return ImportData_->numSameIDs_;
879 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
881 return ImportData_->permuteFromLIDs_.size();
884 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
885 Teuchos::ArrayView<const LocalOrdinal>
887 return ImportData_->permuteFromLIDs_();
890 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
891 Teuchos::ArrayView<const LocalOrdinal>
893 return ImportData_->permuteToLIDs_();
896 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
898 return ImportData_->remoteLIDs_.size();
901 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
902 Teuchos::ArrayView<const LocalOrdinal>
904 return ImportData_->remoteLIDs_();
907 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
909 return ImportData_->exportLIDs_.size();
912 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
913 Teuchos::ArrayView<const LocalOrdinal>
915 return ImportData_->exportLIDs_();
918 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
919 Teuchos::ArrayView<const int>
921 return ImportData_->exportPIDs_();
924 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
925 Teuchos::RCP<const typename Import<LocalOrdinal,GlobalOrdinal,Node>::map_type>
927 return ImportData_->source_;
930 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
931 Teuchos::RCP<const typename Import<LocalOrdinal,GlobalOrdinal,Node>::map_type>
933 return ImportData_->target_;
936 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
939 return ImportData_->distributor_;
942 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
945 return ImportData_->isLocallyComplete_;
948 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
953 ImportData_ = rhs.ImportData_;
958 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
962 const Teuchos::EVerbosityLevel verbLevel)
const 968 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
972 auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
974 this->
describe (*out, Teuchos::VERB_EXTREME);
977 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
983 using Teuchos::Array;
984 using Teuchos::ArrayRCP;
985 using Teuchos::ArrayView;
988 typedef LocalOrdinal LO;
989 typedef GlobalOrdinal GO;
990 typedef typename ArrayView<const GO>::size_type size_type;
996 #ifdef HAVE_TPETRA_DEBUG 997 ArrayView<const GO> rawSrcGids = sourceGIDs;
998 ArrayView<const GO> rawTgtGids = targetGIDs;
1000 const GO*
const rawSrcGids = sourceGIDs.getRawPtr ();
1001 const GO*
const rawTgtGids = targetGIDs.getRawPtr ();
1002 #endif // HAVE_TPETRA_DEBUG 1003 const size_type numSrcGids = sourceGIDs.size ();
1004 const size_type numTgtGids = targetGIDs.size ();
1005 const size_type numGids = std::min (numSrcGids, numTgtGids);
1013 size_type numSameGids = 0;
1014 for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids)
1016 ImportData_->numSameIDs_ = numSameGids;
1028 Array<LO>& permuteToLIDs = ImportData_->permuteToLIDs_;
1029 Array<LO>& permuteFromLIDs = ImportData_->permuteFromLIDs_;
1030 Array<LO>& remoteLIDs = ImportData_->remoteLIDs_;
1031 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
1032 const LO numTgtLids = as<LO> (numTgtGids);
1035 for (LO tgtLid = numSameGids; tgtLid < numTgtLids; ++tgtLid) {
1036 const GO curTargetGid = rawTgtGids[tgtLid];
1040 if (srcLid != LINVALID) {
1041 permuteToLIDs.push_back (tgtLid);
1042 permuteFromLIDs.push_back (srcLid);
1044 remoteGIDs.push_back (curTargetGid);
1045 remoteLIDs.push_back (tgtLid);
1055 ImportData_->isLocallyComplete_ =
false;
1059 (
true, std::runtime_error,
"::setupSamePermuteRemote(): Target has " 1060 "remote LIDs but Source is not distributed globally. Importing to a " 1061 "submap of the target map.");
1066 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1068 setupExport (Teuchos::Array<GlobalOrdinal>& remoteGIDs,
1070 Teuchos::Array<int>& userRemotePIDs)
1072 using Teuchos::arcp;
1073 using Teuchos::Array;
1074 using Teuchos::ArrayRCP;
1075 using Teuchos::ArrayView;
1076 using Teuchos::null;
1078 typedef LocalOrdinal LO;
1079 typedef GlobalOrdinal GO;
1080 typedef typename Array<int>::difference_type size_type;
1081 const char tfecfFuncName[] =
"setupExport: ";
1083 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1084 (
getSourceMap ().is_null (), std::logic_error,
"Source Map is null. " 1085 "Please report this bug to the Tpetra developers.");
1088 Teuchos::OSTab tab (out_);
1097 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1098 (! useRemotePIDs && (userRemotePIDs.size() > 0), std::invalid_argument,
1099 "remotePIDs are non-empty but their use has not been requested.");
1100 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1101 (userRemotePIDs.size () > 0 && remoteGIDs.size () != userRemotePIDs.size (),
1102 std::invalid_argument,
"remotePIDs must either be of size zero or match " 1103 "the size of remoteGIDs.");
1107 ArrayView<GO> remoteGIDsView = remoteGIDs ();
1108 ArrayView<int> remoteProcIDsView;
1128 Array<int> newRemotePIDs;
1131 if (! useRemotePIDs) {
1132 newRemotePIDs.resize (remoteGIDsView.size ());
1133 if (debug_ && ! out_.is_null ()) {
1134 std::ostringstream os;
1135 const int myRank = source.
getComm ()->getRank ();
1136 os << myRank <<
": Import::setupExport: about to call " 1137 "getRemoteIndexList on source Map" << endl;
1142 Array<int>& remoteProcIDs = useRemotePIDs ? userRemotePIDs : newRemotePIDs;
1148 ImportData_->isLocallyComplete_ =
false;
1153 (
true, std::runtime_error,
"::setupExport(): the source Map wasn't " 1154 "able to figure out which process owns one or more of the GIDs in the " 1155 "list of remote GIDs. This probably means that there is at least one " 1156 "GID owned by some process in the target Map which is not owned by any" 1157 " process in the source Map. (That is, the source and target Maps do " 1158 "not contain the same set of GIDs globally.)");
1164 const size_type numInvalidRemote =
1165 std::count_if (remoteProcIDs.begin (), remoteProcIDs.end (),
1166 [] (
const int processor_id) {
1167 return processor_id == -1;
1169 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
1170 (numInvalidRemote == 0, std::logic_error,
"Calling getRemoteIndexList " 1171 "on the source Map returned IDNotPresent, but none of the returned " 1172 "\"remote\" process ranks are -1. Please report this bug to the " 1173 "Tpetra developers.");
1177 if (numInvalidRemote == totalNumRemote) {
1179 remoteProcIDs.clear ();
1180 remoteGIDs.clear ();
1181 ImportData_->remoteLIDs_.clear();
1186 size_type numValidRemote = 0;
1187 #ifdef HAVE_TPETRA_DEBUG 1188 ArrayView<GlobalOrdinal> remoteGIDsPtr = remoteGIDsView;
1190 GlobalOrdinal*
const remoteGIDsPtr = remoteGIDsView.getRawPtr ();
1191 #endif // HAVE_TPETRA_DEBUG 1192 for (size_type r = 0; r < totalNumRemote; ++r) {
1194 if (remoteProcIDs[r] != -1) {
1195 remoteProcIDs[numValidRemote] = remoteProcIDs[r];
1196 remoteGIDsPtr[numValidRemote] = remoteGIDsPtr[r];
1197 ImportData_->remoteLIDs_[numValidRemote] = ImportData_->remoteLIDs_[r];
1201 TEUCHOS_TEST_FOR_EXCEPTION(
1202 numValidRemote != totalNumRemote - numInvalidRemote, std::logic_error,
1203 "Tpetra::Import::setupExport(): After removing invalid remote GIDs and" 1204 " packing the valid remote GIDs, numValidRemote = " << numValidRemote
1205 <<
" != totalNumRemote - numInvalidRemote = " 1206 << totalNumRemote - numInvalidRemote
1207 <<
". Please report this bug to the Tpetra developers.");
1209 remoteProcIDs.resize (numValidRemote);
1210 remoteGIDs.resize (numValidRemote);
1211 ImportData_->remoteLIDs_.resize (numValidRemote);
1214 remoteGIDsView = remoteGIDs ();
1222 sort3 (remoteProcIDs.begin (),
1223 remoteProcIDs.end (),
1224 remoteGIDsView.begin (),
1225 ImportData_->remoteLIDs_.begin ());
1232 Array<GO> exportGIDs;
1233 ImportData_->distributor_.createFromRecvs (remoteGIDsView ().getConst (),
1234 remoteProcIDs, exportGIDs,
1235 ImportData_->exportPIDs_);
1251 const size_type numExportIDs = exportGIDs.size ();
1252 if (numExportIDs > 0) {
1253 ImportData_->exportLIDs_.resize (numExportIDs);
1254 ArrayView<const GO> expGIDs = exportGIDs ();
1255 ArrayView<LO> expLIDs = ImportData_->exportLIDs_ ();
1256 for (size_type k = 0; k < numExportIDs; ++k) {
1261 if (debug_ && ! out_.is_null ()) {
1262 std::ostringstream os;
1263 const int myRank = source.
getComm ()->getRank ();
1264 os << myRank <<
": Import::setupExport: done" << endl;
1269 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1273 Teuchos::Array<std::pair<int,GlobalOrdinal>>& remotePGIDs,
1274 typename Teuchos::Array<GlobalOrdinal>::size_type& numSameGIDs,
1275 typename Teuchos::Array<GlobalOrdinal>::size_type& numPermuteGIDs,
1276 typename Teuchos::Array<GlobalOrdinal>::size_type& numRemoteGIDs,
1277 const Teuchos::ArrayView<const GlobalOrdinal>& sameGIDs1,
1278 const Teuchos::ArrayView<const GlobalOrdinal>& sameGIDs2,
1279 Teuchos::Array<GlobalOrdinal>& permuteGIDs1,
1280 Teuchos::Array<GlobalOrdinal>& permuteGIDs2,
1281 Teuchos::Array<GlobalOrdinal>& remoteGIDs1,
1282 Teuchos::Array<GlobalOrdinal>& remoteGIDs2,
1283 Teuchos::Array<int>& remotePIDs1,
1284 Teuchos::Array<int>& remotePIDs2)
const 1287 typedef GlobalOrdinal GO;
1288 typedef typename Teuchos::Array<GO>::size_type size_type;
1290 const size_type numSameGIDs1 = sameGIDs1.size();
1291 const size_type numSameGIDs2 = sameGIDs2.size();
1294 std::sort(permuteGIDs1.begin(), permuteGIDs1.end());
1295 std::sort(permuteGIDs2.begin(), permuteGIDs2.end());
1300 unionTgtGIDs.reserve(numSameGIDs1 + numSameGIDs2 +
1301 permuteGIDs1.size() + permuteGIDs2.size() +
1302 remoteGIDs1.size() + remoteGIDs2.size());
1306 typename Teuchos::Array<GO>::iterator permuteGIDs1_end;
1307 typename Teuchos::Array<GO>::iterator permuteGIDs2_end;
1308 if (numSameGIDs2 > numSameGIDs1) {
1310 numSameGIDs = numSameGIDs2;
1311 permuteGIDs2_end = permuteGIDs2.end();
1314 std::copy(sameGIDs2.begin(), sameGIDs2.end(), std::back_inserter(unionTgtGIDs));
1318 permuteGIDs1_end = std::set_difference(permuteGIDs1.begin(), permuteGIDs1.end(),
1319 unionTgtGIDs.begin()+numSameGIDs1, unionTgtGIDs.end(),
1320 permuteGIDs1.begin());
1324 numSameGIDs = numSameGIDs1;
1325 permuteGIDs1_end = permuteGIDs1.end();
1328 std::copy(sameGIDs1.begin(), sameGIDs1.end(), std::back_inserter(unionTgtGIDs));
1332 permuteGIDs2_end = std::set_difference(permuteGIDs2.begin(), permuteGIDs2.end(),
1333 unionTgtGIDs.begin()+numSameGIDs2, unionTgtGIDs.end(),
1334 permuteGIDs2.begin());
1339 std::set_union(permuteGIDs1.begin(), permuteGIDs1_end,
1340 permuteGIDs2.begin(), permuteGIDs2_end,
1341 std::back_inserter(unionTgtGIDs));
1344 Teuchos::Array<std::pair<int,GO>> remotePGIDs1(remoteGIDs1.size());
1345 for (size_type k=0; k<remoteGIDs1.size(); k++)
1346 remotePGIDs1[k] = std::make_pair(remotePIDs1[k], remoteGIDs1[k]);
1347 std::sort(remotePGIDs1.begin(), remotePGIDs1.end());
1349 Teuchos::Array<std::pair<int,GO>> remotePGIDs2(remoteGIDs2.size());
1350 for (size_type k=0; k<remoteGIDs2.size(); k++)
1351 remotePGIDs2[k] = std::make_pair(remotePIDs2[k], remoteGIDs2[k]);
1352 std::sort(remotePGIDs2.begin(), remotePGIDs2.end());
1354 remotePGIDs.reserve(remotePGIDs1.size()+remotePGIDs2.size());
1355 std::merge(remotePGIDs1.begin(), remotePGIDs1.end(),
1356 remotePGIDs2.begin(), remotePGIDs2.end(),
1357 std::back_inserter(remotePGIDs));
1358 auto it = std::unique(remotePGIDs.begin(), remotePGIDs.end());
1359 remotePGIDs.resize(std::distance(remotePGIDs.begin(), it));
1362 const size_type oldSize = unionTgtGIDs.size();
1363 unionTgtGIDs.resize(oldSize+remotePGIDs.size());
1364 for (size_type start=oldSize, k=0; k<remotePGIDs.size(); k++)
1365 unionTgtGIDs[start+k] = remotePGIDs[k].second;
1368 numRemoteGIDs = remotePGIDs.size();
1369 numPermuteGIDs = unionTgtGIDs.size() - numSameGIDs - numRemoteGIDs;
1374 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1375 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1380 using Teuchos::Array;
1381 using Teuchos::ArrayView;
1383 using Teuchos::Comm;
1386 using Teuchos::outArg;
1387 using Teuchos::REDUCE_MIN;
1388 using Teuchos::reduceAll;
1389 typedef LocalOrdinal LO;
1390 typedef GlobalOrdinal GO;
1392 typedef typename Array<GO>::size_type size_type;
1394 #ifdef HAVE_TPETRA_MMM_TIMINGS 1395 using Teuchos::TimeMonitor;
1396 std::string label = std::string(
"Tpetra::Import::setUnion");
1397 RCP<TimeMonitor> MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(label)));
1398 label =
"Tpetra::Import::setUnion : Union GIDs";
1399 RCP<TimeMonitor> MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(label)));
1405 RCP<const Comm<int> > comm = srcMap->getComm ();
1410 TEUCHOS_TEST_FOR_EXCEPTION(
1411 ! srcMap->isSameAs (* (rhs.
getSourceMap ())), std::invalid_argument,
1412 "Tpetra::Import::setUnion: The source Map of the input Import must be the " 1413 "same as (in the sense of Map::isSameAs) the source Map of this Import.");
1414 const Comm<int>& comm1 = * (tgtMap1->getComm ());
1415 const Comm<int>& comm2 = * (tgtMap2->getComm ());
1416 TEUCHOS_TEST_FOR_EXCEPTION
1418 std::invalid_argument,
"Tpetra::Import::setUnion: " 1419 "The target Maps must have congruent communicators.");
1425 if (tgtMap1->isSameAs (*tgtMap2)) {
1426 return rcp (
new import_type (*
this));
1435 ArrayView<const GO> sameGIDs1 = (tgtMap1->getNodeElementList())(0,numSameGIDs1);
1438 ArrayView<const GO> sameGIDs2 = (tgtMap2->getNodeElementList())(0,numSameGIDs2);
1442 Array<GO> permuteGIDs1(permuteToLIDs1.size());
1443 for (size_type k=0; k<permuteGIDs1.size(); k++)
1444 permuteGIDs1[k] = tgtMap1->getGlobalElement(permuteToLIDs1[k]);
1447 Array<GO> permuteGIDs2(permuteToLIDs2.size());
1448 for (size_type k=0; k<permuteGIDs2.size(); k++)
1449 permuteGIDs2[k] = tgtMap2->getGlobalElement(permuteToLIDs2[k]);
1453 Array<GO> remoteGIDs1(remoteLIDs1.size());
1454 for (size_type k=0; k<remoteLIDs1.size(); k++)
1455 remoteGIDs1[k] = this->
getTargetMap()->getGlobalElement(remoteLIDs1[k]);
1458 Array<GO> remoteGIDs2(remoteLIDs2.size());
1459 for (size_type k=0; k<remoteLIDs2.size(); k++)
1460 remoteGIDs2[k] = rhs.
getTargetMap()->getGlobalElement(remoteLIDs2[k]);
1463 Array<int> remotePIDs1;
1464 Tpetra::Import_Util::getRemotePIDs(*
this, remotePIDs1);
1466 Array<int> remotePIDs2;
1467 Tpetra::Import_Util::getRemotePIDs(rhs, remotePIDs2);
1470 Array<GO> unionTgtGIDs;
1471 Array<std::pair<int,GO>> remotePGIDs;
1472 size_type numSameIDsUnion, numPermuteIDsUnion, numRemoteIDsUnion;
1475 numSameIDsUnion, numPermuteIDsUnion, numRemoteIDsUnion,
1476 sameGIDs1, sameGIDs2, permuteGIDs1, permuteGIDs2,
1477 remoteGIDs1, remoteGIDs2, remotePIDs1, remotePIDs2);
1480 Array<LO> remoteLIDsUnion(numRemoteIDsUnion);
1481 Array<GO> remoteGIDsUnion(numRemoteIDsUnion);
1482 Array<int> remotePIDsUnion(numRemoteIDsUnion);
1483 const size_type unionRemoteIDsStart = numSameIDsUnion + numPermuteIDsUnion;
1484 for (size_type k = 0; k < numRemoteIDsUnion; ++k) {
1485 remoteLIDsUnion[k] = unionRemoteIDsStart + k;
1486 remotePIDsUnion[k] = remotePGIDs[k].first;
1487 remoteGIDsUnion[k] = remotePGIDs[k].second;
1492 Array<LO> permuteToLIDsUnion(numPermuteIDsUnion);
1493 Array<LO> permuteFromLIDsUnion(numPermuteIDsUnion);
1494 for (size_type k = 0; k < numPermuteIDsUnion; ++k) {
1495 size_type idx = numSameIDsUnion + k;
1496 permuteToLIDsUnion[k] =
static_cast<LO
>(idx);
1497 permuteFromLIDsUnion[k] = srcMap->getLocalElement(unionTgtGIDs[idx]);
1500 #ifdef HAVE_TPETRA_MMM_TIMINGS 1501 MM2 = Teuchos::null;
1502 label =
"Tpetra::Import::setUnion : Construct Tgt Map";
1503 MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(label)));
1507 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
1508 const GO indexBaseUnion = std::min(tgtMap1->getIndexBase(), tgtMap2->getIndexBase());
1509 RCP<const map_type> unionTgtMap =
1510 rcp(
new map_type(INVALID, unionTgtGIDs(), indexBaseUnion, comm));
1512 #ifdef HAVE_TPETRA_MMM_TIMINGS 1513 MM2 = Teuchos::null;
1514 label =
"Tpetra::Import::setUnion : Export GIDs";
1515 MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(label)));
1526 Array<GO> exportGIDsUnion;
1527 Array<LO> exportLIDsUnion;
1528 Array<int> exportPIDsUnion;
1531 #ifdef TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1553 Array<LO> exportLIDs1Copy (exportLIDs1.begin (), exportLIDs1.end ());
1554 Array<int> exportPIDs1Copy (exportLIDs1.begin (), exportLIDs1.end ());
1555 sort2 (exportLIDs1Copy.begin (), exportLIDs1Copy.end (),
1556 exportPIDs1Copy.begin ());
1557 typename ArrayView<LO>::iterator exportLIDs1_end = exportLIDs1Copy.end ();
1558 typename ArrayView<LO>::iterator exportPIDs1_end = exportPIDs1Copy.end ();
1559 merge2 (exportLIDs1_end, exportPIDs1_end,
1560 exportLIDs1Copy.begin (), exportLIDs1_end,
1561 exportPIDs1Copy.begin (), exportPIDs1_end,
1564 Array<LO> exportLIDs2Copy (exportLIDs2.begin (), exportLIDs2.end ());
1565 Array<int> exportPIDs2Copy (exportLIDs2.begin (), exportLIDs2.end ());
1566 sort2 (exportLIDs2Copy.begin (), exportLIDs2Copy.end (),
1567 exportPIDs2Copy.begin ());
1568 typename ArrayView<LO>::iterator exportLIDs2_end = exportLIDs2Copy.end ();
1569 typename ArrayView<LO>::iterator exportPIDs2_end = exportPIDs2Copy.end ();
1570 merge2 (exportLIDs2_end, exportPIDs2_end,
1571 exportLIDs2Copy.begin (), exportLIDs2_end,
1572 exportPIDs2Copy.begin (), exportPIDs2_end,
1579 keyValueMerge (exportLIDs1Copy.begin (), exportLIDs1Copy.end (),
1580 exportPIDs1Copy.begin (), exportPIDs1Copy.end (),
1581 exportLIDs2Copy.begin (), exportLIDs2Copy.end (),
1582 exportPIDs2Copy.begin (), exportPIDs2Copy.end (),
1583 std::back_inserter (exportLIDsUnion),
1584 std::back_inserter (exportPIDsUnion),
1588 sort2 (exportPIDsUnion.begin (), exportPIDsUnion.end (),
1589 exportLIDsUnion.begin ());
1595 #else // NOT TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1603 remotePIDsUnion().getConst(),
1604 exportGIDsUnion, exportPIDsUnion);
1607 const size_type numExportIDsUnion = exportGIDsUnion.size ();
1608 exportLIDsUnion.resize (numExportIDsUnion);
1609 for (size_type k = 0; k < numExportIDsUnion; ++k) {
1610 exportLIDsUnion[k] = srcMap->getLocalElement (exportGIDsUnion[k]);
1612 #endif // TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1615 #ifdef HAVE_TPETRA_MMM_TIMINGS 1616 MM2 = Teuchos::null;
1617 label =
"Tpetra::Import::setUnion : Construct Import";
1618 MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(label)));
1620 RCP<const import_type> unionImport =
1621 rcp (
new import_type (srcMap, unionTgtMap,
1622 as<size_t> (numSameIDsUnion),
1623 permuteToLIDsUnion, permuteFromLIDsUnion,
1624 remoteLIDsUnion, exportLIDsUnion,
1625 exportPIDsUnion, distributor, this->out_));
1630 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1631 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1635 using Teuchos::Array;
1636 using Teuchos::ArrayView;
1638 using Teuchos::Comm;
1641 using Teuchos::outArg;
1642 using Teuchos::REDUCE_MIN;
1643 using Teuchos::reduceAll;
1644 typedef LocalOrdinal LO;
1645 typedef GlobalOrdinal GO;
1646 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> > unionImport;
1649 RCP<const Comm<int> > comm = srcMap->getComm ();
1651 ArrayView<const GO> srcGIDs = srcMap->getNodeElementList ();
1652 ArrayView<const GO> tgtGIDs = tgtMap->getNodeElementList ();
1655 size_t numSameIDsNew = srcMap->getNodeNumElements();
1657 Array<LO> permuteToLIDsNew, permuteFromLIDsNew;
1664 Array<GO> GIDs(numSameIDsNew + numRemoteIDsNew);
1665 for(
size_t i=0; i<numSameIDsNew; i++)
1666 GIDs[i] = srcGIDs[i];
1669 Array<LO> remoteLIDsNew(numRemoteIDsNew);
1670 for(
size_t i=0; i<numRemoteIDsNew; i++) {
1671 GIDs[numSameIDsNew + i] = tgtGIDs[remoteLIDsOld[i]];
1672 remoteLIDsNew[i] = numSameIDsNew+i;
1676 GO GO_INVALID = Teuchos::OrdinalTraits<GO>::invalid();
1677 RCP<const map_type> targetMapNew = rcp(
new map_type(GO_INVALID,GIDs,tgtMap->getIndexBase(),tgtMap->getComm()));
1702 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1703 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1711 TEUCHOS_TEST_FOR_EXCEPTION(
1712 NumRemotes != remoteTarget->getNodeNumElements (),
1713 std::runtime_error,
"Tpetra::createRemoteOnlyImport: " 1714 "remoteTarget map ID count doesn't match.");
1717 Teuchos::ArrayView<const LocalOrdinal> oldRemoteLIDs =
getRemoteLIDs ();
1718 Teuchos::Array<LocalOrdinal> newRemoteLIDs (NumRemotes);
1719 for (
size_t i = 0; i < NumRemotes; ++i) {
1720 newRemoteLIDs[i] = remoteTarget->getLocalElement (
getTargetMap ()->getGlobalElement (oldRemoteLIDs[i]));
1722 TEUCHOS_TEST_FOR_EXCEPTION(
1723 i > 0 && newRemoteLIDs[i] < newRemoteLIDs[i-1],
1724 std::runtime_error,
"Tpetra::createRemoteOnlyImport: " 1725 "this and remoteTarget order don't match.");
1734 Teuchos::Array<LocalOrdinal> newExportLIDs (
getExportLIDs ());
1735 Teuchos::Array<LocalOrdinal> dummy;
1738 return rcp (
new import_type (
getSourceMap (), remoteTarget,
1739 static_cast<size_t> (0), dummy, dummy,
1740 newRemoteLIDs, newExportLIDs,
1741 newExportPIDs, newDistor));
1747 #define TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) \ 1749 namespace Classes { template class Import< LO , GO , NODE >; } 1758 #define TPETRA_IMPORT_INSTANT(LO, GO, NODE) \ 1759 TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) 1761 #endif // TPETRA_IMPORT_DEF_HPP Teuchos::ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Teuchos::RCP< const map_type > getTargetMap() const
The Target Map used to construct this Import object.
Import< LocalOrdinal, GlobalOrdinal, Node > & operator=(const Import< LocalOrdinal, GlobalOrdinal, Node > &Source)
Assignment operator.
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
Sort the first array, and apply the same permutation to the second and third arrays.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
Teuchos::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > setUnion() const
Return the union of this Import this->getSourceMap()
Teuchos::ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
Teuchos::ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent.
Teuchos::RCP< const map_type > getSourceMap() const
The Source Map used to construct this Import object.
Classes::Import< LocalOrdinal, GlobalOrdinal, Node > Import
Alias for Tpetra::Classes::Import.
static bool debug()
Whether Tpetra is in debug mode.
Teuchos::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > createRemoteOnlyImport(const Teuchos::RCP< const map_type > &remoteTarget) const
Returns an importer that contains only the remote entries of this.
void findUnionTargetGIDs(Teuchos::Array< GlobalOrdinal > &unionTgtGIDs, Teuchos::Array< std::pair< int, GlobalOrdinal >> &remotePGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numSameGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numPermuteGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numRemoteGIDs, const Teuchos::ArrayView< const GlobalOrdinal > &sameGIDs1, const Teuchos::ArrayView< const GlobalOrdinal > &sameGIDs2, Teuchos::Array< GlobalOrdinal > &permuteGIDs1, Teuchos::Array< GlobalOrdinal > &permuteGIDs2, Teuchos::Array< GlobalOrdinal > &remoteGIDs1, Teuchos::Array< GlobalOrdinal > &remoteGIDs2, Teuchos::Array< int > &remotePIDs1, Teuchos::Array< int > &remotePIDs2) const
Find the union of the target IDs from two Import objects.
::Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The specialization of Map used by this class.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
size_t createFromSends(const Teuchos::ArrayView< const int > &exportProcIDs)
Set up Distributor using list of process ranks to which this process will send.
size_t global_size_t
Global size_t object.
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2 valEnd)
Merge values in place, additively, with the same index.
Implementation detail of Import and Export.
void keyValueMerge(KeyInputIterType keyBeg1, KeyInputIterType keyEnd1, ValueInputIterType valBeg1, ValueInputIterType valEnd1, KeyInputIterType keyBeg2, KeyInputIterType keyEnd2, ValueInputIterType valBeg2, ValueInputIterType valEnd2, KeyOutputIterType keyOut, ValueOutputIterType valOut, BinaryFunction f)
Merge two sorted (by keys) sequences of unique (key,value) pairs by combining pairs with equal keys...
#define TPETRA_ABUSE_WARNING(throw_exception_test, Exception, msg)
Handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WA...
Sets up and executes a communication plan for a Tpetra DistObject.
static bool verbose()
Whether Tpetra is in verbose mode.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
Teuchos::ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a NONOWNING view of the global indices owned by this process.
bool isLocallyComplete() const
Do all target Map indices on the calling process exist on at least one process (not necessarily this ...
size_t getNumPermuteIDs() const
Number of IDs to permute but not to communicate.
Teuchos::ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
Import(const Teuchos::RCP< const map_type > &source, const Teuchos::RCP< const map_type > &target)
Construct an Import from the source and target Maps.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
size_t getNumExportIDs() const
Number of entries that must be sent by the calling process to other processes.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Describe this object in a human-readable way to the given output stream.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects...
Stand-alone utility functions and macros.
Distributor & getDistributor() const
The Distributor that this Import object uses to move data.
virtual ~Import()
Destructor.
A parallel distribution of indices over processes.
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of describe() for subclasses (Tpetra::Import and Tpetra::Export).
virtual void print(std::ostream &os) const
Print the Import's data to the given output stream.
void createFromRecvs(const Teuchos::ArrayView< const Ordinal > &remoteIDs, const Teuchos::ArrayView< const int > &remoteProcIDs, Teuchos::Array< Ordinal > &exportIDs, Teuchos::Array< int > &exportProcIDs)
Set up Distributor using list of process ranks from which to receive.
Binary function that returns its first argument.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
size_t getNumSameIDs() const
Number of initial identical IDs.