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)
28 TEUCHOS_ASSERT( ! dv.need_sync_host () );
29 auto hostView = dv.view_host ();
30 const auto size = hostView.extent (0);
31 return Teuchos::ArrayView<const ElementType> (size == 0 ?
nullptr : hostView.data (), size);
34 template<
class DeviceType,
class LocalOrdinal>
35 struct OrderedViewFunctor {
36 OrderedViewFunctor (
const Kokkos::View<LocalOrdinal*, DeviceType>& viewToCheck) :
37 viewToCheck_ (viewToCheck) {}
38 KOKKOS_INLINE_FUNCTION
void operator() (
const size_t i,
unsigned int& isUnordered)
const {
39 isUnordered |=
static_cast<unsigned int>(viewToCheck_(i)+1 != viewToCheck_(i+1));
41 Kokkos::View<const LocalOrdinal*, DeviceType> viewToCheck_;
44 template<
class DeviceType,
class LocalOrdinal>
46 isViewOrdered (
const Kokkos::View<LocalOrdinal*, DeviceType>& viewToCheck)
48 using Kokkos::parallel_reduce;
49 typedef DeviceType DT;
50 typedef typename DT::execution_space DES;
51 typedef Kokkos::RangePolicy<DES, size_t> range_type;
53 const size_t size = viewToCheck.extent (0);
54 unsigned int isUnordered = 0;
56 parallel_reduce (
"isViewOrdered",
57 range_type (0, size-1),
58 OrderedViewFunctor<DeviceType, LocalOrdinal> (viewToCheck),
60 return isUnordered == 0;
68 template <
class LO,
class GO,
class NT>
69 Transfer<LO, GO, NT>::
70 Transfer (
const Teuchos::RCP<const map_type>& source,
71 const Teuchos::RCP<const map_type>& target,
72 const Teuchos::RCP<Teuchos::FancyOStream>& out,
73 const Teuchos::RCP<Teuchos::ParameterList>& plist,
74 const std::string& className) :
75 TransferData_ (new
ImportExportData<LO, GO, NT> (source, target, out, plist))
78 this->setParameterList (plist, className);
81 template <
class LO,
class GO,
class NT>
87 TEUCHOS_ASSERT( ! this->TransferData_->out_.is_null () );
90 template <
class LO,
class GO,
class NT>
94 const std::string& className)
96 using ::Tpetra::Details::Behavior;
101 bool verboseParam =
false;
102 if (! plist.is_null ()) {
105 if (plist->isType<
bool> (
"Verbose")) {
106 verboseParam = plist->get<
bool> (
"Verbose");
108 else if (plist->isType<
bool> (
"Debug")) {
109 verboseParam = plist->get<
bool> (
"Debug");
112 this->TransferData_->verbose_ = verboseEnv || verboseParam;
115 template <
class LO,
class GO,
class NT>
119 return TransferData_->numSameIDs_;
122 template <
class LO,
class GO,
class NT>
126 return static_cast<size_t> (TransferData_->permuteFromLIDs_.extent (0));
129 template <
class LO,
class GO,
class NT>
130 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
133 const auto& dv = TransferData_->permuteFromLIDs_;
134 TEUCHOS_TEST_FOR_EXCEPTION
135 (dv.need_sync_device (), std::logic_error,
136 "Tpetra::Details::Transfer::getPermuteFromLIDs_dv: "
137 "DualView needs sync to device" );
138 TEUCHOS_TEST_FOR_EXCEPTION
139 (dv.need_sync_host (), std::logic_error,
140 "Tpetra::Details::Transfer::getPermuteFromLIDs_dv: "
141 "DualView needs sync to host" );
145 template <
class LO,
class GO,
class NT>
146 Teuchos::ArrayView<const LO>
149 return makeConstArrayViewFromDualView (TransferData_->permuteFromLIDs_);
152 template <
class LO,
class GO,
class NT>
153 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
156 const auto& dv = TransferData_->permuteToLIDs_;
157 TEUCHOS_TEST_FOR_EXCEPTION
158 (dv.need_sync_device (), std::logic_error,
159 "Tpetra::Details::Transfer::getPermuteToLIDs_dv: "
160 "DualView needs sync to device" );
161 TEUCHOS_TEST_FOR_EXCEPTION
162 (dv.need_sync_host (), std::logic_error,
163 "Tpetra::Details::Transfer::getPermuteToLIDs_dv: "
164 "DualView needs sync to host" );
168 template <
class LO,
class GO,
class NT>
169 Teuchos::ArrayView<const LO>
172 return makeConstArrayViewFromDualView (TransferData_->permuteToLIDs_);
175 template <
class LO,
class GO,
class NT>
179 return static_cast<size_t> (TransferData_->remoteLIDs_.extent (0));
182 template <
class LO,
class GO,
class NT>
183 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
186 const auto& dv = TransferData_->remoteLIDs_;
187 TEUCHOS_TEST_FOR_EXCEPTION
188 (dv.need_sync_device (), std::logic_error,
189 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
190 "DualView needs sync to device" );
191 TEUCHOS_TEST_FOR_EXCEPTION
192 (dv.need_sync_host (), std::logic_error,
193 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
194 "DualView needs sync to host" );
198 template <
class LO,
class GO,
class NT>
199 Teuchos::ArrayView<const LO>
202 return makeConstArrayViewFromDualView (TransferData_->remoteLIDs_);
205 template <
class LO,
class GO,
class NT>
209 return static_cast<size_t> (TransferData_->exportLIDs_.extent (0));
212 template <
class LO,
class GO,
class NT>
213 Kokkos::DualView<const LO*, typename Transfer<LO, GO, NT>::device_type>
216 const auto& dv = TransferData_->exportLIDs_;
217 TEUCHOS_TEST_FOR_EXCEPTION
218 (dv.need_sync_device (), std::logic_error,
219 "Tpetra::Details::Transfer::getExportLIDs_dv: "
220 "DualView needs sync to device" );
221 TEUCHOS_TEST_FOR_EXCEPTION
222 (dv.need_sync_host (), std::logic_error,
223 "Tpetra::Details::Transfer::getExportLIDs_dv: "
224 "DualView needs sync to host" );
228 template <
class LO,
class GO,
class NT>
229 Teuchos::ArrayView<const LO>
232 return makeConstArrayViewFromDualView (TransferData_->exportLIDs_);
235 template <
class LO,
class GO,
class NT>
236 Teuchos::ArrayView<const int>
239 return TransferData_->exportPIDs_ ();
242 template <
class LO,
class GO,
class NT>
243 Teuchos::RCP<const typename Transfer<LO, GO, NT>::map_type>
246 return TransferData_->source_;
249 template <
class LO,
class GO,
class NT>
250 Teuchos::RCP<const typename Transfer<LO, GO, NT>::map_type>
253 return TransferData_->target_;
256 template <
class LO,
class GO,
class NT>
260 return TransferData_->distributor_;
263 template <
class LO,
class GO,
class NT>
267 return TransferData_->isLocallyComplete_;
270 template <
class LO,
class GO,
class NT>
274 return (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
275 getTargetMap()->getLocalNumElements()));
278 template <
class LO,
class GO,
class NT>
286 bool ordered = (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
287 getTargetMap()->getLocalNumElements()));
288 ordered &= (getTargetMap()->getLocalNumElements() == getNumSameIDs() + getNumRemoteIDs());
290 const auto& dv = TransferData_->remoteLIDs_;
291 TEUCHOS_TEST_FOR_EXCEPTION
292 (dv.need_sync_device (), std::logic_error,
293 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
294 "DualView needs sync to device" );
295 auto v_d = dv.view_device ();
296 ordered &= isViewOrdered<device_type, LO>(v_d);
298 TransferData_->remoteLIDsContiguous_ = ordered;
300 ordered = (getNumSameIDs() == std::min(getSourceMap()->getLocalNumElements(),
301 getTargetMap()->getLocalNumElements()));
302 ordered &= (getSourceMap()->getLocalNumElements() == getNumSameIDs() + getNumExportIDs());
304 const auto& dv = TransferData_->exportLIDs_;
305 TEUCHOS_TEST_FOR_EXCEPTION
306 (dv.need_sync_device (), std::logic_error,
307 "Tpetra::Details::Transfer::getRemoteLIDs_dv: "
308 "DualView needs sync to device" );
309 auto v_d = dv.view_device ();
310 ordered &= isViewOrdered<device_type, LO>(v_d);
312 TransferData_->exportLIDsContiguous_ = ordered;
315 template <
class LO,
class GO,
class NT>
317 Transfer<LO, GO, NT>::
318 areRemoteLIDsContiguous ()
const {
319 return TransferData_->remoteLIDsContiguous_;
322 template <
class LO,
class GO,
class NT>
324 Transfer<LO, GO, NT>::
325 areExportLIDsContiguous ()
const {
326 return TransferData_->exportLIDsContiguous_;
330 template <
class LO,
class GO,
class NT>
334 const Teuchos::EVerbosityLevel verbLevel)
const
336 this->describeImpl (out,
"Tpetra::Details::Transfer", verbLevel);
339 template<
class LO,
class GO,
class NT>
340 Teuchos::FancyOStream&
344 Teuchos::FancyOStream* outPtr = TransferData_->out_.getRawPtr ();
345 TEUCHOS_ASSERT( outPtr !=
nullptr );
349 template<
class LO,
class GO,
class NT>
353 return TransferData_->verbose_;
356 template<
class LO,
class GO,
class NT>
360 const std::string& className,
361 const Teuchos::EVerbosityLevel verbLevel)
const
363 using Teuchos::TypeNameTraits;
364 using Teuchos::VERB_DEFAULT;
365 using Teuchos::VERB_NONE;
366 using Teuchos::VERB_LOW;
368 const Teuchos::EVerbosityLevel vl =
369 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
371 if (vl == VERB_NONE) {
378 auto srcMap = this->getSourceMap ();
379 if (srcMap.is_null ()) {
382 auto comm = srcMap->getComm ();
383 if (comm.is_null ()) {
386 if (this->getTargetMap ().is_null () ||
387 this->getTargetMap ()->getComm ().is_null ()) {
391 const int myRank = comm->getRank ();
392 const int numProcs = comm->getSize ();
399 Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
405 tab0 = Teuchos::rcp (
new Teuchos::OSTab (out));
407 out <<
"\"" << className <<
"\":" << endl;
408 tab1 = Teuchos::rcp (
new Teuchos::OSTab (out));
411 out <<
"Template parameters:" << endl;
412 Teuchos::OSTab tab2 (out);
413 out <<
"LocalOrdinal: " << TypeNameTraits<LO>::name () << endl
414 <<
"GlobalOrdinal: " << TypeNameTraits<GO>::name () << endl
415 <<
"Node: " << TypeNameTraits<NT>::name () << endl;
418 const std::string label = this->getObjectLabel ();
420 out <<
"Label: " << label << endl;
422 out <<
"Number of processes: " << numProcs << endl;
429 this->globalDescribe (out, vl);
441 out <<
"Source Map:" << endl;
444 this->getSourceMap ()->describe (out, vl);
447 out <<
"Target Map:" << endl;
450 this->getTargetMap ()->describe (out, vl);
453 out <<
"Distributor:" << endl;
455 this->getDistributor ().describe (out, vl);
458 template<
class LO,
class GO,
class NT>
462 const Teuchos::EVerbosityLevel vl)
const
465 using Teuchos::OSTab;
467 using Teuchos::toString;
474 auto srcMap = this->getSourceMap ();
475 if (srcMap.is_null ()) {
478 RCP<const Teuchos::Comm<int> > comm = srcMap->getComm ();
479 if (comm.is_null ()) {
483 const std::string myStr = localDescribeToString (vl);
484 ::Tpetra::Details::gathervPrint (out, myStr, *comm);
487 template<
class LO,
class GO,
class NT>
489 Transfer<LO, GO, NT>::
490 localDescribeToString (
const Teuchos::EVerbosityLevel vl)
const
492 using Teuchos::OSTab;
496 RCP<std::ostringstream> outString (
new std::ostringstream);
497 RCP<Teuchos::FancyOStream> outp = Teuchos::getFancyOStream (outString);
498 Teuchos::FancyOStream& out = *outp;
500 RCP<const Teuchos::Comm<int> > comm = this->getSourceMap ()->getComm ();
501 if (this->getSourceMap ().is_null () ||
502 this->getSourceMap ()->getComm ().is_null ()) {
507 return std::string (
"");
510 const int myRank = comm->getRank ();
511 const int numProcs = comm->getSize ();
513 out <<
"Process " << myRank <<
" of " << numProcs <<
":" << endl;
516 out <<
"numSameIDs: " << getNumSameIDs () << endl;
517 out <<
"numPermuteIDs: " << getNumPermuteIDs () << endl;
518 out <<
"numRemoteIDs: " << getNumRemoteIDs () << endl;
519 out <<
"numExportIDs: " << getNumExportIDs () << endl;
523 if (vl <= Teuchos::VERB_MEDIUM) {
524 out <<
"permuteFromLIDs count: " << getPermuteFromLIDs ().size () << endl
525 <<
"permuteToLIDs count: " << getPermuteToLIDs ().size () << endl
526 <<
"remoteLIDs count: " << getRemoteLIDs ().size () << endl
527 <<
"exportLIDs count: " << getExportLIDs ().size () << endl
528 <<
"exportPIDs count: " << getExportPIDs () << endl;
532 RCP<const Map<LO,GO,NT> > tmap = getTargetMap();
533 RCP<const Map<LO,GO,NT> > smap = getSourceMap();
534 Teuchos::Array<GO> RemoteGIDs(getRemoteLIDs().size());
535 Teuchos::Array<int> RemotePIDs(getRemoteLIDs().size());
536 for(
size_t i=0; i<(size_t)getRemoteLIDs().size(); i++)
537 RemoteGIDs[i] = tmap->getGlobalElement(getRemoteLIDs()[i]);
539 Teuchos::Array<int> ExportGIDs(getExportLIDs().size());
540 for(
size_t i=0; i<(size_t)getExportLIDs().size(); i++)
541 ExportGIDs[i] = smap->getGlobalElement(getExportLIDs()[i]);
546 Teuchos::ArrayView<const int> ProcsFrom = D.
getProcsFrom();
547 Teuchos::ArrayView<const size_t> LengthsFrom = D.
getLengthsFrom();
548 for (
size_t i = 0, j = 0; i < NumReceives; ++i) {
549 const int pid = ProcsFrom[i];
550 for (
size_t k = 0; k < LengthsFrom[i]; ++k) {
556 out <<
"distor.NumRecvs : "<<NumReceives<<endl
557 <<
"distor.ProcsFrom : "<<toString(ProcsFrom)<<endl
558 <<
"distor.LengthsFrom: "<<toString(LengthsFrom)<<endl;
561 <<
"distor.ProcsTo : "<<toString(D.
getProcsTo())<<endl
562 <<
"distor.LengthsTo : "<<toString(D.
getLengthsTo())<<endl;
566 out <<
"permuteFromLIDs: " << toString (getPermuteFromLIDs ()) << endl
567 <<
"permuteToLIDs: " << toString (getPermuteToLIDs ()) << endl
568 <<
"remoteLIDs: " << toString (getRemoteLIDs ()) << endl
569 <<
"remoteGIDs: " << toString (RemoteGIDs ()) << endl
570 <<
"remotePIDs: " << toString (RemotePIDs ()) << endl
571 <<
"exportLIDs: " << toString (getExportLIDs ()) << endl
572 <<
"exportGIDs: " << toString (ExportGIDs ()) << endl
573 <<
"exportPIDs: " << toString (getExportPIDs ()) << endl;
577 return outString->str ();
582 template <
class LO,
class GO,
class NT>
584 expertSetRemoteLIDsContiguous(Transfer<LO, GO, NT> transfer,
bool contig) {
585 transfer.TransferData_->remoteLIDsContiguous_ = contig;
589 template <
class LO,
class GO,
class NT>
591 expertSetExportLIDsContiguous(Transfer<LO, GO, NT> transfer,
bool contig) {
592 transfer.TransferData_->exportLIDsContiguous_ = contig;
599 #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.