// FIXME long long Epetra_BlockMap Epetra_Util::Create_OneToOne_BlockMap(const Epetra_BlockMap& usermap, bool high_rank_proc_owns_shared) { // FIXME long long //if usermap is already 1-to-1 then we'll just return a copy of it. if (usermap.IsOneToOne()) { Epetra_BlockMap newmap(usermap); return(newmap); } int myPID = usermap.Comm().MyPID(); Epetra_Directory* directory = usermap.Comm().CreateDirectory(usermap); int numMyElems = usermap.NumMyElements(); const int* myElems = usermap.MyGlobalElements(); int* owner_procs = new int[numMyElems*2]; int* sizes = owner_procs+numMyElems; directory->GetDirectoryEntries(usermap, numMyElems, myElems, owner_procs, 0, sizes, high_rank_proc_owns_shared); //we'll fill a list of map-elements which belong on this processor int* myOwnedElems = new int[numMyElems*2]; int* ownedSizes = myOwnedElems+numMyElems; int numMyOwnedElems = 0; for(int i=0; i<numMyElems; ++i) { int GID = myElems[i]; int owner = owner_procs[i]; if (myPID == owner) { ownedSizes[numMyOwnedElems] = sizes[i]; myOwnedElems[numMyOwnedElems++] = GID; } } Epetra_BlockMap one_to_one_map(-1, numMyOwnedElems, myOwnedElems, sizes, usermap.IndexBase(), usermap.Comm()); delete [] myOwnedElems; delete [] owner_procs; delete directory; return(one_to_one_map); }
Teuchos::Array<int> Albany::NodeGIDsSolutionCullingStrategy:: selectedGIDs(const Epetra_BlockMap &sourceMap) const { Teuchos::Array<int> result; { Teuchos::Array<int> mySelectedGIDs; // Subract 1 to convert exodus GIDs to our GIDs for (int i=0; i<nodeGIDs_.size(); i++) if (sourceMap.MyGID(nodeGIDs_[i] -1) ) mySelectedGIDs.push_back(nodeGIDs_[i] - 1); const Epetra_Comm &comm = sourceMap.Comm(); { int selectedGIDCount; { int mySelectedGIDCount = mySelectedGIDs.size(); comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1); } result.resize(selectedGIDCount); } const int ierr = Epetra::GatherAllV( comm, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
MapEpetra::MapEpetra ( const Epetra_BlockMap& blockMap, const Int offset, const Int maxId) : M_commPtr(blockMap.Comm().Clone()) { std::vector<Int> myGlobalElements; Int* sourceGlobalElements ( blockMap.MyGlobalElements() ); Int const startIdOrig ( offset ); Int const endIdOrig ( startIdOrig + maxId ); const Int maxMyElements = std::min ( maxId, blockMap.NumMyElements() ); myGlobalElements.reserve ( maxMyElements ); //Sort MyGlobalElements to avoid a bug in Trilinos (9?) when multiplying two matrices (A * B^T) std::sort ( myGlobalElements.begin(), myGlobalElements.end() ); // We consider that the source Map may not be ordered for ( Int i (0); i < blockMap.NumMyElements(); ++i ) if ( sourceGlobalElements[i] < endIdOrig && sourceGlobalElements[i] >= startIdOrig ) { myGlobalElements.push_back ( sourceGlobalElements[i] - offset ); } createMap ( -1, myGlobalElements.size(), &myGlobalElements.front(), *M_commPtr ); }
void EpetraCrsGraph::describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const { XPETRA_MONITOR("EpetraCrsGraph::describe"); out << "EpetraCrsGraph::describe : Warning, verbosity level is ignored by this method." << std::endl; const Epetra_BlockMap rowmap = graph_->RowMap(); if (rowmap.Comm().MyPID() == 0) out << "** EpetraCrsGraph **\n\nrowmap" << std::endl; rowmap.Print(out); graph_->Print(out); }
ArrayRCP<zgno_t> roundRobinMap(const Epetra_BlockMap &emap) { const Epetra_Comm &comm = emap.Comm(); int proc = comm.MyPID(); int nprocs = comm.NumProc(); zgno_t basegid = emap.MinAllGID(); zgno_t maxgid = emap.MaxAllGID(); size_t nglobalrows = emap.NumGlobalElements(); return roundRobinMapShared(proc, nprocs, basegid, maxgid, nglobalrows); }
//EpetraMap_To_TpetraMap: takes in Epetra_Map object, converts it to its equivalent Tpetra::Map object, //and returns an RCP pointer to this Tpetra::Map Teuchos::RCP<const Tpetra_Map> Petra::EpetraMap_To_TpetraMap(const Epetra_BlockMap& epetraMap_, const Teuchos::RCP<const Teuchos::Comm<int> >& commT_) { const std::size_t numElements = Teuchos::as<std::size_t>(epetraMap_.NumMyElements()); const auto indexBase = Teuchos::as<GO>(epetraMap_.IndexBase()); if (epetraMap_.DistributedGlobal() || epetraMap_.Comm().NumProc() == Teuchos::OrdinalTraits<int>::one()) { Teuchos::Array<Tpetra_GO> indices(numElements); int *epetra_indices = epetraMap_.MyGlobalElements(); for(LO i=0; i < numElements; i++) indices[i] = epetra_indices[i]; const Tpetra::global_size_t computeGlobalElements = Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(); return Teuchos::rcp(new Tpetra_Map(computeGlobalElements, indices, indexBase, commT_)); } else { return Teuchos::rcp(new Tpetra_Map(numElements, indexBase, commT_, Tpetra::LocallyReplicated)); } }
Teuchos::Array<int> Albany::NodeSetSolutionCullingStrategy:: selectedGIDs(const Epetra_BlockMap &sourceMap) const { Teuchos::Array<int> result; { Teuchos::Array<int> mySelectedGIDs; { const NodeSetList &nodeSets = disc_->getNodeSets(); const NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel_); if (it != nodeSets.end()) { typedef NodeSetList::mapped_type NodeSetEntryList; const NodeSetEntryList &sampleNodeEntries = it->second; for (NodeSetEntryList::const_iterator jt = sampleNodeEntries.begin(); jt != sampleNodeEntries.end(); ++jt) { typedef NodeSetEntryList::value_type NodeEntryList; const NodeEntryList &sampleEntries = *jt; for (NodeEntryList::const_iterator kt = sampleEntries.begin(); kt != sampleEntries.end(); ++kt) { mySelectedGIDs.push_back(sourceMap.GID(*kt)); } } } } const Epetra_Comm &comm = sourceMap.Comm(); { int selectedGIDCount; { int mySelectedGIDCount = mySelectedGIDs.size(); comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1); } result.resize(selectedGIDCount); } const int ierr = Epetra::GatherAllV( comm, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
// ============================================================================ std::shared_ptr<const Tpetra::Map<int,int>> BorderingHelpers:: extendMapBy1(const Epetra_BlockMap & map) { const Teuchos::Comm<int> & comm = map.Comm(); // Create a new map that hosts one more entry. const int numGlobalElements = map.NumGlobalElements() + 1; const int numMyElements = map.NumMyElements(); int * myGlobalElements = map.MyGlobalElements(); // The following if-else construction just makes sure that // the Tpetra::Map<int,int> constructor is called with an extended // map on proc 0, and with the regular old stuff on all // other procs. std::shared_ptr<Tpetra::Map<int,int>> extendedMap; if (comm.MyPID() == 0) { // Copy over the global indices. std::vector<int> a(numMyElements+1); for (int k = 0; k < numMyElements; k++) a[k] = myGlobalElements[k]; // Append one more. a[numMyElements] = map.NumGlobalElements(); extendedMap = std::make_shared<Tpetra::Map<int,int>>( numGlobalElements, numMyElements+1, &a[0], map.IndexBase(), comm ); } else { extendedMap = std::make_shared<Tpetra::Map<int,int>>( numGlobalElements, numMyElements, myGlobalElements, map.IndexBase(), comm ); } return extendedMap; }
Teuchos::Array<int> Albany::UniformSolutionCullingStrategy:: selectedGIDs(const Epetra_BlockMap &sourceMap) const { Teuchos::Array<int> allGIDs(sourceMap.NumGlobalElements()); { const int ierr = Epetra::GatherAllV( sourceMap.Comm(), sourceMap.MyGlobalElements(), sourceMap.NumMyElements(), allGIDs.getRawPtr(), allGIDs.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(allGIDs.begin(), allGIDs.end()); Teuchos::Array<int> result(numValues_); const int stride = 1 + (allGIDs.size() - 1) / numValues_; for (int i = 0; i < numValues_; ++i) { result[i] = allGIDs[i * stride]; } return result; }
//========================================================================= int Ifpack_CrsRiluk::BlockMap2PointMap(const Epetra_BlockMap & BlockMap, Teuchos::RefCountPtr<Epetra_Map>* PointMap) { // Generate an Epetra_Map that has the same number and distribution of points // as the input Epetra_BlockMap object. The global IDs for the output PointMap // are computed by using the MaxElementSize of the BlockMap. For variable block // sizes this will create gaps in the GID space, but that is OK for Epetra_Maps. int MaxElementSize = BlockMap.MaxElementSize(); int PtNumMyElements = BlockMap.NumMyPoints(); vector<int> PtMyGlobalElements; if (PtNumMyElements>0) PtMyGlobalElements.resize(PtNumMyElements); int NumMyElements = BlockMap.NumMyElements(); int curID = 0; for (int i=0; i<NumMyElements; i++) { int StartID = BlockMap.GID(i)*MaxElementSize; int ElementSize = BlockMap.ElementSize(i); for (int j=0; j<ElementSize; j++) PtMyGlobalElements[curID++] = StartID+j; } assert(curID==PtNumMyElements); // Sanity test (*PointMap) = Teuchos::rcp( new Epetra_Map(-1, PtNumMyElements, &PtMyGlobalElements[0], BlockMap.IndexBase(), BlockMap.Comm()) ); if (!BlockMap.PointSameAs(*(*PointMap))) {EPETRA_CHK_ERR(-1);} // Maps not compatible return(0); }
//============================================================================== // Epetra_Export constructor for a Epetra_BlockMap object Epetra_Export::Epetra_Export( const Epetra_BlockMap & SourceMap, const Epetra_BlockMap & TargetMap) : Epetra_Object("Epetra::Export"), TargetMap_(TargetMap), SourceMap_(SourceMap), NumSameIDs_(0), NumPermuteIDs_(0), PermuteToLIDs_(0), PermuteFromLIDs_(0), NumRemoteIDs_(0), RemoteLIDs_(0), NumExportIDs_(0), ExportLIDs_(0), ExportPIDs_(0), NumSend_(0), NumRecv_(0), Distor_(0) { 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 *TargetGIDs = 0; if (NumTargetIDs>0) { TargetGIDs = new int[NumTargetIDs]; TargetMap.MyGlobalElements(TargetGIDs); } int * SourceGIDs = 0; if (NumSourceIDs>0) { SourceGIDs = new int[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 * ExportGIDs = 0; if (NumExportIDs_>0) { ExportLIDs_ = new int[NumExportIDs_]; ExportGIDs = new int[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 * NewExportGIDs = 0; int * NewExportPIDs = 0; int * NewExportLIDs = 0; int cnt1 = NumExportIDs_-cnt; if (cnt1) { NewExportGIDs = new int[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; int * tmpPtr[2]; tmpPtr[0] = ExportLIDs_, tmpPtr[1] = ExportGIDs; util.Sort(true,NumExportIDs_,ExportPIDs_,0,0,2,tmpPtr); 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 ), LenCRemoteGIDs, cRemoteGIDs); if (ierr) throw ReportError("Error in Epetra_Distributor.Do()", ierr); int * RemoteGIDs = reinterpret_cast<int*>(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 (NumExportIDs_>0) delete [] ExportGIDs; if (LenCRemoteGIDs>0) delete [] cRemoteGIDs; } if (NumTargetIDs>0) delete [] TargetGIDs; if (NumSourceIDs>0) delete [] SourceGIDs; return; }
int LOCA::Epetra::AugmentedOp::blockMap2PointMap(const Epetra_BlockMap& BlockMap, Epetra_Map*& PointMap) const { // Generate an Epetra_Map that has the same number and distribution of points // as the input Epetra_BlockMap object. The global IDs for the output PointMap // are computed by using the MaxElementSize of the BlockMap. For variable block // sizes this will create gaps in the GID space, but that is OK for Epetra_Maps. int MaxElementSize = BlockMap.MaxElementSize(); int PtNumMyElements = BlockMap.NumMyPoints(); int * PtMyGlobalElements = 0; if (PtNumMyElements>0) PtMyGlobalElements = new int[PtNumMyElements]; int NumMyElements = BlockMap.NumMyElements(); int curID = 0; for (int i=0; i<NumMyElements; i++) { int StartID = BlockMap.GID(i)*MaxElementSize; int ElementSize = BlockMap.ElementSize(i); for (int j=0; j<ElementSize; j++) PtMyGlobalElements[curID++] = StartID+j; } assert(curID==PtNumMyElements); // Sanity test PointMap = new Epetra_Map(-1, PtNumMyElements, PtMyGlobalElements, BlockMap.IndexBase(), BlockMap.Comm()); if (PtNumMyElements>0) delete [] PtMyGlobalElements; if (!BlockMap.PointSameAs(*PointMap)) {EPETRA_CHK_ERR(-1);} // Maps not compatible return(0); }
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; }
int BlockMapToMatrixMarketFile( const char *filename, const Epetra_BlockMap & map, const char * mapName, const char *mapDescription, bool writeHeader) { int M = map.NumGlobalElements(); int N = 1; if (map.MaxElementSize()>1) N = 2; // Non-trivial block map, store element sizes in second column FILE * handle = 0; if (map.Comm().MyPID()==0) { // Only PE 0 does this section handle = fopen(filename,"w"); if (!handle) return(-1); MM_typecode matcode; mm_initialize_typecode(&matcode); mm_set_matrix(&matcode); mm_set_array(&matcode); mm_set_integer(&matcode); if (writeHeader==true) { // Only write header if requested (true by default) if (mm_write_banner(handle, matcode)) return(-1); if (mapName!=0) fprintf(handle, "%% \n%% %s\n", mapName); if (mapDescription!=0) fprintf(handle, "%% %s\n%% \n", mapDescription); } } if (writeHeader==true) { // Only write header if requested (true by default) // Make an Epetra_IntVector of length numProc such that all elements are on PE 0 and // the ith element is NumMyElements from the ith PE Epetra_Map map1(-1, 1, 0, map.Comm()); // map with one element on each processor int length = 0; if (map.Comm().MyPID()==0) length = map.Comm().NumProc(); Epetra_Map map2(-1, length, 0, map.Comm()); Epetra_Import lengthImporter(map2, map1); Epetra_IntVector v1(map1); Epetra_IntVector v2(map2); v1[0] = map.NumMyElements(); if (v2.Import(v1, lengthImporter, Insert)) return(-1); if (map.Comm().MyPID()==0) { fprintf(handle, "%s", "%Format Version:\n"); //int version = 1; // We may change the format scheme at a later date. fprintf(handle, "%% %d \n", map.Comm().NumProc()); fprintf(handle, "%s", "%NumProc: Number of processors:\n"); fprintf(handle, "%% %d \n", map.Comm().NumProc()); fprintf(handle, "%s", "%MaxElementSize: Maximum element size:\n"); fprintf(handle, "%% %d \n", map.MaxElementSize()); fprintf(handle, "%s", "%MinElementSize: Minimum element size:\n"); fprintf(handle, "%% %d \n", map.MinElementSize()); fprintf(handle, "%s", "%IndexBase: Index base of map:\n"); fprintf(handle, "%% %d \n", map.IndexBase()); fprintf(handle, "%s", "%NumGlobalElements: Total number of GIDs in map:\n"); fprintf(handle, "%% %d \n", map.NumGlobalElements()); fprintf(handle, "%s", "%NumMyElements: BlockMap lengths per processor:\n"); for ( int i=0; i< v2.MyLength(); i++) fprintf(handle, "%% %d\n", v2[i]); if (mm_write_mtx_array_size(handle, M, N)) return(-1); } } if (BlockMapToHandle(handle, map)) return(-1); // Everybody calls this routine if (map.Comm().MyPID()==0) // Only PE 0 opened a file if (fclose(handle)) return(-1); return(0); }
int BlockMapToHandle(FILE * handle, const Epetra_BlockMap & map) { const Epetra_Comm & comm = map.Comm(); int numProc = comm.NumProc(); bool doSizes = !map.ConstantElementSize(); if (numProc==1) { int * myElements = map.MyGlobalElements(); int * elementSizeList = 0; if (doSizes) elementSizeList = map.ElementSizeList(); return(writeBlockMap(handle, map.NumGlobalElements(), myElements, elementSizeList, doSizes)); } int numRows = map.NumMyElements(); Epetra_Map allGidsMap(-1, numRows, 0,comm); Epetra_IntVector allGids(allGidsMap); for (int i=0; i<numRows; i++) allGids[i] = map.GID(i); Epetra_IntVector allSizes(allGidsMap); for (int i=0; i<numRows; i++) allSizes[i] = map.ElementSize(i); // Now construct a Map on PE 0 by strip-mining the rows of the input matrix map. int numChunks = numProc; int stripSize = allGids.GlobalLength()/numChunks; int remainder = allGids.GlobalLength()%numChunks; int curStart = 0; int curStripSize = 0; Epetra_IntSerialDenseVector importGidList; Epetra_IntSerialDenseVector importSizeList; if (comm.MyPID()==0) { importGidList.Size(stripSize+1); // Set size of vector to max needed if (doSizes) importSizeList.Size(stripSize+1); // Set size of vector to max needed } for (int i=0; i<numChunks; i++) { if (comm.MyPID()==0) { // Only PE 0 does this part curStripSize = stripSize; if (i<remainder) curStripSize++; // handle leftovers for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart; curStart += curStripSize; } // The following import map will be non-trivial only on PE 0. Epetra_Map importGidMap(-1, curStripSize, importGidList.Values(), 0, comm); Epetra_Import gidImporter(importGidMap, allGidsMap); Epetra_IntVector importGids(importGidMap); if (importGids.Import(allGids, gidImporter, Insert)) return(-1); Epetra_IntVector importSizes(importGidMap); if (doSizes) if (importSizes.Import(allSizes, gidImporter, Insert)) return(-1); // importGids (and importSizes, if non-trivial block map) // now have a list of GIDs (and sizes, respectively) for the current strip of map. int * myElements = importGids.Values(); int * elementSizeList = 0; if (doSizes) elementSizeList = importSizes.Values(); // Finally we are ready to write this strip of the map to file writeBlockMap(handle, importGids.MyLength(), myElements, elementSizeList, doSizes); } return(0); }
int MatrixMarketFileToMultiVector( const char *filename, const Epetra_BlockMap & map, Epetra_MultiVector * & A) { const int lineLength = 1025; const int tokenLength = 35; char line[lineLength]; char token1[tokenLength]; char token2[tokenLength]; char token3[tokenLength]; char token4[tokenLength]; char token5[tokenLength]; int M, N; FILE * handle = 0; handle = fopen(filename,"r"); // Open file if (handle == 0) EPETRA_CHK_ERR(-1); // file not found // Check first line, which should be "%%MatrixMarket matrix coordinate real general" (without quotes) if(fgets(line, lineLength, handle)==0) return(-1); if(sscanf(line, "%s %s %s %s %s", token1, token2, token3, token4, token5 )==0) return(-1); if (strcmp(token1, "%%MatrixMarket") || strcmp(token2, "matrix") || strcmp(token3, "array") || strcmp(token4, "real") || strcmp(token5, "general")) return(-1); // Next, strip off header lines (which start with "%") do { if(fgets(line, lineLength, handle)==0) return(-1); } while (line[0] == '%'); // Next get problem dimensions: M, N if(sscanf(line, "%d %d", &M, &N)==0) return(-1); // Compute the offset for each processor for when it should start storing values int numMyPoints = map.NumMyPoints(); int offset; map.Comm().ScanSum(&numMyPoints, &offset, 1); // ScanSum will compute offsets for us offset -= numMyPoints; // readjust for my PE // Now construct vector/multivector if (N==1) A = new Epetra_Vector(map); else A = new Epetra_MultiVector(map, N); double ** Ap = A->Pointers(); for (int j=0; j<N; j++) { double * v = Ap[j]; // Now read in lines that we will discard for (int i=0; i<offset; i++) if(fgets(line, lineLength, handle)==0) return(-1); // Now read in each value and store to the local portion of the the if the row is owned. double V; for (int i=0; i<numMyPoints; i++) { if(fgets(line, lineLength, handle)==0) return(-1); if(sscanf(line, "%lg\n", &V)==0) return(-1); v[i] = V; } // Now read in the rest of the lines to discard for (int i=0; i < M-numMyPoints-offset; i++) { if(fgets(line, lineLength, handle)==0) return(-1); } } if (fclose(handle)) return(-1); return(0); }
int CopyMultiVector(double** matlabApr, const Epetra_MultiVector& A) { Epetra_BlockMap bmap = A.Map(); const Epetra_Comm & comm = bmap.Comm(); int numProc = comm.NumProc(); if (numProc==1) DoCopyMultiVector(matlabApr, A); else { // In the case of more than one column in the multivector, and writing to MatrixMarket // format, we call this function recursively, passing each vector of the multivector // individually so that we can get all of it written to file before going on to the next // multivector if (A.NumVectors() > 1) { for (int i=0; i < A.NumVectors(); i++) if (CopyMultiVector(matlabApr, *(A(i)))) return(-1); return(0); } Epetra_Map map(-1, bmap.NumMyPoints(), 0, comm); // Create a veiw of this multivector using a map (instead of block map) Epetra_MultiVector A1(View, map, A.Pointers(), A.NumVectors()); int numRows = map.NumMyElements(); Epetra_Map allGidsMap(-1, numRows, 0,comm); Epetra_IntVector allGids(allGidsMap); for (int i=0; i<numRows; i++) allGids[i] = map.GID(i); // Now construct a MultiVector on PE 0 by strip-mining the rows of the input matrix A. int numChunks = numProc; int stripSize = allGids.GlobalLength()/numChunks; int remainder = allGids.GlobalLength()%numChunks; int curStart = 0; int curStripSize = 0; Epetra_IntSerialDenseVector importGidList; int numImportGids = 0; if (comm.MyPID()==0) importGidList.Size(stripSize+1); // Set size of vector to max needed for (int i=0; i<numChunks; i++) { if (comm.MyPID()==0) { // Only PE 0 does this part curStripSize = stripSize; if (i<remainder) curStripSize++; // handle leftovers for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart; curStart += curStripSize; } // The following import map will be non-trivial only on PE 0. Epetra_Map importGidMap(-1, curStripSize, importGidList.Values(), 0, comm); Epetra_Import gidImporter(importGidMap, allGidsMap); Epetra_IntVector importGids(importGidMap); if (importGids.Import(allGids, gidImporter, Insert)) return(-1); // importGids now has a list of GIDs for the current strip of matrix rows. // Use these values to build another importer that will get rows of the matrix. // The following import map will be non-trivial only on PE 0. Epetra_Map importMap(-1, importGids.MyLength(), importGids.Values(), 0, comm); Epetra_Import importer(importMap, map); Epetra_MultiVector importA(importMap, A1.NumVectors()); if (importA.Import(A1, importer, Insert)) return(-1); // Finally we are ready to write this strip of the matrix to ostream if (DoCopyMultiVector(matlabApr, importA)) return(-1); } } return(0); }
int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose) { (void)NumVectors; const Epetra_Comm & Comm = Map.Comm(); int ierr = 0; /* get number of processors and the name of this processor */ // int NumProc = Comm.getNumProc(); int MyPID = Comm.MyPID(); // Construct FEVector if (verbose&&MyPID==0) cout << "constructing Epetra_FEVector" << endl; Epetra_FEVector A(Map, 1); //For an extreme test, we'll have each processor sum-in a 1.0 for All //global ids. int minGID = Map.MinAllGID(); int numGlobalIDs = Map.NumGlobalElements(); //For now we're going to have just one point associated with //each GID (element). int* ptIndices = new int[numGlobalIDs]; double* ptCoefs = new double[numGlobalIDs]; Epetra_IntSerialDenseVector epetra_indices(View, ptIndices, numGlobalIDs); Epetra_SerialDenseVector epetra_coefs(View, ptCoefs, numGlobalIDs); {for(int i=0; i<numGlobalIDs; ++i) { ptIndices[i] = minGID+i; ptCoefs[i] = 1.0; }} if (verbose&&MyPID==0) { cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl; } EPETRA_TEST_ERR( A.SumIntoGlobalValues(numGlobalIDs, ptIndices, ptCoefs), ierr); if (verbose&&MyPID==0) { cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl; } EPETRA_TEST_ERR( A.SumIntoGlobalValues(epetra_indices, epetra_coefs), ierr); if (verbose&&MyPID==0) { cout << "calling A.GlobalAssemble()" << endl; } EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); if (verbose&&MyPID==0) { cout << "after globalAssemble"<<endl; } if (verbose) { A.Print(cout); } //now do a quick test of the copy constructor Epetra_FEVector B(A); double nrm2a, nrm2b; A.Norm2(&nrm2a); B.Norm2(&nrm2b); if (nrm2a != nrm2b) { cerr << "copy-constructor test failed, norm of copy doesn't equal" << " norm of original."<<endl; return(-1); } delete [] ptIndices; delete [] ptCoefs; return(ierr); }
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; }
int checkmap(Epetra_BlockMap & Map, int NumGlobalElements, int NumMyElements, int *MyGlobalElements, int ElementSize, int * ElementSizeList, int NumGlobalPoints, int NumMyPoints, int IndexBase, Epetra_Comm& Comm, bool DistributedGlobal, bool IsOneToOne) { int i, ierr=0, forierr=0;// forierr is used in for loops, then is tested // after for loop completes to see if it is non zero - potentially prevents // thousands of error messages if (ElementSizeList==0) { EPETRA_TEST_ERR(!Map.ConstantElementSize(),ierr); } else EPETRA_TEST_ERR(Map.ConstantElementSize(),ierr); EPETRA_TEST_ERR(DistributedGlobal!=Map.DistributedGlobal(),ierr); EPETRA_TEST_ERR(IsOneToOne!=Map.IsOneToOne(),ierr); int *MyElementSizeList; if (ElementSizeList==0) { EPETRA_TEST_ERR(Map.ElementSize()!=ElementSize,ierr); MyElementSizeList = new int[NumMyElements]; EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr); forierr = 0; for (i=0; i<NumMyElements; i++) forierr += MyElementSizeList[i]!=ElementSize; EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(Map.MaxMyElementSize() != ElementSize,ierr); EPETRA_TEST_ERR(Map.MinMyElementSize() != ElementSize,ierr); } else { MyElementSizeList = new int[NumMyElements]; EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr); int MaxSize = MyElementSizeList[0]; int MinSize = MyElementSizeList[0]; forierr=0; for (i=0; i<NumMyElements; i++) { forierr += MyElementSizeList[i]!=ElementSizeList[i]; if (MyElementSizeList[i] > MaxSize) MaxSize = MyElementSizeList[i]; if (MyElementSizeList[i] < MinSize) MinSize = MyElementSizeList[i]; // Test ElementSize(int LID) method forierr += Map.ElementSize(Map.LID(MyGlobalElements[i])) != ElementSizeList[i]; } EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(MaxSize !=Map.MaxMyElementSize(),ierr); EPETRA_TEST_ERR(MinSize !=Map.MinMyElementSize(),ierr); } const Epetra_Comm & Comm1 = Map.Comm(); EPETRA_TEST_ERR(Comm1.NumProc()!=Comm.NumProc(),ierr); EPETRA_TEST_ERR(Comm1.MyPID()!=Comm.MyPID(),ierr); EPETRA_TEST_ERR(Map.IndexBase()!=IndexBase,ierr); EPETRA_TEST_ERR(!Map.LinearMap() && MyGlobalElements==0,ierr); EPETRA_TEST_ERR(Map.LinearMap() && MyGlobalElements!=0,ierr); EPETRA_TEST_ERR(Map.MaxAllGID()!=NumGlobalElements-1+IndexBase,ierr); EPETRA_TEST_ERR(Map.MaxElementSize()!=ElementSize,ierr); int MaxLID = Map.MaxLID(); EPETRA_TEST_ERR(MaxLID!=NumMyElements-1,ierr); int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; if (!DistributedGlobal) MaxMyGID = NumMyElements-1+IndexBase; EPETRA_TEST_ERR(Map.MaxMyGID()!=MaxMyGID,ierr); EPETRA_TEST_ERR(Map.MinAllGID()!=IndexBase,ierr); if (ElementSizeList==0) { EPETRA_TEST_ERR(Map.MinElementSize()!=ElementSize,ierr); } else EPETRA_TEST_ERR(Map.MinElementSize()!=2,ierr); int MinLID = Map.MinLID(); EPETRA_TEST_ERR(MinLID!=0,ierr); int MinMyGID = Comm.MyPID()*NumMyElements+IndexBase; if (Comm.MyPID()>2) MinMyGID+=3; if (!DistributedGlobal) MinMyGID = IndexBase; // Not really needed EPETRA_TEST_ERR(Map.MinMyGID()!=MinMyGID,ierr); int * MyGlobalElements1 = new int[NumMyElements]; EPETRA_TEST_ERR(Map.MyGlobalElements(MyGlobalElements1)!=0,ierr); forierr = 0; if (MyGlobalElements==0) { for (i=0; i<NumMyElements; i++) forierr += MyGlobalElements1[i]!=MinMyGID+i; EPETRA_TEST_ERR(forierr,ierr); } else { for (i=0; i<NumMyElements; i++) forierr += MyGlobalElements[i]!=MyGlobalElements1[i]; EPETRA_TEST_ERR(forierr,ierr); } EPETRA_TEST_ERR(Map.NumGlobalElements()!=NumGlobalElements,ierr); EPETRA_TEST_ERR(Map.NumGlobalPoints()!=NumGlobalPoints,ierr); EPETRA_TEST_ERR(Map.NumMyElements()!=NumMyElements,ierr); EPETRA_TEST_ERR(Map.NumMyPoints()!=NumMyPoints,ierr); int MaxMyGID2 = Map.GID(Map.LID(MaxMyGID)); EPETRA_TEST_ERR(MaxMyGID2 != MaxMyGID,ierr); int MaxLID2 = Map.LID(Map.GID(MaxLID)); EPETRA_TEST_ERR(MaxLID2 != MaxLID,ierr); EPETRA_TEST_ERR(Map.GID(MaxLID+1) != IndexBase-1,ierr);// MaxLID+1 doesn't exist EPETRA_TEST_ERR(Map.LID(MaxMyGID+1) != -1,ierr);// MaxMyGID+1 doesn't exist or is on a different processor EPETRA_TEST_ERR(!Map.MyGID(MaxMyGID),ierr); EPETRA_TEST_ERR(Map.MyGID(MaxMyGID+1),ierr); EPETRA_TEST_ERR(!Map.MyLID(MaxLID),ierr); EPETRA_TEST_ERR(Map.MyLID(MaxLID+1),ierr); EPETRA_TEST_ERR(!Map.MyGID(Map.GID(MaxLID)),ierr); EPETRA_TEST_ERR(Map.MyGID(Map.GID(MaxLID+1)),ierr); EPETRA_TEST_ERR(!Map.MyLID(Map.LID(MaxMyGID)),ierr); EPETRA_TEST_ERR(Map.MyLID(Map.LID(MaxMyGID+1)),ierr); // Test the FirstPointInElementList methods, begin by testing that they produce identical results int * FirstPointInElementList = new int[NumMyElements+1]; Map.FirstPointInElementList(FirstPointInElementList); int * FirstPointInElementList1 = Map.FirstPointInElementList(); forierr = 0; for (i=0; i<=NumMyElements; i++) forierr += FirstPointInElementList[i]!=FirstPointInElementList1[i]; EPETRA_TEST_ERR(forierr,ierr); // Now make sure values are correct forierr = 0; if (Map.ConstantElementSize()) { for (i=0; i<=NumMyElements; i++) forierr += FirstPointInElementList1[i]!=(i*ElementSize);// NOTE:FirstPointInElement[NumMyElements] is not the first point of an element EPETRA_TEST_ERR(forierr,ierr); } else { int FirstPoint = 0; for (i=0; i<NumMyElements; i++) { forierr += FirstPointInElementList1[i]!=FirstPoint; FirstPoint += ElementSizeList[i]; } EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(FirstPointInElementList[NumMyElements] != NumMyPoints,ierr);// The last entry in the array = the total number of Points on the proc } delete [] FirstPointInElementList; // Declare some variables for the FindLocalElementID test int ElementID, Offset; // Test the PointToElementList methods, begin by testing that they produce identical results int * PointToElementList = new int[NumMyPoints]; Map.PointToElementList(PointToElementList); int * PointToElementList1 = Map.PointToElementList(); forierr = 0; for (i=0; i<NumMyPoints; i++) forierr += PointToElementList1[i] != PointToElementList[i]; EPETRA_TEST_ERR(forierr,ierr); //Now make sure values are correct forierr=0; if (Map.ConstantElementSize()) { for (i=0; i<NumMyElements; i++) for (int j=0; j<ElementSize; j++) { forierr += PointToElementList[i*ElementSize+j] != i; // Test FindLocalElementID method Map.FindLocalElementID(i*ElementSize+j,ElementID,Offset); forierr += ElementID != i || Offset != j; } EPETRA_TEST_ERR(forierr,ierr); } else { int MyPointTot = 0; // Keep track of total number of points in all previously completely checked elements for (i=0; i<NumMyElements; i++) { for (int j=0; j<ElementSizeList[i]; j++) { forierr += PointToElementList[MyPointTot+j] != i; // Test FindLocalElementID method Map.FindLocalElementID(MyPointTot+j,ElementID,Offset); forierr += ElementID != i || Offset != j; } MyPointTot += ElementSizeList[i]; } EPETRA_TEST_ERR(forierr,ierr); } delete [] PointToElementList; // Check RemoteIDList function that includes a parameter for size // Get some GIDs off of each processor to test int TotalNumEle, NumElePerProc, NumProc = Comm.NumProc(); int MinNumEleOnProc; int NumMyEle = Map.NumMyElements(); Comm.MinAll(&NumMyEle,&MinNumEleOnProc,1); if (MinNumEleOnProc > 5) NumElePerProc = 6; else NumElePerProc = MinNumEleOnProc; if (NumElePerProc > 0) { TotalNumEle = NumElePerProc*NumProc; int * MyGIDlist = new int[NumElePerProc]; int * GIDlist = new int[TotalNumEle]; int * PIDlist = new int[TotalNumEle]; int * LIDlist = new int[TotalNumEle]; int * SizeList = new int[TotalNumEle]; for (i=0; i<NumElePerProc; i++) MyGIDlist[i] = MyGlobalElements1[i]; Comm.GatherAll(MyGIDlist,GIDlist,NumElePerProc);// Get a few values from each proc Map.RemoteIDList(TotalNumEle, GIDlist, PIDlist, LIDlist, SizeList); int MyPID= Comm.MyPID(); forierr = 0; for (i=0; i<TotalNumEle; i++) { if (Map.MyGID(GIDlist[i])) { forierr += PIDlist[i] != MyPID; forierr += !Map.MyLID(Map.LID(GIDlist[i])) || Map.LID(GIDlist[i]) != LIDlist[i] || Map.GID(LIDlist[i]) != GIDlist[i]; forierr += SizeList[i] != Map.ElementSize(LIDlist[i]); } else { forierr += PIDlist[i] == MyPID; // If MyGID comes back false, the PID listed should be that of another proc } } EPETRA_TEST_ERR(forierr,ierr); delete [] MyGIDlist; delete [] GIDlist; delete [] PIDlist; delete [] LIDlist; delete [] SizeList; } delete [] MyGlobalElements1; delete [] MyElementSizeList; // Check RemoteIDList function (assumes all maps are linear, even if not stored that way) if (Map.LinearMap()) { int * GIDList = new int[3]; int * PIDList = new int[3]; int * LIDList = new int[3]; int MyPID = Map.Comm().MyPID(); int NumIDs = 0; //GIDList[NumIDs++] = Map.MaxAllGID()+1; // Should return -1 for both PID and LID if (Map.MinMyGID()-1>=Map.MinAllGID()) GIDList[NumIDs++] = Map.MinMyGID()-1; if (Map.MaxMyGID()+1<=Map.MaxAllGID()) GIDList[NumIDs++] = Map.MaxMyGID()+1; Map.RemoteIDList(NumIDs, GIDList, PIDList, LIDList); NumIDs = 0; //EPETRA_TEST_ERR(!(PIDList[NumIDs]==-1),ierr); //EPETRA_TEST_ERR(!(LIDList[NumIDs++]==-1),ierr); if (Map.MinMyGID()-1>=Map.MinAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs++]==MyPID-1),ierr); if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs]==MyPID+1),ierr); if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(LIDList[NumIDs++]==0),ierr); delete [] GIDList; delete [] PIDList; delete [] LIDList; } return (ierr); }
static int compute_hypergraph_metrics(const Epetra_BlockMap &rowmap, const Epetra_BlockMap &colmap, int numGlobalColumns, Isorropia::Epetra::CostDescriber &costs, double &myGoalWeight, double &balance, double &cutn, double &cutl) // output { const Epetra_Comm &comm = rowmap.Comm(); #ifdef HAVE_MPI const Epetra_MpiComm* mpiComm = dynamic_cast<const Epetra_MpiComm*>(&comm); MPI_Comm mcomm = mpiComm->Comm(); #endif int nProcs = comm.NumProc(); int myProc = comm.MyPID(); double min, avg; std::map<int, float> vertexWeights; std::map<int, std::map<int, float > > graphEdgeWeights; std::map<int, float> hyperEdgeWeights; costs.getCosts(vertexWeights, // vertex global ID -> weight graphEdgeWeights, // vertex global ID -> map from neighbor global ID to edge weight hyperEdgeWeights); // hyperedge global ID -> weight Epetra_Vector vwgt(rowmap); int numVWgts = vertexWeights.size(); if (numVWgts > 0){ double *wvals = new double [numVWgts]; int *gids = new int [numVWgts]; std::map<int, float>::iterator vnext = vertexWeights.begin(); int i=0; while (vnext != vertexWeights.end()){ wvals[i] = vnext->second; gids[i] = vnext->first; vnext++; i++; } vwgt.ReplaceGlobalValues(i, wvals, gids); delete [] wvals; delete [] gids; } else{ vwgt.PutScalar(1.0); // default to unit weights } compute_balance(vwgt, myGoalWeight, min, balance, avg); if (balance < 0){ return 1; } /* Compute cutl and cutn. */ int totalHEWeights = 0; int numHEWeights = hyperEdgeWeights.size(); comm.SumAll(&numHEWeights, &totalHEWeights, 1); if ((totalHEWeights > 0) && (totalHEWeights < numGlobalColumns)){ if (myProc == 0) std::cerr << "Must supply either no h.e. weights or else supply at least one for each column" << std::endl; return -1; } std::map<int, float>::iterator heWgtIter; // Create a set containing all the columns in my rows. We assume all // the rows are in the same partition. int numMyCols = colmap.NumMyElements(); std::set<int> colGIDS; std::set<int>::iterator gidIter; for (int j=0; j<numMyCols; j++){ colGIDS.insert(colmap.GID(j)); } /* Divide columns among processes, then each process computes its * assigned columns' cutl and cutn. * TODO - numGlobalColumns can be less than nprocs * Fix this when a process is assigned no columns. TODO */ int ncols = numGlobalColumns / nProcs; int leftover = numGlobalColumns - (nProcs * ncols); std::vector<int> colCount(nProcs, 0); for (int i=0; i<nProcs; i++){ colCount[i] = ncols; if (i < leftover) colCount[i]++; } int *colTotals = NULL; double *colWeights = NULL; if (colCount[myProc] > 0){ colTotals = new int [colCount[myProc]]; if (totalHEWeights > 0){ colWeights = new double [colCount[myProc]]; } } int *colLocal= new int [ncols + 1]; double *localWeights = NULL; if (totalHEWeights > 0){ localWeights = new double [ncols + 1]; } int base = colmap.IndexBase(); int colStart = base; for (int i=0; i<nProcs; i++){ // All processes send info to the process reponsible // for the next group of columns int ncols = colCount[i]; int colEnd = colStart + ncols; for (int j=colStart,k=0; j < colEnd; j++,k++){ gidIter = colGIDS.find(j); if (gidIter != colGIDS.end()){ colLocal[k] = 1; // column j has rows in my partition } else{ colLocal[k] = 0; } if (totalHEWeights > 0){ std::map<int, float>::iterator heWgtIter = hyperEdgeWeights.find(j); if (heWgtIter != hyperEdgeWeights.end()){ // I have the edge weight for column j localWeights[k] = heWgtIter->second; } else{ localWeights[k] = 0.0; } } } #ifdef HAVE_MPI int rc = MPI_Reduce(colLocal, colTotals, ncols, MPI_INT, MPI_SUM, i, mcomm); if (totalHEWeights > 0){ rc = MPI_Reduce(localWeights, colWeights, ncols, MPI_DOUBLE, MPI_SUM, i, mcomm); } // TODO handle possible MPI error #else memcpy(colTotals, colLocal, ncols * sizeof(int)); if (totalHEWeights > 0){ memcpy(colWeights, localWeights, ncols * sizeof(double)); } #endif colStart = colEnd; } delete [] colLocal; if (localWeights) delete [] localWeights; double localCutN=0; double localCutL=0; double ewgt = 1.0; for (int j=0; j<colCount[myProc]; j++){ if (totalHEWeights > 0){ ewgt = colWeights[j]; } if (colTotals[j] > 1){ localCutL += (colTotals[j] - 1) * ewgt; // # of cuts in columns/edges localCutN += ewgt; // # of cut columns/edges } } if (colTotals) delete [] colTotals; if (colWeights) delete [] colWeights; comm.SumAll(&localCutN, &cutn, 1); comm.SumAll(&localCutL, &cutl, 1); return 0; }
static int compute_graph_metrics(const Epetra_BlockMap &rowmap, const Epetra_BlockMap &colmap, std::vector<std::vector<int> > &rows, Isorropia::Epetra::CostDescriber &costs, double &myGoalWeight, double &balance, int &numCuts, double &cutWgt, double &cutn, double &cutl) { const Epetra_Comm &comm = rowmap.Comm(); int myProc = comm.MyPID(); int myCols = colmap.NumMyElements(); double min, avg; std::map<int, float> vertexWeights; std::map<int, std::map<int, float > > graphEdgeWeights; std::map<int, float> hyperEdgeWeights; costs.getCosts(vertexWeights, // vertex global ID -> weight graphEdgeWeights, // vertex global ID -> map from neighbor global ID to edge weight hyperEdgeWeights); // hyperedge global ID -> weight // Compute the balance Epetra_Vector vwgt(rowmap); int numVWgts = vertexWeights.size(); if (numVWgts > 0){ double *wvals = new double [numVWgts]; int *gids = new int [numVWgts]; std::map<int, float>::iterator vnext = vertexWeights.begin(); int i=0; while (vnext != vertexWeights.end()){ wvals[i] = vnext->second; gids[i] = vnext->first; vnext++; i++; } vwgt.ReplaceGlobalValues(i, wvals, gids); delete [] wvals; delete [] gids; } else{ vwgt.PutScalar(1.0); // default to unit weights } compute_balance(vwgt, myGoalWeight, min, balance, avg); if (balance < 0){ return 1; } // Compute the measures based on cut edges int *procID = new int [myCols]; int *GID = new int [myCols]; int *tmp = new int [myCols]; for (int i=0; i < myCols; i++){ GID[i] = colmap.GID(i); } rowmap.RemoteIDList(myCols, GID, procID, tmp); // matrix is square delete [] tmp; int haveEdgeWeights = graphEdgeWeights.size(); int localNumCuts = 0; double localCutWgt = 0.0; double localCutn = 0.0; double localCutl = 0.0; for (int i=0; i < rowmap.NumMyElements(); i++){ int vtxGID = rowmap.GID(i); int numEdges = rows[i].size(); if (numEdges > 0){ std::map<int, std::map<int, float> >::iterator wnext; if (haveEdgeWeights){ wnext = graphEdgeWeights.find(vtxGID); if (wnext == graphEdgeWeights.end()){ std::cerr << "Graph edge weights are missing for vertex " << vtxGID; std::cerr << std::endl; return -1; } } double heWeight = 0.0; std::set<int> nbors; for (int j=0; j < numEdges; j++){ int colGID = GID[rows[i][j]]; int nborProc = procID[rows[i][j]]; if (colGID == vtxGID) continue; // skip self edges float wgt = 1.0; if (haveEdgeWeights){ std::map<int, float>::iterator curr = (wnext->second).find(colGID); if (curr == (wnext->second).end()){ std::cerr << "Graph edge weights do not match matrix"; std::cerr << std::endl; return -1; } wgt = curr->second; } if (nborProc != myProc){ localNumCuts++; // number of graph edges that are cut nbors.insert(nborProc); // count number of neighboring processes localCutWgt += wgt; // sum of weights of cut edges } heWeight += wgt; // implied hyperedge weight, sum all edges } int numNbors = nbors.size(); if (numNbors > 0){ // implied hyperedge is vertex and neighbors, if cut, add in its he weight localCutn += heWeight; // sum of (number of partitions - 1) weighted by the // implied hyperedge weight localCutl += (numNbors * heWeight); } } } // next vertex in my partition delete [] GID; delete [] procID; double lval[4], gval[4]; lval[0] = (double)localNumCuts; lval[1] = localCutWgt; lval[2] = localCutn; lval[3] = localCutl; comm.SumAll(lval, gval, 4); numCuts = (int)gval[0]; cutWgt = gval[1]; cutn = gval[2]; cutl = gval[3]; return 0; }
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; }
int MatrixTests(const Epetra_BlockMap & Map, const Epetra_LocalMap & LocalMap, int NumVectors, bool verbose) { const Epetra_Comm & Comm = Map.Comm(); int ierr = 0, i; int IndexBase = 0; double *residual = new double[NumVectors]; /* get ID of this processor */ // Test GEMM first. 7 cases: // Num // OPERATIONS case Notes // 1) C(local) = A^X(local) * B^X(local) 4 (X=Trans or Not, No Comm needed) // 2) C(local) = A^T(distr) * B (distr) 1 (2D dot product, replicate C) // 3) C(distr) = A (distr) * B^X(local) 2 (2D vector update, no Comm needed) // ================================================================== // Case 1 through 4 (A, B, C all local) Strided and non-strided cases // ================================================================== // Construct MultiVectors { Epetra_MultiVector A(LocalMap, NumVectors); Epetra_MultiVector B(LocalMap, NumVectors); Epetra_LocalMap Map2d(NumVectors, IndexBase, Comm); Epetra_MultiVector C(Map2d, NumVectors); Epetra_MultiVector C_GEMM(Map2d, NumVectors); double **App, **Bpp, **Cpp; Epetra_MultiVector *Ap, *Bp, *Cp; // For testing non-strided mode, create MultiVectors that are scattered throughout memory App = new double *[NumVectors]; Bpp = new double *[NumVectors]; Cpp = new double *[NumVectors]; for (i=0; i<NumVectors; i++) App[i] = new double[A.MyLength()+i]; for (i=0; i<NumVectors; i++) Bpp[i] = new double[B.MyLength()+i]; for (i=0; i<NumVectors; i++) Cpp[i] = new double[C.MyLength()+i]; Epetra_MultiVector A1(View, LocalMap, App, NumVectors); Epetra_MultiVector B1(View, LocalMap, Bpp, NumVectors); Epetra_MultiVector C1(View, Map2d, Cpp, NumVectors); for (int strided = 0; strided<2; strided++) { // Loop through all trans cases using a variety of values for alpha and beta for (i=0; i<4; i++) { char transa = 'N'; if (i>1) transa = 'T'; char transb = 'N'; if (i%2!=0) transb = 'T'; double alpha = (double) i+1; double beta = (double) (i/2); EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers int localierr = BuildMatrixTests(C,transa, transb, alpha, A, B, beta, C_GEMM ); if (localierr!=-2) { // -2 means the shapes didn't match and we skip the tests if (strided) { Ap = &A; Bp = &B; Cp = &C; } else { A.ExtractCopy(App); Ap = &A1; B.ExtractCopy(Bpp); Bp = &B1; C.ExtractCopy(Cpp); Cp = &C1; } localierr = Cp->Multiply(transa, transb, alpha, *Ap, *Bp, beta); if (localierr!=-2) { // -2 means the shapes didn't match and we skip the tests ierr += Cp->Update(-1.0, C_GEMM, 1.0); ierr += Cp->Norm2(residual); if (verbose) { cout << "XXXXX Replicated Local MultiVector GEMM tests"; if (strided) cout << " (Strided Multivectors)" << endl; else cout << " (Non-Strided Multivectors)" << endl; cout << " alpha = " << alpha << ", beta = " << beta <<", transa = "<<transa <<", transb = " << transb; } if (BadResidual(verbose,residual, NumVectors)) return(-1); } } } } for (i=0; i<NumVectors; i++) { delete [] App[i]; delete [] Bpp[i]; delete [] Cpp[i]; } delete [] App; delete [] Bpp; delete [] Cpp; } // ==================================== // Case 5 (A, B distributed C local) // ==================================== // Construct MultiVectors { Epetra_MultiVector A(Map, NumVectors); Epetra_MultiVector B(Map, NumVectors); Epetra_LocalMap Map2d(NumVectors, IndexBase, Comm); Epetra_MultiVector C(Map2d, NumVectors); Epetra_MultiVector C_GEMM(Map2d, NumVectors); char transa = 'T'; char transb = 'N'; double alpha = 2.0; double beta = 1.0; EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers ierr += BuildMatrixTests(C, transa, transb, alpha, A, B, beta, C_GEMM ); int localierr = C.Multiply(transa, transb, alpha, A, B, beta); if (localierr!=-2) { // -2 means the shapes didn't match ierr += C.Update(-1.0, C_GEMM, 1.0); ierr += C.Norm2(residual); if (verbose) { cout << "XXXXX Generalized 2D dot product via GEMM call " << endl; cout << " alpha = " << alpha << ", beta = " << beta <<", transa = "<<transa <<", transb = " << transb; } if (BadResidual(verbose,residual, NumVectors)) return(-1); } } // ==================================== // Case 6-7 (A, C distributed, B local) // ==================================== // Construct MultiVectors { Epetra_MultiVector A(Map, NumVectors); Epetra_LocalMap Map2d(NumVectors, IndexBase, Comm); Epetra_MultiVector B(Map2d, NumVectors); Epetra_MultiVector C(Map, NumVectors); Epetra_MultiVector C_GEMM(Map, NumVectors); for (i=0; i<2; i++) { char transa = 'N'; char transb = 'N'; if (i>0) transb = 'T'; double alpha = 2.0; double beta = 1.1; EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers ierr += BuildMatrixTests(C,transa, transb, alpha, A, B, beta, C_GEMM ); ierr += C.Multiply(transa, transb, alpha, A, B, beta); ierr += C.Update(-1.0, C_GEMM, 1.0); ierr += C.Norm2(residual); if (verbose) { cout << "XXXXX Generalized 2D vector update via GEMM call " << endl; cout << " alpha = " << alpha << ", beta = " << beta <<", transa = "<<transa <<", transb = " << transb; } if (BadResidual(verbose,residual, NumVectors)) return(-1); } } // ==================================== // LocalMap Tests // ==================================== // Construct MultiVectors { int localLength = 10; double *localMinValue = new double[localLength]; double *localMaxValue = new double[localLength]; double *localNorm1 = new double[localLength]; double *localDot = new double[localLength]; double *localNorm2 = new double[localLength]; double *localMeanValue = new double[localLength]; Epetra_LocalMap MapSmall(localLength, IndexBase, Comm); Epetra_MultiVector A(MapSmall, NumVectors); double doubleLocalLength = (double) localLength; for (int j=0; j< NumVectors; j++) { for (i=0; i< localLength-1; i++) A[j][i] = (double) (i+1); A[j][localLength-1] = (double) (localLength+j); // Only the last value differs across multivectors localMinValue[j] = A[j][0]; // Increasing values localMaxValue[j] = A[j][localLength-1]; localNorm1[j] = (doubleLocalLength-1.0)*(doubleLocalLength)/2.0+A[j][localLength-1]; localDot[j] = (doubleLocalLength-1.0)*(doubleLocalLength)*(2.0*(doubleLocalLength-1.0)+1.0)/6.0+A[j][localLength-1]*A[j][localLength-1]; localNorm2[j] = std::sqrt(localDot[j]); localMeanValue[j] = localNorm1[j]/doubleLocalLength; } ierr += A.MinValue(residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMinValue[j]); if (verbose) cout << "XXXXX MinValue" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); ierr += A.MaxValue(residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMaxValue[j]); if (verbose) cout << "XXXXX MaxValue" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); ierr += A.Norm1(residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localNorm1[j]); if (verbose) cout << "XXXXX Norm1" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); ierr += A.Dot(A,residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localDot[j]); if (verbose) cout << "XXXXX Dot" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); ierr += A.Norm2(residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localNorm2[j]); if (verbose) cout << "XXXXX Norm2" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); ierr += A.MeanValue(residual); for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMeanValue[j]); if (verbose) cout << "XXXXX MeanValue" << endl; if (BadResidual(verbose,residual, NumVectors)) return(-1); delete [] localMinValue; delete [] localMaxValue; delete [] localNorm1; delete [] localDot; delete [] localNorm2; delete [] localMeanValue; } delete [] residual; return(ierr); }
int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose) { const Epetra_Comm & Comm = Map.Comm(); int ierr = 0, i; double *residual = new double[NumVectors]; Epetra_BLAS BLAS; /* get number of processors and the name of this processor */ // int NumProc = Comm.getNumProc(); int MyPID = Comm.MyPID(); // Construct MultiVectors Epetra_MultiVector A(Map, NumVectors); Epetra_MultiVector sqrtA(Map, NumVectors); Epetra_MultiVector B(Map, NumVectors); Epetra_MultiVector C(Map, NumVectors); Epetra_MultiVector C_alphaA(Map, NumVectors); Epetra_MultiVector C_alphaAplusB(Map, NumVectors); Epetra_MultiVector C_plusB(Map, NumVectors); Epetra_MultiVector Weights(Map, NumVectors); // Construct double vectors double *dotvec_AB = new double[NumVectors]; double *norm1_A = new double[NumVectors]; double *norm2_sqrtA = new double[NumVectors]; double *norminf_A = new double[NumVectors]; double *normw_A = new double[NumVectors]; double *minval_A = new double[NumVectors]; double *maxval_A = new double[NumVectors]; double *meanval_A = new double[NumVectors]; // Generate data EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers. double alpha = 2.0; BuildMultiVectorTests (C,alpha, A, sqrtA, B, C_alphaA, C_alphaAplusB, C_plusB, dotvec_AB, norm1_A, norm2_sqrtA, norminf_A, normw_A, Weights, minval_A, maxval_A, meanval_A); int err = 0; if (verbose) cout << "XXXXX Testing alpha * A "; // Test alpha*A Epetra_MultiVector alphaA(A); // Copy of A EPETRA_TEST_ERR(alphaA.Scale(alpha),err); EPETRA_TEST_ERR(alphaA.Update(-1.0, C_alphaA, 1.0),err); EPETRA_TEST_ERR(alphaA.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing C = alpha * A + B "; // Test alpha*A + B Epetra_MultiVector alphaAplusB(A); // Copy of A EPETRA_TEST_ERR(alphaAplusB.Update(1.0, B, alpha, A, 0.0),err); EPETRA_TEST_ERR(alphaAplusB.Update(-1.0, C_alphaAplusB, 1.0),err); EPETRA_TEST_ERR(alphaAplusB.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing C += B "; // Test + B Epetra_MultiVector plusB(C); // Copy of C EPETRA_TEST_ERR(plusB.Update(1.0, B, 1.0),err); EPETRA_TEST_ERR(plusB.Update(-1.0, C_plusB, 1.0),err); EPETRA_TEST_ERR(plusB.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing A.dotProd(B) "; // Test A.dotvec(B) double *dotvec = residual; EPETRA_TEST_ERR(A.Dot(B,dotvec),err); BLAS.AXPY(NumVectors,-1.0,dotvec_AB,dotvec); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norm1_A "; // Test A.norm1() double *norm1 = residual; EPETRA_TEST_ERR(A.Norm1(norm1),err); BLAS.AXPY(NumVectors,-1.0,norm1_A,norm1); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norm2_sqrtA "; // Test sqrtA.norm2() double *norm2 = residual; EPETRA_TEST_ERR(sqrtA.Norm2(norm2),err); BLAS.AXPY(NumVectors,-1.0,norm2_sqrtA,norm2); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norminf_A "; // Test A.norminf() double *norminf = residual; EPETRA_TEST_ERR(A.NormInf(norminf),err); BLAS.AXPY(NumVectors,-1.0,norminf_A,norminf); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing normw_A "; // Test A.NormWeighted() double *normw = residual; EPETRA_TEST_ERR(A.NormWeighted(Weights, normw),err); BLAS.AXPY(NumVectors,-1.0,normw_A,normw); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing minval_A "; // Test A.MinValue() double *minval = residual; EPETRA_TEST_ERR(A.MinValue(minval),err); BLAS.AXPY(NumVectors,-1.0,minval_A,minval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing maxval_A "; // Test A.MaxValue() double *maxval = residual; EPETRA_TEST_ERR(A.MaxValue(maxval),err); BLAS.AXPY(NumVectors,-1.0,maxval_A,maxval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing meanval_A "; // Test A.MeanValue() double *meanval = residual; EPETRA_TEST_ERR(A.MeanValue(meanval),err); BLAS.AXPY(NumVectors,-1.0,meanval_A,meanval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing abs_A "; // Test A.Abs() Epetra_MultiVector Abs_A = A; EPETRA_TEST_ERR(Abs_A.Abs(A),err); EPETRA_TEST_ERR(Abs_A.Update(1.0, A, -1.0),err); // Abs_A = A - Abs_A (should be zero since A > 0) EPETRA_TEST_ERR(Abs_A.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test1) "; // Test A.Random() Epetra_MultiVector Rand1_A(A); Epetra_MultiVector Rand2_A(A); EPETRA_TEST_ERR(Rand1_A.Random(),err); EPETRA_TEST_ERR(Rand2_A.Random(),err); // Rand2_A = Rand1_A - Rand2_A (should be nonzero since Random() should give different vectors > 0) EPETRA_TEST_ERR(Rand2_A.Update(1.0, Rand1_A, -1.0),err); EPETRA_TEST_ERR(Rand2_A.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual1(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test2) "; // Next test that each column of the multivector is different from all other columns by testing the first value // of each vector against the first value of every other vector. int randvalsdiffer = 1; // Assume they all differ for (i=0; i< NumVectors; i++) for (int j=i+1; j<NumVectors; j++) if (Rand1_A[i][0]==Rand1_A[j][0]) randvalsdiffer = 0; // make false if equal int allrandvals = 0; Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error int locerr = err; Comm.MinAll(&locerr, &err, 1); if (verbose) { if (err==0) { cout << "\t Checked OK" << endl; } else { cout << "\t Checked Failed" << endl; } } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test3) "; // Next test that the first element on each processor of the first column of Rand1_A is different from all others // First we will gather them all to PE 0 Epetra_Map RandstartsMap(-1, 1, 0, Comm); // This Map has a single element on each PE int itmp = 0; int nproc = Comm.NumProc(); if (MyPID==0) itmp = nproc; Epetra_Map AllrandstartsMap(nproc, itmp, 0, Comm); // Map has NumProc elements on PE 0, none elsewhere Epetra_MultiVector Randstarts(RandstartsMap, NumVectors); Epetra_MultiVector Allrandstarts(AllrandstartsMap, NumVectors); for (i=0; i< NumVectors; i++) Randstarts[i][0] = Rand1_A[i][0]; // Load first value of local multivector Epetra_Import Randimporter(AllrandstartsMap,RandstartsMap); EPETRA_TEST_ERR(Allrandstarts.Import(Randstarts,Randimporter,Insert),err); // cout << "Randstarts = " << Randstarts << endl << "Allrandstarts = " << Allrandstarts << endl; // Allrandstarts now contains the first values for each local section of Rand1_A. // Next test that this is true. randvalsdiffer = 1; // Assume they all differ if (MyPID==0) { for (i=0; i< NumVectors; i++) for (int irand=0; irand<nproc; irand++) for (int jrand=irand+1; jrand<nproc; jrand++) if (Allrandstarts[i][irand]==Allrandstarts[i][jrand]) randvalsdiffer = 0; // make false if equal } allrandvals = 0; Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error locerr = err; Comm.MinAll(&locerr, &err, 1); if (verbose) { if (err==0) { cout << "\t Checked OK" << endl; } else { cout << "\t Checked Failed" << endl; } } // Delete everything delete [] dotvec_AB; delete [] norm1_A; delete [] norm2_sqrtA; delete [] norminf_A; delete [] normw_A; delete [] minval_A; delete [] maxval_A; delete [] meanval_A; delete [] residual; //******************************************************************* // Post-construction modification tests //******************************************************************* if (verbose) cout << "\n\nXXXXX Testing Post-construction modification of a multivector" <<endl<<endl; err = 0; Epetra_MultiVector X(Map, NumVectors); X.Random(); // Pick middle range values for GID, LID and Vector Index int testGID = Map.NumGlobalElements()/2; int testVecIndex = NumVectors/2; int GIDSize = 1; int LIDOfGID = 0; int FirstEntryOfGID = 0; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); GIDSize = Map.ElementSize(LIDOfGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); } // ======================================================================== // Test int ReplaceGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue) // ======================================================================== double newGIDValue = 4.0; locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID]!=newGIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = " << X[testVecIndex][FirstEntryOfGID] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int ReplaceGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 8.0; locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=newGIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfGID+GIDSize-1] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int SumIntoGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 1.0; locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue); locerr = X.SumIntoGlobalValue(testGID, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID]!=(newGIDValue+newGIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = " << X[testVecIndex][FirstEntryOfGID] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int SumIntoGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 1.0; locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); locerr = X.SumIntoGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=(newGIDValue+newGIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfGID+GIDSize-1] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test Local "My" versions of same routine (less complicated) // ======================================================================== // Pick middle range values for LID int testLID = Map.NumMyElements()/2; int LIDSize = Map.ElementSize(testLID); int FirstEntryOfLID = Map.FirstPointInElement(testLID); double newLIDValue = 4.0; locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID]!=newLIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = " << X[testVecIndex][FirstEntryOfLID] << " should = " << newLIDValue << endl; newLIDValue = 8.0; locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=newLIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfLID+LIDSize-1] << " should = " << newLIDValue << endl; newLIDValue = 1.0; locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue); locerr = X.SumIntoMyValue(testLID, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID]!=(newLIDValue+newLIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = " << X[testVecIndex][FirstEntryOfLID] << " should = " << newLIDValue << endl; newLIDValue = 2.0; locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); locerr = X.SumIntoMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfLID+LIDSize-1] << " should = " << newLIDValue << endl; if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=(newLIDValue+newLIDValue)) err++; ierr += err; // ======================================================================== // Test Post-construction modification of an Epetra_Vector using a vector // our multivector X // ======================================================================== if (verbose) cout << "\n\nXXXXX Testing Post-construction modification of a vector" << endl << endl; Epetra_Vector * x = X(testVecIndex); int NumEntries = 2; double * VecValues = new double[NumEntries]; int * VecGIDs = new int[NumEntries]; VecGIDs[0] = testGID; VecGIDs[1] = testGID+1; // Some pathological chance that these GIDs are not valid // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, double *Values, int *Indices) // ======================================================================== VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); GIDSize = EPETRA_MIN(GIDSize,Map.ElementSize(LIDOfGID)); // Need this value below FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfGID<<"] = " << (*x)[FirstEntryOfGID] << " should = " << VecValues[i] << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices) // ======================================================================== VecValues[0] = 4.0; VecValues[1] = 8.0; locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID+GIDSize-1]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = " << (*x)[FirstEntryOfGID+GIDSize-1] << " should = " << VecValues[i] << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int SumIntoGlobalValues (int NumEntries, double *Values, int *Indices) // ======================================================================== VecValues[0] = 1.0; VecValues[1] = 2.0; locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs); locerr = x->SumIntoGlobalValues(NumEntries, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfGID<<"] = " << (*x)[FirstEntryOfGID] << " should = " << (VecValues[i]+VecValues[i]) << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices) // ======================================================================== VecValues[0] = 1.0; VecValues[1] = 2.0; locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); locerr = x->SumIntoGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID+GIDSize-1]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = " << (*x)[FirstEntryOfGID+GIDSize-1] << " should = " << (VecValues[i]+VecValues[i]) << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test Local "My" versions of same routine (less complicated) // ======================================================================== int * VecLIDs = new int[NumEntries]; VecLIDs[0] = testLID; VecLIDs[1] = testLID+1; // Some pathological chance that these LIDs are not valid VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfLID<<"] = " << (*x)[FirstEntryOfLID] << " should = " << VecValues[i] << endl; } VecValues[0] = 4.0; VecValues[1] = 8.0; locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID+LIDSize-1]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = " << (*x)[FirstEntryOfLID+LIDSize-1] << " should = " << VecValues[i] << endl; } VecValues[0] = 1.0; VecValues[1] = 1.0; locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs); locerr = x->SumIntoMyValues(NumEntries, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfLID<<"] = " << (*x)[FirstEntryOfLID] << " should = " << (VecValues[i]+VecValues[i]) << endl; } VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); locerr = x->SumIntoMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID+LIDSize-1]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = " << (*x)[FirstEntryOfLID+LIDSize-1] << " should = " << (VecValues[i]+VecValues[i]) << endl; } delete [] VecValues; delete [] VecGIDs; delete [] VecLIDs; return(ierr); }