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
62  Export<LocalOrdinal,GlobalOrdinal,Node>::
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 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 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  ArrayView<const LocalOrdinal>
322  return ExportData_->permuteFromLIDs_();
323  }
324 
325  template <class LocalOrdinal, class GlobalOrdinal, class Node>
326  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  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  ArrayView<const LocalOrdinal>
350  return ExportData_->exportLIDs_();
351  }
352 
353  template <class LocalOrdinal, class GlobalOrdinal, class Node>
354  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>
381  if (&rhs != this) {
382  ExportData_ = rhs.ExportData_;
383  }
384  return *this;
385  }
386 
387  template <class LocalOrdinal, class GlobalOrdinal, class Node>
389  print (std::ostream& os) const
390  {
391  using Teuchos::Comm;
392  using Teuchos::getFancyOStream;
393  using Teuchos::RCP;
394  using Teuchos::rcpFromRef;
395  using Teuchos::toString;
396  using std::endl;
397 
398  RCP<const Comm<int> > comm = getSourceMap ()->getComm ();
399  const int myImageID = comm->getRank ();
400  const int numImages = comm->getSize ();
401  for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
402  if (myImageID == imageCtr) {
403  os << endl;
404  if (myImageID == 0) { // I'm the root node (only output this info once)
405  os << "Export Data Members:" << endl;
406  }
407  os << "Image ID : " << myImageID << endl;
408 
409  os << "permuteFromLIDs: " << toString (getPermuteFromLIDs ()) << endl;
410  os << "permuteToLIDs : " << toString (getPermuteToLIDs ()) << endl;
411  os << "remoteLIDs : " << toString (getRemoteLIDs ()) << endl;
412  os << "exportLIDs : " << toString (getExportLIDs ()) << endl;
413  os << "exportPIDs : " << toString (getExportPIDs ()) << endl;
414 
415  os << "numSameIDs : " << getNumSameIDs () << endl;
416  os << "numPermuteIDs : " << getNumPermuteIDs () << endl;
417  os << "numRemoteIDs : " << getNumRemoteIDs () << endl;
418  os << "numExportIDs : " << getNumExportIDs () << endl;
419  }
420  // A few global barriers give output a chance to complete.
421  comm->barrier();
422  comm->barrier();
423  comm->barrier();
424  }
425  if (myImageID == 0) {
426  os << endl << endl << "Source Map:" << endl << std::flush;
427  }
428  comm->barrier();
429  os << *getSourceMap();
430  comm->barrier();
431 
432  if (myImageID == 0) {
433  os << endl << endl << "Target Map:" << endl << std::flush;
434  }
435  comm->barrier();
436  os << *getTargetMap();
437  comm->barrier();
438 
439  // It's also helpful for debugging to print the Distributor
440  // object. Epetra_Export::Print() does this, so we can do a
441  // side-by-side comparison.
442  if (myImageID == 0) {
443  os << endl << endl << "Distributor:" << endl << std::flush;
444  }
445  comm->barrier();
446  getDistributor().describe (*(getFancyOStream (rcpFromRef (os))),
447  Teuchos::VERB_EXTREME);
448  }
449 
450 
451  template <class LocalOrdinal, class GlobalOrdinal, class Node>
452  void
454  setupSamePermuteExport (Teuchos::Array<GlobalOrdinal>& exportGIDs)
455  {
456  using Teuchos::arcp;
457  using Teuchos::Array;
458  using Teuchos::ArrayRCP;
459  using Teuchos::ArrayView;
460  using Teuchos::as;
461  using Teuchos::null;
462  typedef LocalOrdinal LO;
463  typedef GlobalOrdinal GO;
464  typedef typename ArrayView<const GO>::size_type size_type;
465  const map_type& source = * (getSourceMap ());
466  const map_type& target = * (getTargetMap ());
467  ArrayView<const GO> sourceGIDs = source.getNodeElementList ();
468  ArrayView<const GO> targetGIDs = target.getNodeElementList ();
469 
470 #ifdef HAVE_TPETRA_DEBUG
471  ArrayView<const GO> rawSrcGids = sourceGIDs;
472  ArrayView<const GO> rawTgtGids = targetGIDs;
473 #else
474  const GO* const rawSrcGids = sourceGIDs.getRawPtr ();
475  const GO* const rawTgtGids = targetGIDs.getRawPtr ();
476 #endif // HAVE_TPETRA_DEBUG
477  const size_type numSrcGids = sourceGIDs.size ();
478  const size_type numTgtGids = targetGIDs.size ();
479  const size_type numGids = std::min (numSrcGids, numTgtGids);
480 
481  // Compute numSameIDs_: the number of initial GIDs that are the
482  // same (and occur in the same order) in both Maps. The point of
483  // numSameIDs_ is for the common case of an Export where all the
484  // overlapping GIDs are at the end of the source Map, but
485  // otherwise the source and target Maps are the same. This allows
486  // a fast contiguous copy for the initial "same IDs."
487  size_type numSameGids = 0;
488  for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids)
489  {} // third clause of 'for' does everything
490  ExportData_->numSameIDs_ = numSameGids;
491 
492  // Compute permuteToLIDs_, permuteFromLIDs_, exportGIDs, and
493  // exportLIDs_. The first two arrays are IDs to be permuted, and
494  // the latter two arrays are IDs to sent out ("exported"), called
495  // "export" IDs.
496  //
497  // IDs to permute are in both the source and target Maps, which
498  // means we don't have to send or receive them, but we do have to
499  // rearrange (permute) them in general. IDs to send are in the
500  // source Map, but not in the target Map.
501 
502  exportGIDs.resize (0);
503  Array<LO>& permuteToLIDs = ExportData_->permuteToLIDs_;
504  Array<LO>& permuteFromLIDs = ExportData_->permuteFromLIDs_;
505  Array<LO>& exportLIDs = ExportData_->exportLIDs_;
506  const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
507  const LO numSrcLids = as<LO> (numSrcGids);
508  // Iterate over the source Map's LIDs, since we only need to do
509  // GID -> LID lookups for the target Map.
510  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
511  const GO curSrcGid = rawSrcGids[srcLid];
512  // getLocalElement() returns LINVALID if the GID isn't in the target Map.
513  // This saves us a lookup (which isNodeGlobalElement() would do).
514  const LO tgtLid = target.getLocalElement (curSrcGid);
515  if (tgtLid != LINVALID) { // if target.isNodeGlobalElement (curSrcGid)
516  permuteToLIDs.push_back (tgtLid);
517  permuteFromLIDs.push_back (srcLid);
518  } else {
519  exportGIDs.push_back (curSrcGid);
520  exportLIDs.push_back (srcLid);
521  }
522  }
523 
524  // exportLIDs_ is the list of this process' LIDs that it has to
525  // send out. Since this is an Export, and therefore the target
526  // Map is nonoverlapping, we know that each export LID only needs
527  // to be sent to one process. However, the source Map may be
528  // overlapping, so multiple processes might send to the same LID
529  // on a receiving process.
530 
532  getNumExportIDs() > 0 && ! source.isDistributed(),
533  std::runtime_error,
534  "::setupSamePermuteExport(): Source has export LIDs but Source is not "
535  "distributed globally." << std::endl
536  << "Exporting to a submap of the target map.");
537 
538  // Compute exportPIDs_ ("outgoing" process IDs).
539  //
540  // For each GID in exportGIDs (GIDs to which this process must
541  // send), find its corresponding owning process (a.k.a. "image")
542  // ID in the target Map. Store these process IDs in
543  // exportPIDs_. These are the process IDs to which the Export
544  // needs to send data.
545  //
546  // We only need to do this if the source Map is distributed;
547  // otherwise, the Export doesn't have to perform any
548  // communication.
549  if (source.isDistributed ()) {
550  ExportData_->exportPIDs_.resize(exportGIDs.size ());
551  // This call will assign any GID in the target Map with no
552  // corresponding process ID a fake process ID of -1. We'll use
553  // this below to remove exports for processses that don't exist.
554  const LookupStatus lookup =
555  target.getRemoteIndexList (exportGIDs(),
556  ExportData_->exportPIDs_ ());
557  TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error,
558  "::setupSamePermuteExport(): The source Map has GIDs not found "
559  "in the target Map.");
560 
561  // Get rid of process IDs not in the target Map. This prevents
562  // exporting to GIDs which don't belong to any process in the
563  // target Map.
564  if (lookup == IDNotPresent) {
565  const size_type numInvalidExports =
566  std::count_if (ExportData_->exportPIDs_().begin(),
567  ExportData_->exportPIDs_().end(),
568  std::bind1st (std::equal_to<int>(), -1));
569 
570  // count number of valid and total number of exports
571  const size_type totalNumExports = ExportData_->exportPIDs_.size();
572  if (numInvalidExports == totalNumExports) {
573  // all exports are invalid; we have no exports; we can delete all exports
574  exportGIDs.resize(0);
575  ExportData_->exportLIDs_.resize(0);
576  ExportData_->exportPIDs_.resize(0);
577  }
578  else {
579  // some exports are valid; we need to keep the valid exports
580  // pack and resize
581  size_type numValidExports = 0;
582  for (size_type e = 0; e < totalNumExports; ++e) {
583  if (ExportData_->exportPIDs_[e] != -1) {
584  exportGIDs[numValidExports] = exportGIDs[e];
585  ExportData_->exportLIDs_[numValidExports] = ExportData_->exportLIDs_[e];
586  ExportData_->exportPIDs_[numValidExports] = ExportData_->exportPIDs_[e];
587  ++numValidExports;
588  }
589  }
590  exportGIDs.resize (numValidExports);
591  ExportData_->exportLIDs_.resize (numValidExports);
592  ExportData_->exportPIDs_.resize (numValidExports);
593  }
594  }
595  }
596  } // setupSamePermuteExport()
597 
598  template <class LocalOrdinal, class GlobalOrdinal, class Node>
599  void
600  Export<LocalOrdinal,GlobalOrdinal,Node>::setupRemote(Teuchos::Array<GlobalOrdinal> & exportGIDs)
601  {
602  using std::endl;
603  const map_type& target = * (getTargetMap ());
604  const int myRank = target.getComm ()->getRank ();
605 
606  if (! out_.is_null ()) {
607  out_->pushTab ();
608  }
609  if (debug_) {
610  std::ostringstream os;
611  os << myRank << ": Export::setupRemote" << endl;
612  *out_ << os.str ();
613  }
614  if (! out_.is_null ()) {
615  out_->pushTab ();
616  }
617 
618  // Sort exportPIDs_ in ascending order, and apply the same
619  // permutation to exportGIDs_ and exportLIDs_. This ensures that
620  // exportPIDs_[i], exportGIDs_[i], and exportLIDs_[i] all
621  // refer to the same thing.
622  sort3 (ExportData_->exportPIDs_.begin(),
623  ExportData_->exportPIDs_.end(),
624  exportGIDs.begin(),
625  ExportData_->exportLIDs_.begin());
626 
627  if (debug_) {
628  std::ostringstream os;
629  os << myRank << ": Export::setupRemote: Calling createFromSends" << endl;
630  *out_ << os.str ();
631  }
632 
633  // Construct the list of entries that calling image needs to send
634  // as a result of everyone asking for what it needs to receive.
635  //
636  // mfh 05 Jan 2012: I understand the above comment as follows:
637  // Construct the communication plan from the list of image IDs to
638  // which we need to send.
639  size_t numRemoteIDs;
640  numRemoteIDs = ExportData_->distributor_.createFromSends (ExportData_->exportPIDs_ ());
641 
642  if (debug_) {
643  std::ostringstream os;
644  os << myRank << ": Export::setupRemote: Calling doPostsAndWaits" << endl;
645  *out_ << os.str ();
646  }
647 
648  // Use the communication plan with ExportGIDs to find out who is
649  // sending to us and get the proper ordering of GIDs for incoming
650  // remote entries (these will be converted to LIDs when done).
651  Array<GlobalOrdinal> remoteGIDs (numRemoteIDs);
652  ExportData_->distributor_.doPostsAndWaits (exportGIDs().getConst (), 1, remoteGIDs());
653 
654  // Remote (incoming) IDs come in as GIDs; convert to LIDs. LIDs
655  // tell this process where to store the incoming remote data.
656  ExportData_->remoteLIDs_.resize (numRemoteIDs);
657  {
658  typename Array<GlobalOrdinal>::const_iterator i = remoteGIDs.begin();
659  typename Array<LocalOrdinal>::iterator j = ExportData_->remoteLIDs_.begin();
660  while (i != remoteGIDs.end()) {
661  *j++ = target.getLocalElement(*i++);
662  }
663  }
664 
665  if (! out_.is_null ()) {
666  out_->popTab ();
667  }
668  if (debug_) {
669  std::ostringstream os;
670  os << myRank << ": Export::setupRemote: done" << endl;
671  *out_ << os.str ();
672  }
673  if (! out_.is_null ()) {
674  out_->popTab ();
675  }
676  }
677 
678 } // namespace Tpetra
679 
680 // Explicit instantiation macro.
681 // Only invoke this when in the Tpetra namespace.
682 // Most users do not need to use this.
683 //
684 // LO: The local ordinal type.
685 // GO: The global ordinal type.
686 // NODE: The Kokkos Node type.
687 #define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \
688  \
689  template class Export< LO , GO , NODE >;
690 
691 #endif // TPETRA_EXPORT_DEF_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::RCP< const map_type > getSourceMap() const
The source Map used to construct this Export.
ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent.
virtual void print(std::ostream &os) const
Print the Export&#39;s data to the given output stream.
size_t getNumSameIDs() const
Number of initial identical IDs.
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.
size_t getNumPermuteIDs() const
Number of IDs to permute but not to communicate.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
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.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
size_t getNumExportIDs() const
Number of entries that must be sent by the calling process to other processes.
#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.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
Teuchos::RCP< const map_type > getTargetMap() const
The target Map used to construct this Export.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
Describes a parallel distribution of objects over processes.
ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
Stand-alone utility functions and macros.
Distributor & getDistributor() const
The Distributor that this Export object uses to move data.
virtual ~Export()
Destructor.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream.