size_t AbstractConcreteMatrixAdapter< Epetra_RowMatrix, DerivedMat>::getGlobalRowNNZ_impl(global_ordinal_t row) const { // check whether row is local, then transform to local index Epetra_Map rowmap = this->mat_->RowMatrixRowMap(); int gid = Teuchos::as<int>(row); TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyGID(gid), std::invalid_argument, "The specified global row id does not belong to me" ); int lid = rowmap.LID(gid); int nnz = 0; this->mat_->NumMyRowEntries(lid, nnz); return nnz; }
int main(int narg, char *arg[]) { using std::cout; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&narg,&arg); Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif int me = comm.MyPID(); int np = comm.NumProc(); ITYPE nGlobalRows = 10; if (narg > 1) nGlobalRows = (ITYPE) atol(arg[1]); bool verbose = (nGlobalRows < 20); // Linear map similar to Trilinos default, // but want to allow adding OFFSET_EPETRA64 to the indices. int nMyRows = (int) (nGlobalRows / np + (nGlobalRows % np > me)); ITYPE myFirstRow = (ITYPE)(me * (nGlobalRows / np) + MIN(nGlobalRows%np, me)); ITYPE *myGlobalRows = new ITYPE[nMyRows]; for (int i = 0; i < nMyRows; i++) myGlobalRows[i] = (ITYPE)i + myFirstRow + OFFSET_EPETRA64; Epetra_Map *rowMap = new Epetra_Map(-1, nMyRows, &myGlobalRows[0], 0, comm); if (verbose) rowMap->Print(std::cout); // Create an integer vector nnzPerRow that is used to build the Epetra Matrix. // nnzPerRow[i] is the number of entries for the ith local equation std::vector<int> nnzPerRow(nMyRows+1, 0); // Also create lists of the nonzeros to be assigned to processors. // To save programming time and complexity, these vectors are allocated // bigger than they may actually be needed. std::vector<ITYPE> iv(3*nMyRows+1); std::vector<ITYPE> jv(3*nMyRows+1); std::vector<double> vv(3*nMyRows+1); // Generate the nonzeros for the Laplacian matrix. ITYPE nMyNonzeros = 0; for (ITYPE i = 0, myrowcnt = 0; i < nGlobalRows; i++) { if (rowMap->MyGID(i+OFFSET_EPETRA64)) { // This processor owns this row; add nonzeros. if (i > 0) { iv[nMyNonzeros] = i + OFFSET_EPETRA64; jv[nMyNonzeros] = i-1 + OFFSET_EPETRA64; vv[nMyNonzeros] = -1; if (verbose) std::cout << "(" << iv[nMyNonzeros] << "," << jv[nMyNonzeros] << ")=" << vv[nMyNonzeros] << " on processor " << me << " in " << myrowcnt << std::endl; nMyNonzeros++; nnzPerRow[myrowcnt]++; } iv[nMyNonzeros] = i + OFFSET_EPETRA64; jv[nMyNonzeros] = i + OFFSET_EPETRA64; vv[nMyNonzeros] = ((i == 0 || i == nGlobalRows-1) ? 1. : 2.); if (verbose) std::cout << "(" << iv[nMyNonzeros] << "," << jv[nMyNonzeros] << ")=" << vv[nMyNonzeros] << " on processor " << me << " in " << myrowcnt << std::endl; nMyNonzeros++; nnzPerRow[myrowcnt]++; if (i < nGlobalRows - 1) { iv[nMyNonzeros] = i + OFFSET_EPETRA64; jv[nMyNonzeros] = i+1 + OFFSET_EPETRA64; vv[nMyNonzeros] = -1; if (verbose) std::cout << "(" << iv[nMyNonzeros] << "," << jv[nMyNonzeros] << ")=" << vv[nMyNonzeros] << " on processor " << me << " in " << myrowcnt << std::endl; nMyNonzeros++; nnzPerRow[myrowcnt]++; } myrowcnt++; } } // Create an Epetra_Matrix Epetra_CrsMatrix *A = new Epetra_CrsMatrix(Copy, *rowMap, &nnzPerRow[0], false); // Insert the nonzeros. int info; ITYPE sum = 0; for (int i=0; i < nMyRows; i++) { if (nnzPerRow[i]) { if (verbose) { std::cout << "InsertGlobalValus row " << iv[sum] << " count " << nnzPerRow[i] << " cols " << jv[sum] << " " << jv[sum+1] << " "; if (nnzPerRow[i] == 3) std::cout << jv[sum+2]; std::cout << std::endl; } info = A->InsertGlobalValues(iv[sum],nnzPerRow[i],&vv[sum],&jv[sum]); assert(info==0); sum += nnzPerRow[i]; } } // Finish up info = A->FillComplete(); assert(info==0); if (verbose) A->Print(std::cout); // Sanity test: Product of matrix and vector of ones should have norm == 0 // and max/min/mean values of 0 Epetra_Vector sanity(A->RangeMap()); Epetra_Vector sanityres(A->DomainMap()); sanity.PutScalar(1.); A->Multiply(false, sanity, sanityres); double jjone, jjtwo, jjmax; sanityres.Norm1(&jjone); sanityres.Norm2(&jjtwo); sanityres.NormInf(&jjmax); if (me == 0) std::cout << "SanityTest norms 1/2/inf: " << jjone << " " << jjtwo << " " << jjmax << std::endl; bool test_failed = (jjone != 0) || (jjtwo != 0) || (jjmax != 0); sanityres.MinValue(&jjone); sanityres.MeanValue(&jjtwo); sanityres.MaxValue(&jjmax); if (me == 0) std::cout << "SanityTest values min/max/avg: " << jjone << " " << jjmax << " " << jjtwo << std::endl; test_failed = test_failed || (jjone != 0) || (jjtwo != 0) || (jjmax != 0); if (me == 0) { if(test_failed) std::cout << "Bug_5794_IndexBase_LL tests FAILED" << std::endl; } delete A; delete rowMap; delete [] myGlobalRows; FINALIZE; }
int checkmap(Epetra_Map & Map, int NumGlobalElements, int NumMyElements, int *MyGlobalElements, int IndexBase, Epetra_Comm& Comm, bool DistributedGlobal) { int i, ierr=0, forierr = 0; EPETRA_TEST_ERR(!Map.ConstantElementSize(),ierr); EPETRA_TEST_ERR(DistributedGlobal!=Map.DistributedGlobal(),ierr); EPETRA_TEST_ERR(Map.ElementSize()!=1,ierr); int *MyElementSizeList = new int[NumMyElements]; EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr); forierr = 0; for (i=0; i<NumMyElements; i++) forierr += MyElementSizeList[i]!=1; EPETRA_TEST_ERR(forierr,ierr); delete [] MyElementSizeList; 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()!=1,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); EPETRA_TEST_ERR(Map.MinElementSize()!=1,ierr); EPETRA_TEST_ERR(Map.MinLID()!=0,ierr); int MinMyGID = Comm.MyPID()*NumMyElements+IndexBase; if (Comm.MyPID()>2) MinMyGID+=3; if (!DistributedGlobal) MinMyGID = 0; 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()!=NumGlobalElements,ierr); EPETRA_TEST_ERR(Map.NumMyElements()!=NumMyElements,ierr); EPETRA_TEST_ERR(Map.NumMyPoints()!=NumMyElements,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); // Check RemoteIDList function // 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]; 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); 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]; } 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 [] MyGlobalElements1; // 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); }
void build_simple_matrix( Epetra_Comm &comm, // Communicator to use Epetra_CrsMatrix *&A, // OUTPUT: Matrix returned itype nGlobalRows, // Number of global matrix rows and columns bool testEpetra64, // if true, add 2*INT_MAX to each global ID // to exercise Epetra64 bool verbose // if true, print out matrix information ) { Epetra_Map *rowMap = NULL; // Row map for the created matrix Epetra_Map *colMap = NULL; // Col map for the created matrix Epetra_Map *vectorMap = NULL; // Range/Domain map for the created matrix long long offsetEpetra64; build_maps(nGlobalRows, testEpetra64, comm, &vectorMap, &rowMap, &colMap, offsetEpetra64, verbose); // Create an integer vector nnzPerRow that is used to build the Epetra Matrix. // nnzPerRow[i] is the number of entries for the ith global equation int nMyRows = rowMap->NumMyElements(); std::vector<int> nnzPerRow(nMyRows+1, 0); // Also create lists of the nonzeros to be assigned to processors. // To save programming time and complexity, these vectors are allocated // bigger than they may actually be needed. std::vector<itype> iv(3*nMyRows+1); std::vector<itype> jv(3*nMyRows+1); std::vector<double> vv(3*nMyRows+1); itype nMyNonzeros = 0; for (itype i = 0, myrowcnt = 0; i < nGlobalRows; i++) { if (rowMap->MyGID(i+offsetEpetra64)) { // This processor owns part of this row; see whether it owns the nonzeros if (i > 0 && (!colMap || colMap->MyGID(i-1+offsetEpetra64))) { iv[nMyNonzeros] = i + offsetEpetra64; jv[nMyNonzeros] = i-1 + offsetEpetra64; vv[nMyNonzeros] = -1; nMyNonzeros++; nnzPerRow[myrowcnt]++; } if (!colMap || colMap->MyGID(i+offsetEpetra64)) { iv[nMyNonzeros] = i + offsetEpetra64; jv[nMyNonzeros] = i + offsetEpetra64; vv[nMyNonzeros] = ((i == 0 || i == nGlobalRows-1) ? 1. : 2.); nMyNonzeros++; nnzPerRow[myrowcnt]++; } if (i < nGlobalRows - 1 && (!colMap || colMap->MyGID(i+1+offsetEpetra64))) { iv[nMyNonzeros] = i + offsetEpetra64; jv[nMyNonzeros] = i+1 + offsetEpetra64; vv[nMyNonzeros] = -1; nMyNonzeros++; nnzPerRow[myrowcnt]++; } myrowcnt++; } } // Create an Epetra_Matrix A = new Epetra_CrsMatrix(Copy, *rowMap, &nnzPerRow[0], true); int info; for (int sum = 0, i=0; i < nMyRows; i++) { if (nnzPerRow[i]) { info = A->InsertGlobalValues(iv[sum],nnzPerRow[i],&vv[sum],&jv[sum]); assert(info==0); sum += nnzPerRow[i]; } } // Finish up if (vectorMap) info = A->FillComplete(*vectorMap, *vectorMap); else info = A->FillComplete(); assert(info==0); }