10#ifndef TPETRA_EXPORT_DEF_HPP 
   11#define TPETRA_EXPORT_DEF_HPP 
   13#include "Tpetra_Distributor.hpp" 
   14#include "Tpetra_Map.hpp" 
   15#include "Tpetra_ImportExportData.hpp" 
   17#include "Tpetra_Import.hpp" 
   18#include "Tpetra_Details_DualViewUtil.hpp" 
   20#include "Teuchos_as.hpp" 
   21#include "Teuchos_Array.hpp" 
   22#include "Teuchos_FancyOStream.hpp" 
   23#include "Teuchos_ParameterList.hpp" 
   28template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   31           const Teuchos::RCP<const map_type>& 
target,
 
   32           const Teuchos::RCP<Teuchos::FancyOStream>& 
out,
 
   33           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
   37  using ::Tpetra::Details::ProfilingRegion;
 
   41    std::ostringstream 
os;
 
   48  if (
source->isDistributed()) {
 
   61  this->detectRemoteExportLIDsContiguous();
 
   64    std::ostringstream 
os;
 
 
   71template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   74           const Teuchos::RCP<const map_type>& 
target)
 
 
   77template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   80           const Teuchos::RCP<const map_type>& 
target,
 
   81           const Teuchos::RCP<Teuchos::FancyOStream>& 
out)
 
 
   84template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   87           const Teuchos::RCP<const map_type>& 
target,
 
   88           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
 
   91template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   96template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  101template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  104             const Teuchos::EVerbosityLevel 
verbLevel)
 const {
 
 
  109template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  111    print(std::ostream& 
os)
 const {
 
  112  auto out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(
os));
 
  114  this->describe(*
out, Teuchos::VERB_EXTREME);
 
 
  117template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  122  using Teuchos::Array;
 
  123  using Teuchos::ArrayRCP;
 
  124  using Teuchos::ArrayView;
 
  127  using ::Tpetra::Details::makeDualViewFromOwningHostView;
 
  128  using ::Tpetra::Details::ProfilingRegion;
 
  129  using ::Tpetra::Details::view_alloc_no_init;
 
  134  ProfilingRegion 
regionExport(
"Tpetra::Export::setupSamePermuteExport");
 
  136  std::unique_ptr<std::string> 
prefix;
 
  137  if (this->verbose()) {
 
  138    auto srcMap      = this->getSourceMap();
 
  139    auto comm        = 
srcMap.is_null() ? Teuchos::null : 
srcMap->getComm();
 
  140    const int myRank = comm.is_null() ? -1 : comm->getRank();
 
  142    std::ostringstream 
os;
 
  143    os << 
"Proc " << 
myRank << 
": Tpetra::Export::setupSamePermuteExport: ";
 
  144    prefix = std::unique_ptr<std::string>(
new std::string(
os.str()));
 
  146    std::ostringstream 
os2;
 
  148    this->verboseOutputStream() << 
os2.str();
 
  151  const map_type& source         = *(this->getSourceMap());
 
  152  const map_type& target         = *(this->getTargetMap());
 
  153  ArrayView<const GO> sourceGIDs = source.getLocalElementList();
 
  154  ArrayView<const GO> targetGIDs = target.getLocalElementList();
 
  156#ifdef HAVE_TPETRA_DEBUG 
  157  ArrayView<const GO> rawSrcGids = sourceGIDs;
 
  158  ArrayView<const GO> rawTgtGids = targetGIDs;
 
  160  const GO* 
const rawSrcGids = sourceGIDs.getRawPtr();
 
  161  const GO* 
const rawTgtGids = targetGIDs.getRawPtr();
 
  163  const size_type numSrcGids = sourceGIDs.size();
 
  164  const size_type numTgtGids = targetGIDs.size();
 
  165  const size_type numGids    = std::min(numSrcGids, numTgtGids);
 
  173  size_type numSameGids = 0;
 
  174  for (; numSameGids < numGids &&
 
  175         rawSrcGids[numSameGids] == rawTgtGids[numSameGids];
 
  178  this->TransferData_->numSameIDs_ = numSameGids;
 
  180  if (this->verbose()) {
 
  181    std::ostringstream os;
 
  182    os << *prefix << 
"numIDs: " << numGids
 
  183       << 
", numSameIDs: " << numSameGids << endl;
 
  184    this->verboseOutputStream() << os.str();
 
  199  const LO LINVALID   = Teuchos::OrdinalTraits<LO>::invalid();
 
  200  const LO numSrcLids = 
static_cast<LO
>(numSrcGids);
 
  204  for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
 
  205    const GO curSrcGid = rawSrcGids[srcLid];
 
  209    const LO tgtLid = target.getLocalElement(curSrcGid);
 
  210    if (tgtLid != LINVALID) {  
 
  216  if (this->verbose()) {
 
  217    std::ostringstream os;
 
  218    os << *prefix << 
"numPermutes: " << numPermutes
 
  219       << 
", numExports: " << numExports << endl;
 
  220    this->verboseOutputStream() << os.str();
 
  222  TEUCHOS_ASSERT(numPermutes + numExports ==
 
  223                 numSrcLids - numSameGids);
 
  225  typename decltype(this->TransferData_->permuteToLIDs_)::t_host
 
  227  typename decltype(this->TransferData_->permuteToLIDs_)::t_host
 
  229  typename decltype(this->TransferData_->permuteToLIDs_)::t_host
 
  234  exportGIDs.resize(numExports);
 
  239    for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) {
 
  240      const GO curSrcGid = rawSrcGids[srcLid];
 
  241      const LO tgtLid    = target.getLocalElement(curSrcGid);
 
  242      if (tgtLid != LINVALID) {
 
  243        permuteToLIDs[numPermutes2]   = tgtLid;
 
  244        permuteFromLIDs[numPermutes2] = srcLid;
 
  247        exportGIDs[numExports2] = curSrcGid;
 
  248        exportLIDs[numExports2] = srcLid;
 
  252    TEUCHOS_ASSERT(numPermutes == numPermutes2);
 
  253    TEUCHOS_ASSERT(numExports == numExports2);
 
  254    TEUCHOS_ASSERT(
size_t(numExports) == 
size_t(exportGIDs.size()));
 
  267  if (numExports != 0 && !source.isDistributed()) {
 
  273    this->TransferData_->isLocallyComplete_ = 
false;
 
  274    if (this->verbose()) {
 
  275      std::ostringstream os;
 
  276      os << *prefix << 
"Export is not locally complete" << endl;
 
  277      this->verboseOutputStream() << os.str();
 
  282                         "::setupSamePermuteExport(): Source has " 
  283                         "export LIDs but Source is not distributed globally.  Exporting to " 
  284                         "a submap of the target map.");
 
  298  if (source.isDistributed()) {
 
  299    if (this->verbose()) {
 
  300      std::ostringstream os;
 
  301      os << *prefix << 
"Source Map is distributed; " 
  302                       "call targetMap.getRemoteiNdexList" 
  304      this->verboseOutputStream() << os.str();
 
  306    this->TransferData_->exportPIDs_.resize(exportGIDs.size());
 
  311        target.getRemoteIndexList(exportGIDs(),
 
  312                                  this->TransferData_->exportPIDs_());
 
  316                         "::setupSamePermuteExport(): The source Map has GIDs not found " 
  317                         "in the target Map.");
 
  326      this->TransferData_->isLocallyComplete_ = 
false;
 
  328      Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
 
  330      const size_type totalNumExports = exportPIDs.size();
 
  331      const size_type numInvalidExports =
 
  332          std::count_if(exportPIDs.begin(), exportPIDs.end(),
 
  333                        [](
const int procId) { return procId == -1; });
 
  334      if (this->verbose()) {
 
  335        std::ostringstream os;
 
  336        os << *prefix << 
"totalNumExports: " << totalNumExports
 
  337           << 
", numInvalidExports: " << numInvalidExports << endl;
 
  338        this->verboseOutputStream() << os.str();
 
  340      TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(numInvalidExports == 0, std::logic_error,
 
  341                                            "targetMap.getRemoteIndexList returned IDNotPresent, but no export " 
  342                                            "PIDs are -1.  Please report this bug to the Tpetra developers.");
 
  350      if (numInvalidExports == totalNumExports) {
 
  351        exportGIDs.resize(0);
 
  352        exportLIDs = 
decltype(exportLIDs)();
 
  353        exportPIDs.resize(0);
 
  355        size_type numValidExports = 0;
 
  356        for (size_type e = 0; e < totalNumExports; ++e) {
 
  357          if (this->TransferData_->exportPIDs_[e] != -1) {
 
  358            exportGIDs[numValidExports] = exportGIDs[e];
 
  359            exportLIDs[numValidExports] = exportLIDs[e];
 
  360            exportPIDs[numValidExports] = exportPIDs[e];
 
  364        exportGIDs.resize(numValidExports);
 
  365        Kokkos::resize(exportLIDs, numValidExports);
 
  366        exportPIDs.resize(numValidExports);
 
  378  if (this->verbose()) {
 
  379    std::ostringstream os;
 
  380    os << *prefix << 
"Done!" << std::endl;
 
  381    this->verboseOutputStream() << os.str();
 
  385template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  386void Export<LocalOrdinal, GlobalOrdinal, Node>::
 
  387    setupRemote(Teuchos::Array<GlobalOrdinal>& exportGIDs) {
 
  389  using Teuchos::Array;
 
  390  using ::Tpetra::Details::makeDualViewFromOwningHostView;
 
  391  using ::Tpetra::Details::view_alloc_no_init;
 
  392  using LO = LocalOrdinal;
 
  393  using GO = GlobalOrdinal;
 
  395  std::unique_ptr<std::string> prefix;
 
  396  if (this->verbose()) {
 
  397    auto srcMap      = this->getSourceMap();
 
  398    auto comm        = srcMap.is_null() ? Teuchos::null : srcMap->getComm();
 
  399    const int myRank = comm.is_null() ? -1 : comm->getRank();
 
  401    std::ostringstream os;
 
  402    os << 
"Proc " << myRank << 
": Tpetra::Export::setupRemote: ";
 
  403    prefix = std::unique_ptr<std::string>(
new std::string(os.str()));
 
  405    std::ostringstream os2;
 
  406    os2 << *prefix << 
"Start" << std::endl;
 
  407    this->verboseOutputStream() << os2.str();
 
  410  TEUCHOS_ASSERT(!this->getTargetMap().is_null());
 
  411  const map_type& tgtMap = *(this->getTargetMap());
 
  418    TEUCHOS_ASSERT(
size_t(this->TransferData_->exportLIDs_.extent(0)) ==
 
  419                   size_t(this->TransferData_->exportPIDs_.size()));
 
  420    this->TransferData_->exportLIDs_.modify_host();
 
  421    auto exportLIDs = this->TransferData_->exportLIDs_.view_host();
 
  422    sort3(this->TransferData_->exportPIDs_.begin(),
 
  423          this->TransferData_->exportPIDs_.end(),
 
  424          exportGIDs.getRawPtr(),
 
  426    this->TransferData_->exportLIDs_.sync_device();
 
  432  if (this->verbose()) {
 
  433    std::ostringstream os;
 
  434    os << *prefix << 
"Call createFromSends" << endl;
 
  435    this->verboseOutputStream() << os.str();
 
  444  Teuchos::Array<int>& exportPIDs = this->TransferData_->exportPIDs_;
 
  445  Distributor& distributor        = this->TransferData_->distributor_;
 
  446  const size_t numRemoteIDs       = distributor.createFromSends(exportPIDs());
 
  448  if (this->verbose()) {
 
  449    std::ostringstream os;
 
  450    os << *prefix << 
"numRemoteIDs: " << numRemoteIDs
 
  451       << 
"; call doPostsAndWaits" << endl;
 
  452    this->verboseOutputStream() << os.str();
 
  459  Kokkos::View<const GO*, Kokkos::HostSpace> exportGIDsConst(exportGIDs.data(), exportGIDs.size());
 
  460  Kokkos::View<GO*, Kokkos::HostSpace> remoteGIDs(
"remoteGIDs", numRemoteIDs);
 
  461  distributor.doPostsAndWaits(exportGIDsConst, 1, remoteGIDs);
 
  465  using host_remote_lids_type =
 
  466      typename decltype(this->TransferData_->remoteLIDs_)::t_host;
 
  469  for (LO j = 0; j < LO(numRemoteIDs); ++j) {
 
  470    remoteLIDs[j] = tgtMap.getLocalElement(remoteGIDs[j]);
 
  474  if (this->verbose()) {
 
  475    std::ostringstream os;
 
  476    os << *prefix << 
"Done!" << endl;
 
  477    this->verboseOutputStream() << os.str();
 
  490#define TPETRA_EXPORT_INSTANT(LO, GO, NODE) \ 
  491  template class Export<LO, GO, NODE>; 
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
 
Stand-alone utility functions and macros.
 
#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...
 
Struct that holds views of the contents of a CrsMatrix.
 
bool verbose() const
Whether to print verbose debugging output.
 
Teuchos::RCP< ImportExportData< LocalOrdinal, GlobalOrdinal, Node > > TransferData_
All the data needed for executing the Export communication plan.
 
Teuchos::FancyOStream & verboseOutputStream() const
Valid (nonnull) output stream for verbose output.
 
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
 
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.
 
virtual void print(std::ostream &os) const
Print the Export's data 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) -> decltype(Kokkos::view_alloc(label, Kokkos::WithoutInitializing))
Use in place of the string label as the first argument of Kokkos::View's constructor,...
 
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.
 
Namespace Tpetra contains the class and methods constituting the Tpetra library.
 
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
 
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3, const bool stableSort=false)
Sort the first array, and apply the same permutation to the second and third arrays.