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);
101namespace Import_Util {
103template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
106 Teuchos::Array< std::pair<int,GlobalOrdinal> >&
gpids,
117 size_t N =
Importer.getTargetMap()->getLocalNumElements();
124 Teuchos::ArrayView<const int>
ProcsFrom =
D.getProcsFrom();
125 Teuchos::ArrayView<const size_t>
LengthsFrom =
D.getLengthsFrom();
148template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
151 Teuchos::Array<int>&
pids,
155 pids.resize(
Importer.getTargetMap()->getLocalNumElements());
161template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
164 Teuchos::ArrayView<int>&
pids,
172 size_t N =
Importer.getTargetMap()->getLocalNumElements();
173 if(
N!=(
size_t)
pids.size())
throw std::runtime_error(
"Tpetra::Import_Util::getPids(): Incorrect size for output array");
180 Teuchos::ArrayView<const int>
ProcsFrom =
D.getProcsFrom();
181 Teuchos::ArrayView<const size_t>
LengthsFrom =
D.getLengthsFrom();
201template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
213 Teuchos::ArrayView<const int>
ProcsFrom =
D.getProcsFrom();
214 Teuchos::ArrayView<const size_t>
LengthsFrom =
D.getLengthsFrom();
235template <
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
245 if (!
source->isDistributed())
return true;
253 const int MyPID = comm->getRank();
254 const int NumProcs = comm->getSize();
261 std::ostringstream
os;
268 Teuchos::ArrayView<const LocalOrdinal> remoteLIDs =
Importer.getRemoteLIDs();
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) {
323 if((
size_t) tlid < Importer.getNumSameIDs()) {
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;
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.