Epetra Package Browser (Single Doxygen Collection) Development
LL/memorytest_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 // This program tests the memory management system of the class CrsMatrix (memory leak, invalid free).
00043 // It should be run using valgrind.
00044 //
00045 // Initially written to demonstrate bug #5499 and regressions introduced by the first patch.
00046 
00047 #include <vector>
00048 
00049 #include "Epetra_ConfigDefs.h"
00050 #include "Epetra_Map.h"
00051 #include "Epetra_CrsMatrix.h"
00052 #ifdef EPETRA_MPI
00053 #include "Epetra_MpiComm.h"
00054 #include "mpi.h"
00055 #else
00056 #include "Epetra_SerialComm.h"
00057 #endif
00058 //#include "../epetra_test_err.h"
00059 #include "Epetra_Version.h"
00060 
00061 int main(int argc, char *argv[])
00062 {
00063   int ierr = 0;
00064 
00065 #ifdef EPETRA_MPI
00066 
00067   // Initialize MPI
00068 
00069   MPI_Init(&argc, &argv);
00070   int rank; // My process ID
00071 
00072   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00073   Epetra_MpiComm Comm( MPI_COMM_WORLD );
00074 
00075 #else
00076 
00077   int rank = 0;
00078   Epetra_SerialComm Comm;
00079 
00080 #endif
00081 
00082   bool verbose = false;
00083 
00084   // Check if we should print results to standard out
00085   if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
00086 
00087   int verbose_int = verbose ? 1 : 0;
00088   Comm.Broadcast(&verbose_int, 1, 0);
00089   verbose = verbose_int==1 ? true : false;
00090 
00091   Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
00092   int MyPID = Comm.MyPID();
00093   int NumProc = Comm.NumProc();
00094 
00095   if(verbose && MyPID==0)
00096     std::cout << Epetra_Version() << std::endl << std::endl;
00097 
00098   if (verbose) std::cout << "Processor "<<MyPID<<" of "<< NumProc
00099         << " is alive."<< std::endl;
00100 
00101   // unused: bool verbose1 = verbose;
00102 
00103   // Redefine verbose to only print on PE 0
00104   if(verbose && rank!=0)
00105     verbose = false;
00106 
00107   if (verbose) std::cout << "Test the memory management system of the class CrsMatrix (memory leak, invalid free)" << std::endl;
00108 
00109   //
00110   // Test 1: code initially proposed to illustrate bug #5499
00111   //
00112 
00113   if(Comm.NumProc() == 1) { // this is a sequential test
00114 
00115     if (verbose) std::cout << "* Using Copy, ColMap, Variable number of indices per row and Static profile (cf. bug #5499)." << std::endl;
00116 
00117     // Row Map
00118     Epetra_Map RowMap(2LL, 0LL, Comm);
00119 
00120     // ColMap
00121     std::vector<long long> colids(2);
00122     colids[0]=0;
00123     colids[1]=1;
00124     Epetra_Map ColMap(-1LL, 2, &colids[0], 0LL, Comm);
00125 
00126     // NumEntriesPerRow
00127     std::vector<int> NumEntriesPerRow(2);
00128     NumEntriesPerRow[0]=2;
00129     NumEntriesPerRow[1]=2;
00130 
00131     // Test
00132     Epetra_CrsMatrix A(Copy, RowMap, ColMap, &NumEntriesPerRow[0], true);
00133     // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
00134     A.FillComplete();
00135 
00136   }
00137 
00138   //
00139   // Test 1 Bis: same as Test1, but without ColMap and variable number of indices per row. Does not seems to matter
00140   //
00141 
00142   if(Comm.NumProc() == 1) { // this is a sequential test
00143 
00144     if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile" << std::endl;
00145 
00146     Epetra_Map RowMap(2LL, 0LL, Comm);
00147 
00148     // Test
00149     Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
00150     // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
00151     A.FillComplete();
00152 
00153   }
00154 
00155   //
00156   // Test 2: same as Test 1 Bis but with one call to InsertGlobalValues.
00157   //
00158 
00159   if(Comm.NumProc() == 1) {
00160 
00161     if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile + InsertGlobalValues()." << std::endl;
00162 
00163     Epetra_Map RowMap(2LL, 0LL, Comm);
00164 
00165     // Test
00166     Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
00167     std::vector<long long>    Indices(1);
00168     std::vector<double> Values(1);
00169     Values[0] = 2;
00170     Indices[0] = 0;
00171 
00172     A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); // Memory leak if CrsMatrix::Values not freed
00173 
00174     A.FillComplete();
00175 
00176   }
00177 
00178   //
00179   // Test 3: check if the patch is not introducing some obvious regression
00180   //
00181 
00182   if(Comm.NumProc() == 1) {
00183 
00184     if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile" << std::endl;
00185 
00186     Epetra_Map RowMap(2LL, 0LL, Comm);
00187 
00188     // Test
00189     Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
00190     A.FillComplete();
00191 
00192   }
00193 
00194   //
00195   // Test 4: idem but with one call to InsertGlobalValues.
00196   //
00197 
00198   if(Comm.NumProc() == 1) {
00199 
00200     if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile + InsertGlobalValues()." << std::endl;
00201 
00202     Epetra_Map RowMap(2LL, 0LL, Comm);
00203 
00204     // Test
00205     Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
00206     std::vector<long long>    Indices(1);
00207     std::vector<double> Values(1);
00208     Values[0] = 2;
00209     Indices[0] = 0;
00210 
00211     A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
00212     A.FillComplete();
00213 
00214   }
00215 
00216   if(Comm.NumProc() == 1) {
00217 
00218     if (verbose) std::cout << "* Using Copy, Static Graph()." << std::endl;
00219 
00220     Epetra_Map RowMap(1LL, 0LL, Comm);
00221 
00222     // Test
00223     Epetra_CrsGraph    G(Copy, RowMap, 1);
00224     std::vector<long long>    Indices(1);
00225     Indices[0] = 0;
00226     G.InsertGlobalIndices(0, 1, &Indices[0]);
00227     G.FillComplete();
00228 
00229     Epetra_CrsMatrix    A(Copy, G);
00230     std::vector<double> Values(1);
00231     Values[0] = 2;
00232     A.ReplaceGlobalValues(0, 1, &Values[0], &Indices[0]);
00233     A.FillComplete();
00234     double norminf = A.NormInf();
00235     if (verbose) std::cout << "** Inf Norm of Matrix = " << norminf << "." << std::endl;
00236     std::cout << A << std::endl;
00237 
00238 
00239   }
00240 
00241 
00242   if(Comm.NumProc() == 1) {
00243 
00244     if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and static profile + InsertGlobalValues() for a single row." << std::endl;
00245 
00246     Epetra_Map RowMap(1LL, 0LL, Comm);
00247 
00248     // Test
00249     Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
00250     std::vector<long long>    Indices(1);
00251     std::vector<double> Values(1);
00252     Values[0] = 2;
00253     Indices[0] = 0;
00254 
00255     A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
00256     A.FillComplete();
00257 
00258   }
00259 
00260   /*
00261     if (bool) {
00262     if (verbose) std::cout << std::endl << "tests FAILED" << std::endl << std::endl;
00263     }
00264     else {*/
00265   if (verbose) std::cout << std::endl << "tests PASSED" << std::endl << std::endl;
00266   /*    } */
00267 
00268 #ifdef EPETRA_MPI
00269   MPI_Finalize();
00270 #endif
00271 
00272   return ierr;
00273 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines