Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends 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 
246  Kokkos::fence(); // target.getLocalElement will be UVM access
247 
248  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
249  const GO curSrcGid = rawSrcGids[srcLid];
250  // getLocalElement() returns LINVALID if the GID isn't in the
251  // target Map. This saves us a lookup (which
252  // isNodeGlobalElement() would do).
253  const LO tgtLid = target.getLocalElement (curSrcGid);
254  if (tgtLid != LINVALID) { // if target.isNodeGlobalElement (curSrcGid)
255  ++numPermutes;
256  }
257  else {
258  ++numExports;
259  }
260  }
261  if (this->verbose ()) {
262  std::ostringstream os;
263  os << *prefix << "numPermutes: " << numPermutes
264  << ", numExports: " << numExports << endl;
265  this->verboseOutputStream () << os.str ();
266  }
267  TEUCHOS_ASSERT( numPermutes + numExports ==
268  numSrcLids - numSameGids );
269 
270  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
271  permuteToLIDs (view_alloc_no_init ("permuteToLIDs"), numPermutes);
272  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
273  permuteFromLIDs (view_alloc_no_init ("permuteFromLIDs"), numPermutes);
274  typename decltype (this->TransferData_->permuteToLIDs_)::t_host
275  exportLIDs (view_alloc_no_init ("exportLIDs"), numExports);
276 
277  // FIXME (mfh 03 Feb 2019) Replace with std::unique_ptr of array,
278  // to avoid superfluous initialization on resize.
279  exportGIDs.resize (numExports);
280 
281  {
282  LO numPermutes2 = 0;
283  LO numExports2 = 0;
284  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
285  const GO curSrcGid = rawSrcGids[srcLid];
286  const LO tgtLid = target.getLocalElement (curSrcGid);
287  if (tgtLid != LINVALID) {
288  permuteToLIDs[numPermutes2] = tgtLid;
289  permuteFromLIDs[numPermutes2] = srcLid;
290  ++numPermutes2;
291  }
292  else {
293  exportGIDs[numExports2] = curSrcGid;
294  exportLIDs[numExports2] = srcLid;
295  ++numExports2;
296  }
297  }
298  TEUCHOS_ASSERT( numPermutes == numPermutes2 );
299  TEUCHOS_ASSERT( numExports == numExports2 );
300  TEUCHOS_ASSERT( size_t (numExports) == size_t (exportGIDs.size ()) );
301  }
302 
303  // Defer making this->TransferData_->exportLIDs_ until after
304  // getRemoteIndexList, since we might need to shrink it then.
305 
306  // exportLIDs is the list of this process' LIDs that it has to
307  // send out. Since this is an Export, and therefore the target
308  // Map is nonoverlapping, we know that each export LID only needs
309  // to be sent to one process. However, the source Map may be
310  // overlapping, so multiple processes might send to the same LID
311  // on a receiving process.
312 
313  if (numExports != 0 && ! source.isDistributed ()) {
314  // This Export has export LIDs, meaning that the source Map has
315  // entries on this process that are not in the target Map on
316  // this process. However, the source Map is not distributed
317  // globally. This implies that this Import is not locally
318  // complete on this process.
319  this->TransferData_->isLocallyComplete_ = false;
320  if (this->verbose ()) {
321  std::ostringstream os;
322  os << *prefix << "Export is not locally complete" << endl;
323  this->verboseOutputStream () << os.str ();
324  }
325  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
326  // correct behavior, depending on the circumstances.
328  (true, std::runtime_error, "::setupSamePermuteExport(): Source has "
329  "export LIDs but Source is not distributed globally. Exporting to "
330  "a submap of the target map.");
331  }
332 
333  // Compute exportPIDs_ ("outgoing" process IDs).
334  //
335  // For each GID in exportGIDs (GIDs to which this process must
336  // send), find its corresponding owning process (a.k.a. "image")
337  // ID in the target Map. Store these process IDs in
338  // exportPIDs_. These are the process IDs to which the Export
339  // needs to send data.
340  //
341  // We only need to do this if the source Map is distributed;
342  // otherwise, the Export doesn't have to perform any
343  // communication.
344  if (source.isDistributed ()) {
345  if (this->verbose ()) {
346  std::ostringstream os;
347  os << *prefix << "Source Map is distributed; "
348  "call targetMap.getRemoteiNdexList" << endl;
349  this->verboseOutputStream () << os.str ();
350  }
351  this->TransferData_->exportPIDs_.resize(exportGIDs.size ());
352  // This call will assign any GID in the target Map with no
353  // corresponding process ID a fake process ID of -1. We'll use
354  // this below to remove exports for processses that don't exist.
355  const LookupStatus lookup =
356  target.getRemoteIndexList (exportGIDs(),
357  this->TransferData_->exportPIDs_ ());
358  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
359  // correct behavior, depending on the circumstances.
360  TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error,
361  "::setupSamePermuteExport(): The source Map has GIDs not found "
362  "in the target Map.");
363 
364  // Get rid of process IDs not in the target Map. This prevents
365  // exporting to GIDs which don't belong to any process in the
366  // target Map.
367  if (lookup == IDNotPresent) {
368  // There is at least one GID owned by the calling process in
369  // the source Map, which is not owned by any process in the
370  // target Map.
371  this->TransferData_->isLocallyComplete_ = false;
372 
373  Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
374 
375  const size_type totalNumExports = exportPIDs.size ();
376  const size_type numInvalidExports =
377  std::count_if (exportPIDs.begin (), exportPIDs.end (),
378  [] (const int procId) { return procId == -1; });
379  if (this->verbose ()) {
380  std::ostringstream os;
381  os << *prefix << "totalNumExports: " << totalNumExports
382  << ", numInvalidExports: " << numInvalidExports << endl;
383  this->verboseOutputStream () << os.str ();
384  }
385  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
386  (numInvalidExports == 0, std::logic_error,
387  "targetMap.getRemoteIndexList returned IDNotPresent, but no export "
388  "PIDs are -1. Please report this bug to the Tpetra developers.");
389 
390  // We know that at least one export ID is invalid, that is,
391  // not in any process on the target Map. If all export IDs
392  // are invalid, we can delete all exports. Otherwise, keep
393  // the valid exports and discard the rest. This is legit
394  // Petra Object Model behavior, but it's a less common case.
395 
396  if (numInvalidExports == totalNumExports) {
397  exportGIDs.resize (0);
398  exportLIDs = decltype (exportLIDs) ();
399  exportPIDs.resize (0);
400  }
401  else {
402  size_type numValidExports = 0;
403  for (size_type e = 0; e < totalNumExports; ++e) {
404  if (this->TransferData_->exportPIDs_[e] != -1) {
405  exportGIDs[numValidExports] = exportGIDs[e];
406  exportLIDs[numValidExports] = exportLIDs[e];
407  exportPIDs[numValidExports] = exportPIDs[e];
408  ++numValidExports;
409  }
410  }
411  exportGIDs.resize (numValidExports);
412  Kokkos::resize (exportLIDs, numValidExports);
413  exportPIDs.resize (numValidExports);
414  }
415  }
416  }
417 
418  // FIXME (mfh 03 Feb 2019) These three DualViews could share a
419  // single device allocation, in order to avoid high cudaMalloc
420  // cost and device memory fragmentation.
421  makeDualViewFromOwningHostView (this->TransferData_->permuteToLIDs_, permuteToLIDs);
422  makeDualViewFromOwningHostView (this->TransferData_->permuteFromLIDs_, permuteFromLIDs);
423  makeDualViewFromOwningHostView (this->TransferData_->exportLIDs_, exportLIDs);
424 
425  if (this->verbose ()) {
426  std::ostringstream os;
427  os << *prefix << "Done!" << std::endl;
428  this->verboseOutputStream () << os.str ();
429  }
430  }
431 
432  template <class LocalOrdinal, class GlobalOrdinal, class Node>
433  void
434  Export<LocalOrdinal,GlobalOrdinal,Node>::
435  setupRemote (Teuchos::Array<GlobalOrdinal>& exportGIDs)
436  {
437  using ::Tpetra::Details::view_alloc_no_init;
438  using ::Tpetra::Details::makeDualViewFromOwningHostView;
439  using Teuchos::Array;
440  using std::endl;
441  using LO = LocalOrdinal;
442  using GO = GlobalOrdinal;
443 
444  std::unique_ptr<std::string> prefix;
445  if (this->verbose ()) {
446  auto srcMap = this->getSourceMap ();
447  auto comm = srcMap.is_null () ? Teuchos::null : srcMap->getComm ();
448  const int myRank = comm.is_null () ? -1 : comm->getRank ();
449 
450  std::ostringstream os;
451  os << "Proc " << myRank << ": Tpetra::Export::setupRemote: ";
452  prefix = std::unique_ptr<std::string> (new std::string (os.str ()));
453 
454  std::ostringstream os2;
455  os2 << *prefix << "Start" << std::endl;
456  this->verboseOutputStream () << os2.str ();
457  }
458 
459  TEUCHOS_ASSERT( ! this->getTargetMap ().is_null () );
460  const map_type& tgtMap = * (this->getTargetMap ());
461 
462  // Sort exportPIDs_ in ascending order, and apply the same
463  // permutation to exportGIDs_ and exportLIDs_. This ensures that
464  // exportPIDs_[i], exportGIDs_[i], and exportLIDs_[i] all
465  // refer to the same thing.
466  {
467  TEUCHOS_ASSERT( size_t (this->TransferData_->exportLIDs_.extent (0)) ==
468  size_t (this->TransferData_->exportPIDs_.size ()) );
469  this->TransferData_->exportLIDs_.modify_host ();
470  auto exportLIDs = this->TransferData_->exportLIDs_.view_host ();
471  sort3 (this->TransferData_->exportPIDs_.begin (),
472  this->TransferData_->exportPIDs_.end (),
473  exportGIDs.getRawPtr (),
474  exportLIDs.data ());
475  this->TransferData_->exportLIDs_.sync_device ();
476  // FIXME (mfh 03 Feb 2019) We actually end up sync'ing
477  // exportLIDs_ to device twice, once in setupSamePermuteExport,
478  // and once here. We could avoid the first sync.
479  }
480 
481  if (this->verbose ()) {
482  std::ostringstream os;
483  os << *prefix << "Call createFromSends" << endl;
484  this->verboseOutputStream () << os.str ();
485  }
486 
487  // Construct the list of entries that calling image needs to send
488  // as a result of everyone asking for what it needs to receive.
489  //
490  // mfh 05 Jan 2012: I understand the above comment as follows:
491  // Construct the communication plan from the list of image IDs to
492  // which we need to send.
493  Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
494  Distributor& distributor = this->TransferData_->distributor_;
495  const size_t numRemoteIDs = distributor.createFromSends (exportPIDs ());
496 
497  if (this->verbose ()) {
498  std::ostringstream os;
499  os << *prefix << "numRemoteIDs: " << numRemoteIDs
500  << "; call doPostsAndWaits" << endl;
501  this->verboseOutputStream () << os.str ();
502  }
503 
504  // Use the communication plan with ExportGIDs to find out who is
505  // sending to us and get the proper ordering of GIDs for incoming
506  // remote entries (these will be converted to LIDs when done).
507 
508  std::unique_ptr<GO[]> remoteGIDs_ptr (new GlobalOrdinal [numRemoteIDs]);
509  Teuchos::ArrayView<GO> remoteGIDs
510  (numRemoteIDs == 0 ? nullptr : remoteGIDs_ptr.get (), numRemoteIDs);
511  distributor.doPostsAndWaits (exportGIDs ().getConst (), 1, remoteGIDs);
512 
513  // Remote (incoming) IDs come in as GIDs; convert to LIDs. LIDs
514  // tell this process where to store the incoming remote data.
515  using host_remote_lids_type =
516  typename decltype (this->TransferData_->remoteLIDs_)::t_host;
517  host_remote_lids_type remoteLIDs
518  (view_alloc_no_init ("remoteLIDs"), numRemoteIDs);
519 
520  Kokkos::fence(); // tgtMap.getLocalElement will be UVM access
521 
522  for (LO j = 0; j < LO (numRemoteIDs); ++j) {
523  remoteLIDs[j] = tgtMap.getLocalElement (remoteGIDs[j]);
524  }
525  makeDualViewFromOwningHostView (this->TransferData_->remoteLIDs_, remoteLIDs);
526 
527  if (this->verbose ()) {
528  std::ostringstream os;
529  os << *prefix << "Done!" << endl;
530  this->verboseOutputStream () << os.str ();
531  }
532  }
533 
534 } // namespace Tpetra
535 
536 // Explicit instantiation macro.
537 // Only invoke this when in the Tpetra namespace.
538 // Most users do not need to use this.
539 //
540 // LO: The local ordinal type.
541 // GO: The global ordinal type.
542 // NODE: The Kokkos Node type.
543 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
544  template class Export< LO , GO , NODE >;
545 
546 #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.