void GenerateVbrProblem(int numNodesX, int numNodesY, int numProcsX, int numProcsY, int numPoints, int * xoff, int * yoff, int nsizes, int * sizes, int nrhs, const Epetra_Comm &comm, bool verbose, bool summary, Epetra_BlockMap *& map, Epetra_VbrMatrix *& A, Epetra_MultiVector *& b, Epetra_MultiVector *& bt, Epetra_MultiVector *&xexact, bool StaticProfile, bool MakeLocalOnly) { int i; // Determine my global IDs long long * myGlobalElements; GenerateMyGlobalElements(numNodesX, numNodesY, numProcsX, numProcsY, comm.MyPID(), myGlobalElements); int numMyElements = numNodesX*numNodesY; Epetra_Map ptMap((long long)-1, numMyElements, myGlobalElements, 0, comm); // Create map with 2D block partitioning. delete [] myGlobalElements; Epetra_IntVector elementSizes(ptMap); // This vector will have the list of element sizes for (i=0; i<numMyElements; i++) elementSizes[i] = sizes[ptMap.GID64(i)%nsizes]; // cycle through sizes array map = new Epetra_BlockMap((long long)-1, numMyElements, ptMap.MyGlobalElements64(), elementSizes.Values(), ptMap.IndexBase64(), ptMap.Comm()); int profile = 0; if (StaticProfile) profile = numPoints; // FIXME: Won't compile until Epetra_VbrMatrix is modified. #if 0 int j; long long numGlobalEquations = ptMap.NumGlobalElements64(); if (MakeLocalOnly) A = new Epetra_VbrMatrix(Copy, *map, *map, profile); // Construct matrix rowmap=colmap else A = new Epetra_VbrMatrix(Copy, *map, profile); // Construct matrix long long * indices = new long long[numPoints]; // This section of code creates a vector of random values that will be used to create // light-weight dense matrices to pass into the VbrMatrix construction process. int maxElementSize = 0; for (i=0; i< nsizes; i++) maxElementSize = EPETRA_MAX(maxElementSize, sizes[i]); Epetra_LocalMap lmap((long long)maxElementSize*maxElementSize, ptMap.IndexBase(), ptMap.Comm()); Epetra_Vector randvec(lmap); randvec.Random(); randvec.Scale(-1.0); // Make value negative int nx = numNodesX*numProcsX; for (i=0; i<numMyElements; i++) { long long rowID = map->GID64(i); int numIndices = 0; int rowDim = sizes[rowID%nsizes]; for (j=0; j<numPoints; j++) { long long colID = rowID + xoff[j] + nx*yoff[j]; // Compute column ID based on stencil offsets if (colID>-1 && colID<numGlobalEquations) indices[numIndices++] = colID; } A->BeginInsertGlobalValues(rowID, numIndices, indices); for (j=0; j < numIndices; j++) { int colDim = sizes[indices[j]%nsizes]; A->SubmitBlockEntry(&(randvec[0]), rowDim, rowDim, colDim); } A->EndSubmitEntries(); } delete [] indices; A->FillComplete(); // Compute the InvRowSums of the matrix rows Epetra_Vector invRowSums(A->RowMap()); Epetra_Vector rowSums(A->RowMap()); A->InvRowSums(invRowSums); rowSums.Reciprocal(invRowSums); // Jam the row sum values into the diagonal of the Vbr matrix (to make it diag dominant) int numBlockDiagonalEntries; int * rowColDims; int * diagoffsets = map->FirstPointInElementList(); A->BeginExtractBlockDiagonalView(numBlockDiagonalEntries, rowColDims); for (i=0; i< numBlockDiagonalEntries; i++) { double * diagVals; int diagLDA; A->ExtractBlockDiagonalEntryView(diagVals, diagLDA); int rowDim = map->ElementSize(i); for (j=0; j<rowDim; j++) diagVals[j+j*diagLDA] = rowSums[diagoffsets[i]+j]; } if (nrhs<=1) { b = new Epetra_Vector(*map); bt = new Epetra_Vector(*map); xexact = new Epetra_Vector(*map); } else { b = new Epetra_MultiVector(*map, nrhs); bt = new Epetra_MultiVector(*map, nrhs); xexact = new Epetra_MultiVector(*map, nrhs); } xexact->Random(); // Fill xexact with random values A->Multiply(false, *xexact, *b); A->Multiply(true, *xexact, *bt); #endif // EPETRA_NO_32BIT_GLOBAL_INDICES return; }
void Trilinos_Util_GenerateVbrProblem(int nx, int ny, int npoints, int * xoff, int * yoff, int nsizes, int * sizes, int nrhs, const Epetra_Comm &comm, Epetra_BlockMap *& map, Epetra_VbrMatrix *& A, Epetra_MultiVector *& x, Epetra_MultiVector *& b, Epetra_MultiVector *&xexact) { int i, j; // Number of global equations is nx*ny. These will be distributed in a linear fashion int numGlobalEquations = nx*ny; Epetra_Map ptMap(numGlobalEquations, 0, comm); // Create map with equal distribution of equations. int numMyElements = ptMap.NumMyElements(); Epetra_IntVector elementSizes(ptMap); // This vector will have the list of element sizes for (i=0; i<numMyElements; i++) elementSizes[i] = sizes[ptMap.GID64(i)%nsizes]; // cycle through sizes array map = new Epetra_BlockMap(-1, numMyElements, ptMap.MyGlobalElements(), elementSizes.Values(), ptMap.IndexBase(), ptMap.Comm()); A = new Epetra_VbrMatrix(Copy, *map, 0); // Construct matrix int * indices = new int[npoints]; // double * values = new double[npoints]; // double dnpoints = (double) npoints; // This section of code creates a vector of random values that will be used to create // light-weight dense matrices to pass into the VbrMatrix construction process. int maxElementSize = 0; for (i=0; i< nsizes; i++) maxElementSize = EPETRA_MAX(maxElementSize, sizes[i]); Epetra_LocalMap lmap(maxElementSize*maxElementSize, ptMap.IndexBase(), ptMap.Comm()); Epetra_Vector randvec(lmap); randvec.Random(); randvec.Scale(-1.0); // Make value negative for (i=0; i<numMyElements; i++) { int rowID = map->GID(i); int numIndices = 0; int rowDim = sizes[rowID%nsizes]; for (j=0; j<npoints; j++) { int colID = rowID + xoff[j] + nx*yoff[j]; // Compute column ID based on stencil offsets if (colID>-1 && colID<numGlobalEquations) indices[numIndices++] = colID; } A->BeginInsertGlobalValues(rowID, numIndices, indices); for (j=0; j < numIndices; j++) { int colDim = sizes[indices[j]%nsizes]; A->SubmitBlockEntry(&(randvec[0]), rowDim, rowDim, colDim); } A->EndSubmitEntries(); } delete [] indices; A->FillComplete(); // Compute the InvRowSums of the matrix rows Epetra_Vector invRowSums(A->RowMap()); Epetra_Vector rowSums(A->RowMap()); A->InvRowSums(invRowSums); rowSums.Reciprocal(invRowSums); // Jam the row sum values into the diagonal of the Vbr matrix (to make it diag dominant) int numBlockDiagonalEntries; int * rowColDims; int * diagoffsets = map->FirstPointInElementList(); A->BeginExtractBlockDiagonalView(numBlockDiagonalEntries, rowColDims); for (i=0; i< numBlockDiagonalEntries; i++) { double * diagVals; int diagLDA; A->ExtractBlockDiagonalEntryView(diagVals, diagLDA); int rowDim = map->ElementSize(i); for (j=0; j<rowDim; j++) diagVals[j+j*diagLDA] = rowSums[diagoffsets[i]+j]; } if (nrhs<=1) { x = new Epetra_Vector(*map); b = new Epetra_Vector(*map); xexact = new Epetra_Vector(*map); } else { x = new Epetra_MultiVector(*map, nrhs); b = new Epetra_MultiVector(*map, nrhs); xexact = new Epetra_MultiVector(*map, nrhs); } xexact->Random(); // Fill xexact with random values A->Multiply(false, *xexact, *b); return; }
int main(int argc, char *argv[]) { int i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // Uncomment to debug in parallel int tmp; if (comm.MyPID()==0) cin >> tmp; comm.Barrier(); bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; if (!verbose) comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) cout << comm << endl << flush; if (verbose) verbose = (comm.MyPID()==0); if (verbose) cout << EpetraExt::EpetraExt_Version() << endl << endl; int nx = 128; int ny = comm.NumProc()*nx; // Scale y grid with number of processors // Create funky stencil to make sure the matrix is non-symmetric (transpose non-trivial): // (i-1,j-1) (i-1,j ) // (i ,j-1) (i ,j ) (i ,j+1) // (i+1,j-1) (i+1,j ) int npoints = 7; int xoff[] = {-1, 0, 1, -1, 0, 1, 0}; int yoff[] = {-1, -1, -1, 0, 0, 0, 1}; Epetra_Map * map; Epetra_CrsMatrix * A; Epetra_Vector * x, * b, * xexact; Trilinos_Util_GenerateCrsProblem(nx, ny, npoints, xoff, yoff, comm, map, A, x, b, xexact); if (nx<8) { cout << *A << endl; cout << "X exact = " << endl << *xexact << endl; cout << "B = " << endl << *b << endl; } // Construct transposer Epetra_Time timer(comm); double start = timer.ElapsedTime(); //bool IgnoreNonLocalCols = false; bool MakeDataContiguous = true; EpetraExt::RowMatrix_Transpose transposer( MakeDataContiguous ); if (verbose) cout << "\nTime to construct transposer = " << timer.ElapsedTime() - start << endl; Epetra_CrsMatrix & transA = dynamic_cast<Epetra_CrsMatrix&>(transposer(*A)); start = timer.ElapsedTime(); if (verbose) cout << "\nTime to create transpose matrix = " << timer.ElapsedTime() - start << endl; // Now test output of transposer by performing matvecs int ierr = 0; ierr += checkResults(A, &transA, xexact, verbose); // Now change values in original matrix and test update facility of transposer // Add 2 to the diagonal of each row double Value = 2.0; for (i=0; i< A->NumMyRows(); i++) A->SumIntoMyValues(i, 1, &Value, &i); start = timer.ElapsedTime(); transposer.fwd(); if (verbose) cout << "\nTime to update transpose matrix = " << timer.ElapsedTime() - start << endl; ierr += checkResults(A, &transA, xexact, verbose); delete A; delete b; delete x; delete xexact; delete map; if (verbose) cout << endl << "Checking transposer for VbrMatrix objects" << endl<< endl; int nsizes = 4; int sizes[] = {4, 6, 5, 3}; Epetra_VbrMatrix * Avbr; Epetra_BlockMap * bmap; Trilinos_Util_GenerateVbrProblem(nx, ny, npoints, xoff, yoff, nsizes, sizes, comm, bmap, Avbr, x, b, xexact); if (nx<8) { cout << *Avbr << endl; cout << "X exact = " << endl << *xexact << endl; cout << "B = " << endl << *b << endl; } start = timer.ElapsedTime(); EpetraExt::RowMatrix_Transpose transposer1( MakeDataContiguous ); Epetra_CrsMatrix & transA1 = dynamic_cast<Epetra_CrsMatrix&>(transposer1(*Avbr)); if (verbose) cout << "\nTime to create transpose matrix = " << timer.ElapsedTime() - start << endl; // Now test output of transposer by performing matvecs ; ierr += checkResults(Avbr, &transA1, xexact, verbose); // Now change values in original matrix and test update facility of transposer // Scale matrix on the left by rowsums Epetra_Vector invRowSums(Avbr->RowMap()); Avbr->InvRowSums(invRowSums); Avbr->LeftScale(invRowSums); start = timer.ElapsedTime(); transposer1.fwd(); if (verbose) cout << "\nTime to update transpose matrix = " << timer.ElapsedTime() - start << endl; ierr += checkResults(Avbr, &transA1, xexact, verbose); delete Avbr; delete b; delete x; delete xexact; delete bmap; #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }