10#ifndef TPETRA_IMPORT_DEF_HPP 
   11#define TPETRA_IMPORT_DEF_HPP 
   13#include "Tpetra_Distributor.hpp" 
   14#include "Tpetra_Map.hpp" 
   15#include "Tpetra_ImportExportData.hpp" 
   18#include "Tpetra_Export.hpp" 
   20#include "Tpetra_Details_DualViewUtil.hpp" 
   23#include "Teuchos_as.hpp" 
   24#ifdef HAVE_TPETRA_MMM_TIMINGS 
   25#include "Teuchos_TimeMonitor.hpp" 
   32std::string toString(
const std::vector<T>& x) {
 
   33  std::ostringstream os;
 
   35  const std::size_t N = x.size();
 
   36  for (std::size_t k = 0; k < N; ++k) {
 
   38    if (k + std::size_t(1) < N) {
 
   46template <
class ElementType, 
class DeviceType>
 
   47std::string toString(
const Kokkos::View<const ElementType*, DeviceType>& x) {
 
   48  std::ostringstream os;
 
   50  const std::size_t N = std::size_t(x.extent(0));
 
   51  for (std::size_t k = 0; k < N; ++k) {
 
   53    if (k + std::size_t(1) < N) {
 
   66template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   67void Import<LocalOrdinal, GlobalOrdinal, Node>::
 
   68    init(
const Teuchos::RCP<const map_type>& source,
 
   69         const Teuchos::RCP<const map_type>& ,
 
   71         Teuchos::Array<int>& remotePIDs,
 
   72         const Teuchos::RCP<Teuchos::ParameterList>& plist) {
 
   78  using ::Tpetra::Details::ProfilingRegion;
 
   79  ProfilingRegion regionImportInit(
"Tpetra::Import::init");
 
   81  std::unique_ptr<std::string> verbPrefix;
 
   82  if (this->verbose()) {
 
   83    std::ostringstream os;
 
   84    const int myRank = source->getComm()->getRank();
 
   85    os << 
"Proc " << myRank << 
": Tpetra::Import::init: ";
 
   86    verbPrefix = std::unique_ptr<std::string>(
new std::string(os.str()));
 
   88    this->verboseOutputStream() << os.str();
 
   91  Array<GlobalOrdinal> remoteGIDs;
 
   93#ifdef HAVE_TPETRA_MMM_TIMINGS 
   94  using Teuchos::TimeMonitor;
 
   97    label = plist->get(
"Timer Label", label);
 
   98  std::string prefix = std::string(
"Tpetra ") + label + std::string(
":iport_ctor:preIData: ");
 
  103#ifdef HAVE_TPETRA_MMM_TIMINGS 
  104    auto MM(*TimeMonitor::getNewTimer(prefix));
 
  106    if (this->verbose()) {
 
  107      std::ostringstream os;
 
  108      os << *verbPrefix << 
"Call setupSamePermuteRemote" << endl;
 
  109      this->verboseOutputStream() << os.str();
 
  111    setupSamePermuteRemote(remoteGIDs);
 
  114#ifdef HAVE_TPETRA_MMM_TIMINGS 
  115    prefix = std::string(
"Tpetra ") + label + std::string(
":iport_ctor:preSetupExport: ");
 
  116    auto MM2(*TimeMonitor::getNewTimer(prefix));
 
  118    if (source->isDistributed()) {
 
  119      if (this->verbose()) {
 
  120        std::ostringstream os;
 
  121        os << *verbPrefix << 
"Call setupExport" << endl;
 
  122        this->verboseOutputStream() << os.str();
 
  124      setupExport(remoteGIDs, useRemotePIDs, remotePIDs);
 
  125    } 
else if (this->verbose()) {
 
  126      std::ostringstream os;
 
  127      os << *verbPrefix << 
"Source Map not distributed; skip setupExport" 
  129      this->verboseOutputStream() << os.str();
 
  133  TEUCHOS_ASSERT(!this->TransferData_->permuteFromLIDs_.need_sync_device());
 
  134  TEUCHOS_ASSERT(!this->TransferData_->permuteFromLIDs_.need_sync_host());
 
  135  TEUCHOS_ASSERT(!this->TransferData_->permuteToLIDs_.need_sync_device());
 
  136  TEUCHOS_ASSERT(!this->TransferData_->permuteToLIDs_.need_sync_host());
 
  137  TEUCHOS_ASSERT(!this->TransferData_->remoteLIDs_.need_sync_device());
 
  138  TEUCHOS_ASSERT(!this->TransferData_->remoteLIDs_.need_sync_host());
 
  139  TEUCHOS_ASSERT(!this->TransferData_->exportLIDs_.need_sync_device());
 
  140  TEUCHOS_ASSERT(!this->TransferData_->exportLIDs_.need_sync_host());
 
  142  this->detectRemoteExportLIDsContiguous();
 
  144  if (this->verbose()) {
 
  145    std::ostringstream os;
 
  146    os << *verbPrefix << 
"Done!" << endl;
 
  147    this->verboseOutputStream() << os.str();
 
  151template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  154           const Teuchos::RCP<const map_type>& 
target)
 
  156  Teuchos::Array<int> 
dummy;
 
  157#ifdef HAVE_TPETRA_MMM_TIMINGS 
  158  Teuchos::RCP<Teuchos::ParameterList> 
mypars = 
rcp(
new Teuchos::ParameterList);
 
  159  mypars->set(
"Timer Label", 
"Naive_tAFC");
 
 
  166template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  169           const Teuchos::RCP<const map_type>& 
target,
 
  170           const Teuchos::RCP<Teuchos::FancyOStream>& 
out)
 
  172  Teuchos::Array<int> 
dummy;
 
 
  176template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  179           const Teuchos::RCP<const map_type>& 
target,
 
  180           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
  182  Teuchos::Array<int> 
dummy;
 
 
  186template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  189           const Teuchos::RCP<const map_type>& 
target,
 
  190           const Teuchos::RCP<Teuchos::FancyOStream>& 
out,
 
  191           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
  193  Teuchos::Array<int> 
dummy;
 
 
  197template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  200           const Teuchos::RCP<const map_type>& 
target,
 
  201           Teuchos::Array<int>& remotePIDs,
 
  202           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
 
  207template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  212template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  220template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  227           const Teuchos::RCP<Teuchos::ParameterList>& 
plist,
 
  228           const Teuchos::RCP<Teuchos::FancyOStream>& 
out)
 
  232  using Teuchos::Array;
 
  233  using Teuchos::ArrayRCP;
 
  234  using Teuchos::ArrayView;
 
  238  using ::Tpetra::Details::makeDualViewFromArrayView;
 
  241  using size_type = Teuchos::Array<int>::size_type;
 
  243  std::unique_ptr<std::string> 
prefix;
 
  245    auto comm        = 
source.is_null() ? Teuchos::null : 
source->getComm();
 
  246    const int myRank = comm.is_null() ? -1 : comm->getRank();
 
  247    std::ostringstream 
os;
 
  248    os << 
"Proc " << 
myRank << 
": Tpetra::Import createExpert ctor: ";
 
  249    prefix = std::unique_ptr<std::string>(
new std::string(
os.str()));
 
  259    std::ostringstream 
os;
 
  266    std::ostringstream 
os;
 
  276    std::ostringstream 
os;
 
  277    os << *
prefix << 
"Target Map has remote LIDs but source Map is not " 
  278                     "distributed.  Importing to a submap of the target Map." 
  286                       "::constructExpert: Target Map has remote LIDs but source Map " 
  287                       "is not distributed.  Importing to a submap of the target Map.");
 
  291                             "Import::Import createExpert version: " 
  292                             "Size mismatch on userRemotePIDs, remoteGIDs, and remoteLIDs " 
  293                             "Array's to sort3.");
 
  312    if (indexIntoRemotePIDs - 
cnt > 0) {
 
  341                            userExportLIDs, 
"exportLIDs");
 
  352    std::ostringstream 
os;
 
  353    os << *
prefix << 
"locallyComplete: " 
  355       << 
"; call createFromSendsAndRecvs" << 
endl;
 
  359#ifdef HAVE_TPETRA_MMM_TIMINGS 
  361        std::string(
"Tpetra ") + std::string(
":iport_ctor:cFSAR ");
 
  369  this->detectRemoteExportLIDsContiguous();
 
 
  381template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  384           const Teuchos::RCP<const map_type>& 
target,
 
  385           const size_t numSameIDs,
 
  388           Teuchos::Array<LocalOrdinal>& remoteLIDs,
 
  392           const Teuchos::RCP<Teuchos::FancyOStream>& 
out,
 
  393           const Teuchos::RCP<Teuchos::ParameterList>& 
plist)
 
  396  using ::Tpetra::Details::makeDualViewFromArrayView;
 
  398  std::unique_ptr<std::string> 
prefix;
 
  400    auto comm        = 
source.is_null() ? Teuchos::null : 
source->getComm();
 
  401    const int myRank = comm.is_null() ? -1 : comm->getRank();
 
  402    std::ostringstream 
os;
 
  403    os << 
"Proc " << 
myRank << 
": Tpetra::Import export ctor: ";
 
  404    prefix = std::unique_ptr<std::string>(
new std::string(
os.str()));
 
  409  bool locallyComplete = 
true;
 
  410  for (Teuchos::Array<int>::size_type i = 0; i < exportPIDs.size(); ++i) {
 
  411    if (exportPIDs[i] == -1) {
 
  412      locallyComplete = 
false;
 
  416    std::ostringstream os;
 
  417    os << *prefix << 
"numSameIDs: " << numSameIDs << 
", locallyComplete: " 
  418       << (locallyComplete ? 
"true" : 
"false") << endl;
 
  425  makeDualViewFromArrayView(this->
TransferData_->permuteToLIDs_,
 
  426                            permuteToLIDs().getConst(),
 
  428  TEUCHOS_ASSERT(
size_t(this->
TransferData_->permuteToLIDs_.extent(0)) ==
 
  429                 size_t(permuteToLIDs.size()));
 
  430  makeDualViewFromArrayView(this->
TransferData_->permuteFromLIDs_,
 
  431                            permuteFromLIDs().getConst(),
 
  433  TEUCHOS_ASSERT(
size_t(this->
TransferData_->permuteFromLIDs_.extent(0)) ==
 
  434                 size_t(permuteFromLIDs.size()));
 
  436                            remoteLIDs().getConst(),
 
  438  TEUCHOS_ASSERT(
size_t(this->
TransferData_->remoteLIDs_.extent(0)) ==
 
  439                 size_t(remoteLIDs.size()));
 
  441                            exportLIDs().getConst(),
 
  443  TEUCHOS_ASSERT(
size_t(this->
TransferData_->exportLIDs_.extent(0)) ==
 
  444                 size_t(exportLIDs.size()));
 
  448  this->detectRemoteExportLIDsContiguous();
 
  450  TEUCHOS_ASSERT(!this->
TransferData_->permuteFromLIDs_.need_sync_device());
 
  451  TEUCHOS_ASSERT(!this->
TransferData_->permuteFromLIDs_.need_sync_host());
 
  452  TEUCHOS_ASSERT(!this->
TransferData_->permuteToLIDs_.need_sync_device());
 
  453  TEUCHOS_ASSERT(!this->
TransferData_->permuteToLIDs_.need_sync_host());
 
  454  TEUCHOS_ASSERT(!this->
TransferData_->remoteLIDs_.need_sync_device());
 
  455  TEUCHOS_ASSERT(!this->
TransferData_->remoteLIDs_.need_sync_host());
 
  456  TEUCHOS_ASSERT(!this->
TransferData_->exportLIDs_.need_sync_device());
 
  457  TEUCHOS_ASSERT(!this->
TransferData_->exportLIDs_.need_sync_host());
 
  462template <
class LO, 
class GO, 
class NT>
 
  463struct ImportLocalSetupResult {
 
  464  Teuchos::RCP<const ::Tpetra::Map<LO, GO, NT>> targetMap;
 
  468  std::vector<GO> remoteGIDs;
 
  469  std::vector<LO> remoteLIDs;
 
  470  std::vector<int> remotePIDs;
 
  475void printArray(std::ostream& out, 
const T x[], 
const std::size_t N) {
 
  477  for (std::size_t k = 0; k < N; ++k) {
 
  486template <
class LO, 
class GO, 
class NT>
 
  487ImportLocalSetupResult<LO, GO, NT>
 
  488setupSamePermuteRemoteFromUserGlobalIndexList(const ::Tpetra::Map<LO, GO, NT>& sourceMap,
 
  489                                              const GO targetMapRemoteOrPermuteGlobalIndices[],
 
  490                                              const int targetMapRemoteOrPermuteProcessRanks[],
 
  491                                              const LO numTargetMapRemoteOrPermuteGlobalIndices,
 
  492                                              const bool mayReorderTargetMapIndicesLocally,
 
  493                                              Teuchos::FancyOStream* out,        
 
  494                                              const std::string* verboseHeader,  
 
  498  const int myRank = sourceMap.getComm()->getRank();
 
  499  ImportLocalSetupResult<LO, GO, NT> result;
 
  502    std::ostringstream os;
 
  503    os << *verboseHeader << 
"- Import::setupSPR w/ remote GIDs & PIDs: " << endl
 
  504       << *verboseHeader << 
"  Input GIDs: ";
 
  505    printArray(os, targetMapRemoteOrPermuteGlobalIndices, numTargetMapRemoteOrPermuteGlobalIndices);
 
  508    printArray(os, targetMapRemoteOrPermuteProcessRanks, numTargetMapRemoteOrPermuteGlobalIndices);
 
  518    std::vector<GO> badGIDs;
 
  519    std::vector<int> badPIDs;
 
  520    const Teuchos::Comm<int>& comm = *(sourceMap.getComm());
 
  521    const int numProcs             = comm.getSize();
 
  523    for (LO k = 0; k < numTargetMapRemoteOrPermuteGlobalIndices; ++k) {
 
  524      const GO tgtGID = targetMapRemoteOrPermuteGlobalIndices[k];
 
  525      if (sourceMap.isNodeGlobalElement(tgtGID)) {
 
  526        badGIDs.push_back(tgtGID);
 
  528      const int tgtPID = targetMapRemoteOrPermuteProcessRanks[k];
 
  529      if (tgtPID < 0 || tgtPID >= numProcs) {
 
  530        badPIDs.push_back(tgtPID);
 
  534    std::array<int, 2> lclStatus{{badGIDs.size() == 0 ? 1 : 0,
 
  535                                  badPIDs.size() == 0 ? 1 : 0}};
 
  536    std::array<int, 2> gblStatus{{0, 0}};  
 
  537    Teuchos::reduceAll<int, int>(comm, Teuchos::REDUCE_MIN, 2,
 
  538                                 lclStatus.data(), gblStatus.data());
 
  539    const bool good = gblStatus[0] == 1 && gblStatus[1] == 1;
 
  542    if (verbose && gblStatus[0] != 1) {
 
  543      std::ostringstream os;
 
  544      os << *verboseHeader << 
"- Some input GIDs are already in the source Map: ";
 
  545      printArray(os, badGIDs.data(), badGIDs.size());
 
  549    if (verbose && gblStatus[0] != 1) {
 
  550      std::ostringstream os;
 
  551      os << *verboseHeader << 
"- Some input PIDs are invalid: ";
 
  552      printArray(os, badPIDs.data(), badPIDs.size());
 
  558      std::ostringstream os;
 
  559      os << 
"Tpetra::Import constructor that takes remote GIDs and PIDs: ";
 
  560      if (gblStatus[0] != 1) {
 
  561        os << 
"Some input GIDs (global indices) are already in the source Map!  ";
 
  563      if (gblStatus[1] != 1) {
 
  564        os << 
"Some input PIDs (process ranks) are invalid!  ";
 
  566      os << 
"Rerun with the environment variable TPETRA_VERBOSE=Tpetra::Import " 
  567            "to see what GIDs and/or PIDs are bad.";
 
  568      TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument, os.str());
 
  575  const LO numLclSrcIDs = 
static_cast<LO
>(sourceMap.getLocalNumElements());
 
  576  const LO numLclTgtIDs = numLclSrcIDs + numTargetMapRemoteOrPermuteGlobalIndices;
 
  578    std::ostringstream os;
 
  579    os << *verboseHeader << 
"- Copy source Map GIDs into target Map GID list: " 
  582       << 
", numTargetMapRemoteOrPermuteGlobalIndices=" 
  583       << numTargetMapRemoteOrPermuteGlobalIndices << endl;
 
  586  std::vector<GO> tgtGIDs(numLclTgtIDs);  
 
  587  if (sourceMap.isContiguous()) {
 
  588    GO curTgtGID = sourceMap.getMinGlobalIndex();
 
  589    for (LO k = 0; k < numLclSrcIDs; ++k, ++curTgtGID) {
 
  590      tgtGIDs[k] = curTgtGID;
 
  593    auto srcGIDs = sourceMap.getLocalElementList();  
 
  594    for (LO k = 0; k < numLclSrcIDs; ++k) {          
 
  595      tgtGIDs[k] = srcGIDs[k];
 
  598  std::copy(targetMapRemoteOrPermuteGlobalIndices,
 
  599            targetMapRemoteOrPermuteGlobalIndices + numTargetMapRemoteOrPermuteGlobalIndices,
 
  600            tgtGIDs.begin() + numLclSrcIDs);
 
  613    std::ostringstream os;
 
  614    os << *verboseHeader << 
"- Sort by PID? " 
  615       << (mayReorderTargetMapIndicesLocally ? 
"true" : 
"false") << endl;
 
  618  std::vector<int> tgtPIDs(targetMapRemoteOrPermuteProcessRanks,
 
  619                           targetMapRemoteOrPermuteProcessRanks + numTargetMapRemoteOrPermuteGlobalIndices);
 
  620  result.numPermutes = 0;
 
  621  if (mayReorderTargetMapIndicesLocally) {
 
  622    Tpetra::sort2(tgtPIDs.begin(), tgtPIDs.end(), tgtGIDs.begin() + numLclSrcIDs);
 
  623    auto range = std::equal_range(tgtPIDs.begin(), tgtPIDs.end(), myRank);  
 
  624    if (range.second > range.first) {
 
  625      result.numPermutes = 
static_cast<LO
>(range.second - range.first);
 
  628    result.numPermutes = 
static_cast<LO
>(std::count(tgtPIDs.begin(), tgtPIDs.end(), myRank));
 
  631  const LO numRemotes = numTargetMapRemoteOrPermuteGlobalIndices - result.numPermutes;
 
  632  result.numSameIDs   = 
static_cast<LO
>(sourceMap.getLocalNumElements());
 
  635    std::ostringstream os;
 
  636    os << *verboseHeader << 
"- numSame=" << result.numSameIDs
 
  637       << 
", numPermutes=" << result.numPermutes
 
  638       << 
", numRemotes=" << numRemotes << endl;
 
  642  if (result.numPermutes == 0) {
 
  644      std::ostringstream os;
 
  645      os << *verboseHeader << 
"- No permutes" << endl;
 
  648    result.remoteGIDs = std::vector<GO>(tgtGIDs.begin() + numLclSrcIDs, tgtGIDs.end());
 
  649    result.remotePIDs.swap(tgtPIDs);
 
  650    result.remoteLIDs.resize(numRemotes);
 
  651    for (LO k = 0; k < numRemotes; ++k) {
 
  652      const LO tgtLid      = result.numSameIDs + k;
 
  653      result.remoteLIDs[k] = tgtLid;
 
  656      std::ostringstream os;
 
  657      os << *verboseHeader << 
"- Remote GIDs: " 
  658         << Teuchos::toString(result.remoteGIDs) << endl;
 
  659      os << *verboseHeader << 
"- Remote PIDs: " 
  660         << Teuchos::toString(result.remotePIDs) << endl;
 
  661      os << *verboseHeader << 
"- Remote LIDs: " 
  662         << Teuchos::toString(result.remoteLIDs) << endl;
 
  669    result.remoteGIDs.reserve(numRemotes);
 
  670    result.remoteLIDs.reserve(numRemotes);
 
  671    result.remotePIDs.reserve(numRemotes);
 
  672    for (LO k = 0; k < numTargetMapRemoteOrPermuteGlobalIndices; ++k) {
 
  673      const LO tgtLid  = result.numSameIDs + k;
 
  674      const GO tgtGid  = tgtGIDs[numLclSrcIDs + k];
 
  675      const int tgtPid = tgtPIDs[k];
 
  677      if (tgtPid != myRank) {  
 
  678        result.remoteGIDs.push_back(tgtGid);
 
  679        result.remoteLIDs.push_back(tgtLid);
 
  680        result.remotePIDs.push_back(tgtPid);
 
  684      std::ostringstream os;
 
  685      os << *verboseHeader << 
"- Some permutes" << endl;
 
  690  if (sourceMap.isDistributed()) {
 
  692      std::ostringstream os;
 
  693      os << *verboseHeader << 
"- Sort remotes by PID, as Import always does" 
  695         << *verboseHeader << 
"-- remotePIDs before: " 
  696         << Teuchos::toString(result.remotePIDs) << endl
 
  697         << *verboseHeader << 
"-- remoteGIDs before: " 
  698         << Teuchos::toString(result.remoteGIDs) << endl
 
  699         << *verboseHeader << 
"-- remoteLIDs before: " 
  700         << Teuchos::toString(result.remoteLIDs) << endl;
 
  704    sort3(result.remotePIDs.begin(),
 
  705          result.remotePIDs.end(),
 
  706          result.remoteGIDs.begin(),
 
  707          result.remoteLIDs.begin());
 
  709      std::ostringstream os;
 
  710      os << *verboseHeader << 
"-- remotePIDs after: " 
  711         << Teuchos::toString(result.remotePIDs) << endl
 
  712         << *verboseHeader << 
"-- remoteGIDs after: " 
  713         << Teuchos::toString(result.remoteGIDs) << endl
 
  714         << *verboseHeader << 
"-- remoteLIDs after: " 
  715         << Teuchos::toString(result.remoteLIDs) << endl;
 
  716      std::cerr << os.str();
 
  721    std::ostringstream os;
 
  722    os << *verboseHeader << 
"- Make target Map" << endl;
 
  725  using ::Teuchos::rcp;
 
  726  typedef ::Tpetra::Map<LO, GO, NT> map_type;
 
  728  const GST MAP_COMPUTES_GLOBAL_COUNT = ::Teuchos::OrdinalTraits<GST>::invalid();
 
  729  result.targetMap                    = rcp(
new map_type(MAP_COMPUTES_GLOBAL_COUNT,
 
  732                                                         sourceMap.getIndexBase(),
 
  733                                                         sourceMap.getComm()));
 
  735    std::ostringstream os;
 
  736    os << *verboseHeader << 
"- Done with sameSPR..." << endl;
 
  743template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  750           const Teuchos::RCP<Teuchos::ParameterList>& 
plist,
 
  751           const Teuchos::RCP<Teuchos::FancyOStream>& 
debugOutput)
 
  757  using Teuchos::ArrayView;
 
  758  using Teuchos::getFancyOStream;
 
  761  using Teuchos::rcpFromRef;
 
  762  using ::Tpetra::Details::Behavior;
 
  763  using ::Tpetra::Details::makeDualViewFromOwningHostView;
 
  764  using ::Tpetra::Details::makeDualViewFromVector;
 
  765  using ::Tpetra::Details::printDualView;
 
  766  using ::Tpetra::Details::view_alloc_no_init;
 
  771  const bool debug = Behavior::debug(
"Import") ||
 
  772                     Behavior::debug(
"Tpetra::Import");
 
  774  std::unique_ptr<std::string> 
verbPfx;
 
  776    std::ostringstream 
os;
 
  778    os << 
"Proc " << 
myRank << 
": Tpetra::Import ctor from remotes: ";
 
  779    verbPfx = std::unique_ptr<std::string>(
new std::string(
os.str()));
 
  804                                                       this->TransferData_->out_,
 
  806  this->
TransferData_->numSameIDs_ = localSetupResult.numSameIDs;
 
  810                         localSetupResult.remoteLIDs,
 
  824      std::ostringstream 
os;
 
  825      os << *
verbPfx << 
"Make Distributor (createFromRecvs)" << 
endl;
 
  850      std::ostringstream 
os;
 
  854    using size_type              = 
typename Teuchos::Array<GO>::size_type;
 
  863    makeDualViewFromOwningHostView(this->
TransferData_->exportLIDs_, exportLIDs);
 
  867    std::ostringstream 
os;
 
  870                  "ImportExportData::remoteLIDs_");
 
  875    std::ostringstream 
os;
 
 
  881template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  884             const Teuchos::EVerbosityLevel 
verbLevel)
 const {
 
 
  889template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  891    print(std::ostream& 
os)
 const {
 
  892  auto out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(
os));
 
  894  this->describe(*
out, Teuchos::VERB_EXTREME);
 
 
  897template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  901  using Teuchos::Array;
 
  902  using Teuchos::ArrayRCP;
 
  903  using Teuchos::ArrayView;
 
  906  using ::Tpetra::Details::makeDualViewFromOwningHostView;
 
  907  using ::Tpetra::Details::ProfilingRegion;
 
  908  using ::Tpetra::Details::view_alloc_no_init;
 
  912  ProfilingRegion 
regionExport(
"Tpetra::Import::setupSamePermuteRemote");
 
  914  const map_type& 
source         = *(this->getSourceMap());
 
  915  const map_type& 
target         = *(this->getTargetMap());
 
  919#ifdef HAVE_TPETRA_DEBUG 
  939  this->TransferData_->numSameIDs_ = numSameGids;
 
  953  const LO LINVALID   = Teuchos::OrdinalTraits<LO>::invalid();
 
  954  const LO numTgtLids = as<LO>(numTgtGids);
 
  957  for (LO tgtLid = numSameGids; tgtLid < numTgtLids; ++tgtLid) {
 
  958    const GO curTargetGid = rawTgtGids[tgtLid];
 
  962    const LO srcLid = source.getLocalElement(curTargetGid);
 
  963    if (srcLid != LINVALID) {  
 
  967  const LO numRemotes = (numTgtLids - numSameGids) - numPermutes;
 
  969  using host_perm_type =
 
  970      typename decltype(this->TransferData_->permuteToLIDs_)::t_host;
 
  973  typename decltype(this->TransferData_->remoteLIDs_)::t_host remoteLIDs(
view_alloc_no_init(
"permuteFromLIDs"), numRemotes);
 
  978    for (LO tgtLid = numSameGids; tgtLid < numTgtLids; ++tgtLid) {
 
  979      const GO curTargetGid = rawTgtGids[tgtLid];
 
  980      const LO srcLid       = source.getLocalElement(curTargetGid);
 
  981      if (srcLid != LINVALID) {
 
  982        permuteToLIDs[numPermutes2]   = tgtLid;
 
  983        permuteFromLIDs[numPermutes2] = srcLid;
 
  986        remoteGIDs.push_back(curTargetGid);
 
  987        remoteLIDs[numRemotes2] = tgtLid;
 
  991    TEUCHOS_ASSERT(numPermutes == numPermutes2);
 
  992    TEUCHOS_ASSERT(numRemotes == numRemotes2);
 
  993    TEUCHOS_ASSERT(
size_t(numPermutes) + remoteGIDs.size() == 
size_t(numTgtLids - numSameGids));
 
  999  if (remoteLIDs.extent(0) != 0 && !source.isDistributed()) {
 
 1005    this->TransferData_->isLocallyComplete_ = 
false;
 
 1009                         "::setupSamePermuteRemote(): Target has " 
 1010                         "remote LIDs but Source is not distributed globally.  Importing to a " 
 1011                         "submap of the target map.");
 
 1015template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
 1016void Import<LocalOrdinal, GlobalOrdinal, Node>::
 
 1017    setupExport(Teuchos::Array<GlobalOrdinal>& remoteGIDs,
 
 1019                Teuchos::Array<int>& userRemotePIDs,
 
 1020                const Teuchos::RCP<Teuchos::ParameterList>& plist) {
 
 1022  using Teuchos::Array;
 
 1023  using Teuchos::ArrayView;
 
 1024  using ::Tpetra::Details::makeDualViewFromOwningHostView;
 
 1025  using ::Tpetra::Details::view_alloc_no_init;
 
 1026  using GO = GlobalOrdinal;
 
 1027  typedef typename Array<int>::difference_type size_type;
 
 1028  const char tfecfFuncName[] = 
"setupExport: ";
 
 1029  const char suffix[]        = 
"  Please report this bug to the Tpetra developers.";
 
 1031  std::unique_ptr<std::string> prefix;
 
 1032  if (this->verbose()) {
 
 1033    auto srcMap      = this->getSourceMap();
 
 1034    auto comm        = srcMap.is_null() ? Teuchos::null : srcMap->getComm();
 
 1035    const int myRank = comm.is_null() ? -1 : comm->getRank();
 
 1036    std::ostringstream os;
 
 1037    os << 
"Proc " << myRank << 
": Tpetra::Import::setupExport: ";
 
 1038    prefix = std::unique_ptr<std::string>(
new std::string(os.str()));
 
 1039    os << 
"Start" << std::endl;
 
 1040    this->verboseOutputStream() << os.str();
 
 1043  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(this->getSourceMap().is_null(), std::logic_error,
 
 1044                                        "Source Map is null.  " << suffix);
 
 1045  const map_type& source = *(this->getSourceMap());
 
 1047  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!useRemotePIDs && (userRemotePIDs.size() > 0), std::invalid_argument,
 
 1048                                        "remotePIDs are non-empty but their use has not been requested.");
 
 1049  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(userRemotePIDs.size() > 0 && remoteGIDs.size() != userRemotePIDs.size(),
 
 1050                                        std::invalid_argument,
 
 1051                                        "remotePIDs must either be of size zero or match " 
 1052                                        "the size of remoteGIDs.");
 
 1056  ArrayView<GO> remoteGIDsView = remoteGIDs();
 
 1057  ArrayView<int> remoteProcIDsView;
 
 1077  Array<int> newRemotePIDs;
 
 1080  if (!useRemotePIDs) {
 
 1081    newRemotePIDs.resize(remoteGIDsView.size());
 
 1082    if (this->verbose()) {
 
 1083      std::ostringstream os;
 
 1084      os << *prefix << 
"Call sourceMap.getRemoteIndexList" << endl;
 
 1085      this->verboseOutputStream() << os.str();
 
 1087    lookup = source.getRemoteIndexList(remoteGIDsView, newRemotePIDs());
 
 1089  Array<int>& remoteProcIDs = useRemotePIDs ? userRemotePIDs : newRemotePIDs;
 
 1095    this->TransferData_->isLocallyComplete_ = 
false;
 
 1100                         "::setupExport(): the source Map wasn't " 
 1101                         "able to figure out which process owns one or more of the GIDs in the " 
 1102                         "list of remote GIDs.  This probably means that there is at least one " 
 1103                         "GID owned by some process in the target Map which is not owned by any" 
 1104                         " process in the source Map.  (That is, the source and target Maps do " 
 1105                         "not contain the same set of GIDs globally.)");
 
 1111    const size_type numInvalidRemote =
 
 1112        std::count_if(remoteProcIDs.begin(), remoteProcIDs.end(),
 
 1113                      std::bind(std::equal_to<int>(), -1, std::placeholders::_1));
 
 1114    TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(numInvalidRemote == 0, std::logic_error,
 
 1115                                          "Calling getRemoteIndexList " 
 1116                                          "on the source Map returned IDNotPresent, but none of the returned " 
 1117                                          "\"remote\" process ranks are -1.  Please report this bug to the " 
 1118                                          "Tpetra developers.");
 
 1120#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1121    using Teuchos::TimeMonitor;
 
 1123    if (!plist.is_null())
 
 1124      label = plist->get(
"Timer Label", label);
 
 1125    std::string prefix = std::string(
"Tpetra ") + label + std::string(
":iport_ctor:setupExport:1 ");
 
 1126    auto MM            = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix)));
 
 1132    const size_type totalNumRemote = this->getNumRemoteIDs();
 
 1133    if (numInvalidRemote == totalNumRemote) {
 
 1135      remoteProcIDs.clear();
 
 1137      this->TransferData_->remoteLIDs_ =
 
 1138          decltype(this->TransferData_->remoteLIDs_)();
 
 1142      size_type numValidRemote = 0;
 
 1143#ifdef HAVE_TPETRA_DEBUG 
 1144      ArrayView<GO> remoteGIDsPtr = remoteGIDsView;
 
 1146      GO* 
const remoteGIDsPtr = remoteGIDsView.getRawPtr();
 
 1150      auto remoteLIDs = this->TransferData_->remoteLIDs_.view_host();
 
 1152      for (size_type r = 0; r < totalNumRemote; ++r) {
 
 1154        if (remoteProcIDs[r] != -1) {
 
 1155          remoteProcIDs[numValidRemote] = remoteProcIDs[r];
 
 1156          remoteGIDsPtr[numValidRemote] = remoteGIDsPtr[r];
 
 1157          remoteLIDs[numValidRemote]    = remoteLIDs[r];
 
 1161      TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(numValidRemote != totalNumRemote - numInvalidRemote,
 
 1163                                            "After removing invalid remote GIDs and packing " 
 1164                                            "the valid remote GIDs, numValidRemote = " 
 1166                                                << 
" != totalNumRemote - numInvalidRemote = " 
 1167                                                << totalNumRemote - numInvalidRemote
 
 1168                                                << 
".  Please report this bug to the Tpetra developers.");
 
 1170      remoteProcIDs.resize(numValidRemote);
 
 1171      remoteGIDs.resize(numValidRemote);
 
 1173      Kokkos::resize(remoteLIDs, numValidRemote);
 
 1174      this->TransferData_->remoteLIDs_ = 
decltype(this->TransferData_->remoteLIDs_)();
 
 1178    remoteGIDsView = remoteGIDs();
 
 1186    this->TransferData_->remoteLIDs_.modify_host();
 
 1187    auto remoteLIDs = this->TransferData_->remoteLIDs_.view_host();
 
 1188    sort3(remoteProcIDs.begin(),
 
 1189          remoteProcIDs.end(),
 
 1190          remoteGIDsView.getRawPtr(),
 
 1192    this->TransferData_->remoteLIDs_.sync_device();
 
 1200  Array<GO> exportGIDs;
 
 1202#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1203  using Teuchos::TimeMonitor;
 
 1205  if (!plist.is_null())
 
 1206    label = plist->get(
"Timer Label", label);
 
 1207  std::string prefix2 = std::string(
"Tpetra ") + label + std::string(
":iport_ctor:setupExport:3 ");
 
 1208  auto MM             = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix2)));
 
 1211  if (this->verbose()) {
 
 1212    std::ostringstream os;
 
 1213    os << *prefix << 
"Call createFromRecvs" << endl;
 
 1214    this->verboseOutputStream() << endl;
 
 1216  this->TransferData_->distributor_.createFromRecvs(remoteGIDsView().getConst(),
 
 1217                                                    remoteProcIDs, exportGIDs,
 
 1218                                                    this->TransferData_->exportPIDs_);
 
 1224#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1225  prefix2 = std::string(
"Tpetra ") + label + std::string(
":iport_ctor:setupExport:4 ");
 
 1227  MM      = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix2)));
 
 1233  const size_type numExportIDs = exportGIDs.size();
 
 1234  if (numExportIDs > 0) {
 
 1235    typename decltype(this->TransferData_->exportLIDs_)::t_host
 
 1237    ArrayView<const GO> expGIDs = exportGIDs();
 
 1239    for (size_type k = 0; k < numExportIDs; ++k) {
 
 1240      exportLIDs[k] = source.getLocalElement(expGIDs[k]);
 
 1245  if (this->verbose()) {
 
 1246    std::ostringstream os;
 
 1247    os << *prefix << 
"Done!" << endl;
 
 1248    this->verboseOutputStream() << os.str();
 
 1252template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
 1255                        Teuchos::Array<std::pair<int, GlobalOrdinal>>& 
remotePGIDs,
 
 1256                        typename Teuchos::Array<GlobalOrdinal>::size_type& 
numSameGIDs,
 
 1257                        typename Teuchos::Array<GlobalOrdinal>::size_type& 
numPermuteGIDs,
 
 1258                        typename Teuchos::Array<GlobalOrdinal>::size_type& 
numRemoteGIDs,
 
 1259                        const Teuchos::ArrayView<const GlobalOrdinal>& 
sameGIDs1,
 
 1260                        const Teuchos::ArrayView<const GlobalOrdinal>& 
sameGIDs2,
 
 1268  typedef typename Teuchos::Array<GO>::size_type size_type;
 
 
 1351template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
 1352Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node>>
 
 1355  using Teuchos::Array;
 
 1356  using Teuchos::ArrayView;
 
 1358  using Teuchos::Comm;
 
 1359  using Teuchos::outArg;
 
 1362  using Teuchos::REDUCE_MIN;
 
 1363  using Teuchos::reduceAll;
 
 1364  using ::Tpetra::Details::Behavior;
 
 1371#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1372  using Teuchos::TimeMonitor;
 
 1373  std::string label = std::string(
"Tpetra::Import::setUnion");
 
 1382  const bool debug = Behavior::debug(
"Import::setUnion") ||
 
 1383                     Behavior::debug(
"Tpetra::Import::setUnion");
 
 1387                               "Tpetra::Import::setUnion: The source Map of the input Import must be the " 
 1388                               "same as (in the sense of Map::isSameAs) the source Map of this Import.");
 
 1392                               std::invalid_argument,
 
 1393                               "Tpetra::Import::setUnion: " 
 1394                               "The target Maps must have congruent communicators.");
 
 1401    return rcp(
new import_type(*
this));
 
 1439  Tpetra::Import_Util::getRemotePIDs(*
this, 
remotePIDs1);
 
 1476#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1477  MM.disableTimer(label);
 
 1478  label = 
"Tpetra::Import::setUnion : Construct Target Map";
 
 1483  const GST INVALID       = Teuchos::OrdinalTraits<GST>::invalid();
 
 1488#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1489  MM2.disableTimer(label);
 
 1490  label = 
"Tpetra::Import::setUnion : Export GIDs";
 
 1507#ifdef TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 
 1591#ifdef HAVE_TPETRA_MMM_TIMINGS 
 1592  MM3.disableTimer(label);
 
 1593  label = 
"Tpetra::Import::setUnion : Construct Import";
 
 1602                          this->TransferData_->out_));
 
 
 1606template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
 1607Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node>>
 
 1610  using Teuchos::Array;
 
 1611  using Teuchos::ArrayView;
 
 1613  using Teuchos::Comm;
 
 1614  using Teuchos::outArg;
 
 1617  using Teuchos::REDUCE_MIN;
 
 1618  using Teuchos::reduceAll;
 
 1621  Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node>> 
unionImport;
 
 1651  GO 
GO_INVALID = Teuchos::OrdinalTraits<GO>::invalid();
 
 
 1676template <
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
 1677Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node>>
 
 1681  using Teuchos::outArg;
 
 1683  using Teuchos::REDUCE_MIN;
 
 1684  using Teuchos::reduceAll;
 
 1685  using ::Tpetra::Details::Behavior;
 
 1686  using ::Tpetra::Details::gathervPrint;
 
 1691  const char funcPrefix[] = 
"Tpetra::createRemoteOnlyImport: ";
 
 1694  const bool debug        = Behavior::debug();
 
 1696  const size_t NumRemotes = this->getNumRemoteIDs();
 
 1698  Teuchos::RCP<const Teuchos::Comm<int>> comm;
 
 1701    std::ostringstream 
os;
 
 1703    if (comm.is_null()) {
 
 1706      os << comm->getRank();
 
 1709    procPrefix = std::unique_ptr<std::string>(
new std::string(
os.str()));
 
 1713    std::ostringstream 
lclErr;
 
 1719             << 
" != remoteTarget->getLocalNumElements() = " 
 1723    if (comm.is_null()) {
 
 1731      if (comm.is_null()) {
 
 1734        std::ostringstream 
gblErr;
 
 1743  Teuchos::ArrayView<const LO> 
oldRemoteLIDs = this->getRemoteLIDs();
 
 1748  std::unique_ptr<std::vector<size_t>> 
badIndices;
 
 1750    badIndices = std::unique_ptr<std::vector<size_t>>(
new std::vector<size_t>);
 
 1755    if (
oldLclInd == Teuchos::OrdinalTraits<LO>::invalid()) {
 
 1763    if (
gblInd == Teuchos::OrdinalTraits<GO>::invalid()) {
 
 1771    if (
newLclInd == Teuchos::OrdinalTraits<LO>::invalid()) {
 
 1793    if (comm.is_null()) {
 
 1798    std::ostringstream 
lclErr;
 
 1801             << 
", bad indices: [";
 
 1805        const size_t badIndex = (*badIndices)[
k];
 
 1816      std::ostringstream 
gblErr;
 
 1818                              "indices on one or more processes.  \"Bad\" means that the " 
 1819                              "indices are invalid, they don't exist in the target Map, " 
 1820                              "they don't exist in remoteTarget, or they are not in " 
 1821                              "sorted order.  In what follows, I will show the \"bad\" " 
 1822                              "indices as (k, LID) pairs, where k is the zero-based " 
 1823                              "index of the LID in this->getRemoteLIDs()." 
 1825      if (comm.is_null()) {
 
 1843  Teuchos::Array<LO> 
dummy;
 
 
 1854#define TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) \ 
 1855  template class Import<LO, GO, NODE>; 
 1864#define TPETRA_IMPORT_INSTANT(LO, GO, NODE) \ 
 1865  TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) 
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
 
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
 
Declaration of a function that prints strings from each process.
 
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects.
 
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.
 
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
 
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.
 
Sets up and executes a communication plan for a Tpetra DistObject.
 
void createFromRecvs(const Teuchos::ArrayView< const Ordinal > &remoteIDs, const Teuchos::ArrayView< const int > &remoteProcIDs, Teuchos::Array< Ordinal > &exportIDs, Teuchos::Array< int > &exportProcIDs)
Set up Distributor using list of process ranks from which to receive.
 
void createFromSendsAndRecvs(const Teuchos::ArrayView< const int > &exportProcIDs, const Teuchos::ArrayView< const int > &remoteProcIDs)
Set up Distributor using list of process ranks to which to send, and list of process ranks from which...
 
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
 
Teuchos::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > setUnion() const
Return the union of this Import this->getSourceMap()
 
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::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > createRemoteOnlyImport(const Teuchos::RCP< const map_type > &remoteTarget) const
Returns an importer that contains only the remote entries of this.
 
Import(const Teuchos::RCP< const map_type > &source, const Teuchos::RCP< const map_type > &target)
Construct an Import from the source and target Maps.
 
void findUnionTargetGIDs(Teuchos::Array< GlobalOrdinal > &unionTgtGIDs, Teuchos::Array< std::pair< int, GlobalOrdinal > > &remotePGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numSameGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numPermuteGIDs, typename Teuchos::Array< GlobalOrdinal >::size_type &numRemoteGIDs, const Teuchos::ArrayView< const GlobalOrdinal > &sameGIDs1, const Teuchos::ArrayView< const GlobalOrdinal > &sameGIDs2, Teuchos::Array< GlobalOrdinal > &permuteGIDs1, Teuchos::Array< GlobalOrdinal > &permuteGIDs2, Teuchos::Array< GlobalOrdinal > &remoteGIDs1, Teuchos::Array< GlobalOrdinal > &remoteGIDs2, Teuchos::Array< int > &remotePIDs1, Teuchos::Array< int > &remotePIDs2) const
Find the union of the target IDs from two Import objects.
 
virtual void print(std::ostream &os) const
Print the Import's data to the given output stream.
 
A parallel distribution of indices over processes.
 
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.
 
bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
 
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator,...
 
Namespace Tpetra contains the class and methods constituting the Tpetra library.
 
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const bool stableSort=false)
Sort the first array, and apply the resulting permutation to the second array.
 
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
 
size_t global_size_t
Global size_t object.
 
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2)
Merge values in place, additively, with the same index.
 
void keyValueMerge(KeyInputIterType keyBeg1, KeyInputIterType keyEnd1, ValueInputIterType valBeg1, ValueInputIterType valEnd1, KeyInputIterType keyBeg2, KeyInputIterType keyEnd2, ValueInputIterType valBeg2, ValueInputIterType valEnd2, KeyOutputIterType keyOut, ValueOutputIterType valOut, BinaryFunction f)
Merge two sorted (by keys) sequences of unique (key,value) pairs by combining pairs with equal keys.
 
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.