Epetra Package Browser (Single Doxygen Collection) Development
test/MapColoring/cxx_main.cpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 //
00004 //               Epetra: Linear Algebra Services Package
00005 //                 Copyright 2011 Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 
00043 // Epetra_BlockMap Test routine
00044 
00045 #include "Epetra_BlockMap.h"
00046 #include "Epetra_Map.h"
00047 #include "Epetra_MapColoring.h"
00048 #include "Epetra_IntVector.h"
00049 #include "Epetra_Import.h"
00050 #ifdef EPETRA_MPI
00051 #include "Epetra_MpiComm.h"
00052 #include <mpi.h>
00053 #endif
00054 
00055 #include "Epetra_SerialComm.h"
00056 #include "Epetra_Time.h"
00057 #include "Epetra_Version.h"
00058 
00059 int main(int argc, char *argv[]) {
00060 
00061   int i, returnierr=0;
00062 
00063 #ifdef EPETRA_MPI
00064   // Initialize MPI
00065   MPI_Init(&argc,&argv);
00066   Epetra_MpiComm Comm(MPI_COMM_WORLD);
00067 #else
00068   Epetra_SerialComm Comm;
00069 #endif
00070 
00071   // Uncomment to debug in parallel int tmp; if (Comm.MyPID()==0) cin >> tmp; Comm.Barrier();
00072 
00073   bool verbose = false;
00074   bool veryVerbose = false;
00075 
00076   // Check if we should print results to standard out
00077   if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
00078 
00079   // Check if we should print lots of results to standard out
00080   if (argc>2) if (argv[2][0]=='-' && argv[2][1]=='v') veryVerbose = true;
00081 
00082   if (verbose && Comm.MyPID()==0)
00083     std::cout << Epetra_Version() << std::endl << std::endl;
00084 
00085   if (!verbose) Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
00086 
00087   if (verbose) std::cout << Comm << std::endl << std::flush;
00088 
00089   bool verbose1 = verbose;
00090   if (verbose) verbose = (Comm.MyPID()==0);
00091 
00092   bool veryVerbose1 = veryVerbose;
00093   if (veryVerbose) veryVerbose = (Comm.MyPID()==0);
00094 
00095   int NumMyElements = 100;
00096   if (veryVerbose1) NumMyElements = 10;
00097   NumMyElements += Comm.MyPID();
00098   int MaxNumMyElements = NumMyElements+Comm.NumProc()-1;
00099   int * ElementSizeList = new int[NumMyElements];
00100   int * MyGlobalElements = new int[NumMyElements];
00101 
00102   for (i = 0; i<NumMyElements; i++) {
00103     MyGlobalElements[i] = (Comm.MyPID()*MaxNumMyElements+i)*2;
00104     ElementSizeList[i] = i%6 + 2; // elementsizes go from 2 to 7
00105   }
00106 
00107   Epetra_BlockMap Map(-1, NumMyElements, MyGlobalElements, ElementSizeList,
00108           0, Comm);
00109 
00110   delete [] ElementSizeList;
00111   delete [] MyGlobalElements;
00112 
00113   Epetra_MapColoring C0(Map);
00114 
00115   int * elementColors = new int[NumMyElements];
00116 
00117   int maxcolor = 24;
00118   int * colorCount = new int[maxcolor];
00119   int ** colorLIDs = new int*[maxcolor];
00120   for (i=0; i<maxcolor; i++) colorCount[i] = 0;
00121   for (i=0; i<maxcolor; i++) colorLIDs[i] = 0;
00122 
00123   int defaultColor = C0.DefaultColor();
00124   for (i=0; i<Map.NumMyElements(); i++) {
00125     assert(C0[i]==defaultColor);
00126     assert(C0(Map.GID(i))==defaultColor);
00127     if (i%2==0) C0[i] = i%6+5+i%14; // cycle through 5...23 on even elements
00128     else C0(Map.GID(i)) = i%5+1; // cycle through 1...5 on odd elements
00129     elementColors[i] = C0[i]; // Record color of ith element for use below
00130     colorCount[C0[i]]++; // Count how many of each color for checking below
00131   }
00132 
00133   if (veryVerbose)
00134     std::cout << "Original Map Coloring using element-by-element definitions" << std::endl;
00135   if (veryVerbose1)
00136     std::cout <<  C0 << std::endl;
00137 
00138   int numColors = 0;
00139   for (i=0; i<maxcolor; i++)
00140     if (colorCount[i]>0) {
00141       numColors++;
00142       colorLIDs[i] = new int[colorCount[i]];
00143     }
00144   for (i=0; i<maxcolor; i++) colorCount[i] = 0;
00145   for (i=0; i<Map.NumMyElements(); i++) colorLIDs[C0[i]][colorCount[C0[i]]++] = i;
00146 
00147 
00148 
00149   int newDefaultColor = -1;
00150   Epetra_MapColoring C1(Map, elementColors, newDefaultColor);
00151   if (veryVerbose)
00152     std::cout << "Same Map Coloring using one-time construction" << std::endl;
00153   if (veryVerbose1)
00154     std::cout <<  C1 << std::endl;
00155   assert(C1.DefaultColor()==newDefaultColor);
00156   for (i=0; i<Map.NumMyElements(); i++) assert(C1[i]==C0[i]);
00157 
00158   Epetra_MapColoring C2(C1);
00159   if (veryVerbose)
00160     std::cout << "Same Map Coloring using copy constructor" << std::endl;
00161   if (veryVerbose1)
00162     std::cout <<  C1 << std::endl;
00163   for (i=0; i<Map.NumMyElements(); i++) assert(C2[i]==C0[i]);
00164   assert(C2.DefaultColor()==newDefaultColor);
00165 
00166   assert(numColors==C2.NumColors());
00167 
00168   for (i=0; i<maxcolor; i++) {
00169     int curNumElementsWithColor = C2.NumElementsWithColor(i);
00170     assert(colorCount[i]==curNumElementsWithColor);
00171     int * curColorLIDList = C2.ColorLIDList(i);
00172     if (curNumElementsWithColor==0) {
00173       assert(curColorLIDList==0);
00174     }
00175     else
00176       for (int j=0; j<curNumElementsWithColor; j++) assert(curColorLIDList[j]==colorLIDs[i][j]);
00177   }
00178   int curColor = 1;
00179   Epetra_Map * Map1 = C2.GenerateMap(curColor);
00180   Epetra_BlockMap * Map2 = C2.GenerateBlockMap(curColor);
00181 
00182   assert(Map1->NumMyElements()==colorCount[curColor]);
00183   assert(Map2->NumMyElements()==colorCount[curColor]);
00184 
00185   for (i=0; i<Map1->NumMyElements(); i++) {
00186     assert(Map1->GID(i)==Map.GID(colorLIDs[curColor][i]));
00187     assert(Map2->GID(i)==Map.GID(colorLIDs[curColor][i]));
00188     assert(Map2->ElementSize(i)==Map.ElementSize(colorLIDs[curColor][i]));
00189   }
00190 
00191   // Now test data redistribution capabilities
00192 
00193 
00194   Epetra_Map ContiguousMap(-1, Map.NumMyElements(), Map.IndexBase(), Comm);
00195   // This vector contains the element sizes for the original map.
00196   Epetra_IntVector elementSizes(Copy, ContiguousMap, Map.ElementSizeList());
00197   Epetra_IntVector elementIDs(Copy, ContiguousMap, Map.MyGlobalElements());
00198   Epetra_IntVector elementColorValues(Copy, ContiguousMap, C2.ElementColors());
00199 
00200 
00201   int NumMyElements0 = 0;
00202   if (Comm.MyPID()==0) NumMyElements0 = Map.NumGlobalElements();
00203   Epetra_Map CMap0(-1, NumMyElements0, Map.IndexBase(), Comm);
00204   Epetra_Import importer(CMap0, ContiguousMap);
00205   Epetra_IntVector elementSizes0(CMap0);
00206   Epetra_IntVector elementIDs0(CMap0);
00207   Epetra_IntVector elementColorValues0(CMap0);
00208   elementSizes0.Import(elementSizes, importer, Insert);
00209   elementIDs0.Import(elementIDs, importer, Insert);
00210   elementColorValues0.Import(elementColorValues, importer, Insert);
00211 
00212   Epetra_BlockMap MapOnPE0(-1,NumMyElements0, elementIDs0.Values(),
00213          elementSizes0.Values(), Map.IndexBase(), Comm);
00214 
00215   Epetra_Import importer1(MapOnPE0, Map);
00216   Epetra_MapColoring ColoringOnPE0(MapOnPE0);
00217   ColoringOnPE0.Import(C2, importer1, Insert);
00218 
00219   for (i=0; i<MapOnPE0.NumMyElements(); i++)
00220     assert(ColoringOnPE0[i]==elementColorValues0[i]);
00221 
00222   if (veryVerbose)
00223     std::cout << "Same Map Coloring on PE 0 only" << std::endl;
00224   if (veryVerbose1)
00225     std::cout <<  ColoringOnPE0 << std::endl;
00226   Epetra_MapColoring C3(Map);
00227   C3.Export(ColoringOnPE0, importer1, Insert);
00228   for (i=0; i<Map.NumMyElements(); i++) assert(C3[i]==C2[i]);
00229   if (veryVerbose)
00230     std::cout << "Same Map Coloring after Import/Export exercise" << std::endl;
00231   if (veryVerbose1)
00232     std::cout <<  ColoringOnPE0 << std::endl;
00233 
00234 
00235   if (verbose) std::cout << "Checked OK\n\n" << std::endl;
00236 
00237   if (verbose1) {
00238     if (verbose) std::cout << "Test ostream << operator" << std::endl << std::flush;
00239     std::cout << C0 << std::endl;
00240   }
00241   
00242 
00243   delete [] elementColors;
00244   for (i=0; i<maxcolor; i++) if (colorLIDs[i]!=0) delete [] colorLIDs[i];
00245   delete [] colorLIDs;
00246   delete [] colorCount;
00247 
00248   delete Map1;
00249   delete Map2;
00250 
00251 
00252 #ifdef EPETRA_MPI
00253   MPI_Finalize();
00254 #endif
00255 
00256   return returnierr;
00257 }
00258 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines