Epetra Package Browser (Single Doxygen Collection) Development
test/Map/cxx_main.cpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //               Epetra: Linear Algebra Services Package 
00005 //                 Copyright 2001 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_Map (and Epetra_LocalMap) Test routine
00044 #include "Epetra_Time.h"
00045 #include "Epetra_Map.h"
00046 #include "Epetra_LocalMap.h"
00047 #ifdef EPETRA_MPI
00048 #include "Epetra_MpiComm.h"
00049 #include <mpi.h>
00050 #else
00051 #include "Epetra_SerialComm.h"
00052 #endif
00053 #include "checkmap.h"
00054 #include "../epetra_test_err.h"
00055 #include "Epetra_Version.h"
00056 
00057 int checkMapDataClass(Epetra_Comm& Comm, int verbose);
00058 int checkLocalMapDataClass(Epetra_Comm& Comm, int verbose);
00059 
00060 int main(int argc, char *argv[]) {
00061 
00062   int ierr=0, returnierr=0;
00063 
00064 #ifdef EPETRA_MPI
00065   MPI_Init(&argc,&argv);
00066   Epetra_MpiComm Comm(MPI_COMM_WORLD);
00067 #else
00068   Epetra_SerialComm Comm;
00069 #endif
00070 
00071   bool verbose = false;
00072 
00073   // Check if we should print results to standard out
00074   if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
00075 
00076 
00077   if (!verbose) {
00078     Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
00079   }
00080   int MyPID = Comm.MyPID();
00081   int NumProc = Comm.NumProc();
00082 
00083   if (verbose && MyPID==0)
00084     cout << Epetra_Version() << endl << endl;
00085 
00086   if (verbose) cout << Comm << endl;
00087 
00088   bool verbose1 = verbose;
00089   if (verbose) verbose = (MyPID==0);
00090 
00091   int NumMyElements = 10000;
00092   int NumMyElements1 = NumMyElements; // Used for local map
00093   int NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3);
00094   if (MyPID < 3) NumMyElements++;
00095   int IndexBase = 0;
00096   bool DistributedGlobal = (NumGlobalElements>NumMyElements);
00097   
00098   Epetra_Map* Map;
00099 
00100   // Test exceptions
00101 
00102   if (verbose)
00103     cout << "*******************************************************************************************" << endl
00104    << "        Testing Exceptions (Expect error messages if EPETRA_NO_ERROR_REPORTS is not defined" << endl
00105    << "*******************************************************************************************" << endl
00106    << endl << endl;
00107 
00108   try {
00109     if (verbose) cout << "Checking Epetra_Map(-2, IndexBase, Comm)" << endl;
00110     Map = new Epetra_Map(-2, IndexBase, Comm);
00111   }
00112   catch (int Error) {
00113     if (Error!=-1) {
00114       if (Error!=0) {
00115   EPETRA_TEST_ERR(Error,returnierr);
00116   if (verbose) cout << "Error code should be -1" << endl;
00117       }
00118       else {
00119   cout << "Error code = " << Error << "Should be -1" << endl;
00120   returnierr+=1;
00121       }
00122     }
00123     else if (verbose) cout << "Checked OK\n\n" << endl;
00124   }
00125 
00126   try {
00127     if (verbose) cout << "Checking Epetra_Map(2, 3, IndexBase, Comm)" << endl;
00128     Map = new Epetra_Map(2, 3, IndexBase, Comm);
00129   }
00130   catch (int Error) {
00131     if (Error!=-4) {
00132       if (Error!=0) {
00133   EPETRA_TEST_ERR(Error,returnierr);
00134   if (verbose) cout << "Error code should be -4" << endl;
00135       }
00136       else {
00137   cout << "Error code = " << Error << "Should be -4" << endl;
00138   returnierr+=1;
00139       }
00140     }
00141     else if (verbose) cout << "Checked OK\n\n" << endl;
00142   }
00143 
00144   if (verbose) cerr << flush;
00145   if (verbose) cout << flush;
00146   Comm.Barrier();
00147   if (verbose)
00148     cout << endl << endl
00149       << "*******************************************************************************************" << endl
00150       << "        Testing valid constructor now......................................................" << endl
00151       << "*******************************************************************************************" << endl
00152       << endl << endl;
00153 
00154   // Test Epetra-defined uniform linear distribution constructor
00155   Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm);
00156   if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl;
00157   ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, 
00158       IndexBase, Comm, DistributedGlobal);
00159 
00160   EPETRA_TEST_ERR(ierr,returnierr);
00161   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00162 
00163   delete Map;
00164 
00165   // Test User-defined linear distribution constructor
00166   Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm);
00167 
00168   if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl;
00169   ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, 
00170       IndexBase, Comm, DistributedGlobal);
00171 
00172   EPETRA_TEST_ERR(ierr,returnierr);
00173   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00174   delete Map;
00175 
00176   // Test User-defined arbitrary distribution constructor
00177   // Generate Global Element List.  Do in reverse for fun!
00178 
00179   int * MyGlobalElements = new int[NumMyElements];
00180   int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
00181   if (Comm.MyPID()>2) MaxMyGID+=3;
00182   for (int i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;
00183 
00184   Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, 
00185                        IndexBase, Comm);
00186   if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,  IndexBase, Comm)" << endl;
00187   ierr = checkmap(*Map, NumGlobalElements, NumMyElements, MyGlobalElements, 
00188                   IndexBase, Comm, DistributedGlobal);
00189 
00190   EPETRA_TEST_ERR(ierr,returnierr);
00191   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00192   // Test Copy constructor
00193   Epetra_Map* Map1 = new Epetra_Map(*Map);
00194 
00195   // Test SameAs() method
00196   bool same = Map1->SameAs(*Map);
00197   EPETRA_TEST_ERR(!(same==true),ierr);// should return true since Map1 is a copy of Map
00198 
00199   Epetra_BlockMap* Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,  IndexBase, Comm);
00200   same = Map2->SameAs(*Map);
00201   EPETRA_TEST_ERR(!(same==true),ierr); // Map and Map2 were created with the same sets of parameters
00202   delete Map2;
00203 
00204   // now test SameAs() on a map that is different
00205 
00206   Map2 =  new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase-1, Comm);
00207   same = Map2->SameAs(*Map);
00208   EPETRA_TEST_ERR(!(same==false),ierr); // IndexBases are different
00209   delete Map2;
00210 
00211   // Back to testing copy constructor
00212   if (verbose) cout << "Checking Epetra_Map(*Map)" << endl;
00213   ierr = checkmap(*Map1, NumGlobalElements, NumMyElements, MyGlobalElements, 
00214       IndexBase, Comm, DistributedGlobal);
00215 
00216   EPETRA_TEST_ERR(ierr,returnierr);
00217   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00218   Epetra_Map* SmallMap = 0;
00219   if (verbose1) {
00220     // Build a small map for test cout.  Use 10 elements from current map
00221     int* MyEls = Map->MyGlobalElements();
00222     int IndBase = Map->IndexBase();
00223     int MyLen = EPETRA_MIN(10+Comm.MyPID(),Map->NumMyElements());
00224     SmallMap = new Epetra_Map(-1, MyLen, MyEls, IndBase, Comm);
00225   }
00226 
00227   delete [] MyGlobalElements;
00228   delete Map;
00229   delete Map1;
00230 
00231   // Test reference-counting in Epetra_Map
00232   if (verbose) cout << "Checking Epetra_Map reference counting" << endl;
00233   ierr = checkMapDataClass(Comm, verbose);
00234   EPETRA_TEST_ERR(ierr,returnierr);
00235   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00236 
00237   // Test LocalMap constructor
00238   Epetra_LocalMap* LocalMap = new Epetra_LocalMap(NumMyElements1, IndexBase, Comm);
00239   if (verbose) cout << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl;
00240   ierr = checkmap(*LocalMap, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false);
00241 
00242   EPETRA_TEST_ERR(ierr,returnierr);
00243   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00244   // Test Copy constructor
00245   Epetra_LocalMap* LocalMap1 = new Epetra_LocalMap(*LocalMap);
00246   if (verbose) cout << "Checking Epetra_LocalMap(*LocalMap)" << endl;
00247   ierr = checkmap(*LocalMap1, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false);
00248 
00249   EPETRA_TEST_ERR(ierr,returnierr);
00250   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00251   delete LocalMap1;
00252   delete LocalMap;
00253 
00254   // Test reference-counting in Epetra_LocalMap
00255   if (verbose) cout << "Checking Epetra_LocalMap reference counting" << endl;
00256   ierr = checkLocalMapDataClass(Comm, verbose);
00257   EPETRA_TEST_ERR(ierr,returnierr);
00258   if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
00259 
00260   // Test output
00261   if (verbose1) {
00262     if (verbose) cout << "Test ostream << operator" << endl << flush;
00263     cout << *SmallMap;
00264     delete SmallMap;
00265   }
00266 
00267 #ifdef EPETRA_MPI
00268   MPI_Finalize();
00269 #endif
00270 
00271   return returnierr;
00272 }
00273 
00274 int checkMapDataClass(Epetra_Comm& Comm, int verbose) {
00275   int returnierr = 0;
00276   int NumGlobalElements = 1000;
00277   int IndexBase = 0;
00278 
00279   Epetra_Map m1(NumGlobalElements, IndexBase, Comm);
00280   int m1count = m1.ReferenceCount();
00281   const Epetra_BlockMapData* m1addr = m1.DataPtr();
00282   EPETRA_TEST_ERR(!(m1count==1),returnierr); // count should be 1
00283   if(verbose) cout << "Default constructor. \nm1= " << m1count << "  " << m1addr << endl;
00284   
00285   Epetra_Map* m2 = new Epetra_Map(m1);
00286   int m2count = m2->ReferenceCount();
00287   const Epetra_BlockMapData* m2addr = m2->DataPtr();
00288   int m1countold = m1count;
00289   m1count = m1.ReferenceCount();
00290   EPETRA_TEST_ERR(!(m2count==m1count && m1count==(m1countold+1)),returnierr); // both counts should be 2
00291   EPETRA_TEST_ERR(!(m1addr==m2addr),returnierr); // addresses should be same
00292   if(verbose) cout << "Copy constructor. \nm1= " << m1count << "  " << m1addr 
00293                    << "\nm2= " << m2count << "  " << m2addr << endl;
00294 
00295   delete m2;
00296   m1countold = m1count;
00297   m1count = m1.ReferenceCount();
00298   EPETRA_TEST_ERR(!(m1count == m1countold-1), returnierr); // count should have decremented (to 1)
00299   EPETRA_TEST_ERR(!(m1addr == m1.DataPtr()),returnierr); // m1addr should be unchanged
00300   if(verbose) cout << "m2 destroyed. \nm1= " << m1count << "  " << m1addr << endl;
00301 
00302   { // inside of braces to test stack deallocation.
00303     if(verbose) cout << "Assignment operator, post construction" << endl;
00304     Epetra_Map m3(NumGlobalElements, IndexBase+1, Comm);
00305     int m3count = m3.ReferenceCount();
00306     const Epetra_BlockMapData* m3addr = m3.DataPtr();
00307     EPETRA_TEST_ERR(!(m3count==1),returnierr); // m3count should be 1 initially
00308     EPETRA_TEST_ERR(!(m1addr!=m3addr),returnierr); // m1 and m3 should have different ptr addresses
00309     if(verbose) cout << "Prior to assignment: \nm1= " << m1count << "  " << m1addr 
00310                      << "\nm3= " << m3count << "  " << m3addr << endl;
00311     m3 = m1;
00312     m3count = m3.ReferenceCount();
00313     m3addr = m3.DataPtr();
00314     m1countold = m1count;
00315     m1count = m1.ReferenceCount();
00316     EPETRA_TEST_ERR(!(m3count==m1count && m1count==m1countold+1),returnierr); // both counts should be 2
00317     EPETRA_TEST_ERR(!(m1addr==m3addr),returnierr); // addresses should be same
00318     if(verbose) cout << "After assignment: \nm1= " << m1count << "  " << m1addr 
00319                      << "\nm3= " << m3count << "  " << m3addr << endl;
00320   }
00321   m1countold = m1count;
00322   m1count = m1.ReferenceCount();
00323   EPETRA_TEST_ERR(!(m1count==m1countold-1), returnierr); // count should have decremented (to 1)
00324   EPETRA_TEST_ERR(!(m1addr== m1.DataPtr()),returnierr); // m1addr should be unchanged
00325   if(verbose) cout << "m3 destroyed. \nm1= " << m1count << "  " << m1addr << endl;
00326 
00327   return(returnierr);
00328 }
00329 
00330 int checkLocalMapDataClass(Epetra_Comm& Comm, int verbose) {
00331   int returnierr = 0;
00332   int NumMyElements = 100;
00333   int IndexBase = 0;
00334 
00335   Epetra_LocalMap m1(NumMyElements, IndexBase, Comm);
00336   int m1count = m1.ReferenceCount();
00337   const Epetra_BlockMapData* m1addr = m1.DataPtr();
00338   EPETRA_TEST_ERR(!(m1count==1),returnierr); // count should be 1
00339   if(verbose) cout << "Default constructor. \nm1= " << m1count << "  " << m1addr << endl;
00340   
00341   Epetra_LocalMap* m2 = new Epetra_LocalMap(m1);
00342   int m2count = m2->ReferenceCount();
00343   const Epetra_BlockMapData* m2addr = m2->DataPtr();
00344   int m1countold = m1count;
00345   m1count = m1.ReferenceCount();
00346   EPETRA_TEST_ERR(!(m2count==m1count && m1count==(m1countold+1)),returnierr); // both counts should be 2
00347   EPETRA_TEST_ERR(!(m1addr==m2addr),returnierr); // addresses should be same
00348   if(verbose) cout << "Copy constructor. \nm1= " << m1count << "  " << m1addr 
00349                    << "\nm2= " << m2count << "  " << m2addr << endl;
00350 
00351   delete m2;
00352   m1countold = m1count;
00353   m1count = m1.ReferenceCount();
00354   EPETRA_TEST_ERR(!(m1count == m1countold-1), returnierr); // count should have decremented (to 1)
00355   EPETRA_TEST_ERR(!(m1addr == m1.DataPtr()),returnierr); // m1addr should be unchanged
00356   if(verbose) cout << "m2 destroyed. \nm1= " << m1count << "  " << m1addr << endl;
00357 
00358   { // inside of braces to test stack deallocation.
00359     if(verbose) cout << "Assignment operator, post construction" << endl;
00360     Epetra_LocalMap m3(NumMyElements, IndexBase+1, Comm);
00361     int m3count = m3.ReferenceCount();
00362     const Epetra_BlockMapData* m3addr = m3.DataPtr();
00363     EPETRA_TEST_ERR(!(m3count==1),returnierr); // m3count should be 1 initially
00364     EPETRA_TEST_ERR(!(m1addr!=m3addr),returnierr); // m1 and m3 should have different ptr addresses
00365     if(verbose) cout << "Prior to assignment: \nm1= " << m1count << "  " << m1addr 
00366                      << "\nm3= " << m3count << "  " << m3addr << endl;
00367     m3 = m1;
00368     m3count = m3.ReferenceCount();
00369     m3addr = m3.DataPtr(); // cast int* to int
00370     m1countold = m1count;
00371     m1count = m1.ReferenceCount();
00372     EPETRA_TEST_ERR(!(m3count==m1count && m1count==m1countold+1),returnierr); // both counts should be 2
00373     EPETRA_TEST_ERR(!(m1addr==m3addr),returnierr); // addresses should be same
00374     if(verbose) cout << "After assignment: \nm1= " << m1count << "  " << m1addr 
00375                      << "\nm3= " << m3count << "  " << m3addr << endl;
00376   }
00377   m1countold = m1count;
00378   m1count = m1.ReferenceCount();
00379   EPETRA_TEST_ERR(!(m1count==m1countold-1), returnierr); // count should have decremented (to 1)
00380   EPETRA_TEST_ERR(!(m1addr== m1.DataPtr()),returnierr); // m1addr should be unchanged
00381   if(verbose) cout << "m3 destroyed. \nm1= " << m1count << "  " << m1addr << endl;
00382 
00383   return(returnierr);
00384 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines