//============================================================================== // Epetra_OffsetIndex constructor from Importer Epetra_OffsetIndex::Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph, const Epetra_CrsGraph & TargetGraph, Epetra_Import & Importer ) : Epetra_Object("Epetra::OffsetIndex"), NumSame_(0), SameOffsets_(0), NumPermute_(0), PermuteOffsets_(0), NumExport_(0), NumRemote_(0), RemoteOffsets_(0), DataOwned_(true) { NumSame_ = Importer.NumSameIDs(); NumPermute_ = Importer.NumPermuteIDs(); int * PermuteLIDs = Importer.PermuteToLIDs(); NumExport_ = Importer.NumExportIDs(); int * ExportLIDs = Importer.ExportLIDs(); NumRemote_ = Importer.NumRemoteIDs(); int * RemoteLIDs = Importer.RemoteLIDs(); if(!SourceGraph.RowMap().GlobalIndicesTypeMatch(TargetGraph.RowMap())) throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: SourceGraph and TargetGraph global indices type mismatch", -1); if(SourceGraph.RowMap().GlobalIndicesInt()) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES GenerateLocalOffsets_<int>( SourceGraph, TargetGraph, PermuteLIDs ); GenerateRemoteOffsets_<int>( SourceGraph, TargetGraph, ExportLIDs, RemoteLIDs, Importer.Distributor() ); #else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: ERROR, GlobalIndicesInt but no API for it.",-1); #endif } else if(SourceGraph.RowMap().GlobalIndicesLongLong()) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES GenerateLocalOffsets_<long long>( SourceGraph, TargetGraph, PermuteLIDs ); GenerateRemoteOffsets_<long long>( SourceGraph, TargetGraph, ExportLIDs, RemoteLIDs, Importer.Distributor() ); #else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: ERROR, GlobalIndicesLongLong but no API for it.",-1); #endif } else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: SourceGraph global indices type unknown", -1); }
int Epetra_Util::GetPidGidPairs(const Epetra_Import & Importer,std::vector< std::pair<int,long long> > & gpids, bool use_minus_one_for_local){ // Put the (PID,GID) pair in member of Importer.TargetMap() in gpids. If use_minus_one_for_local==true, put in -1 instead of MyPID. // This only works if we have an MpiDistributor in our Importer. Otheriwise return an error. #ifdef HAVE_MPI Epetra_MpiDistributor *D=dynamic_cast<Epetra_MpiDistributor*>(&Importer.Distributor()); if(!D) EPETRA_CHK_ERR(-2); int i,j,k; int mypid=Importer.TargetMap().Comm().MyPID(); int N=Importer.TargetMap().NumMyElements(); // Get the importer's data const int *RemoteLIDs = Importer.RemoteLIDs(); // Get the distributor's data int NumReceives = D->NumReceives(); const int *ProcsFrom = D->ProcsFrom(); const int *LengthsFrom = D->LengthsFrom(); // Resize the outgoing data structure gpids.resize(N); // Start by claiming that I own all the data if(use_minus_one_for_local) for(i=0;i <N; i++) gpids[i]=std::make_pair(-1,Importer.TargetMap().GID64(i)); else for(i=0;i <N; i++) gpids[i]=std::make_pair(mypid,Importer.TargetMap().GID64(i)); // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the // MpiDistributor so it ought to duplicate that effect. for(i=0,j=0;i<NumReceives;i++){ int pid=ProcsFrom[i]; for(k=0;k<LengthsFrom[i];k++){ if(pid!=mypid) gpids[RemoteLIDs[j]].first=pid; j++; } } return 0; #else EPETRA_CHK_ERR(-10); #endif }
//---------------------------------------------------------------------------- int Epetra_Util::GetPids(const Epetra_Import & Importer, std::vector<int> &pids, bool use_minus_one_for_local){ #ifdef HAVE_MPI Epetra_MpiDistributor *D=dynamic_cast<Epetra_MpiDistributor*>(&Importer.Distributor()); if(!D) EPETRA_CHK_ERR(-2); int i,j,k; int mypid=Importer.TargetMap().Comm().MyPID(); int N=Importer.TargetMap().NumMyElements(); // Get the importer's data const int *RemoteLIDs = Importer.RemoteLIDs(); // Get the distributor's data int NumReceives = D->NumReceives(); const int *ProcsFrom = D->ProcsFrom(); const int *LengthsFrom = D->LengthsFrom(); // Resize the outgoing data structure pids.resize(N); // Start by claiming that I own all the data if(use_minus_one_for_local) for(i=0; i<N; i++) pids[i]=-1; else for(i=0; i<N; i++) pids[i]=mypid; // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the // MpiDistributor so it ought to duplicate that effect. for(i=0,j=0;i<NumReceives;i++){ int pid=ProcsFrom[i]; for(k=0;k<LengthsFrom[i];k++){ if(pid!=mypid) pids[RemoteLIDs[j]]=pid; j++; } } return 0; #else EPETRA_CHK_ERR(-10); #endif }
//============================================================================= int Epetra_DistObject::Export(const Epetra_SrcDistObject& A, const Epetra_Import& Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor) { if (!Map_.SameAs(Importer.SourceMap())) EPETRA_CHK_ERR(-2); if (!A.Map().SameAs(Importer.TargetMap())) EPETRA_CHK_ERR(-3); int NumSameIDs = Importer.NumSameIDs(); int NumPermuteIDs = Importer.NumPermuteIDs(); int NumRemoteIDs = Importer.NumExportIDs(); int NumExportIDs = Importer.NumRemoteIDs(); int* ExportLIDs = Importer.RemoteLIDs(); int* RemoteLIDs = Importer.ExportLIDs(); int* PermuteToLIDs = Importer.PermuteFromLIDs(); int* PermuteFromLIDs = Importer.PermuteToLIDs(); EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs, PermuteToLIDs, PermuteFromLIDs, RemoteLIDs, ExportLIDs, LenImports_, Imports_, LenExports_, Exports_, Importer.Distributor(), true, Indexor)); return(0); }