42 #ifndef TPETRA_IMPORT_UTIL_HPP 
   43 #define TPETRA_IMPORT_UTIL_HPP 
   51 #include "Tpetra_ConfigDefs.hpp" 
   52 #include "Tpetra_Import.hpp" 
   53 #include "Tpetra_HashTable.hpp" 
   54 #include "Tpetra_Map.hpp" 
   56 #include "Tpetra_Distributor.hpp" 
   57 #include <Teuchos_Array.hpp> 
   61   namespace Import_Util {
 
   68     template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   71                     Teuchos::Array< std::pair<int,GlobalOrdinal> >& gpids,
 
   72                     bool use_minus_one_for_local);
 
   75     template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   78              Teuchos::Array<int>& pids,
 
   79              bool use_minus_one_for_local);
 
   83     template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   86              Teuchos::ArrayView<int>& pids,
 
   87              bool use_minus_one_for_local);
 
   92     template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
   95                    Teuchos::Array<int>& RemotePIDs);
 
  101 namespace Import_Util {
 
  103 template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  106                 Teuchos::Array< std::pair<int,GlobalOrdinal> >& gpids,
 
  107                 bool use_minus_one_for_local)
 
  116   int mypid = Importer.
getTargetMap()->getComm()->getRank();
 
  117   size_t N  = Importer.
getTargetMap()->getNodeNumElements();
 
  120   Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs  = Importer.
getRemoteLIDs();
 
  124   Teuchos::ArrayView<const int> ProcsFrom      = D.
getProcsFrom();
 
  125   Teuchos::ArrayView<const size_t> LengthsFrom = D.
getLengthsFrom();
 
  131   LocalOrdinal lzero = Teuchos::ScalarTraits<LocalOrdinal>::zero();
 
  132   if(use_minus_one_for_local)
 
  133     for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) gpids[ii]=std::make_pair(-1,Importer.
getTargetMap()->getGlobalElement(ii));
 
  135     for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) gpids[ii]=std::make_pair(mypid,Importer.
getTargetMap()->getGlobalElement(ii));
 
  139   for(i=0,j=0; i<NumReceives; i++){
 
  140     int pid=ProcsFrom[i];
 
  141     for(k=0; k<LengthsFrom[i]; k++){
 
  142       if(pid!=mypid) gpids[RemoteLIDs[j]].first=pid;
 
  148 template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  151          Teuchos::Array<int>& pids,
 
  152          bool use_minus_one_for_local)
 
  155   pids.resize(Importer.
getTargetMap()->getNodeNumElements());
 
  156   Teuchos::ArrayView<int> v_pids = pids();
 
  157   getPids(Importer,v_pids,use_minus_one_for_local);
 
  161 template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  164          Teuchos::ArrayView<int>& pids,
 
  165          bool use_minus_one_for_local)
 
  171   int mypid = Importer.
getTargetMap()->getComm()->getRank();
 
  172   size_t N  = Importer.
getTargetMap()->getNodeNumElements();
 
  173   if(N!=(
size_t)pids.size()) 
throw std::runtime_error(
"Tpetra::Import_Util::getPids(): Incorrect size for output array");
 
  176   Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs  = Importer.
getRemoteLIDs();
 
  180   Teuchos::ArrayView<const int> ProcsFrom      = D.
getProcsFrom();
 
  181   Teuchos::ArrayView<const size_t> LengthsFrom = D.
