Epetra Package Browser (Single Doxygen Collection) Development
test/Directory/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_Time.h"
00046 #include "Epetra_BlockMap.h"
00047 #include "Epetra_Map.h"
00048 #ifdef EPETRA_MPI
00049 #include "Epetra_MpiComm.h"
00050 #include <mpi.h>
00051 #endif
00052 #include "Epetra_SerialComm.h"
00053 #include "Epetra_Util.h"
00054 #include "../epetra_test_err.h"
00055 #include "Epetra_Version.h"
00056 #include "Epetra_Directory.h"
00057 
00058 int directory_test_1(Epetra_Comm& Comm);
00059 int directory_test_2(Epetra_Comm& Comm);
00060 int directory_test_3(Epetra_Comm& Comm);
00061 int directory_test_4(Epetra_Comm& Comm);
00062 int directory_test_5(Epetra_Comm& Comm);
00063 
00064 int main(int argc, char *argv[]) {
00065   bool verbose = false;
00066   // Check if we should print results to standard out
00067   if (argc > 1) {
00068     if ((argv[1][0] == '-') && (argv[1][1] == 'v')) {
00069       verbose = true;
00070     }
00071   }
00072 
00073   int returnierr = 0;
00074 
00075 #ifdef EPETRA_MPI
00076 
00077   // Initialize MPI
00078   MPI_Init(&argc,&argv);
00079   Epetra_MpiComm Comm(MPI_COMM_WORLD);
00080 #else
00081   Epetra_SerialComm Comm;
00082 #endif
00083 
00084   if (!verbose) {
00085     Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
00086   }
00087   int MyPID = Comm.MyPID();
00088 
00089   int verbose_int = verbose ? 1 : 0;
00090   Comm.Broadcast(&verbose_int, 1, 0);
00091   verbose = verbose_int==1 ? true : false;
00092 
00093   if (verbose && MyPID==0)
00094     cout << Epetra_Version() << endl << endl;
00095 
00096   EPETRA_TEST_ERR( directory_test_1(Comm), returnierr );
00097 
00098   EPETRA_TEST_ERR( directory_test_2(Comm), returnierr );
00099 
00100   EPETRA_TEST_ERR( directory_test_3(Comm), returnierr );
00101 
00102   EPETRA_TEST_ERR( directory_test_4(Comm), returnierr );
00103 
00104   EPETRA_TEST_ERR( directory_test_5(Comm), returnierr );
00105 
00106 #ifdef EPETRA_MPI
00107   MPI_Finalize();
00108 #endif
00109 
00110   if (MyPID == 0) {
00111     if (returnierr == 0) {
00112       cout << "Epetra_Directory tests passed."<<endl;
00113     }
00114     else {
00115       cout << "Epetra_Directory tests failed."<<endl;
00116     }
00117   }
00118 
00119   return returnierr;
00120 }
00121 
00122 int directory_test_1(Epetra_Comm& Comm)
00123 {
00124   //set up a map with arbitrary distribution of IDs, but with unique
00125   //processor ID ownership (i.e., each ID only appears on 1 processor)
00126 
00127   int myPID = Comm.MyPID();
00128   int numProcs = Comm.NumProc();
00129 
00130   if (numProcs < 2) return(0);
00131 
00132   int myFirstID = (myPID+1)*(myPID+1);
00133   int myNumIDs = 3+myPID;
00134 
00135   int* myIDs = new int[myNumIDs];
00136   int i;
00137   for(i=0; i<myNumIDs; ++i) {
00138     myIDs[i] = myFirstID+i;
00139   }
00140 
00141   Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
00142 
00143   Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
00144 
00145   int proc = myPID+1;
00146   if (proc >= numProcs) proc = 0;
00147 
00148   int procNumIDs = 3+proc;
00149   int procFirstID = (proc+1)*(proc+1);
00150   int procLastID = procFirstID+procNumIDs - 1;
00151 
00152   int queryProc1 = -1;
00153   int queryProc2 = -1;
00154 
00155   int err = directory->GetDirectoryEntries(blkmap, 1, &procFirstID,
00156              &queryProc1, NULL, NULL);
00157   err += directory->GetDirectoryEntries(blkmap, 1, &procLastID,
00158           &queryProc2, NULL, NULL);
00159   delete directory;
00160   delete [] myIDs;
00161 
00162   if (queryProc1 != proc || queryProc2 != proc) {
00163     return(-1);
00164   }
00165 
00166   return(0);
00167 }
00168 
00169 int directory_test_2(Epetra_Comm& Comm)
00170 {
00171   //set up a Epetra_BlockMap with arbitrary distribution of IDs, but with unique
00172   //processor ID ownership (i.e., each ID only appears on 1 processor)
00173   //
00174   //the thing that makes this Epetra_BlockMap nasty is that higher-numbered
00175   //processors own lower IDs.
00176 
00177   int myPID = Comm.MyPID();
00178   int numProcs = Comm.NumProc();
00179 
00180   if (numProcs < 2) return(0);
00181 
00182   int myFirstID = (numProcs-myPID)*(numProcs-myPID);
00183   int myNumIDs = 3;
00184 
00185   int* myIDs = new int[myNumIDs];
00186   int i;
00187   for(i=0; i<myNumIDs; ++i) {
00188     myIDs[i] = myFirstID+i;
00189   }
00190 
00191   Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
00192 
00193   Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
00194 
00195   int proc = myPID+1;
00196   if (proc >= numProcs) proc = 0;
00197 
00198   int procNumIDs = 3;
00199   int procFirstID = (numProcs-proc)*(numProcs-proc);
00200   int procLastID = procFirstID+procNumIDs - 1;
00201 
00202   int queryProc1 = -1;
00203   int queryProc2 = -1;
00204 
00205   int err = directory->GetDirectoryEntries(blkmap, 1, &procFirstID,
00206              &queryProc1, NULL, NULL);
00207   err += directory->GetDirectoryEntries(blkmap, 1, &procLastID,
00208           &queryProc2, NULL, NULL);
00209   delete directory;
00210   delete [] myIDs;
00211 
00212   if (queryProc1 != proc || queryProc2 != proc) {
00213     return(-1);
00214   }
00215 
00216   return(0);
00217 }
00218 
00219 int directory_test_3(Epetra_Comm& Comm)
00220 {
00221   //set up a map with arbitrary distribution of IDs, including non-unique
00222   //processor ID ownership (i.e., some IDs appear on more than 1 processor)
00223 
00224   int myPID = Comm.MyPID();
00225   int numProcs = Comm.NumProc();
00226 
00227   if (numProcs < 2) return(0);
00228 
00229   int myFirstID = (myPID+1)*(myPID+1);
00230   int myNumIDs = 4;
00231 
00232   int* myIDs = new int[myNumIDs];
00233   int i;
00234   for(i=0; i<myNumIDs-1; ++i) {
00235     myIDs[i] = myFirstID+i;
00236   }
00237 
00238   int nextProc = myPID+1;
00239   if (nextProc >= numProcs) nextProc = 0;
00240 
00241   int nextProcFirstID = (nextProc+1)*(nextProc+1);
00242   myIDs[myNumIDs-1] = nextProcFirstID;
00243 
00244   Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
00245 
00246   Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
00247 
00248   bool uniqueGIDs = directory->GIDsAllUniquelyOwned();
00249 
00250   delete directory;
00251   delete [] myIDs;
00252 
00253   if (uniqueGIDs) {
00254     return(-1);
00255   }
00256 
00257   return(0);
00258 }
00259 
00260 int directory_test_4(Epetra_Comm& Comm)
00261 {
00262   int myPID = Comm.MyPID();
00263   int numProcs = Comm.NumProc();
00264 
00265   if (numProcs < 2) return(0);
00266 
00267   //Set up a map with overlapping ranges of GIDs.
00268   int num = 5;
00269   int numMyGIDs = 2*num;
00270   int myFirstGID = myPID*num;
00271 
00272   int* myGIDs = new int[numMyGIDs];
00273 
00274   for(int i=0; i<numMyGIDs; ++i) {
00275     myGIDs[i] = myFirstGID+i;
00276   }
00277 
00278   Epetra_Map overlappingmap(-1, numMyGIDs, myGIDs, 0, Comm);
00279 
00280   delete [] myGIDs;
00281 
00282   int numGlobal0 = overlappingmap.NumGlobalElements();
00283 
00284   Epetra_Map uniquemap1 =
00285     Epetra_Util::Create_OneToOne_Map(overlappingmap);
00286 
00287   bool use_high_sharing_proc = true;
00288 
00289   Epetra_Map uniquemap2 =
00290     Epetra_Util::Create_OneToOne_Map(overlappingmap, use_high_sharing_proc);
00291 
00292   int numGlobal1 = uniquemap1.NumGlobalElements();
00293   int numGlobal2 = uniquemap2.NumGlobalElements();
00294 
00295   //The two one-to-one maps should have the same number of global elems.
00296   if (numGlobal1 != numGlobal2) {
00297     return(-1);
00298   }
00299 
00300   //The number of global elems should be greater in the original map
00301   //than in the one-to-one map.
00302   if (numGlobal0 <= numGlobal1) {
00303     return(-2);
00304   }
00305 
00306   int numLocal1 = uniquemap1.NumMyElements();
00307   int numLocal2 = uniquemap2.NumMyElements();
00308 
00309   //If this is proc 0 or proc numProcs-1, then the number of
00310   //local elements should be different in the two one-to-one maps.
00311   if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
00312     return(-3);
00313   }
00314 
00315   return(0);
00316 }
00317 
00318 int directory_test_5(Epetra_Comm& Comm)
00319 {
00320   int myPID = Comm.MyPID();
00321   int numProcs = Comm.NumProc();
00322 
00323   if (numProcs < 2) return(0);
00324 
00325   //Set up a map with overlapping ranges of GIDs.
00326   int num = 5;
00327   int numMyGIDs = 2*num;
00328   int myFirstGID = myPID*num;
00329 
00330   int* myGIDs = new int[numMyGIDs];
00331   int* sizes = new int[numMyGIDs];
00332 
00333   for(int i=0; i<numMyGIDs; ++i) {
00334     myGIDs[i] = myFirstGID+i;
00335     sizes[i] = myFirstGID+i+1;
00336   }
00337 
00338   Epetra_BlockMap overlappingmap(-1, numMyGIDs, myGIDs, sizes, 0, Comm);
00339 
00340   delete [] myGIDs;
00341   delete [] sizes;
00342 
00343   int numGlobal0 = overlappingmap.NumGlobalElements();
00344 
00345   Epetra_BlockMap uniquemap1 =
00346     Epetra_Util::Create_OneToOne_BlockMap(overlappingmap);
00347 
00348   bool use_high_sharing_proc = true;
00349 
00350   Epetra_BlockMap uniquemap2 =
00351     Epetra_Util::Create_OneToOne_BlockMap(overlappingmap, use_high_sharing_proc);
00352 
00353   int numGlobal1 = uniquemap1.NumGlobalElements();
00354   int numGlobal2 = uniquemap2.NumGlobalElements();
00355 
00356   //The two one-to-one maps should have the same number of global elems.
00357   if (numGlobal1 != numGlobal2) {
00358     return(-1);
00359   }
00360 
00361   //The number of global elems should be greater in the original map
00362   //than in the one-to-one map.
00363   if (numGlobal0 <= numGlobal1) {
00364     return(-2);
00365   }
00366 
00367   int numLocal1 = uniquemap1.NumMyElements();
00368   int numLocal2 = uniquemap2.NumMyElements();
00369 
00370   //If this is proc 0 or proc numProcs-1, then the number of
00371   //local elements should be different in the two one-to-one maps.
00372   if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
00373     return(-3);
00374   }
00375 
00376   return(0);
00377 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines