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>
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 () ?
267 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr)) : out)
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
965 this->describeImpl (out,
"Tpetra::Import", verbLevel);
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;
991 const map_type& source = * (getSourceMap ());
992 const map_type& target = * (getTargetMap ());
993 ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
994 ArrayView<const GO> targetGIDs = target.getNodeElementList ();
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];
1039 const LO srcLid = source.getLocalElement (curTargetGid);
1040 if (srcLid != LINVALID) {
1041 permuteToLIDs.push_back (tgtLid);
1042 permuteFromLIDs.push_back (srcLid);
1044 remoteGIDs.push_back (curTargetGid);
1045 remoteLIDs.push_back (tgtLid);
1049 if (remoteLIDs.size () != 0 && ! source.isDistributed ()) {
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>
1067 void Import<LocalOrdinal,GlobalOrdinal,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.");
1086 const map_type& source = * (getSourceMap ());
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;
1140 lookup = source.getRemoteIndexList (remoteGIDsView, newRemotePIDs ());
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.");
1176 const size_type totalNumRemote = getNumRemoteIDs ();
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) {
1257 expLIDs[k] = source.getLocalElement (expGIDs[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)));
1402 RCP<const map_type> srcMap = this->getSourceMap ();
1403 RCP<const map_type> tgtMap1 = this->getTargetMap ();
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));
1434 const size_type numSameGIDs1 = this->getNumSameIDs();
1435 ArrayView<const GO> sameGIDs1 = (tgtMap1->getNodeElementList())(0,numSameGIDs1);
1438 ArrayView<const GO> sameGIDs2 = (tgtMap2->getNodeElementList())(0,numSameGIDs2);
1441 ArrayView<const LO> permuteToLIDs1 = this->getPermuteToLIDs();
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]);
1452 ArrayView<const LO> remoteLIDs1 = this->getRemoteLIDs();
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;
1474 findUnionTargetGIDs(unionTgtGIDs, remotePGIDs,
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
1539 ArrayView<const LO> exportLIDs1 = this->getExportLIDs ();
1540 ArrayView<const LO> exportPIDs1 = this->getExportPIDs ();
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;
1647 RCP<const map_type> srcMap = this->getSourceMap ();
1648 RCP<const map_type> tgtMap = this->getTargetMap ();
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();
1656 size_t numRemoteIDsNew = getNumRemoteIDs();
1657 Array<LO> permuteToLIDsNew, permuteFromLIDsNew;
1660 ArrayView<const LO> remoteLIDsOld = getRemoteLIDs();
1661 ArrayView<const LO> exportLIDsOld = getExportLIDs();
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()));
1680 Array<int> exportPIDsnew(getExportPIDs());
1681 Array<LO> exportLIDsnew(getExportLIDs());
1702 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1703 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1710 const size_t NumRemotes = getNumRemoteIDs ();
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.");
1733 Teuchos::Array<int> newExportPIDs (getExportPIDs ());
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