Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tpetra_Export_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_EXPORT_DEF_HPP
43 #define TPETRA_EXPORT_DEF_HPP
44 
45 
46 #include "Tpetra_Distributor.hpp"
47 #include "Tpetra_Map.hpp"
48 #include "Tpetra_ImportExportData.hpp"
49 #include "Tpetra_Util.hpp"
50 #include "Tpetra_Import.hpp"
51 #include "Tpetra_Details_DualViewUtil.hpp"
53 #include "Teuchos_as.hpp"
54 #include "Teuchos_Array.hpp"
55 #include "Teuchos_FancyOStream.hpp"
56 #include "Teuchos_ParameterList.hpp"
57 #include <memory>
58 
59 namespace Tpetra {
60 
61  template <class LocalOrdinal, class GlobalOrdinal, class Node>
63  Export (const Teuchos::RCP<const map_type >& source,
64  const Teuchos::RCP<const map_type >& target,
65  const Teuchos::RCP<Teuchos::FancyOStream>& out,
66  const Teuchos::RCP<Teuchos::ParameterList>& plist) :
67  base_type (source, target, out, plist, "Export")
68  {
69  using Teuchos::rcp;
70  using std::endl;
71  using ::Tpetra::Details::ProfilingRegion;
72  ProfilingRegion regionExport ("Tpetra::Export::Export");
73 
74  if (this->verbose ()) {
75  std::ostringstream os;
76  const int myRank = source->getComm ()->getRank ();
77  os << myRank << ": Export ctor" << endl;
78  this->verboseOutputStream () << os.str ();
79  }
80  Teuchos::Array<GlobalOrdinal> exportGIDs;
81  setupSamePermuteExport (exportGIDs);
82  if (source->isDistributed ()) {
83  setupRemote (exportGIDs);
84  }
85 
86  TEUCHOS_ASSERT( ! this->TransferData_->permuteFromLIDs_.need_sync_device () );
87  TEUCHOS_ASSERT( ! this->TransferData_->permuteFromLIDs_.need_sync_host () );
88  TEUCHOS_ASSERT( ! this->TransferData_->permuteToLIDs_.need_sync_device () );
89  TEUCHOS_ASSERT( ! this->TransferData_->permuteToLIDs_.need_sync_host () );
90  TEUCHOS_ASSERT( ! this->TransferData_->remoteLIDs_.need_sync_device () );
91  TEUCHOS_ASSERT( ! this->TransferData_->remoteLIDs_.need_sync_host () );
92  TEUCHOS_ASSERT( ! this->TransferData_->exportLIDs_.need_sync_device () );
93  TEUCHOS_ASSERT( ! this->TransferData_->exportLIDs_.need_sync_host () );
94 
95  if (this->verbose ()) {
96  std::ostringstream os;
97  const int myRank = source->getComm ()->getRank ();
98  os << myRank << ": Export ctor: done" << endl;
99  this->verboseOutputStream () << os.str ();
100  }
101  }
102 
103  template <class LocalOrdinal, class GlobalOrdinal, class Node>
105  Export (const Teuchos::RCP<const map_type>& source,
106  const Teuchos::RCP<const map_type>& target) :
107  Export (source, target, Teuchos::null, Teuchos::null)
108  {}
109 
110  template <class LocalOrdinal, class GlobalOrdinal, class Node>
112  Export (const Teuchos::RCP<const map_type >& source,
113  const Teuchos::RCP<const map_type >& target,
114  const Teuchos::RCP<Teuchos::FancyOStream>& out) :
115  Export (source, target, out, Teuchos::null)
116  {}
117 
118  template <class LocalOrdinal, class GlobalOrdinal, class Node>
120  Export (const Teuchos::RCP<const map_type >& source,
121  const Teuchos::RCP<const map_type >& target,
122  const Teuchos::RCP<Teuchos::ParameterList>& plist) :
123  Export (source, target, Teuchos::null, plist)
124  {}
125 
126  template <class LocalOrdinal, class GlobalOrdinal, class Node>
129  base_type (rhs)
130  {}
131 
132  template <class LocalOrdinal, class GlobalOrdinal, class Node>
135  base_type (importer, typename base_type::reverse_tag ())
136  {}
137 
138  template <class LocalOrdinal, class GlobalOrdinal, class Node>
139  void
141  describe (Teuchos::FancyOStream& out,
142  const Teuchos::EVerbosityLevel verbLevel) const
143  {
144  // Call the base class' method. It does all the work.
145  this->describeImpl (out, "Tpetra::Export", verbLevel);
146  }
147 
148  template <class LocalOrdinal, class GlobalOrdinal, class Node>
150  print (std::ostream& os) const
151  {
152  auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
153  // "Print" traditionally meant "everything."
154  this->describe (*out, Teuchos::VERB_EXTREME);
155  }
156 
157  template <class LocalOrdinal, class GlobalOrdinal, class Node>
158  void
160  setupSamePermuteExport (Teuchos::Array<GlobalOrdinal>& exportGIDs)
161  {
162  using ::Tpetra::Details::makeDualViewFromOwningHostView;
163  using ::Tpetra::Details::ProfilingRegion;
164  using ::Tpetra::Details::view_alloc_no_init;
165  using Teuchos::arcp;
166  using Teuchos::Array;
167  using Teuchos::ArrayRCP;
168  using Teuchos::ArrayView;
169  using Teuchos::as;
170  using Teuchos::null;
171  using std::endl;
172  using LO = LocalOrdinal;
173  using GO = GlobalOrdinal;
174  using size_type = typename ArrayView<const GO>::size_type;
175  const char tfecfFuncName[] = "setupSamePermuteExport: ";
176  ProfilingRegion regionExport ("Tpetra::Export::setupSamePermuteExport");
177 
178  std::unique_ptr<std::string> prefix;
179  if (this->verbose ()) {
180  auto srcMap = this->getSourceMap ();
181  auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
182  const int myRank = comm.is_null () ? -1 : comm->getRank ();
183 
184  std::ostringstream os;
185  os << "Proc " << myRank << ": Tpetra::Export::setupSamePermuteExport: ";
186  prefix = std::unique_ptr<std::string> (new std::string (os.str ()));
187 
188  std::ostringstream os2;
189  os2 << *prefix << "Start" << std::endl;
190  this->verboseOutputStream () << os2.str ();
191  }
192 
193  const map_type& source = * (this->getSourceMap ());
194  const map_type& target = * (this->getTargetMap ());
195  ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
196  ArrayView<const GO> targetGIDs = target.getNodeElementList ();
197 
198 #ifdef HAVE_TPETRA_DEBUG
199  ArrayView<const GO> rawSrcGids = sourceGIDs;
200  ArrayView<const GO> rawTgtGids = targetGIDs;
201 #else
202  const GO* const rawSrcGids = sourceGIDs.getRawPtr ();
203  const GO* const rawTgtGids = targetGIDs.getRawPtr ();
204 #endif // HAVE_TPETRA_DEBUG
205  const size_type numSrcGids = sourceGIDs.size ();
206  const size_type numTgtGids = targetGIDs.size ();
207  const size_type numGids = std::min (numSrcGids, numTgtGids);
208 
209  // Compute numSameIDs_: the number of initial GIDs that are the
210  // same (and occur in the same order) in both Maps. The point of
211  // numSameIDs_ is for the common case of an Export where all the
212  // overlapping GIDs are at the end of the source Map, but
213  // otherwise the source and target Maps are the same. This allows
214  // a fast contiguous copy for the initial "same IDs."
215  size_type numSameGids = 0;
216  for ( ; numSameGids < numGids &&
217  rawSrcGids[numSameGids] == rawTgtGids[numSameGids];
218  ++numSameGids)
219  {} // third clause of 'for' does everything
220  this->TransferData_->numSameIDs_ = numSameGids;
221 
222  if (this->verbose ()) {
223  std::ostringstream os;
224  os << *prefix << "numIDs: " << numGids
225  << ", numSameIDs: " << numSameGids << endl;
226  this->verboseOutputStream () << os.str ();
227  }
228 
229  // Compute permuteToLIDs_, permuteFromLIDs_, exportGIDs, and
230  // exportLIDs_. The first two arrays are IDs to be permuted, and
231  // the latter two arrays are IDs to sent out ("exported"), called
232  // "export" IDs.
233  //
234  // IDs to permute are in both the source and target Maps, which
235  // means we don't have to send or receive them, but we do have to
236  // rearrange (permute) them in general. IDs to send are in the
237  // source Map, but not in the target Map.
238 
239  // Iterate over the source Map's LIDs, since we only need to do
240  // GID -> LID lookups for the target Map.
241  const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
242  const LO numSrcLids = static_cast<LO> (numSrcGids);
243  LO numPermutes = 0;
244  LO numExports = 0;
245  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
246  const GO curSrcGid = rawSrcGids[srcLid];
247  // getLocalElement() returns LINVALID if the GID isn't in the
248  // target Map. This saves us a lookup (which
249  // isNodeGlobalElement() would do).
250  const LO tgtLid = target.getLocalElement (curSrcGid);
251  if (tgtLid != LINVALID) { // if target.isNodeGlobalElement (curSrcGid)
252  ++numPermutes;
253  }
254  else {
255  ++numExports;
256  }
257  }
258  if (this->verbose ()) {
259  std::ostringstream os;
260  os << *prefix << "numPermutes: " << numPermutes
261  << ", numExports: " << numExports << endl;
262  this->verboseOutputStream () << os.str ();
263  }
264  TEUCHOS_ASSERT( numPermutes + numExports ==
265  numSrcLids - numSameGids );
266 
267  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
268  permuteToLIDs (view_alloc_no_init ("permuteToLIDs"), numPermutes);
269  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
270  permuteFromLIDs (view_alloc_no_init ("permuteFromLIDs"), numPermutes);
271  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
272  exportLIDs (view_alloc_no_init ("exportLIDs"), numExports);
273 
274  // FIXME (mfh 03 Feb 2019) Replace with std::unique_ptr of array,
275  // to avoid superfluous initialization on resize.
276  exportGIDs.resize (numExports);
277 
278  {
279  LO numPermutes2 = 0;
280  LO numExports2 = 0;
281  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
282  const GO curSrcGid = rawSrcGids[srcLid];
283  const LO tgtLid = target.getLocalElement (curSrcGid);
284  if (tgtLid != LINVALID) {
285  permuteToLIDs[numPermutes2] = tgtLid;
286  permuteFromLIDs[numPermutes2] = srcLid;
287  ++numPermutes2;
288  }
289  else {
290  exportGIDs[numExports2] = curSrcGid;
291  exportLIDs[numExports2] = srcLid;
292  ++numExports2;
293  }
294  }
295  TEUCHOS_ASSERT( numPermutes == numPermutes2 );
296  TEUCHOS_ASSERT( numExports == numExports2 );
297  TEUCHOS_ASSERT( size_t (numExports) == size_t (exportGIDs.size ()) );
298  }
299 
300  // Defer making this->TransferData_->exportLIDs_ until after
301  // getRemoteIndexList, since we might need to shrink it then.
302 
303  // exportLIDs is the list of this process' LIDs that it has to
304  // send out. Since this is an Export, and therefore the target
305  // Map is nonoverlapping, we know that each export LID only needs
306  // to be sent to one process. However, the source Map may be
307  // overlapping, so multiple processes might send to the same LID
308  // on a receiving process.
309 
310  if (numExports != 0 && ! source.isDistributed ()) {
311  // This Export has export LIDs, meaning that the source Map has
312  // entries on this process that are not in the target Map on
313  // this process. However, the source Map is not distributed
314  // globally. This implies that this Import is not locally
315  // complete on this process.
316  this->TransferData_->isLocallyComplete_ = false;
317  if (this->verbose ()) {
318  std::ostringstream os;
319  os << *prefix << "Export is not locally complete" << endl;
320  this->verboseOutputStream () << os.str ();
321  }
322  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
323  // correct behavior, depending on the circumstances.
325  (true, std::runtime_error, "::setupSamePermuteExport(): Source has "
326  "export LIDs but Source is not distributed globally. Exporting to "
327  "a submap of the target map.");
328  }
329 
330  // Compute exportPIDs_ ("outgoing" process IDs).
331  //
332  // For each GID in exportGIDs (GIDs to which this process must
333  // send), find its corresponding owning process (a.k.a. "image")
334  // ID in the target Map. Store these process IDs in
335  // exportPIDs_. These are the process IDs to which the Export
336  // needs to send data.
337  //
338  // We only need to do this if the source Map is distributed;
339  // otherwise, the Export doesn't have to perform any
340  // communication.
341  if (source.isDistributed ()) {
342  if (this->verbose ()) {
343  std::ostringstream os;
344  os << *prefix << "Source Map is distributed; "
345  "call targetMap.getRemoteiNdexList" << endl;
346  this->verboseOutputStream () << os.str ();
347  }
348  this->TransferData_->exportPIDs_.resize(exportGIDs.size ());
349  // This call will assign any GID in the target Map with no
350  // corresponding process ID a fake process ID of -1. We'll use
351  // this below to remove exports for processses that don't exist.
352  const LookupStatus lookup =
353  target.getRemoteIndexList (exportGIDs(),
354  this->TransferData_->exportPIDs_ ());
355  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
356  // correct behavior, depending on the circumstances.
357  TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error,
358  "::setupSamePermuteExport(): The source Map has GIDs not found "
359  "in the target Map.");
360 
361  // Get rid of process IDs not in the target Map. This prevents
362  // exporting to GIDs which don't belong to any process in the
363  // target Map.
364  if (lookup == IDNotPresent) {
365  // There is at least one GID owned by the calling process in
366  // the source Map, which is not owned by any process in the
367  // target Map.
368  this->TransferData_->isLocallyComplete_ = false;
369 
370  Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
371 
372  const size_type totalNumExports = exportPIDs.size ();
373  const size_type numInvalidExports =
374  std::count_if (exportPIDs.begin (), exportPIDs.end (),
375  [] (const int procId) { return procId == -1; });
376  if (this->verbose ()) {
377  std::ostringstream os;
378  os << *prefix << "totalNumExports: " << totalNumExports
379  << ", numInvalidExports: " << numInvalidExports << endl;
380  this->verboseOutputStream () << os.str ();
381  }
382  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
383  (numInvalidExports == 0, std::logic_error,
384  "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
385  "PIDs are -1. Please report this bug to the Tpetra developers.");
386 
387  // We know that at least one export ID is invalid, that is,
388  // not in any process on the target Map. If all export IDs
389  // are invalid, we can delete all exports. Otherwise, keep
390  // the valid exports and discard the rest. This is legit
391  // Petra Object Model behavior, but it's a less common case.
392 
393  if (numInvalidExports == totalNumExports) {
394  exportGIDs.resize (0);
395  exportLIDs = decltype (exportLIDs) ();
396  exportPIDs.resize (0);
397  }
398  else {
399  size_type numValidExports = 0;
400  for (size_type e = 0; e < totalNumExports; ++e) {
401  if (this->TransferData_->exportPIDs_[e] != -1) {
402  exportGIDs[numValidExports] = exportGIDs[e];
403  exportLIDs[numValidExports] = exportLIDs[e];
404  exportPIDs[numValidExports] = exportPIDs[e];
405  ++numValidExports;
406  }
407  }
408  exportGIDs.resize (numValidExports);
409  Kokkos::resize (exportLIDs, numValidExports);
410  exportPIDs.resize (numValidExports);
411  }
412  }
413  }
414 
415  // FIXME (mfh 03 Feb 2019) These three DualViews could share a
416  // single device allocation, in order to avoid high cudaMalloc
417  // cost and device memory fragmentation.
418  makeDualViewFromOwningHostView (this->TransferData_->permuteToLIDs_, permuteToLIDs);
419  makeDualViewFromOwningHostView (this->TransferData_->permuteFromLIDs_, permuteFromLIDs);
420  makeDualViewFromOwningHostView (this->TransferData_->exportLIDs_, exportLIDs);
421 
422  if (this->verbose ()) {
423  std::ostringstream os;
424  os << *prefix << "Done!" << std::endl;
425  this->verboseOutputStream () << os.str ();
426  }
427  }
428 
429  template <class LocalOrdinal, class GlobalOrdinal, class Node>
430  void
431  Export<LocalOrdinal,GlobalOrdinal,Node>::
432  setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
433  {
434  using ::Tpetra::Details::view_alloc_no_init;
435  using ::Tpetra::Details::makeDualViewFromOwningHostView;
436  using Teuchos::Array;
437  using std::endl;
438  using LO = LocalOrdinal;
439  using GO = GlobalOrdinal;
440 
441  std::unique_ptr<std::string> prefix;
442  if (this->verbose ()) {
443  auto srcMap = this->getSourceMap ();
444  auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
445  const int myRank = comm.is_null () ? -1 : comm->getRank ();
446 
447  std::ostringstream os;
448  os << "Proc " << myRank << ": Tpetra::Export::setupRemote: ";
449  prefix = std::unique_ptr<std::string> (new std::string (os.str ()));
450 
451  std::ostringstream os2;
452  os2 << *prefix << "Start" << std::endl;
453  this->verboseOutputStream () << os2.str ();
454  }
455 
456  TEUCHOS_ASSERT( ! this->getTargetMap ().is_null () );
457  const map_type& tgtMap = * (this->getTargetMap ());
458 
459  // Sort exportPIDs_ in ascending order, and apply the same
460  // permutation to exportGIDs_ and exportLIDs_. This ensures that
461  // exportPIDs_[i], exportGIDs_[i], and exportLIDs_[i] all
462  // refer to the same thing.
463  {
464  TEUCHOS_ASSERT( size_t (this->TransferData_->exportLIDs_.extent (0)) ==
465  size_t (this->TransferData_->exportPIDs_.size ()) );
466  this->TransferData_->exportLIDs_.modify_host ();
467  auto exportLIDs = this->TransferData_->exportLIDs_.view_host ();
468  sort3 (this->TransferData_->exportPIDs_.begin (),
469  this->TransferData_->exportPIDs_.end (),
470  exportGIDs.getRawPtr (),
471  exportLIDs.data ());
472  this->TransferData_->exportLIDs_.sync_device ();
473  // FIXME (mfh 03 Feb 2019) We actually end up sync'ing
474  // exportLIDs_ to device twice, once in setupSamePermuteExport,
475  // and once here. We could avoid the first sync.
476  }
477 
478  if (this->verbose ()) {
479  std::ostringstream os;
480  os << *prefix << "Call createFromSends" << endl;
481  this->verboseOutputStream () << os.str ();
482  }
483 
484  // Construct the list of entries that calling image needs to send
485  // as a result of everyone asking for what it needs to receive.
486  //
487  // mfh 05 Jan 2012: I understand the above comment as follows:
488  // Construct the communication plan from the list of image IDs to
489  // which we need to send.
490  Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
491  Distributor& distributor = this->TransferData_->distributor_;
492  const size_t numRemoteIDs = distributor.createFromSends (exportPIDs ());
493 
494  if (this->verbose ()) {
495  std::ostringstream os;
496  os << *prefix << "numRemoteIDs: " << numRemoteIDs
497  << "; call doPostsAndWaits" << endl;
498  this->verboseOutputStream () << os.str ();
499  }
500 
501  // Use the communication plan with ExportGIDs to find out who is
502  // sending to us and get the proper ordering of GIDs for incoming
503  // remote entries (these will be converted to LIDs when done).
504 
505  std::unique_ptr<GO[]> remoteGIDs_ptr (new GlobalOrdinal [numRemoteIDs]);
506  Teuchos::ArrayView<GO> remoteGIDs
507  (numRemoteIDs == 0 ? nullptr : remoteGIDs_ptr.get (), numRemoteIDs);
508  distributor.doPostsAndWaits (exportGIDs ().getConst (), 1, remoteGIDs);
509 
510  // Remote (incoming) IDs come in as GIDs; convert to LIDs. LIDs
511  // tell this process where to store the incoming remote data.
512  using host_remote_lids_type =
513  typename decltype (this->TransferData_->remoteLIDs_)::t_host;
514  host_remote_lids_type remoteLIDs
515  (view_alloc_no_init ("remoteLIDs"), numRemoteIDs);
516  for (LO j = 0; j < LO (numRemoteIDs); ++j) {
517  remoteLIDs[j] = tgtMap.getLocalElement (remoteGIDs[j]);
518  }
519  makeDualViewFromOwningHostView (this->TransferData_->remoteLIDs_, remoteLIDs);
520 
521  if (this->verbose ()) {
522  std::ostringstream os;
523  os << *prefix << "Done!" << endl;
524  this->verboseOutputStream () << os.str ();
525  }
526  }
527 
528 } // namespace Tpetra
529 
530 // Explicit instantiation macro.
531 // Only invoke this when in the Tpetra namespace.
532 // Most users do not need to use this.
533 //
534 // LO: The local ordinal type.
535 // GO: The global ordinal type.
536 // NODE: The Kokkos Node type.
537 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
538  template class Export< LO , GO , NODE >;
539 
540 #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&#39;s data to the given output stream.
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
Sort the first array, and apply the same permutation to the second and third arrays.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
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&#39;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.