10#ifndef TPETRA_IMPORT_UTIL_HPP 
   11#define TPETRA_IMPORT_UTIL_HPP 
   19#include "Tpetra_ConfigDefs.hpp" 
   20#include "Tpetra_Import.hpp" 
   21#include "Tpetra_HashTable.hpp" 
   22#include "Tpetra_Map.hpp" 
   24#include "Tpetra_Distributor.hpp" 
   25#include <Teuchos_Array.hpp> 
   29namespace Import_Util {
 
   36template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   38                    Teuchos::Array<std::pair<int, GlobalOrdinal> >& gpids,
 
   39                    bool use_minus_one_for_local);
 
   42template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   44             Teuchos::Array<int>& pids,
 
   45             bool use_minus_one_for_local);
 
   49template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   51             Teuchos::ArrayView<int>& pids,
 
   52             bool use_minus_one_for_local);
 
   56template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   58                   Teuchos::Array<int>& RemotePIDs);
 
   64namespace Import_Util {
 
   66template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   68                    Teuchos::Array<std::pair<int, GlobalOrdinal> >& 
gpids,
 
   78  size_t N  = 
Importer.getTargetMap()->getLocalNumElements();
 
   85  Teuchos::ArrayView<const int> 
ProcsFrom      = 
D.getProcsFrom();
 
   86  Teuchos::ArrayView<const size_t> 
LengthsFrom = 
D.getLengthsFrom();
 
 
  109template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  111             Teuchos::Array<int>& 
pids,
 
  114  pids.resize(
Importer.getTargetMap()->getLocalNumElements());
 
 
  119template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  121             Teuchos::ArrayView<int>& 
pids,
 
  128  size_t N  = 
Importer.getTargetMap()->getLocalNumElements();
 
  129  if (
N != (
size_t)
pids.size()) 
throw std::runtime_error(
"Tpetra::Import_Util::getPids(): Incorrect size for output array");
 
  136  Teuchos::ArrayView<const int> 
ProcsFrom      = 
D.getProcsFrom();
 
  137  Teuchos::ArrayView<const size_t> 
LengthsFrom = 
D.getLengthsFrom();
 
 
  157template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  167  Teuchos::ArrayView<const int> 
ProcsFrom      = 
D.getProcsFrom();
 
  168  Teuchos::ArrayView<const size_t> 
LengthsFrom = 
D.getLengthsFrom();
 
 
  188template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  196  if (!
source->isDistributed()) 
return true;
 
  204  const int MyPID         = comm->getRank();
 
  205  const int NumProcs      = comm->getSize();
 
  212  std::ostringstream 
os;
 
  219  Teuchos::ArrayView<const LocalOrdinal> remoteLIDs    = 
Importer.getRemoteLIDs();
 
  222  Teuchos::Array<int> remotePIDs;
 
  223  getRemotePIDs(
Importer, remotePIDs);
 
  226  Teuchos::Array<GlobalOrdinal> remoteGIDs(remoteLIDs.size());
 
  227  for (
size_t i = 0; 
i < (
size_t)remoteLIDs.size(); 
i++) {
 
  228    remoteGIDs[
i] = 
target->getGlobalElement(remoteLIDs[
i]);
 
  229    if (remoteGIDs[
i] < 0) {
 
  230      os << 
MyPID << 
"ERROR3: source->getGlobalElement(remoteLIDs[l]) is invalid GID=" << remoteGIDs[
i] << 
" LID= " << remoteLIDs[
i] << std::endl;
 
  235  Teuchos::Array<GlobalOrdinal> exportGIDs(exportLIDs.size(), -1);
 
  236  for (
size_t i = 0; i < (size_t)exportLIDs.size(); i++) {
 
  237    exportGIDs[i] = source->getGlobalElement(exportLIDs[i]);
 
  238    exportGIDs[i] = source->getGlobalElement(exportLIDs[i]);
 
  239    if (exportGIDs[i] < 0) {
 
  240      os << MyPID << 
"ERROR3: source->getGlobalElement(exportLIDs[l]) is invalid GID=" << exportGIDs[i] << 
" LID= " << exportLIDs[i] << std::endl;
 
  246  for (
auto&& rgid : remoteGIDs) {
 
  247    if (std::find(exportGIDs.begin(), exportGIDs.end(), rgid) != exportGIDs.end()) {
 
  249      os << MyPID << 
"ERROR0: Overlap between remoteGIDs and exportGIDs " << rgid << std::endl;
 
  253  int TempPID, OwningPID;
 
  254  for (GlobalOrdinal i = minSourceGID; i < maxSourceGID; i++) {
 
  258    LocalOrdinal slid = source->getLocalElement(i);
 
  259    if (slid == LO_INVALID)
 
  263    Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, TempPID, Teuchos::outArg(OwningPID));
 
  266    LocalOrdinal tlid = target->getLocalElement(i);
 
  268    if (tlid != LO_INVALID) {
 
  273      if (OwningPID == -1) 
continue;
 
  275      if (OwningPID == MyPID) {
 
  277        if ((
size_t)tlid < Importer.getNumSameIDs()) {
 
  282          for (
size_t j = 0; j < (size_t)permuteTarget.size(); j++) {
 
  283            if (tlid == permuteTarget[j]) {
 
  291        bool already_hit = 
false;
 
  292        for (
size_t j = 0; j < (size_t)remoteGIDs.size(); j++) {
 
  293          if (i == remoteGIDs[j]) {
 
  300            if (OwningPID == remotePIDs[j]) {
 
  308        os << MyPID << 
"  ERROR1: GID " << i << 
" should be remoted from PID " << OwningPID << 
" but isn't." << std::endl;
 
  318  Teuchos::Array<int> local_proc_mask(NumProcs, 0), global_proc_mask(NumProcs, 0);
 
  320  for (GlobalOrdinal i = minTargetGID; i < maxTargetGID; i++) {
 
  322    LocalOrdinal tlid = target->getLocalElement(i);
 
  323    LocalOrdinal slid = source->getLocalElement(i);
 
  325    if (tlid == LO_INVALID)
 
  326      local_proc_mask[MyPID] = 0;
 
  328      local_proc_mask[MyPID] = 1;
 
  330    Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, NumProcs, &local_proc_mask[0], &global_proc_mask[0]);
 
  332    if (slid != LO_INVALID) {
 
  334      for (
int j = 0; j < NumProcs; j++) {
 
  335        if (j == MyPID) 
continue;  
 
  336        if (global_proc_mask[j] == 1) {
 
  339          bool already_hit = 
false;
 
  340          for (
size_t k = 0; k < (size_t)exportPIDs.size(); k++) {
 
  341            if (exportPIDs[k] == j && source->getGlobalElement(exportLIDs[k]) == i) {
 
  353            os << MyPID << 
" ERROR2: GID " << i << 
" should be sent to PID " << j << 
" but isn't" << std::endl;
 
  363  Teuchos::Array<int> proc_num_exports_recv(NumProcs, 0);
 
  365  Teuchos::Array<int> remoteGIDcount(remoteGIDs.size(), 0);
 
  368  Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, exportGIDs.size(), Teuchos::outArg(allexpsiz));
 
  370  for (
int i = 0; i < allexpsiz; ++i) {
 
  371    Teuchos::Array<GlobalOrdinal> myexpgid(NumProcs, -2), yourexpgid(NumProcs, -2);
 
  372    Teuchos::Array<int> myexppid(NumProcs, -2), yourexppid(NumProcs, -2);
 
  373    if (i < exportGIDs.size()) {
 
  374      myexpgid[MyPID] = exportGIDs[i];
 
  375      myexppid[MyPID] = exportPIDs[i];
 
  377    Teuchos::reduceAll<int, GlobalOrdinal>(*comm, Teuchos::REDUCE_MAX, NumProcs, &myexpgid[0], &yourexpgid[0]);
 
  378    Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, NumProcs, &myexppid[0], &yourexppid[0]);
 
  379    for (
int p = 0; p < NumProcs; ++p) {  
 
  380      GlobalOrdinal cgid = yourexpgid[p];
 
  382      if (cgid == -2) 
continue;
 
  384        os << MyPID << 
" ERROR4: received exportGID is invalid " << cgid << std::endl;
 
  387      bool foundit = 
false;
 
  388      for (
size_t k = 0; k < (size_t)remoteGIDs.size(); ++k) {
 
  389        if (cgid == remoteGIDs[k] && yourexppid[p] == MyPID) {
 
  390          if (p != remotePIDs[k]) {
 
  391            os << MyPID << 
" ERROR5: receive export from wrong pid: got " << p << 
" expected: " << remotePIDs[k] << std::endl;
 
  396            os << MyPID << 
" ERROR6: found multiple GIDs from correct pid: GID  " << remoteGIDs[k] << std::endl;
 
  402      if (!foundit && yourexppid[p] == MyPID) {
 
  403        os << MyPID << 
" ERROR7: receive gid  " << cgid << 
" that is not in my remote gid list, from pid  " << p << std::endl;
 
  409  for (
size_t i = 0; i < (size_t)remoteGIDcount.size(); ++i) {
 
  410    int rc = remoteGIDcount[i];
 
  411    if (rc == 1) 
continue;
 
  412    os << MyPID << 
" ERROR8: my remote at " << i << 
" gid " << remoteGIDs[i] << 
" has count " << rc << std::endl;
 
  417  Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MIN, (
int)is_valid, Teuchos::outArg(global_is_valid));
 
  419  if (!global_is_valid) {
 
  420    std::cerr << os.str() << std::flush;
 
  421    Importer.print(std::cout);
 
  424  return global_is_valid > 0;
 
  428template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  430  Teuchos::RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > source = Importer.getSourceMap();
 
  431  Teuchos::RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > target = Importer.getTargetMap();
 
  434  Teuchos::Array<std::pair<int, GlobalOrdinal> > gpids;
 
  438  bool is_local          = 
true;
 
  440  GlobalOrdinal INVALID  = Teuchos::OrdinalTraits<GlobalOrdinal>::invalid();
 
  441  GlobalOrdinal last_GID = Teuchos::OrdinalTraits<GlobalOrdinal>::invalid();
 
  443  for (
size_t i = 0; i < (size_t)gpids.size(); i++) {
 
  444    int pid           = gpids[i].first;
 
  445    GlobalOrdinal gid = gpids[i].second;
 
  447    if (is_local == 
false && pid == -1) {
 
  451    } 
else if (pid == -1) {
 
  453      if (source->getGlobalElement(i) != target->getGlobalElement(i)) {
 
  461      if (last_PID == -1) {
 
  464      } 
else if (pid < last_PID) {
 
  468      } 
else if (pid == last_PID) {
 
  469        if (gid < last_GID) {
 
  486template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  488  bool consistent_block = 
true;
 
  490  for (
size_t lid = 0; lid < map.getLocalNumElements(); lid += block_size) {
 
  491    auto lbid = floor(
double(lid) / block_size);
 
  492    auto gbid = floor(
double(map.getGlobalElement(lid)) / block_size);
 
  494    for (
size_t lid2 = 1; lid2 < block_size; ++lid2) {
 
  495      auto lbid_n = floor(
double(lid + lid2) / block_size);
 
  496      auto gbid_n = floor(
double(map.getGlobalElement(lid + lid2)) / block_size);
 
  497      if (consistent_block)
 
  498        consistent_block = (lbid == lbid_n);
 
  499      if (consistent_block)
 
  500        consistent_block = (gbid == gbid_n);
 
  504  return consistent_block;
 
void getPids(const Tpetra::Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
 
void getRemotePIDs(const Tpetra::Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &RemotePIDs)
Get a list of remote PIDs from an importer in the order corresponding to the remote LIDs.
 
void getPidGidPairs(const Tpetra::Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< std::pair< int, GlobalOrdinal > > &gpids, bool use_minus_one_for_local)
For each GID in the TargetMap, find who owns the GID in the SourceMap.
 
Stand-alone utility functions and macros.
 
Struct that holds views of the contents of a CrsMatrix.
 
Sets up and executes a communication plan for a Tpetra DistObject.
 
Namespace Tpetra contains the class and methods constituting the Tpetra library.