Teuchos::RCP<Map> Cartesian2D(const Teuchos::RCP<const Teuchos::Comm<int> > & comm, const GlobalOrdinal nx, const GlobalOrdinal ny, const GlobalOrdinal mx, const GlobalOrdinal my) { if (nx <= 0 || ny <= 0 || mx <= 0 || my <= 0 || (mx > nx) || (my > ny)) throw(Exception(__FILE__, __LINE__, "Incorrect input parameter to Maps::Cartesian2D()", "nx = " + toString(nx) + ", ny = " + toString(ny) + ", mx = " + toString(mx) + ", my = " + toString(my))); int MyPID = comm->getRank(); GlobalOrdinal startx, starty, endx, endy; GlobalOrdinal xpid = MyPID % mx; GlobalOrdinal ypid = MyPID / mx; GlobalOrdinal PerProcSmallXDir = Teuchos::as<GlobalOrdinal>(Teuchos::as<double>(nx)/Teuchos::as<double>(mx)); GlobalOrdinal PerProcSmallYDir = Teuchos::as<GlobalOrdinal>(Teuchos::as<double>(ny)/Teuchos::as<double>(my)); GlobalOrdinal NBigXDir = nx - PerProcSmallXDir*mx; GlobalOrdinal NBigYDir = ny - PerProcSmallYDir*my; if (xpid < NBigXDir) startx = xpid*(PerProcSmallXDir+1); else startx = (xpid-NBigXDir)*PerProcSmallXDir + NBigXDir*(PerProcSmallXDir+1); endx = startx + PerProcSmallXDir; if (xpid < NBigXDir) endx++; if (ypid < NBigYDir) starty = ypid*(PerProcSmallYDir+1); else starty = (ypid-NBigYDir)*PerProcSmallYDir + NBigYDir*(PerProcSmallYDir+1); endy = starty + PerProcSmallYDir; if ( ypid < NBigYDir) endy++; size_t NumMyElements = (endx - startx) * (endy - starty); vector<GlobalOrdinal> MyGlobalElements(NumMyElements); size_t count = 0; for (GlobalOrdinal i = startx ; i < endx ; ++i) for (GlobalOrdinal j = starty ; j < endy ; ++j) MyGlobalElements[count++] = i + j * nx; global_size_t numGlobalElements = nx * ny; const Teuchos::ArrayView<const GlobalOrdinal> elementList(MyGlobalElements); return MapTraits<GlobalOrdinal,Map>::Build(numGlobalElements, elementList, 0/*indexBase*/, comm /*TODO:node*/); } // Cartesian2D()
// ====================================================================== Operator GetPtent1D(const MultiVector& D, const int offset = 0) { if (D.GetNumVectors() != 1) ML_THROW("D.GetNumVectors() != 1", -1); int size = D.GetMyLength(); if (size == 0) ML_THROW("empty diagonal vector in input", -1); double* diag = new double[size]; for (int i = 0 ; i < size ; ++i) diag[i] = D(i); // creates the ML operator and store the diag pointer, // as well as the function pointers ML_Operator* MLDiag = ML_Operator_Create(GetML_Comm()); int invec_leng = size / 3 + size % 3; int outvec_leng = size; MLDiag->invec_leng = invec_leng; MLDiag->outvec_leng = outvec_leng; MLDiag->data = (void*)diag; MLDiag->data_destroy = Ptent1D_destroy; MLDiag->matvec->func_ptr = Ptent1D_matvec; MLDiag->matvec->ML_id = ML_NONEMPTY; MLDiag->matvec->Nrows = outvec_leng; MLDiag->from_an_ml_operator = 0; MLDiag->getrow->func_ptr = Ptent1D_getrows; MLDiag->getrow->ML_id = ML_NONEMPTY; MLDiag->getrow->Nrows = outvec_leng; // creates the domain space vector<int> MyGlobalElements(invec_leng); for (int i = 0 ; i < invec_leng ; ++i) MyGlobalElements[i] = D.GetVectorSpace()(i * 3) / 3; Space DomainSpace(invec_leng, -1, &MyGlobalElements[0]); Space RangeSpace = D.GetVectorSpace(); // creates the MLAPI wrapper Operator Diag(DomainSpace,RangeSpace,MLDiag,true); return(Diag); }
//============================================================================= Epetra_Map* Epetra_Map::ReplaceCommWithSubset(const Epetra_Comm * theComm) const { // mfh 26 Mar 2013: The lazy way to do this is simply to recreate // the Map by calling its ordinary public constructor, using the // original Map's data. This only involves O(1) all-reduces over // the new communicator, which in the common case only includes a // small number of processes. Epetra_Map * NewMap=0; // Create the Map to return (unless theComm is NULL, in which case // we return zero). if(theComm) { // Map requires that the index base equal the global min GID. // Figuring out the global min GID requires a reduction over all // processes in the new communicator. It could be that some (or // even all) of these processes contain zero entries. (Recall // that this method, unlike removeEmptyProcesses(), may remove // an arbitrary subset of processes.) We deal with this by // doing a min over the min GID on each process if the process // has more than zero entries, or the global max GID, if that // process has zero entries. If no processes have any entries, // then the index base doesn't matter anyway. #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(GlobalIndicesInt()) { int MyMin, theIndexBase; MyMin = NumMyElements() > 0 ? MinMyGID() : MaxAllGID(); theComm->MinAll(&MyMin,&theIndexBase,1); NewMap = new Epetra_Map(-1,NumMyElements(),MyGlobalElements(),theIndexBase,*theComm); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(GlobalIndicesLongLong()) { long long MyMin, theIndexBase; MyMin = NumMyElements() > 0 ? MinMyGID64() : MaxAllGID64(); theComm->MinAll(&MyMin,&theIndexBase,1); NewMap = new Epetra_Map(-1,NumMyElements(),MyGlobalElements64(),theIndexBase,*theComm); } else #endif throw ReportError("Epetra_Map::ReplaceCommWithSubset ERROR, GlobalIndices type unknown.",-1); } return NewMap; }
int main(int argc, char *argv[]) { int i; bool ierr, gerr; gerr = true; #ifdef HAVE_MPI // Initialize MPI and setup an Epetra communicator MPI_Init(&argc,&argv); Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) ); #else // If we aren't using MPI, then setup a serial communicator. Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() ); #endif // number of global elements int dim = 100; int blockSize = 5; bool verbose = false; if (argc>1) { if (argv[1][0]=='-' && argv[1][1]=='v') { verbose = true; } } // Construct a Map that puts approximately the same number of // equations on each processor. Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) ); // Get update list and number of local equations from newly created Map. int NumMyElements = Map->NumMyElements(); std::vector<int> MyGlobalElements(NumMyElements); Map->MyGlobalElements(&MyGlobalElements[0]); // Create an integer std::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 std::vector<int> NumNz(NumMyElements); // 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<NumMyElements; i++) { if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) { NumNz[i] = 2; } else { NumNz[i] = 3; } } // Create an Epetra_Matrix Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) ); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 std::vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; std::vector<int> Indices(2); double two = 2.0; int NumEntries; for (i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == dim-1) { Indices[0] = dim-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]); assert(ierr==0); // Put in the diagonal entry ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]); assert(ierr==0); } // Finish building the epetra matrix A ierr = A->FillComplete(); assert(ierr==0); // Issue several useful typedefs; typedef Belos::MultiVec<double> EMV; typedef Belos::Operator<double> EOP; // Create an Epetra_MultiVector for an initial std::vector to start the solver. // Note that this needs to have the same number of columns as the blocksize. Teuchos::RCP<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) ); ivec->Random(); // Create an output manager to handle the I/O from the solver Teuchos::RCP<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>() ); if (verbose) { MyOM->setVerbosity( Belos::Warnings ); } // test the Epetra adapter multivector ierr = Belos::TestMultiVecTraits<double,EMV>(MyOM,ivec); gerr &= ierr; if (ierr) { MyOM->print(Belos::Warnings,"*** EpetraAdapter PASSED TestMultiVecTraits()\n"); } else { MyOM->print(Belos::Warnings,"*** EpetraAdapter FAILED TestMultiVecTraits() ***\n\n"); } #ifdef HAVE_MPI MPI_Finalize(); #endif if (gerr == false) { MyOM->print(Belos::Warnings,"End Result: TEST FAILED\n"); return -1; } // // Default return value // MyOM->print(Belos::Warnings,"End Result: TEST PASSED\n"); return 0; }
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 main(int argc, char *argv[]) { int ierr = 0, i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); bool verbose = (MyPID==0); if (verbose) cout << Epetra_Version() << endl << endl; cout << Comm << endl; // Get the number of local equations from the command line if (argc!=2) { if (verbose) cout << "Usage: " << argv[0] << " number_of_equations" << endl; std::exit(1); } long long NumGlobalElements = std::atoi(argv[1]); if (NumGlobalElements < NumProc) { if (verbose) cout << "numGlobalBlocks = " << NumGlobalElements << " cannot be < number of processors = " << NumProc << endl; std::exit(1); } // Construct a Map that puts approximately the same number of // equations on each processor. Epetra_Map Map(NumGlobalElements, 0LL, Comm); // Get update list and number of local equations from newly created Map. int NumMyElements = Map.NumMyElements(); std::vector<long long> MyGlobalElements(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 std::vector<int> NumNz(NumMyElements); // 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<NumMyElements; i++) if (MyGlobalElements[i]==0 || MyGlobalElements[i] == NumGlobalElements-1) NumNz[i] = 2; else NumNz[i] = 3; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 std::vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; std::vector<long long> Indices(2); double two = 2.0; int NumEntries; for (i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalElements-1) { Indices[0] = NumGlobalElements-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } ierr = A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert(ierr==0); // Put in the diagonal entry ierr = A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i]); assert(ierr==0); } // Finish up ierr = A.FillComplete(); assert(ierr==0); // Create vectors for Power method // variable needed for iteration double lambda = 0.0; int niters = (int) NumGlobalElements*10; double tolerance = 1.0e-2; // Iterate Epetra_Flops counter; A.SetFlopCounter(counter); Epetra_Time timer(Comm); ierr += power_method(A, lambda, niters, tolerance, verbose); double elapsed_time = timer.ElapsedTime(); double total_flops =counter.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << endl<< endl; // Increase diagonal dominance if (verbose) cout << "\nIncreasing magnitude of first diagonal term, solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); std::vector<double> Rowvals(numvals); std::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]); } // Iterate (again) lambda = 0.0; timer.ResetStartTime(); counter.ResetFlops(); ierr += power_method(A, lambda, niters, tolerance, verbose); elapsed_time = timer.ElapsedTime(); total_flops = counter.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl; // Release all objects #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
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 Amesos_Scalapack::RedistributeA( ) { if( debug_ == 1 ) std::cout << "Entering `RedistributeA()'" << std::endl; Time_->ResetStartTime(); Epetra_RowMatrix *RowMatrixA = dynamic_cast<Epetra_RowMatrix *>(Problem_->GetOperator()); EPETRA_CHK_ERR( RowMatrixA == 0 ) ; const Epetra_Map &OriginalMap = RowMatrixA->RowMatrixRowMap() ; int NumberOfProcesses = Comm().NumProc() ; // // Compute a uniform distribution as ScaLAPACK would want it // MyFirstElement - The first element which this processor would have // NumExpectedElemetns - The number of elements which this processor would have // int NumRows_ = RowMatrixA->NumGlobalRows() ; int NumColumns_ = RowMatrixA->NumGlobalCols() ; if ( MaxProcesses_ > 0 ) { NumberOfProcesses = EPETRA_MIN( NumberOfProcesses, MaxProcesses_ ) ; } else { int ProcessNumHeuristic = (1+NumRows_/200)*(1+NumRows_/200); NumberOfProcesses = EPETRA_MIN( NumberOfProcesses, ProcessNumHeuristic ); } if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:171" << std::endl; // // Create the ScaLAPACK data distribution. // The TwoD data distribution is created in a completely different // manner and is not transposed (whereas the SaLAPACK 1D data // distribution was transposed) // if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:163" << std::endl; Comm().Barrier(); if ( TwoD_distribution_ ) { if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:166" << std::endl; Comm().Barrier(); npcol_ = EPETRA_MIN( NumberOfProcesses, EPETRA_MAX ( 2, (int) sqrt( NumberOfProcesses * 0.5 ) ) ) ; nprow_ = NumberOfProcesses / npcol_ ; // // Create the map for FatA - our first intermediate matrix // int NumMyElements = RowMatrixA->RowMatrixRowMap().NumMyElements() ; std::vector<int> MyGlobalElements( NumMyElements ); RowMatrixA->RowMatrixRowMap().MyGlobalElements( &MyGlobalElements[0] ) ; int NumMyColumns = RowMatrixA->RowMatrixColMap().NumMyElements() ; std::vector<int> MyGlobalColumns( NumMyColumns ); RowMatrixA->RowMatrixColMap().MyGlobalElements( &MyGlobalColumns[0] ) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:194" << std::endl; std::vector<int> MyFatElements( NumMyElements * npcol_ ); for( int LocalRow=0; LocalRow<NumMyElements; LocalRow++ ) { for (int i = 0 ; i < npcol_; i++ ){ MyFatElements[LocalRow*npcol_+i] = MyGlobalElements[LocalRow]*npcol_+i; } } Epetra_Map FatInMap( npcol_*NumRows_, NumMyElements*npcol_, &MyFatElements[0], 0, Comm() ); // // Create FatIn, our first intermediate matrix // Epetra_CrsMatrix FatIn( Copy, FatInMap, 0 ); std::vector<std::vector<int> > FatColumnIndices(npcol_,std::vector<int>(1)); std::vector<std::vector<double> > FatMatrixValues(npcol_,std::vector<double>(1)); std::vector<int> FatRowPtrs(npcol_); // A FatRowPtrs[i] = the number // of entries in local row LocalRow*npcol_ + i if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:219" << std::endl; // mypcol_ = iam_%npcol_; myprow_ = (iam_/npcol_)%nprow_; if ( iam_ >= nprow_ * npcol_ ) { myprow_ = nprow_; mypcol_ = npcol_; } // Each row is split into npcol_ rows, with each of the // new rows containing only those elements belonging to // its process column (in the ScaLAPACK 2D process grid) // int MaxNumIndices = RowMatrixA->MaxNumEntries(); int NumIndices; std::vector<int> ColumnIndices(MaxNumIndices); std::vector<double> MatrixValues(MaxNumIndices); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:232 NumMyElements = " << NumMyElements << std::endl; nb_ = grid_nb_; for( int LocalRow=0; LocalRow<NumMyElements; ++LocalRow ) { RowMatrixA->ExtractMyRowCopy( LocalRow, MaxNumIndices, NumIndices, &MatrixValues[0], &ColumnIndices[0] ); for (int i=0; i<npcol_; i++ ) FatRowPtrs[i] = 0 ; // // Deal the individual matrix entries out to the row owned by // the process to which this matrix entry will belong. // for( int i=0 ; i<NumIndices ; ++i ) { int GlobalCol = MyGlobalColumns[ ColumnIndices[i] ]; int pcol_i = pcolnum( GlobalCol, nb_, npcol_ ) ; if ( FatRowPtrs[ pcol_i ]+1 >= FatColumnIndices[ pcol_i ].size() ) { FatColumnIndices[ pcol_i ]. resize( 2 * FatRowPtrs[ pcol_i ]+1 ); FatMatrixValues[ pcol_i ]. resize( 2 * FatRowPtrs[ pcol_i ]+1 ); } FatColumnIndices[pcol_i][FatRowPtrs[pcol_i]] = GlobalCol ; FatMatrixValues[pcol_i][FatRowPtrs[pcol_i]] = MatrixValues[i]; FatRowPtrs[ pcol_i ]++; } // // Insert each of the npcol_ rows individually // for ( int pcol_i = 0 ; pcol_i < npcol_ ; pcol_i++ ) { FatIn.InsertGlobalValues( MyGlobalElements[LocalRow]*npcol_ + pcol_i, FatRowPtrs[ pcol_i ], &FatMatrixValues[ pcol_i ][0], &FatColumnIndices[ pcol_i ][0] ); } } FatIn.FillComplete( false ); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:260" << std::endl; if ( debug_ == 1) std::cout << "Amesos_Scalapack.cpp:265B" << " iam_ = " << iam_ << " nb_ = " << nb_ << " nprow_ = " << nprow_ << " npcol_ = " << npcol_ << std::endl; // // Compute the map for our second intermediate matrix, FatOut // // Compute directly int UniformRows = ( NumRows_ / ( nprow_ * nb_ ) ) * nb_ ; int AllExcessRows = NumRows_ - UniformRows * nprow_ ; int OurExcessRows = EPETRA_MIN( nb_, AllExcessRows - ( myprow_ * nb_ ) ) ; OurExcessRows = EPETRA_MAX( 0, OurExcessRows ); NumOurRows_ = UniformRows + OurExcessRows ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:277" << std::endl; int UniformColumns = ( NumColumns_ / ( npcol_ * nb_ ) ) * nb_ ; int AllExcessColumns = NumColumns_ - UniformColumns * npcol_ ; int OurExcessColumns = EPETRA_MIN( nb_, AllExcessColumns - ( mypcol_ * nb_ ) ) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:281" << std::endl; OurExcessColumns = EPETRA_MAX( 0, OurExcessColumns ); NumOurColumns_ = UniformColumns + OurExcessColumns ; if ( iam_ >= nprow_ * npcol_ ) { UniformRows = 0; NumOurRows_ = 0; NumOurColumns_ = 0; } Comm().Barrier(); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:295" << std::endl; #if 0 // Compute using ScaLAPACK's numroc routine, assert agreement int izero = 0; // All matrices start at process 0 int NumRocSays = numroc_( &NumRows_, &nb_, &myprow_, &izero, &nprow_ ); assert( NumOurRows_ == NumRocSays ); #endif // // Compute the rows which this process row owns in the ScaLAPACK 2D // process grid. // std::vector<int> AllOurRows(NumOurRows_); int RowIndex = 0 ; int BlockRow = 0 ; for ( ; BlockRow < UniformRows / nb_ ; BlockRow++ ) { for ( int RowOffset = 0; RowOffset < nb_ ; RowOffset++ ) { AllOurRows[RowIndex++] = BlockRow*nb_*nprow_ + myprow_*nb_ + RowOffset ; } } Comm().Barrier(); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:315" << std::endl; assert ( BlockRow == UniformRows / nb_ ) ; for ( int RowOffset = 0; RowOffset < OurExcessRows ; RowOffset++ ) { AllOurRows[RowIndex++] = BlockRow*nb_*nprow_ + myprow_*nb_ + RowOffset ; } assert( RowIndex == NumOurRows_ ); // // Distribute those rows amongst all the processes in that process row // This is an artificial distribution with the following properties: // 1) It is a 1D data distribution (each row belogs entirely to // a single process // 2) All data which will eventually belong to a given process row, // is entirely contained within the processes in that row. // Comm().Barrier(); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:312" << std::endl; // // Compute MyRows directly // std::vector<int>MyRows(NumOurRows_); RowIndex = 0 ; BlockRow = 0 ; for ( ; BlockRow < UniformRows / nb_ ; BlockRow++ ) { for ( int RowOffset = 0; RowOffset < nb_ ; RowOffset++ ) { MyRows[RowIndex++] = BlockRow*nb_*nprow_*npcol_ + myprow_*nb_*npcol_ + RowOffset*npcol_ + mypcol_ ; } } Comm().Barrier(); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:326" << std::endl; assert ( BlockRow == UniformRows / nb_ ) ; for ( int RowOffset = 0; RowOffset < OurExcessRows ; RowOffset++ ) { MyRows[RowIndex++] = BlockRow*nb_*nprow_*npcol_ + myprow_*nb_*npcol_ + RowOffset*npcol_ + mypcol_ ; } Comm().Barrier(); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:334" << std::endl; Comm().Barrier(); for (int i=0; i < NumOurRows_; i++ ) { assert( MyRows[i] == AllOurRows[i]*npcol_+mypcol_ ); } Comm().Barrier(); if ( debug_ == 1) std::cout << "Amesos_Scalapack.cpp:340" << " iam_ = " << iam_ << " myprow_ = " << myprow_ << " mypcol_ = " << mypcol_ << " NumRows_ = " << NumRows_ << " NumOurRows_ = " << NumOurRows_ << std::endl; Comm().Barrier(); Epetra_Map FatOutMap( npcol_*NumRows_, NumOurRows_, &MyRows[0], 0, Comm() ); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:344" << std::endl; Comm().Barrier(); if ( FatOut_ ) delete FatOut_ ; FatOut_ = new Epetra_CrsMatrix( Copy, FatOutMap, 0 ) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:348" << std::endl; Epetra_Export ExportToFatOut( FatInMap, FatOutMap ) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:360" << std::endl; FatOut_->Export( FatIn, ExportToFatOut, Add ); FatOut_->FillComplete( false ); // // Create a map to allow us to redistribute the vectors X and B // Epetra_RowMatrix *RowMatrixA = dynamic_cast<Epetra_RowMatrix *>(Problem_->GetOperator()); const Epetra_Map &OriginalMap = RowMatrixA->RowMatrixRowMap() ; assert( NumGlobalElements_ == OriginalMap.NumGlobalElements() ) ; int NumMyVecElements = 0 ; if ( mypcol_ == 0 ) { NumMyVecElements = NumOurRows_; } if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:385" << std::endl; if (VectorMap_) { delete VectorMap_ ; VectorMap_ = 0 ; } VectorMap_ = new Epetra_Map( NumGlobalElements_, NumMyVecElements, &AllOurRows[0], 0, Comm() ); if ( debug_ == 1) std::cout << "iam_ = " << iam_ << " Amesos_Scalapack.cpp:393 debug_ = " << debug_ << std::endl; } else { nprow_ = 1 ; npcol_ = NumberOfProcesses / nprow_ ; assert ( nprow_ * npcol_ == NumberOfProcesses ) ; m_per_p_ = ( NumRows_ + NumberOfProcesses - 1 ) / NumberOfProcesses ; int MyFirstElement = EPETRA_MIN( iam_ * m_per_p_, NumRows_ ) ; int MyFirstNonElement = EPETRA_MIN( (iam_+1) * m_per_p_, NumRows_ ) ; int NumExpectedElements = MyFirstNonElement - MyFirstElement ; assert( NumRows_ == RowMatrixA->NumGlobalRows() ) ; if ( ScaLAPACK1DMap_ ) delete( ScaLAPACK1DMap_ ) ; ScaLAPACK1DMap_ = new Epetra_Map( NumRows_, NumExpectedElements, 0, Comm() ); if ( ScaLAPACK1DMatrix_ ) delete( ScaLAPACK1DMatrix_ ) ; ScaLAPACK1DMatrix_ = new Epetra_CrsMatrix(Copy, *ScaLAPACK1DMap_, 0); Epetra_Export ExportToScaLAPACK1D_( OriginalMap, *ScaLAPACK1DMap_); ScaLAPACK1DMatrix_->Export( *RowMatrixA, ExportToScaLAPACK1D_, Add ); ScaLAPACK1DMatrix_->FillComplete( false ) ; } if ( debug_ == 1) std::cout << "iam_ = " << iam_ << " Amesos_Scalapack.cpp:417 debug_ = " << debug_ << std::endl; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:402" << " nprow_ = " << nprow_ << " npcol_ = " << npcol_ << std::endl ; int info; const int zero = 0 ; if ( ictxt_ == -1313 ) { ictxt_ = 0 ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:408" << std::endl; SL_INIT_F77(&ictxt_, &nprow_, &npcol_) ; } if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:410A" << std::endl; int nprow; int npcol; int myrow; int mycol; BLACS_GRIDINFO_F77(&ictxt_, &nprow, &npcol, &myrow, &mycol) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "iam_ = " << iam_ << " Amesos_Scalapack.cpp:410" << std::endl; if ( iam_ < nprow_ * npcol_ ) { assert( nprow == nprow_ ) ; if ( npcol != npcol_ ) std::cout << "Amesos_Scalapack.cpp:430 npcol = " << npcol << " npcol_ = " << npcol_ << std::endl ; assert( npcol == npcol_ ) ; if ( TwoD_distribution_ ) { assert( myrow == myprow_ ) ; assert( mycol == mypcol_ ) ; lda_ = EPETRA_MAX(1,NumOurRows_) ; } else { assert( myrow == 0 ) ; assert( mycol == iam_ ) ; nb_ = m_per_p_; lda_ = EPETRA_MAX(1,NumGlobalElements_); } if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp: " << __LINE__ << " TwoD_distribution_ = " << TwoD_distribution_ << " NumGlobalElements_ = " << NumGlobalElements_ << " debug_ = " << debug_ << " nb_ = " << nb_ << " lda_ = " << lda_ << " nprow_ = " << nprow_ << " npcol_ = " << npcol_ << " myprow_ = " << myprow_ << " mypcol_ = " << mypcol_ << " iam_ = " << iam_ << std::endl ; AMESOS_PRINT( myprow_ ); DESCINIT_F77(DescA_, &NumGlobalElements_, &NumGlobalElements_, &nb_, &nb_, &zero, &zero, &ictxt_, &lda_, &info) ; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:441" << std::endl; assert( info == 0 ) ; } else { DescA_[0] = -13; if ( debug_ == 1) std::cout << "iam_ = " << iam_ << "Amesos_Scalapack.cpp:458 nprow = " << nprow << std::endl; assert( nprow == -1 ) ; } if ( debug_ == 1) std::cout << "Amesos_Scalapack.cpp:446" << std::endl; MatTime_ += Time_->ElapsedTime(); return 0; }
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool testFailed; bool boolret; int MyPID = Comm.MyPID(); bool verbose = true; bool debug = false; std::string which("SM"); Teuchos::CommandLineProcessor cmdp(false,true); cmdp.setOption("verbose","quiet",&verbose,"Print messages and results."); cmdp.setOption("debug","nodebug",&debug,"Print debugging information."); cmdp.setOption("sort",&which,"Targetted eigenvalues (SM,LM,SR,LR,SI,or LI)."); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } typedef double ScalarType; typedef Teuchos::ScalarTraits<ScalarType> ScalarTypeTraits; typedef ScalarTypeTraits::magnitudeType MagnitudeType; typedef Epetra_MultiVector MV; typedef Epetra_Operator OP; typedef Anasazi::MultiVecTraits<ScalarType,MV> MVTraits; typedef Anasazi::OperatorTraits<ScalarType,MV,OP> OpTraits; // Dimension of the matrix int nx = 10; // Discretization points in any one direction. int NumGlobalElements = nx*nx; // Size of matrix nx*nx // Construct a Map that puts approximately the same number of // equations on each processor. Epetra_Map Map(NumGlobalElements, 0, Comm); // Get update list and number of local equations from newly created Map. int NumMyElements = Map.NumMyElements(); std::vector<int> MyGlobalElements(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 std::vector<int> NumNz(NumMyElements); /* We are building a matrix of block structure: | T -I | |-I T -I | | -I T | | ... -I| | -I T| where each block is dimension nx by nx and the matrix is on the order of nx*nx. The block T is a tridiagonal matrix. */ for (int i=0; i<NumMyElements; i++) { if (MyGlobalElements[i] == 0 || MyGlobalElements[i] == NumGlobalElements-1 || MyGlobalElements[i] == nx-1 || MyGlobalElements[i] == nx*(nx-1) ) { NumNz[i] = 3; } else if (MyGlobalElements[i] < nx || MyGlobalElements[i] > nx*(nx-1) || MyGlobalElements[i]%nx == 0 || (MyGlobalElements[i]+1)%nx == 0) { NumNz[i] = 4; } else { NumNz[i] = 5; } } // Create an Epetra_Matrix Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, Map, &NumNz[0]) ); // Diffusion coefficient, can be set by user. // When rho*h/2 <= 1, the discrete convection-diffusion operator has real eigenvalues. // When rho*h/2 > 1, the operator has complex eigenvalues. double rho = 2*(nx+1); // Compute coefficients for discrete convection-diffution operator const double one = 1.0; std::vector<double> Values(4); std::vector<int> Indices(4); double h = one /(nx+1); double h2 = h*h; double c = 5.0e-01*rho/ h; Values[0] = -one/h2 - c; Values[1] = -one/h2 + c; Values[2] = -one/h2; Values[3]= -one/h2; double diag = 4.0 / h2; int NumEntries, info; for (int i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; Indices[1] = nx; NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == nx*(nx-1)) { Indices[0] = nx*(nx-1)+1; Indices[1] = nx*(nx-2); NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == nx-1) { Indices[0] = nx-2; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); Indices[0] = 2*nx-1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == NumGlobalElements-1) { Indices[0] = NumGlobalElements-2; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); Indices[0] = nx*(nx-1)-1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] < nx) { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]+nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] > nx*(nx-1)) { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]-nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i]%nx == 0) { Indices[0] = MyGlobalElements[i]+1; Indices[1] = MyGlobalElements[i]-nx; Indices[2] = MyGlobalElements[i]+nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if ((MyGlobalElements[i]+1)%nx == 0) { Indices[0] = MyGlobalElements[i]-nx; Indices[1] = MyGlobalElements[i]+nx; NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); Indices[0] = MyGlobalElements[i]-1; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]-nx; Indices[3] = MyGlobalElements[i]+nx; NumEntries = 4; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } // Put in the diagonal entry info = A->InsertGlobalValues(MyGlobalElements[i], 1, &diag, &MyGlobalElements[i]); assert( info==0 ); } // Finish up info = A->FillComplete(); assert( info==0 ); A->SetTracebackMode(1); // Shutdown Epetra Warning tracebacks //************************************ // Start the block Davidson iteration //*********************************** // // Variables used for the Generalized Davidson Method // int nev = 4; int blockSize = 1; int maxDim = 50; int restartDim = 10; int maxRestarts = 500; double tol = 1e-10; // Set verbosity level int verbosity = Anasazi::Errors + Anasazi::Warnings; if (verbose) { verbosity += Anasazi::FinalSummary + Anasazi::TimingDetails; } if (debug) { verbosity += Anasazi::Debug; } // // Create parameter list to pass into solver manager // Teuchos::ParameterList MyPL; MyPL.set( "Verbosity", verbosity ); MyPL.set( "Which", which ); MyPL.set( "Block Size", blockSize ); MyPL.set( "Maximum Subspace Dimension", maxDim); MyPL.set( "Restart Dimension", restartDim); MyPL.set( "Maximum Restarts", maxRestarts ); MyPL.set( "Convergence Tolerance", tol ); MyPL.set( "Relative Convergence Tolerance", true ); MyPL.set( "Initial Guess", "User" ); // Create an Epetra_MultiVector for an initial vector to start the solver. // Note: This needs to have the same number of columns as the blocksize. Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(Map, blockSize) ); ivec->Random(); // Create the eigenproblem. Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem = Teuchos::rcp( new Anasazi::BasicEigenproblem<double,MV,OP>() ); MyProblem->setA(A); MyProblem->setInitVec(ivec); // Inform the eigenproblem that the operator A is non-Hermitian MyProblem->setHermitian(false); // Set the number of eigenvalues requested MyProblem->setNEV( nev ); // Inform the eigenproblem that you are finishing passing it information boolret = MyProblem->setProblem(); if (boolret != true) { if (verbose && MyPID == 0) { std::cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << std::endl; } #ifdef HAVE_MPI MPI_Finalize() ; #endif return -1; } // Initialize the Block Arnoldi solver Anasazi::GeneralizedDavidsonSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL); // Solve the problem to the specified tolerances or length Anasazi::ReturnType returnCode = MySolverMgr.solve(); testFailed = false; if (returnCode != Anasazi::Converged && MyPID==0 && verbose) { testFailed = true; } // Get the eigenvalues and eigenvectors from the eigenproblem Anasazi::Eigensolution<ScalarType,MV> sol = MyProblem->getSolution(); std::vector<Anasazi::Value<ScalarType> > evals = sol.Evals; Teuchos::RCP<MV> evecs = sol.Evecs; std::vector<int> index = sol.index; int numev = sol.numVecs; // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { int numritz = (int)evals.size(); std::cout.setf(std::ios_base::right, std::ios_base::adjustfield); std::cout<<std::endl<< "Computed Ritz Values"<< std::endl; std::cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << std::endl; std::cout<<"-----------------------------------------------------------"<<std::endl; for (int i=0; i<numritz; i++) { std::cout<< std::setw(16) << evals[i].realpart << std::setw(16) << evals[i].imagpart << std::endl; } std::cout<<"-----------------------------------------------------------"<<std::endl; } if (numev > 0) { // Compute residuals. Teuchos::LAPACK<int,double> lapack; std::vector<double> normA(numev); // The problem is non-Hermitian. int i=0; std::vector<int> curind(1); std::vector<double> resnorm(1), tempnrm(1); Teuchos::RCP<MV> tempAevec; Teuchos::RCP<const MV> evecr, eveci; Epetra_MultiVector Aevec(Map,numev); // Compute A*evecs OpTraits::Apply( *A, *evecs, Aevec ); Teuchos::SerialDenseMatrix<int,double> Breal(1,1), Bimag(1,1); while (i<numev) { if (index[i]==0) { // Get a view of the current eigenvector (evecr) curind[0] = i; evecr = MVTraits::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVTraits::CloneCopy( Aevec, curind ); // Compute A*evecr - lambda*evecr Breal(0,0) = evals[i].realpart; MVTraits::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); // Compute the norm of the residual and increment counter MVTraits::MvNorm( *tempAevec, resnorm ); normA[i] = resnorm[0] / Teuchos::ScalarTraits<MagnitudeType>::magnitude( evals[i].realpart ); i++; } else { // Get a view of the real part of the eigenvector (evecr) curind[0] = i; evecr = MVTraits::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVTraits::CloneCopy( Aevec, curind ); // Get a view of the imaginary part of the eigenvector (eveci) curind[0] = i+1; eveci = MVTraits::CloneView( *evecs, curind ); // Set the eigenvalue into Breal and Bimag Breal(0,0) = evals[i].realpart; Bimag(0,0) = evals[i].imagpart; // Compute A*evecr - evecr*lambdar + eveci*lambdai MVTraits::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); MVTraits::MvTimesMatAddMv( 1.0, *eveci, Bimag, 1.0, *tempAevec ); MVTraits::MvNorm( *tempAevec, tempnrm ); // Get a copy of A*eveci tempAevec = MVTraits::CloneCopy( Aevec, curind ); // Compute A*eveci - eveci*lambdar - evecr*lambdai MVTraits::MvTimesMatAddMv( -1.0, *evecr, Bimag, 1.0, *tempAevec ); MVTraits::MvTimesMatAddMv( -1.0, *eveci, Breal, 1.0, *tempAevec ); MVTraits::MvNorm( *tempAevec, resnorm ); // Compute the norms and scale by magnitude of eigenvalue normA[i] = lapack.LAPY2( tempnrm[0], resnorm[0] ) / lapack.LAPY2( evals[i].realpart, evals[i].imagpart ); normA[i+1] = normA[i]; i=i+2; } } // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { std::cout.setf(std::ios_base::right, std::ios_base::adjustfield); std::cout<<std::endl<< "Actual Residuals"<<std::endl; std::cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << std::setw(20) << "Direct Residual"<< std::endl; std::cout<<"-----------------------------------------------------------"<<std::endl; for (int j=0; j<numev; j++) { std::cout<< std::setw(16) << evals[j].realpart << std::setw(16) << evals[j].imagpart << std::setw(20) << normA[j] << std::endl; if ( normA[j] > tol ) { testFailed = true; } } std::cout<<"-----------------------------------------------------------"<<std::endl; } } #ifdef EPETRA_MPI MPI_Finalize(); #endif if (testFailed) { if (verbose && MyPID==0) { std::cout << "End Result: TEST FAILED" << std::endl; } return -1; } // // Default return value // if (verbose && MyPID==0) { std::cout << "End Result: TEST PASSED" << std::endl; } return 0; }
int main(int argc, char *argv[]) { int ierr = 0, i; #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool success = false; bool verbose = true; try { //int myRank = Comm.MyPID(); //int numGlobalElements = 10000000; int numGlobalElements = 100; Teuchos::CommandLineProcessor cmdp(false,true); cmdp.setOption("numGlobalElements",&numGlobalElements,"Global problem size."); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { throw -1; } Epetra_Map Map(numGlobalElements, 0, Comm); int NumMyElements = Map.NumMyElements(); std::vector<int> MyGlobalElements(NumMyElements); Map.MyGlobalElements(&MyGlobalElements[0]); int NumNz = 3; // std::vector<int> NumNz(NumMyElements); // for (i=0; i<NumMyElements; i++) // if (MyGlobalElements[i]==0 || MyGlobalElements[i] == numGlobalElements-1) // NumNz[i] = 2; // else // NumNz[i] = 3; // Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); MemoryUsageStart("Epetra"); PrintMemoryUsage("Initial memory usage", "epetra-init.heap"); Epetra_CrsMatrix A(Copy, Map, NumNz); PrintMemoryUsage("Memory after CrsMatrix constructor", "epetra-after-ctor.heap"); std::vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; std::vector<int> Indices(2); double two = 2.0; int NumEntries; for (i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == numGlobalElements-1) { Indices[0] = numGlobalElements-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } ierr = A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert(ierr==0); // Put in the diagonal entry ierr = A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i]); assert(ierr==0); } PrintMemoryUsage("Memory after InsertGlobalValues()", "epetra-after-insert.heap"); ierr = A.FillComplete(); assert(ierr == 0); PrintMemoryUsage("Memory after FillComplete()", "epetra-after-fillcomplete.heap"); MemoryUsageStop(); success = true; } TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success); #ifdef HAVE_MPI MPI_Finalize(); #endif return ( success ? EXIT_SUCCESS : EXIT_FAILURE ); }
int main(int argc, char *argv[]) { int i; bool ierr, gerr; gerr = true; #ifdef HAVE_MPI // Initialize MPI and setup an Epetra communicator MPI_Init(&argc,&argv); Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) ); #else // If we aren't using MPI, then setup a serial communicator. Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() ); #endif // number of global elements const int dim = 100; const int blockSize = 5; bool verbose = false; if (argc>1) { if (argv[1][0]=='-' && argv[1][1]=='v') { verbose = true; } } // Create an output manager to handle the I/O from the solver Teuchos::RCP<Anasazi::OutputManager<double> > MyOM = Teuchos::rcp( new Anasazi::BasicOutputManager<double>() ); if (verbose) { MyOM->setVerbosity( Anasazi::Warnings ); } #ifndef HAVE_EPETRA_THYRA MyOM->stream(Anasazi::Warnings) << "Please configure Anasazi with:" << std::endl << "--enable-epetra-thyra" << std::endl << "--enable-anasazi-thyra" << std::endl; #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; #endif // Construct a Map that puts approximately the same number of // equations on each processor. Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) ); // Get update list and number of local equations from newly created Map. int NumMyElements = Map->NumMyElements(); std::vector<int> MyGlobalElements(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 std::vector<int> NumNz(NumMyElements); // 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<NumMyElements; i++) { if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) { NumNz[i] = 2; } else { NumNz[i] = 3; } } // Create an Epetra_Matrix Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) ); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 std::vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; std::vector<int> Indices(2); double two = 2.0; int NumEntries; for (i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == dim-1) { Indices[0] = dim-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]); assert(ierr==0); // Put in the diagonal entry ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]); assert(ierr==0); } // Finish building the epetra matrix A ierr = A->FillComplete(); assert(ierr==0); #ifdef HAVE_EPETRA_THYRA typedef Thyra::MultiVectorBase<double> TMVB; typedef Thyra::LinearOpBase<double> TLOB; // first, create a Thyra::VectorSpaceBase from an Epetra_Map using the Epetra-Thyra wrappers Teuchos::RCP<const Thyra::VectorSpaceBase<double> > space = Thyra::create_VectorSpace(Map); // then, create a Thyra::MultiVectorBase from the Thyra::VectorSpaceBase using Thyra creational functions Teuchos::RCP<Thyra::MultiVectorBase<double> > thyra_ivec = Thyra::createMembers(space,blockSize); // then, create a Thyra::LinearOpBase from the Epetra_CrsMatrix using the Epetra-Thyra wrappers Teuchos::RCP<const Thyra::LinearOpBase<double> > thyra_op = Thyra::epetraLinearOp(A); // test the Thyra multivector adapter ierr = Anasazi::TestMultiVecTraits<double,TMVB>(MyOM,thyra_ivec); gerr |= ierr; if (ierr) { MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter PASSED TestMultiVecTraits()" << std::endl; } else { MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter FAILED TestMultiVecTraits() ***" << std::endl << std::endl; } // test the Thyra operator adapter ierr = Anasazi::TestOperatorTraits<double,TMVB,TLOB>(MyOM,thyra_ivec,thyra_op); gerr |= ierr; if (ierr) { MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter PASSED TestOperatorTraits()" << std::endl; } else { MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter FAILED TestOperatorTraits() ***" << std::endl << std::endl; } #endif #ifdef HAVE_MPI MPI_Finalize(); #endif if (gerr == false) { MyOM->print(Anasazi::Warnings,"End Result: TEST FAILED\n"); return -1; } // // Default return value // MyOM->print(Anasazi::Warnings,"End Result: TEST PASSED\n"); return 0; }
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; 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 vector<int> 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<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 += !(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(); HYPRE_IJMatrix Matrix; int ilower = Map.MinMyGID(); int iupper = Map.MaxMyGID(); //printf("Proc[%d], ilower = %d, iupper = %d.\n", MyPID, ilower, iupper); HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &Matrix); HYPRE_IJMatrixSetObjectType(Matrix, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(Matrix); for(i = 0; i < A.NumMyRows(); i++){ int numElements; A.NumMyRowEntries(i, numElements); vector<int> my_indices; my_indices.resize(numElements); vector<double> my_values; my_values.resize(numElements); int numEntries; A.ExtractMyRowCopy(i, numElements, numEntries, &my_values[0], &my_indices[0]); for(int j = 0; j < numEntries; j++) { my_indices[j] = A.GCID(my_indices[j]); } int GlobalRow[1]; GlobalRow[0] = A.GRID(i); HYPRE_IJMatrixSetValues(Matrix, 1, &numEntries, GlobalRow, &my_indices[0], &my_values[0]); } HYPRE_IJMatrixAssemble(Matrix); EpetraExt_HypreIJMatrix JadA(Matrix); JadA.SetMaps(JadA.RowMatrixRowMap(), A.RowMatrixColMap()); // 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); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); #ifdef EPETRA_MPI MPI_Finalize() ; #endif return ierr ; }
int Epetra_BlockMap::MyGlobalElementsPtr(int *& MyGlobalElementList) const { MyGlobalElementList = MyGlobalElements(); return(0); }
//============================================================================== void Epetra_BlockMap::Print(ostream & os) const { int * FirstPointInElementList1 = 0; int * ElementSizeList1 = 0; if (!ConstantElementSize()) { FirstPointInElementList1 = FirstPointInElementList(); ElementSizeList1 = ElementSizeList(); } int MyPID = Comm().MyPID(); int NumProc = Comm().NumProc(); for (int iproc = 0; iproc < NumProc; iproc++) { if (MyPID == iproc) { if (MyPID == 0) { os << "\nNumber of Global Elements = "; os << NumGlobalElements64(); os << endl; os << "Number of Global Points = "; os << NumGlobalPoints64(); os << endl; os << "Maximum of all GIDs = "; os << MaxAllGID64(); os << endl; os << "Minimum of all GIDs = "; os << MinAllGID64(); os << endl; os << "Index Base = "; os << IndexBase(); os << endl; if (ConstantElementSize()) os << "Constant Element Size = "; os << ElementSize(); os << endl; } os << endl; os << "Number of Local Elements = "; os << NumMyElements(); os << endl; os << "Number of Local Points = "; os << NumMyPoints(); os << endl; os << "Maximum of my GIDs = "; os << MaxMyGID64(); os << endl; os << "Minimum of my GIDs = "; os << MinMyGID64(); os << endl; os << endl; os.width(14); os << " MyPID"; os << " "; os.width(14); os << " Local Index "; os << " "; os.width(14); os << " Global Index "; os << " "; if (!ConstantElementSize()) { os.width(14); os <<" FirstPointInElement "; os << " "; os.width(14); os <<" ElementSize "; os << " "; } os << endl; for (int i = 0; i < NumMyElements(); i++) { os.width(14); os << MyPID; os << " "; os.width(14); os << i; os << " "; os.width(14); if(BlockMapData_->GlobalIndicesLongLong_) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES long long * MyGlobalElements1 = MyGlobalElements64(); os << MyGlobalElements1[i]; os << " "; #else throw ReportError("Epetra_BlockMap::Print: ERROR, GlobalIndicesLongLong but no API for it.",-1); #endif } else if(BlockMapData_->GlobalIndicesInt_) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES int * MyGlobalElements1 = MyGlobalElements(); os << MyGlobalElements1[i]; os << " "; #else throw ReportError("Epetra_BlockMap::Print: ERROR, no GlobalIndicesLongLong but no API for it.",-1); #endif } if (!ConstantElementSize()) { os.width(14); os << FirstPointInElementList1[i]; os << " "; os.width(14); os << ElementSizeList1[i]; os << " "; } os << endl; } os << flush; } // Do a few global ops to give I/O a chance to complete Comm().Barrier(); Comm().Barrier(); Comm().Barrier(); } return; }
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI // Initialize MPI MPI_Init( &argc, &argv ); //int size, rank; // Number of MPI processes, My process ID //MPI_Comm_size(MPI_COMM_WORLD, &size); //MPI_Comm_rank(MPI_COMM_WORLD, &rank); #else //int size = 1; // Serial case (not using MPI) //int rank = 0; #endif bool verbose = false; int nx = 5; int ny = 5; if( argc > 1 ) { if( argc > 4 ) { cout << "Usage: " << argv[0] << " [-v [nx [ny]]]" << endl; exit(1); } int loc = 1; // Check if we should print results to standard out if(argv[loc][0]=='-' && argv[loc][1]=='v') { verbose = true; ++loc; } if (loc < argc) nx = atoi( argv[loc++] ); if( loc < argc) ny = atoi( argv[loc] ); } #ifdef EPETRA_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); bool verbose1 = false; if(verbose) verbose1 = (MyPID==0); if(verbose1) cout << EpetraExt::EpetraExt_Version() << endl << endl; Comm.Barrier(); if(verbose) cout << Comm << endl << flush; Comm.Barrier(); int NumGlobalElements = nx * ny; if( NumGlobalElements < NumProc ) { cout << "NumGlobalElements = " << NumGlobalElements << " cannot be < number of processors = " << NumProc; exit(1); } int IndexBase = 0; Epetra_Map Map( NumGlobalElements, IndexBase, Comm ); // Extract the global indices of the elements local to this processor int NumMyElements = Map.NumMyElements(); std::vector<int> MyGlobalElements( NumMyElements ); Map.MyGlobalElements( &MyGlobalElements[0] ); if( verbose ) cout << Map; // Create the number of non-zeros for a tridiagonal (1D problem) or banded // (2D problem) matrix std::vector<int> NumNz( NumMyElements, 5 ); int global_i; int global_j; for (int i = 0; i < NumMyElements; ++i) { global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; if (global_i == 0) NumNz[i] -= 1; // By having separate statements, if (global_i == nx-1) NumNz[i] -= 1; // this works for 2D as well as 1D if (global_j == 0) NumNz[i] -= 1; // systems (i.e. nx x 1 or 1 x ny) if (global_j == ny-1) NumNz[i] -= 1; // or even a 1 x 1 system } if(verbose) { cout << endl << "NumNz: "; for (int i = 0; i < NumMyElements; i++) cout << NumNz[i] << " "; cout << endl; } // end if // Create the Epetra Compressed Row Sparse Graph Epetra_CrsGraph A( Copy, Map, &NumNz[0] ); std::vector<int> Indices(5); int NumEntries; for (int i = 0; i < NumMyElements; ++i ) { global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; NumEntries = 0; // (i,j-1) entry if (global_j > 0 && ny > 1) Indices[NumEntries++] = global_i + (global_j-1)*nx; // (i-1,j) entry if (global_i > 0) Indices[NumEntries++] = global_i-1 + global_j *nx; // (i,j) entry Indices[NumEntries++] = MyGlobalElements[i]; // (i+1,j) entry if (global_i < nx-1) Indices[NumEntries++] = global_i+1 + global_j *nx; // (i,j+1) entry if (global_j < ny-1 && ny > 1) Indices[NumEntries++] = global_i + (global_j+1)*nx; // Insert the global indices A.InsertGlobalIndices( MyGlobalElements[i], NumEntries, &Indices[0] ); } // end i loop // Finish up graph construction A.FillComplete(); EpetraExt::CrsGraph_MapColoring Greedy0MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 0, false, verbose ); Epetra_MapColoring & Greedy0ColorMap = Greedy0MapColoringTransform( A ); printColoring(Greedy0ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Greedy1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 1, false, verbose ); Epetra_MapColoring & Greedy1ColorMap = Greedy1MapColoringTransform( A ); printColoring(Greedy1ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Greedy2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 2, false, verbose ); Epetra_MapColoring & Greedy2ColorMap = Greedy2MapColoringTransform( A ); printColoring(Greedy2ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi0MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 0, false, verbose ); Epetra_MapColoring & Lubi0ColorMap = Lubi0MapColoringTransform( A ); printColoring(Lubi0ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 1, false, verbose ); Epetra_MapColoring & Lubi1ColorMap = Lubi1MapColoringTransform( A ); printColoring(Lubi1ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 2, false, verbose ); Epetra_MapColoring & Lubi2ColorMap = Lubi2MapColoringTransform( A ); printColoring(Lubi2ColorMap, &A,verbose); #ifdef EPETRA_MPI if( verbose ) cout << "Parallel Map Coloring 1!\n"; EpetraExt::CrsGraph_MapColoring Parallel1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::PSEUDO_PARALLEL, 0, false, verbose ); Epetra_MapColoring & Parallel1ColorMap = Parallel1MapColoringTransform( A ); printColoring(Parallel1ColorMap, &A,verbose); if( verbose ) cout << "Parallel Map Coloring 2!\n"; EpetraExt::CrsGraph_MapColoring Parallel2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::JONES_PLASSMAN, 0, false, verbose ); Epetra_MapColoring & Parallel2ColorMap = Parallel2MapColoringTransform( A ); printColoring(Parallel2ColorMap, &A,verbose); #endif #ifdef EPETRA_MPI MPI_Finalize(); #endif return 0; }