//========================================================================= // checks the signatures of two matrices bool identicalSignatures(Epetra_SerialDenseMatrix& a, Epetra_SerialDenseMatrix& b, bool testLDA) { if((a.M() != b.M() )|| // check properties first (a.N() != b.N() )|| (a.CV() != b.CV() )) return(false); if(testLDA == true) // if we are coming from op= c->c #2 (have enough space) if(a.LDA() != b.LDA()) // then we don't check LDA (but we do check it in the test function) return(false); if(a.CV() == View) { // if we're still here, we need to check the data if(a.A() != b.A()) // for a view, this just means checking the pointers return(false); // for a copy, this means checking each element } else { // CV == Copy const int m = a.M(); const int n = a.N(); for(int i = 0; i < m; i++) for(int j = 0; j < n; j++) { if(a(i,j) != b(i,j)) return(false); } } return(true); // if we're still here, signatures are identical }
void ISVDUDV::shrink(const int down, std::vector<double> &S, Epetra_SerialDenseMatrix &U, Epetra_SerialDenseMatrix &V) { // // put RU1 into an Epetra MultiVector Epetra_LocalMap LocalMap(curRank_, 0, U_->Map().Comm()); Epetra_MultiVector Uh1(Epetra_DataAccess::View, LocalMap, U.A(), U.LDA(), curRank_-down); Epetra_MultiVector Vh1(Epetra_DataAccess::View, LocalMap, V.A(), V.LDA(), curRank_-down); // // update bases Teuchos::RCP<Epetra_MultiVector> newwU, fullU, newU, newwV, fullV, newV; fullU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*U_,0,curRank_) ); newwU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*workU_,0,curRank_-down) ); // multiply by Uh1 int info = newwU->Multiply('N','N',1.0,*fullU,Uh1,0.0); TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,"ISVDUDV::shrink(): Error calling EMV::Multiply(U)."); fullU = Teuchos::null; newU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*U_,0,curRank_-down) ); *newU = *newwU; newU = Teuchos::null; newwU = Teuchos::null; // multiply by Vh1 // get multivector views of V(1:numProc,1:curRank) and workV(1:numProc,1:curRank-down) double *V_A, *workV_A; int V_LDA, workV_LDA; info = V_->ExtractView(&V_A,&V_LDA); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "RBGen::ISVDUDV::shrink(): Error calling Epetra_MultiVector::ExtractView() on V_."); info = workV_->ExtractView(&workV_A,&workV_LDA); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "RBGen::ISVDUDV::shrink(): Error calling Epetra_MultiVector::ExtractView() on workV_."); Epetra_LocalMap lclmap(numProc_,0,A_->Comm()); fullV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap, V_A, V_LDA,curRank_ ) ); newwV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap,workV_A,workV_LDA,curRank_-down) ); // multiply workV = fullV * Vh1 info = newwV->Multiply('N','N',1.0,*fullV,Vh1,0.0); TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,"ISVDUDV::shrink(): Error calling EMV::Multiply(V)."); fullV = Teuchos::null; // now set newV = workV newV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap, V_A, V_LDA, curRank_-down) ); *newV = *newwV; newV = Teuchos::null; newwV = Teuchos::null; // save new singular values for (int i=0; i<curRank_-down; i++) { sigma_[i] = S[i]; } curRank_ = curRank_-down; }
//============================================================================= int Epetra_SerialDenseSVD::SetVectors(Epetra_SerialDenseMatrix & X_in, Epetra_SerialDenseMatrix & B_in) { if (B_in.M()!=X_in.M() || B_in.N() != X_in.N()) EPETRA_CHK_ERR(-1); if (B_in.A()==0) EPETRA_CHK_ERR(-2); if (B_in.LDA()<1) EPETRA_CHK_ERR(-3); if (X_in.A()==0) EPETRA_CHK_ERR(-4); if (X_in.LDA()<1) EPETRA_CHK_ERR(-5); ResetVectors(); LHS_ = &X_in; RHS_ = &B_in; NRHS_ = B_in.N(); B_ = B_in.A(); LDB_ = B_in.LDA(); X_ = X_in.A(); LDX_ = X_in.LDA(); return(0); }
int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_LongLongSerialDenseVector& indices, const Epetra_SerialDenseMatrix& values, int format) { if (indices.Length() != values.M() || indices.Length() != values.N()) { return(-1); } return( ReplaceGlobalValues(indices.Length(), indices.Values(), values.A(), format) ); }
int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_IntSerialDenseVector& rows, const Epetra_IntSerialDenseVector& cols, const Epetra_SerialDenseMatrix& values, int format) { if (rows.Length() != values.M() || cols.Length() != values.N()) { return(-1); } return( ReplaceGlobalValues(rows.Length(), rows.Values(), cols.Length(), cols.Values(), values.A(), format) ); }
//============================================================================= int Epetra_SerialDenseSVD::SetMatrix(Epetra_SerialDenseMatrix & A_in) { ResetMatrix(); Matrix_ = &A_in; // Factor_ = &A_in; M_ = A_in.M(); N_ = A_in.N(); Min_MN_ = EPETRA_MIN(M_,N_); LDA_ = A_in.LDA(); // LDAF_ = LDA_; A_ = A_in.A(); // AF_ = A_in.A(); return(0); }
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 main(int argc, char *argv[]) { int ierr = 0, i, j, k; #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) std::cout << Epetra_Version() << std::endl << std::endl; int rank = Comm.MyPID(); // char tmp; // if (rank==0) std::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 if (verbose) std::cout << Comm << std::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 Upper = false; Epetra_SerialSpdDenseSolver solver; Epetra_SerialSymDenseMatrix * 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_SerialSymDenseMatrix(View, A, LDA, i); LDA1 = LDA; } else { Matrix = new Epetra_SerialSymDenseMatrix(Copy, A, LDA, i); LDA1 = i; } GenerateHilbert(A1, LDA1, i); if (kk==1) { solver.FactorWithEquilibration(true); Matrix->SetUpper(); Upper = true; solver.SolveToRefinedSolution(false); } 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, Upper, verbose); assert (ierr>-1); delete Matrix; if (ierr!=0) { if (verbose) std::cout << "Factorization failed due to bad conditioning. This is normal if SCOND is small." << std::endl; break; } } } delete [] A; delete [] A1; delete [] X; delete [] X1; delete [] B; delete [] B1; ///////////////////////////////////////////////////////////////////// // Now test norms and scaling functions ///////////////////////////////////////////////////////////////////// Epetra_SerialSymDenseMatrix D; double ScalarA = 2.0; int DM = 10; int DN = 10; D.Shape(DM); for (j=0; j<DN; j++) for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ; //std::cout << D << std::endl; double NormInfD_ref = (double)(DM*(DN*(DN+1))/2); double NormOneD_ref = NormInfD_ref; double NormInfD = D.NormInf(); double NormOneD = D.NormOne(); if (verbose) { std::cout << " *** Before scaling *** " << std::endl << " Computed one-norm of test matrix = " << NormOneD << std::endl << " Expected one-norm = " << NormOneD_ref << std::endl << " Computed inf-norm of test matrix = " << NormInfD << std::endl << " Expected inf-norm = " << NormInfD_ref << std::endl; } D.Scale(ScalarA); // Scale entire D matrix by this value //std::cout << D << std::endl; NormInfD = D.NormInf(); NormOneD = D.NormOne(); if (verbose) { std::cout << " *** After scaling *** " << std::endl << " Computed one-norm of test matrix = " << NormOneD << std::endl << " Expected one-norm = " << NormOneD_ref*ScalarA << std::endl << " Computed inf-norm of test matrix = " << NormInfD << std::endl << " Expected inf-norm = " << NormInfD_ref*ScalarA << std::endl; } ///////////////////////////////////////////////////////////////////// // Now test for larger system, both correctness and performance. ///////////////////////////////////////////////////////////////////// N = 2000; NRHS = 5; LDA = N; LDB = N; LDX = N; if (verbose) std::cout << "\n\nComputing factor of an " << N << " x " << N << " SPD matrix...Please wait.\n\n" << std::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) A[i+j*LDA] = 100.0 + i; else A[i+j*LDA] = -1.0/((double) (i+10)*(j+10)); } } // Define Epetra_SerialDenseMatrix object Epetra_SerialSymDenseMatrix BigMatrix(Copy, A, LDA, N); Epetra_SerialSymDenseMatrix OrigBigMatrix(View, A, LDA, N); Epetra_SerialSpdDenseSolver 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) std::cout << "Error in factorization = "<<ierr<< std::endl; assert(ierr==0); double time = Timer.ElapsedTime() - tstart; double FLOPS = counter.Flops(); double MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS for Factorization = " << MFLOPS << std::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('L', 1.0, OrigBigMatrix, LHS, 0.0); // Symmetric Matrix-multiply time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseMatrix OrigRHS = RHS; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << std::endl; // Set LHS and RHS and solve BigSolver.SetVectors(LHS, RHS); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); if (ierr==1 && verbose) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl; else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl; assert(ierr>=0); time = Timer.ElapsedTime() - tstart; FLOPS = BigSolver.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << std::endl; double * resid = new double[NRHS]; bool OK = Residual(N, NRHS, A, LDA, BigSolver.X(), BigSolver.LDX(), OrigRHS.A(), OrigRHS.LDA(), resid); if (verbose) { if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl; for (i=0; i<NRHS; i++) std::cout << "Residual[" << i <<"] = "<< resid[i] << std::endl; std::cout << std::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) std::cout << "MFLOPS to build single RHS = " << MFLOPS << std::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) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl; else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl; assert(ierr>=0); FLOPS = counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS to solve single RHS = " << MFLOPS << std::endl; OK = Residual(N, 1, A, LDA, BigSolver.X(), BigSolver.LDX(), OrigB2.A(), OrigB2.LDA(), resid); if (verbose) { if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl; std::cout << "Residual = "<< resid[0] << std::endl; } delete [] resid; delete [] A; delete [] X; /////////////////////////////////////////////////// // Now test default constructor and index operators /////////////////////////////////////////////////// N = 5; Epetra_SerialSymDenseMatrix C; // Implicit call to default constructor, should not need to call destructor C.Shape(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) std::cout << "Default constructor and index operator check OK. Values of Hilbert matrix = " << std::endl << C << std::endl << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << std::endl; delete [] C1; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int NSIDE = 1; int NPIX ; int NSTOKES = 3; NPIX = 12. * NSIDE * NSIDE +1; //total pixel size, each pixel is an element which contains 3 floats which are IQU Epetra_BlockMap PixMap(NPIX,NSTOKES,0,Comm); int * PixMyGlobalElements = PixMap.MyGlobalElements(); cout << PixMap << endl; Epetra_FEVbrMatrix invM(Copy, PixMap, 1); int BlockIndices[1]; BlockIndices[0] = 2; int RowDim, NumBlockEntries; int err; Epetra_SerialDenseMatrix Mpp(NSTOKES, NSTOKES); Mpp[0][0] = 1.; cout << Mpp << endl; Epetra_SerialDenseMatrix * Zero; for( int i=0 ; i<PixMap.NumMyElements(); ++i ) { //loop on local pixel BlockIndices[0] = PixMyGlobalElements[i]; Zero = new Epetra_SerialDenseMatrix(NSTOKES, NSTOKES); invM.BeginInsertGlobalValues(BlockIndices[0], 1, BlockIndices); err = invM.SubmitBlockEntry(Zero->A(), Zero->LDA(), NSTOKES, NSTOKES); if (err != 0) { cout << "PID:" << Comm.MyPID() << "Error in inserting init zero values in M, error code:" << err << endl; } err = invM.EndSubmitEntries(); } BlockIndices[0] = 2; cout << invM << endl; int NumHits = 2*Comm.MyPID() + 5; for( int i=0 ; i<NumHits; ++i ) { //loop on local pointing invM.BeginSumIntoGlobalValues(BlockIndices[0], 1, BlockIndices); err = invM.SubmitBlockEntry(Mpp.A(), Mpp.LDA(), NSTOKES, NSTOKES); //FIXME check order if (err != 0) { cout << "PID:" << Comm.MyPID() << "Error in inserting values in M, error code:" << err << endl; } err = invM.EndSubmitEntries(); if (err != 0) { cout << "PID:" << Comm.MyPID() << " LocalRow[i]:" << i << " Error in ending submit entries in M, error code:" << err << endl; } } invM.GlobalAssemble(); cout << invM << endl; if (Comm.MyPID() == 0) { Epetra_SerialDenseMatrix * blockM; int * BlockIndicesBlock; invM.BeginExtractMyBlockRowView(2, RowDim, NumBlockEntries, BlockIndicesBlock); invM.ExtractEntryView(blockM); cout << *blockM << endl; cout << "*blockM[0][0]" << endl; cout << *blockM[0][0] << endl; cout << "*blockM[0][4]" << endl; cout << *blockM[0][4] << endl; cout << "*blockM[1][1]" << endl; cout << *blockM[1][1] << endl; } #ifdef HAVE_MPI MPI_Finalize(); #endif return(0); };