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