Epetra Package Browser (Single Doxygen Collection) Development
test/Directory_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_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   long long* myIDs = new long long[myNumIDs];
00136   int i;
00137   for(i=0; i<myNumIDs; ++i) {
00138     myIDs[i] = myFirstID+i;
00139   }
00140 
00141   Epetra_BlockMap blkmap((long long)-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   long long procFirstID = (long long)(proc+1)*(proc+1);
00150   long long procLastID = procFirstID+procNumIDs - 1;
00151 
00152   int queryProc1 = -1;
00153   int queryProc2 = -1;
00154 
00155   int err = directory->GetDirectoryEntries(
00156       blkmap, 1, &procFirstID,
00157       &queryProc1, NULL, NULL
00158       );
00159   err += directory->GetDirectoryEntries(
00160       blkmap, 1, &procLastID,
00161       &queryProc2, NULL, NULL
00162       );
00163   delete directory;
00164   delete [] myIDs;
00165 
00166   if (queryProc1 != proc || queryProc2 != proc) {
00167     return(-1);
00168   }
00169 
00170   return(0);
00171 }
00172 
00173 int directory_test_2(Epetra_Comm& Comm)
00174 {
00175   //set up a Epetra_BlockMap with arbitrary distribution of IDs, but with unique
00176   //processor ID ownership (i.e., each ID only appears on 1 processor)
00177   //
00178   //the thing that makes this Epetra_BlockMap nasty is that higher-numbered
00179   //processors own lower IDs.
00180 
00181   int myPID = Comm.MyPID();
00182   int numProcs = Comm.NumProc();
00183 
00184   if (numProcs < 2) return(0);
00185 
00186   int myFirstID = (numProcs-myPID)*(numProcs-myPID);
00187   int myNumIDs = 3;
00188 
00189   long long* myIDs = new long long[myNumIDs];
00190   int i;
00191   for(i=0; i<myNumIDs; ++i) {
00192     myIDs[i] = myFirstID+i;
00193   }
00194 
00195   Epetra_BlockMap blkmap((long long)-1, myNumIDs, myIDs, 1, 0, Comm);
00196 
00197   Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
00198 
00199   int proc = myPID+1;
00200   if (proc >= numProcs) proc = 0;
00201 
00202   int procNumIDs = 3;
00203   long long procFirstID = (long long)(numProcs-proc)*(numProcs-proc);
00204   long long procLastID = procFirstID+procNumIDs - 1;
00205 
00206   int queryProc1 = -1;
00207   int queryProc2 = -1;
00208 
00209   int err = directory->GetDirectoryEntries(blkmap, 1, &procFirstID,
00210       &queryProc1, NULL, NULL);
00211   err += directory->GetDirectoryEntries(blkmap, 1, &procLastID,
00212       &queryProc2, NULL, NULL);
00213   delete directory;
00214   delete [] myIDs;
00215 
00216   if (queryProc1 != proc || queryProc2 != proc) {
00217     return(-1);
00218   }
00219 
00220   return(0);
00221 }
00222 
00223 int directory_test_3(Epetra_Comm& Comm)
00224 {
00225   //set up a map with arbitrary distribution of IDs, including non-unique
00226   //processor ID ownership (i.e., some IDs appear on more than 1 processor)
00227 
00228   int myPID = Comm.MyPID();
00229   int numProcs = Comm.NumProc();
00230 
00231   if (numProcs < 2) return(0);
00232 
00233   int myFirstID = (myPID+1)*(myPID+1);
00234   int myNumIDs = 4;
00235 
00236   long long* myIDs = new long long[myNumIDs];
00237   int i;
00238   for(i=0; i<myNumIDs-1; ++i) {
00239     myIDs[i] = myFirstID+i;
00240   }
00241 
00242   int nextProc = myPID+1;
00243   if (nextProc >= numProcs) nextProc = 0;
00244 
00245   int nextProcFirstID = (nextProc+1)*(nextProc+1);
00246   myIDs[myNumIDs-1] = nextProcFirstID;
00247 
00248   Epetra_BlockMap blkmap((long long)-1, myNumIDs, myIDs, 1, 0, Comm);
00249 
00250   Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
00251 
00252   bool uniqueGIDs = directory->GIDsAllUniquelyOwned();
00253 
00254   delete directory;
00255   delete [] myIDs;
00256 
00257   if (uniqueGIDs) {
00258     return(-1);
00259   }
00260 
00261   return(0);
00262 }
00263 
00264 int directory_test_4(Epetra_Comm& Comm)
00265 {
00266   int myPID = Comm.MyPID();
00267   int numProcs = Comm.NumProc();
00268 
00269   if (numProcs < 2) return(0);
00270 
00271   //Set up a map with overlapping ranges of GIDs.
00272   int num = 5;
00273   int numMyGIDs = 2*num;
00274   int myFirstGID = myPID*num;
00275 
00276   long long* myGIDs = new long long[numMyGIDs];
00277 
00278   for(int i=0; i<numMyGIDs; ++i) {
00279     myGIDs[i] = myFirstGID+i;
00280   }
00281 
00282   Epetra_Map overlappingmap((long long)-1, numMyGIDs, myGIDs, 0, Comm);
00283 
00284   delete [] myGIDs;
00285 
00286   long long numGlobal0 = overlappingmap.NumGlobalElements64();
00287 
00288 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // FIXME
00289   Epetra_Map uniquemap1 =
00290     Epetra_Util::Create_OneToOne_Map(overlappingmap);
00291 
00292   bool use_high_sharing_proc = true;
00293 
00294   Epetra_Map uniquemap2 =
00295     Epetra_Util::Create_OneToOne_Map(overlappingmap, use_high_sharing_proc);
00296 
00297   long long numGlobal1 = uniquemap1.NumGlobalElements64();
00298   long long numGlobal2 = uniquemap2.NumGlobalElements64();
00299 
00300   //The two one-to-one maps should have the same number of global elems.
00301   if (numGlobal1 != numGlobal2) {
00302     return(-1);
00303   }
00304 
00305   //The number of global elems should be greater in the original map
00306   //than in the one-to-one map.
00307   if (numGlobal0 <= numGlobal1) {
00308     return(-2);
00309   }
00310 
00311   int numLocal1 = uniquemap1.NumMyElements();
00312   int numLocal2 = uniquemap2.NumMyElements();
00313 
00314   //If this is proc 0 or proc numProcs-1, then the number of
00315   //local elements should be different in the two one-to-one maps.
00316   if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
00317     return(-3);
00318   }
00319 
00320 #endif
00321   return(0);
00322 }
00323 
00324 int directory_test_5(Epetra_Comm& Comm)
00325 {
00326   int myPID = Comm.MyPID();
00327   int numProcs = Comm.NumProc();
00328 
00329   if (numProcs < 2) return(0);
00330 
00331   //Set up a map with overlapping ranges of GIDs.
00332   int num = 5;
00333   int numMyGIDs = 2*num;
00334   int myFirstGID = myPID*num;
00335 
00336   long long* myGIDs = new long long[numMyGIDs];
00337   int* sizes = new int[numMyGIDs];
00338 
00339   for(int i=0; i<numMyGIDs; ++i) {
00340     myGIDs[i] = myFirstGID+i;
00341     sizes[i] = myFirstGID+i+1;
00342   }
00343 
00344   Epetra_BlockMap overlappingmap((long long)-1, numMyGIDs, myGIDs, sizes, 0, Comm);
00345 
00346   delete [] myGIDs;
00347   delete [] sizes;
00348 
00349   long long numGlobal0 = overlappingmap.NumGlobalElements64();
00350 
00351 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // FIXME
00352   Epetra_BlockMap uniquemap1 =
00353     Epetra_Util::Create_OneToOne_BlockMap(overlappingmap);
00354 
00355   bool use_high_sharing_proc = true;
00356 
00357   Epetra_BlockMap uniquemap2 =
00358     Epetra_Util::Create_OneToOne_BlockMap(overlappingmap, use_high_sharing_proc);
00359 
00360   long long numGlobal1 = uniquemap1.NumGlobalElements64();
00361   long long numGlobal2 = uniquemap2.NumGlobalElements64();
00362 
00363   //The two one-to-one maps should have the same number of global elems.
00364   if (numGlobal1 != numGlobal2) {
00365     return(-1);
00366   }
00367 
00368   //The number of global elems should be greater in the original map
00369   //than in the one-to-one map.
00370   if (numGlobal0 <= numGlobal1) {
00371     return(-2);
00372   }
00373 
00374   int numLocal1 = uniquemap1.NumMyElements();
00375   int numLocal2 = uniquemap2.NumMyElements();
00376 
00377   //If this is proc 0 or proc numProcs-1, then the number of
00378   //local elements should be different in the two one-to-one maps.
00379   if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
00380     return(-3);
00381   }
00382 #endif
00383   return(0);
00384 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines