42 #ifndef TPETRA_EXPORT_DEF_HPP
43 #define TPETRA_EXPORT_DEF_HPP
45 #include "Tpetra_Distributor.hpp"
46 #include "Tpetra_Map.hpp"
47 #include "Tpetra_ImportExportData.hpp"
49 #include "Tpetra_Import.hpp"
50 #include "Teuchos_as.hpp"
51 #include "Teuchos_Array.hpp"
52 #include "Teuchos_FancyOStream.hpp"
53 #include "Teuchos_ParameterList.hpp"
57 const bool tpetraExportDebugDefault =
false;
62 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 bool debug = tpetraExportDebugDefault;
68 if (! plist.is_null ()) {
70 debug = plist->get<
bool> (
"Debug");
71 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
74 ExportData_->distributor_.setParameterList (plist);
77 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
79 Export (
const Teuchos::RCP<const map_type >& source,
80 const Teuchos::RCP<const map_type >& target) :
81 out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
82 debug_ (tpetraExportDebugDefault)
88 if (! out_.is_null ()) {
92 std::ostringstream os;
93 const int myRank = source->getComm ()->getRank ();
94 os << myRank <<
": Export ctor" << endl;
97 ExportData_ = rcp (
new data_type (source, target, out_));
98 Teuchos::Array<GlobalOrdinal> exportGIDs;
99 setupSamePermuteExport (exportGIDs);
101 std::ostringstream os;
102 const int myRank = source->getComm ()->getRank ();
103 os << myRank <<
": Export ctor: "
104 <<
"setupSamePermuteExport done" << endl;
107 if (source->isDistributed ()) {
108 setupRemote (exportGIDs);
111 std::ostringstream os;
112 const int myRank = source->getComm ()->getRank ();
113 os << myRank <<
": Export ctor: done" << endl;
116 if (! out_.is_null ()) {
121 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
123 Export (
const Teuchos::RCP<const map_type >& source,
124 const Teuchos::RCP<const map_type >& target,
125 const Teuchos::RCP<Teuchos::FancyOStream>& out) :
127 debug_ (tpetraExportDebugDefault)
133 if (! out_.is_null ()) {
137 std::ostringstream os;
138 const int myRank = source->getComm ()->getRank ();
139 os << myRank <<
": Export ctor" << endl;
142 ExportData_ = rcp (
new data_type (source, target, out));
143 Teuchos::Array<GlobalOrdinal> exportGIDs;
144 setupSamePermuteExport (exportGIDs);
146 std::ostringstream os;
147 const int myRank = source->getComm ()->getRank ();
148 os << myRank <<
": Export ctor: "
149 <<
"setupSamePermuteExport done" << endl;
152 if (source->isDistributed ()) {
153 setupRemote (exportGIDs);
156 std::ostringstream os;
157 const int myRank = source->getComm ()->getRank ();
158 os << myRank <<
": Export ctor: done" << endl;
161 if (! out_.is_null ()) {
166 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
168 Export (
const Teuchos::RCP<const map_type >& source,
169 const Teuchos::RCP<const map_type >& target,
170 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
171 out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
172 debug_ (tpetraExportDebugDefault)
179 bool debug = tpetraExportDebugDefault;
180 if (! plist.is_null ()) {
182 debug = plist->get<
bool> (
"Debug");
183 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
187 if (! out_.is_null ()) {
191 std::ostringstream os;
192 const int myRank = source->getComm ()->getRank ();
193 os << myRank <<
": Export ctor" << endl;
196 ExportData_ = rcp (
new data_type (source, target, out_, plist));
197 Teuchos::Array<GlobalOrdinal> exportGIDs;
198 setupSamePermuteExport (exportGIDs);
200 std::ostringstream os;
201 const int myRank = source->getComm ()->getRank ();
202 os << myRank <<
": Export ctor: "
203 <<
"setupSamePermuteExport done" << endl;
206 if (source->isDistributed ()) {
207 setupRemote (exportGIDs);
210 std::ostringstream os;
211 const int myRank = source->getComm ()->getRank ();
212 os << myRank <<
": Export ctor: done" << endl;
215 if (! out_.is_null ()) {
220 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
222 Export (
const Teuchos::RCP<const map_type >& source,
223 const Teuchos::RCP<const map_type >& target,
224 const Teuchos::RCP<Teuchos::FancyOStream>& out,
225 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
226 out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
227 debug_ (tpetraExportDebugDefault)
234 bool debug = tpetraExportDebugDefault;
235 if (! plist.is_null ()) {
237 debug = plist->get<
bool> (
"Debug");
238 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
242 if (! out_.is_null ()) {
246 std::ostringstream os;
247 const int myRank = source->getComm ()->getRank ();
248 os << myRank <<
": Export ctor" << endl;
251 ExportData_ = rcp (
new data_type (source, target, out, plist));
252 Teuchos::Array<GlobalOrdinal> exportGIDs;
253 setupSamePermuteExport (exportGIDs);
255 std::ostringstream os;
256 const int myRank = source->getComm ()->getRank ();
257 os << myRank <<
": Export ctor: "
258 <<
"setupSamePermuteExport done" << endl;
261 if (source->isDistributed ()) {
262 setupRemote (exportGIDs);
265 std::ostringstream os;
266 const int myRank = source->getComm ()->getRank ();
267 os << myRank <<
": Export ctor: done" << endl;
270 if (! out_.is_null ()) {
275 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
278 : ExportData_ (rhs.ExportData_),
284 if (! out_.is_null ()) {
288 std::ostringstream os;
289 const int myRank =
getSourceMap ()->getComm ()->getRank ();
290 os << myRank <<
": Export copy ctor (done)" << endl;
293 if (! out_.is_null ()) {
298 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
301 : out_ (importer.out_)
302 , debug_ (importer.debug_)
304 if(!importer.ImportData_.is_null()) ExportData_ = importer.ImportData_->reverseClone();
307 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
311 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
313 return ExportData_->numSameIDs_;
316 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
318 return ExportData_->permuteFromLIDs_.size();
321 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
322 Teuchos::ArrayView<const LocalOrdinal>
324 return ExportData_->permuteFromLIDs_();
327 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
328 Teuchos::ArrayView<const LocalOrdinal>
330 return ExportData_->permuteToLIDs_();
333 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
335 return ExportData_->remoteLIDs_.size();
338 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
339 Teuchos::ArrayView<const LocalOrdinal>
341 return ExportData_->remoteLIDs_();
344 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
346 return ExportData_->exportLIDs_.size();
349 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
350 Teuchos::ArrayView<const LocalOrdinal>
352 return ExportData_->exportLIDs_();
355 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
356 Teuchos::ArrayView<const int>
358 return ExportData_->exportPIDs_();
361 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
362 Teuchos::RCP<const typename Export<LocalOrdinal,GlobalOrdinal,Node>::map_type>
364 return ExportData_->source_;
367 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
368 Teuchos::RCP<const typename Export<LocalOrdinal,GlobalOrdinal,Node>::map_type>
370 return ExportData_->target_;
373 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
376 return ExportData_->distributor_;
379 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
382 return ExportData_->isLocallyComplete_;
385 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
390 ExportData_ = rhs.ExportData_;
395 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
399 const Teuchos::EVerbosityLevel verbLevel)
const
402 this->describeImpl (out,
"Tpetra::Export", verbLevel);
405 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
409 auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
411 this->describe (*out, Teuchos::VERB_EXTREME);
414 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
420 using Teuchos::Array;
421 using Teuchos::ArrayRCP;
422 using Teuchos::ArrayView;
425 typedef LocalOrdinal LO;
426 typedef GlobalOrdinal GO;
427 typedef typename ArrayView<const GO>::size_type size_type;
428 const char tfecfFuncName[] =
"setupExport: ";
430 const map_type& source = * (getSourceMap ());
431 const map_type& target = * (getTargetMap ());
432 ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
433 ArrayView<const GO> targetGIDs = target.getNodeElementList ();
435 #ifdef HAVE_TPETRA_DEBUG
436 ArrayView<const GO> rawSrcGids = sourceGIDs;
437 ArrayView<const GO> rawTgtGids = targetGIDs;
439 const GO*
const rawSrcGids = sourceGIDs.getRawPtr ();
440 const GO*
const rawTgtGids = targetGIDs.getRawPtr ();
441 #endif // HAVE_TPETRA_DEBUG
442 const size_type numSrcGids = sourceGIDs.size ();
443 const size_type numTgtGids = targetGIDs.size ();
444 const size_type numGids = std::min (numSrcGids, numTgtGids);
452 size_type numSameGids = 0;
453 for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids)
455 ExportData_->numSameIDs_ = numSameGids;
467 exportGIDs.resize (0);
468 Array<LO>& permuteToLIDs = ExportData_->permuteToLIDs_;
469 Array<LO>& permuteFromLIDs = ExportData_->permuteFromLIDs_;
470 Array<LO>& exportLIDs = ExportData_->exportLIDs_;
471 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
472 const LO numSrcLids = as<LO> (numSrcGids);
475 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
476 const GO curSrcGid = rawSrcGids[srcLid];
479 const LO tgtLid = target.getLocalElement (curSrcGid);
480 if (tgtLid != LINVALID) {
481 permuteToLIDs.push_back (tgtLid);
482 permuteFromLIDs.push_back (srcLid);
484 exportGIDs.push_back (curSrcGid);
485 exportLIDs.push_back (srcLid);
496 if (exportLIDs.size () != 0 && ! source.isDistributed ()) {
502 ExportData_->isLocallyComplete_ =
false;
506 (
true, std::runtime_error,
"::setupSamePermuteExport(): Source has "
507 "export LIDs but Source is not distributed globally. Exporting to "
508 "a submap of the target map.");
522 if (source.isDistributed ()) {
523 ExportData_->exportPIDs_.resize(exportGIDs.size ());
528 target.getRemoteIndexList (exportGIDs(),
529 ExportData_->exportPIDs_ ());
533 "::setupSamePermuteExport(): The source Map has GIDs not found "
534 "in the target Map.");
543 ExportData_->isLocallyComplete_ =
false;
545 const size_type numInvalidExports =
546 std::count_if (ExportData_->exportPIDs_().begin(),
547 ExportData_->exportPIDs_().end(),
548 [] (
const int processor_id) {
549 return processor_id == -1;
551 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
552 (numInvalidExports == 0, std::logic_error,
"Calling getRemoteIndexList "
553 "on the target Map returned IDNotPresent, but none of the returned "
554 "\"export\" process ranks are -1. Please report this bug to the "
555 "Tpetra developers.");
558 const size_type totalNumExports = ExportData_->exportPIDs_.size();
559 if (numInvalidExports == totalNumExports) {
561 exportGIDs.resize(0);
562 ExportData_->exportLIDs_.resize(0);
563 ExportData_->exportPIDs_.resize(0);
568 size_type numValidExports = 0;
569 for (size_type e = 0; e < totalNumExports; ++e) {
570 if (ExportData_->exportPIDs_[e] != -1) {
571 exportGIDs[numValidExports] = exportGIDs[e];
572 ExportData_->exportLIDs_[numValidExports] = ExportData_->exportLIDs_[e];
573 ExportData_->exportPIDs_[numValidExports] = ExportData_->exportPIDs_[e];
577 exportGIDs.resize (numValidExports);
578 ExportData_->exportLIDs_.resize (numValidExports);
579 ExportData_->exportPIDs_.resize (numValidExports);
585 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
587 Export<LocalOrdinal,GlobalOrdinal,Node>::setupRemote(Teuchos::Array<GlobalOrdinal> & exportGIDs)
589 using Teuchos::Array;
592 const map_type& target = * (getTargetMap ());
593 const int myRank = target.getComm ()->getRank ();
595 if (! out_.is_null ()) {
599 std::ostringstream os;
600 os << myRank <<
": Export::setupRemote" << endl;
603 if (! out_.is_null ()) {
611 sort3 (ExportData_->exportPIDs_.begin(),
612 ExportData_->exportPIDs_.end(),
614 ExportData_->exportLIDs_.begin());
617 std::ostringstream os;
618 os << myRank <<
": Export::setupRemote: Calling createFromSends" << endl;
629 numRemoteIDs = ExportData_->distributor_.createFromSends (ExportData_->exportPIDs_ ());
632 std::ostringstream os;
633 os << myRank <<
": Export::setupRemote: Calling doPostsAndWaits" << endl;
640 Array<GlobalOrdinal> remoteGIDs (numRemoteIDs);
641 ExportData_->distributor_.doPostsAndWaits (exportGIDs().getConst (), 1, remoteGIDs());
645 ExportData_->remoteLIDs_.resize (numRemoteIDs);
647 typename Array<GlobalOrdinal>::const_iterator i = remoteGIDs.begin();
648 typename Array<LocalOrdinal>::iterator j = ExportData_->remoteLIDs_.begin();
649 while (i != remoteGIDs.end()) {
650 *j++ = target.getLocalElement(*i++);
654 if (! out_.is_null ()) {
658 std::ostringstream os;
659 os << myRank <<
": Export::setupRemote: done" << endl;
662 if (! out_.is_null ()) {
677 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
679 namespace Classes { template class Export< LO , GO , NODE >; }
681 #endif // TPETRA_EXPORT_DEF_HPP