10#ifndef TPETRA_EXPORT_DEF_HPP
11#define TPETRA_EXPORT_DEF_HPP
13#include "Tpetra_Distributor.hpp"
14#include "Tpetra_Map.hpp"
15#include "Tpetra_ImportExportData.hpp"
17#include "Tpetra_Import.hpp"
18#include "Tpetra_Details_DualViewUtil.hpp"
20#include "Teuchos_as.hpp"
21#include "Teuchos_Array.hpp"
22#include "Teuchos_FancyOStream.hpp"
23#include "Teuchos_ParameterList.hpp"
28template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
31 const Teuchos::RCP<const map_type>&
target,
32 const Teuchos::RCP<Teuchos::FancyOStream>&
out,
33 const Teuchos::RCP<Teuchos::ParameterList>&
plist)
37 using ::Tpetra::Details::ProfilingRegion;
41 std::ostringstream
os;
48 if (
source->isDistributed()) {
61 this->detectRemoteExportLIDsContiguous();
64 std::ostringstream
os;
71template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
74 const Teuchos::RCP<const map_type>&
target)
77template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 const Teuchos::RCP<const map_type>&
target,
81 const Teuchos::RCP<Teuchos::FancyOStream>&
out)
84template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 const Teuchos::RCP<const map_type>&
target,
88 const Teuchos::RCP<Teuchos::ParameterList>&
plist)
91template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
96template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
101template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
104 const Teuchos::EVerbosityLevel
verbLevel)
const {
109template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
111 print(std::ostream&
os)
const {
112 auto out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(
os));
114 this->describe(*
out, Teuchos::VERB_EXTREME);
117template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
122 using Teuchos::Array;
123 using Teuchos::ArrayRCP;
124 using Teuchos::ArrayView;
127 using ::Tpetra::Details::makeDualViewFromOwningHostView;
128 using ::Tpetra::Details::ProfilingRegion;
129 using ::Tpetra::Details::view_alloc_no_init;
134 ProfilingRegion
regionExport(
"Tpetra::Export::setupSamePermuteExport");
136 std::unique_ptr<std::string>
prefix;
137 if (this->verbose()) {
138 auto srcMap = this->getSourceMap();
139 auto comm =
srcMap.is_null() ? Teuchos::null :
srcMap->getComm();
140 const int myRank = comm.is_null() ? -1 : comm->getRank();
142 std::ostringstream
os;
143 os <<
"Proc " <<
myRank <<
": Tpetra::Export::setupSamePermuteExport: ";
144 prefix = std::unique_ptr<std::string>(
new std::string(
os.str()));
146 std::ostringstream
os2;
148 this->verboseOutputStream() <<
os2.str();
151 const map_type& source = *(this->getSourceMap());
152 const map_type& target = *(this->getTargetMap());
153 ArrayView<const GO> sourceGIDs = source.getLocalElementList();
154 ArrayView<const GO> targetGIDs = target.getLocalElementList();
156#ifdef HAVE_TPETRA_DEBUG
157 ArrayView<const GO> rawSrcGids = sourceGIDs;
158 ArrayView<const GO> rawTgtGids = targetGIDs;
160 const GO*
const rawSrcGids = sourceGIDs.getRawPtr();
161 const GO*
const rawTgtGids = targetGIDs.getRawPtr();
163 const size_type numSrcGids = sourceGIDs.size();
164 const size_type numTgtGids = targetGIDs.size();
165 const size_type numGids = std::min(numSrcGids, numTgtGids);
173 size_type numSameGids = 0;
174 for (; numSameGids < numGids &&
175 rawSrcGids[numSameGids] == rawTgtGids[numSameGids];
178 this->TransferData_->numSameIDs_ = numSameGids;
180 if (this->verbose()) {
181 std::ostringstream os;
182 os << *prefix <<
"numIDs: " << numGids
183 <<
", numSameIDs: " << numSameGids << endl;
184 this->verboseOutputStream() << os.str();
199 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
200 const LO numSrcLids =
static_cast<LO
>(numSrcGids);
204 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
205 const GO curSrcGid = rawSrcGids[srcLid];
209 const LO tgtLid = target.getLocalElement(curSrcGid);
210 if (tgtLid != LINVALID) {
216 if (this->verbose()) {
217 std::ostringstream os;
218 os << *prefix <<
"numPermutes: " << numPermutes
219 <<
", numExports: " << numExports << endl;
220 this->verboseOutputStream() << os.str();
222 TEUCHOS_ASSERT(numPermutes + numExports ==
223 numSrcLids - numSameGids);
225 typename decltype(this->TransferData_->permuteToLIDs_)::t_host
227 typename decltype(this->TransferData_->permuteToLIDs_)::t_host
229 typename decltype(this->TransferData_->permuteToLIDs_)::t_host
234 exportGIDs.resize(numExports);
239 for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
240 const GO curSrcGid = rawSrcGids[srcLid];
241 const LO tgtLid = target.getLocalElement(curSrcGid);
242 if (tgtLid != LINVALID) {
243 permuteToLIDs[numPermutes2] = tgtLid;
244 permuteFromLIDs[numPermutes2] = srcLid;
247 exportGIDs[numExports2] = curSrcGid;
248 exportLIDs[numExports2] = srcLid;
252 TEUCHOS_ASSERT(numPermutes == numPermutes2);
253 TEUCHOS_ASSERT(numExports == numExports2);
254 TEUCHOS_ASSERT(
size_t(numExports) ==
size_t(exportGIDs.size()));
267 if (numExports != 0 && !source.isDistributed()) {
273 this->TransferData_->isLocallyComplete_ =
false;
274 if (this->verbose()) {
275 std::ostringstream os;
276 os << *prefix <<
"Export is not locally complete" << endl;
277 this->verboseOutputStream() << os.str();
282 "::setupSamePermuteExport(): Source has "
283 "export LIDs but Source is not distributed globally. Exporting to "
284 "a submap of the target map.");
298 if (source.isDistributed()) {
299 if (this->verbose()) {
300 std::ostringstream os;
301 os << *prefix <<
"Source Map is distributed; "
302 "call targetMap.getRemoteiNdexList"
304 this->verboseOutputStream() << os.str();
306 this->TransferData_->exportPIDs_.resize(exportGIDs.size());
311 target.getRemoteIndexList(exportGIDs(),
312 this->TransferData_->exportPIDs_());
316 "::setupSamePermuteExport(): The source Map has GIDs not found "
317 "in the target Map.");
326 this->TransferData_->isLocallyComplete_ =
false;
328 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
330 const size_type totalNumExports = exportPIDs.size();
331 const size_type numInvalidExports =
332 std::count_if(exportPIDs.begin(), exportPIDs.end(),
333 [](
const int procId) { return procId == -1; });
334 if (this->verbose()) {
335 std::ostringstream os;
336 os << *prefix <<
"totalNumExports: " << totalNumExports
337 <<
", numInvalidExports: " << numInvalidExports << endl;
338 this->verboseOutputStream() << os.str();
340 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(numInvalidExports == 0, std::logic_error,
341 "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
342 "PIDs are -1. Please report this bug to the Tpetra developers.");
350 if (numInvalidExports == totalNumExports) {
351 exportGIDs.resize(0);
352 exportLIDs =
decltype(exportLIDs)();
353 exportPIDs.resize(0);
355 size_type numValidExports = 0;
356 for (size_type e = 0; e < totalNumExports; ++e) {
357 if (this->TransferData_->exportPIDs_[e] != -1) {
358 exportGIDs[numValidExports] = exportGIDs[e];
359 exportLIDs[numValidExports] = exportLIDs[e];
360 exportPIDs[numValidExports] = exportPIDs[e];
364 exportGIDs.resize(numValidExports);
365 Kokkos::resize(exportLIDs, numValidExports);
366 exportPIDs.resize(numValidExports);
378 if (this->verbose()) {
379 std::ostringstream os;
380 os << *prefix <<
"Done!" << std::endl;
381 this->verboseOutputStream() << os.str();
385template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
386void Export<LocalOrdinal, GlobalOrdinal, Node>::
387 setupRemote(Teuchos::Array<GlobalOrdinal>& exportGIDs) {
389 using Teuchos::Array;
390 using ::Tpetra::Details::makeDualViewFromOwningHostView;
391 using ::Tpetra::Details::view_alloc_no_init;
392 using LO = LocalOrdinal;
393 using GO = GlobalOrdinal;
395 std::unique_ptr<std::string> prefix;
396 if (this->verbose()) {
397 auto srcMap = this->getSourceMap();
398 auto comm = srcMap.is_null() ? Teuchos::null : srcMap->getComm();
399 const int myRank = comm.is_null() ? -1 : comm->getRank();
401 std::ostringstream os;
402 os <<
"Proc " << myRank <<
": Tpetra::Export::setupRemote: ";
403 prefix = std::unique_ptr<std::string>(
new std::string(os.str()));
405 std::ostringstream os2;
406 os2 << *prefix <<
"Start" << std::endl;
407 this->verboseOutputStream() << os2.str();
410 TEUCHOS_ASSERT(!this->getTargetMap().is_null());
411 const map_type& tgtMap = *(this->getTargetMap());
418 TEUCHOS_ASSERT(
size_t(this->TransferData_->exportLIDs_.extent(0)) ==
419 size_t(this->TransferData_->exportPIDs_.size()));
420 this->TransferData_->exportLIDs_.modify_host();
421 auto exportLIDs = this->TransferData_->exportLIDs_.view_host();
422 sort3(this->TransferData_->exportPIDs_.begin(),
423 this->TransferData_->exportPIDs_.end(),
424 exportGIDs.getRawPtr(),
426 this->TransferData_->exportLIDs_.sync_device();
432 if (this->verbose()) {
433 std::ostringstream os;
434 os << *prefix <<
"Call createFromSends" << endl;
435 this->verboseOutputStream() << os.str();
444 Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
445 Distributor& distributor = this->TransferData_->distributor_;
446 const size_t numRemoteIDs = distributor.createFromSends(exportPIDs());
448 if (this->verbose()) {
449 std::ostringstream os;
450 os << *prefix <<
"numRemoteIDs: " << numRemoteIDs
451 <<
"; call doPostsAndWaits" << endl;
452 this->verboseOutputStream() << os.str();
459 Kokkos::View<const GO*, Kokkos::HostSpace> exportGIDsConst(exportGIDs.data(), exportGIDs.size());
460 Kokkos::View<GO*, Kokkos::HostSpace> remoteGIDs(
"remoteGIDs", numRemoteIDs);
461 distributor.doPostsAndWaits(exportGIDsConst, 1, remoteGIDs);
465 using host_remote_lids_type =
466 typename decltype(this->TransferData_->remoteLIDs_)::t_host;
469 for (LO j = 0; j < LO(numRemoteIDs); ++j) {
470 remoteLIDs[j] = tgtMap.getLocalElement(remoteGIDs[j]);
474 if (this->verbose()) {
475 std::ostringstream os;
476 os << *prefix <<
"Done!" << endl;
477 this->verboseOutputStream() << os.str();
490#define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
491 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...
Struct that holds views of the contents of a CrsMatrix.
bool verbose() const
Whether to print verbose debugging output.
Teuchos::RCP< ImportExportData< LocalOrdinal, GlobalOrdinal, Node > > TransferData_
All the data needed for executing the Export communication plan.
Teuchos::FancyOStream & verboseOutputStream() const
Valid (nonnull) output stream for verbose output.
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.
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.