Epetra Package Browser (Single Doxygen Collection) Development
test/Comm/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_Comm Test routine
00044 #include "../epetra_test_err.h"
00045 #include "Epetra_Time.h"
00046 #include "Epetra_Util.h"
00047 #include "Epetra_Distributor.h"
00048 #include "Epetra_SerialComm.h"
00049 #include "Epetra_IntSerialDenseVector.h"
00050 #include "Epetra_Version.h"
00051 
00052 #ifdef EPETRA_MPI
00053 #include <mpi.h>
00054 #include "Epetra_MpiComm.h"
00055 
00056 int checkMpiDataClass(bool verbose);
00057 #endif
00058 
00059 int checkSerialDataClass(bool verbose);
00060 int checkCommMethods(Epetra_Comm& petracomm,
00061                      bool verbose, bool verbose1,
00062                      int& NumProc, int& rank);
00063 int checkRankAndSize(Epetra_Comm& petracomm, bool verbose, int rank, int size);
00064 void checkBarrier(Epetra_Comm& petracomm, bool verbose, int rank);
00065 
00066 int checkDistributor(Epetra_Distributor* distr,
00067                      Epetra_Comm& Comm);
00068 
00069 int main(int argc, char* argv[]) {
00070   bool verbose = false;  // used to set verbose false on non-root processors
00071   bool verbose1 = false; // user's command-line argument
00072   // Check if we should print results to standard out
00073   if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose1 = true;
00074 
00075   int ierr = 0;
00076   int returnierr = 0;
00077   int size = 1;
00078   int rank = 0;
00079 
00080   if (verbose1)
00081     cout << Epetra_Version() << endl << endl;
00082 
00083   // Test Epetra_SerialComm
00084   if(verbose1) cout << "Testing Epetra_SerialComm..." << endl;
00085   Epetra_SerialComm serialcomm;
00086   if (verbose1) cout << serialcomm << endl;
00087   ierr = checkRankAndSize(serialcomm, verbose1, rank, size);
00088   EPETRA_TEST_ERR(ierr,returnierr);
00089   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00090   // method testing
00091   int numProc = serialcomm.NumProc();
00092   ierr = checkCommMethods(serialcomm, verbose, verbose1, numProc, rank);
00093   EPETRA_TEST_ERR(ierr,returnierr);
00094   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00095   // clone
00096   if(verbose1) cout << "SerialComm Clone.." << endl;
00097   Epetra_Comm* cloned_serialcomm = serialcomm.Clone();
00098   ierr = checkCommMethods(*cloned_serialcomm, verbose, verbose1, numProc, rank);
00099   delete cloned_serialcomm;
00100   EPETRA_TEST_ERR(ierr,returnierr);
00101   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00102   // check inner data class
00103   ierr = checkSerialDataClass(verbose1);
00104   EPETRA_TEST_ERR(ierr,returnierr);
00105   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00106 
00107   Epetra_Distributor* serialdistr = serialcomm.CreateDistributor();
00108   ierr = checkDistributor(serialdistr, serialcomm);
00109   delete serialdistr;
00110   EPETRA_TEST_ERR(ierr, returnierr);
00111 
00112   // Test Epetra_MpiComm
00113 #ifdef EPETRA_MPI
00114   // Initialize MPI
00115   if(verbose1) cout << "Testing Epetra_MpiComm..." << endl;
00116   MPI_Init(&argc,&argv);
00117   MPI_Comm_size(MPI_COMM_WORLD, &size);
00118   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00119   Epetra_MpiComm petracomm( MPI_COMM_WORLD );
00120   ierr = checkRankAndSize(petracomm, verbose1, rank, size);
00121   EPETRA_TEST_ERR(ierr,returnierr);
00122   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00123   MPI_Comm MPIComm1 = petracomm.Comm();
00124   int size1, rank1;
00125   MPI_Comm_size(MPIComm1, &size1);
00126   MPI_Comm_rank(MPIComm1, &rank1);
00127   if (verbose1) cout << petracomm <<  ".  Using MPI_Comm from Petra_Comm:"
00128                            << " Processor " << rank1 << " of " << size1
00129                            << " (should be the same)." << endl;
00130   EPETRA_TEST_ERR(!(rank1==rank),ierr);
00131   EPETRA_TEST_ERR(!(size1==size),ierr);
00132   checkBarrier(petracomm, verbose1, rank);
00133 
00134   // method testing
00135   numProc = petracomm.NumProc();
00136   ierr = checkCommMethods(petracomm, verbose, verbose1, numProc, rank);
00137   EPETRA_TEST_ERR(ierr,returnierr);
00138   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00139 
00140   // clone
00141   if(verbose1) cout << "MpiComm Clone.." << endl;
00142   Epetra_Comm* cloned_mpicomm = petracomm.Clone();
00143   ierr = checkCommMethods(*cloned_mpicomm, verbose, verbose1, numProc, rank);
00144   delete cloned_mpicomm;
00145   EPETRA_TEST_ERR(ierr,returnierr);
00146   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00147 
00148   // check inner data class
00149   petracomm.Barrier();
00150   ierr = checkMpiDataClass(verbose1);
00151   EPETRA_TEST_ERR(ierr,returnierr);
00152   if (verbose1 && ierr==0) cout << "Checked OK\n\n" <<endl;
00153 
00154   Epetra_Distributor* plldistr = petracomm.CreateDistributor();
00155   ierr = checkDistributor(plldistr, petracomm);
00156   delete plldistr;
00157   EPETRA_TEST_ERR(ierr, returnierr);
00158 
00159   petracomm.Barrier();
00160   MPI_Finalize();
00161 #endif
00162 
00163   return(returnierr);
00164 }
00165 
00166 //=============================================================================
00167 void checkBarrier(Epetra_Comm& petracomm, bool verbose, int rank) {
00168   // Do some timing to test barrier function
00169   int MyPID = petracomm.MyPID();
00170   Epetra_Time before_barrier(petracomm);
00171   Epetra_Time after_barrier(petracomm);
00172   // Give each processor rank+1 amount of work
00173   // Time before barrier should increase roughly linearly
00174   // Time after barrier should be same for all processors
00175   double sum = 0.0;
00176   for (int j=0; j<rank+1; j++)
00177     for (int i=0; i<1000000; i++) 
00178       sum += ((double )rand())/((double) RAND_MAX);
00179   sum /= rank+1;
00180   if (verbose) cout << "Processor " << MyPID
00181                     << " Time to reach barrier: "
00182                     << before_barrier.ElapsedTime() << endl;
00183   petracomm.Barrier();
00184   if (verbose) cout << "Processor " << MyPID << " Sum result  "
00185                     << sum << " Time to get beyond barrier: "
00186                     << after_barrier.ElapsedTime() << endl;
00187  
00188   petracomm.Barrier();
00189 }
00190 
00191 //=============================================================================
00192 int checkRankAndSize(Epetra_Comm& petracomm, bool verbose, int rank, int size) {
00193   int ierr = 0;
00194   //if(verbose) cout << "CRS Breakpoint 1" << endl;
00195   int MyPID = petracomm.MyPID();
00196   //if(verbose) cout << "CRS Breakpoint 2" << endl;
00197   int NumProc = petracomm.NumProc();
00198   EPETRA_TEST_ERR(!(MyPID==rank),ierr);
00199   EPETRA_TEST_ERR(!(NumProc==size),ierr);
00200   petracomm.Barrier();
00201   return(ierr);
00202 }
00203 
00204 //=============================================================================
00205 int checkCommMethods(Epetra_Comm& petracomm, bool verbose, bool verbose1, int& NumProc, int& rank) {
00206   int i,j;
00207   int forierr = 0;
00208   int ierr = 0;
00209 
00210   verbose = (petracomm.MyPID() == 0);  // Turn verbose on; 
00211                                        // it is always false in main.
00212 
00213   // Some vars needed for the following tests
00214   int count = 4;
00215   int* iInputs = new int[count]; // General array for int type tests
00216   for (i=0; i<count; i++)
00217     iInputs[i] = 10*(i + rank - 2) + rank; 
00218     // if these values are changed, the expected maxs, mins, sums, etc must also change.  
00219     //NOTE: Broadcst() does not use these values.  The lines that need to be changed are located
00220     //in the "Values for ****** tests" sections directly below.
00221 
00222   double* dInputs = new double[count]; // General array for double type tests
00223   for (i=0; i<count; i++)
00224     dInputs[i] = pow(2.0,i-rank); 
00225     // if these values are changed, the expected maxs, mins, sums, etc must also change.  
00226     //NOTE: Broadcst() does not use these values.  The lines that need to be changed are located
00227     //in the "Values for ****** tests" sections directly below.
00228 
00229 
00230   // Values for Broadcast tests
00231   int* iVals = new int[count];
00232   if (rank == 0) {
00233     for (i=0; i<count; i++)
00234        iVals[i] = i; // if these values are changed, the values in iBVals must also be changed
00235   }
00236   
00237   int* iBVals = new int[count]; // Values to be checked against the values broadcast to the non root processors
00238   for (i=0; i<count; i++)
00239     iBVals[i] = i; // if these values are changed, the values in iVals must also be changed
00240   double* dVals = new double[count];
00241   if (rank == 0) {
00242      for (i=0; i<count; i++)
00243        dVals[i] = double(i); // if these values are changed, the values in dBVals must also be changed
00244   }    
00245   double* dBVals = new double[count]; // Values to be checked against the values broadcast to the non root processors
00246   for (i=0; i<count; i++)
00247     dBVals[i] = i; // if these values are changed, the values in dVals must also be changed
00248 
00249   const char *cConst = "Heidi, do you want a cookie?";
00250   int cCount = strlen(cConst)+1;
00251   char* cVals = new char[cCount];
00252   if (rank == 0) {
00253      strcpy(cVals, cConst);        // if these values are changed, 
00254      cVals[cCount-1] = '\0';       // the values in cBVals must also be changed
00255   }
00256   char* cBVals = new char[cCount]; // Values to be checked against the values 
00257                                    // broadcast to the non root processors
00258   strcpy(cBVals, cConst);          // if these values are changed, 
00259   cBVals[cCount-1] = '\0';         // the values in cVals must also be changed
00260 
00261   // Values for MaxAll tests
00262   int* iMyGlobalMaxs = new int[count];
00263   for (i=0; i<count; i++)
00264     iMyGlobalMaxs[i]=10 * (i + NumProc-1 -2) +  NumProc-1; // if these values are changed, iInput must be changed 
00265                                                            //as well as all other values dependent on iInput
00266   double* dMyGlobalMaxs = new double[count];
00267   for (i=0; i<count; i++)
00268     dMyGlobalMaxs[i]= pow(2.0,i); //if these values are changed, dInput must be changed 
00269                                   //as well as all other values dependent on dInput
00270 
00271 
00272   // Values for MinAll tests
00273   int* iMyGlobalMins = new int[count];
00274   for (i=0; i<count; i++)
00275     iMyGlobalMins[i]= 10 * (i - 2); //if these values are changed, iInput must be changed 
00276                                     //as well as all other values dependent on iInput
00277   double* dMyGlobalMins = new double[count];
00278   for (i=0; i<count; i++)
00279     dMyGlobalMins[i]= pow(2.0,i-(NumProc-1)); //if these values are changed, dInput must be changed 
00280                                               //as well as all other values dependent on dInput
00281 
00282 
00283   // Values for SumAll tests
00284   int* iMyGlobalSums = new int[count];
00285   for (i=0; i<count; i++){
00286     iMyGlobalSums[i]=0;
00287     for (j=0; j<NumProc; j++)
00288       iMyGlobalSums[i] += 10*(i+j-2) + j;// if these values are changed, iInput must be changed                                          
00289   }                                      //as well as all other values dependent on iInput
00290 
00291   double* dMyGlobalSums = new double[count];
00292   for (i=0; i<count; i++){
00293     dMyGlobalSums[i]=0;
00294     for (j=0; j<NumProc; j++)
00295       dMyGlobalSums[i] += pow(2.0,i-j);// if these values are changed, dInput must be changed 
00296   }                                    //as well as all other values dependent on dInput
00297 
00298 
00299   // Values for ScanSum tests
00300   int* iMyScanSums = new int[count];
00301   for (i=0; i<count; i++)
00302     iMyScanSums[i] = int((rank+1)*(10*(2*i+rank-4)+rank)*.5);// if these values are changed, 
00303                                                              //iInput must be changed as well as 
00304                                                              //all other values dependent on iInput
00305   double* dMyScanSums = new double[count];
00306   for (i=0; i<count; i++) {
00307     dMyScanSums[i] = 0;
00308     for (j=0; j<=rank; j++)
00309       dMyScanSums[i] += pow(2.0,i-j); //if these values are changed, dInput must be changed 
00310   }                                   //as well as all other values dependent on dInput
00311 
00312 
00313   // Values for Gather tests
00314   int totalVals = count*NumProc;
00315   int* iMyOrderedVals = new int[totalVals];
00316   double* dMyOrderedVals = new double[totalVals];
00317   int k=0;
00318   for (j=0; j<NumProc; j++) {
00319     for (i=0; i<count; i++) {
00320       iMyOrderedVals[k] = 10*(i + j - 2) + j;; // if these values are changed, iInput must be changed 
00321                                                //as well as all other values dependent on iInput
00322       dMyOrderedVals[k] = pow(2.0,i-j); // if these values are changed, dInput must be changed 
00323                                         //as well as all other values dependent on dInput
00324       k++;
00325     }
00326   }
00327   petracomm.Barrier();
00328 
00329 
00330   // Method testing section
00331   // Test the Broadcast functions
00332   EPETRA_TEST_ERR(petracomm.Broadcast(iVals,count,0),ierr);
00333   if (verbose1) {
00334     if (rank == 0) 
00335       cout << "The values on the root processor are: ";
00336     else
00337       cout << "The values on processor " << rank << " are: ";
00338     for (i=0; i<count; i++) 
00339       cout << iVals[i] << " ";
00340     cout << endl;
00341   }
00342   // ierr = 0; need to track errors the whole way through the file - this line of code seems like a bad idea 
00343   forierr = 0;
00344   for (i=0; i<count; i++)
00345     forierr += !(iVals[i] == iBVals[i]); // otherwise Broadcast didn't occur properly
00346   EPETRA_TEST_ERR(forierr,ierr);
00347   delete [] iVals;
00348   delete [] iBVals;
00349   petracomm.Barrier();
00350   if (verbose) cout << endl << "Broadcast (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00351                                                                                    //only output on one node
00352   petracomm.Barrier();
00353 
00354   EPETRA_TEST_ERR(petracomm.Broadcast(dVals,count,0),ierr);
00355   if (verbose1) {
00356     if (rank == 0)
00357       cout << "The values on the root processor are: ";
00358     else
00359       cout << "The values on processor " << rank << " are: ";
00360     for (i=0; i<count; i++) 
00361       cout << dVals[i] << " ";
00362     cout << endl;
00363   }
00364   forierr = 0;
00365   for (i=0; i<count; i++)
00366     forierr += !(dVals[i] == dBVals[i]); // otherwise Broadcast didn't occur properly
00367   EPETRA_TEST_ERR(forierr,ierr);
00368   delete [] dVals;
00369   delete [] dBVals;
00370   petracomm.Barrier();
00371   if (verbose) cout << endl << "Broadcast (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00372                                                                                       //only output on one node
00373   petracomm.Barrier();
00374 
00375   EPETRA_TEST_ERR(petracomm.Broadcast(cVals,cCount,0),ierr);
00376   if (verbose1) {
00377     if (rank == 0)
00378       cout << "The values on the root processor are: " << cVals << endl;
00379     else
00380       cout << "The values on processor " << rank << " are: " << cVals << endl;
00381   }
00382   forierr = 0;
00383   for (i=0; i<cCount; i++)
00384     forierr += !(cVals[i] == cBVals[i]); // otherwise Broadcast didn't work.
00385   EPETRA_TEST_ERR(forierr,ierr);
00386   delete [] cVals;
00387   delete [] cBVals;
00388   petracomm.Barrier();
00389   // If test gets to here the test passed, 
00390   if (verbose) 
00391     cout << endl << "Broadcast (type char) test passed!" << endl << endl;
00392                                                                                       //only output on one node
00393   petracomm.Barrier();
00394 
00395  // Test the MaxAll functions
00396   int* iGlobalMaxs = new int[count];
00397   if (verbose1) {
00398     cout << "The values on processor " << rank << " are: ";
00399     for (i=0; i<count; i++) 
00400       cout << iInputs[i] << " ";
00401     cout << endl;
00402   }
00403   EPETRA_TEST_ERR(petracomm.MaxAll(iInputs,iGlobalMaxs,count),ierr);
00404   petracomm.Barrier();
00405   
00406   if (verbose1) {
00407     cout << "The max values according to processor " << rank << " are: ";
00408     for (i=0; i<count; i++) 
00409       cout << iGlobalMaxs[i] << " ";
00410     cout << endl;
00411   }
00412   forierr = 0;
00413   for (i=0; i<count; i++) 
00414     forierr += !(iMyGlobalMaxs[i] == iGlobalMaxs[i]);
00415   EPETRA_TEST_ERR(forierr,ierr);
00416 
00417   delete [] iGlobalMaxs;
00418   delete [] iMyGlobalMaxs;
00419   petracomm.Barrier();
00420   if (verbose) cout << endl << "MaxAll (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00421                                                                                 //only output on one node
00422   petracomm.Barrier();
00423 
00424   double* dGlobalMaxs = new double[count];
00425   if (verbose1) {
00426     cout << "The values on processor " << rank << " are: ";
00427     for (i=0; i<count; i++) 
00428       cout << dInputs[i] << " ";
00429     cout << endl;
00430   }
00431   EPETRA_TEST_ERR(petracomm.MaxAll(dInputs,dGlobalMaxs,count),ierr);
00432   petracomm.Barrier();
00433   
00434   if (verbose1) {
00435     cout << "The max values according to processor " << rank << " are: ";
00436     for (i=0; i<count; i++) 
00437       cout << dGlobalMaxs[i] << " ";
00438     cout << endl;
00439   }
00440   forierr = 0;
00441   for (i=0; i<count; i++)
00442     forierr += !(Epetra_Util::Chop(dMyGlobalMaxs[i] - dGlobalMaxs[i]) == 0);
00443   EPETRA_TEST_ERR(forierr,ierr);
00444   delete [] dGlobalMaxs;
00445   delete [] dMyGlobalMaxs;
00446   petracomm.Barrier();
00447   if (verbose) cout << endl << "MaxAll (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00448                                                                                    //only output on one node
00449   petracomm.Barrier();
00450 
00451 
00452  // Test the MinAll functions
00453   int* iGlobalMins = new int[count];
00454   if (verbose1) {
00455     cout << "The values on processor " << rank << " are: ";
00456     for (i=0; i<count; i++) 
00457       cout << iInputs[i] << " ";
00458     cout << endl;
00459   }
00460   EPETRA_TEST_ERR(petracomm.MinAll(iInputs,iGlobalMins,count),ierr);
00461   petracomm.Barrier();
00462 
00463   if (verbose1) {
00464     cout << "The min values according to processor " << rank << " are: ";
00465     for (i=0; i<count; i++) 
00466       cout << iGlobalMins[i] << " ";
00467     cout << endl;
00468   }
00469   forierr = 0;
00470   for (i=0; i<count; i++) 
00471     forierr += !(iMyGlobalMins[i] == iGlobalMins[i]); // otherwise calculated min is wrong
00472   EPETRA_TEST_ERR(forierr,ierr);
00473   delete [] iGlobalMins;
00474   delete [] iMyGlobalMins;
00475   petracomm.Barrier();
00476   if (verbose) cout << endl << "MinAll (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00477                                                                                 //only output on one node
00478   petracomm.Barrier();
00479 
00480   double* dGlobalMins = new double[count];
00481   if (verbose1) {
00482     cout << "The values on processor " << rank << " are: ";
00483     for (i=0; i<count; i++) 
00484       cout << dInputs[i] << " ";
00485     cout << endl;
00486   }
00487   EPETRA_TEST_ERR(petracomm.MinAll(dInputs,dGlobalMins,count),ierr);
00488   petracomm.Barrier();
00489 
00490   if (verbose1) {
00491     cout << "The min values according to processor " << rank << " are: ";
00492     for (i=0; i<count; i++) 
00493       cout << dGlobalMins[i] << " ";
00494     cout << endl;
00495   }
00496   forierr = 0;
00497   for (i=0; i<count; i++)
00498     forierr += !(Epetra_Util::Chop(dMyGlobalMins[i] - dGlobalMins[i]) == 0); // otherwise calculated min is wrong
00499   EPETRA_TEST_ERR(forierr,ierr);
00500   delete [] dGlobalMins;
00501   delete [] dMyGlobalMins;
00502   petracomm.Barrier();
00503   if (verbose) cout << endl << "MinAll (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00504                                                                                    //only output on one node
00505   petracomm.Barrier();
00506 
00507 
00508  // Test the SumAll functions
00509   int* iGlobalSums = new int[count];
00510   if (verbose1) {
00511     cout << "The values on processor " << rank << " are: ";
00512     for (i=0; i<count; i++) 
00513       cout << iInputs[i] << " ";
00514     cout << endl;
00515   }
00516   EPETRA_TEST_ERR(petracomm.SumAll(iInputs,iGlobalSums,count),ierr);
00517   petracomm.Barrier();
00518 
00519   if (verbose1) {
00520     cout << "The sums of all values according to processor " << rank << " are: ";
00521     for (i=0; i<count; i++) 
00522       cout << iGlobalSums[i] << " ";
00523     cout << endl;
00524   }
00525   forierr = 0;
00526   for (i=0; i<count; i++)
00527     forierr += !(iMyGlobalSums[i] == iGlobalSums[i]); // otherwise calculated sum is wrong
00528   EPETRA_TEST_ERR(forierr,ierr);
00529   delete [] iGlobalSums;
00530   delete [] iMyGlobalSums;
00531   petracomm.Barrier();
00532   if (verbose) cout << endl << "SumAll (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00533                                                                                 //only output on one node
00534   petracomm.Barrier();
00535 
00536   double* dGlobalSums = new double[count];
00537   if (verbose1) {
00538     cout << "The values on processor " << rank << " are: ";
00539     for (i=0; i<count; i++) 
00540       cout << dInputs[i] << " ";
00541     cout << endl;
00542   }
00543   EPETRA_TEST_ERR(petracomm.SumAll(dInputs,dGlobalSums,count),ierr);
00544   petracomm.Barrier();
00545 
00546   if (verbose1) {
00547     cout << "The sums of all values according to processor " << rank << " are: ";
00548     for (i=0; i<count; i++) 
00549       cout << dGlobalSums[i] << " ";
00550     cout << endl;
00551   }
00552   forierr = 0;
00553   for (i=0; i<count; i++)
00554     forierr += !(Epetra_Util::Chop(dMyGlobalSums[i] - dGlobalSums[i]) == 0); // otherwise calculated sum is wrong
00555   EPETRA_TEST_ERR(forierr,ierr);
00556 
00557   delete [] dGlobalSums;
00558   delete [] dMyGlobalSums;
00559   petracomm.Barrier();
00560   if (verbose) cout << endl << "SumAll (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00561                                                                                    //only output on one node
00562   petracomm.Barrier();
00563 
00564 
00565  // Test the ScanSum functions
00566   int* iScanSums = new int[count];
00567   if (verbose1) {
00568     cout << "The values on processor " << rank << " are: ";
00569     for (i=0; i<count; i++) 
00570       cout << iInputs[i] << " ";
00571     cout << endl;
00572   }
00573   
00574   EPETRA_TEST_ERR(petracomm.ScanSum(iInputs,iScanSums,count),ierr);
00575   petracomm.Barrier();
00576 
00577   if (verbose1) {
00578     cout << "The sums of all values on processors 0 - " << rank << " are: ";
00579     for (i=0; i<count; i++) {
00580       cout << iScanSums[i] << " ";
00581     }
00582     cout << endl;
00583   }
00584   forierr = 0;
00585   for (i=0; i<count; i++)
00586     forierr += !(iMyScanSums[i] == iScanSums[i]);
00587   EPETRA_TEST_ERR(forierr,ierr);
00588   delete [] iScanSums;
00589   delete [] iMyScanSums;
00590   petracomm.Barrier();
00591   if (verbose) cout << endl << "ScanSum (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00592                                                                                  //only output on one node
00593   petracomm.Barrier();
00594 
00595   double* dScanSums = new double[count];
00596   if (verbose1) {
00597     cout << "The values on processor " << rank << " are: ";
00598     for (i=0; i<count; i++)
00599       cout << dInputs[i] << " ";
00600     cout << endl;
00601   }
00602 
00603   EPETRA_TEST_ERR(petracomm.ScanSum(dInputs,dScanSums,count),ierr);
00604   petracomm.Barrier();
00605 
00606   if (verbose1) {
00607     cout << "The sums of all values on processors 0 - " << rank << " are: ";
00608     for (i=0; i<count; i++) {
00609       cout << dScanSums[i] << " ";
00610     }
00611     cout << endl;
00612   }
00613   forierr = 0;
00614   for (i=0; i<count; i++)
00615     forierr += !(Epetra_Util::Chop(dMyScanSums[i] - dScanSums[i])== 0);
00616   EPETRA_TEST_ERR(forierr,ierr);
00617   delete [] dScanSums;
00618   delete [] dMyScanSums;
00619   petracomm.Barrier();
00620   if (verbose) cout << endl << "ScanSum (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00621                                                                                     //only output on one node
00622   petracomm.Barrier();
00623 
00624 
00625  // Test the Gather functions
00626   int* iOrderedVals = new int[totalVals];
00627   if (verbose1) {
00628     cout << "The values on processor " << rank << " are: ";
00629     for (i=0; i<count; i++) 
00630       cout << iInputs[i] << " ";
00631     cout << endl;
00632   }
00633   
00634   EPETRA_TEST_ERR(petracomm.GatherAll(iInputs,iOrderedVals,count),ierr);
00635   petracomm.Barrier();
00636 
00637   if (verbose1) {
00638     cout << "The combined list of all values from all processors according to processor " << rank << " is: ";
00639     for (i=0; i<totalVals; i++) {
00640       cout << iOrderedVals[i] << " ";
00641     }
00642     cout << endl;
00643   }
00644   forierr = 0;
00645   for (i=0; i<totalVals; i++)
00646     forierr += !(iMyOrderedVals[i] == iOrderedVals[i]);
00647   EPETRA_TEST_ERR(forierr,ierr);
00648   delete [] iOrderedVals;
00649   delete [] iMyOrderedVals;
00650   petracomm.Barrier();
00651   if (verbose) cout << endl << "GatherAll (type int) test passed!" << endl << endl;// If test gets to here the test passed, 
00652                                                                                    //only output on one node
00653   petracomm.Barrier();
00654 
00655   double* dOrderedVals = new double[totalVals];
00656   if (verbose1) {
00657     cout << "The values on processor " << rank << " are: ";
00658     for (i=0; i<count; i++) 
00659       cout << dInputs[i] << " ";
00660     cout << endl;
00661   }
00662   
00663   EPETRA_TEST_ERR(petracomm.GatherAll(dInputs,dOrderedVals,count),ierr);
00664   petracomm.Barrier();
00665 
00666   if (verbose1) {
00667     cout << "The combined list of all values from all processors according to processor " << rank << " is: ";
00668     for (i=0; i<totalVals; i++) {
00669       cout << dOrderedVals[i] << " ";
00670     }
00671     cout << endl;
00672   }
00673   forierr = 0;
00674   for (i=0; i<totalVals; i++)
00675     forierr += !(Epetra_Util::Chop(dMyOrderedVals[i] - dOrderedVals[i]) == 0);
00676   EPETRA_TEST_ERR(forierr,ierr);
00677   delete [] dOrderedVals;
00678   delete [] dMyOrderedVals;
00679   petracomm.Barrier();
00680   if (verbose) cout << endl << "GatherAll (type double) test passed!" << endl << endl;// If test gets to here the test passed, 
00681                                                                                       //only output on one node
00682   petracomm.Barrier();
00683 
00684   delete[] dInputs;
00685   delete[] iInputs;
00686 
00687   return(ierr);
00688 }
00689 
00690 //=============================================================================
00691 int checkSerialDataClass(bool verbose) {
00692   int ierr = 0;
00693   if(verbose) cout << "Testing Reference Counting... ";               
00694   Epetra_SerialComm c1;
00695   int c1count = c1.ReferenceCount();
00696   const Epetra_SerialCommData* c1addr = c1.DataPtr();
00697   EPETRA_TEST_ERR(!(c1count==1),ierr); // count should be 1
00698   if(verbose) cout << "Default constructor. \nc1= " << c1count << "  " << c1addr << endl;
00699 
00700   Epetra_SerialComm* c2 = new Epetra_SerialComm(c1);
00701   int c2count = c2->ReferenceCount();
00702   const Epetra_SerialCommData* c2addr = c2->DataPtr();
00703   int c1countold = c1count;
00704   c1count = c1.ReferenceCount();
00705   EPETRA_TEST_ERR(!(c2count==c1count && c1count==(c1countold+1)),ierr); // both counts should be 2
00706   EPETRA_TEST_ERR(!(c1addr==c2addr),ierr); // addresses should be same
00707   if(verbose) cout << "Copy constructor(heap). \nc1= " << c1count << "  " << c1addr 
00708                     << "\nc2= " << c2count << "  " << c2addr << endl;
00709   delete c2;
00710   c1countold = c1count;
00711   c1count = c1.ReferenceCount();
00712   EPETRA_TEST_ERR(!(c1count==c1countold-1),ierr); // count should have decremented (to 1)
00713   EPETRA_TEST_ERR(!(c1addr==c1.DataPtr()),ierr); // c1addr should be unchanged
00714   if(verbose) cout << "c2 Deleted. \nc1= " << c1count << "  " << c1addr << endl;
00715   { // inside own set of brackets so that c2a will be automatically at end of brackets
00716     // so that we can test to make sure objects on the stack deallocate correctly
00717     Epetra_SerialComm c2a(c1);
00718     c2count = c2a.ReferenceCount();
00719     c2addr = c2a.DataPtr();
00720     c1countold = c1count;
00721     c1count = c1.ReferenceCount();
00722     EPETRA_TEST_ERR(!(c2count==c1count && c1count==c1countold+1),ierr); // both counts should be 2
00723     EPETRA_TEST_ERR(!(c1addr==c2addr),ierr); // addresses should be same
00724     if(verbose) cout << "Copy constructor(stack). \nc1= " << c1count << "  " << c1addr 
00725                       << "\nc2a= " << c2count << "  " << c2addr << endl;
00726   }
00727   c1countold = c1count;
00728   c1count = c1.ReferenceCount();
00729   EPETRA_TEST_ERR(!(c1count==c1countold-1),ierr); // count should have decremented (to 1)
00730   EPETRA_TEST_ERR(!(c1addr==c1.DataPtr()),ierr); // c1addr should be unchanged
00731   if(verbose) cout << "c2a Destroyed. \nc1= " << c1count << "  " << c1addr << endl;
00732   if(verbose) cout << "Assignment operator, post construction" << endl;
00733   Epetra_SerialComm c3;
00734   int c3count = c3.ReferenceCount();
00735   const Epetra_SerialCommData* c3addr = c3.DataPtr();
00736   EPETRA_TEST_ERR(!(c3count==1),ierr); // c3count should be 1 initially
00737   EPETRA_TEST_ERR(!(c1addr!=c3addr),ierr); // c1 and c3 should have different ptr addresses
00738   if(verbose)cout << "Prior to assignment: \nc1=" << c1count << "  " << c1addr 
00739                    << "\nc3=" << c3count << "  " << c3addr << endl;
00740   c3 = c1;
00741   c3count = c3.ReferenceCount();
00742   c3addr = c3.DataPtr();
00743   c1countold = c1count;
00744   c1count = c1.ReferenceCount();
00745   EPETRA_TEST_ERR(!(c3count==c1count && c1count==c1countold+1),ierr); // both counts should be 2
00746   EPETRA_TEST_ERR(!(c1addr==c3addr),ierr); // addresses should be same
00747   if(verbose)cout << "After assignment: \nc1=" << c1count << "  " << c1addr 
00748                    << "\nc3=" << c3count << "  " << c3addr << endl;
00749   return(ierr);
00750 }
00751 
00752 //=============================================================================
00753 #ifdef EPETRA_MPI
00754 int checkMpiDataClass(bool verbose) {
00755   int ierr = 0;
00756   if(verbose) cout << "Testing Reference Counting... ";               
00757   Epetra_MpiComm c1( MPI_COMM_WORLD );
00758   int c1count = c1.ReferenceCount();
00759   const Epetra_MpiCommData* c1addr = c1.DataPtr();
00760   EPETRA_TEST_ERR(!(c1count==1),ierr); // count should be 1
00761   if(verbose) cout << "Default constructor. \nc1= " << c1count << "  " << c1addr << endl;
00762 
00763   Epetra_MpiComm* c2 = new Epetra_MpiComm(c1);
00764   int c2count = c2->ReferenceCount();
00765   const Epetra_MpiCommData* c2addr = c2->DataPtr();
00766   int c1countold = c1count;
00767   c1count = c1.ReferenceCount();
00768   EPETRA_TEST_ERR(!(c2count==c1count && c1count==(c1countold+1)),ierr); // both counts should be 2
00769   EPETRA_TEST_ERR(!(c1addr==c2addr),ierr); // addresses should be same
00770   if(verbose) cout << "Copy constructor(heap). \nc1= " << c1count << "  " << c1addr 
00771                     << "\nc2= " << c2count << "  " << c2addr << endl;
00772   delete c2;
00773   c1countold = c1count;
00774   c1count = c1.ReferenceCount();
00775   EPETRA_TEST_ERR(!(c1count==c1countold-1),ierr); // count should have decremented (to 1)
00776   EPETRA_TEST_ERR(!(c1addr==c1.DataPtr()),ierr); // c1addr should be unchanged
00777   if(verbose) cout << "c2 Deleted. \nc1= " << c1count << "  " << c1addr << endl;
00778   { // inside own set of brackets so that c2a will be automatically at end of brackets
00779     // so that we can test to make sure objects on the stack deallocate correctly
00780     Epetra_MpiComm c2a(c1);
00781     c2count = c2a.ReferenceCount();
00782     c2addr = c2a.DataPtr();
00783     c1countold = c1count;
00784     c1count = c1.ReferenceCount();
00785     EPETRA_TEST_ERR(!(c2count==c1count && c1count==c1countold+1),ierr); // both counts should be 2
00786     EPETRA_TEST_ERR(!(c1addr==c2addr),ierr); // addresses should be same
00787     if(verbose) cout << "Copy constructor(stack). \nc1= " << c1count << "  " << c1addr 
00788                       << "\nc2a= " << c2count << "  " << c2addr << endl;
00789   }
00790   c1countold = c1count;
00791   c1count = c1.ReferenceCount();
00792   EPETRA_TEST_ERR(!(c1count==c1countold-1),ierr); // count should have decremented (to 1)
00793   EPETRA_TEST_ERR(!(c1addr==c1.DataPtr()),ierr); // c1addr should be unchanged
00794   if(verbose) cout << "c2a Destroyed. \nc1= " << c1count << "  " << c1addr << endl;
00795   if(verbose) cout << "Assignment operator, post construction" << endl;
00796   Epetra_MpiComm c3( MPI_COMM_WORLD );
00797   int c3count = c3.ReferenceCount();
00798   const Epetra_MpiCommData* c3addr = c3.DataPtr();
00799   EPETRA_TEST_ERR(!(c3count==1),ierr); // c3count should be 1 initially
00800   EPETRA_TEST_ERR(!(c1addr!=c3addr),ierr); // c1 and c3 should have different ptr addresses
00801   if(verbose)cout << "Prior to assignment: \nc1=" << c1count << "  " << c1addr 
00802                    << "\nc3=" << c3count << "  " << c3addr << endl;
00803   c3 = c1;
00804   c3count = c3.ReferenceCount();
00805   c3addr = c3.DataPtr();
00806   c1countold = c1count;
00807   c1count = c1.ReferenceCount();
00808   EPETRA_TEST_ERR(!(c3count==c1count && c1count==c1countold+1),ierr); // both counts should be 2
00809   EPETRA_TEST_ERR(!(c1addr==c3addr),ierr); // addresses should be same
00810   if(verbose)cout << "After assignment: \nc1=" << c1count << "  " << c1addr 
00811                    << "\nc3=" << c3count << "  " << c3addr << endl;
00812   return(ierr);
00813 }
00814 #endif
00815 
00816 int checkDistributor(Epetra_Distributor* distr,
00817                      Epetra_Comm& Comm)
00818 {
00819   int numprocs = Comm.NumProc();
00820 
00821   int numExportIDs = numprocs;
00822   int* exportPIDs = new int[numExportIDs];
00823   for(int p=0; p<numExportIDs; ++p) {
00824     exportPIDs[p] = p;
00825   }
00826 
00827   bool deterministic = true;
00828   int numRemoteIDs = 0;
00829 
00830   int err = distr->CreateFromSends(numExportIDs, exportPIDs,
00831                                    deterministic, numRemoteIDs);
00832 
00833   //numRemoteIDs should equal numExportIDs.
00834 
00835   int returnValue = numRemoteIDs == numExportIDs ? 0 : -99;
00836 
00837   delete [] exportPIDs;
00838 
00839   if (returnValue + err != 0) {
00840     return(returnValue + err);
00841   }
00842 
00843   int* exportIDs = new int[numExportIDs];
00844   for(int i=0; i<numExportIDs; ++i) {
00845     exportIDs[i] = i+1;
00846   }
00847 
00848   int len_imports = 0;
00849   char* imports = NULL;
00850 
00851   err = distr->Do((char*)exportIDs, sizeof(int),
00852                   len_imports, imports);
00853 
00854   delete [] exportIDs;
00855 
00856   if (len_imports > 0) {
00857     delete [] imports;
00858   }
00859 
00860   return(err);
00861 }
00862 
00863 /*
00864   end of file cxx_main.cpp
00865 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines