Tpetra parallel linear algebra  Version of the Day
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 #include <Tpetra_Export_decl.hpp>
46 
47 #include <Tpetra_Distributor.hpp>
48 #include <Tpetra_Map.hpp>
49 #include <Tpetra_ImportExportData.hpp>
50 #include <Tpetra_Util.hpp>
51 #include <Tpetra_Import.hpp>
52 #include <Teuchos_as.hpp>
53 
54 namespace {
55  // Default value of Export's "Debug" parameter.
56  const bool tpetraExportDebugDefault = false;
57 } // namespace (anonymous)
58 
59 namespace Tpetra {
60  template <class LocalOrdinal, class GlobalOrdinal, class Node>
61  void
63  setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& plist)
64  {
65  bool debug = tpetraExportDebugDefault;
66  if (! plist.is_null ()) {
67  try {
68  debug = plist->get<bool> ("Debug");
69  } catch (Teuchos::Exceptions::InvalidParameter&) {}
70  }
71  debug_ = debug;
72  ExportData_->distributor_.setParameterList (plist);
73  }
74 
75  template <class LocalOrdinal, class GlobalOrdinal, class Node>
77  Export (const Teuchos::RCP<const map_type >& source,
78  const Teuchos::RCP<const map_type >& target) :
79  out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
80  debug_ (tpetraExportDebugDefault)
81  {
82  using Teuchos::rcp;
83  using std::endl;
85 
86  if (! out_.is_null ()) {
87  out_->pushTab ();
88  }
89  if (debug_) {
90  std::ostringstream os;
91  const int myRank = source->getComm ()->getRank ();
92  os << myRank << ": Export ctor" << endl;
93  *out_ << os.str ();
94  }
95  ExportData_ = rcp (new data_type (source, target, out_));
96  Teuchos::Array<GlobalOrdinal> exportGIDs;
97  setupSamePermuteExport (exportGIDs);
98  if (debug_) {
99  std::ostringstream os;
100  const int myRank = source->getComm ()->getRank ();
101  os << myRank << ": Export ctor: "
102  << "setupSamePermuteExport done" << endl;
103  *out_ << os.str ();
104  }
105  if (source->isDistributed ()) {
106  setupRemote (exportGIDs);
107  }
108  if (debug_) {
109  std::ostringstream os;
110  const int myRank = source->getComm ()->getRank ();
111  os << myRank << ": Export ctor: done" << endl;
112  *out_ << os.str ();
113  }
114  if (! out_.is_null ()) {
115  out_->popTab ();
116  }
117  }
118 
119  template <class LocalOrdinal, class GlobalOrdinal, class Node>
121  Export (const Teuchos::RCP<const map_type >& source,
122  const Teuchos::RCP<const map_type >& target,
123  const Teuchos::RCP<Teuchos::FancyOStream>& out) :
124  out_ (out),
125  debug_ (tpetraExportDebugDefault)
126  {
127  using Teuchos::rcp;
128  using std::endl;
130 
131  if (! out_.is_null ()) {
132  out_->pushTab ();
133  }
134  if (debug_) {
135  std::ostringstream os;
136  const int myRank = source->getComm ()->getRank ();
137  os << myRank << ": Export ctor" << endl;
138  *out_ << os.str ();
139  }
140  ExportData_ = rcp (new data_type (source, target, out));
141  Teuchos::Array<GlobalOrdinal> exportGIDs;
142  setupSamePermuteExport (exportGIDs);
143  if (debug_) {
144  std::ostringstream os;
145  const int myRank = source->getComm ()->getRank ();
146  os << myRank << ": Export ctor: "
147  << "setupSamePermuteExport done" << endl;
148  *out_ << os.str ();
149  }
150  if (source->isDistributed ()) {
151  setupRemote (exportGIDs);
152  }
153  if (debug_) {
154  std::ostringstream os;
155  const int myRank = source->getComm ()->getRank ();
156  os << myRank << ": Export ctor: done" << endl;
157  *out_ << os.str ();
158  }
159  if (! out_.is_null ()) {
160  out_->popTab ();
161  }
162  }
163 
164  template <class LocalOrdinal, class GlobalOrdinal, class Node>
166  Export (const Teuchos::RCP<const map_type >& source,
167  const Teuchos::RCP<const map_type >& target,
168  const Teuchos::RCP<Teuchos::ParameterList>& plist) :
169  out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
170  debug_ (tpetraExportDebugDefault)
171  {
172  using Teuchos::rcp;
173  using std::endl;
175 
176  // Read "Debug" parameter from the input ParameterList.
177  bool debug = tpetraExportDebugDefault;
178  if (! plist.is_null ()) {
179  try {
180  debug = plist->get<bool> ("Debug");
181  } catch (Teuchos::Exceptions::InvalidParameter&) {}
182  }
183  debug_ = debug;
184 
185  if (! out_.is_null ()) {
186  out_->pushTab ();
187  }
188  if (debug_) {
189  std::ostringstream os;
190  const int myRank = source->getComm ()->getRank ();
191  os << myRank << ": Export ctor" << endl;
192  *out_ << os.str ();
193  }
194  ExportData_ = rcp (new data_type (source, target, out_, plist));
195  Teuchos::Array<GlobalOrdinal> exportGIDs;
196  setupSamePermuteExport (exportGIDs);
197  if (debug_) {
198  std::ostringstream os;
199  const int myRank = source->getComm ()->getRank ();
200  os << myRank << ": Export ctor: "
201  << "setupSamePermuteExport done" << endl;
202  *out_ << os.str ();
203  }
204  if (source->isDistributed ()) {
205  setupRemote (exportGIDs);
206  }
207  if (debug_) {
208  std::ostringstream os;
209  const int myRank = source->getComm ()->getRank ();
210  os << myRank << ": Export ctor: done" << endl;
211  *out_ << os.str ();
212  }
213  if (! out_.is_null ()) {
214  out_->popTab ();
215  }
216  }
217 
218  template <class LocalOrdinal, class GlobalOrdinal, class Node>
220  Export (const Teuchos::RCP<const map_type >& source,
221  const Teuchos::RCP<const map_type >& target,
222  const Teuchos::RCP<Teuchos::FancyOStream>& out,
223  const Teuchos::RCP<Teuchos::ParameterList>& plist) :
224  out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
225  debug_ (tpetraExportDebugDefault)
226  {
227  using Teuchos::rcp;
228  using std::endl;
230 
231  // Read "Debug" parameter from the input ParameterList.
232  bool debug = tpetraExportDebugDefault;
233  if (! plist.is_null ()) {
234  try {
235  debug = plist->get<bool> ("Debug");
236  } catch (Teuchos::Exceptions::InvalidParameter&) {}
237  }
238  debug_ = debug;
239 
240  if (! out_.is_null ()) {
241  out_->pushTab ();
242  }
243  if (debug_) {
244  std::ostringstream os;
245  const int myRank = source->getComm ()->getRank ();
246  os << myRank << ": Export ctor" << endl;
247  *out_ << os.str ();
248  }
249  ExportData_ = rcp (new data_type (source, target, out, plist));
250  Teuchos::Array<GlobalOrdinal> exportGIDs;
251  setupSamePermuteExport (exportGIDs);
252  if (debug_) {
253  std::ostringstream os;
254  const int myRank = source->getComm ()->getRank ();
255  os << myRank << ": Export ctor: "
256  << "setupSamePermuteExport done" << endl;
257  *out_ << os.str ();
258  }
259  if (source->isDistributed ()) {
260  setupRemote (exportGIDs);
261  }
262  if (debug_) {
263  std::ostringstream os;
264  const int myRank = source->getComm ()->getRank ();
265  os << myRank << ": Export ctor: done" << endl;
266  *out_ << os.str ();
267  }
268  if (! out_.is_null ()) {
269  out_->popTab ();
270  }
271  }
272 
273  template <class LocalOrdinal, class GlobalOrdinal, class Node>
276  : ExportData_ (rhs.ExportData_),
277  out_ (rhs.out_),
278  debug_ (rhs.debug_)
279  {
280  using std::endl;
281 
282  if (! out_.is_null ()) {
283  out_->pushTab ();
284  }
285  if (debug_) {
286  std::ostringstream os;
287  const int myRank = getSourceMap ()->getComm ()->getRank ();
288  os << myRank << ": Export copy ctor (done)" << endl;
289  *out_ << os.str ();
290  }
291  if (! out_.is_null ()) {
292  out_->popTab ();
293  }
294  }
295 
296  template <class LocalOrdinal, class GlobalOrdinal, class Node>
299  : out_ (importer.out_)
300  , debug_ (importer.debug_)
301  {
302  if(!importer.ImportData_.is_null()) ExportData_ = importer.ImportData_->reverseClone();
303  }
304 
305  template <class LocalOrdinal, class GlobalOrdinal, class Node>
307  {}
308 
309  template <class LocalOrdinal, class GlobalOrdinal, class Node>
311  return ExportData_->numSameIDs_;
312  }
313 
314  template <class LocalOrdinal, class GlobalOrdinal, class Node>
316  return ExportData_->permuteFromLIDs_.size();
317  }
318 
319  template <class LocalOrdinal, class GlobalOrdinal, class Node>
320  Teuchos::ArrayView<const LocalOrdinal>
322  return ExportData_->permuteFromLIDs_();
323  }
324 
325  template <class LocalOrdinal, class GlobalOrdinal, class Node>
326  Teuchos::ArrayView<const LocalOrdinal>
328  return ExportData_->permuteToLIDs_();
329  }
330 
331  template <class LocalOrdinal, class GlobalOrdinal, class Node>
333  return ExportData_->remoteLIDs_.size();
334  }
335 
336  template <class LocalOrdinal, class GlobalOrdinal, class Node>
337  Teuchos::ArrayView<const LocalOrdinal>
339  return ExportData_->remoteLIDs_();
340  }
341 
342  template <class LocalOrdinal, class GlobalOrdinal, class Node>
344  return ExportData_->exportLIDs_.size();
345  }
346 
347  template <class LocalOrdinal, class GlobalOrdinal, class Node>
348  Teuchos::ArrayView<const LocalOrdinal>
350  return ExportData_->exportLIDs_();
351  }
352 
353  template <class LocalOrdinal, class GlobalOrdinal, class Node>
354  Teuchos::ArrayView<const int>
356  return ExportData_->exportPIDs_();
357  }
358 
359  template <class LocalOrdinal, class GlobalOrdinal, class Node>
360  Teuchos::RCP<const typename Export<LocalOrdinal,GlobalOrdinal,Node>::map_type>
362  return ExportData_->source_;
363  }
364 
365  template <class LocalOrdinal, class GlobalOrdinal, class Node>
366  Teuchos::RCP<const typename Export<LocalOrdinal,GlobalOrdinal,Node>::map_type>
368  return ExportData_->target_;
369  }
370 
371  template <class LocalOrdinal, class GlobalOrdinal, class Node>
372  Distributor &
374  return ExportData_->distributor_;
375  }
376 
377  template <class LocalOrdinal, class GlobalOrdinal, class Node>
378  bool
380  return ExportData_->isLocallyComplete_;
381  }
382 
383  template <class LocalOrdinal, class GlobalOrdinal, class Node>
387  if (&rhs != this) {
388  ExportData_ = rhs.ExportData_;
389  }
390  return *this;
391  }
392 
393  template <class LocalOrdinal, class GlobalOrdinal, class Node>
394  void
396  describe (Teuchos::FancyOStream& out,
397  const Teuchos::EVerbosityLevel verbLevel) const
398  {
399  // Call the base class' method. It does all the work.
400  this->describeImpl (out, "Tpetra::Export", verbLevel);
401  }
402 
403  template <class LocalOrdinal, class GlobalOrdinal, class Node>
405  print (std::ostream& os) const
406  {
407  auto out = Teuchos::getFancyOStream (Teuchos::rcpFromRef (os));
408  // "Print" traditionally meant "everything."
409  this->describe (*out, Teuchos::VERB_EXTREME);
410  }
411 
412  template <class LocalOrdinal, class GlobalOrdinal, class Node>
413  void
415  setupSamePermuteExport (Teuchos::Array<GlobalOrdinal>& exportGIDs)
416  {
417  using Teuchos::arcp;
418  using Teuchos::Array;
419  using Teuchos::ArrayRCP;
420  using Teuchos::ArrayView;
421  using Teuchos::as;
422  using Teuchos::null;
423  typedef LocalOrdinal LO;
424  typedef GlobalOrdinal GO;
425  typedef typename ArrayView<const GO>::size_type size_type;
426  const char tfecfFuncName[] = "setupExport: ";
427 
428  const map_type& source = * (getSourceMap ());
429  const map_type& target = * (getTargetMap ());
430  ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
431  ArrayView<const GO> targetGIDs = target.getNodeElementList ();
432 
433 #ifdef HAVE_TPETRA_DEBUG
434  ArrayView<const GO> rawSrcGids = sourceGIDs;
435  ArrayView<const GO> rawTgtGids = targetGIDs;
436 #else
437  const GO* const rawSrcGids = sourceGIDs.getRawPtr ();
438  const GO* const rawTgtGids = targetGIDs.getRawPtr ();
439 #endif // HAVE_TPETRA_DEBUG
440  const size_type numSrcGids = sourceGIDs.size ();
441  const size_type numTgtGids = targetGIDs.size ();
442  const size_type numGids = std::min (numSrcGids, numTgtGids);
443 
444  // Compute numSameIDs_: the number of initial GIDs that are the
445  // same (and occur in the same order) in both Maps. The point of
446  // numSameIDs_ is for the common case of an Export where all the
447  // overlapping GIDs are at the end of the source Map, but
448  // otherwise the source and target Maps are the same. This allows
449  // a fast contiguous copy for the initial "same IDs."
450  size_type numSameGids = 0;
451  for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids)
452  {} // third clause of 'for' does everything
453  ExportData_->numSameIDs_ = numSameGids;
454 
455  // Compute permuteToLIDs_, permuteFromLIDs_, exportGIDs, and
456  // exportLIDs_. The first two arrays are IDs to be permuted, and
457  // the latter two arrays are IDs to sent out ("exported"), called
458  // "export" IDs.
459  //
460  // IDs to permute are in both the source and target Maps, which
461  // means we don't have to send or receive them, but we do have to
462  // rearrange (permute) them in general. IDs to send are in the
463  // source Map, but not in the target Map.
464 
465  exportGIDs.resize (0);
466  Array<LO>& permuteToLIDs = ExportData_->permuteToLIDs_;
467  Array<LO>& permuteFromLIDs = ExportData_->permuteFromLIDs_;
468  Array<LO>& exportLIDs = ExportData_->exportLIDs_;
469  const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
470  const LO numSrcLids = as<LO> (numSrcGids);
471  // Iterate over the source Map's LIDs, since we only need to do
472  // GID -> LID lookups for the target Map.
473  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
474  const GO curSrcGid = rawSrcGids[srcLid];
475  // getLocalElement() returns LINVALID if the GID isn't in the target Map.
476  // This saves us a lookup (which isNodeGlobalElement() would do).
477  const LO tgtLid = target.getLocalElement (curSrcGid);
478  if (tgtLid != LINVALID) { // if target.isNodeGlobalElement (curSrcGid)
479  permuteToLIDs.push_back (tgtLid);
480  permuteFromLIDs.push_back (srcLid);
481  } else {
482  exportGIDs.push_back (curSrcGid);
483  exportLIDs.push_back (srcLid);
484  }
485  }
486 
487  // exportLIDs_ is the list of this process' LIDs that it has to
488  // send out. Since this is an Export, and therefore the target
489  // Map is nonoverlapping, we know that each export LID only needs
490  // to be sent to one process. However, the source Map may be
491  // overlapping, so multiple processes might send to the same LID
492  // on a receiving process.
493 
494  if (exportLIDs.size () != 0 && ! source.isDistributed ()) {
495  // This Export has export LIDs, meaning that the source Map has
496  // entries on this process that are not in the target Map on
497  // this process. However, the source Map is not distributed
498  // globally. This implies that this Import is not locally
499  // complete on this process.
500  ExportData_->isLocallyComplete_ = false;
501  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
502  // correct behavior, depending on the circumstances.
504  (true, std::runtime_error, "::setupSamePermuteExport(): Source has "
505  "export LIDs but Source is not distributed globally. Exporting to "
506  "a submap of the target map.");
507  }
508 
509  // Compute exportPIDs_ ("outgoing" process IDs).
510  //
511  // For each GID in exportGIDs (GIDs to which this process must
512  // send), find its corresponding owning process (a.k.a. "image")
513  // ID in the target Map. Store these process IDs in
514  // exportPIDs_. These are the process IDs to which the Export
515  // needs to send data.
516  //
517  // We only need to do this if the source Map is distributed;
518  // otherwise, the Export doesn't have to perform any
519  // communication.
520  if (source.isDistributed ()) {
521  ExportData_->exportPIDs_.resize(exportGIDs.size ());
522  // This call will assign any GID in the target Map with no
523  // corresponding process ID a fake process ID of -1. We'll use
524  // this below to remove exports for processses that don't exist.
525  const LookupStatus lookup =
526  target.getRemoteIndexList (exportGIDs(),
527  ExportData_->exportPIDs_ ());
528  // mfh 12 Sep 2016: I disagree that this is "abuse"; it may be
529  // correct behavior, depending on the circumstances.
530  TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error,
531  "::setupSamePermuteExport(): The source Map has GIDs not found "
532  "in the target Map.");
533 
534  // Get rid of process IDs not in the target Map. This prevents
535  // exporting to GIDs which don't belong to any process in the
536  // target Map.
537  if (lookup == IDNotPresent) {
538  // There is at least one GID owned by the calling process in
539  // the source Map, which is not owned by any process in the
540  // target Map.
541  ExportData_->isLocallyComplete_ = false;
542 
543  const size_type numInvalidExports =
544  std::count_if (ExportData_->exportPIDs_().begin(),
545  ExportData_->exportPIDs_().end(),
546  std::bind1st (std::equal_to<int>(), -1));
547  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
548  (numInvalidExports == 0, std::logic_error, "Calling getRemoteIndexList "
549  "on the target Map returned IDNotPresent, but none of the returned "
550  "\"export\" process ranks are -1. Please report this bug to the "
551  "Tpetra developers.");
552 
553  // count number of valid and total number of exports
554  const size_type totalNumExports = ExportData_->exportPIDs_.size();
555  if (numInvalidExports == totalNumExports) {
556  // all exports are invalid; we have no exports; we can delete all exports
557  exportGIDs.resize(0);
558  ExportData_->exportLIDs_.resize(0);
559  ExportData_->exportPIDs_.resize(0);
560  }
561  else {
562  // some exports are valid; we need to keep the valid exports
563  // pack and resize
564  size_type numValidExports = 0;
565  for (size_type e = 0; e < totalNumExports; ++e) {
566  if (ExportData_->exportPIDs_[e] != -1) {
567  exportGIDs[numValidExports] = exportGIDs[e];
568  ExportData_->exportLIDs_[numValidExports] = ExportData_->exportLIDs_[e];
569  ExportData_->exportPIDs_[numValidExports] = ExportData_->exportPIDs_[e];
570  ++numValidExports;
571  }
572  }
573  exportGIDs.resize (numValidExports);
574  ExportData_->exportLIDs_.resize (numValidExports);
575  ExportData_->exportPIDs_.resize (numValidExports);
576  }
577  }
578  }
579  } // setupSamePermuteExport()
580 
581  template <class LocalOrdinal, class GlobalOrdinal, class Node>
582  void
583  Export<LocalOrdinal,GlobalOrdinal,Node>::setupRemote(Teuchos::Array<GlobalOrdinal> & exportGIDs)
584  {
585  using Teuchos::Array;
586  using std::endl;
587 
588  const map_type& target = * (getTargetMap ());
589  const int myRank = target.getComm ()->getRank ();
590 
591  if (! out_.is_null ()) {
592  out_->pushTab ();
593  }
594  if (debug_) {
595  std::ostringstream os;
596  os << myRank << ": Export::setupRemote" << endl;
597  *out_ << os.str ();
598  }
599  if (! out_.is_null ()) {
600  out_->pushTab ();
601  }
602 
603  // Sort exportPIDs_ in ascending order, and apply the same
604  // permutation to exportGIDs_ and exportLIDs_. This ensures that
605  // exportPIDs_[i], exportGIDs_[i], and exportLIDs_[i] all
606  // refer to the same thing.
607  sort3 (ExportData_->exportPIDs_.begin(),
608  ExportData_->exportPIDs_.end(),
609  exportGIDs.begin(),
610  ExportData_->exportLIDs_.begin());
611 
612  if (debug_) {
613  std::ostringstream os;
614  os << myRank << ": Export::setupRemote: Calling createFromSends" << endl;
615  *out_ << os.str ();
616  }
617 
618  // Construct the list of entries that calling image needs to send
619  // as a result of everyone asking for what it needs to receive.
620  //
621  // mfh 05 Jan 2012: I understand the above comment as follows:
622  // Construct the communication plan from the list of image IDs to
623  // which we need to send.
624  size_t numRemoteIDs;
625  numRemoteIDs = ExportData_->distributor_.createFromSends (ExportData_->exportPIDs_ ());
626 
627  if (debug_) {
628  std::ostringstream os;
629  os << myRank << ": Export::setupRemote: Calling doPostsAndWaits" << endl;
630  *out_ << os.str ();
631  }
632 
633  // Use the communication plan with ExportGIDs to find out who is
634  // sending to us and get the proper ordering of GIDs for incoming
635  // remote entries (these will be converted to LIDs when done).
636  Array<GlobalOrdinal> remoteGIDs (numRemoteIDs);
637  ExportData_->distributor_.doPostsAndWaits (exportGIDs().getConst (), 1, remoteGIDs());
638 
639  // Remote (incoming) IDs come in as GIDs; convert to LIDs. LIDs
640  // tell this process where to store the incoming remote data.
641  ExportData_->remoteLIDs_.resize (numRemoteIDs);
642  {
643  typename Array<GlobalOrdinal>::const_iterator i = remoteGIDs.begin();
644  typename Array<LocalOrdinal>::iterator j = ExportData_->remoteLIDs_.begin();
645  while (i != remoteGIDs.end()) {
646  *j++ = target.getLocalElement(*i++);
647  }
648  }
649 
650  if (! out_.is_null ()) {
651  out_->popTab ();
652  }
653  if (debug_) {
654  std::ostringstream os;
655  os << myRank << ": Export::setupRemote: done" << endl;
656  *out_ << os.str ();
657  }
658  if (! out_.is_null ()) {
659  out_->popTab ();
660  }
661  }
662 
663 } // namespace Tpetra
664 
665 // Explicit instantiation macro.
666 // Only invoke this when in the Tpetra namespace.
667 // Most users do not need to use this.
668 //
669 // LO: The local ordinal type.
670 // GO: The global ordinal type.
671 // NODE: The Kokkos Node type.
672 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
673  \
674  template class Export< LO , GO , NODE >;
675 
676 #endif // TPETRA_EXPORT_DEF_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Distributor & getDistributor() const
The Distributor that this Export object uses to move data.
size_t getNumSameIDs() const
Number of initial identical IDs.
size_t getNumExportIDs() const
Number of entries that must be sent by the calling process to other processes.
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.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
bool isLocallyComplete() const
Do all source Map indices on the calling process exist on at least one process (not necessarily this ...
size_t getNumPermuteIDs() const
Number of IDs to permute but not to communicate.
Teuchos::ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent.
Teuchos::ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
Teuchos::RCP< const map_type > getSourceMap() const
The source Map used to construct this Export.
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.
Export< LocalOrdinal, GlobalOrdinal, Node > & operator=(const Export< LocalOrdinal, GlobalOrdinal, Node > &rhs)
Assignment operator.
Teuchos::ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
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...
Implementation detail of Import and Export.
Sets up and executes a communication plan for a Tpetra DistObject.
Stand-alone utility functions and macros.
virtual void print(std::ostream &os) const
Print the Export&#39;s data to the given output stream.
virtual ~Export()
Destructor.
Teuchos::ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set parameters.
Teuchos::RCP< const map_type > getTargetMap() const
The target Map used to construct this Export.
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.