10 #ifndef TPETRA_DETAILS_TRANSFER_DEF_HPP
11 #define TPETRA_DETAILS_TRANSFER_DEF_HPP
14 #include "Tpetra_Distributor.hpp"
15 #include "Tpetra_ImportExportData.hpp"
16 #include "Tpetra_Map.hpp"
17 #include "Teuchos_CommHelpers.hpp"
18 #include "Teuchos_TypeNameTraits.hpp"
24 template <
class ElementType,
class DeviceType>
25 Teuchos::ArrayView<const ElementType>
26 makeConstArrayViewFromDualView(
const Kokkos::DualView<ElementType*, DeviceType>& dv) {
27 TEUCHOS_ASSERT(!dv.need_sync_host());
28 auto hostView = dv.view_host();
29 const auto size = hostView.extent(0);
30 return Teuchos::ArrayView<const ElementType>(size == 0 ?
nullptr : hostView.data(), size);
33 template <
class DeviceType,
class LocalOrdinal>
34 struct OrderedViewFunctor {
35 OrderedViewFunctor(
const Kokkos::View<LocalOrdinal*, DeviceType>& viewToCheck)
36 : viewToCheck_(viewToCheck) {}
37 KOKKOS_INLINE_FUNCTION
void operator()(
const size_t i,
unsigned int& isUnordered)
const {
38 isUnordered |=
static_cast<unsigned int>(viewToCheck_(i) + 1 != viewToCheck_(i + 1));
40 Kokkos::View<const LocalOrdinal*, DeviceType> viewToCheck_;
43 template <
class DeviceType,
class LocalOrdinal>
44 bool isViewOrdered(
const Kokkos::View<LocalOrdinal*, DeviceType>& viewToCheck) {
45 using Kokkos::parallel_reduce;
46 typedef DeviceType DT;
47 typedef typename DT::execution_space DES;
48 typedef Kokkos::RangePolicy<DES, size_t> range_type;
50 const size_t size = viewToCheck.extent(0);
51 unsigned int isUnordered = 0;
53 parallel_reduce(
"isViewOrdered",
54 range_type(0, size - 1),
55 OrderedViewFunctor<DeviceType, LocalOrdinal>(viewToCheck),
57 return isUnordered == 0;
65 template <
class LO,
class GO,
class NT>
66 Transfer<LO, GO, NT>::
67 Transfer(
const Teuchos::RCP<const map_type>& source,
68 const Teuchos::RCP<const map_type>& target,
69 const Teuchos::RCP<Teuchos::FancyOStream>& out,
70 const Teuchos::RCP<Teuchos::ParameterList>& plist,
71 const std::string& className)
72 : TransferData_(new
ImportExportData<LO, GO, NT>(source, target, out, plist)) {
74 this->setParameterList(plist, className);
77 template <
class LO,
class GO,
class NT>
82 TEUCHOS_ASSERT(!this->TransferData_->out_.is_null());
85 template <
class LO,
class GO,
class NT>
88 const std::string& className) {
89 using ::Tpetra::Details::Behavior;
94 bool verboseParam =
false;
95 if (!plist.is_null()) {
98 if (plist->isType<
bool>(
"Verbose")) {
99 verboseParam = plist->get<
bool>(
"Verbose");
100 }
else if (plist->isType<
bool>(
"Debug")) {
101 verboseParam = plist->get<
bool>(
"Debug");
104 this->TransferData_->verbose_ = verboseEnv || verboseParam;
107 template <
class LO,
class GO,
class NT>
111 return TransferData_->numSameIDs_;
114 template <
class LO,
class GO,
class NT>
118 return static_cast<size_t>(TransferData_->permuteFromLIDs_.extent(0));
121 template <
class LO,
class GO,
class NT>
122 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
125 const auto& dv = TransferData_->permuteFromLIDs_;
126 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
127 "Tpetra::Details::Transfer::getPermuteFromLIDs_dv: "
128 "DualView needs sync to device");
129 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_host(), std::logic_error,
130 "Tpetra::Details::Transfer::getPermuteFromLIDs_dv: "
131 "DualView needs sync to host");
135 template <
class LO,
class GO,
class NT>
136 Teuchos::ArrayView<const LO>
139 return makeConstArrayViewFromDualView(TransferData_->permuteFromLIDs_);
142 template <
class LO,
class GO,
class NT>
143 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
146 const auto& dv = TransferData_->permuteToLIDs_;
147 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
148 "Tpetra::Details::Transfer::getPermuteToLIDs_dv: "
149 "DualView needs sync to device");
150 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_host(), std::logic_error,
151 "Tpetra::Details::Transfer::getPermuteToLIDs_dv: "
152 "DualView needs sync to host");
156 template <
class LO,
class GO,
class NT>
157 Teuchos::ArrayView<const LO>
160 return makeConstArrayViewFromDualView(TransferData_->permuteToLIDs_);
163 template <
class LO,
class GO,
class NT>
167 return static_cast<size_t>(TransferData_->remoteLIDs_.extent(0));
170 template <
class LO,
class GO,
class NT>
171 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
174 const auto& dv = TransferData_->remoteLIDs_;
175 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
176 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
177 "DualView needs sync to device");
178 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_host(), std::logic_error,
179 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
180 "DualView needs sync to host");
184 template <
class LO,
class GO,
class NT>
185 Teuchos::ArrayView<const LO>
188 return makeConstArrayViewFromDualView(TransferData_->remoteLIDs_);
191 template <
class LO,
class GO,
class NT>
195 return static_cast<size_t>(TransferData_->exportLIDs_.extent(0));
198 template <
class LO,
class GO,
class NT>
199 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
202 const auto& dv = TransferData_->exportLIDs_;
203 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
204 "Tpetra::Details::Transfer::getExportLIDs_dv: "
205 "DualView needs sync to device");
206 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_host(), std::logic_error,
207 "Tpetra::Details::Transfer::getExportLIDs_dv: "
208 "DualView needs sync to host");
212 template <
class LO,
class GO,
class NT>
213 Teuchos::ArrayView<const LO>
216 return makeConstArrayViewFromDualView(TransferData_->exportLIDs_);
219 template <
class LO,
class GO,
class NT>
220 Teuchos::ArrayView<const int>
223 return TransferData_->exportPIDs_();
226 template <
class LO,
class GO,
class NT>
227 Teuchos::RCP<const typename Transfer<LO, GO, NT>::map_type>
230 return TransferData_->source_;
233 template <
class LO,
class GO,
class NT>
234 Teuchos::RCP<const typename Transfer<LO, GO, NT>::map_type>
237 return TransferData_->target_;
240 template <
class LO,
class GO,
class NT>
244 return TransferData_->distributor_;
247 template <
class LO,
class GO,
class NT>
250 return TransferData_->isLocallyComplete_;
253 template <
class LO,
class GO,
class NT>
256 return (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
257 getTargetMap()->getLocalNumElements()));
260 template <
class LO,
class GO,
class NT>
266 bool ordered = (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
267 getTargetMap()->getLocalNumElements()));
268 ordered &= (getTargetMap()->getLocalNumElements() == getNumSameIDs() + getNumRemoteIDs());
270 const auto& dv = TransferData_->remoteLIDs_;
271 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
272 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
273 "DualView needs sync to device");
274 auto v_d = dv.view_device();
275 ordered &= isViewOrdered<device_type, LO>(v_d);
277 TransferData_->remoteLIDsContiguous_ = ordered;
279 ordered = (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
280 getTargetMap()->getLocalNumElements()));
281 ordered &= (getSourceMap()->getLocalNumElements() == getNumSameIDs() + getNumExportIDs());
283 const auto& dv = TransferData_->exportLIDs_;
284 TEUCHOS_TEST_FOR_EXCEPTION(dv.need_sync_device(), std::logic_error,
285 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
286 "DualView needs sync to device");
287 auto v_d = dv.view_device();
288 ordered &= isViewOrdered<device_type, LO>(v_d);
290 TransferData_->exportLIDsContiguous_ = ordered;
293 template <
class LO,
class GO,
class NT>
294 bool Transfer<LO, GO, NT>::
295 areRemoteLIDsContiguous()
const {
296 return TransferData_->remoteLIDsContiguous_;
299 template <
class LO,
class GO,
class NT>
300 bool Transfer<LO, GO, NT>::
301 areExportLIDsContiguous()
const {
302 return TransferData_->exportLIDsContiguous_;
305 template <
class LO,
class GO,
class NT>
308 const Teuchos::EVerbosityLevel verbLevel)
const {
309 this->describeImpl(out,
"Tpetra::Details::Transfer", verbLevel);
312 template <
class LO,
class GO,
class NT>
313 Teuchos::FancyOStream&
316 Teuchos::FancyOStream* outPtr = TransferData_->out_.getRawPtr();
317 TEUCHOS_ASSERT(outPtr !=
nullptr);
321 template <
class LO,
class GO,
class NT>
324 return TransferData_->verbose_;
327 template <
class LO,
class GO,
class NT>
330 const std::string& className,
331 const Teuchos::EVerbosityLevel verbLevel)
const {
333 using Teuchos::TypeNameTraits;
334 using Teuchos::VERB_DEFAULT;
335 using Teuchos::VERB_LOW;
336 using Teuchos::VERB_NONE;
337 const Teuchos::EVerbosityLevel vl =
338 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
340 if (vl == VERB_NONE) {
347 auto srcMap = this->getSourceMap();
348 if (srcMap.is_null()) {
351 auto comm = srcMap->getComm();
352 if (comm.is_null()) {
355 if (this->getTargetMap().is_null() ||
356 this->getTargetMap()->getComm().is_null()) {
360 const int myRank = comm->getRank();
361 const int numProcs = comm->getSize();
368 Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
374 tab0 = Teuchos::rcp(
new Teuchos::OSTab(out));
376 out <<
"\"" << className <<
"\":" << endl;
377 tab1 = Teuchos::rcp(
new Teuchos::OSTab(out));
380 out <<
"Template parameters:" << endl;
381 Teuchos::OSTab tab2(out);
382 out <<
"LocalOrdinal: " << TypeNameTraits<LO>::name() << endl
383 <<
"GlobalOrdinal: " << TypeNameTraits<GO>::name() << endl
384 <<
"Node: " << TypeNameTraits<NT>::name() << endl;
387 const std::string label = this->getObjectLabel();
389 out <<
"Label: " << label << endl;
391 out <<
"Number of processes: " << numProcs << endl;
398 this->globalDescribe(out, vl);
410 out <<
"Source Map:" << endl;
413 this->getSourceMap()->describe(out, vl);
416 out <<
"Target Map:" << endl;
419 this->getTargetMap()->describe(out, vl);
422 out <<
"Distributor:" << endl;
424 this->getDistributor().describe(out, vl);
427 template <
class LO,
class GO,
class NT>
430 const Teuchos::EVerbosityLevel vl)
const {
433 using Teuchos::OSTab;
435 using Teuchos::toString;
441 auto srcMap = this->getSourceMap();
442 if (srcMap.is_null()) {
445 RCP<const Teuchos::Comm<int> > comm = srcMap->getComm();
446 if (comm.is_null()) {
450 const std::string myStr = localDescribeToString(vl);
451 ::Tpetra::Details::gathervPrint(out, myStr, *comm);
454 template <
class LO,
class GO,
class NT>
456 Transfer<LO, GO, NT>::
457 localDescribeToString(
const Teuchos::EVerbosityLevel vl)
const {
459 using Teuchos::OSTab;
462 RCP<std::ostringstream> outString(
new std::ostringstream);
463 RCP<Teuchos::FancyOStream> outp = Teuchos::getFancyOStream(outString);
464 Teuchos::FancyOStream& out = *outp;
466 RCP<const Teuchos::Comm<int> > comm = this->getSourceMap()->getComm();
467 if (this->getSourceMap().is_null() ||
468 this->getSourceMap()->getComm().is_null()) {
473 return std::string(
"");
475 const int myRank = comm->getRank();
476 const int numProcs = comm->getSize();
478 out <<
"Process " << myRank <<
" of " << numProcs <<
":" << endl;
481 out <<
"numSameIDs: " << getNumSameIDs() << endl;
482 out <<
"numPermuteIDs: " << getNumPermuteIDs() << endl;
483 out <<
"numRemoteIDs: " << getNumRemoteIDs() << endl;
484 out <<
"numExportIDs: " << getNumExportIDs() << endl;
488 if (vl <= Teuchos::VERB_MEDIUM) {
489 out <<
"permuteFromLIDs count: " << getPermuteFromLIDs().size() << endl
490 <<
"permuteToLIDs count: " << getPermuteToLIDs().size() << endl
491 <<
"remoteLIDs count: " << getRemoteLIDs().size() << endl
492 <<
"exportLIDs count: " << getExportLIDs().size() << endl
493 <<
"exportPIDs count: " << getExportPIDs() << endl;
496 RCP<const Map<LO, GO, NT> > tmap = getTargetMap();
497 RCP<const Map<LO, GO, NT> > smap = getSourceMap();
498 Teuchos::Array<GO> RemoteGIDs(getRemoteLIDs().size());
499 Teuchos::Array<int> RemotePIDs(getRemoteLIDs().size());
500 for (
size_t i = 0; i < (size_t)getRemoteLIDs().size(); i++)
501 RemoteGIDs[i] = tmap->getGlobalElement(getRemoteLIDs()[i]);
503 Teuchos::Array<int> ExportGIDs(getExportLIDs().size());
504 for (
size_t i = 0; i < (size_t)getExportLIDs().size(); i++)
505 ExportGIDs[i] = smap->getGlobalElement(getExportLIDs()[i]);
510 Teuchos::ArrayView<const int> ProcsFrom = D.
getProcsFrom();
511 Teuchos::ArrayView<const size_t> LengthsFrom = D.
getLengthsFrom();
512 for (
size_t i = 0, j = 0; i < NumReceives; ++i) {
513 const int pid = ProcsFrom[i];
514 for (
size_t k = 0; k < LengthsFrom[i]; ++k) {
520 out <<
"distor.NumRecvs : " << NumReceives << endl
521 <<
"distor.ProcsFrom : " << toString(ProcsFrom) << endl
522 <<
"distor.LengthsFrom: " << toString(LengthsFrom) << endl;
524 out <<
"distor.NumSends : " << D.
getNumSends() << endl
525 <<
"distor.ProcsTo : " << toString(D.
getProcsTo()) << endl
526 <<
"distor.LengthsTo : " << toString(D.
getLengthsTo()) << endl;
530 out <<
"permuteFromLIDs: " << toString(getPermuteFromLIDs()) << endl
531 <<
"permuteToLIDs: " << toString(getPermuteToLIDs()) << endl
532 <<
"remoteLIDs: " << toString(getRemoteLIDs()) << endl
533 <<
"remoteGIDs: " << toString(RemoteGIDs()) << endl
534 <<
"remotePIDs: " << toString(RemotePIDs()) << endl
535 <<
"exportLIDs: " << toString(getExportLIDs()) << endl
536 <<
"exportGIDs: " << toString(ExportGIDs()) << endl
537 <<
"exportPIDs: " << toString(getExportPIDs()) << endl;
541 return outString->str();
545 template <
class LO,
class GO,
class NT>
546 void expertSetRemoteLIDsContiguous(Transfer<LO, GO, NT> transfer,
bool contig) {
547 transfer.TransferData_->remoteLIDsContiguous_ = contig;
550 template <
class LO,
class GO,
class NT>
551 void expertSetExportLIDsContiguous(Transfer<LO, GO, NT> transfer,
bool contig) {
552 transfer.TransferData_->exportLIDsContiguous_ = contig;
558 #endif // TPETRA_DETAILS_TRANSFER_DEF_HPP
Kokkos::DualView< const LO *, device_type > getRemoteLIDs_dv() const
List of entries in the target Map to receive from other processes, as a const DualView (that is sync'...
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of describe() for subclasses (Tpetra::Import and Tpetra::Export).
Common base class of Import and Export.
size_t getNumReceives() const
The number of processes from which we will receive data.
Teuchos::FancyOStream & verboseOutputStream() const
Valid (nonnull) output stream for verbose output.
bool isLocallyFitted() const
Are source and target map locally fitted?
Declaration of a function that prints strings from each process.
Teuchos::ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent.
Teuchos::ArrayView< const LO > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
Teuchos::RCP< const map_type > getTargetMap() const
The target Map used to construct this Export or Import.
size_t getNumSameIDs() const
Number of initial identical IDs.
Teuchos::ArrayView< const size_t > getLengthsFrom() const
Number of values this process will receive from each process.
Teuchos::ArrayView< const int > getProcsFrom() const
Ranks of the processes sending values to this process.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
Kokkos::DualView< const LO *, device_type > getPermuteFromLIDs_dv() const
List of local IDs in the source Map that are permuted, as a const DualView (that is sync'd to both ho...
Teuchos::ArrayView< const LO > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
Teuchos::ArrayView< const int > getProcsTo() const
Ranks of the processes to which this process will send values.
Kokkos::DualView< const LO *, device_type > getPermuteToLIDs_dv() const
List of local IDs in the target Map that are permuted, as a const DualView (that is sync'd to both ho...
size_t getNumPermuteIDs() const
Number of IDs to permute but not to communicate.
bool hasSelfMessage() const
Whether the calling process will send or receive messages to itself.
Implementation detail of Import and Export.
Sets up and executes a communication plan for a Tpetra DistObject.
static bool verbose()
Whether Tpetra is in verbose mode.
Teuchos::RCP< ImportExportData< LO, GO, NT > > TransferData_
All the data needed for executing the Export communication plan.
Kokkos::DualView< const LO *, device_type > getExportLIDs_dv() const
List of entries in the source Map that will be sent to other processes, as a const DualView (that is ...
Teuchos::RCP< const map_type > getSourceMap() const
The source Map used to construct this Export or Import.
size_t getNumExportIDs() const
Number of entries that must be sent by the calling process to other processes.
bool isLocallyComplete() const
Is this Export or Import locally complete?
Teuchos::ArrayView< const size_t > getLengthsTo() const
Number of values this process will send to each process.
Teuchos::ArrayView< const LO > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Teuchos::ArrayView< const LO > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
::Tpetra::Distributor & getDistributor() const
The Distributor that this Export or Import object uses to move data.
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.
size_t getNumSends() const
The number of processes to which we will send data.
bool verbose() const
Whether to print verbose debugging output.