int main(int argc, char *argv[]) { int returnierr=0; bool verbose = false; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // Check if we should print results to standard out if (argc>1) { if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; } //Make sure the value of verbose is consistent across processors. int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; if (!verbose) { Comm.SetTracebackMode(0); // This should shut down error traceback reporting } if (verbose && Comm.MyPID()==0) cout << EpetraExt::EpetraExt_Version() << endl << endl; EPETRA_CHK_ERR( check_rowpermute_crsmatrix_local_diagonal( Comm, verbose ) ); EPETRA_CHK_ERR( check_rowpermute_crsmatrix_global_diagonal( Comm, verbose) ); EPETRA_CHK_ERR( check_rowpermute_crsgraph_local_diagonal( Comm, verbose) ); EPETRA_CHK_ERR( check_colpermute_crsgraph( Comm, verbose) ); EPETRA_CHK_ERR( check_colpermute_crsmatrix( Comm, verbose) ); EPETRA_CHK_ERR( check_rowpermute_multivector_local( Comm, verbose) ); #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
void BurkardtFileIOHandler::Initialize( const Teuchos::RCP<Teuchos::ParameterList>& params ) { #ifdef EPETRA_MPI Epetra_MpiComm comm( MPI_COMM_WORLD ); #else Epetra_SerialComm comm; #endif // Get the "File I/O" sublist. Teuchos::ParameterList& fileio_params = params->sublist( "File IO" ); if( fileio_params.isParameter("Burkardt Data Format File") ) { std::string format_file = Teuchos::getParameter<std::string>( fileio_params, "Burkardt Data Format File" ); // // The first processor get the number of nodes from the data format file and then broadcasts it. // if ( comm.MyPID() == 0 ) num_nodes = data_size( format_file ); comm.Broadcast( &num_nodes, 1, 0 ); // if (!num_nodes) { TO DO: THROW EXCEPTION! } isInit = true; } else { // Can't find the data size or data format file isInit = false; TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cannot find the data size or data format file 'Burkardt Data Format File'!"); } // Get the input path. in_path = ""; if ( fileio_params.isParameter( "Data Input Path" ) ) { in_path = Teuchos::getParameter<std::string>( fileio_params, "Data Input Path" ); } // Get the output path. out_path = ""; if ( fileio_params.isParameter( "Data Output Path" ) ) { out_path = Teuchos::getParameter<std::string>( fileio_params, "Data Output Path" ); } // This file i/o handler is not initialized. isInit = true; }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc, &argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) std::cout << Epetra_Version() << std::endl << std::endl; if (verbose) std::cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<< std::endl; // unused: bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; if (verbose) std::cout << "Test the memory management system of the class CrsMatrix (memory leak, invalid free)" << std::endl; // // Test 1: code initially proposed to illustrate bug #5499 // if(Comm.NumProc() == 1) { // this is a sequential test if (verbose) std::cout << "* Using Copy, ColMap, Variable number of indices per row and Static profile (cf. bug #5499)." << std::endl; // Row Map Epetra_Map RowMap(2LL, 0LL, Comm); // ColMap std::vector<long long> colids(2); colids[0]=0; colids[1]=1; Epetra_Map ColMap(-1LL, 2, &colids[0], 0LL, Comm); // NumEntriesPerRow std::vector<int> NumEntriesPerRow(2); NumEntriesPerRow[0]=2; NumEntriesPerRow[1]=2; // Test Epetra_CrsMatrix A(Copy, RowMap, ColMap, &NumEntriesPerRow[0], true); // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed) A.FillComplete(); } // // Test 1 Bis: same as Test1, but without ColMap and variable number of indices per row. Does not seems to matter // if(Comm.NumProc() == 1) { // this is a sequential test if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile" << std::endl; Epetra_Map RowMap(2LL, 0LL, Comm); // Test Epetra_CrsMatrix A(Copy, RowMap, 1, true); // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed) A.FillComplete(); } // // Test 2: same as Test 1 Bis but with one call to InsertGlobalValues. // if(Comm.NumProc() == 1) { if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile + InsertGlobalValues()." << std::endl; Epetra_Map RowMap(2LL, 0LL, Comm); // Test Epetra_CrsMatrix A(Copy, RowMap, 1, true); std::vector<long long> Indices(1); std::vector<double> Values(1); Values[0] = 2; Indices[0] = 0; A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); // Memory leak if CrsMatrix::Values not freed A.FillComplete(); } // // Test 3: check if the patch is not introducing some obvious regression // if(Comm.NumProc() == 1) { if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile" << std::endl; Epetra_Map RowMap(2LL, 0LL, Comm); // Test Epetra_CrsMatrix A(Copy, RowMap, 1, false); A.FillComplete(); } // // Test 4: idem but with one call to InsertGlobalValues. // if(Comm.NumProc() == 1) { if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile + InsertGlobalValues()." << std::endl; Epetra_Map RowMap(2LL, 0LL, Comm); // Test Epetra_CrsMatrix A(Copy, RowMap, 1, false); std::vector<long long> Indices(1); std::vector<double> Values(1); Values[0] = 2; Indices[0] = 0; A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); A.FillComplete(); } if(Comm.NumProc() == 1) { if (verbose) std::cout << "* Using Copy, Static Graph()." << std::endl; Epetra_Map RowMap(1LL, 0LL, Comm); // Test Epetra_CrsGraph G(Copy, RowMap, 1); std::vector<long long> Indices(1); Indices[0] = 0; G.InsertGlobalIndices(0, 1, &Indices[0]); G.FillComplete(); Epetra_CrsMatrix A(Copy, G); std::vector<double> Values(1); Values[0] = 2; A.ReplaceGlobalValues(0, 1, &Values[0], &Indices[0]); A.FillComplete(); double norminf = A.NormInf(); if (verbose) std::cout << "** Inf Norm of Matrix = " << norminf << "." << std::endl; std::cout << A << std::endl; } if(Comm.NumProc() == 1) { if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and static profile + InsertGlobalValues() for a single row." << std::endl; Epetra_Map RowMap(1LL, 0LL, Comm); // Test Epetra_CrsMatrix A(Copy, RowMap, 1, true); std::vector<long long> Indices(1); std::vector<double> Values(1); Values[0] = 2; Indices[0] = 0; A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); A.FillComplete(); } /* if (bool) { if (verbose) std::cout << std::endl << "tests FAILED" << std::endl << std::endl; } else {*/ if (verbose) std::cout << std::endl << "tests PASSED" << std::endl << std::endl; /* } */ #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
int main(int argc, char *argv[]) { int ierr = 0, i, forierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; long long NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0LL, Comm); // Get update list and number of local equations from newly created Map vector<long long> MyGlobalElements(Map.NumMyElements()); Map.MyGlobalElements(&MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor vector<int> NumNz(NumMyEquations); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; vector<long long> Indices(2); double two = 2.0; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up A.FillComplete(); A.OptimizeStorage(); Epetra_JadMatrix JadA(A); Epetra_JadMatrix JadA1(A); Epetra_JadMatrix JadA2(A); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); z.Random(); Epetra_Vector resid(Map); Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); JadA.SetFlopCounter(A); JadA1.SetFlopCounter(A); JadA2.SetFlopCounter(A); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); vector<double> Rowvals(numvals); vector<long long> Rowinds(numvals); A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0] for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]); } JadA.UpdateValues(A); A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); if (verbose) cout << "================================================================" << endl << "Testing Jad using Jad matrix as input matrix for construction..." << endl << "================================================================" << endl; JadA1.ResetFlops(); powerMethodTests(JadA1, JadA2, Map, q, z, resid, verbose); #ifdef EPETRA_MPI MPI_Finalize() ; #endif return ierr ; }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; //bool verbose1 = verbose; // unused // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 1; long long NumGlobalEquations = NumProc; // Get update list and number of local equations from newly created Map long long* MyGlobalElementsLL = new long long[NumMyEquations]; MyGlobalElementsLL[0] = 2000000000+MyPID; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map MapLL(NumGlobalEquations, NumMyEquations, MyGlobalElementsLL, 0, Comm); EPETRA_TEST_ERR(MapLL.GlobalIndicesInt(),ierr); EPETRA_TEST_ERR(!(MapLL.GlobalIndicesLongLong()),ierr); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNzLL = new int[NumMyEquations]; NumNzLL[0] = 0; // Create int types meant to add to long long matrix for test of failure int* MyIntGlobalElementsLL = new int[NumMyEquations]; MyIntGlobalElementsLL[0] = 20000+MyPID; // Create a long long Epetra_Matrix Epetra_CrsMatrix A_LL(Copy, MapLL, NumNzLL); EPETRA_TEST_ERR(A_LL.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A_LL.IndicesAreLocal(),ierr); // Insert values double one = 1.0; #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // Try to add ints which should fail and be caught as an int try { A_LL.InsertGlobalValues(MyIntGlobalElementsLL[0], 1, &one, MyIntGlobalElementsLL+0); } catch(int i) { EPETRA_TEST_ERR(!(i==-1),ierr); } #endif // Add long longs which should succeed EPETRA_TEST_ERR(!(A_LL.InsertGlobalValues(MyGlobalElementsLL[0], 1, &one, MyGlobalElementsLL+0)==0),ierr); EPETRA_TEST_ERR(!(A_LL.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A_LL.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A_LL.IndicesAreLocal()),ierr); // Get update list and number of local equations from newly created Map int* MyGlobalElementsInt = new int[NumMyEquations]; MyGlobalElementsInt[0] = 2000+MyPID; // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNzInt = new int[NumMyEquations]; NumNzInt[0] = 0; // Create int types meant to add to long long matrix for test of failure long long* MyLLGlobalElementsInt = new long long[NumMyEquations]; MyLLGlobalElementsInt[0] = 2000000000+MyPID; #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map MapInt(NumGlobalEquations, NumMyEquations, MyGlobalElementsInt, 0LL, Comm); EPETRA_TEST_ERR(!(MapInt.GlobalIndicesInt()),ierr); EPETRA_TEST_ERR(MapInt.GlobalIndicesLongLong(),ierr); // Create a int Epetra_Matrix Epetra_CrsMatrix A_Int(Copy, MapInt, NumNzInt); EPETRA_TEST_ERR(A_Int.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A_Int.IndicesAreLocal(),ierr); // Insert values try { A_Int.InsertGlobalValues(MyLLGlobalElementsInt[0], 1, &one, MyLLGlobalElementsInt+0); } catch(int i) { EPETRA_TEST_ERR(!(i==-1),ierr); } // Add long longs which should succeed EPETRA_TEST_ERR(!(A_Int.InsertGlobalValues(MyGlobalElementsInt[0], 1, &one, MyGlobalElementsInt+0)==0),ierr); EPETRA_TEST_ERR(!(A_Int.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A_Int.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A_Int.IndicesAreLocal()),ierr); #endif delete [] MyGlobalElementsLL; delete [] NumNzLL; delete [] MyIntGlobalElementsLL; delete [] MyGlobalElementsInt; delete [] NumNzInt; delete [] MyLLGlobalElementsInt; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm <<endl; int NumVectors = 1; int NumMyElements = 4; int NumGlobalElements = NumMyElements*NumProc; int IndexBase = 0; Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR( quad1(Map, verbose), ierr); EPETRA_TEST_ERR( quad2(Map, verbose), ierr); EPETRA_TEST_ERR( MultiVectorTests(Map, NumVectors, verbose), ierr); bool preconstruct_graph = false; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); preconstruct_graph = true; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
int main(int argc, char *argv[]) { int ierr = 0, forierr = 0; bool debug = false; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map int* MyGlobalElements = new int[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, NumNz); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double* Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int* Indices = new int[2]; double two = 2.0; int NumEntries; forierr = 0; for (int i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices)==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); int * indexOffsetTmp; int * indicesTmp; double * valuesTmp; // Finish up EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr); EPETRA_TEST_ERR(A.StorageOptimized(),ierr); A.OptimizeStorage(); EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==0),ierr); // Should succeed const Epetra_CrsGraph & GofA = A.Graph(); EPETRA_TEST_ERR((indicesTmp!=GofA[0] || valuesTmp!=A[0]),ierr); // Extra check to see if operator[] is consistent EPETRA_TEST_ERR(A.UpperTriangular(),ierr); EPETRA_TEST_ERR(A.LowerTriangular(),ierr); int NumMyNonzeros = 3 * NumMyEquations; if(A.LRID(0) >= 0) NumMyNonzeros--; // If I own first global row, then there is one less nonzero if(A.LRID(NumGlobalEquations-1) >= 0) NumMyNonzeros--; // If I own last global row, then there is one less nonzero EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, MyGlobalElements, verbose),ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumGlobalEntries(MyGlobalElements[i])==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumMyEntries(i)==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << std::endl<< std::endl; EPETRA_TEST_ERR(check_graph_sharing(Comm),ierr); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); Epetra_Vector resid(Map); // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 200; double tolerance = 1.0e-1; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); Epetra_Time timer(Comm); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = timer.ElapsedTime(); double total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << std::endl<< std::endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << std::endl; // Iterate lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for transpose solve = " << MFLOPs << std::endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); double * Rowvals = new double [numvals]; int * Rowinds = new int [numvals]; A.ExtractGlobalRowCopy(0, numvals, numvals, Rowvals, Rowinds); // Get A[0,0] for (int i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, Rowvals, Rowinds); delete [] Rowvals; delete [] Rowinds; } // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for tranpose of second solve = " << MFLOPs << endl<< endl; if (verbose) cout << "\n\n*****Testing constant entry constructor" << endl<< endl; Epetra_CrsMatrix AA(Copy, Map, 5); if (debug) Comm.Barrier(); double dble_one = 1.0; for (int i=0; i< NumMyEquations; i++) AA.InsertGlobalValues(MyGlobalElements[i], 1, &dble_one, MyGlobalElements+i); // Note: All processors will call the following Insert routines, but only the processor // that owns it will actually do anything int One = 1; if (AA.MyGlobalRow(0)) { EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 0, &dble_one, &One)==0),ierr); } else EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 1, &dble_one, &One)==-1),ierr); EPETRA_TEST_ERR(!(AA.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(AA.StorageOptimized(),ierr); EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr); EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr); if (debug) Comm.Barrier(); EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); if (debug) Comm.Barrier(); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(AA.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Epetra_CrsMatrix B(AA); EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(B.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing local view constructor" << endl<< endl; Epetra_CrsMatrix BV(View, AA.RowMap(), AA.ColMap(), 0); forierr = 0; int* Inds; double* Vals; for (int i = 0; i < NumMyEquations; i++) { forierr += !(AA.ExtractMyRowView(i, NumEntries, Vals, Inds)==0); forierr += !(BV.InsertMyValues(i, NumEntries, Vals, Inds)==0); } BV.FillComplete(false); EPETRA_TEST_ERR(check(BV, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(BV.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing post construction modifications" << endl<< endl; EPETRA_TEST_ERR(!(B.InsertGlobalValues(0, 1, &dble_one, &One)==-2),ierr); // Release all objects delete [] NumNz; delete [] Values; delete [] Indices; delete [] MyGlobalElements; if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 2 equations on each PE int NumMyElements1 = 2; int NumMyEquations1 = NumMyElements1; int NumGlobalEquations1 = NumMyEquations1*NumProc; Epetra_Map Map1(-1, NumMyElements1, 0, Comm); // Get update list and number of local equations from newly created Map int * MyGlobalElements1 = new int[Map1.NumMyElements()]; Map1.MyGlobalElements(MyGlobalElements1); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int * NumNz1 = new int[NumMyEquations1]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i=0; i<NumMyEquations1; i++) if (MyGlobalElements1[i]==0 || MyGlobalElements1[i] == NumGlobalEquations1-1) NumNz1[i] = 1; else NumNz1[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A1(Copy, Map1, NumNz1); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double *Values1 = new double[2]; Values1[0] = -1.0; Values1[1] = -1.0; int *Indices1 = new int[2]; double two1 = 2.0; int NumEntries1; forierr = 0; for (int i=0; i<NumMyEquations1; i++) { if (MyGlobalElements1[i]==0) { Indices1[0] = 1; NumEntries1 = 1; } else if (MyGlobalElements1[i] == NumGlobalEquations1-1) { Indices1[0] = NumGlobalEquations1-2; NumEntries1 = 1; } else { Indices1[0] = MyGlobalElements1[i]-1; Indices1[1] = MyGlobalElements1[i]+1; NumEntries1 = 2; } forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], NumEntries1, Values1, Indices1)==0); forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], 1, &two1, MyGlobalElements1+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); delete [] Indices1; delete [] Values1; // Finish up EPETRA_TEST_ERR(!(A1.FillComplete(false)==0),ierr); // Test diagonal extraction function Epetra_Vector checkDiag(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==two1); EPETRA_TEST_ERR(forierr,ierr); // Test diagonal replacement method forierr = 0; for (int i=0; i<NumMyEquations1; i++) checkDiag[i]=two1*two1; EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(!(A1.ReplaceDiagonalValues(checkDiag)==0),ierr); Epetra_Vector checkDiag1(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag1)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==checkDiag1[i]); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nDiagonal extraction and replacement OK.\n\n" << endl; double orignorm = A1.NormOne(); EPETRA_TEST_ERR(!(A1.Scale(4.0)==0),ierr); EPETRA_TEST_ERR(!(A1.NormOne()!=orignorm),ierr); if (verbose) cout << "\n\nMatrix scale OK.\n\n" << endl; if (verbose) cout << "\n\nPrint out tridiagonal matrix, each part on each processor.\n\n" << endl; cout << A1 << endl; // Release all objects delete [] NumNz1; delete [] MyGlobalElements1; } if (verbose) cout << "\n\n*****Testing LeftScale and RightScale" << endl << endl; int NumMyElements2 = 7; int NumMyRows2 = 1;//This value should not be changed without editing the // code below. Epetra_Map RowMap(-1,NumMyRows2,0,Comm); Epetra_Map ColMap(NumMyElements2,NumMyElements2,0,Comm); // The DomainMap needs to be different from the ColMap for the test to // be meaningful. Epetra_Map DomainMap(NumMyElements2,0,Comm); int NumMyRangeElements2 = 0; // We need to distribute the elements differently for the range map also. if (MyPID % 2 == 0) NumMyRangeElements2 = NumMyRows2*2; //put elements on even number procs if (NumProc % 2 == 1 && MyPID == NumProc-1) NumMyRangeElements2 = NumMyRows2; //If number of procs is odd, put // the last NumMyElements2 elements on the last proc Epetra_Map RangeMap(-1,NumMyRangeElements2,0,Comm); Epetra_CrsMatrix A2(Copy,RowMap,ColMap,NumMyElements2); double * Values2 = new double[NumMyElements2]; int * Indices2 = new int[NumMyElements2]; for (int i=0; i<NumMyElements2; i++) { Values2[i] = i+MyPID; Indices2[i]=i; } A2.InsertMyValues(0,NumMyElements2,Values2,Indices2); A2.FillComplete(DomainMap,RangeMap,false); Epetra_CrsMatrix A2copy(A2); double * RowLeftScaleValues = new double[NumMyRows2]; double * ColRightScaleValues = new double[NumMyElements2]; int RowLoopLength = RowMap.MaxMyGID()-RowMap.MinMyGID()+1; for (int i=0; i<RowLoopLength; i++) RowLeftScaleValues[i] = (i + RowMap.MinMyGID() ) % 2 + 1; // For the column map, all procs own all elements for (int i=0; i<NumMyElements2;i++) ColRightScaleValues[i] = i % 2 + 1; int RangeLoopLength = RangeMap.MaxMyGID()-RangeMap.MinMyGID()+1; double * RangeLeftScaleValues = new double[RangeLoopLength]; int DomainLoopLength = DomainMap.MaxMyGID()-DomainMap.MinMyGID()+1; double * DomainRightScaleValues = new double[DomainLoopLength]; for (int i=0; i<RangeLoopLength; i++) RangeLeftScaleValues[i] = 1.0/((i + RangeMap.MinMyGID() ) % 2 + 1); for (int i=0; i<DomainLoopLength;i++) DomainRightScaleValues[i] = 1.0/((i + DomainMap.MinMyGID() ) % 2 + 1); Epetra_Vector xRow(View,RowMap,RowLeftScaleValues); Epetra_Vector xCol(View,ColMap,ColRightScaleValues); Epetra_Vector xRange(View,RangeMap,RangeLeftScaleValues); Epetra_Vector xDomain(View,DomainMap,DomainRightScaleValues); double A2infNorm = A2.NormInf(); double A2oneNorm = A2.NormOne(); if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); double A2infNorm1 = A2.NormInf(); double A2oneNorm1 = A2.NormOne(); bool ScalingBroke = false; if (A2infNorm1>2*A2infNorm||A2infNorm1<A2infNorm) { EPETRA_TEST_ERR(-31,ierr); ScalingBroke = true; } if (A2oneNorm1>2*A2oneNorm||A2oneNorm1<A2oneNorm) { EPETRA_TEST_ERR(-32,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); double A2infNorm2 = A2.NormInf(); double A2oneNorm2 = A2.NormOne(); if (A2infNorm2>=2*A2infNorm1||A2infNorm2<=A2infNorm1) { EPETRA_TEST_ERR(-33,ierr); ScalingBroke = true; } if (A2oneNorm2>2*A2oneNorm1||A2oneNorm2<=A2oneNorm1) { EPETRA_TEST_ERR(-34,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); double A2infNorm3 = A2.NormInf(); double A2oneNorm3 = A2.NormOne(); // The last two scaling ops cancel each other out if (A2infNorm3!=A2infNorm1) { EPETRA_TEST_ERR(-35,ierr) ScalingBroke = true; } if (A2oneNorm3!=A2oneNorm1) { EPETRA_TEST_ERR(-36,ierr) ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); double A2infNorm4 = A2.NormInf(); double A2oneNorm4 = A2.NormOne(); // The 4 scaling ops all cancel out if (A2infNorm4!=A2infNorm) { EPETRA_TEST_ERR(-37,ierr) ScalingBroke = true; } if (A2oneNorm4!=A2oneNorm) { EPETRA_TEST_ERR(-38,ierr) ScalingBroke = true; } // // Now try changing the values underneath and make sure that // telling one process about the change causes NormInf() and // NormOne() to recompute the norm on all processes. // double *values; int num_my_rows = A2.NumMyRows() ; int num_entries; for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] *= 2.0; } } if ( MyPID == 0 ) A2.SumIntoGlobalValues( 0, 0, 0, 0 ) ; double A2infNorm5 = A2.NormInf(); double A2oneNorm5 = A2.NormOne(); if (A2infNorm5!=2.0 * A2infNorm4) { EPETRA_TEST_ERR(-39,ierr) ScalingBroke = true; } if (A2oneNorm5!= 2.0 * A2oneNorm4) { EPETRA_TEST_ERR(-40,ierr) ScalingBroke = true; } // // Restore the values underneath // for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] /= 2.0; } } if (verbose1) cout << A2; if (ScalingBroke) { if (verbose) cout << endl << "LeftScale and RightScale tests FAILED" << endl << endl; } else { if (verbose) cout << endl << "LeftScale and RightScale tests PASSED" << endl << endl; } Comm.Barrier(); if (verbose) cout << "\n\n*****Testing InvRowMaxs and InvColMaxs" << endl << endl; if (verbose1) cout << A2 << endl; EPETRA_TEST_ERR(A2.InvRowMaxs(xRow),ierr); EPETRA_TEST_ERR(A2.InvRowMaxs(xRange),ierr); if (verbose1) cout << xRow << endl << xRange << endl; if (verbose) cout << "\n\n*****Testing InvRowSums and InvColSums" << endl << endl; bool InvSumsBroke = false; // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRow),ierr); if (verbose1) cout << xRow; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); float A2infNormFloat = A2.NormInf(); if (verbose1) cout << A2 << endl; if (fabs(1.0-A2infNormFloat) > 1.e-5) { EPETRA_TEST_ERR(-41,ierr); InvSumsBroke = true; } // Works int expectedcode = 1; if (Comm.NumProc()>1) expectedcode = 0; EPETRA_TEST_ERR(!(A2.InvColSums(xDomain)==expectedcode),ierr); // This matrix has a single row, the first column has a zero, so a warning is issued. if (verbose1) cout << xDomain << endl; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); float A2oneNormFloat2 = A2.NormOne(); if (verbose1) cout << A2; if (fabs(1.0-A2oneNormFloat2)>1.e-5) { EPETRA_TEST_ERR(-42,ierr) InvSumsBroke = true; } // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRange),ierr); if (verbose1) cout << xRange; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); float A2infNormFloat2 = A2.NormInf(); // We use a float so that rounding error // will not prevent the sum from being 1.0. if (verbose1) cout << A2; if (fabs(1.0-A2infNormFloat2)>1.e-5) { cout << "InfNorm should be = 1, but InfNorm = " << A2infNormFloat2 << endl; EPETRA_TEST_ERR(-43,ierr); InvSumsBroke = true; } // Doesn't work - may not need this test because column ownership is not unique /* EPETRA_TEST_ERR(A2.InvColSums(xCol),ierr); cout << xCol; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); float A2oneNormFloat = A2.NormOne(); cout << A2; if (fabs(1.0-A2oneNormFloat)>1.e-5) { EPETRA_TEST_ERR(-44,ierr); InvSumsBroke = true; } */ delete [] ColRightScaleValues; delete [] DomainRightScaleValues; if (verbose) cout << "Begin partial sum testing." << endl; // Test with a matrix that has partial sums for a subset of the rows // on multiple processors. (Except for the serial case, of course.) int NumMyRows3 = 2; // Changing this requires further changes below int * myGlobalElements = new int[NumMyRows3]; for (int i=0; i<NumMyRows3; i++) myGlobalElements[i] = MyPID+i; Epetra_Map RowMap3(NumProc*2, NumMyRows3, myGlobalElements, 0, Comm); int NumMyElements3 = 5; Epetra_CrsMatrix A3(Copy, RowMap3, NumMyElements3); double * Values3 = new double[NumMyElements3]; int * Indices3 = new int[NumMyElements3]; for (int i=0; i < NumMyElements3; i++) { Values3[i] = (int) (MyPID + (i+1)); Indices3[i]=i; } for (int i=0; i<NumMyRows3; i++) { A3.InsertGlobalValues(myGlobalElements[i],NumMyElements3,Values3,Indices3); } Epetra_Map RangeMap3(NumProc+1, 0, Comm); Epetra_Map DomainMap3(NumMyElements3, 0, Comm); EPETRA_TEST_ERR(A3.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A3; Epetra_Vector xRange3(RangeMap3,false); Epetra_Vector xDomain3(DomainMap3,false); EPETRA_TEST_ERR(A3.InvRowSums(xRange3),ierr); if (verbose1) cout << xRange3; EPETRA_TEST_ERR(A3.LeftScale(xRange3),ierr); float A3infNormFloat = A3.NormInf(); if (verbose1) cout << A3; if (1.0!=A3infNormFloat) { cout << "InfNorm should be = 1, but InfNorm = " << A3infNormFloat <<endl; EPETRA_TEST_ERR(-61,ierr); InvSumsBroke = true; } // we want to take the transpose of our matrix and fill in different values. int NumMyColumns3 = NumMyRows3; Epetra_Map ColMap3cm(RowMap3); Epetra_Map RowMap3cm(A3.ColMap()); Epetra_CrsMatrix A3cm(Copy,RowMap3cm,ColMap3cm,NumProc+1); double *Values3cm = new double[NumMyColumns3]; int * Indices3cm = new int[NumMyColumns3]; for (int i=0; i<NumMyColumns3; i++) { Values3cm[i] = MyPID + i + 1; Indices3cm[i]= i + MyPID; } for (int ii=0; ii<NumMyElements3; ii++) { A3cm.InsertGlobalValues(ii, NumMyColumns3, Values3cm, Indices3cm); } // The DomainMap and the RangeMap from the last test will work fine for // the RangeMap and DomainMap, respectively, but I will make copies to // avaoid confusion when passing what looks like a DomainMap where we // need a RangeMap and vice vera. Epetra_Map RangeMap3cm(DomainMap3); Epetra_Map DomainMap3cm(RangeMap3); EPETRA_TEST_ERR(A3cm.FillComplete(DomainMap3cm,RangeMap3cm),ierr); if (verbose1) cout << A3cm << endl; // Again, we can copy objects from the last example. //Epetra_Vector xRange3cm(xDomain3); //Don't use at this time Epetra_Vector xDomain3cm(DomainMap3cm,false); EPETRA_TEST_ERR(A3cm.InvColSums(xDomain3cm),ierr); if (verbose1) cout << xDomain3cm << endl; EPETRA_TEST_ERR(A3cm.RightScale(xDomain3cm),ierr); float A3cmOneNormFloat = A3cm.NormOne(); if (verbose1) cout << A3cm << endl; if (1.0!=A3cmOneNormFloat) { cout << "OneNorm should be = 1, but OneNorm = " << A3cmOneNormFloat << endl; EPETRA_TEST_ERR(-62,ierr); InvSumsBroke = true; } if (verbose) cout << "End partial sum testing" << endl; if (verbose) cout << "Begin replicated testing" << endl; // We will now view the shared row as a repliated row, rather than one // that has partial sums of its entries on mulitple processors. // We will reuse much of the data used for the partial sum tesitng. Epetra_Vector xRow3(RowMap3,false); Epetra_CrsMatrix A4(Copy, RowMap3, NumMyElements3); for (int ii=0; ii < NumMyElements3; ii++) { Values3[ii] = (int)((ii*.6)+1.0); } for (int ii=0; ii<NumMyRows3; ii++) { A4.InsertGlobalValues(myGlobalElements[ii],NumMyElements3,Values3,Indices3); } EPETRA_TEST_ERR(A4.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A4 << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4.InvRowMaxs(xRow3),ierr); EPETRA_TEST_ERR(A4.InvRowMaxs(xRange3),ierr); if (verbose1) cout << xRow3 << xRange3; EPETRA_TEST_ERR(A4.InvRowSums(xRow3),ierr); if (verbose1) cout << xRow3; EPETRA_TEST_ERR(A4.LeftScale(xRow3),ierr); float A4infNormFloat = A4.NormInf(); if (verbose1) cout << A4; if (2.0!=A4infNormFloat && NumProc != 1) { if (verbose1) cout << "InfNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } else if (1.0!=A4infNormFloat && NumProc == 1) { if (verbose1) cout << "InfNorm should be = 1, but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } Epetra_Vector xCol3cm(ColMap3cm,false); Epetra_CrsMatrix A4cm(Copy, RowMap3cm, ColMap3cm, NumProc+1); //Use values from A3cm for (int ii=0; ii<NumMyElements3; ii++) { A4cm.InsertGlobalValues(ii,NumMyColumns3,Values3cm,Indices3cm); } EPETRA_TEST_ERR(A4cm.FillComplete(DomainMap3cm, RangeMap3cm,false),ierr); if (verbose1) cout << A4cm << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4cm.InvColMaxs(xCol3cm),ierr); EPETRA_TEST_ERR(A4cm.InvColMaxs(xDomain3cm),ierr); if (verbose1) cout << xCol3cm << xDomain3cm; EPETRA_TEST_ERR(A4cm.InvColSums(xCol3cm),ierr); if (verbose1) cout << xCol3cm << endl; EPETRA_TEST_ERR(A4cm.RightScale(xCol3cm),ierr); float A4cmOneNormFloat = A4cm.NormOne(); if (verbose1) cout << A4cm << endl; if (2.0!=A4cmOneNormFloat && NumProc != 1) { if (verbose1) cout << "OneNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but OneNorm = " << A4cmOneNormFloat << endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } else if (1.0!=A4cmOneNormFloat && NumProc == 1) { if (verbose1) cout << "OneNorm should be = 1, but OneNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } if (verbose) cout << "End replicated testing" << endl; if (InvSumsBroke) { if (verbose) cout << endl << "InvRowSums tests FAILED" << endl << endl; } else if (verbose) cout << endl << "InvRowSums tests PASSED" << endl << endl; A3cm.PutScalar(2.0); int nnz_A3cm = A3cm.Graph().NumGlobalNonzeros(); double check_frobnorm = sqrt(nnz_A3cm*4.0); double frobnorm = A3cm.NormFrobenius(); bool frobnorm_test_failed = false; if (fabs(check_frobnorm-frobnorm) > 5.e-5) { frobnorm_test_failed = true; } if (frobnorm_test_failed) { if (verbose) std::cout << "Frobenius-norm test FAILED."<<std::endl; EPETRA_TEST_ERR(-65, ierr); } delete [] Values2; delete [] Indices2; delete [] myGlobalElements; delete [] Values3; delete [] Indices3; delete [] Values3cm; delete [] Indices3cm; delete [] RangeLeftScaleValues; delete [] RowLeftScaleValues; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
Teuchos::RCP<Epetra_MultiVector> NetCDFFileIOHandler::Read( const std::vector<std::string>& filenames ) { #ifdef EPETRA_MPI Epetra_MpiComm comm( MPI_COMM_WORLD ); #else Epetra_SerialComm comm; #endif int ncid=0, row_id=0, col_id=0, ss_id=0, num_nod_var_id=0; int i, j, k, col_ptr=0; int rows=0, num_ss=0, num_vars=0, status=0; size_t rows_t=0, num_nod_var_t=0, start2[2],count2[2]; // // Check to see if we have to create a scaling index vector // bool createSSIdx = false; std::vector< std::pair<int,int> > scaling_idx; std::pair<int, int> idx_pair; /* try { scaling_idx = Teuchos::getParameter< std::vector< std::pair<int,int> > >( *params_, "Snapshot Scaling Indices" ); } catch (std::exception &e) { createSSIdx = true; } */ // // Open all the files and check that the snapshots have the same dimensions. // if ( comm.MyPID() == 0 ) { size_t rows0=0, cols0=0, cols_t=0, total_rows=0; std::string temp_filename = in_path + filenames[0]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // If the scaling index vector is needed we can create it here. // if (createSSIdx) { idx_pair.first = total_rows; } // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows0); if (status != NC_NOERR) handle_error(status); total_rows += rows0; // // Get information on the snapshot length. status = nc_inq_dimid(ncid,"col",&col_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,col_id, &cols0); if (status != NC_NOERR) handle_error(status); // if (!isInit) { int len_string_id, num_nodes_id, name_nod_var_id; size_t len_string_t, num_nodes_t; // Get maximum variable name length. status=nc_inq_dimid(ncid,"len_string",&len_string_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,len_string_id,&len_string_t); if (status != NC_NOERR) handle_error(status); // Get number of nodes. status=nc_inq_dimid(ncid,"num_nodes",&num_nodes_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nodes_id, &num_nodes_t); if (status != NC_NOERR) handle_error(status); // Get number of nodal variables. status=nc_inq_dimid(ncid,"num_nod_var",&num_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nod_var_id,&num_nod_var_t); if (status != NC_NOERR) handle_error(status); len_string = len_string_t; num_nodes = num_nodes_t; num_nod_var = num_nod_var_t; // Read in names of nodal variables. status=nc_inq_varid(ncid,"name_nod_var",&name_nod_var_id); if (status != NC_NOERR) handle_error(status); var_name = new char*[ num_nod_var ]; for (i=0; i<num_nod_var; ++i) var_name[i] = new char[ len_string ]; for (i=0; i<num_nod_var; ++i) { start2[0]=i; start2[1]=0; count2[0]=1; count2[1]=len_string; status=nc_get_vara_text(ncid,name_nod_var_id,start2,count2,var_name[i]); if (status != NC_NOERR) handle_error(status); } // // If the scaling index vector is needed we can set the endpoint here. // if (createSSIdx) { idx_pair.second = total_rows-1; scaling_idx.push_back( idx_pair ); } // Now we are initialized! isInit = true; // Output information. std::cout<<"len_string = "<<len_string<<std::endl; std::cout<<"num_nodes = "<<num_nodes<<std::endl; std::cout<<"num_nod_var = "<<num_nod_var<<std::endl; std::cout<<"var_name = "; for (i=0; i< num_nod_var; ++i) std::cout<<var_name[i]<<" "; std::cout<<std::endl; } // Close first file. status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); // for (i=1; i<(int)filenames.size(); i++) { std::string temp_filename = in_path + filenames[i]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // If the scaling index vector is needed we can create it here. // if (createSSIdx) { idx_pair.first = total_rows; } // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows_t); if (status != NC_NOERR) handle_error(status); // // Get information on the snapshot length. status = nc_inq_dimid(ncid,"col",&col_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,col_id, &cols_t); if (status != NC_NOERR) handle_error(status); // // Get number of nodal variables. status=nc_inq_dimid(ncid,"num_nod_var",&num_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nod_var_id,&num_nod_var_t); if (status != NC_NOERR) handle_error(status); // // TEUCHOS_TEST_FOR_EXCEPTION(cols_t != cols0 || (int)num_nod_var_t != num_nod_var, std::runtime_error, "Data set in file "+temp_filename+" is of inconsistent size!"); total_rows += rows_t; // // If the scaling index vector is needed we can set the endpoint here. // if (createSSIdx) { idx_pair.second = total_rows-1; scaling_idx.push_back( idx_pair ); } // Close the file. status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); } // Convert from size_t to int. num_ss = total_rows; num_vars = cols0; std::cout<<"Number of snapshots: "<< num_ss << std::endl; std::cout<<"Length of snapshot : "<< num_vars << std::endl; } // Broadcast information about size of snapshot matrix. comm.Broadcast( &num_ss, 1, 0 ); comm.Broadcast( &num_vars, 1, 0 ); // // Sync all other processors on the scaling index vector if necessary // if (createSSIdx) { for (i=0; i<(int)filenames.size(); i++) { if ( comm.MyPID() != 0 ) scaling_idx.push_back( idx_pair ); comm.Broadcast( &scaling_idx[i].first, 1, 0 ); comm.Broadcast( &scaling_idx[i].second, 1, 0 ); } // Set the scaling index vector //params_->set("Snapshot Scaling Indices", scaling_idx); } // // Create maps for new Epetra_MultiVector to hold the snapshots and // temporary Epetra_Vector used by processor 0 to import the information. // Epetra_Map Map( num_vars, 0, comm ); Teuchos::RCP<Epetra_MultiVector> newMV = Teuchos::rcp( new Epetra_MultiVector( Map, num_ss ) ); Epetra_Vector *col_newMV = 0; Epetra_Map *Proc0Map = 0; int *index = 0; float *temp_vec_f = 0; double *temp_vec_d = 0; // if ( comm.MyPID() == 0 ) { Proc0Map = new Epetra_Map( num_vars, num_vars, 0, comm ); temp_vec_f = new float [ num_vars ]; temp_vec_d = new double [ num_vars ]; index = new int[ num_vars ]; for ( i=0; i<num_vars; i++ ) { index[i] = i; } } else { Proc0Map = new Epetra_Map( num_vars, 0, 0, comm ); } // // Create an importer to get this information into the global Epetra_MultiVector // Epetra_Import importer( Map, *Proc0Map ); // // Processor 0 reads each file and then creates a local Epetra_Vector, which will be // imported into the i-th column of the Epetra_MultiVector. // // Read starting with row "start2[0]" for "count2[0]" rows, as the columns vary from // "start2[1]" to "count2[1]", i.e. specifically for this case, read starting with row i // for 1 row, as the columns vary from first column to the last column // start2[1]=0; count2[0]=1; count2[1]=num_vars; col_ptr = 0; // for (i=0; i<(int)filenames.size(); i++) { if ( comm.MyPID() == 0 ) { // Open the next snapshot file; std::string temp_filename = in_path + filenames[i]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows_t); if (status != NC_NOERR) handle_error(status); // Get the pointer for the snapshot matrix status = nc_inq_varid(ncid,"snapshot",&ss_id); if (status != NC_NOERR) handle_error(status); // // Convert from size_t to int. rows = rows_t; } comm.Broadcast( &rows, 1, 0 ); for (j=0; j<rows; j++) { // // Get column of Epetra_MultiVector in terms of Epetra_Vector. // col_newMV = (*newMV)( col_ptr ); // // Let Processor 0 fill in the Epetra_Vector. // if ( comm.MyPID() == 0 ) { // // Read in next snapshot, set pointer to next row containing snapshot in NetCDF file. // start2[0]=j; status=nc_get_vara_float(ncid,ss_id,start2,count2,temp_vec_f); for (k=0; k<num_vars; k++) { temp_vec_d[k] = temp_vec_f[k]; } } // // Create the Proc0Vector with values from temp_vec_d // Epetra_Vector Proc0Vector( View, *Proc0Map, temp_vec_d ); // // Import the information. // col_newMV->Import(Proc0Vector, importer, Add); // // Increment the counter. // col_ptr++; } // // Close this snapshot file. if ( comm.MyPID() == 0 ) { status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); } } // // Clean up delete Proc0Map; if ( index ) delete [] index; if ( temp_vec_f ) delete [] temp_vec_f; if ( temp_vec_d ) delete [] temp_vec_d; // Return. return newMV; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // initialize the random number generator int ml_one = 1; ML_srandom1(&ml_one); // ===================== // // create linear problem // // ===================== // Epetra_CrsMatrix *BadMatrix; int * i_blockids; int numblocks; EpetraExt::MatlabFileToCrsMatrix("samplemat.dat",Comm,BadMatrix); const Epetra_Map *Map=&BadMatrix->RowMap(); // Read in the block GLOBAL ids Epetra_Vector* d_blockids; int rv=EpetraExt::MatrixMarketFileToVector("blockids.dat",*Map,d_blockids); i_blockids=new int[d_blockids->MyLength()]; numblocks=-1; for(int i=0;i<d_blockids->MyLength();i++){ i_blockids[i]=(int)(*d_blockids)[i]-1; numblocks=MAX(numblocks,i_blockids[i]); } numblocks++; BadMatrix->FillComplete(); BadMatrix->OptimizeStorage(); int N=BadMatrix->RowMatrixRowMap().NumMyElements(); // Create the trivial blockID list int * trivial_blockids=new int[N]; for(int i=0;i<N;i++) trivial_blockids[i]=i; Epetra_Vector LHS(*Map); Epetra_Vector RHS(*Map); Epetra_LinearProblem BadProblem(BadMatrix, &LHS, &RHS); Teuchos::ParameterList MLList; double TotalErrorResidual = 0.0, TotalErrorExactSol = 0.0; char mystring[80]; // ====================== // // ML Cheby // ====================== // if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","Chebyshev"); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("aggregation: threshold",.02); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"Cheby"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); // These tests only work in serial due to how the block id's are written. if(Comm.NumProc()==1){ // ====================== // // ML Block Cheby (Trivial) // ====================== // if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","Block Chebyshev"); MLList.set("smoother: Block Chebyshev number of blocks",N); MLList.set("smoother: Block Chebyshev block list",trivial_blockids); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"ML Block Cheby (Trivial)"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); // ====================== // // ML Block Cheby (Smart) // ====================== // if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","Block Chebyshev"); MLList.set("smoother: Block Chebyshev number of blocks",numblocks); MLList.set("smoother: Block Chebyshev block list",i_blockids); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"ML Block Cheby (Smart)"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); } #if defined(HAVE_ML_IFPACK) // ====================== // // IFPACK Cheby // ====================== // if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","IFPACK-Chebyshev"); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"IFPACK Cheby"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); // ====================== // // IFPACK Block Cheby (Trivial) // ====================== // int NumBlocks=Map->NumMyElements(); int *BlockStarts=new int[NumBlocks+1]; int *Blockids=new int [NumBlocks]; for(int i=0;i<NumBlocks;i++){ BlockStarts[i]=i; Blockids[i]=Map->GID(i); } BlockStarts[NumBlocks]=NumBlocks; if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","IFPACK-Block Chebyshev"); MLList.set("smoother: Block Chebyshev number of blocks",NumBlocks); MLList.set("smoother: Block Chebyshev block starts",&BlockStarts[0]); MLList.set("smoother: Block Chebyshev block list",&Blockids[0]); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"IFPACK Block Cheby (Trivial)"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); delete [] BlockStarts; delete [] Blockids; // ====================== // // IFPACK Block Cheby (Smart) // ====================== // // Figure out how many blocks we actually have and build a map... Epetra_Map* IfpackMap; int g_NumBlocks=-1,g_MaxSize=-1; if(Comm.MyPID() == 0){ const int lineLength = 1025; char line[lineLength]; FILE * f=fopen("localids_in_blocks.dat","r"); assert(f!=0); // Next, strip off header lines (which start with "%") do { if(fgets(line, lineLength,f)==0) return(-4); } while (line[0] == '%'); // Grab the number we actually care about sscanf(line, "%d %d", &g_NumBlocks, &g_MaxSize); fclose(f); } Comm.Broadcast(&g_NumBlocks,1,0); Comm.Broadcast(&g_MaxSize,1,0); Epetra_Map BlockMap(g_NumBlocks,0,Comm); Epetra_MultiVector *blockids_disk=0; rv=EpetraExt::MatrixMarketFileToMultiVector("localids_in_blocks.dat",BlockMap,blockids_disk); // Put all the block info into the right place NumBlocks=BlockMap.NumMyElements(); BlockStarts=new int[NumBlocks+1]; Blockids= new int[g_MaxSize*NumBlocks]; // NTS: Blockids_ is overallocated because I don't want to write a counting loop int i,cidx; for(i=0,cidx=0;i<NumBlocks;i++){ BlockStarts[i]=cidx; Blockids[cidx]=(int)(*blockids_disk)[0][i];cidx++; if((*blockids_disk)[1][i] > 1e-2){ Blockids[cidx]=(int)(*blockids_disk)[1][i];cidx++; } } BlockStarts[NumBlocks]=cidx; if (Comm.MyPID() == 0) PrintLine(); ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","IFPACK-Block Chebyshev"); MLList.set("smoother: Block Chebyshev number of blocks",NumBlocks); MLList.set("smoother: Block Chebyshev block starts",&BlockStarts[0]); MLList.set("smoother: Block Chebyshev block list",&Blockids[0]); MLList.set("coarse: type","Amesos-KLU"); MLList.set("max levels",2); MLList.set("ML output",10); MLList.set("smoother: polynomial order",2); strcpy(mystring,"IFPACK Block Cheby (Smart)"); TestMultiLevelPreconditioner(mystring, MLList, BadProblem, TotalErrorResidual, TotalErrorExactSol); delete blockids_disk; delete [] BlockStarts; delete [] Blockids; #endif // ===================== // // print out total error // // ===================== // if (Comm.MyPID() == 0) { cout << endl; cout << "......Total error for residual = " << TotalErrorResidual << endl; cout << "......Total error for exact solution = " << TotalErrorExactSol << endl; cout << endl; } delete [] i_blockids; delete [] trivial_blockids; delete BadMatrix; delete d_blockids; if (TotalErrorResidual > 1e-5) { cerr << "Error: `BlockCheby.exe' failed!" << endl; exit(EXIT_FAILURE); } #ifdef HAVE_MPI MPI_Finalize(); #endif if (Comm.MyPID() == 0) cerr << "`BlockCheby.exe' passed!" << endl; return (EXIT_SUCCESS); }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); // define an Epetra communicator Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // get the proc ID of this process int MyPID = Comm.MyPID(); // get the total number of processes int NumProc = Comm.NumProc(); // output some information to std output cout << Comm << endl; // ======================== // // now some basic MPI calls // // ------------------------ // int ivalue; double dvalue, dvalue2; double* dvalues; dvalues = new double[NumProc]; double* dvalues2; dvalues2 = new double[NumProc]; int root = 0; // equivalent to MPI_Barrier Comm.Barrier(); if (MyPID == root) dvalue = 12.0; // On input, the root processor contains the list of values // (in this case, a single value). On exit, all processes will // have he same list of values. Note that all values must be allocated // vefore the broadcast // equivalent to MPI_Broadcast Comm.Broadcast(&dvalue, 1, root); // as before, but with integer values. As C++ can bind to the appropriate // interface based on argument typing, the type of data is not required. Comm.Broadcast(&ivalue, 1, root); // equivalent MPI_Allgather Comm.GatherAll(dvalues, dvalues2, 1); // equivalent to MPI_Allreduce with MPI_SUM dvalue = 1.0*MyPID; Comm.SumAll( &dvalue, dvalues, 1); // equivalent to MPI_Allreduce with MPI_SUM Comm.MaxAll( &dvalue, dvalues, 1); // equiavant to MPI_Scan with MPI_SUM dvalue = 1.0 * MyPID; Comm.ScanSum(&dvalue, &dvalue2, 1); cout << "On proc " << MyPID << " dvalue2 = " << dvalue2 << endl; delete[] dvalues; delete[] dvalues2; // ======================= // // Finalize MPI and return // // ----------------------- // #ifdef HAVE_MPI MPI_Finalize(); #endif return( EXIT_SUCCESS ); } /* main */
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 ; }