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