int main(int argc, char *argv[]) { int i, returnierr=0; #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; bool veryVerbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Check if we should print lots of results to standard out if (argc>2) if (argv[2][0]=='-' && argv[2][1]=='v') veryVerbose = true; if (verbose && Comm.MyPID()==0) std::cout << Epetra_Version() << std::endl << std::endl; if (!verbose) Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) std::cout << Comm << std::endl << std::flush; bool verbose1 = verbose; if (verbose) verbose = (Comm.MyPID()==0); bool veryVerbose1 = veryVerbose; if (veryVerbose) veryVerbose = (Comm.MyPID()==0); int NumMyElements = 100; if (veryVerbose1) NumMyElements = 10; NumMyElements += Comm.MyPID(); int MaxNumMyElements = NumMyElements+Comm.NumProc()-1; int * ElementSizeList = new int[NumMyElements]; long long * MyGlobalElements = new long long[NumMyElements]; for (i = 0; i<NumMyElements; i++) { MyGlobalElements[i] = (Comm.MyPID()*MaxNumMyElements+i)*2; ElementSizeList[i] = i%6 + 2; // elementsizes go from 2 to 7 } Epetra_BlockMap Map(-1LL, NumMyElements, MyGlobalElements, ElementSizeList, 0, Comm); delete [] ElementSizeList; delete [] MyGlobalElements; Epetra_MapColoring C0(Map); int * elementColors = new int[NumMyElements]; int maxcolor = 24; int * colorCount = new int[maxcolor]; int ** colorLIDs = new int*[maxcolor]; for (i=0; i<maxcolor; i++) colorCount[i] = 0; for (i=0; i<maxcolor; i++) colorLIDs[i] = 0; int defaultColor = C0.DefaultColor(); for (i=0; i<Map.NumMyElements(); i++) { assert(C0[i]==defaultColor); assert(C0(Map.GID64(i))==defaultColor); if (i%2==0) C0[i] = i%6+5+i%14; // cycle through 5...23 on even elements else C0(Map.GID64(i)) = i%5+1; // cycle through 1...5 on odd elements elementColors[i] = C0[i]; // Record color of ith element for use below colorCount[C0[i]]++; // Count how many of each color for checking below } if (veryVerbose) std::cout << "Original Map Coloring using element-by-element definitions" << std::endl; if (veryVerbose1) std::cout << C0 << std::endl; int numColors = 0; for (i=0; i<maxcolor; i++) if (colorCount[i]>0) { numColors++; colorLIDs[i] = new int[colorCount[i]]; } for (i=0; i<maxcolor; i++) colorCount[i] = 0; for (i=0; i<Map.NumMyElements(); i++) colorLIDs[C0[i]][colorCount[C0[i]]++] = i; int newDefaultColor = -1; Epetra_MapColoring C1(Map, elementColors, newDefaultColor); if (veryVerbose) std::cout << "Same Map Coloring using one-time construction" << std::endl; if (veryVerbose1) std::cout << C1 << std::endl; assert(C1.DefaultColor()==newDefaultColor); for (i=0; i<Map.NumMyElements(); i++) assert(C1[i]==C0[i]); Epetra_MapColoring C2(C1); if (veryVerbose) std::cout << "Same Map Coloring using copy constructor" << std::endl; if (veryVerbose1) std::cout << C1 << std::endl; for (i=0; i<Map.NumMyElements(); i++) assert(C2[i]==C0[i]); assert(C2.DefaultColor()==newDefaultColor); assert(numColors==C2.NumColors()); for (i=0; i<maxcolor; i++) { int curNumElementsWithColor = C2.NumElementsWithColor(i); assert(colorCount[i]==curNumElementsWithColor); int * curColorLIDList = C2.ColorLIDList(i); if (curNumElementsWithColor==0) { assert(curColorLIDList==0); } else for (int j=0; j<curNumElementsWithColor; j++) assert(curColorLIDList[j]==colorLIDs[i][j]); } int curColor = 1; Epetra_Map * Map1 = C2.GenerateMap(curColor); Epetra_BlockMap * Map2 = C2.GenerateBlockMap(curColor); assert(Map1->NumMyElements()==colorCount[curColor]); assert(Map2->NumMyElements()==colorCount[curColor]); for (i=0; i<Map1->NumMyElements(); i++) { assert(Map1->GID64(i)==Map.GID64(colorLIDs[curColor][i])); assert(Map2->GID64(i)==Map.GID64(colorLIDs[curColor][i])); assert(Map2->ElementSize(i)==Map.ElementSize(colorLIDs[curColor][i])); } // Now test data redistribution capabilities Epetra_Map ContiguousMap(-1LL, Map.NumMyElements(), Map.IndexBase64(), Comm); // This vector contains the element sizes for the original map. Epetra_IntVector elementSizes(Copy, ContiguousMap, Map.ElementSizeList()); Epetra_LongLongVector elementIDs(Copy, ContiguousMap, Map.MyGlobalElements64()); Epetra_IntVector elementColorValues(Copy, ContiguousMap, C2.ElementColors()); long long NumMyElements0 = 0; if (Comm.MyPID()==0) NumMyElements0 = Map.NumGlobalElements64(); Epetra_Map CMap0(-1LL, NumMyElements0, Map.IndexBase64(), Comm); Epetra_Import importer(CMap0, ContiguousMap); Epetra_IntVector elementSizes0(CMap0); Epetra_LongLongVector elementIDs0(CMap0); Epetra_IntVector elementColorValues0(CMap0); elementSizes0.Import(elementSizes, importer, Insert); elementIDs0.Import(elementIDs, importer, Insert); elementColorValues0.Import(elementColorValues, importer, Insert); Epetra_BlockMap MapOnPE0(-1LL,NumMyElements0, elementIDs0.Values(), elementSizes0.Values(), Map.IndexBase64(), Comm); Epetra_Import importer1(MapOnPE0, Map); Epetra_MapColoring ColoringOnPE0(MapOnPE0); ColoringOnPE0.Import(C2, importer1, Insert); for (i=0; i<MapOnPE0.NumMyElements(); i++) assert(ColoringOnPE0[i]==elementColorValues0[i]); if (veryVerbose) std::cout << "Same Map Coloring on PE 0 only" << std::endl; if (veryVerbose1) std::cout << ColoringOnPE0 << std::endl; Epetra_MapColoring C3(Map); C3.Export(ColoringOnPE0, importer1, Insert); for (i=0; i<Map.NumMyElements(); i++) assert(C3[i]==C2[i]); if (veryVerbose) std::cout << "Same Map Coloring after Import/Export exercise" << std::endl; if (veryVerbose1) std::cout << ColoringOnPE0 << std::endl; if (verbose) std::cout << "Checked OK\n\n" << std::endl; if (verbose1) { if (verbose) std::cout << "Test ostream << operator" << std::endl << std::flush; std::cout << C0 << std::endl; } delete [] elementColors; for (i=0; i<maxcolor; i++) if (colorLIDs[i]!=0) delete [] colorLIDs[i]; delete [] colorLIDs; delete [] colorCount; delete Map1; delete Map2; #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
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; }
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; }