1 
2 #include "Mongoose_EdgeCut.hpp"
3 #include "Mongoose_IO.hpp"
4 #include <iostream>
5 #include "Mongoose_Test.hpp"
6 
7 using namespace Mongoose;
8 
9 int RunAllTests(const std::string &inputFile, EdgeCut_Options*);
10 
11 int RunTest(const std::string &inputFile, const EdgeCut_Options*, int allowedMallocs);
12 
13 /* Custom memory management functions allow for memory testing. */
14 int AllowedMallocs;
15 
myMalloc(size_t size)16 void *myMalloc(size_t size)
17 {
18     if(AllowedMallocs <= 0) return NULL;
19     AllowedMallocs--;
20     return malloc(size);
21 }
22 
myCalloc(size_t count,size_t size)23 void *myCalloc(size_t count, size_t size)
24 {
25     if(AllowedMallocs <= 0) return NULL;
26     AllowedMallocs--;
27     return calloc(count, size);
28 }
29 
myRealloc(void * ptr,size_t newSize)30 void *myRealloc(void *ptr, size_t newSize)
31 {
32     if(AllowedMallocs <= 0) return NULL;
33     AllowedMallocs--;
34     return realloc(ptr, newSize);
35 }
36 
myFree(void * ptr)37 void myFree(void *ptr)
38 {
39     if(ptr != NULL) free(ptr);
40 }
41 
runMemoryTest(const std::string & inputFile)42 int runMemoryTest(const std::string &inputFile)
43 {
44     EdgeCut_Options *options = EdgeCut_Options::create();
45 
46     if(!options)
47     {
48         LogTest("Error creating Options struct in Memory Test");
49         return EXIT_FAILURE; // Return early if we failed.
50     }
51 
52     /* Override SuiteSparse memory management with custom testers. */
53     SuiteSparse_config.malloc_func = myMalloc;
54     SuiteSparse_config.calloc_func = myCalloc;
55     SuiteSparse_config.realloc_func = myRealloc;
56     SuiteSparse_config.free_func = myFree;
57 
58     int status = RunAllTests(inputFile, options);
59 
60     options->~EdgeCut_Options();
61 
62     return status;
63 }
64 
RunAllTests(const std::string & inputFile,EdgeCut_Options * options)65 int RunAllTests (const std::string &inputFile, EdgeCut_Options *options)
66 {
67     LogTest("Running Memory Test on " << inputFile);
68 
69     int m = 0;
70     int remainingMallocs;
71 
72     MatchingStrategy matchingStrategies[4] = {Random, HEM, HEMSR, HEMSRdeg};
73     InitialEdgeCutType guessCutStrategies[3] = {InitialEdgeCut_QP, InitialEdgeCut_Random, InitialEdgeCut_NaturalOrder};
74     Int coarsenLimit[3] = {64, 256, 1024};
75 
76     for(int c = 0; c < 2; c++)
77     {
78         options->do_community_matching = static_cast<bool>(c);
79 
80         for(int i = 0; i < 4; i++)
81         {
82             options->matching_strategy = matchingStrategies[i];
83 
84             for(int j = 0; j < 3; j++)
85             {
86                 options->initial_cut_type = guessCutStrategies[j];
87                 for(int k = 0; k < 3; k++)
88                 {
89                     options->coarsen_limit = coarsenLimit[k];
90                     m = 0;
91                     do {
92                         remainingMallocs = RunTest(inputFile, options, m);
93                         if (remainingMallocs == -1)
94                         {
95                             // Error!
96                             LogTest("Terminating Memory Test Early");
97                             return EXIT_FAILURE;
98                         }
99                         m += 1;
100                     } while (remainingMallocs < 1);
101                 }
102             }
103         }
104     }
105 
106     // Run once with no options struct
107     m = 0;
108     do {
109         remainingMallocs = RunTest(inputFile, NULL, m);
110         if (remainingMallocs == -1)
111         {
112             // Error!
113             LogTest("Terminating Memory Test Early");
114             return EXIT_FAILURE;
115         }
116         m += 1;
117     } while (remainingMallocs < 1);
118 
119     LogTest("Memory Test Completed Successfully");
120     return EXIT_SUCCESS;
121 }
122 
RunTest(const std::string & inputFile,const EdgeCut_Options * O,int allowedMallocs)123 int RunTest (const std::string &inputFile, const EdgeCut_Options *O, int allowedMallocs)
124 {
125     /* Set the # of mallocs that we're allowed. */
126     AllowedMallocs = allowedMallocs;
127 
128     /* Read and condition the matrix from the MM file. */
129     Graph *U = read_graph(inputFile);
130     if (!U) return AllowedMallocs;
131 
132     EdgeCut *result;
133 
134     if (O)
135     {
136         result = edge_cut(U, O);
137     }
138     else
139     {
140         result = edge_cut(U);
141     }
142 
143     U->~Graph();
144 
145     if (result != NULL)
146         result->~EdgeCut();
147 
148     return AllowedMallocs;
149 }