10 #ifndef TPETRA_EXPORT_DEF_HPP
11 #define TPETRA_EXPORT_DEF_HPP
14 #include "Tpetra_Distributor.hpp"
15 #include "Tpetra_Map.hpp"
16 #include "Tpetra_ImportExportData.hpp"
18 #include "Tpetra_Import.hpp"
19 #include "Tpetra_Details_DualViewUtil.hpp"
21 #include "Teuchos_as.hpp"
22 #include "Teuchos_Array.hpp"
23 #include "Teuchos_FancyOStream.hpp"
24 #include "Teuchos_ParameterList.hpp"
29 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
31 Export (
const Teuchos::RCP<const map_type >& source,
32 const Teuchos::RCP<const map_type >& target,
33 const Teuchos::RCP<Teuchos::FancyOStream>& out,
34 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
35 base_type (source, target, out, plist,
"Export")
39 using ::Tpetra::Details::ProfilingRegion;
40 ProfilingRegion regionExport (
"Tpetra::Export::Export");
43 std::ostringstream os;
44 const int myRank = source->getComm ()->getRank ();
45 os << myRank <<
": Export ctor" << endl;
48 Teuchos::Array<GlobalOrdinal> exportGIDs;
49 setupSamePermuteExport (exportGIDs);
50 if (source->isDistributed ()) {
51 setupRemote (exportGIDs);
54 TEUCHOS_ASSERT( ! this->
TransferData_->permuteFromLIDs_.need_sync_device () );
55 TEUCHOS_ASSERT( ! this->
TransferData_->permuteFromLIDs_.need_sync_host () );
56 TEUCHOS_ASSERT( ! this->
TransferData_->permuteToLIDs_.need_sync_device () );
57 TEUCHOS_ASSERT( ! this->
TransferData_->permuteToLIDs_.need_sync_host () );
58 TEUCHOS_ASSERT( ! this->
TransferData_->remoteLIDs_.need_sync_device () );
59 TEUCHOS_ASSERT( ! this->
TransferData_->remoteLIDs_.need_sync_host () );
60 TEUCHOS_ASSERT( ! this->
TransferData_->exportLIDs_.need_sync_device () );
61 TEUCHOS_ASSERT( ! this->
TransferData_->exportLIDs_.need_sync_host () );
63 this->detectRemoteExportLIDsContiguous();
66 std::ostringstream os;
67 const int myRank = source->getComm ()->getRank ();
68 os << myRank <<
": Export ctor: done" << endl;
73 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
75 Export (
const Teuchos::RCP<const map_type>& source,
76 const Teuchos::RCP<const map_type>& target) :
77 Export (source, target, Teuchos::null, Teuchos::null)
80 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 Export (
const Teuchos::RCP<const map_type >& source,
83 const Teuchos::RCP<const map_type >& target,
84 const Teuchos::RCP<Teuchos::FancyOStream>& out) :
85 Export (source, target, out, Teuchos::null)
88 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
90 Export (
const Teuchos::RCP<const map_type >& source,
91 const Teuchos::RCP<const map_type >& target,
92 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
93 Export (source, target, Teuchos::null, plist)
96 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
108 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
112 const Teuchos::EVerbosityLevel verbLevel)
const
115 this->describeImpl (out,
"Tpetra::Export", verbLevel);
118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
122 auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
124 this->describe (*out, Teuchos::VERB_EXTREME);
127 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
132 using ::Tpetra::Details::makeDualViewFromOwningHostView;
133 using ::Tpetra::Details::ProfilingRegion;
134 using ::Tpetra::Details::view_alloc_no_init;
136 using Teuchos::Array;
137 using Teuchos::ArrayRCP;
138 using Teuchos::ArrayView;
142 using LO = LocalOrdinal;
143 using GO = GlobalOrdinal;
144 using size_type =
typename ArrayView<const GO>::size_type;
145 const char tfecfFuncName[] =
"setupSamePermuteExport: ";
146 ProfilingRegion regionExport (
"Tpetra::Export::setupSamePermuteExport");
148 std::unique_ptr<std::string> prefix;
149 if (this->verbose ()) {
150 auto srcMap = this->getSourceMap ();
151 auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
152 const int myRank = comm.is_null () ? -1 : comm->getRank ();
154 std::ostringstream os;
155 os <<
"Proc " << myRank <<
": Tpetra::Export::setupSamePermuteExport: ";
156 prefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
158 std::ostringstream os2;
159 os2 << *prefix <<
"Start" << std::endl;
160 this->verboseOutputStream () << os2.str ();
163 const map_type& source = * (this->getSourceMap ());
164 const map_type& target = * (this->getTargetMap ());
165 ArrayView<const GO> sourceGIDs = source.getLocalElementList ();
166 ArrayView<const GO> targetGIDs = target.getLocalElementList ();
168 #ifdef HAVE_TPETRA_DEBUG
169 ArrayView<const GO> rawSrcGids = sourceGIDs;
170 ArrayView<const GO> rawTgtGids = targetGIDs;
172 const GO*
const rawSrcGids = sourceGIDs.getRawPtr ();
173 const GO*
const rawTgtGids = targetGIDs.getRawPtr ();
174 #endif // HAVE_TPETRA_DEBUG
175 const size_type numSrcGids = sourceGIDs.size ();
176 const size_type numTgtGids = targetGIDs.size ();
177 const size_type numGids = std::min (numSrcGids, numTgtGids);
185 size_type numSameGids = 0;
186 for ( ; numSameGids < numGids &&
187 rawSrcGids[numSameGids] == rawTgtGids[numSameGids];
190 this->TransferData_->numSameIDs_ = numSameGids;
192 if (this->verbose ()) {
193 std::ostringstream os;
194 os << *prefix <<
"numIDs: " << numGids
195 <<
", numSameIDs: " << numSameGids << endl;
196 this->verboseOutputStream () << os.str ();
211 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
212 const LO numSrcLids =
static_cast<LO
> (numSrcGids);
216 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
217 const GO curSrcGid = rawSrcGids[srcLid];
221 const LO tgtLid = target.getLocalElement (curSrcGid);
222 if (tgtLid != LINVALID) {
229 if (this->verbose ()) {
230 std::ostringstream os;
231 os << *prefix <<
"numPermutes: " << numPermutes
232 <<
", numExports: " << numExports << endl;
233 this->verboseOutputStream () << os.str ();
235 TEUCHOS_ASSERT( numPermutes + numExports ==
236 numSrcLids - numSameGids );
238 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
240 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
242 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
247 exportGIDs.resize (numExports);
252 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
253 const GO curSrcGid = rawSrcGids[srcLid];
254 const LO tgtLid = target.getLocalElement (curSrcGid);
255 if (tgtLid != LINVALID) {
256 permuteToLIDs[numPermutes2] = tgtLid;
257 permuteFromLIDs[numPermutes2] = srcLid;
261 exportGIDs[numExports2] = curSrcGid;
262 exportLIDs[numExports2] = srcLid;
266 TEUCHOS_ASSERT( numPermutes == numPermutes2 );
267 TEUCHOS_ASSERT( numExports == numExports2 );
268 TEUCHOS_ASSERT(
size_t (numExports) ==
size_t (exportGIDs.size ()) );
281 if (numExports != 0 && ! source.isDistributed ()) {
287 this->TransferData_->isLocallyComplete_ =
false;
288 if (this->verbose ()) {
289 std::ostringstream os;
290 os << *prefix <<
"Export is not locally complete" << endl;
291 this->verboseOutputStream () << os.str ();
296 (
true, std::runtime_error,
"::setupSamePermuteExport(): Source has "
297 "export LIDs but Source is not distributed globally. Exporting to "
298 "a submap of the target map.");
312 if (source.isDistributed ()) {
313 if (this->verbose ()) {
314 std::ostringstream os;
315 os << *prefix <<
"Source Map is distributed; "
316 "call targetMap.getRemoteiNdexList" << endl;
317 this->verboseOutputStream () << os.str ();
319 this->TransferData_->exportPIDs_.resize(exportGIDs.size ());
324 target.getRemoteIndexList (exportGIDs(),
325 this->TransferData_->exportPIDs_ ());
329 "::setupSamePermuteExport(): The source Map has GIDs not found "
330 "in the target Map.");
339 this->TransferData_->isLocallyComplete_ =
false;
341 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
343 const size_type totalNumExports = exportPIDs.size ();
344 const size_type numInvalidExports =
345 std::count_if (exportPIDs.begin (), exportPIDs.end (),
346 [] (
const int procId) {
return procId == -1; });
347 if (this->verbose ()) {
348 std::ostringstream os;
349 os << *prefix <<
"totalNumExports: " << totalNumExports
350 <<
", numInvalidExports: " << numInvalidExports << endl;
351 this->verboseOutputStream () << os.str ();
353 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
354 (numInvalidExports == 0, std::logic_error,
355 "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
356 "PIDs are -1. Please report this bug to the Tpetra developers.");
364 if (numInvalidExports == totalNumExports) {
365 exportGIDs.resize (0);
366 exportLIDs = decltype (exportLIDs) ();
367 exportPIDs.resize (0);
370 size_type numValidExports = 0;
371 for (size_type e = 0; e < totalNumExports; ++e) {
372 if (this->TransferData_->exportPIDs_[e] != -1) {
373 exportGIDs[numValidExports] = exportGIDs[e];
374 exportLIDs[numValidExports] = exportLIDs[e];
375 exportPIDs[numValidExports] = exportPIDs[e];
379 exportGIDs.resize (numValidExports);
380 Kokkos::resize (exportLIDs, numValidExports);
381 exportPIDs.resize (numValidExports);
393 if (this->verbose ()) {
394 std::ostringstream os;
395 os << *prefix <<
"Done!" << std::endl;
396 this->verboseOutputStream () << os.str ();
400 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
402 Export<LocalOrdinal,GlobalOrdinal,Node>::
403 setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
405 using ::Tpetra::Details::view_alloc_no_init;
406 using ::Tpetra::Details::makeDualViewFromOwningHostView;
407 using Teuchos::Array;
409 using LO = LocalOrdinal;
410 using GO = GlobalOrdinal;
412 std::unique_ptr<std::string> prefix;
413 if (this->verbose ()) {
414 auto srcMap = this->getSourceMap ();
415 auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
416 const int myRank = comm.is_null () ? -1 : comm->getRank ();
418 std::ostringstream os;
419 os <<
"Proc " << myRank <<
": Tpetra::Export::setupRemote: ";
420 prefix = std::unique_ptr<std::string> (
new std::string (os.str ()));
422 std::ostringstream os2;
423 os2 << *prefix <<
"Start" << std::endl;
424 this->verboseOutputStream () << os2.str ();
427 TEUCHOS_ASSERT( ! this->getTargetMap ().is_null () );
428 const map_type& tgtMap = * (this->getTargetMap ());
435 TEUCHOS_ASSERT(
size_t (this->TransferData_->exportLIDs_.extent (0)) ==
436 size_t (this->TransferData_->exportPIDs_.size ()) );
437 this->TransferData_->exportLIDs_.modify_host ();
438 auto exportLIDs = this->TransferData_->exportLIDs_.view_host ();
439 sort3 (this->TransferData_->exportPIDs_.begin (),
440 this->TransferData_->exportPIDs_.end (),
441 exportGIDs.getRawPtr (),
443 this->TransferData_->exportLIDs_.sync_device ();
449 if (this->verbose ()) {
450 std::ostringstream os;
451 os << *prefix <<
"Call createFromSends" << endl;
452 this->verboseOutputStream () << os.str ();
461 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
462 Distributor& distributor = this->TransferData_->distributor_;
463 const size_t numRemoteIDs = distributor.createFromSends (exportPIDs ());
465 if (this->verbose ()) {
466 std::ostringstream os;
467 os << *prefix <<
"numRemoteIDs: " << numRemoteIDs
468 <<
"; call doPostsAndWaits" << endl;
469 this->verboseOutputStream () << os.str ();
476 Kokkos::View<const GO*, Kokkos::HostSpace> exportGIDsConst(exportGIDs.data(), exportGIDs.size());
477 Kokkos::View<GO*, Kokkos::HostSpace> remoteGIDs(
"remoteGIDs", numRemoteIDs);
478 distributor.doPostsAndWaits(exportGIDsConst, 1, remoteGIDs);
482 using host_remote_lids_type =
483 typename decltype (this->TransferData_->remoteLIDs_)::t_host;
484 host_remote_lids_type remoteLIDs
485 (view_alloc_no_init (
"remoteLIDs"), numRemoteIDs);
487 for (LO j = 0; j < LO (numRemoteIDs); ++j) {
488 remoteLIDs[j] = tgtMap.getLocalElement (remoteGIDs[j]);
492 if (this->verbose ()) {
493 std::ostringstream os;
494 os << *prefix <<
"Done!" << endl;
495 this->verboseOutputStream () << os.str ();
508 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
509 template class Export< LO , GO , NODE >;
511 #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.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3, const bool stableSort=false)
Sort the first array, and apply the same permutation to the second and third arrays.
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.