//============================================================================= Epetra_LongLongVector::Epetra_LongLongVector(const Epetra_BlockMap& map, bool zeroOut) : Epetra_DistObject(map, "Epetra::LongLongVector"), Values_(0), UserAllocated_(false), Allocated_(false) { if(!map.GlobalIndicesLongLong()) throw ReportError("Epetra_LongLongVector::Epetra_LongLongVector: cannot be called with non long long map index type", -1); AllocateForCopy(); if(zeroOut) PutValue(0); // Zero out values }
int BlockMapToHandle(FILE * handle, const Epetra_BlockMap & map) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(map.GlobalIndicesInt()) { return TBlockMapToHandle<int>(handle, map); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(map.GlobalIndicesLongLong()) { return TBlockMapToHandle<long long>(handle, map); } else #endif throw "EpetraExt::BlockMapToHandle: GlobalIndices type unknown"; }
//============================================================================= Epetra_LongLongVector::Epetra_LongLongVector(Epetra_DataAccess CV, const Epetra_BlockMap& map, long long *V) : Epetra_DistObject(map, "Epetra::LongLongVector"), Values_(0), UserAllocated_(false), Allocated_(false) { if(!map.GlobalIndicesLongLong()) throw ReportError("Epetra_LongLongVector::Epetra_LongLongVector: cannot be called with non long long map index type", -1); if (CV==Copy) { AllocateForCopy(); DoCopy(V); } else { AllocateForView(); DoView(V); } }
void Epetra_Export::Construct( const Epetra_BlockMap & sourceMap, const Epetra_BlockMap & targetMap) { int i; // Build three ID lists: // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first // nonidentical ID. // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor. // NumExportIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be exported. int NumSourceIDs = sourceMap.NumMyElements(); int NumTargetIDs = targetMap.NumMyElements(); int_type *TargetGIDs = 0; if (NumTargetIDs>0) { TargetGIDs = new int_type[NumTargetIDs]; targetMap.MyGlobalElements(TargetGIDs); } int_type * SourceGIDs = 0; if (NumSourceIDs>0) { SourceGIDs = new int_type[NumSourceIDs]; sourceMap.MyGlobalElements(SourceGIDs); } int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs); NumSameIDs_ = 0; for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break; // Find count of Source IDs that are truly remote and those that are local but permuted NumPermuteIDs_ = 0; NumExportIDs_ = 0; for (i=NumSameIDs_; i< NumSourceIDs; i++) if (targetMap.MyGID(SourceGIDs[i])) NumPermuteIDs_++; // Check if Source GID is a local Target GID else NumExportIDs_++; // If not, then it is remote // Define remote and permutation lists int_type * ExportGIDs = 0; if (NumExportIDs_>0) { ExportLIDs_ = new int[NumExportIDs_]; ExportGIDs = new int_type[NumExportIDs_]; } if (NumPermuteIDs_>0) { PermuteToLIDs_ = new int[NumPermuteIDs_]; PermuteFromLIDs_ = new int[NumPermuteIDs_]; } NumPermuteIDs_ = 0; NumExportIDs_ = 0; for (i=NumSameIDs_; i< NumSourceIDs; i++) { if (targetMap.MyGID(SourceGIDs[i])) { PermuteFromLIDs_[NumPermuteIDs_] = i; PermuteToLIDs_[NumPermuteIDs_++] = targetMap.LID(SourceGIDs[i]); } else { //NumSend_ +=sourceMap.ElementSize(i); // Count total number of entries to send NumSend_ +=sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max) ExportGIDs[NumExportIDs_] = SourceGIDs[i]; ExportLIDs_[NumExportIDs_++] = i; } } if ( NumExportIDs_>0 && !sourceMap.DistributedGlobal()) ReportError("Warning in Epetra_Export: Serial Export has remote IDs. (Exporting from Subset of Source Map)", 1); // Test for distributed cases int ierr = 0; if (sourceMap.DistributedGlobal()) { if (NumExportIDs_>0) ExportPIDs_ = new int[NumExportIDs_]; ierr = targetMap.RemoteIDList(NumExportIDs_, ExportGIDs, ExportPIDs_, 0); // Get remote PIDs if( ierr ) throw ReportError("Error in Epetra_BlockMap::RemoteIDList", ierr); //Get rid of IDs not in Target Map if(NumExportIDs_>0) { int cnt = 0; for( i = 0; i < NumExportIDs_; ++i ) if( ExportPIDs_[i] == -1 ) ++cnt; if( cnt ) { int_type * NewExportGIDs = 0; int * NewExportPIDs = 0; int * NewExportLIDs = 0; int cnt1 = NumExportIDs_-cnt; if (cnt1) { NewExportGIDs = new int_type[cnt1]; NewExportPIDs = new int[cnt1]; NewExportLIDs = new int[cnt1]; } cnt = 0; for( i = 0; i < NumExportIDs_; ++i ) if( ExportPIDs_[i] != -1 ) { NewExportGIDs[cnt] = ExportGIDs[i]; NewExportPIDs[cnt] = ExportPIDs_[i]; NewExportLIDs[cnt] = ExportLIDs_[i]; ++cnt; } assert(cnt==cnt1); // Sanity test NumExportIDs_ = cnt; delete [] ExportGIDs; delete [] ExportPIDs_; delete [] ExportLIDs_; ExportGIDs = NewExportGIDs; ExportPIDs_ = NewExportPIDs; ExportLIDs_ = NewExportLIDs; ReportError("Warning in Epetra_Export: Source IDs not found in Target Map (Do you want to export from subset of Source Map?)", 1 ); } } //Make sure Export IDs are ordered by processor Epetra_Util util; if(targetMap.GlobalIndicesLongLong()) { // FIXME (mfh 11 Jul 2013) This breaks ANSI aliasing rules, if // int_type != long long. On some compilers, it results in // warnings such as this: "dereferencing type-punned pointer // will break strict-aliasing rules". util.Sort(true,NumExportIDs_,ExportPIDs_,0,0,1,&ExportLIDs_, 1, (long long **)&ExportGIDs); } else if(targetMap.GlobalIndicesInt()) { int* ptrs[2] = {ExportLIDs_, (int*) ExportGIDs}; util.Sort(true,NumExportIDs_,ExportPIDs_,0,0, 2,&ptrs[0], 0, 0); } else { throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1); } Distor_ = sourceMap.Comm().CreateDistributor(); // Construct list of exports that calling processor needs to send as a result // of everyone asking for what it needs to receive. ierr = Distor_->CreateFromSends( NumExportIDs_, ExportPIDs_, true, NumRemoteIDs_); if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromSends()", ierr); // Use comm plan with ExportGIDs to find out who is sending to us and // get proper ordering of GIDs for remote entries // (that we will convert to LIDs when done). if (NumRemoteIDs_>0) RemoteLIDs_ = new int[NumRemoteIDs_]; // Allocate space for LIDs in target that are // going to get something from off-processor. char * cRemoteGIDs = 0; //Do will alloc memory for this object int LenCRemoteGIDs = 0; ierr = Distor_->Do(reinterpret_cast<char *> (ExportGIDs), sizeof( int_type ), LenCRemoteGIDs, cRemoteGIDs); if (ierr) throw ReportError("Error in Epetra_Distributor.Do()", ierr); int_type * RemoteGIDs = reinterpret_cast<int_type*>(cRemoteGIDs); // Remote IDs come in as GIDs, convert to LIDs for (i=0; i< NumRemoteIDs_; i++) { RemoteLIDs_[i] = targetMap.LID(RemoteGIDs[i]); //NumRecv_ += targetMap.ElementSize(RemoteLIDs_[i]); // Count total number of entries to receive NumRecv_ += targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max) } if (LenCRemoteGIDs>0) delete [] cRemoteGIDs; } if (NumExportIDs_>0) delete [] ExportGIDs; if (NumTargetIDs>0) delete [] TargetGIDs; if (NumSourceIDs>0) delete [] SourceGIDs; return; }
void Epetra_Import::Construct( const Epetra_BlockMap & targetMap, const Epetra_BlockMap & sourceMap) { int i; // Build three ID lists: // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first // nonidentical ID. // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor. // NumRemoteIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be imported. int NumSourceIDs = sourceMap.NumMyElements(); int NumTargetIDs = targetMap.NumMyElements(); int_type *TargetGIDs = 0; if (NumTargetIDs>0) { TargetGIDs = new int_type[NumTargetIDs]; targetMap.MyGlobalElements(TargetGIDs); } int_type * SourceGIDs = 0; if (NumSourceIDs>0) { SourceGIDs = new int_type[NumSourceIDs]; sourceMap.MyGlobalElements(SourceGIDs); } int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs); NumSameIDs_ = 0; for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break; // Find count of Target IDs that are truly remote and those that are local but permuted NumPermuteIDs_ = 0; NumRemoteIDs_ = 0; for (i=NumSameIDs_; i< NumTargetIDs; i++) if (sourceMap.MyGID(TargetGIDs[i])) NumPermuteIDs_++; // Check if Target GID is a local Source GID else NumRemoteIDs_++; // If not, then it is remote // Define remote and permutation lists int_type * RemoteGIDs=0; RemoteLIDs_ = 0; if (NumRemoteIDs_>0) { RemoteLIDs_ = new int[NumRemoteIDs_]; RemoteGIDs = new int_type[NumRemoteIDs_]; } if (NumPermuteIDs_>0) { PermuteToLIDs_ = new int[NumPermuteIDs_]; PermuteFromLIDs_ = new int[NumPermuteIDs_]; } NumPermuteIDs_ = 0; NumRemoteIDs_ = 0; for (i=NumSameIDs_; i< NumTargetIDs; i++) { if (sourceMap.MyGID(TargetGIDs[i])) { PermuteToLIDs_[NumPermuteIDs_] = i; PermuteFromLIDs_[NumPermuteIDs_++] = sourceMap.LID(TargetGIDs[i]); } else { //NumRecv_ +=TargetMap.ElementSize(i); // Count total number of entries to receive NumRecv_ +=targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max) RemoteGIDs[NumRemoteIDs_] = TargetGIDs[i]; RemoteLIDs_[NumRemoteIDs_++] = i; } } if( NumRemoteIDs_>0 && !sourceMap.DistributedGlobal() ) ReportError("Warning in Epetra_Import: Serial Import has remote IDs. (Importing to Subset of Target Map)", 1); // Test for distributed cases int * RemotePIDs = 0; if (sourceMap.DistributedGlobal()) { if (NumRemoteIDs_>0) RemotePIDs = new int[NumRemoteIDs_]; int ierr = sourceMap.RemoteIDList(NumRemoteIDs_, RemoteGIDs, RemotePIDs, 0); // Get remote PIDs if (ierr) throw ReportError("Error in sourceMap.RemoteIDList call", ierr); //Get rid of IDs that don't exist in SourceMap if(NumRemoteIDs_>0) { int cnt = 0; for( i = 0; i < NumRemoteIDs_; ++i ) if( RemotePIDs[i] == -1 ) ++cnt; if( cnt ) { if( NumRemoteIDs_-cnt ) { int_type * NewRemoteGIDs = new int_type[NumRemoteIDs_-cnt]; int * NewRemotePIDs = new int[NumRemoteIDs_-cnt]; int * NewRemoteLIDs = new int[NumRemoteIDs_-cnt]; cnt = 0; for( i = 0; i < NumRemoteIDs_; ++i ) if( RemotePIDs[i] != -1 ) { NewRemoteGIDs[cnt] = RemoteGIDs[i]; NewRemotePIDs[cnt] = RemotePIDs[i]; NewRemoteLIDs[cnt] = targetMap.LID(RemoteGIDs[i]); ++cnt; } NumRemoteIDs_ = cnt; delete [] RemoteGIDs; delete [] RemotePIDs; delete [] RemoteLIDs_; RemoteGIDs = NewRemoteGIDs; RemotePIDs = NewRemotePIDs; RemoteLIDs_ = NewRemoteLIDs; ReportError("Warning in Epetra_Import: Target IDs not found in Source Map (Do you want to import to subset of Target Map?)", 1); } else { //valid RemoteIDs empty NumRemoteIDs_ = 0; delete [] RemoteGIDs; RemoteGIDs = 0; delete [] RemotePIDs; RemotePIDs = 0; } } } //Sort Remote IDs by processor so DoReverses will work Epetra_Util util; if(targetMap.GlobalIndicesLongLong()) { util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0, 1,&RemoteLIDs_, 1,(long long**)&RemoteGIDs); } else if(targetMap.GlobalIndicesInt()) { int* ptrs[2] = {RemoteLIDs_, (int*)RemoteGIDs}; util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0,2,&ptrs[0], 0, 0); } else { throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1); } Distor_ = sourceMap.Comm().CreateDistributor(); // Construct list of exports that calling processor needs to send as a result // of everyone asking for what it needs to receive. bool Deterministic = true; int_type* tmp_ExportLIDs; //Export IDs come in as GIDs ierr = Distor_->CreateFromRecvs( NumRemoteIDs_, RemoteGIDs, RemotePIDs, Deterministic, NumExportIDs_, tmp_ExportLIDs, ExportPIDs_ ); if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromRecvs()", ierr); // Export IDs come in as GIDs, convert to LIDs if(targetMap.GlobalIndicesLongLong()) { ExportLIDs_ = new int[NumExportIDs_]; for (i=0; i< NumExportIDs_; i++) { if (ExportPIDs_[i] < 0) throw ReportError("targetMap requested a GID that is not in the sourceMap.", -1); ExportLIDs_[i] = sourceMap.LID(tmp_ExportLIDs[i]); NumSend_ += sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max) } delete[] tmp_ExportLIDs; } else if(targetMap.GlobalIndicesInt()) { for (i=0; i< NumExportIDs_; i++) { if (ExportPIDs_[i] < 0) throw ReportError("targetMap requested a GID that is not in the sourceMap.", -1); tmp_ExportLIDs[i] = sourceMap.LID(tmp_ExportLIDs[i]); NumSend_ += sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max) } ExportLIDs_ = reinterpret_cast<int *>(tmp_ExportLIDs); // Can't reach here if tmp_ExportLIDs is long long. } else { throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1); } } if( NumRemoteIDs_>0 ) delete [] RemoteGIDs; if( NumRemoteIDs_>0 ) delete [] RemotePIDs; if (NumTargetIDs>0) delete [] TargetGIDs; if (NumSourceIDs>0) delete [] SourceGIDs; return; }
void Epetra_Import::Construct_Expert( const Epetra_BlockMap & targetMap, const Epetra_BlockMap & sourceMap, int NumRemotePIDs, const int * UserRemotePIDs, const int & UserNumExportIDs, const int * UserExportLIDs, const int * UserExportPIDs) { int i,ierr; // Build three ID lists: // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first // nonidentical ID. // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor. // NumRemoteIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be imported. int NumSourceIDs = sourceMap.NumMyElements(); int NumTargetIDs = targetMap.NumMyElements(); int_type *TargetGIDs = 0; if (NumTargetIDs>0) { TargetGIDs = new int_type[NumTargetIDs]; targetMap.MyGlobalElements(TargetGIDs); } int_type * SourceGIDs = 0; if (NumSourceIDs>0) { SourceGIDs = new int_type[NumSourceIDs]; sourceMap.MyGlobalElements(SourceGIDs); } int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs); NumSameIDs_ = 0; for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break; // Find count of Target IDs that are truly remote and those that are local but permuted NumPermuteIDs_ = 0; NumRemoteIDs_ = 0; for (i=NumSameIDs_; i< NumTargetIDs; i++) if (sourceMap.MyGID(TargetGIDs[i])) NumPermuteIDs_++; // Check if Target GID is a local Source GID else NumRemoteIDs_++; // If not, then it is remote // Define remote and permutation lists int_type * RemoteGIDs=0; RemoteLIDs_ = 0; if (NumRemoteIDs_>0) { RemoteLIDs_ = new int[NumRemoteIDs_]; RemoteGIDs = new int_type[NumRemoteIDs_]; } if (NumPermuteIDs_>0) { PermuteToLIDs_ = new int[NumPermuteIDs_]; PermuteFromLIDs_ = new int[NumPermuteIDs_]; } NumPermuteIDs_ = 0; NumRemoteIDs_ = 0; for (i=NumSameIDs_; i< NumTargetIDs; i++) { if (sourceMap.MyGID(TargetGIDs[i])) { PermuteToLIDs_[NumPermuteIDs_] = i; PermuteFromLIDs_[NumPermuteIDs_++] = sourceMap.LID(TargetGIDs[i]); } else { //NumRecv_ +=TargetMap.ElementSize(i); // Count total number of entries to receive NumRecv_ +=targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max) RemoteGIDs[NumRemoteIDs_] = TargetGIDs[i]; RemoteLIDs_[NumRemoteIDs_++] = i; } } if( NumRemoteIDs_>0 && !sourceMap.DistributedGlobal() ) ReportError("Warning in Epetra_Import: Serial Import has remote IDs. (Importing to Subset of Target Map)", 1); // Test for distributed cases int * RemotePIDs = 0; if (sourceMap.DistributedGlobal()) { if (NumRemoteIDs_>0) RemotePIDs = new int[NumRemoteIDs_]; #ifdef EPETRA_ENABLE_DEBUG int myeq = (NumRemotePIDs==NumRemoteIDs_); int globaleq=0; sourceMap.Comm().MinAll(&myeq,&globaleq,1); if(globaleq!=1) { printf("[%d] UserRemotePIDs count wrong %d != %d\n",sourceMap.Comm().MyPID(),NumRemotePIDs,NumRemoteIDs_); fflush(stdout); sourceMap.Comm().Barrier(); sourceMap.Comm().Barrier(); sourceMap.Comm().Barrier(); throw ReportError("Epetra_Import: UserRemotePIDs count wrong"); } #endif if(NumRemotePIDs==NumRemoteIDs_){ // Since I need to sort these, I'll copy them for(i=0; i<NumRemoteIDs_; i++) RemotePIDs[i] = UserRemotePIDs[i]; } //Get rid of IDs that don't exist in SourceMap if(NumRemoteIDs_>0) { int cnt = 0; for( i = 0; i < NumRemoteIDs_; ++i ) if( RemotePIDs[i] == -1 ) ++cnt; if( cnt ) { if( NumRemoteIDs_-cnt ) { int_type * NewRemoteGIDs = new int_type[NumRemoteIDs_-cnt]; int * NewRemotePIDs = new int[NumRemoteIDs_-cnt]; int * NewRemoteLIDs = new int[NumRemoteIDs_-cnt]; cnt = 0; for( i = 0; i < NumRemoteIDs_; ++i ) if( RemotePIDs[i] != -1 ) { NewRemoteGIDs[cnt] = RemoteGIDs[i]; NewRemotePIDs[cnt] = RemotePIDs[i]; NewRemoteLIDs[cnt] = targetMap.LID(RemoteGIDs[i]); ++cnt; } NumRemoteIDs_ = cnt; delete [] RemoteGIDs; delete [] RemotePIDs; delete [] RemoteLIDs_; RemoteGIDs = NewRemoteGIDs; RemotePIDs = NewRemotePIDs; RemoteLIDs_ = NewRemoteLIDs; ReportError("Warning in Epetra_Import: Target IDs not found in Source Map (Do you want to import to subset of Target Map?)", 1); } else { //valid RemoteIDs empty NumRemoteIDs_ = 0; delete [] RemoteGIDs; RemoteGIDs = 0; delete [] RemotePIDs; RemotePIDs = 0; } } } //Sort Remote IDs by processor so DoReverses will work Epetra_Util util; if(targetMap.GlobalIndicesLongLong()) { util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0, 1,&RemoteLIDs_, 1,(long long**)&RemoteGIDs); } else if(targetMap.GlobalIndicesInt()) { int* ptrs[2] = {RemoteLIDs_, (int*)RemoteGIDs}; util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0,2,&ptrs[0], 0, 0); } else { throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1); } // Build distributor & Export lists Distor_ = sourceMap.Comm().CreateDistributor(); NumExportIDs_=UserNumExportIDs; ExportLIDs_ = new int[NumExportIDs_]; ExportPIDs_ = new int[NumExportIDs_]; for(i=0; i<NumExportIDs_; i++) { ExportPIDs_[i] = UserExportPIDs[i]; ExportLIDs_[i] = UserExportLIDs[i]; } #ifdef HAVE_MPI Epetra_MpiDistributor* MpiDistor = dynamic_cast< Epetra_MpiDistributor*>(Distor_); bool Deterministic = true; if(MpiDistor) ierr=MpiDistor->CreateFromSendsAndRecvs(NumExportIDs_,ExportPIDs_, NumRemoteIDs_, RemoteGIDs, RemotePIDs,Deterministic); else ierr=-10; #else ierr=-20; #endif if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromRecvs()", ierr); } if( NumRemoteIDs_>0 ) delete [] RemoteGIDs; if( NumRemoteIDs_>0 ) delete [] RemotePIDs; if (NumTargetIDs>0) delete [] TargetGIDs; if (NumSourceIDs>0) delete [] SourceGIDs; #ifdef EPETRA_ENABLE_DEBUG // Sanity check to make sure we got the import right Epetra_IntVector Source(sourceMap); Epetra_IntVector Target(targetMap); for(i=0; i<Source.MyLength(); i++) Source[i] = (int) (Source.Map().GID(i) % INT_MAX); Target.PutValue(-1); Target.Import(Source,*this,Insert); bool test_passed=true; for(i=0; i<Target.MyLength(); i++){ if(Target[i] != Target.Map().GID(i) % INT_MAX) test_passed=false; } if(!test_passed) { printf("[%d] PROCESSOR has a mismatch... prepearing to crash or hang!\n",sourceMap.Comm().MyPID()); fflush(stdout); sourceMap.Comm().Barrier(); sourceMap.Comm().Barrier(); sourceMap.Comm().Barrier(); throw ReportError("Epetra_Import: ERROR. User provided IDs do not match what an import generates."); } #endif return; }