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