42 #ifndef TPETRA_EXPORT_DEF_HPP
43 #define TPETRA_EXPORT_DEF_HPP
46 #include "Tpetra_Distributor.hpp"
47 #include "Tpetra_Map.hpp"
48 #include "Tpetra_ImportExportData.hpp"
50 #include "Tpetra_Import.hpp"
51 #include "Tpetra_Details_DualViewUtil.hpp"
53 #include "Teuchos_as.hpp"
54 #include "Teuchos_Array.hpp"
55 #include "Teuchos_FancyOStream.hpp"
56 #include "Teuchos_ParameterList.hpp"
61 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
63 Export (
const Teuchos::RCP<const map_type >& source,
64 const Teuchos::RCP<const map_type >& target,
65 const Teuchos::RCP<Teuchos::FancyOStream>& out,
66 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
67 base_type (source, target, out, plist,
"Export")
71 using ::Tpetra::Details::ProfilingRegion;
72 ProfilingRegion regionExport (
"Tpetra::Export::Export");
75 std::ostringstream os;
76 const int myRank = source->getComm ()->getRank ();
77 os << myRank <<
": Export ctor" << endl;
80 Teuchos::Array<GlobalOrdinal> exportGIDs;
81 setupSamePermuteExport (exportGIDs);
82 if (source->isDistributed ()) {
83 setupRemote (exportGIDs);
86 TEUCHOS_ASSERT( ! this->
TransferData_->permuteFromLIDs_.need_sync_device () );
87 TEUCHOS_ASSERT( ! this->
TransferData_->permuteFromLIDs_.need_sync_host () );
88 TEUCHOS_ASSERT( ! this->
TransferData_->permuteToLIDs_.need_sync_device () );
89 TEUCHOS_ASSERT( ! this->
TransferData_->permuteToLIDs_.need_sync_host () );
90 TEUCHOS_ASSERT( ! this->
TransferData_->remoteLIDs_.need_sync_device () );
91 TEUCHOS_ASSERT( ! this->
TransferData_->remoteLIDs_.need_sync_host () );
92 TEUCHOS_ASSERT( ! this->
TransferData_->exportLIDs_.need_sync_device () );
93 TEUCHOS_ASSERT( ! this->
TransferData_->exportLIDs_.need_sync_host () );
96 std::ostringstream os;
97 const int myRank = source->getComm ()->getRank ();
98 os << myRank <<
": Export ctor: done" << endl;
103 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
105 Export (
const Teuchos::RCP<const map_type>& source,
106 const Teuchos::RCP<const map_type>& target) :
107 Export (source, target, Teuchos::null, Teuchos::null)
110 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
112 Export (
const Teuchos::RCP<const map_type >& source,
113 const Teuchos::RCP<const map_type >& target,
114 const Teuchos::RCP<Teuchos::FancyOStream>& out) :
115 Export (source, target, out, Teuchos::null)
118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
120 Export (
const Teuchos::RCP<const map_type >& source,
121 const Teuchos::RCP<const map_type >& target,
122 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
123 Export (source, target, Teuchos::null, plist)
126 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
132 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
138 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
142 const Teuchos::EVerbosityLevel verbLevel)
const
145 this->describeImpl (out,
"Tpetra::Export", verbLevel);
148 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
152 auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
154 this->describe (*out, Teuchos::VERB_EXTREME);
157 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
162 using ::Tpetra::Details::makeDualViewFromOwningHostView;
163 using ::Tpetra::Details::ProfilingRegion;
164 using ::Tpetra::Details::view_alloc_no_init;
166 using Teuchos::Array;
167 using Teuchos::ArrayRCP;
168 using Teuchos::ArrayView;
172 using LO = LocalOrdinal;
173 using GO = GlobalOrdinal;
174 using size_type =
typename ArrayView<const GO>::size_type;
175 const char tfecfFuncName[] =
"setupSamePermuteExport: ";
176 ProfilingRegion regionExport (
"Tpetra::Export::setupSamePermuteExport");
178 std::unique_ptr<std::string> prefix;
179 if (this->verbose ()) {
180 auto srcMap = this->getSourceMap ();
181 auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
182 const int myRank = comm.is_null () ? -1 : comm->getRank ();
184 std::ostringstream os;
185 os <<
"Proc " << myRank <<
": Tpetra::Export::setupSamePermuteExport: ";
186 prefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
188 std::ostringstream os2;
189 os2 << *prefix <<
"Start" << std::endl;
190 this->verboseOutputStream () << os2.str ();
193 const map_type& source = * (this->getSourceMap ());
194 const map_type& target = * (this->getTargetMap ());
195 ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
196 ArrayView<const GO> targetGIDs = target.getNodeElementList ();
198 #ifdef HAVE_TPETRA_DEBUG
199 ArrayView<const GO> rawSrcGids = sourceGIDs;
200 ArrayView<const GO> rawTgtGids = targetGIDs;
202 const GO*
const rawSrcGids = sourceGIDs.getRawPtr ();
203 const GO*
const rawTgtGids = targetGIDs.getRawPtr ();
204 #endif // HAVE_TPETRA_DEBUG
205 const size_type numSrcGids = sourceGIDs.size ();
206 const size_type numTgtGids = targetGIDs.size ();
207 const size_type numGids = std::min (numSrcGids, numTgtGids);
215 size_type numSameGids = 0;
216 for ( ; numSameGids < numGids &&
217 rawSrcGids[numSameGids] == rawTgtGids[numSameGids];
220 this->TransferData_->numSameIDs_ = numSameGids;
222 if (this->verbose ()) {
223 std::ostringstream os;
224 os << *prefix <<
"numIDs: " << numGids
225 <<
", numSameIDs: " << numSameGids << endl;
226 this->verboseOutputStream () << os.str ();
241 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
242 const LO numSrcLids =
static_cast<LO
> (numSrcGids);
248 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
249 const GO curSrcGid = rawSrcGids[srcLid];
253 const LO tgtLid = target.getLocalElement (curSrcGid);
254 if (tgtLid != LINVALID) {
261 if (this->verbose ()) {
262 std::ostringstream os;
263 os << *prefix <<
"numPermutes: " << numPermutes
264 <<
", numExports: " << numExports << endl;
265 this->verboseOutputStream () << os.str ();
267 TEUCHOS_ASSERT( numPermutes + numExports ==
268 numSrcLids - numSameGids );
270 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
272 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
274 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
279 exportGIDs.resize (numExports);
284 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
285 const GO curSrcGid = rawSrcGids[srcLid];
286 const LO tgtLid = target.getLocalElement (curSrcGid);
287 if (tgtLid != LINVALID) {
288 permuteToLIDs[numPermutes2] = tgtLid;
289 permuteFromLIDs[numPermutes2] = srcLid;
293 exportGIDs[numExports2] = curSrcGid;
294 exportLIDs[numExports2] = srcLid;
298 TEUCHOS_ASSERT( numPermutes == numPermutes2 );
299 TEUCHOS_ASSERT( numExports == numExports2 );
300 TEUCHOS_ASSERT(
size_t (numExports) ==
size_t (exportGIDs.size ()) );
313 if (numExports != 0 && ! source.isDistributed ()) {
319 this->TransferData_->isLocallyComplete_ =
false;
320 if (this->verbose ()) {
321 std::ostringstream os;
322 os << *prefix <<
"Export is not locally complete" << endl;
323 this->verboseOutputStream () << os.str ();
328 (
true, std::runtime_error,
"::setupSamePermuteExport(): Source has "
329 "export LIDs but Source is not distributed globally. Exporting to "
330 "a submap of the target map.");
344 if (source.isDistributed ()) {
345 if (this->verbose ()) {
346 std::ostringstream os;
347 os << *prefix <<
"Source Map is distributed; "
348 "call targetMap.getRemoteiNdexList" << endl;
349 this->verboseOutputStream () << os.str ();
351 this->TransferData_->exportPIDs_.resize(exportGIDs.size ());
356 target.getRemoteIndexList (exportGIDs(),
357 this->TransferData_->exportPIDs_ ());
361 "::setupSamePermuteExport(): The source Map has GIDs not found "
362 "in the target Map.");
371 this->TransferData_->isLocallyComplete_ =
false;
373 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
375 const size_type totalNumExports = exportPIDs.size ();
376 const size_type numInvalidExports =
377 std::count_if (exportPIDs.begin (), exportPIDs.end (),
378 [] (
const int procId) {
return procId == -1; });
379 if (this->verbose ()) {
380 std::ostringstream os;
381 os << *prefix <<
"totalNumExports: " << totalNumExports
382 <<
", numInvalidExports: " << numInvalidExports << endl;
383 this->verboseOutputStream () << os.str ();
385 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
386 (numInvalidExports == 0, std::logic_error,
387 "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
388 "PIDs are -1. Please report this bug to the Tpetra developers.");
396 if (numInvalidExports == totalNumExports) {
397 exportGIDs.resize (0);
398 exportLIDs = decltype (exportLIDs) ();
399 exportPIDs.resize (0);
402 size_type numValidExports = 0;
403 for (size_type e = 0; e < totalNumExports; ++e) {
404 if (this->TransferData_->exportPIDs_[e] != -1) {
405 exportGIDs[numValidExports] = exportGIDs[e];
406 exportLIDs[numValidExports] = exportLIDs[e];
407 exportPIDs[numValidExports] = exportPIDs[e];
411 exportGIDs.resize (numValidExports);
412 Kokkos::resize (exportLIDs, numValidExports);
413 exportPIDs.resize (numValidExports);
425 if (this->verbose ()) {
426 std::ostringstream os;
427 os << *prefix <<
"Done!" << std::endl;
428 this->verboseOutputStream () << os.str ();
432 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
434 Export<LocalOrdinal,GlobalOrdinal,Node>::
435 setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
437 using ::Tpetra::Details::view_alloc_no_init;
438 using ::Tpetra::Details::makeDualViewFromOwningHostView;
439 using Teuchos::Array;
441 using LO = LocalOrdinal;
442 using GO = GlobalOrdinal;
444 std::unique_ptr<std::string> prefix;
445 if (this->verbose ()) {
446 auto srcMap = this->getSourceMap ();
447 auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
448 const int myRank = comm.is_null () ? -1 : comm->getRank ();
450 std::ostringstream os;
451 os <<
"Proc " << myRank <<
": Tpetra::Export::setupRemote: ";
452 prefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
454 std::ostringstream os2;
455 os2 << *prefix <<
"Start" << std::endl;
456 this->verboseOutputStream () << os2.str ();
459 TEUCHOS_ASSERT( ! this->getTargetMap ().is_null () );
460 const map_type& tgtMap = * (this->getTargetMap ());
467 TEUCHOS_ASSERT(
size_t (this->TransferData_->exportLIDs_.extent (0)) ==
468 size_t (this->TransferData_->exportPIDs_.size ()) );
469 this->TransferData_->exportLIDs_.modify_host ();
470 auto exportLIDs = this->TransferData_->exportLIDs_.view_host ();
471 sort3 (this->TransferData_->exportPIDs_.begin (),
472 this->TransferData_->exportPIDs_.end (),
473 exportGIDs.getRawPtr (),
475 this->TransferData_->exportLIDs_.sync_device ();
481 if (this->verbose ()) {
482 std::ostringstream os;
483 os << *prefix <<
"Call createFromSends" << endl;
484 this->verboseOutputStream () << os.str ();
493 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
494 Distributor& distributor = this->TransferData_->distributor_;
495 const size_t numRemoteIDs = distributor.createFromSends (exportPIDs ());
497 if (this->verbose ()) {
498 std::ostringstream os;
499 os << *prefix <<
"numRemoteIDs: " << numRemoteIDs
500 <<
"; call doPostsAndWaits" << endl;
501 this->verboseOutputStream () << os.str ();
508 std::unique_ptr<GO[]> remoteGIDs_ptr (
new GlobalOrdinal [numRemoteIDs]);
509 Teuchos::ArrayView<GO> remoteGIDs
510 (numRemoteIDs == 0 ?
nullptr : remoteGIDs_ptr.get (), numRemoteIDs);
511 distributor.doPostsAndWaits (exportGIDs ().getConst (), 1, remoteGIDs);
515 using host_remote_lids_type =
516 typename decltype (this->TransferData_->remoteLIDs_)::t_host;
517 host_remote_lids_type remoteLIDs
518 (view_alloc_no_init (
"remoteLIDs"), numRemoteIDs);
522 for (LO j = 0; j < LO (numRemoteIDs); ++j) {
523 remoteLIDs[j] = tgtMap.getLocalElement (remoteGIDs[j]);
527 if (this->verbose ()) {
528 std::ostringstream os;
529 os << *prefix <<
"Done!" << endl;
530 this->verboseOutputStream () << os.str ();
543 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
544 template class Export< LO , GO , NODE >;
546 #endif // TPETRA_EXPORT_DEF_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::FancyOStream & verboseOutputStream() const
Valid (nonnull) output stream for verbose output.
virtual void print(std::ostream &os) const
Print the Export's data to the given output stream.
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.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
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.
Export(const Teuchos::RCP< const map_type > &source, const Teuchos::RCP< const map_type > &target)
Construct a Export object from the source and target Map.
auto view_alloc_no_init(const std::string &label) ->
Use in place of the string label as the first argument of Kokkos::View's constructor, in case you want to allocate without initializing.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
#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...
Teuchos::RCP< ImportExportData< LocalOrdinal, GlobalOrdinal, Node > > TransferData_
All the data needed for executing the Export communication plan.
Stand-alone utility functions and macros.
void makeDualViewFromOwningHostView(Kokkos::DualView< ElementType *, DeviceType > &dv, const typename Kokkos::DualView< ElementType *, DeviceType >::t_host &hostView)
Initialize dv such that its host View is hostView.
bool verbose() const
Whether to print verbose debugging output.