//============================================================================== int checkCopyAndAssignment(Epetra_Comm& Comm, bool verbose) { int ierr = 0; // check to make sure that copy ctr and op= are working correctly // (making level 1 deep copies) // create initial Map and Graph const int NumIndicesPerRow = 10; const long long NumGlobalElements = 50; const long long IndexBase = 0; Epetra_Map Map1(NumGlobalElements, IndexBase, Comm); Epetra_CrsGraph Graph1(Copy, Map1, NumIndicesPerRow); int g1count = Graph1.ReferenceCount(); const Epetra_CrsGraphData* g1addr = Graph1.DataPtr(); EPETRA_TEST_ERR(!(g1count == 1), ierr); if(verbose) cout << "Graph1 created (def ctr). data addr = " << g1addr << " ref. count = " << g1count << endl; //test copy constructor { Epetra_CrsGraph Graph2(Graph1); int g2count = Graph2.ReferenceCount(); const Epetra_CrsGraphData* g2addr = Graph2.DataPtr(); EPETRA_TEST_ERR(!(g2count == g1count+1), ierr); EPETRA_TEST_ERR(!(g2addr == g1addr), ierr); if(verbose) cout << "Graph2 created (cpy ctr). data addr = " << g2addr << " ref. count = " << g2count << endl; } int g1newcount = Graph1.ReferenceCount(); const Epetra_CrsGraphData* g1newaddr = Graph1.DataPtr(); EPETRA_TEST_ERR(!(g1newcount == g1count), ierr); EPETRA_TEST_ERR(!(g1newaddr = g1addr), ierr); if(verbose) cout << "Graph2 destroyed. Graph1 data addr = " << g1newaddr << " ref. count = " << g1newcount << endl; //test op= Epetra_CrsGraph Graph3(Copy, Map1, NumIndicesPerRow+1); int g3count = Graph3.ReferenceCount(); const Epetra_CrsGraphData* g3addr = Graph3.DataPtr(); EPETRA_TEST_ERR(!(g3addr != g1addr), ierr); if(verbose) cout << "Graph3 created (op= before). data addr = " << g3addr << " ref. count = " << g3count << endl; Graph3 = Graph1; g3count = Graph3.ReferenceCount(); g3addr = Graph3.DataPtr(); EPETRA_TEST_ERR(!(g3count == g1count+1), ierr); EPETRA_TEST_ERR(!(g3addr == g1addr), ierr); if(verbose) cout << "Graph3 set equal to Graph1 (op= after). data addr = " << g3addr << " ref. count = " << g3count << endl; return(ierr); }
//========================================================================= // test matrix copy constructor (copy & view) int matrixCpyCtr(bool verbose, bool debug) { const int m1rows = 5; const int m1cols = 4; const int m2rows = 2; const int m2cols = 6; int ierr = 0; int returnierr = 0; if(verbose) printHeading("Testing matrix copy constructors"); if(verbose) cout << "checking copy constructor (view)" << endl; double* m1rand = getRandArray(m1rows * m1cols); if(debug) printArray(m1rand, m1rows * m1cols); Epetra_SerialDenseMatrix m1(View, m1rand, m1rows, m1rows, m1cols); if(debug) { cout << "original matrix:" << endl; printMat("m1",m1); } Epetra_SerialDenseMatrix m1clone(m1); if(debug) { cout << "clone matrix:" << endl; printMat("m1clone",m1clone); } if(verbose) cout << "making sure signatures match" << endl; EPETRA_TEST_ERR(!identicalSignatures(m1, m1clone), ierr); delete[] m1rand; returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; if(verbose) cout << "\nchecking copy constructor (copy)" << endl; double* m2rand = getRandArray(m2rows * m2cols); if(debug) printArray(m2rand, m2rows * m2cols); Epetra_SerialDenseMatrix m2(Copy, m2rand, m2rows, m2rows, m2cols); if(debug) { cout << "original matrix:" << endl; printMat("m2",m2); } Epetra_SerialDenseMatrix m2clone(m2); if(debug) { cout << "clone matrix:" << endl; printMat("m2clone",m2clone); } if(verbose) cout << "checking that signatures match" << endl; EPETRA_TEST_ERR(!identicalSignatures(m2, m2clone), ierr); returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; if(verbose) cout << "\nmodifying entry in m2, m2clone should be unchanged" << endl; EPETRA_TEST_ERR(!seperateData(m2, m2clone), ierr); if(debug) { printArray(m2rand, m2rows * m2cols); cout << "orig:" << endl; printMat("m2",m2); cout << "clone:" << endl; printMat("m2clone",m2clone); } delete[] m2rand; returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; return(returnierr); }
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); }
int main(int argc, char *argv[]) { int ierr = 0, i, j, k; bool debug = false; #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; if (verbose && Comm.MyPID()==0) cout << Epetra_Version() << endl << endl; int rank = Comm.MyPID(); // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) cout << Comm <<endl; // bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int N = 20; int NRHS = 4; double * A = new double[N*N]; double * A1 = new double[N*N]; double * X = new double[(N+1)*NRHS]; double * X1 = new double[(N+1)*NRHS]; int LDX = N+1; int LDX1 = N+1; double * B = new double[N*NRHS]; double * B1 = new double[N*NRHS]; int LDB = N; int LDB1 = N; int LDA = N; int LDA1 = LDA; double OneNorm1; bool Transpose = false; Epetra_SerialDenseSolver solver; Epetra_SerialDenseMatrix * Matrix; for (int kk=0; kk<2; kk++) { for (i=1; i<=N; i++) { GenerateHilbert(A, LDA, i); OneNorm1 = 0.0; for (j=1; j<=i; j++) OneNorm1 += 1.0/((double) j); // 1-Norm = 1 + 1/2 + ...+1/n if (kk==0) { Matrix = new Epetra_SerialDenseMatrix(View, A, LDA, i, i); LDA1 = LDA; } else { Matrix = new Epetra_SerialDenseMatrix(Copy, A, LDA, i, i); LDA1 = i; } GenerateHilbert(A1, LDA1, i); if (kk==1) { solver.FactorWithEquilibration(true); solver.SolveWithTranspose(true); Transpose = true; solver.SolveToRefinedSolution(true); } for (k=0; k<NRHS; k++) for (j=0; j<i; j++) { B[j+k*LDB] = 1.0/((double) (k+3)*(j+3)); B1[j+k*LDB1] = B[j+k*LDB1]; } Epetra_SerialDenseMatrix Epetra_B(View, B, LDB, i, NRHS); Epetra_SerialDenseMatrix Epetra_X(View, X, LDX, i, NRHS); solver.SetMatrix(*Matrix); solver.SetVectors(Epetra_X, Epetra_B); ierr = check(solver, A1, LDA1, i, NRHS, OneNorm1, B1, LDB1, X1, LDX1, Transpose, verbose); assert (ierr>-1); delete Matrix; if (ierr!=0) { if (verbose) cout << "Factorization failed due to bad conditioning. This is normal if RCOND is small." << endl; break; } } } delete [] A; delete [] A1; delete [] X; delete [] X1; delete [] B; delete [] B1; ///////////////////////////////////////////////////////////////////// // Now test norms and scaling functions ///////////////////////////////////////////////////////////////////// Epetra_SerialDenseMatrix D; double ScalarA = 2.0; int DM = 10; int DN = 8; D.Shape(DM, DN); for (j=0; j<DN; j++) for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ; //cout << D << endl; double NormInfD_ref = (double)(DM*(DN*(DN+1))/2); double NormOneD_ref = (double)((DM*DN*(DM*DN+1))/2 - (DM*(DN-1)*(DM*(DN-1)+1))/2 ); double NormInfD = D.NormInf(); double NormOneD = D.NormOne(); if (verbose) { cout << " *** Before scaling *** " << endl << " Computed one-norm of test matrix = " << NormOneD << endl << " Expected one-norm = " << NormOneD_ref << endl << " Computed inf-norm of test matrix = " << NormInfD << endl << " Expected inf-norm = " << NormInfD_ref << endl; } D.Scale(ScalarA); // Scale entire D matrix by this value NormInfD = D.NormInf(); NormOneD = D.NormOne(); if (verbose) { cout << " *** After scaling *** " << endl << " Computed one-norm of test matrix = " << NormOneD << endl << " Expected one-norm = " << NormOneD_ref*ScalarA << endl << " Computed inf-norm of test matrix = " << NormInfD << endl << " Expected inf-norm = " << NormInfD_ref*ScalarA << endl; } ///////////////////////////////////////////////////////////////////// // Now test that A.Multiply(false, x, y) produces the same result // as y.Multiply('N','N', 1.0, A, x, 0.0). ///////////////////////////////////////////////////////////////////// N = 10; int M = 10; LDA = N; Epetra_SerialDenseMatrix smallA(N, M, false); Epetra_SerialDenseMatrix x(N, 1, false); Epetra_SerialDenseMatrix y1(N, 1, false); Epetra_SerialDenseMatrix y2(N, 1, false); for(i=0; i<N; ++i) { for(j=0; j<M; ++j) { smallA(i,j) = 1.0*i+2.0*j+1.0; } x(i,0) = 1.0; y1(i,0) = 0.0; y2(i,0) = 0.0; } //quick check of operator== if (x == y1) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, " << "erroneously returned true." << std::endl; return(-1); } //quick check of operator!= if (x != x) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, " << "erroneously returned true." << std::endl; return(-1); } int err1 = smallA.Multiply(false, x, y1); int err2 = y2.Multiply('N','N', 1.0, smallA, x, 0.0); if (err1 != 0 || err2 != 0) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::Multiply"<<endl; return(err1+err2); } for(i=0; i<N; ++i) { if (y1(i,0) != y2(i,0)) { if (verbose) cout << "different versions of Multiply don't match."<<endl; return(-99); } } ///////////////////////////////////////////////////////////////////// // Now test for larger system, both correctness and performance. ///////////////////////////////////////////////////////////////////// N = 2000; NRHS = 5; LDA = N; LDB = N; LDX = N; if (verbose) cout << "\n\nComputing factor of an " << N << " x " << N << " general matrix...Please wait.\n\n" << endl; // Define A and X A = new double[LDA*N]; X = new double[LDB*NRHS]; for (j=0; j<N; j++) { for (k=0; k<NRHS; k++) X[j+k*LDX] = 1.0/((double) (j+5+k)); for (i=0; i<N; i++) { if (i==((j+2)%N)) A[i+j*LDA] = 100.0 + i; else A[i+j*LDA] = -11.0/((double) (i+5)*(j+2)); } } // Define Epetra_SerialDenseMatrix object Epetra_SerialDenseMatrix BigMatrix(Copy, A, LDA, N, N); Epetra_SerialDenseMatrix OrigBigMatrix(View, A, LDA, N, N); Epetra_SerialDenseSolver BigSolver; BigSolver.FactorWithEquilibration(true); BigSolver.SetMatrix(BigMatrix); // Time factorization Epetra_Flops counter; BigSolver.SetFlopCounter(counter); Epetra_Time Timer(Comm); double tstart = Timer.ElapsedTime(); ierr = BigSolver.Factor(); if (ierr!=0 && verbose) cout << "Error in factorization = "<<ierr<< endl; assert(ierr==0); double time = Timer.ElapsedTime() - tstart; double FLOPS = counter.Flops(); double MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS for Factorization = " << MFLOPS << endl; // Define Left hand side and right hand side Epetra_SerialDenseMatrix LHS(View, X, LDX, N, NRHS); Epetra_SerialDenseMatrix RHS; RHS.Shape(N,NRHS); // Allocate RHS // Compute RHS from A and X Epetra_Flops RHS_counter; RHS.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); RHS.Multiply('N', 'N', 1.0, OrigBigMatrix, LHS, 0.0); time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseMatrix OrigRHS = RHS; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << endl; // Set LHS and RHS and solve BigSolver.SetVectors(LHS, RHS); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl; else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl; assert(ierr>=0); time = Timer.ElapsedTime() - tstart; FLOPS = BigSolver.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << endl; double * resid = new double[NRHS]; bool OK = Residual(N, NRHS, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(), OrigRHS.A(), OrigRHS.LDA(), resid); if (verbose) { if (!OK) cout << "************* Residual do not meet tolerance *************" << endl; for (i=0; i<NRHS; i++) cout << "Residual[" << i <<"] = "<< resid[i] << endl; cout << endl; } // Solve again using the Epetra_SerialDenseVector class for LHS and RHS Epetra_SerialDenseVector X2; Epetra_SerialDenseVector B2; X2.Size(BigMatrix.N()); B2.Size(BigMatrix.M()); int length = BigMatrix.N(); {for (int kk=0; kk<length; kk++) X2[kk] = ((double ) kk)/ ((double) length);} // Define entries of X2 RHS_counter.ResetFlops(); B2.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); B2.Multiply('N', 'N', 1.0, OrigBigMatrix, X2, 0.0); // Define B2 = A*X2 time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseVector OrigB2 = B2; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to build single RHS = " << MFLOPS << endl; // Set LHS and RHS and solve BigSolver.SetVectors(X2, B2); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); time = Timer.ElapsedTime() - tstart; if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl; else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl; assert(ierr>=0); FLOPS = counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to solve single RHS = " << MFLOPS << endl; OK = Residual(N, 1, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(), OrigB2.A(), OrigB2.LDA(), resid); if (verbose) { if (!OK) cout << "************* Residual do not meet tolerance *************" << endl; cout << "Residual = "<< resid[0] << endl; } delete [] resid; delete [] A; delete [] X; /////////////////////////////////////////////////// // Now test default constructor and index operators /////////////////////////////////////////////////// N = 5; Epetra_SerialDenseMatrix C; // Implicit call to default constructor, should not need to call destructor C.Shape(5,5); // Make it 5 by 5 double * C1 = new double[N*N]; GenerateHilbert(C1, N, N); // Generate Hilber matrix C1[1+2*N] = 1000.0; // Make matrix nonsymmetric // Fill values of C with Hilbert values for (i=0; i<N; i++) for (j=0; j<N; j++) C(i,j) = C1[i+j*N]; // Test if values are correctly written and read for (i=0; i<N; i++) for (j=0; j<N; j++) { assert(C(i,j) == C1[i+j*N]); assert(C(i,j) == C[j][i]); } if (verbose) cout << "Default constructor and index operator check OK. Values of Hilbert matrix = " << endl << C << endl << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << endl; delete [] C1; // now test sized/shaped constructor Epetra_SerialDenseMatrix shapedMatrix(10, 12); assert(shapedMatrix.M() == 10); assert(shapedMatrix.N() == 12); for(i = 0; i < 10; i++) for(j = 0; j < 12; j++) assert(shapedMatrix(i, j) == 0.0); Epetra_SerialDenseVector sizedVector(20); assert(sizedVector.Length() == 20); for(i = 0; i < 20; i++) assert(sizedVector(i) == 0.0); if (verbose) cout << "Shaped/sized constructors check OK." << endl; // test Copy/View mode in op= and cpy ctr int temperr = 0; temperr = matrixAssignment(verbose, debug); if(verbose && temperr == 0) cout << "Operator = checked OK." << endl; EPETRA_TEST_ERR(temperr, ierr); temperr = matrixCpyCtr(verbose, debug); if(verbose && temperr == 0) cout << "Copy ctr checked OK." << endl; EPETRA_TEST_ERR(temperr, ierr); // Test some vector methods Epetra_SerialDenseVector v1(3); v1[0] = 1.0; v1[1] = 3.0; v1[2] = 2.0; Epetra_SerialDenseVector v2(3); v2[0] = 2.0; v2[1] = 1.0; v2[2] = -2.0; temperr = 0; if (v1.Norm1()!=6.0) temperr++; if (fabs(sqrt(14.0)-v1.Norm2())>1.0e-6) temperr++; if (v1.NormInf()!=3.0) temperr++; if(verbose && temperr == 0) cout << "Vector Norms checked OK." << endl; temperr = 0; if (v1.Dot(v2)!=1.0) temperr++; if(verbose && temperr == 0) cout << "Vector Dot product checked OK." << endl; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
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 main(int argc, char *argv[]) { int ierr = 0, i, forierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; long long NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0LL, Comm); // Get update list and number of local equations from newly created Map vector<long long> MyGlobalElements(Map.NumMyElements()); Map.MyGlobalElements(&MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor vector<int> NumNz(NumMyEquations); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; vector<long long> Indices(2); double two = 2.0; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up A.FillComplete(); A.OptimizeStorage(); Epetra_JadMatrix JadA(A); Epetra_JadMatrix JadA1(A); Epetra_JadMatrix JadA2(A); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); z.Random(); Epetra_Vector resid(Map); Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); JadA.SetFlopCounter(A); JadA1.SetFlopCounter(A); JadA2.SetFlopCounter(A); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); vector<double> Rowvals(numvals); vector<long long> Rowinds(numvals); A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0] for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]); } JadA.UpdateValues(A); A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); if (verbose) cout << "================================================================" << endl << "Testing Jad using Jad matrix as input matrix for construction..." << endl << "================================================================" << endl; JadA1.ResetFlops(); powerMethodTests(JadA1, JadA2, Map, q, z, resid, verbose); #ifdef EPETRA_MPI MPI_Finalize() ; #endif return ierr ; }
int check(Epetra_RowMatrix& A, Epetra_RowMatrix & B, bool verbose) { int ierr = 0; EPETRA_TEST_ERR(!A.Comm().NumProc()==B.Comm().NumProc(),ierr); EPETRA_TEST_ERR(!A.Comm().MyPID()==B.Comm().MyPID(),ierr); EPETRA_TEST_ERR(!A.Filled()==B.Filled(),ierr); EPETRA_TEST_ERR(!A.HasNormInf()==B.HasNormInf(),ierr); EPETRA_TEST_ERR(!A.LowerTriangular()==B.LowerTriangular(),ierr); EPETRA_TEST_ERR(!A.Map().SameAs(B.Map()),ierr); EPETRA_TEST_ERR(!A.MaxNumEntries()==B.MaxNumEntries(),ierr); EPETRA_TEST_ERR(!A.NumGlobalCols64()==B.NumGlobalCols64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalDiagonals64()==B.NumGlobalDiagonals64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalNonzeros64()==B.NumGlobalNonzeros64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalRows64()==B.NumGlobalRows64(),ierr); EPETRA_TEST_ERR(!A.NumMyCols()==B.NumMyCols(),ierr); EPETRA_TEST_ERR(!A.NumMyDiagonals()==B.NumMyDiagonals(),ierr); EPETRA_TEST_ERR(!A.NumMyNonzeros()==B.NumMyNonzeros(),ierr); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; A.NumMyRowEntries(i,nA); B.NumMyRowEntries(i,nB); EPETRA_TEST_ERR(!nA==nB,ierr); } EPETRA_TEST_ERR(!A.NumMyRows()==B.NumMyRows(),ierr); EPETRA_TEST_ERR(!A.OperatorDomainMap().SameAs(B.OperatorDomainMap()),ierr); EPETRA_TEST_ERR(!A.OperatorRangeMap().SameAs(B.OperatorRangeMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixColMap().SameAs(B.RowMatrixColMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixRowMap().SameAs(B.RowMatrixRowMap()),ierr); EPETRA_TEST_ERR(!A.UpperTriangular()==B.UpperTriangular(),ierr); EPETRA_TEST_ERR(!A.UseTranspose()==B.UseTranspose(),ierr); int NumVectors = 5; { // No transpose case Epetra_MultiVector X(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = false; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2,"A Multiply and A Apply", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1,"A Multiply and B Multiply", verbose),ierr); B.Multiply(transA, X, YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2,"A Multiply and B Apply", verbose), ierr); } {// transpose case Epetra_MultiVector X(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = true; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2, "A Multiply and A Apply (transpose)", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1, "A Multiply and B Multiply (transpose)", verbose),ierr); B.Multiply(transA, X,YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2, "A Multiply and B Apply (transpose)", verbose),ierr); } Epetra_Vector diagA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.ExtractDiagonalCopy(diagA),ierr); Epetra_Vector diagB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.ExtractDiagonalCopy(diagB),ierr); EPETRA_TEST_ERR(checkMultiVectors(diagA,diagB, "ExtractDiagonalCopy", verbose),ierr); Epetra_Vector rowA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.InvRowSums(rowA),ierr); Epetra_Vector rowB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.InvRowSums(rowB),ierr) EPETRA_TEST_ERR(checkMultiVectors(rowA,rowB, "InvRowSums", verbose),ierr); Epetra_Vector colA(A.RowMatrixColMap()); EPETRA_TEST_ERR(A.InvColSums(colA),ierr); Epetra_Vector colB(B.RowMatrixColMap()); EPETRA_TEST_ERR(B.InvColSums(colB),ierr); EPETRA_TEST_ERR(checkMultiVectors(colA,colB, "InvColSums", verbose),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf before scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne before scaling", verbose),ierr); EPETRA_TEST_ERR(A.RightScale(colA),ierr); EPETRA_TEST_ERR(B.RightScale(colB),ierr); EPETRA_TEST_ERR(A.LeftScale(rowA),ierr); EPETRA_TEST_ERR(B.LeftScale(rowB),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf after scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne after scaling", verbose),ierr); vector<double> valuesA(A.MaxNumEntries()); vector<int> indicesA(A.MaxNumEntries()); vector<double> valuesB(B.MaxNumEntries()); vector<int> indicesB(B.MaxNumEntries()); return(0); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; EPETRA_TEST_ERR(A.ExtractMyRowCopy(i, A.MaxNumEntries(), nA, &valuesA[0], &indicesA[0]),ierr); EPETRA_TEST_ERR(B.ExtractMyRowCopy(i, B.MaxNumEntries(), nB, &valuesB[0], &indicesB[0]),ierr); EPETRA_TEST_ERR(!nA==nB,ierr); for (int j=0; j<nA; j++) { double curVal = valuesA[j]; int curIndex = indicesA[j]; bool notfound = true; int jj = 0; while (notfound && jj< nB) { if (!checkValues(curVal, valuesB[jj])) notfound = false; jj++; } EPETRA_TEST_ERR(notfound, ierr); vector<int>::iterator p = find(indicesB.begin(),indicesB.end(),curIndex); // find curIndex in indicesB EPETRA_TEST_ERR(p==indicesB.end(), ierr); } } if (verbose) cout << "RowMatrix Methods check OK" << endl; return (ierr); }
int main(int argc, char *argv[]) { int ierr=0, returnierr=0; #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; if (!verbose) { Comm.SetTracebackMode(0); // This should shut down any error traceback reporting } int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm << endl; bool verbose1 = verbose; if (verbose) verbose = (MyPID==0); int NumMyElements = 10000; int NumMyElements1 = NumMyElements; // Used for local map long long NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3); if (MyPID < 3) NumMyElements++; int IndexBase = 0; bool DistributedGlobal = (NumGlobalElements>NumMyElements); Epetra_Map* Map; // Test exceptions if (verbose) cout << "*******************************************************************************************" << endl << " Testing Exceptions (Expect error messages if EPETRA_NO_ERROR_REPORTS is not defined" << endl << "*******************************************************************************************" << endl << endl << endl; try { if (verbose) cout << "Checking Epetra_Map(-2, IndexBase, Comm)" << endl; Map = new Epetra_Map((long long)-2, IndexBase, Comm); } catch (int Error) { if (Error!=-1) { if (Error!=0) { EPETRA_TEST_ERR(Error,returnierr); if (verbose) cout << "Error code should be -1" << endl; } else { cout << "Error code = " << Error << "Should be -1" << endl; returnierr+=1; } } else if (verbose) cout << "Checked OK\n\n" << endl; } try { if (verbose) cout << "Checking Epetra_Map(2, 3, IndexBase, Comm)" << endl; Map = new Epetra_Map((long long)2, 3, IndexBase, Comm); } catch (int Error) { if (Error!=-4) { if (Error!=0) { EPETRA_TEST_ERR(Error,returnierr); if (verbose) cout << "Error code should be -4" << endl; } else { cout << "Error code = " << Error << "Should be -4" << endl; returnierr+=1; } } else if (verbose) cout << "Checked OK\n\n" << endl; } if (verbose) cerr << flush; if (verbose) cout << flush; Comm.Barrier(); if (verbose) cout << endl << endl << "*******************************************************************************************" << endl << " Testing valid constructor now......................................................" << endl << "*******************************************************************************************" << endl << endl << endl; // Test Epetra-defined uniform linear distribution constructor Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete Map; // Test User-defined linear distribution constructor Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete Map; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! long long * MyGlobalElements = new long long[NumMyElements]; int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (int i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test Copy constructor Epetra_Map* Map1 = new Epetra_Map(*Map); // Test SameAs() method bool same = Map1->SameAs(*Map); EPETRA_TEST_ERR(!(same==true),ierr);// should return true since Map1 is a copy of Map Epetra_BlockMap* Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); same = Map2->SameAs(*Map); EPETRA_TEST_ERR(!(same==true),ierr); // Map and Map2 were created with the same sets of parameters delete Map2; // now test SameAs() on a map that is different Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase-1, Comm); same = Map2->SameAs(*Map); EPETRA_TEST_ERR(!(same==false),ierr); // IndexBases are different delete Map2; // Back to testing copy constructor if (verbose) cout << "Checking Epetra_Map(*Map)" << endl; ierr = checkmap(*Map1, NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; Epetra_Map* SmallMap = 0; if (verbose1) { // Build a small map for test cout. Use 10 elements from current map long long* MyEls = Map->MyGlobalElements64(); int IndBase = Map->IndexBase(); int MyLen = EPETRA_MIN(10+Comm.MyPID(),Map->NumMyElements()); SmallMap = new Epetra_Map((long long)-1, MyLen, MyEls, IndBase, Comm); } delete [] MyGlobalElements; delete Map; delete Map1; // Test reference-counting in Epetra_Map if (verbose) cout << "Checking Epetra_Map reference counting" << endl; ierr = checkMapDataClass(Comm, verbose); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test LocalMap constructor Epetra_LocalMap* LocalMap = new Epetra_LocalMap((long long)NumMyElements1, IndexBase, Comm); if (verbose) cout << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl; ierr = checkmap(*LocalMap, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test Copy constructor Epetra_LocalMap* LocalMap1 = new Epetra_LocalMap(*LocalMap); if (verbose) cout << "Checking Epetra_LocalMap(*LocalMap)" << endl; ierr = checkmap(*LocalMap1, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete LocalMap1; delete LocalMap; // Test reference-counting in Epetra_LocalMap if (verbose) cout << "Checking Epetra_LocalMap reference counting" << endl; ierr = checkLocalMapDataClass(Comm, verbose); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test output if (verbose1) { if (verbose) cout << "Test ostream << operator" << endl << flush; cout << *SmallMap; delete SmallMap; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
int powerMethodTests(CT_Epetra_RowMatrix_ID_t & A, CT_Epetra_RowMatrix_ID_t & JadA, CT_Epetra_Map_ID_Flex_t & Map, CT_Epetra_Vector_ID_Flex_t & q, CT_Epetra_Vector_ID_Flex_t & z, CT_Epetra_Vector_ID_Flex_t & resid, bool verbose) { // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 300; double tolerance = 1.0e-2; int ierr = 0; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate CT_Epetra_Comm_ID_t Comm = Epetra_BlockMap_Comm(Map.Epetra_BlockMap); CT_Epetra_Time_ID_t timer = Epetra_Time_Create(Comm); Epetra_Comm_Destroy(&Comm); double startTime = Epetra_Time_ElapsedTime(timer); EPETRA_TEST_ERR(power_method(FALSE, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = Epetra_Time_ElapsedTime(timer) - startTime; double total_flops = Epetra_CompObject_Flops(q.Epetra_CompObject); double MFLOPs = total_flops/elapsed_time/1000000.0; double lambdaref = lambda; double flopsref = total_flops; if (verbose) cout << "\n\nTotal MFLOPs for reference first solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; lambda = 0.0; startTime = Epetra_Time_ElapsedTime(timer); EPETRA_TEST_ERR(power_method(FALSE, JadA, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = Epetra_Time_ElapsedTime(timer) - startTime; total_flops = Epetra_CompObject_Flops(q.Epetra_CompObject); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for candidate first solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; EPETRA_TEST_ERR(checkValues(lambda,lambdaref," No-transpose Power Method result", verbose),ierr); EPETRA_TEST_ERR(checkValues(total_flops,flopsref," No-transpose Power Method flop count", verbose),ierr); ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate lambda = 0.0; startTime = Epetra_Time_ElapsedTime(timer); EPETRA_TEST_ERR(power_method(TRUE, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = Epetra_Time_ElapsedTime(timer) - startTime; total_flops = Epetra_CompObject_Flops(q.Epetra_CompObject); MFLOPs = total_flops/elapsed_time/1000000.0; lambdaref = lambda; flopsref = total_flops; if (verbose) cout << "\n\nTotal MFLOPs for reference transpose solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; lambda = 0.0; startTime = Epetra_Time_ElapsedTime(timer); EPETRA_TEST_ERR(power_method(TRUE, JadA, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = Epetra_Time_ElapsedTime(timer) - startTime; total_flops = Epetra_CompObject_Flops(q.Epetra_CompObject); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for candidate transpose solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; EPETRA_TEST_ERR(checkValues(lambda,lambdaref,"Transpose Power Method result", verbose),ierr); EPETRA_TEST_ERR(checkValues(total_flops,flopsref,"Transpose Power Method flop count", verbose),ierr); EPETRA_TEST_ERR(check(A, JadA, verbose),ierr); return(0); }
int fevec1(Epetra_Comm& Comm, bool verbose) { int Numprocs = Comm.NumProc(); if (Numprocs != 2) return(0); int MyPID = Comm.MyPID(); int ierr = 0; int NumGlobalRows = 6; const int NumVectors = 4; int indexBase = 0; Epetra_Map Map(NumGlobalRows, indexBase, Comm); const int Num = 4; int Indices[Num]; double Values[Num]; // Create vectors Epetra_FEVector b(Map, NumVectors); Epetra_FEVector x0(Map, NumVectors); // source terms if(MyPID==0) // indices corresponding to element 0 on processor 0 { Indices[0] = 0; Indices[1] = 1; Indices[2] = 4; Indices[3] = 5; Values[0] = 1./2.; Values[1] = 1./2.; Values[2] = 1./2.; Values[3] = 1./2.; } else { Indices[0] = 1; Indices[1] = 2; Indices[2] = 3; Indices[3] = 4; Values[0] = 0; Values[1] = 0; Values[2] = 0; Values[3] = 0; } for(int i=0; i<NumVectors; ++i) { EPETRA_TEST_ERR( b.SumIntoGlobalValues(Num, Indices, Values, i), ierr); } EPETRA_TEST_ERR( b.GlobalAssemble(), ierr); double nrm2[NumVectors]; b.Norm2(nrm2); for(int i=1; i<NumVectors; ++i) { if (fabs(nrm2[i]-nrm2[0]) > 1.e-12) { EPETRA_TEST_ERR(-1, ierr); return(-1); } } //now sum-in again, to make sure the previous call to GlobalAssemble //didn't do something nasty to internal non-local data structures. //(This is a specific case that has bitten me. Hence this test...) for(int i=0; i<NumVectors; ++i) { EPETRA_TEST_ERR( b.SumIntoGlobalValues(Num, Indices, Values, i), ierr); } //and now GlobalAssemble again... EPETRA_TEST_ERR( b.GlobalAssemble(), ierr); if (verbose&&MyPID==0) { cout << "b:"<<endl; } if (verbose) { b.Print(cout); } x0 = b; if (verbose&&MyPID==0) { cout << "x:"<<endl; } if (verbose) { x0.Print(cout); } return(0); }
int fevec3(Epetra_Comm& Comm, bool verbose) { int ierr = 0; int NumGlobalElems = 4; int elemSize = 40; int indexBase = 0; Epetra_BlockMap Map(NumGlobalElems, elemSize, indexBase, Comm); int Numprocs = Comm.NumProc(); int MyPID = Comm.MyPID(); if (Numprocs != 2) return(0); int NumCols = 3; int* Indices = new int[NumCols]; int* numValuesPerID = new int[NumCols]; for(int i=0; i<NumCols; ++i) { numValuesPerID[i] = elemSize; } double* Values = new double[NumCols*elemSize]; // Create vectors Epetra_FEVector b(Map, 1); Epetra_FEVector x0(Map, 1); // source terms NumCols = 2; if(MyPID==0) // indices corresponding to element 0 on processor 0 { Indices[0] = 0; Indices[1] = 3; for(int ii=0; ii<NumCols*elemSize; ++ii) { Values[ii] = 1./2.; } } else { Indices[0] = 1; Indices[1] = 2; for(int ii=0; ii<NumCols*elemSize; ++ii) { Values[ii] = 0.; } } EPETRA_TEST_ERR( b.SumIntoGlobalValues(NumCols, Indices, numValuesPerID, Values), ierr); EPETRA_TEST_ERR( b.GlobalAssemble(), ierr); if (verbose&&MyPID==0) { cout << "b:"<<endl; } if (verbose) { b.Print(cout); } x0 = b; if (verbose&&MyPID==0) { cout << "x:"<<endl; } if (verbose) { x0.Print(cout); } delete [] Values; delete [] Indices; delete [] numValuesPerID; return(0); }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm <<endl; int NumVectors = 1; int NumMyElements = 4; int NumGlobalElements = NumMyElements*NumProc; int IndexBase = 0; Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR( quad1(Map, verbose), ierr); EPETRA_TEST_ERR( quad2(Map, verbose), ierr); EPETRA_TEST_ERR( MultiVectorTests(Map, NumVectors, verbose), ierr); bool preconstruct_graph = false; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); preconstruct_graph = true; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
int fevec0(Epetra_Comm& Comm, bool verbose) { int ierr = 0; int NumGlobalRows = 4; int indexBase = 0; Epetra_Map Map(NumGlobalRows, indexBase, Comm); int Numprocs = Comm.NumProc(); int MyPID = Comm.MyPID(); if (Numprocs != 2) return(0); int NumCols = 3; int* Indices = new int[NumCols]; double* Values = new double[NumCols]; // Create vectors Epetra_FEVector b(Map, 1); Epetra_FEVector x0(Map, 1); // source terms NumCols = 2; if(MyPID==0) // indices corresponding to element 0 on processor 0 { Indices[0] = 0; Indices[1] = 3; Values[0] = 1./2.; Values[1] = 1./2.; } else { Indices[0] = 1; Indices[1] = 2; Values[0] = 0; Values[1] = 0; } EPETRA_TEST_ERR( b.SumIntoGlobalValues(NumCols, Indices, Values), ierr); EPETRA_TEST_ERR( b.GlobalAssemble(), ierr); if (verbose&&MyPID==0) { cout << "b:"<<endl; } if (verbose) { b.Print(cout); } x0 = b; if (verbose&&MyPID==0) { cout << "x:"<<endl; } if (verbose) { x0.Print(cout); } delete [] Values; delete [] Indices; return(0); }
int Drumm1(const Epetra_Map& map, bool verbose) { //Simple 2-element problem (element as in "finite-element") from //Clif Drumm. Two triangular elements, one per processor, as shown //here: // // *----* // 3|\ 2| // | \ | // | 0\1| // | \| // *----* // 0 1 // //Element 0 on processor 0, element 1 on processor 1. //Processor 0 will own nodes 0,1 and processor 1 will own nodes 2,3. //Each processor will pass a 3x3 element-connectivity-matrix to //Epetra_FECrsGraph. //After GlobalAssemble(), the graph should be as follows: // // row 0: 2 1 0 1 //proc 0 row 1: 1 4 1 2 //---------------------------------- // row 2: 0 1 2 1 //proc 1 row 3: 1 2 1 4 // int numProcs = map.Comm().NumProc(); int localProc = map.Comm().MyPID(); if (numProcs != 2) return(0); int indexBase = 0, ierr = 0; int numMyNodes = 2; long long* myNodes = new long long[numMyNodes]; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; } else { myNodes[0] = 2; myNodes[1] = 3; } Epetra_Map Map((long long) -1, numMyNodes, myNodes, indexBase, map.Comm()); delete [] myNodes; numMyNodes = 3; myNodes = new long long[numMyNodes]; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; myNodes[2] = 3; } else { myNodes[0] = 1; myNodes[1] = 2; myNodes[2] = 3; } int rowLengths = 3; Epetra_FECrsGraph A(Copy, Map, rowLengths); EPETRA_TEST_ERR( A.InsertGlobalIndices(numMyNodes, myNodes, numMyNodes, myNodes),ierr); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); if (verbose) { A.Print(std::cout); } delete [] myNodes; return(0); }
int check(Epetra_CrsMatrix& A, int NumMyRows1, int NumGlobalRows1, int NumMyNonzeros1, int NumGlobalNonzeros1, int* MyGlobalElements, bool verbose) { (void)MyGlobalElements; int ierr = 0, forierr = 0; int NumGlobalIndices; int NumMyIndices; int* MyViewIndices = 0; int* GlobalViewIndices = 0; double* MyViewValues = 0; double* GlobalViewValues = 0; int MaxNumIndices = A.Graph().MaxNumIndices(); int* MyCopyIndices = new int[MaxNumIndices]; int* GlobalCopyIndices = new int[MaxNumIndices]; double* MyCopyValues = new double[MaxNumIndices]; double* GlobalCopyValues = new double[MaxNumIndices]; // Test query functions int NumMyRows = A.NumMyRows(); if (verbose) cout << "\n\nNumber of local Rows = " << NumMyRows << endl<< endl; EPETRA_TEST_ERR(!(NumMyRows==NumMyRows1),ierr); int NumMyNonzeros = A.NumMyNonzeros(); if (verbose) cout << "\n\nNumber of local Nonzero entries = " << NumMyNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumMyNonzeros==NumMyNonzeros1),ierr); int NumGlobalRows = A.NumGlobalRows(); if (verbose) cout << "\n\nNumber of global Rows = " << NumGlobalRows << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalRows==NumGlobalRows1),ierr); int NumGlobalNonzeros = A.NumGlobalNonzeros(); if (verbose) cout << "\n\nNumber of global Nonzero entries = " << NumGlobalNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalNonzeros==NumGlobalNonzeros1),ierr); // GlobalRowView should be illegal (since we have local indices) EPETRA_TEST_ERR(!(A.ExtractGlobalRowView(A.RowMap().MaxMyGID(), NumGlobalIndices, GlobalViewValues, GlobalViewIndices)==-2),ierr); // Other binary tests EPETRA_TEST_ERR(A.NoDiagonal(),ierr); EPETRA_TEST_ERR(!(A.Filled()),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MaxMyGID())),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MinMyGID())),ierr); EPETRA_TEST_ERR(A.MyGRID(1+A.RowMap().MaxMyGID()),ierr); EPETRA_TEST_ERR(A.MyGRID(-1+A.RowMap().MinMyGID()),ierr); EPETRA_TEST_ERR(!(A.MyLRID(0)),ierr); EPETRA_TEST_ERR(!(A.MyLRID(NumMyRows-1)),ierr); EPETRA_TEST_ERR(A.MyLRID(-1),ierr); EPETRA_TEST_ERR(A.MyLRID(NumMyRows),ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowView(i, NumMyIndices, MyViewValues, MyViewIndices); // this is where the problem comes from forierr += !(NumGlobalIndices == NumMyIndices); for(int j = 1; j < NumMyIndices; j++) { forierr += !(MyViewIndices[j-1] < MyViewIndices[j]); // this is where the test fails } for(int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyViewIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyViewIndices[j]); forierr += !(GlobalCopyValues[j] == MyViewValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowCopy(i, MaxNumIndices, NumMyIndices, MyCopyValues, MyCopyIndices); forierr += !(NumGlobalIndices == NumMyIndices); for (int j = 1; j < NumMyIndices; j++) forierr += !(MyCopyIndices[j-1] < MyCopyIndices[j]); for (int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyCopyIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyCopyIndices[j]); forierr += !(GlobalCopyValues[j] == MyCopyValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); delete [] MyCopyIndices; delete [] GlobalCopyIndices; delete [] MyCopyValues; delete [] GlobalCopyValues; if (verbose) cout << "\n\nRows sorted check OK" << endl<< endl; return (ierr); }
int main(int argc, char *argv[]) { int ierr = 0, forierr = 0; bool debug = false; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map int* MyGlobalElements = new int[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, NumNz); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double* Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int* Indices = new int[2]; double two = 2.0; int NumEntries; forierr = 0; for (int i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices)==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); int * indexOffsetTmp; int * indicesTmp; double * valuesTmp; // Finish up EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr); EPETRA_TEST_ERR(A.StorageOptimized(),ierr); A.OptimizeStorage(); EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==0),ierr); // Should succeed const Epetra_CrsGraph & GofA = A.Graph(); EPETRA_TEST_ERR((indicesTmp!=GofA[0] || valuesTmp!=A[0]),ierr); // Extra check to see if operator[] is consistent EPETRA_TEST_ERR(A.UpperTriangular(),ierr); EPETRA_TEST_ERR(A.LowerTriangular(),ierr); int NumMyNonzeros = 3 * NumMyEquations; if(A.LRID(0) >= 0) NumMyNonzeros--; // If I own first global row, then there is one less nonzero if(A.LRID(NumGlobalEquations-1) >= 0) NumMyNonzeros--; // If I own last global row, then there is one less nonzero EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, MyGlobalElements, verbose),ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumGlobalEntries(MyGlobalElements[i])==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumMyEntries(i)==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << std::endl<< std::endl; EPETRA_TEST_ERR(check_graph_sharing(Comm),ierr); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); Epetra_Vector resid(Map); // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 200; double tolerance = 1.0e-1; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); Epetra_Time timer(Comm); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = timer.ElapsedTime(); double total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << std::endl<< std::endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << std::endl; // Iterate lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for transpose solve = " << MFLOPs << std::endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); double * Rowvals = new double [numvals]; int * Rowinds = new int [numvals]; A.ExtractGlobalRowCopy(0, numvals, numvals, Rowvals, Rowinds); // Get A[0,0] for (int i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, Rowvals, Rowinds); delete [] Rowvals; delete [] Rowinds; } // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for tranpose of second solve = " << MFLOPs << endl<< endl; if (verbose) cout << "\n\n*****Testing constant entry constructor" << endl<< endl; Epetra_CrsMatrix AA(Copy, Map, 5); if (debug) Comm.Barrier(); double dble_one = 1.0; for (int i=0; i< NumMyEquations; i++) AA.InsertGlobalValues(MyGlobalElements[i], 1, &dble_one, MyGlobalElements+i); // Note: All processors will call the following Insert routines, but only the processor // that owns it will actually do anything int One = 1; if (AA.MyGlobalRow(0)) { EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 0, &dble_one, &One)==0),ierr); } else EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 1, &dble_one, &One)==-1),ierr); EPETRA_TEST_ERR(!(AA.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(AA.StorageOptimized(),ierr); EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr); EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr); if (debug) Comm.Barrier(); EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); if (debug) Comm.Barrier(); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(AA.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Epetra_CrsMatrix B(AA); EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(B.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing local view constructor" << endl<< endl; Epetra_CrsMatrix BV(View, AA.RowMap(), AA.ColMap(), 0); forierr = 0; int* Inds; double* Vals; for (int i = 0; i < NumMyEquations; i++) { forierr += !(AA.ExtractMyRowView(i, NumEntries, Vals, Inds)==0); forierr += !(BV.InsertMyValues(i, NumEntries, Vals, Inds)==0); } BV.FillComplete(false); EPETRA_TEST_ERR(check(BV, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(BV.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing post construction modifications" << endl<< endl; EPETRA_TEST_ERR(!(B.InsertGlobalValues(0, 1, &dble_one, &One)==-2),ierr); // Release all objects delete [] NumNz; delete [] Values; delete [] Indices; delete [] MyGlobalElements; if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 2 equations on each PE int NumMyElements1 = 2; int NumMyEquations1 = NumMyElements1; int NumGlobalEquations1 = NumMyEquations1*NumProc; Epetra_Map Map1(-1, NumMyElements1, 0, Comm); // Get update list and number of local equations from newly created Map int * MyGlobalElements1 = new int[Map1.NumMyElements()]; Map1.MyGlobalElements(MyGlobalElements1); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int * NumNz1 = new int[NumMyEquations1]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i=0; i<NumMyEquations1; i++) if (MyGlobalElements1[i]==0 || MyGlobalElements1[i] == NumGlobalEquations1-1) NumNz1[i] = 1; else NumNz1[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A1(Copy, Map1, NumNz1); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double *Values1 = new double[2]; Values1[0] = -1.0; Values1[1] = -1.0; int *Indices1 = new int[2]; double two1 = 2.0; int NumEntries1; forierr = 0; for (int i=0; i<NumMyEquations1; i++) { if (MyGlobalElements1[i]==0) { Indices1[0] = 1; NumEntries1 = 1; } else if (MyGlobalElements1[i] == NumGlobalEquations1-1) { Indices1[0] = NumGlobalEquations1-2; NumEntries1 = 1; } else { Indices1[0] = MyGlobalElements1[i]-1; Indices1[1] = MyGlobalElements1[i]+1; NumEntries1 = 2; } forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], NumEntries1, Values1, Indices1)==0); forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], 1, &two1, MyGlobalElements1+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); delete [] Indices1; delete [] Values1; // Finish up EPETRA_TEST_ERR(!(A1.FillComplete(false)==0),ierr); // Test diagonal extraction function Epetra_Vector checkDiag(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==two1); EPETRA_TEST_ERR(forierr,ierr); // Test diagonal replacement method forierr = 0; for (int i=0; i<NumMyEquations1; i++) checkDiag[i]=two1*two1; EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(!(A1.ReplaceDiagonalValues(checkDiag)==0),ierr); Epetra_Vector checkDiag1(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag1)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==checkDiag1[i]); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nDiagonal extraction and replacement OK.\n\n" << endl; double orignorm = A1.NormOne(); EPETRA_TEST_ERR(!(A1.Scale(4.0)==0),ierr); EPETRA_TEST_ERR(!(A1.NormOne()!=orignorm),ierr); if (verbose) cout << "\n\nMatrix scale OK.\n\n" << endl; if (verbose) cout << "\n\nPrint out tridiagonal matrix, each part on each processor.\n\n" << endl; cout << A1 << endl; // Release all objects delete [] NumNz1; delete [] MyGlobalElements1; } if (verbose) cout << "\n\n*****Testing LeftScale and RightScale" << endl << endl; int NumMyElements2 = 7; int NumMyRows2 = 1;//This value should not be changed without editing the // code below. Epetra_Map RowMap(-1,NumMyRows2,0,Comm); Epetra_Map ColMap(NumMyElements2,NumMyElements2,0,Comm); // The DomainMap needs to be different from the ColMap for the test to // be meaningful. Epetra_Map DomainMap(NumMyElements2,0,Comm); int NumMyRangeElements2 = 0; // We need to distribute the elements differently for the range map also. if (MyPID % 2 == 0) NumMyRangeElements2 = NumMyRows2*2; //put elements on even number procs if (NumProc % 2 == 1 && MyPID == NumProc-1) NumMyRangeElements2 = NumMyRows2; //If number of procs is odd, put // the last NumMyElements2 elements on the last proc Epetra_Map RangeMap(-1,NumMyRangeElements2,0,Comm); Epetra_CrsMatrix A2(Copy,RowMap,ColMap,NumMyElements2); double * Values2 = new double[NumMyElements2]; int * Indices2 = new int[NumMyElements2]; for (int i=0; i<NumMyElements2; i++) { Values2[i] = i+MyPID; Indices2[i]=i; } A2.InsertMyValues(0,NumMyElements2,Values2,Indices2); A2.FillComplete(DomainMap,RangeMap,false); Epetra_CrsMatrix A2copy(A2); double * RowLeftScaleValues = new double[NumMyRows2]; double * ColRightScaleValues = new double[NumMyElements2]; int RowLoopLength = RowMap.MaxMyGID()-RowMap.MinMyGID()+1; for (int i=0; i<RowLoopLength; i++) RowLeftScaleValues[i] = (i + RowMap.MinMyGID() ) % 2 + 1; // For the column map, all procs own all elements for (int i=0; i<NumMyElements2;i++) ColRightScaleValues[i] = i % 2 + 1; int RangeLoopLength = RangeMap.MaxMyGID()-RangeMap.MinMyGID()+1; double * RangeLeftScaleValues = new double[RangeLoopLength]; int DomainLoopLength = DomainMap.MaxMyGID()-DomainMap.MinMyGID()+1; double * DomainRightScaleValues = new double[DomainLoopLength]; for (int i=0; i<RangeLoopLength; i++) RangeLeftScaleValues[i] = 1.0/((i + RangeMap.MinMyGID() ) % 2 + 1); for (int i=0; i<DomainLoopLength;i++) DomainRightScaleValues[i] = 1.0/((i + DomainMap.MinMyGID() ) % 2 + 1); Epetra_Vector xRow(View,RowMap,RowLeftScaleValues); Epetra_Vector xCol(View,ColMap,ColRightScaleValues); Epetra_Vector xRange(View,RangeMap,RangeLeftScaleValues); Epetra_Vector xDomain(View,DomainMap,DomainRightScaleValues); double A2infNorm = A2.NormInf(); double A2oneNorm = A2.NormOne(); if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); double A2infNorm1 = A2.NormInf(); double A2oneNorm1 = A2.NormOne(); bool ScalingBroke = false; if (A2infNorm1>2*A2infNorm||A2infNorm1<A2infNorm) { EPETRA_TEST_ERR(-31,ierr); ScalingBroke = true; } if (A2oneNorm1>2*A2oneNorm||A2oneNorm1<A2oneNorm) { EPETRA_TEST_ERR(-32,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); double A2infNorm2 = A2.NormInf(); double A2oneNorm2 = A2.NormOne(); if (A2infNorm2>=2*A2infNorm1||A2infNorm2<=A2infNorm1) { EPETRA_TEST_ERR(-33,ierr); ScalingBroke = true; } if (A2oneNorm2>2*A2oneNorm1||A2oneNorm2<=A2oneNorm1) { EPETRA_TEST_ERR(-34,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); double A2infNorm3 = A2.NormInf(); double A2oneNorm3 = A2.NormOne(); // The last two scaling ops cancel each other out if (A2infNorm3!=A2infNorm1) { EPETRA_TEST_ERR(-35,ierr) ScalingBroke = true; } if (A2oneNorm3!=A2oneNorm1) { EPETRA_TEST_ERR(-36,ierr) ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); double A2infNorm4 = A2.NormInf(); double A2oneNorm4 = A2.NormOne(); // The 4 scaling ops all cancel out if (A2infNorm4!=A2infNorm) { EPETRA_TEST_ERR(-37,ierr) ScalingBroke = true; } if (A2oneNorm4!=A2oneNorm) { EPETRA_TEST_ERR(-38,ierr) ScalingBroke = true; } // // Now try changing the values underneath and make sure that // telling one process about the change causes NormInf() and // NormOne() to recompute the norm on all processes. // double *values; int num_my_rows = A2.NumMyRows() ; int num_entries; for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] *= 2.0; } } if ( MyPID == 0 ) A2.SumIntoGlobalValues( 0, 0, 0, 0 ) ; double A2infNorm5 = A2.NormInf(); double A2oneNorm5 = A2.NormOne(); if (A2infNorm5!=2.0 * A2infNorm4) { EPETRA_TEST_ERR(-39,ierr) ScalingBroke = true; } if (A2oneNorm5!= 2.0 * A2oneNorm4) { EPETRA_TEST_ERR(-40,ierr) ScalingBroke = true; } // // Restore the values underneath // for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] /= 2.0; } } if (verbose1) cout << A2; if (ScalingBroke) { if (verbose) cout << endl << "LeftScale and RightScale tests FAILED" << endl << endl; } else { if (verbose) cout << endl << "LeftScale and RightScale tests PASSED" << endl << endl; } Comm.Barrier(); if (verbose) cout << "\n\n*****Testing InvRowMaxs and InvColMaxs" << endl << endl; if (verbose1) cout << A2 << endl; EPETRA_TEST_ERR(A2.InvRowMaxs(xRow),ierr); EPETRA_TEST_ERR(A2.InvRowMaxs(xRange),ierr); if (verbose1) cout << xRow << endl << xRange << endl; if (verbose) cout << "\n\n*****Testing InvRowSums and InvColSums" << endl << endl; bool InvSumsBroke = false; // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRow),ierr); if (verbose1) cout << xRow; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); float A2infNormFloat = A2.NormInf(); if (verbose1) cout << A2 << endl; if (fabs(1.0-A2infNormFloat) > 1.e-5) { EPETRA_TEST_ERR(-41,ierr); InvSumsBroke = true; } // Works int expectedcode = 1; if (Comm.NumProc()>1) expectedcode = 0; EPETRA_TEST_ERR(!(A2.InvColSums(xDomain)==expectedcode),ierr); // This matrix has a single row, the first column has a zero, so a warning is issued. if (verbose1) cout << xDomain << endl; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); float A2oneNormFloat2 = A2.NormOne(); if (verbose1) cout << A2; if (fabs(1.0-A2oneNormFloat2)>1.e-5) { EPETRA_TEST_ERR(-42,ierr) InvSumsBroke = true; } // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRange),ierr); if (verbose1) cout << xRange; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); float A2infNormFloat2 = A2.NormInf(); // We use a float so that rounding error // will not prevent the sum from being 1.0. if (verbose1) cout << A2; if (fabs(1.0-A2infNormFloat2)>1.e-5) { cout << "InfNorm should be = 1, but InfNorm = " << A2infNormFloat2 << endl; EPETRA_TEST_ERR(-43,ierr); InvSumsBroke = true; } // Doesn't work - may not need this test because column ownership is not unique /* EPETRA_TEST_ERR(A2.InvColSums(xCol),ierr); cout << xCol; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); float A2oneNormFloat = A2.NormOne(); cout << A2; if (fabs(1.0-A2oneNormFloat)>1.e-5) { EPETRA_TEST_ERR(-44,ierr); InvSumsBroke = true; } */ delete [] ColRightScaleValues; delete [] DomainRightScaleValues; if (verbose) cout << "Begin partial sum testing." << endl; // Test with a matrix that has partial sums for a subset of the rows // on multiple processors. (Except for the serial case, of course.) int NumMyRows3 = 2; // Changing this requires further changes below int * myGlobalElements = new int[NumMyRows3]; for (int i=0; i<NumMyRows3; i++) myGlobalElements[i] = MyPID+i; Epetra_Map RowMap3(NumProc*2, NumMyRows3, myGlobalElements, 0, Comm); int NumMyElements3 = 5; Epetra_CrsMatrix A3(Copy, RowMap3, NumMyElements3); double * Values3 = new double[NumMyElements3]; int * Indices3 = new int[NumMyElements3]; for (int i=0; i < NumMyElements3; i++) { Values3[i] = (int) (MyPID + (i+1)); Indices3[i]=i; } for (int i=0; i<NumMyRows3; i++) { A3.InsertGlobalValues(myGlobalElements[i],NumMyElements3,Values3,Indices3); } Epetra_Map RangeMap3(NumProc+1, 0, Comm); Epetra_Map DomainMap3(NumMyElements3, 0, Comm); EPETRA_TEST_ERR(A3.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A3; Epetra_Vector xRange3(RangeMap3,false); Epetra_Vector xDomain3(DomainMap3,false); EPETRA_TEST_ERR(A3.InvRowSums(xRange3),ierr); if (verbose1) cout << xRange3; EPETRA_TEST_ERR(A3.LeftScale(xRange3),ierr); float A3infNormFloat = A3.NormInf(); if (verbose1) cout << A3; if (1.0!=A3infNormFloat) { cout << "InfNorm should be = 1, but InfNorm = " << A3infNormFloat <<endl; EPETRA_TEST_ERR(-61,ierr); InvSumsBroke = true; } // we want to take the transpose of our matrix and fill in different values. int NumMyColumns3 = NumMyRows3; Epetra_Map ColMap3cm(RowMap3); Epetra_Map RowMap3cm(A3.ColMap()); Epetra_CrsMatrix A3cm(Copy,RowMap3cm,ColMap3cm,NumProc+1); double *Values3cm = new double[NumMyColumns3]; int * Indices3cm = new int[NumMyColumns3]; for (int i=0; i<NumMyColumns3; i++) { Values3cm[i] = MyPID + i + 1; Indices3cm[i]= i + MyPID; } for (int ii=0; ii<NumMyElements3; ii++) { A3cm.InsertGlobalValues(ii, NumMyColumns3, Values3cm, Indices3cm); } // The DomainMap and the RangeMap from the last test will work fine for // the RangeMap and DomainMap, respectively, but I will make copies to // avaoid confusion when passing what looks like a DomainMap where we // need a RangeMap and vice vera. Epetra_Map RangeMap3cm(DomainMap3); Epetra_Map DomainMap3cm(RangeMap3); EPETRA_TEST_ERR(A3cm.FillComplete(DomainMap3cm,RangeMap3cm),ierr); if (verbose1) cout << A3cm << endl; // Again, we can copy objects from the last example. //Epetra_Vector xRange3cm(xDomain3); //Don't use at this time Epetra_Vector xDomain3cm(DomainMap3cm,false); EPETRA_TEST_ERR(A3cm.InvColSums(xDomain3cm),ierr); if (verbose1) cout << xDomain3cm << endl; EPETRA_TEST_ERR(A3cm.RightScale(xDomain3cm),ierr); float A3cmOneNormFloat = A3cm.NormOne(); if (verbose1) cout << A3cm << endl; if (1.0!=A3cmOneNormFloat) { cout << "OneNorm should be = 1, but OneNorm = " << A3cmOneNormFloat << endl; EPETRA_TEST_ERR(-62,ierr); InvSumsBroke = true; } if (verbose) cout << "End partial sum testing" << endl; if (verbose) cout << "Begin replicated testing" << endl; // We will now view the shared row as a repliated row, rather than one // that has partial sums of its entries on mulitple processors. // We will reuse much of the data used for the partial sum tesitng. Epetra_Vector xRow3(RowMap3,false); Epetra_CrsMatrix A4(Copy, RowMap3, NumMyElements3); for (int ii=0; ii < NumMyElements3; ii++) { Values3[ii] = (int)((ii*.6)+1.0); } for (int ii=0; ii<NumMyRows3; ii++) { A4.InsertGlobalValues(myGlobalElements[ii],NumMyElements3,Values3,Indices3); } EPETRA_TEST_ERR(A4.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A4 << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4.InvRowMaxs(xRow3),ierr); EPETRA_TEST_ERR(A4.InvRowMaxs(xRange3),ierr); if (verbose1) cout << xRow3 << xRange3; EPETRA_TEST_ERR(A4.InvRowSums(xRow3),ierr); if (verbose1) cout << xRow3; EPETRA_TEST_ERR(A4.LeftScale(xRow3),ierr); float A4infNormFloat = A4.NormInf(); if (verbose1) cout << A4; if (2.0!=A4infNormFloat && NumProc != 1) { if (verbose1) cout << "InfNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } else if (1.0!=A4infNormFloat && NumProc == 1) { if (verbose1) cout << "InfNorm should be = 1, but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } Epetra_Vector xCol3cm(ColMap3cm,false); Epetra_CrsMatrix A4cm(Copy, RowMap3cm, ColMap3cm, NumProc+1); //Use values from A3cm for (int ii=0; ii<NumMyElements3; ii++) { A4cm.InsertGlobalValues(ii,NumMyColumns3,Values3cm,Indices3cm); } EPETRA_TEST_ERR(A4cm.FillComplete(DomainMap3cm, RangeMap3cm,false),ierr); if (verbose1) cout << A4cm << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4cm.InvColMaxs(xCol3cm),ierr); EPETRA_TEST_ERR(A4cm.InvColMaxs(xDomain3cm),ierr); if (verbose1) cout << xCol3cm << xDomain3cm; EPETRA_TEST_ERR(A4cm.InvColSums(xCol3cm),ierr); if (verbose1) cout << xCol3cm << endl; EPETRA_TEST_ERR(A4cm.RightScale(xCol3cm),ierr); float A4cmOneNormFloat = A4cm.NormOne(); if (verbose1) cout << A4cm << endl; if (2.0!=A4cmOneNormFloat && NumProc != 1) { if (verbose1) cout << "OneNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but OneNorm = " << A4cmOneNormFloat << endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } else if (1.0!=A4cmOneNormFloat && NumProc == 1) { if (verbose1) cout << "OneNorm should be = 1, but OneNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } if (verbose) cout << "End replicated testing" << endl; if (InvSumsBroke) { if (verbose) cout << endl << "InvRowSums tests FAILED" << endl << endl; } else if (verbose) cout << endl << "InvRowSums tests PASSED" << endl << endl; A3cm.PutScalar(2.0); int nnz_A3cm = A3cm.Graph().NumGlobalNonzeros(); double check_frobnorm = sqrt(nnz_A3cm*4.0); double frobnorm = A3cm.NormFrobenius(); bool frobnorm_test_failed = false; if (fabs(check_frobnorm-frobnorm) > 5.e-5) { frobnorm_test_failed = true; } if (frobnorm_test_failed) { if (verbose) std::cout << "Frobenius-norm test FAILED."<<std::endl; EPETRA_TEST_ERR(-65, ierr); } delete [] Values2; delete [] Indices2; delete [] myGlobalElements; delete [] Values3; delete [] Indices3; delete [] Values3cm; delete [] Indices3cm; delete [] RangeLeftScaleValues; delete [] RowLeftScaleValues; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { int ierr = 0, i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else int rank = 0; Epetra_SerialComm Comm; #endif #ifdef HAVE_EPETRA_TEUCHOS Teuchos::RCP<Teuchos::FancyOStream> fancyOut = Teuchos::VerboseObjectBase::getDefaultOStream(); if (Comm.NumProc() > 1 ) { fancyOut->setShowProcRank(true); fancyOut->setOutputToRootOnly(-1); } std::ostream &out = *fancyOut; #else std::ostream &out = std::cout; #endif Comm.SetTracebackMode(0); // This should shut down any error tracing bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // char tmp; // if (rank==0) out << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) out << Epetra_Version() << endl << endl; if (verbose) out << Comm <<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int NumMyElements = 10000; int NumMyElements1 = NumMyElements; // Needed for localmap int NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3); if (MyPID < 3) NumMyElements++; int IndexBase = 0; int ElementSize = 7; // Test LocalMap constructor // and Petra-defined uniform linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl; if (verbose) out << " and Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_LocalMap *LocalMap = new Epetra_LocalMap(NumMyElements1, IndexBase, Comm); Epetra_BlockMap * BlockMap = new Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; // Test User-defined linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! int * MyGlobalElements = new int[NumMyElements]; int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; int * ElementSizeList = new int[NumMyElements]; int NumMyEquations = 0; int NumGlobalEquations = 0; for (i = 0; i<NumMyElements; i++) { ElementSizeList[i] = i%6+2; // blocksizes go from 2 to 7 NumMyEquations += ElementSizeList[i]; } ElementSize = 7; // Set to maximum for use in checkmap NumGlobalEquations = Comm.NumProc()*NumMyEquations; // Adjust NumGlobalEquations based on processor ID if (Comm.NumProc() > 3) { if (Comm.MyPID()>2) NumGlobalEquations += 3*((NumMyElements)%6+2); else NumGlobalEquations -= (Comm.NumProc()-3)*((NumMyElements-1)%6+2); } if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); // Test Copy constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(*BlockMap)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_BlockMap * BlockMap1 = new Epetra_BlockMap(*BlockMap); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete [] ElementSizeList; delete [] MyGlobalElements; delete BlockMap; delete BlockMap1; // Test Petra-defined uniform linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_Map * Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete Map; // Test User-defined linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete Map; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! MyGlobalElements = new int[NumMyElements]; MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); // Test Copy constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(*Map)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_Map Map1(*Map); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete [] MyGlobalElements; delete Map; if (verbose1) { // Test Vector MFLOPS for 2D Dot Product int M = 1; int K = 1000000; Epetra_Map Map2(-1, K, IndexBase, Comm); Epetra_LocalMap Map3(M, IndexBase, Comm); Epetra_Vector A(Map2);A.Random(); Epetra_Vector B(Map2);B.Random(); Epetra_Vector C(Map3);C.Random(); // Test Epetra_Vector label const char* VecLabel = A.Label(); const char* VecLabel1 = "Epetra::Vector"; if (verbose) out << endl << endl <<"This should say " << VecLabel1 << ": " << VecLabel << endl << endl << endl; EPETRA_TEST_ERR(strcmp(VecLabel1,VecLabel),ierr); if (verbose) out << "Testing Assignment operator" << endl; double tmp1 = 1.00001* (double) (MyPID+1); double tmp2 = tmp1; A[1] = tmp1; tmp2 = A[1]; out << "On PE "<< MyPID << " A[1] should equal = " << tmp1; if (tmp1==tmp2) out << " and it does!" << endl; else out << " but it equals " << tmp2; Comm.Barrier(); if (verbose) out << endl << endl << "Testing MFLOPs" << endl; Epetra_Flops counter; C.SetFlopCounter(counter); Epetra_Time mytimer(Comm); C.Multiply('T', 'N', 0.5, A, B, 0.0); double Multiply_time = mytimer.ElapsedTime(); double Multiply_flops = C.Flops(); if (verbose) out << "\n\nTotal FLOPs = " << Multiply_flops << endl; if (verbose) out << "Total Time = " << Multiply_time << endl; if (verbose) out << "MFLOPs = " << Multiply_flops/Multiply_time/1000000.0 << endl; Comm.Barrier(); // Test Vector ostream operator with Petra-defined uniform linear distribution constructor // and a small vector Epetra_Map Map4(100, IndexBase, Comm); double * Dp = new double[100]; for (i=0; i<100; i++) Dp[i] = i; Epetra_Vector D(View, Map4,Dp); if (verbose) out << "\n\nTesting ostream operator: Multivector should be 100-by-2 and print i,j indices" << endl << endl; out << D << endl; if (verbose) out << "Traceback Mode value = " << D.GetTracebackMode() << endl; delete [] Dp; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
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); }
int checkLocalMapDataClass(Epetra_Comm& Comm, int verbose) { int returnierr = 0; int NumMyElements = 100; int IndexBase = 0; Epetra_LocalMap m1(NumMyElements, IndexBase, Comm); int m1count = m1.ReferenceCount(); const Epetra_BlockMapData* m1addr = m1.DataPtr(); EPETRA_TEST_ERR(!(m1count==1),returnierr); // count should be 1 if(verbose) cout << "Default constructor. \nm1= " << m1count << " " << m1addr << endl; Epetra_LocalMap* m2 = new Epetra_LocalMap(m1); int m2count = m2->ReferenceCount(); const Epetra_BlockMapData* m2addr = m2->DataPtr(); int m1countold = m1count; m1count = m1.ReferenceCount(); EPETRA_TEST_ERR(!(m2count==m1count && m1count==(m1countold+1)),returnierr); // both counts should be 2 EPETRA_TEST_ERR(!(m1addr==m2addr),returnierr); // addresses should be same if(verbose) cout << "Copy constructor. \nm1= " << m1count << " " << m1addr << "\nm2= " << m2count << " " << m2addr << endl; delete m2; m1countold = m1count; m1count = m1.ReferenceCount(); EPETRA_TEST_ERR(!(m1count == m1countold-1), returnierr); // count should have decremented (to 1) EPETRA_TEST_ERR(!(m1addr == m1.DataPtr()),returnierr); // m1addr should be unchanged if(verbose) cout << "m2 destroyed. \nm1= " << m1count << " " << m1addr << endl; { // inside of braces to test stack deallocation. if(verbose) cout << "Assignment operator, post construction" << endl; Epetra_LocalMap m3(NumMyElements, IndexBase+1, Comm); int m3count = m3.ReferenceCount(); const Epetra_BlockMapData* m3addr = m3.DataPtr(); EPETRA_TEST_ERR(!(m3count==1),returnierr); // m3count should be 1 initially EPETRA_TEST_ERR(!(m1addr!=m3addr),returnierr); // m1 and m3 should have different ptr addresses if(verbose) cout << "Prior to assignment: \nm1= " << m1count << " " << m1addr << "\nm3= " << m3count << " " << m3addr << endl; m3 = m1; m3count = m3.ReferenceCount(); m3addr = m3.DataPtr(); // cast int* to int m1countold = m1count; m1count = m1.ReferenceCount(); EPETRA_TEST_ERR(!(m3count==m1count && m1count==m1countold+1),returnierr); // both counts should be 2 EPETRA_TEST_ERR(!(m1addr==m3addr),returnierr); // addresses should be same if(verbose) cout << "After assignment: \nm1= " << m1count << " " << m1addr << "\nm3= " << m3count << " " << m3addr << endl; } m1countold = m1count; m1count = m1.ReferenceCount(); EPETRA_TEST_ERR(!(m1count==m1countold-1), returnierr); // count should have decremented (to 1) EPETRA_TEST_ERR(!(m1addr== m1.DataPtr()),returnierr); // m1addr should be unchanged if(verbose) cout << "m3 destroyed. \nm1= " << m1count << " " << m1addr << endl; return(returnierr); }
int quad2(const Epetra_Map& map, bool verbose) { const Epetra_Comm & Comm = map.Comm(); int numProcs = Comm.NumProc(); int localProc = Comm.MyPID(); Comm.Barrier(); if (verbose && localProc == 0) { cout << "====================== quad2 =============================="<<endl; } //Set up a simple finite-element mesh containing 2-D quad elements, 2 per proc. //(This test is similar to quad1() above, except for having 2 elements-per-proc // rather than 1.) // // *-----*-----*-----*-------* // 0| 2| 4| 6| 8| // | 0 | 1 | 2 | 2*np-1| // | | | | | // *-----*-----*-----*-------* // 1 3 5 7 9 // //In the above drawing, 'np' means num-procs. node-numbers are to the //lower-left of each node (*). // //Each processor owns element 'localProc' and 'localProc+1', and each processor //owns nodes 'localProc*4' through 'localProc*4+3' except for the last //processor, which also owns the last two nodes in the mesh. // //There will be 3 degrees-of-freedom per node, so each element-matrix is //of size 12x12. // int myFirstNode = localProc*4; int myLastNode = localProc*4+3; if (localProc == numProcs-1) { myLastNode += 2; } int numMyElems = 2; int numMyNodes = myLastNode - myFirstNode + 1; int* myNodes = new int[numMyNodes]; int i, j, ierr; for(i=0; i<numMyNodes; ++i) { myNodes[i] = myFirstNode + i; } int dofPerNode = 3; //degrees-of-freedom per node int indexBase = 0; Epetra_BlockMap blkMap(-1, numMyNodes, myNodes, dofPerNode, indexBase, Comm); int rowLengths = 4; //each element-matrix will have 4 block-columns. //the rows of the assembled matrix will be longer than //this, but we don't need to worry about that because the //VbrMatrix will add memory as needed. For a real //application where efficiency is a concern, better //performance would be obtained by giving a more accurate //row-length here. Epetra_FEVbrMatrix A(Copy, blkMap, rowLengths); int nodesPerElem = 4; int* elemNodes = new int[nodesPerElem]; int elemMatrixDim = nodesPerElem*dofPerNode; int len = elemMatrixDim*elemMatrixDim; double* elemMatrix = new double[len]; //In an actual finite-element problem, we would calculate and fill //meaningful element stiffness matrices. But for this simple matrix assembly //test, we're just going to fill our element matrix with 1.0's. This will //make it easy to see whether the matrix is correct after it's assembled. for(i=0; i<len; ++i) elemMatrix[i] = 1.0; //For filling in the matrix block-entries, we would ordinarily have to //carefully copy, or set pointers to, appropriate sections of the //element-matrix. But for this simple case we know that the element-matrix //is all 1's, so we'll just set our block-entry pointer to point to the //beginning of the element-matrix and leave it at that. //Note that the matrix class will refer to dofPerNode X dofPerNode (==9) //positions in the memory pointed to by 'blockEntry'. double* blockEntry = elemMatrix; //Each element-matrix is a 4x4 (nodesPerElem X nodesPerElem) matrix of //3x3 block-entries. We'll now load our element-matrices into the global //matrix by looping over them and loading block-entries individually. int firstNode = myFirstNode; for(int el=0; el<numMyElems; ++el) { for(i=0; i<nodesPerElem; ++i) { for(int n=0; n<nodesPerElem; ++n) elemNodes[n] = firstNode+n; int blkrow = firstNode+i; EPETRA_TEST_ERR( A.BeginInsertGlobalValues(blkrow, nodesPerElem, elemNodes), ierr); for(j=0; j<nodesPerElem; ++j) { EPETRA_TEST_ERR( A.SubmitBlockEntry( blockEntry, dofPerNode, dofPerNode, dofPerNode), ierr); } int this_err = A.EndSubmitEntries(); if (this_err < 0) { cerr << "error in quad2, A.EndSubmitEntries(): " << this_err << endl; return(this_err); } } firstNode += 2; } EPETRA_TEST_ERR( A.GlobalAssemble(), ierr); if (verbose && localProc==0) { cout << "after globalAssemble"<<endl; } if (verbose) { A.Print(cout); } //now let's make sure that we can perform a matvec... Epetra_FEVector x(blkMap, 1), y(blkMap, 1); x.PutScalar(1.0); EPETRA_TEST_ERR( A.Multiply(false, x, y), ierr); if (verbose && localProc==0) { cout << "quad2, y:"<<endl; } if (verbose) { y.Print(cout); } delete [] elemMatrix; delete [] myNodes; delete [] elemNodes; return(0); }
int main(int argc, char *argv[]) { int ierr = 0, i, forierr = 0; #ifdef HAVE_MPI CT_Epetra_MpiComm_ID_Flex_t Comm; // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Comm.Epetra_MpiComm = Epetra_MpiComm_Create( MPI_COMM_WORLD ); #else int rank = 0; CT_Epetra_SerialComm_ID_Flex_t Comm; Comm.Epetra_SerialComm = Epetra_SerialComm_Create(); #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Epetra_Comm_Broadcast_Int(Comm.Epetra_Comm, &verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Epetra_Comm_Barrier(Comm.Epetra_Comm); // Epetra_Comm_SetTracebackMode(Comm.Epetra_Comm, 0); // This should shut down any error traceback reporting int MyPID = Epetra_Comm_MyPID(Comm.Epetra_Comm); int NumProc = Epetra_Comm_NumProc(Comm.Epetra_Comm); if(verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor CT_Epetra_Map_ID_Flex_t Map; Map.Epetra_Map = Epetra_Map_Create_Linear(NumGlobalEquations, NumMyEquations, 0, Comm.Epetra_Comm); // Get update list and number of local equations from newly created Map vector<int> MyGlobalElements(Epetra_BlockMap_NumMyElements(Map.Epetra_BlockMap)); Epetra_BlockMap_MyGlobalElements_Fill(Map.Epetra_BlockMap, &MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor vector<int> NumNz(NumMyEquations); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix CT_Epetra_CrsMatrix_ID_Flex_t A; A.Epetra_CrsMatrix = Epetra_CrsMatrix_Create_VarPerRow( CT_Epetra_DataAccess_E_Copy, Map.Epetra_Map, &NumNz[0], FALSE); EPETRA_TEST_ERR(Epetra_CrsMatrix_IndicesAreGlobal(A.Epetra_CrsMatrix),ierr); EPETRA_TEST_ERR(Epetra_CrsMatrix_IndicesAreLocal(A.Epetra_CrsMatrix),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; vector<int> Indices(2); double two = 2.0; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(Epetra_CrsMatrix_InsertGlobalValues(A.Epetra_CrsMatrix, MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0); forierr += !(Epetra_CrsMatrix_InsertGlobalValues(A.Epetra_CrsMatrix, MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up Epetra_CrsMatrix_FillComplete(A.Epetra_CrsMatrix, TRUE); Epetra_CrsMatrix_OptimizeStorage(A.Epetra_CrsMatrix); CT_Epetra_JadMatrix_ID_Flex_t JadA, JadA1, JadA2; JadA.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix); JadA1.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix); JadA2.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix); // Create vectors for Power method CT_Epetra_Vector_ID_Flex_t q, z, resid; q.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE); z.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE); Epetra_MultiVector_Random(z.Epetra_MultiVector); resid.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE); CT_Epetra_Flops_ID_t flopcounter = Epetra_Flops_Create(); Epetra_CompObject_SetFlopCounter(A.Epetra_CompObject, flopcounter); Epetra_CompObject_SetFlopCounter_Matching(q.Epetra_CompObject, A.Epetra_CompObject); Epetra_CompObject_SetFlopCounter_Matching(z.Epetra_CompObject, A.Epetra_CompObject); Epetra_CompObject_SetFlopCounter_Matching(resid.Epetra_CompObject, A.Epetra_CompObject); Epetra_CompObject_SetFlopCounter_Matching(JadA.Epetra_CompObject, A.Epetra_CompObject); Epetra_CompObject_SetFlopCounter_Matching(JadA1.Epetra_CompObject, A.Epetra_CompObject); Epetra_CompObject_SetFlopCounter_Matching(JadA2.Epetra_CompObject, A.Epetra_CompObject); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; Epetra_CompObject_ResetFlops(A.Epetra_CompObject); powerMethodTests(A.Epetra_RowMatrix, JadA.Epetra_RowMatrix, Map, q, z, resid, verbose); // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (Epetra_CrsMatrix_MyGlobalRow(A.Epetra_CrsMatrix, 0)) { int numvals = Epetra_CrsMatrix_NumGlobalEntries(A.Epetra_CrsMatrix, 0); vector<double> Rowvals(numvals); vector<int> Rowinds(numvals); Epetra_CrsMatrix_ExtractGlobalRowCopy_WithIndices(A.Epetra_CrsMatrix, 0, numvals, &numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0] for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; Epetra_CrsMatrix_ReplaceGlobalValues(A.Epetra_CrsMatrix, 0, numvals, &Rowvals[0], &Rowinds[0]); } Epetra_JadMatrix_UpdateValues(JadA.Epetra_JadMatrix, A.Epetra_RowMatrix, FALSE); Epetra_CompObject_ResetFlops(A.Epetra_CompObject); powerMethodTests(A.Epetra_RowMatrix, JadA.Epetra_RowMatrix, Map, q, z, resid, verbose); if (verbose) cout << "================================================================" << endl << "Testing Jad using Jad matrix as input matrix for construction..." << endl << "================================================================" << endl; Epetra_CompObject_ResetFlops(JadA1.Epetra_CompObject); powerMethodTests(JadA1.Epetra_RowMatrix, JadA2.Epetra_RowMatrix, Map, q, z, resid, verbose); #ifdef HAVE_MPI MPI_Finalize() ; #endif return ierr ; }
int MultiVectorTests(const Epetra_Map & Map, int NumVectors, bool verbose) { const Epetra_Comm & Comm = Map.Comm(); int ierr = 0, i, j; /* get number of processors and the name of this processor */ int MyPID = Comm.MyPID(); // Construct FEVbrMatrix if (verbose && MyPID==0) cout << "constructing Epetra_FEVbrMatrix" << endl; // //we'll set up a tri-diagonal matrix. // int numGlobalRows = Map.NumGlobalElements(); int minLocalRow = Map.MinMyGID(); int rowLengths = 3; Epetra_FEVbrMatrix A(Copy, Map, rowLengths); if (verbose && MyPID==0) { cout << "calling A.InsertGlobalValues with 1-D data array"<<endl; } int numCols = 3; int* ptIndices = new int[numCols]; for(int k=0; k<numCols; ++k) { ptIndices[k] = minLocalRow+k; } double* values_1d = new double[numCols*numCols]; for(j=0; j<numCols*numCols; ++j) { values_1d[j] = 3.0; } //For an extreme test, we'll have all processors sum into all rows. int minGID = Map.MinAllGID(); //For now we're going to assume that there's just one point associated with //each GID (element). double* ptCoefs = new double[3]; {for(i=0; i<numGlobalRows; ++i) { if (i>0 && i<numGlobalRows-1) { ptIndices[0] = minGID+i-1; ptIndices[1] = minGID+i; ptIndices[2] = minGID+i+1; ptCoefs[0] = -1.0; ptCoefs[1] = 2.0; ptCoefs[2] = -1.0; numCols = 3; } else if (i == 0) { ptIndices[0] = minGID+i; ptIndices[1] = minGID+i+1; ptIndices[2] = minGID+i+2; ptCoefs[0] = 2.0; ptCoefs[1] = -1.0; ptCoefs[2] = -1.0; numCols = 3; } else { ptIndices[0] = minGID+i-2; ptIndices[1] = minGID+i-1; ptIndices[2] = minGID+i; ptCoefs[0] = -1.0; ptCoefs[1] = -1.0; ptCoefs[2] = 2.0; numCols = 3; } int row = minGID+i; EPETRA_TEST_ERR( A.BeginInsertGlobalValues(row, rowLengths, ptIndices), ierr); for(j=0; j<rowLengths; ++j) { EPETRA_TEST_ERR( A.SubmitBlockEntry(&(ptCoefs[j]), 1, 1, 1), ierr); } EPETRA_TEST_ERR( A.EndSubmitEntries(), 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); } delete [] values_1d; delete [] ptIndices; delete [] ptCoefs; return(ierr); }
int check(CT_Epetra_RowMatrix_ID_t& A, CT_Epetra_RowMatrix_ID_t & B, bool verbose) { int ierr = 0; CT_Epetra_Operator_ID_t tmp_oA = Epetra_Operator_Degeneralize(Epetra_RowMatrix_Generalize(A)); CT_Epetra_Operator_ID_t tmp_oB = Epetra_Operator_Degeneralize(Epetra_RowMatrix_Generalize(B)); CT_Epetra_Comm_ID_t CommA = Epetra_Operator_Comm(tmp_oA); CT_Epetra_Comm_ID_t CommB = Epetra_Operator_Comm(tmp_oB); EPETRA_TEST_ERR(!Epetra_Comm_NumProc(CommA)==Epetra_Comm_NumProc(CommB),ierr); EPETRA_TEST_ERR(!Epetra_Comm_MyPID(CommA)==Epetra_Comm_MyPID(CommB),ierr); Epetra_Comm_Destroy(&CommB); Epetra_Comm_Destroy(&CommA); EPETRA_TEST_ERR(!Epetra_RowMatrix_Filled(A)==Epetra_RowMatrix_Filled(B),ierr); EPETRA_TEST_ERR(!Epetra_Operator_HasNormInf(tmp_oA)==Epetra_Operator_HasNormInf(tmp_oB),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_LowerTriangular(A)==Epetra_RowMatrix_LowerTriangular(B),ierr); CT_Epetra_BlockMap_ID_t mapA = Epetra_SrcDistObject_Map(Epetra_SrcDistObject_Degeneralize( Epetra_RowMatrix_Generalize(A))); CT_Epetra_BlockMap_ID_t mapB = Epetra_SrcDistObject_Map(Epetra_SrcDistObject_Degeneralize( Epetra_RowMatrix_Generalize(B))); EPETRA_TEST_ERR(!Epetra_BlockMap_SameAs(mapA, mapB),ierr); Epetra_BlockMap_Destroy(&mapB); Epetra_BlockMap_Destroy(&mapA); EPETRA_TEST_ERR(!Epetra_RowMatrix_MaxNumEntries(A)==Epetra_RowMatrix_MaxNumEntries(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumGlobalCols(A)==Epetra_RowMatrix_NumGlobalCols(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumGlobalDiagonals(A)==Epetra_RowMatrix_NumGlobalDiagonals(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumGlobalNonzeros(A)==Epetra_RowMatrix_NumGlobalNonzeros(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumGlobalRows(A)==Epetra_RowMatrix_NumGlobalRows(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumMyCols(A)==Epetra_RowMatrix_NumMyCols(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumMyDiagonals(A)==Epetra_RowMatrix_NumMyDiagonals(B),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_NumMyNonzeros(A)==Epetra_RowMatrix_NumMyNonzeros(B),ierr); for (int i=0; i<Epetra_RowMatrix_NumMyRows(A); i++) { int nA, nB; Epetra_RowMatrix_NumMyRowEntries(A,i,&nA); Epetra_RowMatrix_NumMyRowEntries(B,i,&nB); EPETRA_TEST_ERR(!nA==nB,ierr); } EPETRA_TEST_ERR(!Epetra_RowMatrix_NumMyRows(A)==Epetra_RowMatrix_NumMyRows(B),ierr); CT_Epetra_BlockMap_ID_t bodmA = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_Operator_OperatorDomainMap(tmp_oA))); CT_Epetra_BlockMap_ID_t bodmB = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_Operator_OperatorDomainMap(tmp_oB))); EPETRA_TEST_ERR(!Epetra_BlockMap_SameAs(bodmA, bodmB),ierr); CT_Epetra_BlockMap_ID_t bormA = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_Operator_OperatorRangeMap(tmp_oA))); CT_Epetra_BlockMap_ID_t bormB = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_Operator_OperatorRangeMap(tmp_oB))); EPETRA_TEST_ERR(!Epetra_BlockMap_SameAs(bormA, bormB),ierr); CT_Epetra_BlockMap_ID_t brcmA = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_RowMatrix_RowMatrixColMap(A))); CT_Epetra_BlockMap_ID_t brcmB = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_RowMatrix_RowMatrixColMap(B))); EPETRA_TEST_ERR(!Epetra_BlockMap_SameAs(brcmA, brcmB),ierr); CT_Epetra_BlockMap_ID_t brrmA = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_RowMatrix_RowMatrixRowMap(A))); CT_Epetra_BlockMap_ID_t brrmB = Epetra_BlockMap_Degeneralize(Epetra_Map_Generalize( Epetra_RowMatrix_RowMatrixRowMap(B))); EPETRA_TEST_ERR(!Epetra_BlockMap_SameAs(brrmA, brrmB),ierr); EPETRA_TEST_ERR(!Epetra_RowMatrix_UpperTriangular(A)==Epetra_RowMatrix_UpperTriangular(B),ierr); EPETRA_TEST_ERR(!Epetra_Operator_UseTranspose(tmp_oA)==Epetra_Operator_UseTranspose(tmp_oB),ierr); int NumVectors = 5; { // No transpose case CT_Epetra_MultiVector_ID_t X = Epetra_MultiVector_Create(bodmA, NumVectors, TRUE); CT_Epetra_MultiVector_ID_t YA1 = Epetra_MultiVector_Create(bormA, NumVectors, TRUE); CT_Epetra_MultiVector_ID_t YA2 = Epetra_MultiVector_Duplicate(YA1); CT_Epetra_MultiVector_ID_t YB1 = Epetra_MultiVector_Duplicate(YA1); CT_Epetra_MultiVector_ID_t YB2 = Epetra_MultiVector_Duplicate(YA1); Epetra_MultiVector_Random(X); boolean transA = FALSE; Epetra_Operator_SetUseTranspose(tmp_oA, transA); Epetra_Operator_SetUseTranspose(tmp_oB, transA); Epetra_Operator_Apply(tmp_oA,X,YA1); Epetra_RowMatrix_Multiply(A, transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2,"A Multiply and A Apply", verbose),ierr); Epetra_Operator_Apply(tmp_oB,X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1,"A Multiply and B Multiply", verbose),ierr); Epetra_RowMatrix_Multiply(B, transA, X, YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2,"A Multiply and B Apply", verbose), ierr); Epetra_MultiVector_Destroy(&X); Epetra_MultiVector_Destroy(&YB2); Epetra_MultiVector_Destroy(&YB1); Epetra_MultiVector_Destroy(&YA2); Epetra_MultiVector_Destroy(&YA1); } {// transpose case CT_Epetra_MultiVector_ID_t X = Epetra_MultiVector_Create(bormA, NumVectors, TRUE); CT_Epetra_MultiVector_ID_t YA1 = Epetra_MultiVector_Create(bodmA, NumVectors, TRUE); CT_Epetra_MultiVector_ID_t YA2 = Epetra_MultiVector_Duplicate(YA1); CT_Epetra_MultiVector_ID_t YB1 = Epetra_MultiVector_Duplicate(YA1); CT_Epetra_MultiVector_ID_t YB2 = Epetra_MultiVector_Duplicate(YA1); Epetra_MultiVector_Random(X); boolean transA = TRUE; Epetra_Operator_SetUseTranspose(tmp_oA, transA); Epetra_Operator_SetUseTranspose(tmp_oB, transA); Epetra_Operator_Apply(tmp_oA,X,YA1); Epetra_RowMatrix_Multiply(A, transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2, "A Multiply and A Apply (transpose)", verbose),ierr); Epetra_Operator_Apply(tmp_oB,X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1, "A Multiply and B Multiply (transpose)", verbose),ierr); Epetra_RowMatrix_Multiply(B, transA, X, YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2, "A Multiply and B Apply (transpose)", verbose),ierr); Epetra_MultiVector_Destroy(&X); Epetra_MultiVector_Destroy(&YB2); Epetra_MultiVector_Destroy(&YB1); Epetra_MultiVector_Destroy(&YA2); Epetra_MultiVector_Destroy(&YA1); } CT_Epetra_Vector_ID_Flex_t diagA; diagA.Epetra_Vector = Epetra_Vector_Create(brrmA, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_ExtractDiagonalCopy(A, diagA.Epetra_Vector),ierr); CT_Epetra_Vector_ID_Flex_t diagB; diagB.Epetra_Vector = Epetra_Vector_Create(brrmB, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_ExtractDiagonalCopy(B, diagB.Epetra_Vector),ierr); EPETRA_TEST_ERR(checkMultiVectors(diagA.Epetra_MultiVector,diagB.Epetra_MultiVector, "ExtractDiagonalCopy", verbose),ierr); CT_Epetra_Vector_ID_Flex_t rowA; rowA.Epetra_Vector = Epetra_Vector_Create(brrmA, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_InvRowSums(A, rowA.Epetra_Vector),ierr); CT_Epetra_Vector_ID_Flex_t rowB; rowB.Epetra_Vector = Epetra_Vector_Create(brrmB, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_InvRowSums(B, rowB.Epetra_Vector),ierr) EPETRA_TEST_ERR(checkMultiVectors(rowA.Epetra_MultiVector,rowB.Epetra_MultiVector, "InvRowSums", verbose),ierr); CT_Epetra_Vector_ID_Flex_t colA; colA.Epetra_Vector = Epetra_Vector_Create(brcmA, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_InvColSums(A, colA.Epetra_Vector),ierr); CT_Epetra_Vector_ID_Flex_t colB; colB.Epetra_Vector = Epetra_Vector_Create(brcmB, TRUE); EPETRA_TEST_ERR(Epetra_RowMatrix_InvColSums(B, colB.Epetra_Vector),ierr); EPETRA_TEST_ERR(checkMultiVectors(colA.Epetra_MultiVector,colB.Epetra_MultiVector, "InvColSums", verbose),ierr); EPETRA_TEST_ERR(checkValues(Epetra_RowMatrix_NormInf(A), Epetra_RowMatrix_NormInf(B), "NormInf before scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(Epetra_RowMatrix_NormOne(A), Epetra_RowMatrix_NormOne(B), "NormOne before scaling", verbose),ierr); EPETRA_TEST_ERR(Epetra_RowMatrix_RightScale(A, colA.Epetra_Vector),ierr); EPETRA_TEST_ERR(Epetra_RowMatrix_RightScale(B, colB.Epetra_Vector),ierr); EPETRA_TEST_ERR(Epetra_RowMatrix_LeftScale(A, rowA.Epetra_Vector),ierr); EPETRA_TEST_ERR(Epetra_RowMatrix_LeftScale(B, rowB.Epetra_Vector),ierr); Epetra_Vector_Destroy(&colB.Epetra_Vector); Epetra_Vector_Destroy(&colA.Epetra_Vector); Epetra_Vector_Destroy(&rowB.Epetra_Vector); Epetra_Vector_Destroy(&rowA.Epetra_Vector); Epetra_Vector_Destroy(&diagB.Epetra_Vector); Epetra_Vector_Destroy(&diagA.Epetra_Vector); Epetra_BlockMap_Destroy(&brrmA); Epetra_BlockMap_Destroy(&brrmB); Epetra_BlockMap_Destroy(&brcmA); Epetra_BlockMap_Destroy(&brcmB); Epetra_BlockMap_Destroy(&bormA); Epetra_BlockMap_Destroy(&bormB); Epetra_BlockMap_Destroy(&bodmA); Epetra_BlockMap_Destroy(&bodmB); EPETRA_TEST_ERR(checkValues(Epetra_RowMatrix_NormInf(A), Epetra_RowMatrix_NormInf(B), "NormInf after scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(Epetra_RowMatrix_NormOne(A), Epetra_RowMatrix_NormOne(B), "NormOne after scaling", verbose),ierr); vector<double> valuesA(Epetra_RowMatrix_MaxNumEntries(A)); vector<int> indicesA(Epetra_RowMatrix_MaxNumEntries(A)); vector<double> valuesB(Epetra_RowMatrix_MaxNumEntries(B)); vector<int> indicesB(Epetra_RowMatrix_MaxNumEntries(B)); return(0); for (int i=0; i<Epetra_RowMatrix_NumMyRows(A); i++) { int nA, nB; EPETRA_TEST_ERR(Epetra_RowMatrix_ExtractMyRowCopy(A, i, Epetra_RowMatrix_MaxNumEntries(A), &nA, &valuesA[0], &indicesA[0]),ierr); EPETRA_TEST_ERR(Epetra_RowMatrix_ExtractMyRowCopy(B, i, Epetra_RowMatrix_MaxNumEntries(B), &nB, &valuesB[0], &indicesB[0]),ierr); EPETRA_TEST_ERR(!nA==nB,ierr); for (int j=0; j<nA; j++) { double curVal = valuesA[j]; int curIndex = indicesA[j]; bool notfound = true; int jj = 0; while (notfound && jj< nB) { if (!checkValues(curVal, valuesB[jj])) notfound = false; jj++; } EPETRA_TEST_ERR(notfound, ierr); vector<int>::iterator p = find(indicesB.begin(),indicesB.end(),curIndex); // find curIndex in indicesB EPETRA_TEST_ERR(p==indicesB.end(), ierr); } } if (verbose) cout << "RowMatrix Methods check OK" << endl; return (ierr); }
int quad1(const Epetra_Map& map, bool verbose) { const Epetra_Comm & Comm = map.Comm(); int numProcs = Comm.NumProc(); int localProc = Comm.MyPID(); Comm.Barrier(); if (verbose && localProc == 0) { cout << "====================== quad1 =============================="<<endl; } //Set up a simple finite-element mesh containing 2-D quad elements, 1 per proc. // // *-----*-----*-----* // 0| 2| 4| 6| // | 0 | 1 | np-1| // | | | | // *-----*-----*-----* // 1 3 5 7 // //In the above drawing, 'np' means num-procs. node-numbers are to the //lower-left of each node (*). // //Each processor owns element 'localProc', and each processor owns //nodes 'localProc*2' and 'localProc*2+1' except for the last processor, //which also owns the last two nodes. // //There will be 3 degrees-of-freedom per node, so each element-matrix is //of size 12x12. (4 nodes per element, X 3 dof per node) // int myFirstNode = localProc*2; int myLastNode = localProc*2+1; if (localProc == numProcs-1) { myLastNode += 2; } int numMyNodes = myLastNode - myFirstNode + 1; int* myNodes = new int[numMyNodes]; int i, j, ierr; for(i=0; i<numMyNodes; ++i) { myNodes[i] = myFirstNode + i; } int dofPerNode = 3; //degrees-of-freedom per node int indexBase = 0; Epetra_BlockMap blkMap(-1, numMyNodes, myNodes, dofPerNode, indexBase, Comm); int rowLengths = 3; //each element-matrix will have 4 block-columns. //the rows of the assembled matrix will be longer than //this, but we don't need to worry about that because the //VbrMatrix will add memory as needed. For a real //application where efficiency is a concern, better //performance would be obtained by giving more accurate //row-lengths here. Epetra_FEVbrMatrix A(Copy, blkMap, rowLengths); int nodesPerElem = 4; int* elemNodes = new int[nodesPerElem]; for(i=0; i<nodesPerElem; ++i) elemNodes[i] = myFirstNode+i; int elemMatrixDim = nodesPerElem*dofPerNode; int len = elemMatrixDim*elemMatrixDim; double* elemMatrix = new double[len]; //In an actual finite-element problem, we would calculate and fill //meaningful element stiffness matrices. But for this simple matrix assembly //test, we're just going to fill our element matrix with 1.0's. This will //make it easy to see whether the matrix is correct after it's assembled. for(i=0; i<len; ++i) elemMatrix[i] = 1.0; //For filling in the matrix block-entries, we would ordinarily have to //carefully copy, or set pointers to, appropriate sections of the //element-matrix. But for this simple case we know that the element-matrix //is all 1's, so we'll just set our block-entry pointer to point to the //beginning of the element-matrix and leave it at that. //Note that the matrix class will refer to dofPerNode X dofPerNode (==9) //positions in the memory pointed to by 'blockEntry'. double* blockEntry = elemMatrix; //The element-matrix is a 4x4 (nodesPerElem X nodesPerElem) matrix of //3x3 block-entries. We'll now load our element-matrix into the global //matrix by looping over it and loading block-entries individually. for(i=0; i<nodesPerElem; ++i) { int blkrow = myFirstNode+i; EPETRA_TEST_ERR( A.BeginInsertGlobalValues(blkrow, nodesPerElem, elemNodes), ierr); for(j=0; j<nodesPerElem; ++j) { for(int ii=0; ii<dofPerNode*dofPerNode; ii++) { blockEntry[ii] = blkrow+elemNodes[j]; } EPETRA_TEST_ERR( A.SubmitBlockEntry( blockEntry, dofPerNode, dofPerNode, dofPerNode), ierr); } int err = A.EndSubmitEntries(); if (err < 0) { cout << "quad1: error in A.EndSubmitEntries: "<<err<<endl; return(-1); } } EPETRA_TEST_ERR( A.GlobalAssemble(), ierr); if (verbose && localProc==0) { cout << "after globalAssemble"<<endl; } if (verbose) { A.Print(cout); } int numMyRows = A.NumMyRows(); int correct_numMyRows = dofPerNode*numMyNodes; if (numMyRows != correct_numMyRows) { cout << "proc " << localProc << ", numMyRows("<<numMyRows<<") doesn't match" << " correct_numMyRows("<<correct_numMyRows<<")."<<endl; return(-1); } int numMyNonzeros = A.NumMyNonzeros(); int correct_numMyNonzeros = nodesPerElem*nodesPerElem*dofPerNode*dofPerNode; if (numProcs > 1) { if (localProc == numProcs-1) { correct_numMyNonzeros += dofPerNode*dofPerNode*4; } else if (localProc > 0) { correct_numMyNonzeros -= dofPerNode*dofPerNode*4; } else { //localProc==0 && numProcs > 1 correct_numMyNonzeros -= dofPerNode*dofPerNode*8; } } if (numMyNonzeros != correct_numMyNonzeros) { cout << "proc " << localProc << ", numMyNonzeros(" << numMyNonzeros <<") != correct_numMyNonzeros("<<correct_numMyNonzeros<<")"<<endl; return(-1); } delete [] elemMatrix; delete [] myNodes; delete [] elemNodes; Comm.Barrier(); return(0); }
int powerMethodTests(Epetra_RowMatrix & A, Epetra_RowMatrix & JadA, Epetra_Map & Map, Epetra_Vector & q, Epetra_Vector & z, Epetra_Vector & resid, bool verbose) { // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 300; double tolerance = 1.0e-2; int ierr = 0; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate Epetra_Time timer(Map.Comm()); double startTime = timer.ElapsedTime(); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = timer.ElapsedTime() - startTime; double total_flops = q.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; double lambdaref = lambda; double flopsref = total_flops; if (verbose) cout << "\n\nTotal MFLOPs for reference first solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; lambda = 0.0; startTime = timer.ElapsedTime(); EPETRA_TEST_ERR(power_method(false, JadA, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime() - startTime; total_flops = q.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for candidate first solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; EPETRA_TEST_ERR(checkValues(lambda,lambdaref," No-transpose Power Method result", verbose),ierr); EPETRA_TEST_ERR(checkValues(total_flops,flopsref," No-transpose Power Method flop count", verbose),ierr); ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate lambda = 0.0; startTime = timer.ElapsedTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime() - startTime; total_flops = q.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; lambdaref = lambda; flopsref = total_flops; if (verbose) cout << "\n\nTotal MFLOPs for reference transpose solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; lambda = 0.0; startTime = timer.ElapsedTime(); EPETRA_TEST_ERR(power_method(true, JadA, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime() - startTime; total_flops = q.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for candidate transpose solve = " << MFLOPs << endl << "Total FLOPS = " <<total_flops <<endl<<endl; EPETRA_TEST_ERR(checkValues(lambda,lambdaref,"Transpose Power Method result", verbose),ierr); EPETRA_TEST_ERR(checkValues(total_flops,flopsref,"Transpose Power Method flop count", verbose),ierr); EPETRA_TEST_ERR(check(A, JadA, verbose),ierr); return(0); }
int Drumm1(const Epetra_Map& map, bool verbose) { (void)verbose; //Simple 2-element problem (element as in "finite-element") from //Clif Drumm. Two triangular elements, one per processor, as shown //here: // // *----* // 3|\ 2| // | \ | // | 0\1| // | \| // *----* // 0 1 // //Element 0 on processor 0, element 1 on processor 1. //Processor 0 will own nodes 0,1 and processor 1 will own nodes 2,3. //Each processor will pass a 3x3 element-matrix to Epetra_FECrsMatrix. //After GlobalAssemble(), the matrix should be as follows: // // row 0: 2 1 0 1 //proc 0 row 1: 1 4 1 2 //---------------------------------- // row 2: 0 1 2 1 //proc 1 row 3: 1 2 1 4 // int numProcs = map.Comm().NumProc(); int localProc = map.Comm().MyPID(); if (numProcs != 2) return(0); //so first we'll set up a epetra_test::matrix_data object with //contents that match the above-described matrix. (but the //matrix_data object will have all 4 rows on each processor) int i; int rowlengths[4]; rowlengths[0] = 3; rowlengths[1] = 4; rowlengths[2] = 3; rowlengths[3] = 4; epetra_test::matrix_data matdata(4, rowlengths); for(i=0; i<4; ++i) { for(int j=0; j<matdata.rowlengths()[i]; ++j) { matdata.colindices()[i][j] = j; } } matdata.colindices()[0][2] = 3; matdata.colindices()[2][0] = 1; matdata.colindices()[2][1] = 2; matdata.colindices()[2][2] = 3; double** coefs = matdata.coefs(); coefs[0][0] = 2.0; coefs[0][1] = 1.0; coefs[0][2] = 1.0; coefs[1][0] = 1.0; coefs[1][1] = 4.0; coefs[1][2] = 1.0; coefs[1][3] = 2.0; coefs[2][0] = 1.0; coefs[2][1] = 2.0; coefs[2][2] = 1.0; coefs[3][0] = 1.0; coefs[3][1] = 2.0; coefs[3][2] = 1.0; coefs[3][3] = 4.0; //now we'll load a Epetra_FECrsMatrix with data that matches the //above-described finite-element problem. int indexBase = 0, ierr = 0; int myNodes[4]; double values[9]; values[0] = 2.0; values[1] = 1.0; values[2] = 1.0; values[3] = 1.0; values[4] = 2.0; values[5] = 1.0; values[6] = 1.0; values[7] = 1.0; values[8] = 2.0; int numMyNodes = 2; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; } else { myNodes[0] = 2; myNodes[1] = 3; } Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm()); numMyNodes = 3; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; myNodes[2] = 3; } else { myNodes[0] = 1; myNodes[1] = 2; myNodes[2] = 3; } int rowLengths = 3; Epetra_FECrsMatrix A(Copy, Map, rowLengths); EPETRA_TEST_ERR( A.InsertGlobalValues(numMyNodes, myNodes, numMyNodes, myNodes, values, Epetra_FECrsMatrix::ROW_MAJOR),ierr); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); //now the test is to check whether the FECrsMatrix data matches the //epetra_test::matrix_data object... bool the_same = matdata.compare_local_data(A); if (!the_same) { return(-1); } return(0); }
//========================================================================= // test matrix operator= (copy & view) int matrixAssignment(bool verbose, bool debug) { int ierr = 0; int returnierr = 0; if(verbose) printHeading("Testing matrix operator="); // each section is in its own block so we can reuse variable names // lhs = left hand side, rhs = right hand side { // copy->copy (more space needed) // orig and dup should have same signature // modifying orig or dup should have no effect on the other if(verbose) cout << "Checking copy->copy (new alloc)" << endl; Epetra_SerialDenseMatrix lhs(2,2); double* rand1 = getRandArray(25); Epetra_SerialDenseMatrix rhs(Copy, rand1, 5, 5, 5); if(debug) { cout << "before assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } lhs = rhs; if(debug) { cout << "after assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } EPETRA_TEST_ERR(!identicalSignatures(rhs,lhs), ierr); EPETRA_TEST_ERR(!seperateData(rhs,lhs), ierr); delete[] rand1; } returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; { // copy->copy (have enough space) // orig and dup should have same signature // modifying orig or dup should have no effect on the other if(verbose) cout << "\nChecking copy->copy (no alloc)" << endl; double* rand1 = getRandArray(25); double* rand2 = getRandArray(20); Epetra_SerialDenseMatrix lhs(Copy, rand1, 5, 5, 5); Epetra_SerialDenseMatrix rhs(Copy, rand2, 4, 4, 5); double* origA = lhs.A(); int origLDA = lhs.LDA(); if(debug) { cout << "before assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } lhs = rhs; if(debug) { cout << "after assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } // in this case, instead of doing a "normal" LDA test in identSig, // we do our own. Since we had enough space already, A and LDA should // not have been changed by the assignment. (The extra parameter to // identicalSignatures tells it not to test LDA). EPETRA_TEST_ERR((lhs.A() != origA) || (lhs.LDA() != origLDA), ierr); EPETRA_TEST_ERR(!identicalSignatures(rhs,lhs,false), ierr); EPETRA_TEST_ERR(!seperateData(rhs,lhs), ierr); } returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; { // view->copy // orig and dup should have same signature // modifying orig or dup should have no effect on the other if(verbose) cout << "\nChecking view->copy" << endl; double* rand1 = getRandArray(25); double* rand2 = getRandArray(64); Epetra_SerialDenseMatrix lhs(View, rand1, 5, 5, 5); Epetra_SerialDenseMatrix rhs(Copy, rand2, 8, 8, 8); if(debug) { cout << "before assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } lhs = rhs; if(debug) { cout << "after assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } EPETRA_TEST_ERR(!identicalSignatures(rhs,lhs), ierr); EPETRA_TEST_ERR(!seperateData(rhs,lhs), ierr); delete[] rand1; delete[] rand2; } returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; { // copy->view // orig and dup should have same signature // modifying orig or dup should change the other if(verbose) cout << "\nChecking copy->view" << endl; double* rand1 = getRandArray(10); Epetra_SerialDenseMatrix lhs(4,4); Epetra_SerialDenseMatrix rhs(View, rand1, 2, 2, 5); if(debug) { cout << "before assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } lhs = rhs; if(debug) { cout << "after assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } EPETRA_TEST_ERR(!identicalSignatures(rhs,lhs), ierr); EPETRA_TEST_ERR(seperateData(rhs,lhs), ierr); delete[] rand1; } returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; { // view->view // orig and dup should have same signature // modifying orig or dup should change the other if(verbose) cout << "\nChecking view->view" << endl; double* rand1 = getRandArray(9); double* rand2 = getRandArray(18); Epetra_SerialDenseMatrix lhs(View, rand1, 3, 3, 3); Epetra_SerialDenseMatrix rhs(View, rand2, 3, 3, 6); if(debug) { cout << "before assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } lhs = rhs; if(debug) { cout << "after assignment:" << endl; printMat("rhs",rhs); printMat("lhs",lhs); } EPETRA_TEST_ERR(!identicalSignatures(rhs,lhs), ierr); EPETRA_TEST_ERR(seperateData(rhs,lhs), ierr); delete[] rand1; delete[] rand2; } returnierr += ierr; if(ierr == 0) if(verbose) cout << "Checked OK." << endl; ierr = 0; return(returnierr); }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; //bool verbose1 = verbose; // unused // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 1; long long NumGlobalEquations = NumProc; // Get update list and number of local equations from newly created Map long long* MyGlobalElementsLL = new long long[NumMyEquations]; MyGlobalElementsLL[0] = 2000000000+MyPID; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map MapLL(NumGlobalEquations, NumMyEquations, MyGlobalElementsLL, 0, Comm); EPETRA_TEST_ERR(MapLL.GlobalIndicesInt(),ierr); EPETRA_TEST_ERR(!(MapLL.GlobalIndicesLongLong()),ierr); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNzLL = new int[NumMyEquations]; NumNzLL[0] = 0; // Create int types meant to add to long long matrix for test of failure int* MyIntGlobalElementsLL = new int[NumMyEquations]; MyIntGlobalElementsLL[0] = 20000+MyPID; // Create a long long Epetra_Matrix Epetra_CrsMatrix A_LL(Copy, MapLL, NumNzLL); EPETRA_TEST_ERR(A_LL.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A_LL.IndicesAreLocal(),ierr); // Insert values double one = 1.0; #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // Try to add ints which should fail and be caught as an int try { A_LL.InsertGlobalValues(MyIntGlobalElementsLL[0], 1, &one, MyIntGlobalElementsLL+0); } catch(int i) { EPETRA_TEST_ERR(!(i==-1),ierr); } #endif // Add long longs which should succeed EPETRA_TEST_ERR(!(A_LL.InsertGlobalValues(MyGlobalElementsLL[0], 1, &one, MyGlobalElementsLL+0)==0),ierr); EPETRA_TEST_ERR(!(A_LL.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A_LL.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A_LL.IndicesAreLocal()),ierr); // Get update list and number of local equations from newly created Map int* MyGlobalElementsInt = new int[NumMyEquations]; MyGlobalElementsInt[0] = 2000+MyPID; // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNzInt = new int[NumMyEquations]; NumNzInt[0] = 0; // Create int types meant to add to long long matrix for test of failure long long* MyLLGlobalElementsInt = new long long[NumMyEquations]; MyLLGlobalElementsInt[0] = 2000000000+MyPID; #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map MapInt(NumGlobalEquations, NumMyEquations, MyGlobalElementsInt, 0LL, Comm); EPETRA_TEST_ERR(!(MapInt.GlobalIndicesInt()),ierr); EPETRA_TEST_ERR(MapInt.GlobalIndicesLongLong(),ierr); // Create a int Epetra_Matrix Epetra_CrsMatrix A_Int(Copy, MapInt, NumNzInt); EPETRA_TEST_ERR(A_Int.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A_Int.IndicesAreLocal(),ierr); // Insert values try { A_Int.InsertGlobalValues(MyLLGlobalElementsInt[0], 1, &one, MyLLGlobalElementsInt+0); } catch(int i) { EPETRA_TEST_ERR(!(i==-1),ierr); } // Add long longs which should succeed EPETRA_TEST_ERR(!(A_Int.InsertGlobalValues(MyGlobalElementsInt[0], 1, &one, MyGlobalElementsInt+0)==0),ierr); EPETRA_TEST_ERR(!(A_Int.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A_Int.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A_Int.IndicesAreLocal()),ierr); #endif delete [] MyGlobalElementsLL; delete [] NumNzLL; delete [] MyIntGlobalElementsLL; delete [] MyGlobalElementsInt; delete [] NumNzInt; delete [] MyLLGlobalElementsInt; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // Comm.SetTracebackMode(0); // This should shut down any error tracing bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; #ifdef EPETRA_MPI int localverbose = verbose ? 1 : 0; int globalverbose=0; MPI_Allreduce(&localverbose, &globalverbose, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); verbose = (globalverbose>0); #endif int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm <<endl; int NumMyElements = 4; long long NumGlobalElements = NumMyElements*NumProc; int IndexBase = 0; Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR( Drumm1(Map, verbose),ierr); EPETRA_TEST_ERR( Drumm2(Map, verbose),ierr); bool preconstruct_graph = false; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); preconstruct_graph = true; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); EPETRA_TEST_ERR( rectangular(Comm, verbose), ierr); EPETRA_TEST_ERR( Young1(Comm, verbose), ierr); #ifdef EPETRA_MPI MPI_Finalize(); #endif 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); }