getLengthsFrom();
 
  184   LocalOrdinal lzero = Teuchos::ScalarTraits<LocalOrdinal>::zero();
 
  185   if(use_minus_one_for_local)
 
  186     for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) pids[ii]=-1;
 
  188     for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) pids[ii]=mypid;
 
  192   for(i=0,j=0; i<NumReceives; i++){
 
  193     int pid=ProcsFrom[i];
 
  194     for(k=0; k<LengthsFrom[i]; k++){
 
  195       if(pid!=mypid) pids[RemoteLIDs[j]]=pid;
 
  201 template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  204                Teuchos::Array<int>& RemotePIDs)
 
  209   Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs  = Importer.
getRemoteLIDs();
 
  213   Teuchos::ArrayView<const int> ProcsFrom      = D.
getProcsFrom();
 
  214   Teuchos::ArrayView<const size_t> LengthsFrom = D.
getLengthsFrom();
 
  223   for (i = 0, j = 0; i < NumReceives; ++i) {
 
  224     const int pid = ProcsFrom[i];
 
  225     for (k = 0; k < LengthsFrom[i]; ++k) {
 
  235 template <
typename LocalOrdinal, 
typename GlobalOrdinal, 
typename Node>
 
  240   RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > source = Importer.
getSourceMap();
 
  241   RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > target = Importer.
getTargetMap();
 
  242   RCP<const Teuchos::Comm<int> > comm = source->getComm();
 
  245   if (!source->isDistributed()) 
return true;
 
  247   int global_is_valid=0;
 
  252   LocalOrdinal LO_INVALID = Teuchos::OrdinalTraits<LocalOrdinal>::invalid();
 
  253   const int MyPID    = comm->getRank();
 
  254   const int NumProcs = comm->getSize();
 
  256   GlobalOrdinal minSourceGID = source->getMinAllGlobalIndex();
 
  257   GlobalOrdinal maxSourceGID = source->getMaxAllGlobalIndex();
 
  258   GlobalOrdinal minTargetGID = target->getMinAllGlobalIndex();
 
  259   GlobalOrdinal maxTargetGID = target->getMaxAllGlobalIndex();
 
  261   std::ostringstream os;
 
  267   Teuchos::ArrayView<const LocalOrdinal> permuteTarget = Importer.
getPermuteToLIDs();
 
  268   Teuchos::ArrayView<const LocalOrdinal> remoteLIDs    = Importer.
getRemoteLIDs();
 
  269   Teuchos::ArrayView<const LocalOrdinal> exportLIDs    = Importer.
getExportLIDs();
 
  270   Teuchos::ArrayView<const LocalOrdinal> exportPIDs    = Importer.
getExportPIDs();
 
  271   Teuchos::Array<int> remotePIDs; getRemotePIDs(Importer,remotePIDs);
 
  274   Teuchos::Array<GlobalOrdinal> remoteGIDs(remoteLIDs.size());
 
  275   for(
size_t i=0; i<(size_t)remoteLIDs.size(); i++) {
 
  276     remoteGIDs[i] = target->getGlobalElement(remoteLIDs[i]);
 
  277     if(remoteGIDs[i]<0) {
 
  278       os<<MyPID<<
"ERROR3: source->getGlobalElement(remoteLIDs[l]) is invalid GID="<<remoteGIDs[i]<<
" LID= "<<remoteLIDs[i]<<std::endl;
 
  283   Teuchos::Array<GlobalOrdinal> exportGIDs(exportLIDs.size(),-1);
 
  284   for(
size_t i=0; i<(size_t)exportLIDs.size(); i++) {
 
  285     exportGIDs[i] = source->getGlobalElement(exportLIDs[i]);
 
  286     exportGIDs[i]=source->getGlobalElement(exportLIDs[i]);
 
  287     if(exportGIDs[i]<0) {
 
  288       os<<MyPID<<
"ERROR3: source->getGlobalElement(exportLIDs[l]) is invalid GID="<<exportGIDs[i]<<
" LID= "<<exportLIDs[i]<<std::endl;
 
  294   for( 
auto &&rgid : remoteGIDs) {
 
  295     if(std::find(exportGIDs.begin(),exportGIDs.end(),rgid) != exportGIDs.end()) {
 
  297         os<<MyPID<<
"ERROR0: Overlap between remoteGIDs and exportGIDs "<<rgid<<std::endl;
 
  301   int TempPID , OwningPID;
 
  302   for(GlobalOrdinal i=minSourceGID; i<maxSourceGID; i++) {
 
  306     LocalOrdinal slid = source->getLocalElement(i);    
 
  307     if(slid == LO_INVALID) TempPID = -1;
 
  308     else TempPID = MyPID;
 
  309     Teuchos::reduceAll<int, int> (*comm, Teuchos::REDUCE_MAX,TempPID, Teuchos::outArg(OwningPID));
 
  312     LocalOrdinal tlid = target->getLocalElement(i);    
 
  314     if(tlid != LO_INVALID) {
 
  319       if(OwningPID == -1) 
continue;
 
  321       if (OwningPID == MyPID) {
 
  329     for (
size_t j=0; j<(size_t)permuteTarget.size(); j++) {
 
  330       if(tlid == permuteTarget[j]) {
 
  339   bool already_hit = 
false;
 
  340   for(
size_t j=0; j<(size_t)remoteGIDs.size(); j++) {
 
  341     if(i == remoteGIDs[j]) {
 
  348       if(OwningPID == remotePIDs[j]) {
 
  356         os<<MyPID<<
"  ERROR1: GID "<<i<<
" should be remoted from PID "<<OwningPID<<
" but isn't."<<std::endl;
 
  366   Teuchos::Array<int> local_proc_mask(NumProcs,0), global_proc_mask(NumProcs,0);
 
  369   for(GlobalOrdinal i=minTargetGID; i<maxTargetGID; i++) {
 
  372     LocalOrdinal tlid = target->getLocalElement(i);    
 
  373     LocalOrdinal slid = source->getLocalElement(i);    
 
  375     if(tlid==LO_INVALID) local_proc_mask[MyPID] = 0;
 
  376     else local_proc_mask[MyPID] = 1;
 
  378     Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,NumProcs, &local_proc_mask[0],&global_proc_mask[0]);
 
  381     if(slid !=LO_INVALID) {
 
  383       for(
int j=0; j<NumProcs; j++) {
 
  384   if(j==MyPID) 
continue; 
 
  385   if(global_proc_mask[j]==1) {
 
  388     bool already_hit = 
false;
 
  389     for(
size_t k=0; k<(size_t)exportPIDs.size(); k++) {
 
  390       if (exportPIDs[k] == j && source->getGlobalElement(exportLIDs[k]) == i) {
 
  403       os<<MyPID<<
" ERROR2: GID "<<i<<
" should be sent to PID "<<j<<
" but isn't"<<std::endl;
 
  413   Teuchos::Array<int> proc_num_exports_recv(NumProcs,0);
 
  415   Teuchos::Array<int> remoteGIDcount(remoteGIDs.size(),0);
 
  418   Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,exportGIDs.size(),  Teuchos::outArg(allexpsiz));
 
  420   for(
int i=0;i<allexpsiz;++i) {
 
  421     Teuchos::Array<GlobalOrdinal> myexpgid(NumProcs,-2), yourexpgid(NumProcs,-2);
 
  422     Teuchos::Array<int> myexppid(NumProcs,-2), yourexppid(NumProcs,-2);
 
  423     if(i<exportGIDs.size()) {
 
  424       myexpgid[MyPID] = exportGIDs[i];
 
  425       myexppid[MyPID] = exportPIDs[i];
 
  427     Teuchos::reduceAll<int,GlobalOrdinal>(*comm,Teuchos::REDUCE_MAX,NumProcs, &myexpgid[0],&yourexpgid[0]);
 
  428     Teuchos::reduceAll<int,int>(*comm,Teuchos::REDUCE_MAX,NumProcs, &myexppid[0],&yourexppid[0]);
 
  429     for(
int p=0;p<NumProcs;++p) { 
 
  430       GlobalOrdinal cgid = yourexpgid[p];
 
  432       if(cgid == -2) 
continue;
 
  434         os<<MyPID<<
" ERROR4: received exportGID is invalid "<<cgid<<std::endl;
 
  438       for(
size_t k=0;k<(size_t)remoteGIDs.size();++k) {
 
  439         if(cgid == remoteGIDs[k] && yourexppid[p] == MyPID ) {
 
  440           if(p != remotePIDs[k]) {
 
  441             os<<MyPID<<
" ERROR5: receive export from wrong pid: got "<<p<<
" expected: "<<remotePIDs[k]<<std::endl;
 
  446             os<<MyPID<<
" ERROR6: found multiple GIDs from correct pid: GID  "<<remoteGIDs[k]<<std::endl;
 
  452       if(!foundit &&  yourexppid[p] == MyPID ) {
 
  453         os<<MyPID<<
" ERROR7: receive gid  "<<cgid<<
" that is not in my remote gid list, from pid  "<<p<<std::endl;
 
  460   for(
size_t i = 0; i< (size_t) remoteGIDcount.size(); ++i) {
 
  461     int rc = remoteGIDcount[i];
 
  462     if(rc == 1) 
continue;
 
  463     os<<MyPID<<
" ERROR8: my remote at "<<i<<
" gid "<<remoteGIDs[i]<<
" has count "<<rc<<std::endl;
 
  469   Teuchos::reduceAll<int,int> (*comm, Teuchos::REDUCE_MIN,(int)is_valid, Teuchos::outArg(global_is_valid));
 
  471   if(!global_is_valid) {
 
  472     std::cerr<<os.str()<<std::flush;
 
  473     Importer.
print(std::cout);
 
  476   return global_is_valid>0;
 
  484 #endif // TPETRA_IMPORT_UTIL_HPP 
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
size_t getNumReceives() const 
The number of processes from which we will receive data. 
Teuchos::ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent. 
Teuchos::ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted. 
Teuchos::RCP< const map_type > getTargetMap() const
The target Map used to construct this Export or Import. 
size_t getNumSameIDs() const
Number of initial identical IDs. 
Teuchos::ArrayView< const size_t > getLengthsFrom() const 
Number of values this process will receive from each process. 
Teuchos::ArrayView< const int > getProcsFrom() const 
Ranks of the processes sending values to this process. 
size_t getNumRemoteIDs() const
Number of entries not on the calling process. 
Teuchos::ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes. 
Sets up and executes a communication plan for a Tpetra DistObject. 
Teuchos::RCP< const map_type > getSourceMap() const
The source Map used to construct this Export or Import. 
Teuchos::ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes. 
::Tpetra::Distributor & getDistributor() const
The Distributor that this Export or Import object uses to move data. 
Stand-alone utility functions and macros. 
virtual void print(std::ostream &os) const 
Print the Import's data to the given output stream.