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")
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>
105 base_type (importer, typename base_type::reverse_tag ())
108 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
111 describe (Teuchos::FancyOStream& out,
112 const Teuchos::EVerbosityLevel verbLevel)
const
118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
120 print (std::ostream& os)
const
122 auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
124 this->
describe (*out, Teuchos::VERB_EXTREME);
127 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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 ();
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
239 permuteToLIDs (view_alloc_no_init (
"permuteToLIDs"), numPermutes);
240 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
241 permuteFromLIDs (view_alloc_no_init (
"permuteFromLIDs"), numPermutes);
242 typename decltype (this->TransferData_->permuteToLIDs_)::t_host
243 exportLIDs (view_alloc_no_init (
"exportLIDs"), numExports);
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>
403 setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
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 >;
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
Stand-alone utility functions and macros.
#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_
Teuchos::FancyOStream & verboseOutputStream() const
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Sets up and executes a communication plan for a Tpetra DistObject.
size_t createFromSends(const Teuchos::ArrayView< const int > &exportProcIDs)
Set up Distributor using list of process ranks to which this process will send.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
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.
virtual void print(std::ostream &os) const
Print the Export's data 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.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
auto view_alloc_no_init(const std::string &label) -> decltype(Kokkos::view_alloc(label, Kokkos::WithoutInitializing))
Use in place of the string label as the first argument of Kokkos::View's constructor,...
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.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
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.