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);
245 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
246 const GO curSrcGid = rawSrcGids[srcLid];
250 const LO tgtLid = target.getLocalElement (curSrcGid);
251 if (tgtLid != LINVALID) {
258 if (this->verbose ()) {
259 std::ostringstream os;
260 os << *prefix <<
"numPermutes: " << numPermutes
261 <<
", numExports: " << numExports << endl;
262 this->verboseOutputStream () << os.str ();
264 TEUCHOS_ASSERT( numPermutes + numExports ==
265 numSrcLids - numSameGids );
267 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
269 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
271 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
276 exportGIDs.resize (numExports);
281 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
282 const GO curSrcGid = rawSrcGids[srcLid];
283 const LO tgtLid = target.getLocalElement (curSrcGid);
284 if (tgtLid != LINVALID) {
285 permuteToLIDs[numPermutes2] = tgtLid;
286 permuteFromLIDs[numPermutes2] = srcLid;
290 exportGIDs[numExports2] = curSrcGid;
291 exportLIDs[numExports2] = srcLid;
295 TEUCHOS_ASSERT( numPermutes == numPermutes2 );
296 TEUCHOS_ASSERT( numExports == numExports2 );
297 TEUCHOS_ASSERT(
size_t (numExports) ==
size_t (exportGIDs.size ()) );
310 if (numExports != 0 && ! source.isDistributed ()) {
316 this->TransferData_->isLocallyComplete_ =
false;
317 if (this->verbose ()) {
318 std::ostringstream os;
319 os << *prefix <<
"Export is not locally complete" << endl;
320 this->verboseOutputStream () << os.str ();
325 (
true, std::runtime_error,
"::setupSamePermuteExport(): Source has "
326 "export LIDs but Source is not distributed globally. Exporting to "
327 "a submap of the target map.");
341 if (source.isDistributed ()) {
342 if (this->verbose ()) {
343 std::ostringstream os;
344 os << *prefix <<
"Source Map is distributed; "
345 "call targetMap.getRemoteiNdexList" << endl;
346 this->verboseOutputStream () << os.str ();
348 this->TransferData_->exportPIDs_.resize(exportGIDs.size ());
353 target.getRemoteIndexList (exportGIDs(),
354 this->TransferData_->exportPIDs_ ());
358 "::setupSamePermuteExport(): The source Map has GIDs not found "
359 "in the target Map.");
368 this->TransferData_->isLocallyComplete_ =
false;
370 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
372 const size_type totalNumExports = exportPIDs.size ();
373 const size_type numInvalidExports =
374 std::count_if (exportPIDs.begin (), exportPIDs.end (),
375 [] (
const int procId) {
return procId == -1; });
376 if (this->verbose ()) {
377 std::ostringstream os;
378 os << *prefix <<
"totalNumExports: " << totalNumExports
379 <<
", numInvalidExports: " << numInvalidExports << endl;
380 this->verboseOutputStream () << os.str ();
382 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
383 (numInvalidExports == 0, std::logic_error,
384 "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
385 "PIDs are -1. Please report this bug to the Tpetra developers.");
393 if (numInvalidExports == totalNumExports) {
394 exportGIDs.resize (0);
395 exportLIDs = decltype (exportLIDs) ();
396 exportPIDs.resize (0);
399 size_type numValidExports = 0;
400 for (size_type e = 0; e < totalNumExports; ++e) {
401 if (this->TransferData_->exportPIDs_[e] != -1) {
402 exportGIDs[numValidExports] = exportGIDs[e];
403 exportLIDs[numValidExports] = exportLIDs[e];
404 exportPIDs[numValidExports] = exportPIDs[e];
408 exportGIDs.resize (numValidExports);
409 Kokkos::resize (exportLIDs, numValidExports);
410 exportPIDs.resize (numValidExports);
422 if (this->verbose ()) {
423 std::ostringstream os;
424 os << *prefix <<
"Done!" << std::endl;
425 this->verboseOutputStream () << os.str ();
429 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
431 Export<LocalOrdinal,GlobalOrdinal,Node>::
432 setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
434 using ::Tpetra::Details::view_alloc_no_init;
435 using ::Tpetra::Details::makeDualViewFromOwningHostView;
436 using Teuchos::Array;
438 using LO = LocalOrdinal;
439 using GO = GlobalOrdinal;
441 std::unique_ptr<std::string> prefix;
442 if (this->verbose ()) {
443 auto srcMap = this->getSourceMap ();
444 auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
445 const int myRank = comm.is_null () ? -1 : comm->getRank ();
447 std::ostringstream os;
448 os <<
"Proc " << myRank <<
": Tpetra::Export::setupRemote: ";
449 prefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
451 std::ostringstream os2;
452 os2 << *prefix <<
"Start" << std::endl;
453 this->verboseOutputStream () << os2.str ();
456 TEUCHOS_ASSERT( ! this->getTargetMap ().is_null () );
457 const map_type& tgtMap = * (this->getTargetMap ());
464 TEUCHOS_ASSERT(
size_t (this->TransferData_->exportLIDs_.extent (0)) ==
465 size_t (this->TransferData_->exportPIDs_.size ()) );
466 this->TransferData_->exportLIDs_.modify_host ();
467 auto exportLIDs = this->TransferData_->exportLIDs_.view_host ();
468 sort3 (this->TransferData_->exportPIDs_.begin (),
469 this->TransferData_->exportPIDs_.end (),
470 exportGIDs.getRawPtr (),
472 this->TransferData_->exportLIDs_.sync_device ();
478 if (this->verbose ()) {
479 std::ostringstream os;
480 os << *prefix <<
"Call createFromSends" << endl;
481 this->verboseOutputStream () << os.str ();
490 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
491 Distributor& distributor = this->TransferData_->distributor_;
492 const size_t numRemoteIDs = distributor.createFromSends (exportPIDs ());
494 if (this->verbose ()) {
495 std::ostringstream os;
496 os << *prefix <<
"numRemoteIDs: " << numRemoteIDs
497 <<
"; call doPostsAndWaits" << endl;
498 this->verboseOutputStream () << os.str ();
505 std::unique_ptr<GO[]> remoteGIDs_ptr (
new GlobalOrdinal [numRemoteIDs]);
506 Teuchos::ArrayView<GO> remoteGIDs
507 (numRemoteIDs == 0 ?
nullptr : remoteGIDs_ptr.get (), numRemoteIDs);
508 distributor.doPostsAndWaits (exportGIDs ().getConst (), 1, remoteGIDs);
512 using host_remote_lids_type =
513 typename decltype (this->TransferData_->remoteLIDs_)::t_host;
514 host_remote_lids_type remoteLIDs
515 (view_alloc_no_init (
"remoteLIDs"), numRemoteIDs);
516 for (LO j = 0; j < LO (numRemoteIDs); ++j) {
517 remoteLIDs[j] = tgtMap.getLocalElement (remoteGIDs[j]);
521 if (this->verbose ()) {
522 std::ostringstream os;
523 os << *prefix <<
"Done!" << endl;
524 this->verboseOutputStream () << os.str ();
537 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
538 template class Export< LO , GO , NODE >;
540 #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.